diff --git a/source/Gnomeshade.Avalonia.Core/DesignTime/DesignTimeGnomeshadeClient.cs b/source/Gnomeshade.Avalonia.Core/DesignTime/DesignTimeGnomeshadeClient.cs index ca1ca237c..009618c36 100644 --- a/source/Gnomeshade.Avalonia.Core/DesignTime/DesignTimeGnomeshadeClient.cs +++ b/source/Gnomeshade.Avalonia.Core/DesignTime/DesignTimeGnomeshadeClient.cs @@ -388,6 +388,9 @@ public Task AddLinkToTransactionAsync(Guid transactionId, Guid linkId) public Task RemoveLinkFromTransactionAsync(Guid transactionId, Guid linkId) { var relation = _transactionLinks.Single(kvp => kvp.Key == transactionId && kvp.Value == linkId); + + // Performance is not an issue here + // ReSharper disable once UsageOfDefaultStructEquality _transactionLinks.Remove(relation); return Task.CompletedTask; } diff --git a/source/Gnomeshade.Data/Identity/ApplicationUser.cs b/source/Gnomeshade.Data/Identity/ApplicationUser.cs index f1d1fd746..5ed197d71 100644 --- a/source/Gnomeshade.Data/Identity/ApplicationUser.cs +++ b/source/Gnomeshade.Data/Identity/ApplicationUser.cs @@ -3,12 +3,14 @@ // See LICENSE.txt file in the project root for full license information. using System; +using System.Diagnostics.CodeAnalysis; using Microsoft.AspNetCore.Identity; namespace Gnomeshade.Data.Identity; /// Application identity user. +[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] public sealed class ApplicationUser : IdentityUser { /// Initializes a new instance of the class. @@ -19,7 +21,7 @@ public ApplicationUser() } /// Initializes a new instance of the class. - /// The user name. + /// The username. public ApplicationUser(string userName) : this() { @@ -27,5 +29,6 @@ public ApplicationUser(string userName) } /// Gets or sets the full name for this user. + // ReSharper disable once EntityFramework.ModelValidation.UnlimitedStringLength public string FullName { get; set; } = null!; } diff --git a/source/Gnomeshade.Data/Identity/IdentityContext.cs b/source/Gnomeshade.Data/Identity/IdentityContext.cs index d78344d40..188455bb9 100644 --- a/source/Gnomeshade.Data/Identity/IdentityContext.cs +++ b/source/Gnomeshade.Data/Identity/IdentityContext.cs @@ -28,12 +28,6 @@ protected IdentityContext(ILoggerFactory loggerFactory) _loggerFactory = loggerFactory; } - /// - protected sealed override void OnModelCreating(ModelBuilder builder) - { - base.OnModelCreating(builder); - } - /// protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { diff --git a/source/Gnomeshade.WebApi/OpenApi/ProducesStatus404NotFoundAttribute.cs b/source/Gnomeshade.WebApi/OpenApi/ProducesStatus404NotFoundAttribute.cs index ce28180ed..973dd2c14 100644 --- a/source/Gnomeshade.WebApi/OpenApi/ProducesStatus404NotFoundAttribute.cs +++ b/source/Gnomeshade.WebApi/OpenApi/ProducesStatus404NotFoundAttribute.cs @@ -9,10 +9,5 @@ namespace Gnomeshade.WebApi.OpenApi; /// A filter that specifies that the action returns with . -internal sealed class ProducesStatus404NotFoundAttribute : ProducesResponseTypeAttribute -{ - public ProducesStatus404NotFoundAttribute() - : base(Status404NotFound) - { - } -} +internal sealed class ProducesStatus404NotFoundAttribute() + : ProducesResponseTypeAttribute(Status404NotFound); diff --git a/source/Gnomeshade.WebApi/OpenApi/ProducesStatus409ConflictAttribute.cs b/source/Gnomeshade.WebApi/OpenApi/ProducesStatus409ConflictAttribute.cs index 733f108a7..988593e53 100644 --- a/source/Gnomeshade.WebApi/OpenApi/ProducesStatus409ConflictAttribute.cs +++ b/source/Gnomeshade.WebApi/OpenApi/ProducesStatus409ConflictAttribute.cs @@ -9,10 +9,5 @@ namespace Gnomeshade.WebApi.OpenApi; /// A filter that specifies that the action returns with . -internal sealed class ProducesStatus409ConflictAttribute : ProducesResponseTypeAttribute -{ - public ProducesStatus409ConflictAttribute() - : base(Status409Conflict) - { - } -} +internal sealed class ProducesStatus409ConflictAttribute() + : ProducesResponseTypeAttribute(Status409Conflict); diff --git a/source/Gnomeshade.WebApi/OpenApi/ValidationProblemDetailsFilter.cs b/source/Gnomeshade.WebApi/OpenApi/ValidationProblemDetailsFilter.cs index cf3f44bf7..8c2019cc6 100644 --- a/source/Gnomeshade.WebApi/OpenApi/ValidationProblemDetailsFilter.cs +++ b/source/Gnomeshade.WebApi/OpenApi/ValidationProblemDetailsFilter.cs @@ -32,11 +32,11 @@ void IOperationFilter.Apply(OpenApiOperation operation, OperationFilterContext c .MethodInfo .DeclaringType? .GetCustomAttributes(true) - .OfType(); + .OfType() + .ToArray(); - if (apiControllerAttributes is null || - !apiControllerAttributes.Any() || - (!operation.Parameters.Any() && !(operation.RequestBody?.Required ?? false))) + if (apiControllerAttributes is null or [] || + (operation.Parameters is [] && operation.RequestBody?.Required is not true)) { return; } @@ -48,7 +48,7 @@ void IOperationFilter.Apply(OpenApiOperation operation, OperationFilterContext c Content = new Dictionary { { - "application/problem+json", new OpenApiMediaType + "application/problem+json", new() { Schema = context.SchemaRepository.Schemas[nameof(ValidationProblemDetails)], } diff --git a/source/Gnomeshade.WebApi/V1/Controllers/CategoriesController.cs b/source/Gnomeshade.WebApi/V1/Controllers/CategoriesController.cs index 1815140e5..737236fb5 100644 --- a/source/Gnomeshade.WebApi/V1/Controllers/CategoriesController.cs +++ b/source/Gnomeshade.WebApi/V1/Controllers/CategoriesController.cs @@ -68,9 +68,12 @@ public override Task Post([FromBody] CategoryCreation category) => public override Task Put(Guid id, [FromBody] CategoryCreation category) => base.Put(id, category); - /// - /// The category was deleted successfully. // ReSharper disable once RedundantOverriddenMember + + /// + /// Category was deleted successfully. + /// Category with the specified id does not exist. + /// Category cannot be deleted because some other entity is still referencing it. public override Task Delete(Guid id) => base.Delete(id); diff --git a/source/Gnomeshade.WebApi/V1/Controllers/LinksController.cs b/source/Gnomeshade.WebApi/V1/Controllers/LinksController.cs index e82784387..b5e0b24eb 100644 --- a/source/Gnomeshade.WebApi/V1/Controllers/LinksController.cs +++ b/source/Gnomeshade.WebApi/V1/Controllers/LinksController.cs @@ -23,17 +23,9 @@ namespace Gnomeshade.WebApi.V1.Controllers; /// CRUD operations on link entity. -public sealed class LinksController : CreatableBase +public sealed class LinksController(Mapper mapper, LinkRepository repository, DbConnection dbConnection) + : CreatableBase(mapper, repository, dbConnection) { - /// Initializes a new instance of the class. - /// Repository entity and API model mapper. - /// The repository for performing CRUD operations on . - /// Database connection for transaction management. - public LinksController(Mapper mapper, LinkRepository repository, DbConnection dbConnection) - : base(mapper, repository, dbConnection) - { - } - /// /// Successfully got all links. [ProducesResponseType>(Status200OK)] @@ -51,10 +43,12 @@ public override Task> Get(Guid id, CancellationToken cancella public override Task Put(Guid id, LinkCreation link) => base.Put(id, link); + // ReSharper disable once RedundantOverriddenMember + /// /// Link was successfully deleted. /// Link with the specified id does not exist. - // ReSharper disable once RedundantOverriddenMember + /// Link cannot be deleted because some other entity is still referencing it. public override Task Delete(Guid id) => base.Delete(id); diff --git a/source/Gnomeshade.WebApi/V1/Controllers/LoansController.cs b/source/Gnomeshade.WebApi/V1/Controllers/LoansController.cs index 935379eb6..7b6008f2f 100644 --- a/source/Gnomeshade.WebApi/V1/Controllers/LoansController.cs +++ b/source/Gnomeshade.WebApi/V1/Controllers/LoansController.cs @@ -22,22 +22,9 @@ namespace Gnomeshade.WebApi.V1.Controllers; /// CRUD operations on loan entity. [Obsolete] -public sealed class LoansController : TransactionItemController +public sealed class LoansController(Mapper mapper, LoanRepository repository, DbConnection dbConnection, TransactionRepository transactionRepository) + : TransactionItemController(mapper, repository, dbConnection, transactionRepository) { - /// Initializes a new instance of the class. - /// Repository entity and API model mapper. - /// The repository for performing CRUD operations on . - /// Database connection for transaction management. - /// Transaction repository for validation of transactions. - public LoansController( - Mapper mapper, - LoanRepository repository, - DbConnection dbConnection, - TransactionRepository transactionRepository) - : base(mapper, repository, dbConnection, transactionRepository) - { - } - /// Gets the specified loan. /// The id of the loan to get. /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. @@ -66,12 +53,14 @@ public override Task> Get(CancellationToken cancellationToken) => public override Task Put(Guid id, [FromBody] LoanCreation loan) => base.Put(id, loan); + // ReSharper disable once RedundantOverriddenMember + /// Deletes the specified loan. /// The id of the loan to delete. /// A representing the asynchronous operation. /// Loan was successfully deleted. /// Loan with the specified id does not exist. - // ReSharper disable once RedundantOverriddenMember + /// Loan cannot be deleted because some other entity is still referencing it. public override Task Delete(Guid id) => base.Delete(id); } diff --git a/source/Gnomeshade.WebApi/V1/Controllers/OwnersController.cs b/source/Gnomeshade.WebApi/V1/Controllers/OwnersController.cs index 60e85a39f..f621040ca 100644 --- a/source/Gnomeshade.WebApi/V1/Controllers/OwnersController.cs +++ b/source/Gnomeshade.WebApi/V1/Controllers/OwnersController.cs @@ -22,20 +22,9 @@ namespace Gnomeshade.WebApi.V1.Controllers; /// CRUD operations on . -public sealed class OwnersController : CreatableBase +public sealed class OwnersController(Mapper mapper, OwnerRepository repository, DbConnection dbConnection) + : CreatableBase(mapper, repository, dbConnection) { - private readonly OwnerRepository _repository; - - /// Initializes a new instance of the class. - /// Repository entity and API model mapper. - /// The repository for performing CRUD operations on . - /// Database connection for transaction management. - public OwnersController(Mapper mapper, OwnerRepository repository, DbConnection dbConnection) - : base(mapper, repository, dbConnection) - { - _repository = repository; - } - /// /// Successfully got the owners. [ProducesResponseType>(Status200OK)] @@ -49,9 +38,12 @@ public override Task> Get(CancellationToken cancellationToken) => public override Task Put(Guid id, OwnerCreation owner) => base.Put(id, owner); - /// - /// The owner was deleted successfully. // ReSharper disable once RedundantOverriddenMember + + /// + /// Owner was deleted successfully. + /// Owner with the specified id does not exist. + /// Owner cannot be deleted because some other entity is still referencing it. public override Task Delete(Guid id) => base.Delete(id); @@ -71,7 +63,7 @@ protected override async Task CreateNewAsync(Guid id, OwnerCreatio CreatedByUserId = ApplicationUser.Id, }; - await _repository.AddAsync(owner); + await Repository.AddAsync(owner); return CreatedAtAction(nameof(Get), new { id }, id); } } diff --git a/source/Gnomeshade.WebApi/V1/Controllers/OwnershipsController.cs b/source/Gnomeshade.WebApi/V1/Controllers/OwnershipsController.cs index bdc5cccb6..90093e2d3 100644 --- a/source/Gnomeshade.WebApi/V1/Controllers/OwnershipsController.cs +++ b/source/Gnomeshade.WebApi/V1/Controllers/OwnershipsController.cs @@ -22,20 +22,9 @@ namespace Gnomeshade.WebApi.V1.Controllers; /// Resource access management. -public sealed class OwnershipsController : CreatableBase +public sealed class OwnershipsController(Mapper mapper, OwnershipRepository repository, DbConnection dbConnection) + : CreatableBase(mapper, repository, dbConnection) { - private readonly OwnershipRepository _repository; - - /// Initializes a new instance of the class. - /// Repository entity and API model mapper. - /// The repository for performing CRUD operations on . - /// Database connection for transaction management. - public OwnershipsController(Mapper mapper, OwnershipRepository repository, DbConnection dbConnection) - : base(mapper, repository, dbConnection) - { - _repository = repository; - } - /// /// Successfully got all ownerships. [ProducesResponseType>(Status200OK)] @@ -48,9 +37,12 @@ public override Task> Get(CancellationToken cancellationToken) = public override Task Put(Guid id, OwnershipCreation ownership) => base.Put(id, ownership); - /// - /// The ownership was deleted successfully. // ReSharper disable once RedundantOverriddenMember + + /// + /// Ownership was deleted successfully. + /// Ownership with the specified id does not exist. + /// Ownership cannot be deleted because some other entity is still referencing it. public override Task Delete(Guid id) => base.Delete(id); @@ -72,7 +64,7 @@ protected override async Task UpdateExistingAsync( protected override async Task CreateNewAsync(Guid id, OwnershipCreation creation, UserEntity user) { var ownership = Mapper.Map(creation) with { Id = id }; - await _repository.AddAsync(ownership); + await Repository.AddAsync(ownership); return CreatedAtAction(nameof(Get), new { id }, id); } } diff --git a/source/Gnomeshade.WebApi/V1/Controllers/PurchasesController.cs b/source/Gnomeshade.WebApi/V1/Controllers/PurchasesController.cs index 8b63e2ce1..6ba1f2518 100644 --- a/source/Gnomeshade.WebApi/V1/Controllers/PurchasesController.cs +++ b/source/Gnomeshade.WebApi/V1/Controllers/PurchasesController.cs @@ -22,22 +22,9 @@ namespace Gnomeshade.WebApi.V1.Controllers; /// CRUD operations on purchase entity. -public sealed class PurchasesController : TransactionItemController +public sealed class PurchasesController(Mapper mapper, PurchaseRepository repository, DbConnection dbConnection, TransactionRepository transactionRepository) + : TransactionItemController(mapper, repository, dbConnection, transactionRepository) { - /// Initializes a new instance of the class. - /// Repository entity and API model mapper. - /// The repository for performing CRUD operations on . - /// Database connection for transaction management. - /// Transaction repository for validation of transactions. - public PurchasesController( - Mapper mapper, - PurchaseRepository repository, - DbConnection dbConnection, - TransactionRepository transactionRepository) - : base(mapper, repository, dbConnection, transactionRepository) - { - } - /// /// Successfully got the purchase. /// Purchase with the specified id does not exist. @@ -58,10 +45,12 @@ public override Task> Get(CancellationToken cancellationToken) => public override Task Put(Guid id, [FromBody] PurchaseCreation product) => base.Put(id, product); + // ReSharper disable once RedundantOverriddenMember + /// /// Purchase was successfully deleted. /// Purchase with the specified id does not exist. - // ReSharper disable once RedundantOverriddenMember + /// Purchase cannot be deleted because some other entity is still referencing it. public override Task Delete(Guid id) => base.Delete(id); } diff --git a/source/Gnomeshade.WebApi/V1/Controllers/TransactionsController.cs b/source/Gnomeshade.WebApi/V1/Controllers/TransactionsController.cs index 18f97f355..dd34cf9e7 100644 --- a/source/Gnomeshade.WebApi/V1/Controllers/TransactionsController.cs +++ b/source/Gnomeshade.WebApi/V1/Controllers/TransactionsController.cs @@ -146,10 +146,12 @@ public override Task Post([FromBody] TransactionCreation transacti public override Task Put(Guid id, [FromBody] TransactionCreation transaction) => base.Put(id, transaction); + // ReSharper disable once RedundantOverriddenMember + /// /// Transaction was successfully deleted. /// Transaction with the specified id does not exist. - // ReSharper disable once RedundantOverriddenMember + /// Transaction cannot be deleted because some other entity is still referencing it. public override Task Delete(Guid id) => base.Delete(id); diff --git a/source/Gnomeshade.WebApi/V1/Controllers/TransfersController.cs b/source/Gnomeshade.WebApi/V1/Controllers/TransfersController.cs index 5f607f6f4..7fa73df37 100644 --- a/source/Gnomeshade.WebApi/V1/Controllers/TransfersController.cs +++ b/source/Gnomeshade.WebApi/V1/Controllers/TransfersController.cs @@ -22,22 +22,9 @@ namespace Gnomeshade.WebApi.V1.Controllers; /// CRUD operations on transfer entity. -public sealed class TransfersController : TransactionItemController +public sealed class TransfersController(Mapper mapper, TransferRepository repository, DbConnection dbConnection, TransactionRepository transactionRepository) + : TransactionItemController(mapper, repository, dbConnection, transactionRepository) { - /// Initializes a new instance of the class. - /// Repository entity and API model mapper. - /// The repository for performing CRUD operations on . - /// Database connection for transaction management. - /// Transaction repository for validation of transactions. - public TransfersController( - Mapper mapper, - TransferRepository repository, - DbConnection dbConnection, - TransactionRepository transactionRepository) - : base(mapper, repository, dbConnection, transactionRepository) - { - } - /// /// Successfully got the transfer. /// Transfer with the specified id does not exist. @@ -58,10 +45,12 @@ public override Task> Get(CancellationToken cancellationToken) => public override Task Put(Guid id, [FromBody] TransferCreation product) => base.Put(id, product); + // ReSharper disable once RedundantOverriddenMember + /// /// Transfer was successfully deleted. /// Transfer with the specified id does not exist. - // ReSharper disable once RedundantOverriddenMember + /// Transfer cannot be deleted because some other entity is still referencing it. public override Task Delete(Guid id) => base.Delete(id); } diff --git a/source/Gnomeshade.WebApi/V2/Controllers/LoanPaymentsController.cs b/source/Gnomeshade.WebApi/V2/Controllers/LoanPaymentsController.cs index 0422f1572..63886cd80 100644 --- a/source/Gnomeshade.WebApi/V2/Controllers/LoanPaymentsController.cs +++ b/source/Gnomeshade.WebApi/V2/Controllers/LoanPaymentsController.cs @@ -23,17 +23,9 @@ namespace Gnomeshade.WebApi.V2.Controllers; /// CRUD operations on loan payment entity. -public sealed class LoanPaymentsController : CreatableBase +public sealed class LoanPaymentsController(Mapper mapper, LoanPaymentRepository repository, DbConnection dbConnection) + : CreatableBase(mapper, repository, dbConnection) { - /// Initializes a new instance of the class. - /// Repository entity and API model mapper. - /// The repository for performing CRUD operations on . - /// Database connection for transaction management. - public LoanPaymentsController(Mapper mapper, LoanPaymentRepository repository, DbConnection dbConnection) - : base(mapper, repository, dbConnection) - { - } - /// /// Successfully got the loan payment. /// Loan payment with the specified id does not exist. @@ -58,10 +50,12 @@ public override Task Post(LoanPaymentCreation loanPayment) => public override Task Put(Guid id, LoanPaymentCreation loanPayment) => base.Put(id, loanPayment); + // ReSharper disable once RedundantOverriddenMember + /// /// Loan payment was successfully deleted. /// Loan payment with the specified id does not exist. - // ReSharper disable once RedundantOverriddenMember + /// Loan payment cannot be deleted because some other entity is still referencing it. public override Task Delete(Guid id) => base.Delete(id); diff --git a/source/Gnomeshade.WebApi/V2/Controllers/LoansController.cs b/source/Gnomeshade.WebApi/V2/Controllers/LoansController.cs index c124896d2..8bb0017e3 100644 --- a/source/Gnomeshade.WebApi/V2/Controllers/LoansController.cs +++ b/source/Gnomeshade.WebApi/V2/Controllers/LoansController.cs @@ -63,10 +63,12 @@ public override Task Post(LoanCreation loan) => public override Task Put(Guid id, LoanCreation loan) => base.Put(id, loan); + // ReSharper disable once RedundantOverriddenMember + /// /// Loan was successfully deleted. /// Loan with the specified id does not exist. - // ReSharper disable once RedundantOverriddenMember + /// Loan cannot be deleted because some other entity is still referencing it. public override Task Delete(Guid id) => base.Delete(id); diff --git a/tests/Gnomeshade.Data.Tests.Integration/Currencies.cs b/tests/Gnomeshade.Data.Tests.Integration/Currencies.cs index b76f74d01..88f3a5f53 100644 --- a/tests/Gnomeshade.Data.Tests.Integration/Currencies.cs +++ b/tests/Gnomeshade.Data.Tests.Integration/Currencies.cs @@ -16,6 +16,9 @@ using JetBrains.Annotations; +using static JetBrains.Annotations.ImplicitUseKindFlags; +using static JetBrains.Annotations.ImplicitUseTargetFlags; + namespace Gnomeshade.Data.Tests.Integration; public sealed class Currencies @@ -40,7 +43,7 @@ public async Task GetCurrencyData() var data = csv .GetRecords() - .Where(row => row.NumericCode is not (203 or 978 or 826 or 191 or 428 or 985 or 643 or 840 or 752 or 191)) + .Where(row => row.NumericCode is not (203 or 978 or 826 or 191 or 428 or 985 or 643 or 840 or 752)) .Select(row => { row.Name = row.Name?.Replace("'", "''"); @@ -55,9 +58,7 @@ public async Task GetCurrencyData() values.Should().NotBeNullOrWhiteSpace(); } - [UsedImplicitly( - ImplicitUseKindFlags.InstantiatedNoFixedConstructorSignature | ImplicitUseKindFlags.Assign, - ImplicitUseTargetFlags.Members)] + [UsedImplicitly(InstantiatedNoFixedConstructorSignature | Assign, Members)] private sealed class Row { public string? Name { get; set; } diff --git a/tests/Gnomeshade.WebApi.Tests.Integration/OpenApiTests.ApiDefinition_ShouldBeExpected._swagger_v1_swagger.json.verified.txt b/tests/Gnomeshade.WebApi.Tests.Integration/OpenApiTests.ApiDefinition_ShouldBeExpected._swagger_v1_swagger.json.verified.txt index a2f0c4e3b..54010b4cc 100644 --- a/tests/Gnomeshade.WebApi.Tests.Integration/OpenApiTests.ApiDefinition_ShouldBeExpected._swagger_v1_swagger.json.verified.txt +++ b/tests/Gnomeshade.WebApi.Tests.Integration/OpenApiTests.ApiDefinition_ShouldBeExpected._swagger_v1_swagger.json.verified.txt @@ -3160,7 +3160,7 @@ } }, 409: { - description: Conflict, + description: Loan cannot be deleted because some other entity is still referencing it., content: { text/plain: { schema: {