From b637abede3df86fe4b45e5a46a3baf78ce97018a Mon Sep 17 00:00:00 2001 From: CesarD Date: Mon, 18 Dec 2023 20:58:09 +0100 Subject: [PATCH 01/21] FEAT: Implementation of #52 . --- .../Auth/Scopes.cs | 8 +- .../Controllers/FilesController.cs | 35 +- .../Controllers/ImagesController.cs | 75 - .../Controllers/ProductsController.cs | 71 + .../DTOs/Extensions/ProductExtensions.cs | 23 + .../DTOs/ProductCreateEditDto.cs | 8 + .../Monaco.Template.Backend.Api/Program.cs | 2 +- .../appsettings.json | 4 +- .../20231204192153_Init.Designer.cs | 1318 +++++++++++++++++ .../Migrations/20231204192153_Init.cs | 395 +++++ .../Migrations/AppDbContextModelSnapshot.cs | 1315 ++++++++++++++++ ...plication.Infrastructure.Migrations.csproj | 4 + .../CompanyEntityConfiguration.cs | 6 + .../ImageEntityConfiguration.cs | 29 +- .../ProductEntityConfiguration.cs | 47 + ....Backend.Application.Infrastructure.csproj | 2 +- .../Company/CreateCompanyHandlerTests.cs | 43 +- .../Company/CreateCompanyValidatorTests.cs | 56 +- .../Company/DeleteCompanyHandlerTests.cs | 92 +- .../Company/DeleteCompanyValidatorTests.cs | 2 +- .../Company/EditCompanyHandlerTests.cs | 33 +- .../Company/EditCompanyValidatorTests.cs | 78 +- .../Features/Company/GetCompanyByIdTests.cs | 2 +- .../Features/Company/GetCompanyPageTests.cs | 42 +- .../Features/Country/GetCountryByIdTests.cs | 2 +- .../Features/Country/GetCountryListTests.cs | 2 +- .../Features/File/CreateFileHandlerTests.cs | 90 ++ .../Features/File/CreateFileValidatorTests.cs | 61 + .../Product/CreateProductHandlerTests.cs | 65 + .../Product/CreateProductValidatorTests.cs | 389 +++++ .../Product/DeleteProductHandlerTests.cs | 64 + .../Product/DeleteProductValidatorTests.cs | 73 + .../Product/DownloadProductPictureTests.cs | 97 ++ .../Product/EditProductHandlerTests.cs | 80 + .../Product/EditProductValidatorTests.cs | 434 ++++++ .../Features/Product/GetProductByIdTests.cs | 50 + .../Features/Product/GetProductPageTests.cs | 79 + ....Template.Backend.Application.Tests.csproj | 4 + .../Services/FileServiceTests.cs | 480 +++++- .../DTOs/Extensions/FileExtensions.cs | 4 +- .../DTOs/Extensions/ProductExtensions.cs | 79 + .../DTOs/FileDownloadDto.cs | 3 - .../DTOs/ProductDto.cs | 11 + .../DependencyInjection/ApplicationOptions.cs | 4 +- .../ServiceCollectionExtensions.cs | 6 +- .../Features/Company/DeleteCompany.cs | 41 +- .../Features/File/CreateFile.cs | 22 +- .../Features/File/DeleteFile.cs | 43 - .../Features/File/DownloadFileById.cs | 41 - .../File/Extensions/FileExtensions.cs | 11 - .../Features/File/GetFileById.cs | 31 - .../Image/DownloadThumbnailByImageId.cs | 41 - .../Image/Extensions/ImageExtensions.cs | 19 - .../Features/Image/GetImageById.cs | 31 - .../Features/Image/GetThumbnailByImageId.cs | 31 - .../Features/Product/CreateProduct.cs | 90 ++ .../Features/Product/DeleteProduct.cs | 62 + .../Product/DownloadProductPicture.cs | 51 + .../Features/Product/EditProduct.cs | 106 ++ .../Extensions/ProductDataExtensions.cs | 21 + .../Features/Product/GetProductById.cs | 33 + .../Features/Product/GetProductPage.cs | 58 + ...Monaco.Template.Backend.Application.csproj | 9 +- .../Services/Contracts/IFileService.cs | 26 +- .../Services/FileService.cs | 341 ++--- .../MediatorExtensions.cs | 54 + .../Auth/Scopes.cs | 4 +- .../reverseProxy.json | 2 +- .../DTOs/FileDownloadDto.cs | 5 + .../Factories/Entities/AddressFactory.cs | 1 - .../Factories/Entities/DocumentFactory.cs | 45 + .../Factories/Entities/ImageFactory.cs | 84 ++ .../Factories/Entities/ProductFactory.cs | 62 + .../Factories/FixtureExtensions.cs | 10 +- .../CompanyTests.cs | 36 +- .../GpsPositionTests.cs | 28 + .../ProductTests.cs | 112 ++ .../Model/Company.cs | 15 + .../Model/File.cs | 2 +- .../Model/GpsPosition.cs | 27 + .../Model/Image.cs | 34 +- .../Model/ImageDimensions.cs | 24 + .../Model/Product.cs | 66 + .../Solution/Monaco.Template.Backend.sln | 6 +- 84 files changed, 6682 insertions(+), 810 deletions(-) delete mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Api/Controllers/ImagesController.cs create mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Api/Controllers/ProductsController.cs create mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Api/DTOs/Extensions/ProductExtensions.cs create mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Api/DTOs/ProductCreateEditDto.cs create mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure.Migrations/Migrations/20231204192153_Init.Designer.cs create mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure.Migrations/Migrations/20231204192153_Init.cs create mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure.Migrations/Migrations/AppDbContextModelSnapshot.cs create mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure/EntityConfigurations/ProductEntityConfiguration.cs create mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/File/CreateFileHandlerTests.cs create mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/File/CreateFileValidatorTests.cs create mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/CreateProductHandlerTests.cs create mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/CreateProductValidatorTests.cs create mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/DeleteProductHandlerTests.cs create mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/DeleteProductValidatorTests.cs create mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/DownloadProductPictureTests.cs create mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/EditProductHandlerTests.cs create mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/EditProductValidatorTests.cs create mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/GetProductByIdTests.cs create mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/GetProductPageTests.cs create mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Application/DTOs/Extensions/ProductExtensions.cs delete mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Application/DTOs/FileDownloadDto.cs create mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Application/DTOs/ProductDto.cs delete mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/File/DeleteFile.cs delete mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/File/DownloadFileById.cs delete mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/File/Extensions/FileExtensions.cs delete mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/File/GetFileById.cs delete mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Image/DownloadThumbnailByImageId.cs delete mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Image/Extensions/ImageExtensions.cs delete mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Image/GetImageById.cs delete mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Image/GetThumbnailByImageId.cs create mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/CreateProduct.cs create mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/DeleteProduct.cs create mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/DownloadProductPicture.cs create mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/EditProduct.cs create mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/Extensions/ProductDataExtensions.cs create mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/GetProductById.cs create mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/GetProductPage.cs create mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Common.Application/DTOs/FileDownloadDto.cs create mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Common.Tests/Factories/Entities/DocumentFactory.cs create mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Common.Tests/Factories/Entities/ImageFactory.cs create mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Common.Tests/Factories/Entities/ProductFactory.cs create mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/GpsPositionTests.cs create mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/ProductTests.cs create mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/GpsPosition.cs create mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/ImageDimensions.cs create mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/Product.cs diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Auth/Scopes.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Auth/Scopes.cs index 74b204d..615ed6b 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Auth/Scopes.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Auth/Scopes.cs @@ -5,18 +5,20 @@ public static class Scopes { public const string CompaniesRead = "companies:read"; public const string CompaniesWrite = "companies:write"; -#if filesSupport +#if !excludeFilesSupport public const string FilesRead = "files:read"; public const string FilesWrite = "files:write"; + public const string ProductsWrite = "products:write"; #endif public static List List => new() { CompaniesRead, CompaniesWrite, -#if filesSupport +#if !excludeFilesSupport FilesRead, - FilesWrite + FilesWrite, + ProductsWrite #endif }; } diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Controllers/FilesController.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Controllers/FilesController.cs index ec48099..e6834ca 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Controllers/FilesController.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Controllers/FilesController.cs @@ -1,8 +1,7 @@ -#if filesSupport +#if !excludeFilesSupport #if (!disableAuth) using Monaco.Template.Backend.Api.Auth; #endif -using Monaco.Template.Backend.Application.DTOs; using Monaco.Template.Backend.Application.Features.File; using Monaco.Template.Backend.Common.Api.Application; using MediatR; @@ -10,7 +9,6 @@ using Microsoft.AspNetCore.Authorization; #endif using Microsoft.AspNetCore.Mvc; -using System.Net; using Asp.Versioning; namespace Monaco.Template.Backend.Api.Controllers; @@ -35,36 +33,5 @@ public Task> Post([FromRoute] ApiVersion apiVersion, [FromFor ModelState, "api/v{0}/files/{1}", apiVersion); - - [HttpGet("{id:guid}")] - #if (!disableAuth) - [Authorize(Scopes.FilesRead)] - #endif - public Task> Get(Guid id) => - _mediator.ExecuteQueryAsync(new GetFileById.Query(id)); - - [HttpGet("{id:guid}/Download")] - #if (!disableAuth) - [Authorize(Scopes.FilesRead)] - #endif - [ProducesResponseType(typeof(FileContentResult), (int)HttpStatusCode.OK)] - [ProducesResponseType((int)HttpStatusCode.NotFound)] - public async Task Download(Guid id) - { - var result = await _mediator.Send(new DownloadFileById.Query(id)); - - if (result == null) - return NotFound(); - - return File(result.FileContent, result.ContentType, result.FileName); - } - - [HttpDelete("{id:guid}")] - #if (!disableAuth) - [Authorize(Scopes.FilesWrite)] - #endif - public Task Delete(Guid id) => - _mediator.ExecuteCommandAsync(new DeleteFile.Command(id), - ModelState); } #endif \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Controllers/ImagesController.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Controllers/ImagesController.cs deleted file mode 100644 index d9b357b..0000000 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Controllers/ImagesController.cs +++ /dev/null @@ -1,75 +0,0 @@ -#if filesSupport -#if (!disableAuth) -using Monaco.Template.Backend.Api.Auth; -#endif -using Monaco.Template.Backend.Application.DTOs; -using Monaco.Template.Backend.Application.Features.File; -using Monaco.Template.Backend.Application.Features.Image; -using MediatR; -#if (!disableAuth) -using Microsoft.AspNetCore.Authorization; -#endif -using Microsoft.AspNetCore.Mvc; -using System.Net; -using Monaco.Template.Backend.Common.Api.Application; - -namespace Monaco.Template.Backend.Api.Controllers; - -[Route("api/v{apiVersion:apiVersion}/[controller]")] -[ApiController] -public class ImagesController : ControllerBase -{ - private readonly IMediator _mediator; - - public ImagesController(IMediator mediator) - { - _mediator = mediator; - } - - [HttpGet("{id:guid}")] - #if (!disableAuth) - [Authorize(Scopes.FilesRead)] - #endif - public Task> Get(Guid id) => - _mediator.ExecuteQueryAsync(new GetImageById.Query(id)); - - [HttpGet("{id:guid}/Thumbnail")] - #if (!disableAuth) - [Authorize(Scopes.FilesRead)] - #endif - public Task> GetThumbnail(Guid id) => - _mediator.ExecuteQueryAsync(new GetThumbnailByImageId.Query(id)); - - [HttpGet("{id:guid}/Download")] - #if (!disableAuth) - [Authorize(Scopes.FilesRead)] - #endif - [ProducesResponseType(typeof(FileContentResult), (int)HttpStatusCode.OK)] - [ProducesResponseType((int)HttpStatusCode.NotFound)] - public async Task Download(Guid id) - { - var result = await _mediator.Send(new DownloadFileById.Query(id)); - - if (result is null) - return NotFound(); - - return File(result.FileContent, result.ContentType, result.FileName); - } - - [HttpGet("{id:guid}/Thumbnail/Download")] - #if (!disableAuth) - [Authorize(Scopes.FilesRead)] - #endif - [ProducesResponseType(typeof(FileContentResult), (int)HttpStatusCode.OK)] - [ProducesResponseType((int)HttpStatusCode.NotFound)] - public async Task DownloadThumbnail(Guid id) - { - var result = await _mediator.Send(new DownloadThumbnailByImageId.Query(id)); - - if (result is null) - return NotFound(); - - return File(result.FileContent, result.ContentType, result.FileName); - } -} -#endif \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Controllers/ProductsController.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Controllers/ProductsController.cs new file mode 100644 index 0000000..c7e1239 --- /dev/null +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Controllers/ProductsController.cs @@ -0,0 +1,71 @@ +using Asp.Versioning; +using MediatR; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Monaco.Template.Backend.Api.Auth; +using Monaco.Template.Backend.Api.DTOs; +using Monaco.Template.Backend.Api.DTOs.Extensions; +using Monaco.Template.Backend.Application.DTOs; +using Monaco.Template.Backend.Application.Features.Product; +using Monaco.Template.Backend.Common.Api.Application; +using Monaco.Template.Backend.Common.Api.Application.Enums; +using Monaco.Template.Backend.Common.Domain.Model; +using System.Net; + +namespace Monaco.Template.Backend.Api.Controllers; + +[Route("api/v{apiVersion:apiVersion}/[controller]")] +[ApiController] +public class ProductsController : ControllerBase +{ + private readonly IMediator _mediator; + + public ProductsController(IMediator mediator) + { + _mediator = mediator; + } + + [HttpGet] + [AllowAnonymous] + public Task>> Get() => + _mediator.ExecuteQueryAsync(new GetProductPage.Query(Request.Query)); + + [HttpGet("{id:guid}")] + [AllowAnonymous] + public Task> Get(Guid id) => + _mediator.ExecuteQueryAsync(new GetProductById.Query(id)); + + [HttpPost] + #if (!disableAuth) + [Authorize(Scopes.ProductsWrite)] + #endif + public Task> Post([FromRoute] ApiVersion apiVersion, [FromBody] ProductCreateEditDto dto) => + _mediator.ExecuteCommandAsync(dto.Map(), + ModelState, + "api/v{0}/Products/{1}", + apiVersion); + + [HttpPut("{id:guid}")] + #if (!disableAuth) + [Authorize(Scopes.ProductsWrite)] + #endif + public Task Put(Guid id, [FromBody] ProductCreateEditDto dto) => + _mediator.ExecuteCommandAsync(dto.Map(id), + ModelState, + ResponseType.NoContent); + + [HttpDelete("{id:guid}")] + #if (!disableAuth) + [Authorize(Scopes.ProductsWrite)] + #endif + public Task Delete(Guid id) => + _mediator.ExecuteCommandAsync(new DeleteProduct.Command(id), + ModelState); + + [HttpGet("{productId:guid}/Pictures/{pictureId:guid}")] + [AllowAnonymous] + [ProducesResponseType(typeof(FileContentResult), (int)HttpStatusCode.OK)] + [ProducesResponseType((int)HttpStatusCode.NotFound)] + public Task Download(Guid productId, Guid pictureId) => + _mediator.ExecuteFileDownloadAsync(new DownloadProductPicture.Query(productId, pictureId, Request.Query)); +} diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Api/DTOs/Extensions/ProductExtensions.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Api/DTOs/Extensions/ProductExtensions.cs new file mode 100644 index 0000000..e7f5cb7 --- /dev/null +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Api/DTOs/Extensions/ProductExtensions.cs @@ -0,0 +1,23 @@ +using Monaco.Template.Backend.Application.Features.Product; + +namespace Monaco.Template.Backend.Api.DTOs.Extensions; + +public static class ProductExtensions +{ + public static CreateProduct.Command Map(this ProductCreateEditDto value) => + new(value.Title, + value.Description, + value.Price, + value.CompanyId, + value.Pictures, + value.DefaultPictureId); + + public static EditProduct.Command Map(this ProductCreateEditDto value, Guid id) => + new(id, + value.Title, + value.Description, + value.Price, + value.CompanyId, + value.Pictures, + value.DefaultPictureId); +} \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Api/DTOs/ProductCreateEditDto.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Api/DTOs/ProductCreateEditDto.cs new file mode 100644 index 0000000..43fcbda --- /dev/null +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Api/DTOs/ProductCreateEditDto.cs @@ -0,0 +1,8 @@ +namespace Monaco.Template.Backend.Api.DTOs; + +public record ProductCreateEditDto(string Title, + string Description, + decimal Price, + Guid CompanyId, + Guid[] Pictures, + Guid DefaultPictureId); \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Program.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Program.cs index 8809179..8d06745 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Program.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Program.cs @@ -51,7 +51,7 @@ { options.EntityFramework.ConnectionString = configuration.GetConnectionString("AppDbContext")!; options.EntityFramework.EnableEfSensitiveLogging = bool.Parse(configuration["EnableEFSensitiveLogging"] ?? "false"); -#if filesSupport +#if !excludeFilesSupport options.BlobStorage.ConnectionString = configuration["BlobStorage:ConnectionString"]!; options.BlobStorage.ContainerName = configuration["BlobStorage:Container"]!; #endif diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Api/appsettings.json b/src/Content/Backend/Solution/Monaco.Template.Backend.Api/appsettings.json index c5d1a55..dead077 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Api/appsettings.json +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Api/appsettings.json @@ -30,9 +30,9 @@ }, //#endif - //#if (filesSupport) + //#if (!excludeFilesSupport) "BlobStorage": { - "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=monaco-template;AccountKey=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx==;EndpointSuffix=core.windows.net", + "ConnectionString": "UseDevelopmentStorage=true", "Container": "files-store" }, diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure.Migrations/Migrations/20231204192153_Init.Designer.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure.Migrations/Migrations/20231204192153_Init.Designer.cs new file mode 100644 index 0000000..2efa9a6 --- /dev/null +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure.Migrations/Migrations/20231204192153_Init.Designer.cs @@ -0,0 +1,1318 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Monaco.Template.Backend.Application.Infrastructure.Context; + +#nullable disable + +namespace Monaco.Template.Backend.Application.Infrastructure.Migrations.Migrations +{ + [DbContext(typeof(AppDbContext))] + [Migration("20231204192153_Init")] + partial class Init + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.0") + .HasAnnotation("Proxies:ChangeTracking", false) + .HasAnnotation("Proxies:CheckEquality", false) + .HasAnnotation("Proxies:LazyLoading", true) + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.Company", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("Version") + .IsConcurrencyToken() + .IsRequired() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("rowversion"); + + b.Property("WebSiteUrl") + .HasMaxLength(300) + .HasColumnType("nvarchar(300)"); + + b.HasKey("Id"); + + b.ToTable("Company"); + }); + + modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.Country", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.HasKey("Id"); + + b.ToTable("Country"); + + b.HasData( + new + { + Id = new Guid("5c064eff-a037-a6a3-06ec-92f662903af3"), + Name = "Afghanistan" + }, + new + { + Id = new Guid("a8b54a61-35d8-9b82-76e4-c709561d9952"), + Name = "Albania" + }, + new + { + Id = new Guid("9f420922-9842-0d2d-616d-dacee7c25db7"), + Name = "Algeria" + }, + new + { + Id = new Guid("26253117-7664-92a9-1a3c-b15cf4bf4c78"), + Name = "Andorra" + }, + new + { + Id = new Guid("ba510e09-5109-42a2-63f0-32d7ede12a5a"), + Name = "Angola" + }, + new + { + Id = new Guid("359da8da-68eb-9466-855d-f0f381f715b8"), + Name = "Antigua and Barbuda" + }, + new + { + Id = new Guid("01ec70b8-6aad-3770-a129-62c0fc294791"), + Name = "Argentina" + }, + new + { + Id = new Guid("7d62846b-1841-882f-1cc4-85e2edeea265"), + Name = "Armenia" + }, + new + { + Id = new Guid("269928e1-37c5-32e0-60c5-bc6da2b8240e"), + Name = "Australia" + }, + new + { + Id = new Guid("7fce71e6-a14d-5d96-2dc1-1fc6779e02d3"), + Name = "Austria" + }, + new + { + Id = new Guid("4cf81cef-66a5-a117-3297-884134e903ee"), + Name = "Azerbaijan" + }, + new + { + Id = new Guid("08b5d3d0-89ed-a66f-3175-05316ae4a309"), + Name = "Bahamas" + }, + new + { + Id = new Guid("d7bd1f34-6ef7-43a6-24ed-53bca003086c"), + Name = "Bahrain" + }, + new + { + Id = new Guid("0d69d315-2825-2d05-9c04-ba1ad47180ac"), + Name = "Bangladesh" + }, + new + { + Id = new Guid("52f81e1e-6903-88e8-199f-cfc5139b0c69"), + Name = "Barbados" + }, + new + { + Id = new Guid("52b13dd7-28fc-9bba-8d59-5c2209531bf5"), + Name = "Belarus" + }, + new + { + Id = new Guid("8b9ac6d0-2320-3f99-8db7-d78c5d53151a"), + Name = "Belgium" + }, + new + { + Id = new Guid("c12db9c7-7ca1-4aec-34f1-7d0bb4713ca8"), + Name = "Belize" + }, + new + { + Id = new Guid("e34dc09e-2df2-3661-90e1-f03154d45caf"), + Name = "Benin" + }, + new + { + Id = new Guid("cf59ee2f-144d-99ac-9048-eafaba1f4732"), + Name = "Bhutan" + }, + new + { + Id = new Guid("1a426c53-787f-527c-5471-c505d6403603"), + Name = "Bolivia" + }, + new + { + Id = new Guid("fae877c5-4806-05e8-2068-950cdcea6ba9"), + Name = "Bosnia and Herzegovina" + }, + new + { + Id = new Guid("e0276db5-123f-6028-9e3e-eb43f2e06c47"), + Name = "Botswana" + }, + new + { + Id = new Guid("72499e6c-80a1-32c3-2692-7216abe7815b"), + Name = "Brazil" + }, + new + { + Id = new Guid("ba408210-2ea9-8c6c-1d5d-7e33973f1c99"), + Name = "Brunei" + }, + new + { + Id = new Guid("99532f86-827d-39ba-1c01-b9795ec60bf4"), + Name = "Bulgaria" + }, + new + { + Id = new Guid("f16e701a-5dbf-a441-3305-20ac536d34dc"), + Name = "Burkina Faso" + }, + new + { + Id = new Guid("ff0258f4-35a2-220b-9d9d-f0fe28226cc3"), + Name = "Burundi" + }, + new + { + Id = new Guid("f8135306-1323-4f48-7a4b-8d0427cb075b"), + Name = "Côte d'Ivoire" + }, + new + { + Id = new Guid("4676b79b-461c-95de-9871-041d2e0b130b"), + Name = "Cabo Verde" + }, + new + { + Id = new Guid("42f62587-3470-5967-77e3-f9b0cf285d90"), + Name = "Cambodia" + }, + new + { + Id = new Guid("01deb5a8-6bd7-1879-9d4b-cb73dd0e9a97"), + Name = "Cameroon" + }, + new + { + Id = new Guid("ff7c5aa2-6b56-218e-491a-42f4c67ca4a9"), + Name = "Canada" + }, + new + { + Id = new Guid("77b88575-0e8c-82d0-72bf-06f638b7485f"), + Name = "Central African Republic" + }, + new + { + Id = new Guid("758d4f58-7371-36c1-26c2-fcdb993806eb"), + Name = "Chad" + }, + new + { + Id = new Guid("97c787c7-915b-4878-3aa2-6ca1eec02f65"), + Name = "Chile" + }, + new + { + Id = new Guid("003548f7-318a-6f99-8a27-d62963b64cb5"), + Name = "China" + }, + new + { + Id = new Guid("63a948ca-178b-93da-4fdd-e6be10b49a42"), + Name = "Colombia" + }, + new + { + Id = new Guid("6d2bc2ca-2f37-3698-7f08-b7b3eeda5bf5"), + Name = "Comoros" + }, + new + { + Id = new Guid("d9e7fd6d-77f2-8e76-0174-4c17df936d4e"), + Name = "Congo (Congo-Brazzaville)" + }, + new + { + Id = new Guid("16eded64-8619-2b73-682f-a703c1cb2d76"), + Name = "Costa Rica" + }, + new + { + Id = new Guid("7915a976-5224-94f8-232f-ac163a11630c"), + Name = "Croatia" + }, + new + { + Id = new Guid("b6ed03e6-096c-3f87-093d-f3ff4bf34c24"), + Name = "Cuba" + }, + new + { + Id = new Guid("d7506bd0-454d-1b83-39e0-905836535271"), + Name = "Cyprus" + }, + new + { + Id = new Guid("caf14a3d-777d-0ee5-63a9-1c3da4e81458"), + Name = "Czechia (Czech Republic)" + }, + new + { + Id = new Guid("da82e26d-40bd-0866-0822-3d5468a36c3e"), + Name = "Democratic Republic of the Congo" + }, + new + { + Id = new Guid("57dc70e9-17ec-995b-5a60-a7c029b1476a"), + Name = "Denmark" + }, + new + { + Id = new Guid("8c6486fe-2680-4725-1ef3-3d56e3100f08"), + Name = "Djibouti" + }, + new + { + Id = new Guid("d7e310ab-99c3-0a50-2ead-57a2823433ee"), + Name = "Dominica" + }, + new + { + Id = new Guid("555a4e83-0151-7a10-2072-6cc9f4ac77c1"), + Name = "Dominican Republic" + }, + new + { + Id = new Guid("2908f020-3d75-3f9a-1a7f-020d1f8d5553"), + Name = "Ecuador" + }, + new + { + Id = new Guid("89bd993a-4eaa-6bae-8cf9-22f766fa2a1e"), + Name = "Egypt" + }, + new + { + Id = new Guid("ab1e3408-7157-2629-29a5-fbd6a61d92a9"), + Name = "El Salvador" + }, + new + { + Id = new Guid("e58f3cfd-069a-4457-23ef-9df8d7fe9ba0"), + Name = "Equatorial Guinea" + }, + new + { + Id = new Guid("5e7808be-01a7-9495-2320-314ce20871f3"), + Name = "Eritrea" + }, + new + { + Id = new Guid("5198e2c0-8107-5bcf-90b4-0054eac52295"), + Name = "Estonia" + }, + new + { + Id = new Guid("cfa8f583-23d4-1475-57ea-ef72ae7b633f"), + Name = "Eswatini (fmr. \"Swaziland\")" + }, + new + { + Id = new Guid("637e0fb3-34ed-6a1b-7524-3d6cd3155d35"), + Name = "Ethiopia" + }, + new + { + Id = new Guid("6459ce24-8398-57e0-4a31-48addb374e6d"), + Name = "Fiji" + }, + new + { + Id = new Guid("d726f074-4b1d-3043-39eb-f9b4ab9b2344"), + Name = "Finland" + }, + new + { + Id = new Guid("a5d734a1-021d-9b50-6fd4-b8f24bb96b12"), + Name = "France" + }, + new + { + Id = new Guid("a64406fb-51f7-2ed2-31af-847f9cf16783"), + Name = "Gabon" + }, + new + { + Id = new Guid("967f775b-3c8b-889d-5189-ee71f59f520e"), + Name = "Gambia" + }, + new + { + Id = new Guid("914f8571-1cac-3f1b-14ef-71aa91836616"), + Name = "Georgia" + }, + new + { + Id = new Guid("d4249520-8674-a2c1-0084-683d7aea64db"), + Name = "Germany" + }, + new + { + Id = new Guid("4fa88e4e-344a-32f8-a5ef-4ef2c33858d2"), + Name = "Ghana" + }, + new + { + Id = new Guid("a9fe165c-96e6-6bdf-99b0-68f7b2972ef6"), + Name = "Greece" + }, + new + { + Id = new Guid("6dfb0c67-2ab9-a5bc-1c58-5eaf76016b9d"), + Name = "Grenada" + }, + new + { + Id = new Guid("c8f8a591-79c3-a19e-94dd-1c96ed1aa23a"), + Name = "Guatemala" + }, + new + { + Id = new Guid("b0ac51a0-0128-4070-a49f-19b3dc5e8135"), + Name = "Guinea" + }, + new + { + Id = new Guid("d9060b41-6ea0-8efa-1dfe-ce293774947b"), + Name = "Guinea-Bissau" + }, + new + { + Id = new Guid("c79ec6ec-2f3d-0c12-8658-5ccbc1a20a77"), + Name = "Guyana" + }, + new + { + Id = new Guid("60a26e14-90ee-5838-4d27-3672a8e88c48"), + Name = "Haiti" + }, + new + { + Id = new Guid("a2c0a247-350e-85e6-9009-8106f5fd49b2"), + Name = "Holy See" + }, + new + { + Id = new Guid("d2300477-7258-17b8-7e8a-cf65f06a325f"), + Name = "Honduras" + }, + new + { + Id = new Guid("81f4a56e-5d53-47f3-52c3-2cd843434126"), + Name = "Hungary" + }, + new + { + Id = new Guid("9c239e38-640c-3fb2-0bc8-8edaace24c70"), + Name = "Iceland" + }, + new + { + Id = new Guid("a0d1f65e-307d-59fa-7792-24a5f0359889"), + Name = "India" + }, + new + { + Id = new Guid("5b9d725f-4e89-0181-74ae-ba87e96590d7"), + Name = "Indonesia" + }, + new + { + Id = new Guid("afa8b53f-45e6-391f-1c60-db81be664b1b"), + Name = "Iran" + }, + new + { + Id = new Guid("59bee04d-32a1-1e53-4a1b-599671a4a693"), + Name = "Iraq" + }, + new + { + Id = new Guid("18bd53bd-3519-69ef-1148-3453ad744c0f"), + Name = "Ireland" + }, + new + { + Id = new Guid("6704c135-5af7-88e9-16a5-ad4656fa1be2"), + Name = "Israel" + }, + new + { + Id = new Guid("cf1fcfbe-11fa-7009-0d71-d2cf5c80a334"), + Name = "Italy" + }, + new + { + Id = new Guid("038fb0db-7012-50fb-9ace-3b9f240d9627"), + Name = "Jamaica" + }, + new + { + Id = new Guid("12d9457c-1c12-9961-60cf-ec2ee534843a"), + Name = "Japan" + }, + new + { + Id = new Guid("aa9d471d-3f2f-5d42-3d01-443a83c12f59"), + Name = "Jordan" + }, + new + { + Id = new Guid("7708a52a-1d62-8f8b-0a4d-6028ed834994"), + Name = "Kazakhstan" + }, + new + { + Id = new Guid("f27f4ccb-4e04-8e05-456e-621788247647"), + Name = "Kenya" + }, + new + { + Id = new Guid("c7fc5498-271d-1027-343a-1560793d1c26"), + Name = "Kiribati" + }, + new + { + Id = new Guid("ee007dac-7417-54e4-18c2-ec6a678ba130"), + Name = "Kuwait" + }, + new + { + Id = new Guid("20bfffe5-7601-63e6-3574-9346e80d5d5c"), + Name = "Kyrgyzstan" + }, + new + { + Id = new Guid("6a5e5c1a-4d04-237e-8415-a7f93945133b"), + Name = "Laos" + }, + new + { + Id = new Guid("1e2e1979-539d-128f-538e-c30b8ba49b42"), + Name = "Latvia" + }, + new + { + Id = new Guid("29e7cce5-28a0-990c-6ded-54e96cad9caa"), + Name = "Lebanon" + }, + new + { + Id = new Guid("dbe19dde-374b-68a8-41e0-48d5195aa6f5"), + Name = "Lesotho" + }, + new + { + Id = new Guid("2092625a-45e4-166e-53cf-bb48408f1b09"), + Name = "Liberia" + }, + new + { + Id = new Guid("9d8cf3fc-222d-a56c-211b-8e8e9edf54e0"), + Name = "Libya" + }, + new + { + Id = new Guid("b232a961-1224-244f-27a1-06cba2046c22"), + Name = "Liechtenstein" + }, + new + { + Id = new Guid("a681eaeb-1fa0-12d7-93fb-e33a13c188e9"), + Name = "Lithuania" + }, + new + { + Id = new Guid("5ee9fcd4-5680-3cb4-1174-d85201e82367"), + Name = "Luxembourg" + }, + new + { + Id = new Guid("408f1ee6-42d3-a211-67c5-32f601b79bd9"), + Name = "Madagascar" + }, + new + { + Id = new Guid("341651be-9d9c-206b-9162-aad732979787"), + Name = "Malawi" + }, + new + { + Id = new Guid("40563307-5fe1-97d4-9d10-d81af5138548"), + Name = "Malaysia" + }, + new + { + Id = new Guid("43da6311-4ed9-9a74-9a46-82847f79a7c3"), + Name = "Maldives" + }, + new + { + Id = new Guid("c3700331-07c2-264c-2335-ba61bc718cac"), + Name = "Mali" + }, + new + { + Id = new Guid("1e3241f2-78b6-56e8-4c2d-4a50647973cf"), + Name = "Malta" + }, + new + { + Id = new Guid("bdf3f266-9570-2bb9-330f-9ea51c927068"), + Name = "Marshall Islands" + }, + new + { + Id = new Guid("572563f8-2f44-603d-857e-3f8230035e82"), + Name = "Mauritania" + }, + new + { + Id = new Guid("e8b389a9-0afd-4904-46af-464012f102c2"), + Name = "Mauritius" + }, + new + { + Id = new Guid("2f7432c5-405f-3f99-4bc3-35e318bd66cc"), + Name = "Mexico" + }, + new + { + Id = new Guid("94e831a3-3e52-7bb4-7616-dc0ac75c2d1d"), + Name = "Micronesia" + }, + new + { + Id = new Guid("abe01fc7-a484-7a8e-74b6-c5fa27554505"), + Name = "Moldova" + }, + new + { + Id = new Guid("6a265dd9-314e-2eb2-a4f8-3faf9c11a39d"), + Name = "Monaco" + }, + new + { + Id = new Guid("a484eabd-775b-4b7d-595b-3f5d857f5052"), + Name = "Mongolia" + }, + new + { + Id = new Guid("46fd6123-5206-2c2c-2832-953d13847069"), + Name = "Montenegro" + }, + new + { + Id = new Guid("09ee26e3-5c82-221e-0729-e47d663a949c"), + Name = "Morocco" + }, + new + { + Id = new Guid("aa6f7328-8f52-9bd1-0bba-9fb4f18a926e"), + Name = "Mozambique" + }, + new + { + Id = new Guid("4ebfeb1d-67d6-2499-5346-740f737100ee"), + Name = "Myanmar (formerly Burma)" + }, + new + { + Id = new Guid("aa29ea0b-2681-3475-6e16-1b7d164b081a"), + Name = "Namibia" + }, + new + { + Id = new Guid("d9a21a29-a0e2-71bc-7308-548cc27b19f1"), + Name = "Nauru" + }, + new + { + Id = new Guid("2c4ab1fa-60da-7c87-35b3-ac6903455853"), + Name = "Nepal" + }, + new + { + Id = new Guid("cb245d05-3293-7315-7ee1-eef8a383319c"), + Name = "Netherlands" + }, + new + { + Id = new Guid("472e0e57-77f5-9c34-8e10-a621c97108f7"), + Name = "New Zealand" + }, + new + { + Id = new Guid("350dc86e-03b2-2c20-1908-b4de7d179de7"), + Name = "Nicaragua" + }, + new + { + Id = new Guid("9b36a6c2-4739-69a2-068b-c0b3c87c6f67"), + Name = "Niger" + }, + new + { + Id = new Guid("2ca00749-35c0-511b-9c2c-b53e5a8f0a71"), + Name = "Nigeria" + }, + new + { + Id = new Guid("10ef2f04-4d96-5b5e-316f-b373a88731be"), + Name = "North Korea" + }, + new + { + Id = new Guid("51c38ab5-0b2b-2994-4eb2-c8e82fe17950"), + Name = "North Macedonia" + }, + new + { + Id = new Guid("c1c8ec1f-58ce-3931-7ad7-ad4b55c14a85"), + Name = "Norway" + }, + new + { + Id = new Guid("859adf7d-1bf9-87d1-6a9b-4a06ebab6796"), + Name = "Oman" + }, + new + { + Id = new Guid("6133196d-26d0-5f8e-5792-6215aefd668d"), + Name = "Pakistan" + }, + new + { + Id = new Guid("3881b3b6-a332-3d35-8a73-43acfbf9045b"), + Name = "Palau" + }, + new + { + Id = new Guid("9a79f7fb-27a4-811b-88c3-9de906521017"), + Name = "Palestine State" + }, + new + { + Id = new Guid("f5b0c42e-3b0e-3808-1922-fdae58ea075c"), + Name = "Panama" + }, + new + { + Id = new Guid("16ff3157-a061-2e81-5ca6-b71e3619376e"), + Name = "Papua New Guinea" + }, + new + { + Id = new Guid("1b84f08e-8e6d-5779-967c-a162c2307153"), + Name = "Paraguay" + }, + new + { + Id = new Guid("f625e01e-4a07-7ff3-0a7e-ce6e27b586ff"), + Name = "Peru" + }, + new + { + Id = new Guid("19be2963-072b-2f4b-0f85-558d90ee1770"), + Name = "Philippines" + }, + new + { + Id = new Guid("fc432d5c-66dd-5660-8186-da84b4e164a0"), + Name = "Poland" + }, + new + { + Id = new Guid("2b1486b9-0cfa-2dc6-3f70-4ee2f11955b4"), + Name = "Portugal" + }, + new + { + Id = new Guid("47ac0edf-9beb-345b-0e4b-bccb0c1a2032"), + Name = "Qatar" + }, + new + { + Id = new Guid("d5cb2660-9af9-0385-8a99-52871814043d"), + Name = "Romania" + }, + new + { + Id = new Guid("6fa56ae5-2091-39c4-0010-ae74ffa2a0f2"), + Name = "Russia" + }, + new + { + Id = new Guid("362ac8d8-6fba-a641-8272-958f9e553b54"), + Name = "Rwanda" + }, + new + { + Id = new Guid("c3553d72-9d17-04d8-6692-12a5a7250008"), + Name = "Saint Kitts and Nevis" + }, + new + { + Id = new Guid("fd3ab0e3-279a-107a-88e0-93ee1bb45ffb"), + Name = "Saint Lucia" + }, + new + { + Id = new Guid("420b0acb-a1b0-27e5-45fc-3c6e96f25361"), + Name = "Saint Vincent and the Grenadines" + }, + new + { + Id = new Guid("37425b6c-2940-370c-805d-27cb7af97f88"), + Name = "Samoa" + }, + new + { + Id = new Guid("b6667319-a515-1cf5-7392-92e15c52438d"), + Name = "San Marino" + }, + new + { + Id = new Guid("75c8834a-67e9-9ee5-65bb-e2db6a937074"), + Name = "Sao Tome and Principe" + }, + new + { + Id = new Guid("1e9ab108-4d4b-1812-21d9-5c90d7d897ea"), + Name = "Saudi Arabia" + }, + new + { + Id = new Guid("3cb2d6c7-8bb5-191d-183d-b201063d5491"), + Name = "Senegal" + }, + new + { + Id = new Guid("1995e756-0e82-9463-1627-feeb766d2d0d"), + Name = "Serbia" + }, + new + { + Id = new Guid("1ff73b0c-27c4-9d4a-3d5b-ec77a6612d56"), + Name = "Seychelles" + }, + new + { + Id = new Guid("6df0d56f-3b4e-33fe-6d5f-74da585ea5d0"), + Name = "Sierra Leone" + }, + new + { + Id = new Guid("912f9045-7a3b-151b-2c06-19f899d1787a"), + Name = "Singapore" + }, + new + { + Id = new Guid("53e7d0fc-816f-59dd-7b4a-0ade62330830"), + Name = "Slovakia" + }, + new + { + Id = new Guid("a522756f-2fd9-48d1-7443-dd1546fd8b37"), + Name = "Slovenia" + }, + new + { + Id = new Guid("5f47ed3b-0b54-95aa-93e8-16bf035c9247"), + Name = "Solomon Islands" + }, + new + { + Id = new Guid("b58da294-9556-8ece-163f-3d89514017a7"), + Name = "Somalia" + }, + new + { + Id = new Guid("03a82f52-22d5-8259-1072-429791258b72"), + Name = "South Africa" + }, + new + { + Id = new Guid("55cafe8e-1585-278e-5736-bab16f1b1b8d"), + Name = "South Korea" + }, + new + { + Id = new Guid("9d2d676f-97fb-952c-06a9-09d4e9696631"), + Name = "South Sudan" + }, + new + { + Id = new Guid("534a826b-70ef-2128-1a4c-52e23b7d5447"), + Name = "Spain" + }, + new + { + Id = new Guid("932a43ac-56dc-951e-7de5-996314e92e9c"), + Name = "Sri Lanka" + }, + new + { + Id = new Guid("6c4a7b61-3bfd-4a47-95a3-0ca86c72521f"), + Name = "Sudan" + }, + new + { + Id = new Guid("9a0a2c1d-3475-3554-9d18-b11946af6086"), + Name = "Suriname" + }, + new + { + Id = new Guid("896ef05e-0fe4-92a6-229e-63d7a26e0625"), + Name = "Sweden" + }, + new + { + Id = new Guid("bb0b41a9-7363-5922-9ce0-939412a9036e"), + Name = "Switzerland" + }, + new + { + Id = new Guid("7b9c857e-3fbd-3d19-38cf-f204da39890c"), + Name = "Syria" + }, + new + { + Id = new Guid("d7cd92d3-4522-5a78-3533-816fc61a293f"), + Name = "Tajikistan" + }, + new + { + Id = new Guid("fa81562d-1bc4-944c-86a9-6cc5af502265"), + Name = "Tanzania" + }, + new + { + Id = new Guid("439e3108-0908-4d90-6f5c-1974362b74b1"), + Name = "Thailand" + }, + new + { + Id = new Guid("47e7cc9c-4368-8ab3-056b-66a1351c24cd"), + Name = "Timor-Leste" + }, + new + { + Id = new Guid("492a6eb7-5ca3-8e50-3559-c71205b71c3b"), + Name = "Togo" + }, + new + { + Id = new Guid("e376c876-6960-270c-8744-583fb7a72f55"), + Name = "Tonga" + }, + new + { + Id = new Guid("2f7c276f-4d0d-9368-4132-c04149924bb5"), + Name = "Trinidad and Tobago" + }, + new + { + Id = new Guid("93ba288b-2a62-1880-1e20-aeb705431890"), + Name = "Tunisia" + }, + new + { + Id = new Guid("c576d8f0-5300-2436-2d17-48b699214549"), + Name = "Turkey" + }, + new + { + Id = new Guid("a9c5d1ec-319a-085c-1ee3-80ae15bd27ed"), + Name = "Turkmenistan" + }, + new + { + Id = new Guid("95938676-73d1-2031-219d-dc67ba314bdf"), + Name = "Tuvalu" + }, + new + { + Id = new Guid("2cfae83c-0f45-72d1-4624-5af1e10e6147"), + Name = "Uganda" + }, + new + { + Id = new Guid("1b837dfa-0bda-54f3-918a-beef19f691e5"), + Name = "Ukraine" + }, + new + { + Id = new Guid("f7675604-4744-6d6f-a077-67a3e0c85324"), + Name = "United Arab Emirates" + }, + new + { + Id = new Guid("8f9ec4fb-916f-90ea-5162-f486a0fc0893"), + Name = "United Kingdom" + }, + new + { + Id = new Guid("ca111c84-983b-4525-054c-d14dee3a422c"), + Name = "United States of America" + }, + new + { + Id = new Guid("ee06c3ba-4e8c-95c3-88da-6be3f23b9aaa"), + Name = "Uruguay" + }, + new + { + Id = new Guid("2f02c930-1d71-8ca6-49e7-0d3679a522ea"), + Name = "Uzbekistan" + }, + new + { + Id = new Guid("28dc2817-94b4-955d-10bc-6a8793dd386c"), + Name = "Vanuatu" + }, + new + { + Id = new Guid("9c9e3bca-5880-437f-4f18-d6998d90173f"), + Name = "Venezuela" + }, + new + { + Id = new Guid("5a3893d1-1e36-310c-7633-8f36ffa26315"), + Name = "Vietnam" + }, + new + { + Id = new Guid("a2689ae3-3643-6250-a748-8f055cc72da8"), + Name = "Yemen" + }, + new + { + Id = new Guid("be447a08-0a85-5779-8c65-cf15c2c9a5a8"), + Name = "Zambia" + }, + new + { + Id = new Guid("c776f397-182b-6d0d-09f2-4e440dc093d3"), + Name = "Zimbabwe" + }); + }); + + modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.File", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ContentType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Discriminator") + .IsRequired() + .HasMaxLength(8) + .HasColumnType("nvarchar(8)"); + + b.Property("Extension") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("IsTemp") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(300) + .HasColumnType("nvarchar(300)"); + + b.Property("Size") + .HasColumnType("bigint"); + + b.Property("UploadedOn") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.ToTable("File", (string)null); + + b.HasDiscriminator("Discriminator").IsComplete(true).HasValue("File"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.Product", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CompanyId") + .HasColumnType("uniqueidentifier"); + + b.Property("DefaultPictureId") + .HasColumnType("uniqueidentifier"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("Price") + .HasPrecision(10, 2) + .HasColumnType("decimal(10,2)"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.HasKey("Id"); + + b.HasIndex("CompanyId"); + + b.HasIndex("DefaultPictureId") + .IsUnique(); + + b.HasIndex("Title"); + + b.ToTable("Product"); + }); + + modelBuilder.Entity("ProductPicture", b => + { + b.Property("PicturesId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("PicturesId", "ProductId"); + + b.HasIndex("PicturesId") + .IsUnique(); + + b.HasIndex("ProductId"); + + b.ToTable("ProductPicture"); + }); + + modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.Document", b => + { + b.HasBaseType("Monaco.Template.Backend.Domain.Model.File"); + + b.HasDiscriminator().HasValue("Document"); + }); + + modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.Image", b => + { + b.HasBaseType("Monaco.Template.Backend.Domain.Model.File"); + + b.Property("DateTaken") + .HasColumnType("datetime2"); + + b.Property("ThumbnailId") + .HasColumnType("uniqueidentifier"); + + b.HasIndex("ThumbnailId") + .IsUnique() + .HasFilter("[ThumbnailId] IS NOT NULL"); + + b.HasDiscriminator().HasValue("Image"); + }); + + modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.Company", b => + { + b.OwnsOne("Monaco.Template.Backend.Domain.Model.Address", "Address", b1 => + { + b1.Property("CompanyId") + .HasColumnType("uniqueidentifier"); + + b1.Property("City") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b1.Property("CountryId") + .HasColumnType("uniqueidentifier"); + + b1.Property("County") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b1.Property("PostCode") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b1.Property("Street") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b1.HasKey("CompanyId"); + + b1.HasIndex("CountryId"); + + b1.ToTable("Company"); + + b1.WithOwner() + .HasForeignKey("CompanyId"); + + b1.HasOne("Monaco.Template.Backend.Domain.Model.Country", "Country") + .WithMany() + .HasForeignKey("CountryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b1.Navigation("Country"); + }); + + b.Navigation("Address"); + }); + + modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.Product", b => + { + b.HasOne("Monaco.Template.Backend.Domain.Model.Company", "Company") + .WithMany("Products") + .HasForeignKey("CompanyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Monaco.Template.Backend.Domain.Model.Image", "DefaultPicture") + .WithOne() + .HasForeignKey("Monaco.Template.Backend.Domain.Model.Product", "DefaultPictureId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Company"); + + b.Navigation("DefaultPicture"); + }); + + modelBuilder.Entity("ProductPicture", b => + { + b.HasOne("Monaco.Template.Backend.Domain.Model.Image", null) + .WithMany() + .HasForeignKey("PicturesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Monaco.Template.Backend.Domain.Model.Product", null) + .WithMany() + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.ClientCascade) + .IsRequired(); + }); + + modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.Image", b => + { + b.HasOne("Monaco.Template.Backend.Domain.Model.Image", "Thumbnail") + .WithOne() + .HasForeignKey("Monaco.Template.Backend.Domain.Model.Image", "ThumbnailId"); + + b.OwnsOne("Monaco.Template.Backend.Domain.Model.GpsPosition", "Position", b1 => + { + b1.Property("ImageId") + .HasColumnType("uniqueidentifier"); + + b1.Property("Latitude") + .HasColumnType("real"); + + b1.Property("Longitude") + .HasColumnType("real"); + + b1.HasKey("ImageId"); + + b1.ToTable("File"); + + b1.WithOwner() + .HasForeignKey("ImageId"); + }); + + b.OwnsOne("Monaco.Template.Backend.Domain.Model.ImageDimensions", "Dimensions", b1 => + { + b1.Property("ImageId") + .HasColumnType("uniqueidentifier"); + + b1.Property("Height") + .HasColumnType("int"); + + b1.Property("Width") + .HasColumnType("int"); + + b1.HasKey("ImageId"); + + b1.ToTable("File"); + + b1.WithOwner() + .HasForeignKey("ImageId"); + }); + + b.Navigation("Dimensions") + .IsRequired(); + + b.Navigation("Position"); + + b.Navigation("Thumbnail"); + }); + + modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.Company", b => + { + b.Navigation("Products"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure.Migrations/Migrations/20231204192153_Init.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure.Migrations/Migrations/20231204192153_Init.cs new file mode 100644 index 0000000..1dcfb82 --- /dev/null +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure.Migrations/Migrations/20231204192153_Init.cs @@ -0,0 +1,395 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional + +namespace Monaco.Template.Backend.Application.Infrastructure.Migrations.Migrations +{ + /// + public partial class Init : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Country", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + Name = table.Column(type: "nvarchar(100)", maxLength: 100, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Country", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "File", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + Name = table.Column(type: "nvarchar(300)", maxLength: 300, nullable: false), + Extension = table.Column(type: "nvarchar(20)", maxLength: 20, nullable: false), + Size = table.Column(type: "bigint", nullable: false), + ContentType = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: false), + UploadedOn = table.Column(type: "datetime2", nullable: false), + IsTemp = table.Column(type: "bit", nullable: false), + Discriminator = table.Column(type: "nvarchar(8)", maxLength: 8, nullable: false), + DateTaken = table.Column(type: "datetime2", nullable: true), + Dimensions_Height = table.Column(type: "int", nullable: true), + Dimensions_Width = table.Column(type: "int", nullable: true), + Position_Latitude = table.Column(type: "real", nullable: true), + Position_Longitude = table.Column(type: "real", nullable: true), + ThumbnailId = table.Column(type: "uniqueidentifier", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_File", x => x.Id); + table.ForeignKey( + name: "FK_File_File_ThumbnailId", + column: x => x.ThumbnailId, + principalTable: "File", + principalColumn: "Id"); + }); + + migrationBuilder.CreateTable( + name: "Company", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + Name = table.Column(type: "nvarchar(100)", maxLength: 100, nullable: false), + Email = table.Column(type: "nvarchar(255)", maxLength: 255, nullable: false), + WebSiteUrl = table.Column(type: "nvarchar(300)", maxLength: 300, nullable: true), + Version = table.Column(type: "rowversion", rowVersion: true, nullable: false), + Address_Street = table.Column(type: "nvarchar(100)", maxLength: 100, nullable: true), + Address_City = table.Column(type: "nvarchar(100)", maxLength: 100, nullable: true), + Address_County = table.Column(type: "nvarchar(100)", maxLength: 100, nullable: true), + Address_PostCode = table.Column(type: "nvarchar(10)", maxLength: 10, nullable: true), + Address_CountryId = table.Column(type: "uniqueidentifier", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Company", x => x.Id); + table.ForeignKey( + name: "FK_Company_Country_Address_CountryId", + column: x => x.Address_CountryId, + principalTable: "Country", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Product", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + Title = table.Column(type: "nvarchar(100)", maxLength: 100, nullable: false), + Description = table.Column(type: "nvarchar(500)", maxLength: 500, nullable: false), + Price = table.Column(type: "decimal(10,2)", precision: 10, scale: 2, nullable: false), + CompanyId = table.Column(type: "uniqueidentifier", nullable: false), + DefaultPictureId = table.Column(type: "uniqueidentifier", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Product", x => x.Id); + table.ForeignKey( + name: "FK_Product_Company_CompanyId", + column: x => x.CompanyId, + principalTable: "Company", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Product_File_DefaultPictureId", + column: x => x.DefaultPictureId, + principalTable: "File", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ProductPicture", + columns: table => new + { + PicturesId = table.Column(type: "uniqueidentifier", nullable: false), + ProductId = table.Column(type: "uniqueidentifier", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ProductPicture", x => new { x.PicturesId, x.ProductId }); + table.ForeignKey( + name: "FK_ProductPicture_File_PicturesId", + column: x => x.PicturesId, + principalTable: "File", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_ProductPicture_Product_ProductId", + column: x => x.ProductId, + principalTable: "Product", + principalColumn: "Id"); + }); + + migrationBuilder.InsertData( + table: "Country", + columns: new[] { "Id", "Name" }, + values: new object[,] + { + { new Guid("003548f7-318a-6f99-8a27-d62963b64cb5"), "China" }, + { new Guid("01deb5a8-6bd7-1879-9d4b-cb73dd0e9a97"), "Cameroon" }, + { new Guid("01ec70b8-6aad-3770-a129-62c0fc294791"), "Argentina" }, + { new Guid("038fb0db-7012-50fb-9ace-3b9f240d9627"), "Jamaica" }, + { new Guid("03a82f52-22d5-8259-1072-429791258b72"), "South Africa" }, + { new Guid("08b5d3d0-89ed-a66f-3175-05316ae4a309"), "Bahamas" }, + { new Guid("09ee26e3-5c82-221e-0729-e47d663a949c"), "Morocco" }, + { new Guid("0d69d315-2825-2d05-9c04-ba1ad47180ac"), "Bangladesh" }, + { new Guid("10ef2f04-4d96-5b5e-316f-b373a88731be"), "North Korea" }, + { new Guid("12d9457c-1c12-9961-60cf-ec2ee534843a"), "Japan" }, + { new Guid("16eded64-8619-2b73-682f-a703c1cb2d76"), "Costa Rica" }, + { new Guid("16ff3157-a061-2e81-5ca6-b71e3619376e"), "Papua New Guinea" }, + { new Guid("18bd53bd-3519-69ef-1148-3453ad744c0f"), "Ireland" }, + { new Guid("1995e756-0e82-9463-1627-feeb766d2d0d"), "Serbia" }, + { new Guid("19be2963-072b-2f4b-0f85-558d90ee1770"), "Philippines" }, + { new Guid("1a426c53-787f-527c-5471-c505d6403603"), "Bolivia" }, + { new Guid("1b837dfa-0bda-54f3-918a-beef19f691e5"), "Ukraine" }, + { new Guid("1b84f08e-8e6d-5779-967c-a162c2307153"), "Paraguay" }, + { new Guid("1e2e1979-539d-128f-538e-c30b8ba49b42"), "Latvia" }, + { new Guid("1e3241f2-78b6-56e8-4c2d-4a50647973cf"), "Malta" }, + { new Guid("1e9ab108-4d4b-1812-21d9-5c90d7d897ea"), "Saudi Arabia" }, + { new Guid("1ff73b0c-27c4-9d4a-3d5b-ec77a6612d56"), "Seychelles" }, + { new Guid("2092625a-45e4-166e-53cf-bb48408f1b09"), "Liberia" }, + { new Guid("20bfffe5-7601-63e6-3574-9346e80d5d5c"), "Kyrgyzstan" }, + { new Guid("26253117-7664-92a9-1a3c-b15cf4bf4c78"), "Andorra" }, + { new Guid("269928e1-37c5-32e0-60c5-bc6da2b8240e"), "Australia" }, + { new Guid("28dc2817-94b4-955d-10bc-6a8793dd386c"), "Vanuatu" }, + { new Guid("2908f020-3d75-3f9a-1a7f-020d1f8d5553"), "Ecuador" }, + { new Guid("29e7cce5-28a0-990c-6ded-54e96cad9caa"), "Lebanon" }, + { new Guid("2b1486b9-0cfa-2dc6-3f70-4ee2f11955b4"), "Portugal" }, + { new Guid("2c4ab1fa-60da-7c87-35b3-ac6903455853"), "Nepal" }, + { new Guid("2ca00749-35c0-511b-9c2c-b53e5a8f0a71"), "Nigeria" }, + { new Guid("2cfae83c-0f45-72d1-4624-5af1e10e6147"), "Uganda" }, + { new Guid("2f02c930-1d71-8ca6-49e7-0d3679a522ea"), "Uzbekistan" }, + { new Guid("2f7432c5-405f-3f99-4bc3-35e318bd66cc"), "Mexico" }, + { new Guid("2f7c276f-4d0d-9368-4132-c04149924bb5"), "Trinidad and Tobago" }, + { new Guid("341651be-9d9c-206b-9162-aad732979787"), "Malawi" }, + { new Guid("350dc86e-03b2-2c20-1908-b4de7d179de7"), "Nicaragua" }, + { new Guid("359da8da-68eb-9466-855d-f0f381f715b8"), "Antigua and Barbuda" }, + { new Guid("362ac8d8-6fba-a641-8272-958f9e553b54"), "Rwanda" }, + { new Guid("37425b6c-2940-370c-805d-27cb7af97f88"), "Samoa" }, + { new Guid("3881b3b6-a332-3d35-8a73-43acfbf9045b"), "Palau" }, + { new Guid("3cb2d6c7-8bb5-191d-183d-b201063d5491"), "Senegal" }, + { new Guid("40563307-5fe1-97d4-9d10-d81af5138548"), "Malaysia" }, + { new Guid("408f1ee6-42d3-a211-67c5-32f601b79bd9"), "Madagascar" }, + { new Guid("420b0acb-a1b0-27e5-45fc-3c6e96f25361"), "Saint Vincent and the Grenadines" }, + { new Guid("42f62587-3470-5967-77e3-f9b0cf285d90"), "Cambodia" }, + { new Guid("439e3108-0908-4d90-6f5c-1974362b74b1"), "Thailand" }, + { new Guid("43da6311-4ed9-9a74-9a46-82847f79a7c3"), "Maldives" }, + { new Guid("4676b79b-461c-95de-9871-041d2e0b130b"), "Cabo Verde" }, + { new Guid("46fd6123-5206-2c2c-2832-953d13847069"), "Montenegro" }, + { new Guid("472e0e57-77f5-9c34-8e10-a621c97108f7"), "New Zealand" }, + { new Guid("47ac0edf-9beb-345b-0e4b-bccb0c1a2032"), "Qatar" }, + { new Guid("47e7cc9c-4368-8ab3-056b-66a1351c24cd"), "Timor-Leste" }, + { new Guid("492a6eb7-5ca3-8e50-3559-c71205b71c3b"), "Togo" }, + { new Guid("4cf81cef-66a5-a117-3297-884134e903ee"), "Azerbaijan" }, + { new Guid("4ebfeb1d-67d6-2499-5346-740f737100ee"), "Myanmar (formerly Burma)" }, + { new Guid("4fa88e4e-344a-32f8-a5ef-4ef2c33858d2"), "Ghana" }, + { new Guid("5198e2c0-8107-5bcf-90b4-0054eac52295"), "Estonia" }, + { new Guid("51c38ab5-0b2b-2994-4eb2-c8e82fe17950"), "North Macedonia" }, + { new Guid("52b13dd7-28fc-9bba-8d59-5c2209531bf5"), "Belarus" }, + { new Guid("52f81e1e-6903-88e8-199f-cfc5139b0c69"), "Barbados" }, + { new Guid("534a826b-70ef-2128-1a4c-52e23b7d5447"), "Spain" }, + { new Guid("53e7d0fc-816f-59dd-7b4a-0ade62330830"), "Slovakia" }, + { new Guid("555a4e83-0151-7a10-2072-6cc9f4ac77c1"), "Dominican Republic" }, + { new Guid("55cafe8e-1585-278e-5736-bab16f1b1b8d"), "South Korea" }, + { new Guid("572563f8-2f44-603d-857e-3f8230035e82"), "Mauritania" }, + { new Guid("57dc70e9-17ec-995b-5a60-a7c029b1476a"), "Denmark" }, + { new Guid("59bee04d-32a1-1e53-4a1b-599671a4a693"), "Iraq" }, + { new Guid("5a3893d1-1e36-310c-7633-8f36ffa26315"), "Vietnam" }, + { new Guid("5b9d725f-4e89-0181-74ae-ba87e96590d7"), "Indonesia" }, + { new Guid("5c064eff-a037-a6a3-06ec-92f662903af3"), "Afghanistan" }, + { new Guid("5e7808be-01a7-9495-2320-314ce20871f3"), "Eritrea" }, + { new Guid("5ee9fcd4-5680-3cb4-1174-d85201e82367"), "Luxembourg" }, + { new Guid("5f47ed3b-0b54-95aa-93e8-16bf035c9247"), "Solomon Islands" }, + { new Guid("60a26e14-90ee-5838-4d27-3672a8e88c48"), "Haiti" }, + { new Guid("6133196d-26d0-5f8e-5792-6215aefd668d"), "Pakistan" }, + { new Guid("637e0fb3-34ed-6a1b-7524-3d6cd3155d35"), "Ethiopia" }, + { new Guid("63a948ca-178b-93da-4fdd-e6be10b49a42"), "Colombia" }, + { new Guid("6459ce24-8398-57e0-4a31-48addb374e6d"), "Fiji" }, + { new Guid("6704c135-5af7-88e9-16a5-ad4656fa1be2"), "Israel" }, + { new Guid("6a265dd9-314e-2eb2-a4f8-3faf9c11a39d"), "Monaco" }, + { new Guid("6a5e5c1a-4d04-237e-8415-a7f93945133b"), "Laos" }, + { new Guid("6c4a7b61-3bfd-4a47-95a3-0ca86c72521f"), "Sudan" }, + { new Guid("6d2bc2ca-2f37-3698-7f08-b7b3eeda5bf5"), "Comoros" }, + { new Guid("6df0d56f-3b4e-33fe-6d5f-74da585ea5d0"), "Sierra Leone" }, + { new Guid("6dfb0c67-2ab9-a5bc-1c58-5eaf76016b9d"), "Grenada" }, + { new Guid("6fa56ae5-2091-39c4-0010-ae74ffa2a0f2"), "Russia" }, + { new Guid("72499e6c-80a1-32c3-2692-7216abe7815b"), "Brazil" }, + { new Guid("758d4f58-7371-36c1-26c2-fcdb993806eb"), "Chad" }, + { new Guid("75c8834a-67e9-9ee5-65bb-e2db6a937074"), "Sao Tome and Principe" }, + { new Guid("7708a52a-1d62-8f8b-0a4d-6028ed834994"), "Kazakhstan" }, + { new Guid("77b88575-0e8c-82d0-72bf-06f638b7485f"), "Central African Republic" }, + { new Guid("7915a976-5224-94f8-232f-ac163a11630c"), "Croatia" }, + { new Guid("7b9c857e-3fbd-3d19-38cf-f204da39890c"), "Syria" }, + { new Guid("7d62846b-1841-882f-1cc4-85e2edeea265"), "Armenia" }, + { new Guid("7fce71e6-a14d-5d96-2dc1-1fc6779e02d3"), "Austria" }, + { new Guid("81f4a56e-5d53-47f3-52c3-2cd843434126"), "Hungary" }, + { new Guid("859adf7d-1bf9-87d1-6a9b-4a06ebab6796"), "Oman" }, + { new Guid("896ef05e-0fe4-92a6-229e-63d7a26e0625"), "Sweden" }, + { new Guid("89bd993a-4eaa-6bae-8cf9-22f766fa2a1e"), "Egypt" }, + { new Guid("8b9ac6d0-2320-3f99-8db7-d78c5d53151a"), "Belgium" }, + { new Guid("8c6486fe-2680-4725-1ef3-3d56e3100f08"), "Djibouti" }, + { new Guid("8f9ec4fb-916f-90ea-5162-f486a0fc0893"), "United Kingdom" }, + { new Guid("912f9045-7a3b-151b-2c06-19f899d1787a"), "Singapore" }, + { new Guid("914f8571-1cac-3f1b-14ef-71aa91836616"), "Georgia" }, + { new Guid("932a43ac-56dc-951e-7de5-996314e92e9c"), "Sri Lanka" }, + { new Guid("93ba288b-2a62-1880-1e20-aeb705431890"), "Tunisia" }, + { new Guid("94e831a3-3e52-7bb4-7616-dc0ac75c2d1d"), "Micronesia" }, + { new Guid("95938676-73d1-2031-219d-dc67ba314bdf"), "Tuvalu" }, + { new Guid("967f775b-3c8b-889d-5189-ee71f59f520e"), "Gambia" }, + { new Guid("97c787c7-915b-4878-3aa2-6ca1eec02f65"), "Chile" }, + { new Guid("99532f86-827d-39ba-1c01-b9795ec60bf4"), "Bulgaria" }, + { new Guid("9a0a2c1d-3475-3554-9d18-b11946af6086"), "Suriname" }, + { new Guid("9a79f7fb-27a4-811b-88c3-9de906521017"), "Palestine State" }, + { new Guid("9b36a6c2-4739-69a2-068b-c0b3c87c6f67"), "Niger" }, + { new Guid("9c239e38-640c-3fb2-0bc8-8edaace24c70"), "Iceland" }, + { new Guid("9c9e3bca-5880-437f-4f18-d6998d90173f"), "Venezuela" }, + { new Guid("9d2d676f-97fb-952c-06a9-09d4e9696631"), "South Sudan" }, + { new Guid("9d8cf3fc-222d-a56c-211b-8e8e9edf54e0"), "Libya" }, + { new Guid("9f420922-9842-0d2d-616d-dacee7c25db7"), "Algeria" }, + { new Guid("a0d1f65e-307d-59fa-7792-24a5f0359889"), "India" }, + { new Guid("a2689ae3-3643-6250-a748-8f055cc72da8"), "Yemen" }, + { new Guid("a2c0a247-350e-85e6-9009-8106f5fd49b2"), "Holy See" }, + { new Guid("a484eabd-775b-4b7d-595b-3f5d857f5052"), "Mongolia" }, + { new Guid("a522756f-2fd9-48d1-7443-dd1546fd8b37"), "Slovenia" }, + { new Guid("a5d734a1-021d-9b50-6fd4-b8f24bb96b12"), "France" }, + { new Guid("a64406fb-51f7-2ed2-31af-847f9cf16783"), "Gabon" }, + { new Guid("a681eaeb-1fa0-12d7-93fb-e33a13c188e9"), "Lithuania" }, + { new Guid("a8b54a61-35d8-9b82-76e4-c709561d9952"), "Albania" }, + { new Guid("a9c5d1ec-319a-085c-1ee3-80ae15bd27ed"), "Turkmenistan" }, + { new Guid("a9fe165c-96e6-6bdf-99b0-68f7b2972ef6"), "Greece" }, + { new Guid("aa29ea0b-2681-3475-6e16-1b7d164b081a"), "Namibia" }, + { new Guid("aa6f7328-8f52-9bd1-0bba-9fb4f18a926e"), "Mozambique" }, + { new Guid("aa9d471d-3f2f-5d42-3d01-443a83c12f59"), "Jordan" }, + { new Guid("ab1e3408-7157-2629-29a5-fbd6a61d92a9"), "El Salvador" }, + { new Guid("abe01fc7-a484-7a8e-74b6-c5fa27554505"), "Moldova" }, + { new Guid("afa8b53f-45e6-391f-1c60-db81be664b1b"), "Iran" }, + { new Guid("b0ac51a0-0128-4070-a49f-19b3dc5e8135"), "Guinea" }, + { new Guid("b232a961-1224-244f-27a1-06cba2046c22"), "Liechtenstein" }, + { new Guid("b58da294-9556-8ece-163f-3d89514017a7"), "Somalia" }, + { new Guid("b6667319-a515-1cf5-7392-92e15c52438d"), "San Marino" }, + { new Guid("b6ed03e6-096c-3f87-093d-f3ff4bf34c24"), "Cuba" }, + { new Guid("ba408210-2ea9-8c6c-1d5d-7e33973f1c99"), "Brunei" }, + { new Guid("ba510e09-5109-42a2-63f0-32d7ede12a5a"), "Angola" }, + { new Guid("bb0b41a9-7363-5922-9ce0-939412a9036e"), "Switzerland" }, + { new Guid("bdf3f266-9570-2bb9-330f-9ea51c927068"), "Marshall Islands" }, + { new Guid("be447a08-0a85-5779-8c65-cf15c2c9a5a8"), "Zambia" }, + { new Guid("c12db9c7-7ca1-4aec-34f1-7d0bb4713ca8"), "Belize" }, + { new Guid("c1c8ec1f-58ce-3931-7ad7-ad4b55c14a85"), "Norway" }, + { new Guid("c3553d72-9d17-04d8-6692-12a5a7250008"), "Saint Kitts and Nevis" }, + { new Guid("c3700331-07c2-264c-2335-ba61bc718cac"), "Mali" }, + { new Guid("c576d8f0-5300-2436-2d17-48b699214549"), "Turkey" }, + { new Guid("c776f397-182b-6d0d-09f2-4e440dc093d3"), "Zimbabwe" }, + { new Guid("c79ec6ec-2f3d-0c12-8658-5ccbc1a20a77"), "Guyana" }, + { new Guid("c7fc5498-271d-1027-343a-1560793d1c26"), "Kiribati" }, + { new Guid("c8f8a591-79c3-a19e-94dd-1c96ed1aa23a"), "Guatemala" }, + { new Guid("ca111c84-983b-4525-054c-d14dee3a422c"), "United States of America" }, + { new Guid("caf14a3d-777d-0ee5-63a9-1c3da4e81458"), "Czechia (Czech Republic)" }, + { new Guid("cb245d05-3293-7315-7ee1-eef8a383319c"), "Netherlands" }, + { new Guid("cf1fcfbe-11fa-7009-0d71-d2cf5c80a334"), "Italy" }, + { new Guid("cf59ee2f-144d-99ac-9048-eafaba1f4732"), "Bhutan" }, + { new Guid("cfa8f583-23d4-1475-57ea-ef72ae7b633f"), "Eswatini (fmr. \"Swaziland\")" }, + { new Guid("d2300477-7258-17b8-7e8a-cf65f06a325f"), "Honduras" }, + { new Guid("d4249520-8674-a2c1-0084-683d7aea64db"), "Germany" }, + { new Guid("d5cb2660-9af9-0385-8a99-52871814043d"), "Romania" }, + { new Guid("d726f074-4b1d-3043-39eb-f9b4ab9b2344"), "Finland" }, + { new Guid("d7506bd0-454d-1b83-39e0-905836535271"), "Cyprus" }, + { new Guid("d7bd1f34-6ef7-43a6-24ed-53bca003086c"), "Bahrain" }, + { new Guid("d7cd92d3-4522-5a78-3533-816fc61a293f"), "Tajikistan" }, + { new Guid("d7e310ab-99c3-0a50-2ead-57a2823433ee"), "Dominica" }, + { new Guid("d9060b41-6ea0-8efa-1dfe-ce293774947b"), "Guinea-Bissau" }, + { new Guid("d9a21a29-a0e2-71bc-7308-548cc27b19f1"), "Nauru" }, + { new Guid("d9e7fd6d-77f2-8e76-0174-4c17df936d4e"), "Congo (Congo-Brazzaville)" }, + { new Guid("da82e26d-40bd-0866-0822-3d5468a36c3e"), "Democratic Republic of the Congo" }, + { new Guid("dbe19dde-374b-68a8-41e0-48d5195aa6f5"), "Lesotho" }, + { new Guid("e0276db5-123f-6028-9e3e-eb43f2e06c47"), "Botswana" }, + { new Guid("e34dc09e-2df2-3661-90e1-f03154d45caf"), "Benin" }, + { new Guid("e376c876-6960-270c-8744-583fb7a72f55"), "Tonga" }, + { new Guid("e58f3cfd-069a-4457-23ef-9df8d7fe9ba0"), "Equatorial Guinea" }, + { new Guid("e8b389a9-0afd-4904-46af-464012f102c2"), "Mauritius" }, + { new Guid("ee007dac-7417-54e4-18c2-ec6a678ba130"), "Kuwait" }, + { new Guid("ee06c3ba-4e8c-95c3-88da-6be3f23b9aaa"), "Uruguay" }, + { new Guid("f16e701a-5dbf-a441-3305-20ac536d34dc"), "Burkina Faso" }, + { new Guid("f27f4ccb-4e04-8e05-456e-621788247647"), "Kenya" }, + { new Guid("f5b0c42e-3b0e-3808-1922-fdae58ea075c"), "Panama" }, + { new Guid("f625e01e-4a07-7ff3-0a7e-ce6e27b586ff"), "Peru" }, + { new Guid("f7675604-4744-6d6f-a077-67a3e0c85324"), "United Arab Emirates" }, + { new Guid("f8135306-1323-4f48-7a4b-8d0427cb075b"), "Côte d'Ivoire" }, + { new Guid("fa81562d-1bc4-944c-86a9-6cc5af502265"), "Tanzania" }, + { new Guid("fae877c5-4806-05e8-2068-950cdcea6ba9"), "Bosnia and Herzegovina" }, + { new Guid("fc432d5c-66dd-5660-8186-da84b4e164a0"), "Poland" }, + { new Guid("fd3ab0e3-279a-107a-88e0-93ee1bb45ffb"), "Saint Lucia" }, + { new Guid("ff0258f4-35a2-220b-9d9d-f0fe28226cc3"), "Burundi" }, + { new Guid("ff7c5aa2-6b56-218e-491a-42f4c67ca4a9"), "Canada" } + }); + + migrationBuilder.CreateIndex( + name: "IX_Company_Address_CountryId", + table: "Company", + column: "Address_CountryId"); + + migrationBuilder.CreateIndex( + name: "IX_File_ThumbnailId", + table: "File", + column: "ThumbnailId", + unique: true, + filter: "[ThumbnailId] IS NOT NULL"); + + migrationBuilder.CreateIndex( + name: "IX_Product_CompanyId", + table: "Product", + column: "CompanyId"); + + migrationBuilder.CreateIndex( + name: "IX_Product_DefaultPictureId", + table: "Product", + column: "DefaultPictureId", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Product_Title", + table: "Product", + column: "Title"); + + migrationBuilder.CreateIndex( + name: "IX_ProductPicture_PicturesId", + table: "ProductPicture", + column: "PicturesId", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_ProductPicture_ProductId", + table: "ProductPicture", + column: "ProductId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "ProductPicture"); + + migrationBuilder.DropTable( + name: "Product"); + + migrationBuilder.DropTable( + name: "Company"); + + migrationBuilder.DropTable( + name: "File"); + + migrationBuilder.DropTable( + name: "Country"); + } + } +} diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure.Migrations/Migrations/AppDbContextModelSnapshot.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure.Migrations/Migrations/AppDbContextModelSnapshot.cs new file mode 100644 index 0000000..10d6b98 --- /dev/null +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure.Migrations/Migrations/AppDbContextModelSnapshot.cs @@ -0,0 +1,1315 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Monaco.Template.Backend.Application.Infrastructure.Context; + +#nullable disable + +namespace Monaco.Template.Backend.Application.Infrastructure.Migrations.Migrations +{ + [DbContext(typeof(AppDbContext))] + partial class AppDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.0") + .HasAnnotation("Proxies:ChangeTracking", false) + .HasAnnotation("Proxies:CheckEquality", false) + .HasAnnotation("Proxies:LazyLoading", true) + .HasAnnotation("Relational:MaxIdentifierLength", 128); + + SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); + + modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.Company", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("nvarchar(255)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.Property("Version") + .IsConcurrencyToken() + .IsRequired() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("rowversion"); + + b.Property("WebSiteUrl") + .HasMaxLength(300) + .HasColumnType("nvarchar(300)"); + + b.HasKey("Id"); + + b.ToTable("Company"); + }); + + modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.Country", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.HasKey("Id"); + + b.ToTable("Country"); + + b.HasData( + new + { + Id = new Guid("5c064eff-a037-a6a3-06ec-92f662903af3"), + Name = "Afghanistan" + }, + new + { + Id = new Guid("a8b54a61-35d8-9b82-76e4-c709561d9952"), + Name = "Albania" + }, + new + { + Id = new Guid("9f420922-9842-0d2d-616d-dacee7c25db7"), + Name = "Algeria" + }, + new + { + Id = new Guid("26253117-7664-92a9-1a3c-b15cf4bf4c78"), + Name = "Andorra" + }, + new + { + Id = new Guid("ba510e09-5109-42a2-63f0-32d7ede12a5a"), + Name = "Angola" + }, + new + { + Id = new Guid("359da8da-68eb-9466-855d-f0f381f715b8"), + Name = "Antigua and Barbuda" + }, + new + { + Id = new Guid("01ec70b8-6aad-3770-a129-62c0fc294791"), + Name = "Argentina" + }, + new + { + Id = new Guid("7d62846b-1841-882f-1cc4-85e2edeea265"), + Name = "Armenia" + }, + new + { + Id = new Guid("269928e1-37c5-32e0-60c5-bc6da2b8240e"), + Name = "Australia" + }, + new + { + Id = new Guid("7fce71e6-a14d-5d96-2dc1-1fc6779e02d3"), + Name = "Austria" + }, + new + { + Id = new Guid("4cf81cef-66a5-a117-3297-884134e903ee"), + Name = "Azerbaijan" + }, + new + { + Id = new Guid("08b5d3d0-89ed-a66f-3175-05316ae4a309"), + Name = "Bahamas" + }, + new + { + Id = new Guid("d7bd1f34-6ef7-43a6-24ed-53bca003086c"), + Name = "Bahrain" + }, + new + { + Id = new Guid("0d69d315-2825-2d05-9c04-ba1ad47180ac"), + Name = "Bangladesh" + }, + new + { + Id = new Guid("52f81e1e-6903-88e8-199f-cfc5139b0c69"), + Name = "Barbados" + }, + new + { + Id = new Guid("52b13dd7-28fc-9bba-8d59-5c2209531bf5"), + Name = "Belarus" + }, + new + { + Id = new Guid("8b9ac6d0-2320-3f99-8db7-d78c5d53151a"), + Name = "Belgium" + }, + new + { + Id = new Guid("c12db9c7-7ca1-4aec-34f1-7d0bb4713ca8"), + Name = "Belize" + }, + new + { + Id = new Guid("e34dc09e-2df2-3661-90e1-f03154d45caf"), + Name = "Benin" + }, + new + { + Id = new Guid("cf59ee2f-144d-99ac-9048-eafaba1f4732"), + Name = "Bhutan" + }, + new + { + Id = new Guid("1a426c53-787f-527c-5471-c505d6403603"), + Name = "Bolivia" + }, + new + { + Id = new Guid("fae877c5-4806-05e8-2068-950cdcea6ba9"), + Name = "Bosnia and Herzegovina" + }, + new + { + Id = new Guid("e0276db5-123f-6028-9e3e-eb43f2e06c47"), + Name = "Botswana" + }, + new + { + Id = new Guid("72499e6c-80a1-32c3-2692-7216abe7815b"), + Name = "Brazil" + }, + new + { + Id = new Guid("ba408210-2ea9-8c6c-1d5d-7e33973f1c99"), + Name = "Brunei" + }, + new + { + Id = new Guid("99532f86-827d-39ba-1c01-b9795ec60bf4"), + Name = "Bulgaria" + }, + new + { + Id = new Guid("f16e701a-5dbf-a441-3305-20ac536d34dc"), + Name = "Burkina Faso" + }, + new + { + Id = new Guid("ff0258f4-35a2-220b-9d9d-f0fe28226cc3"), + Name = "Burundi" + }, + new + { + Id = new Guid("f8135306-1323-4f48-7a4b-8d0427cb075b"), + Name = "Côte d'Ivoire" + }, + new + { + Id = new Guid("4676b79b-461c-95de-9871-041d2e0b130b"), + Name = "Cabo Verde" + }, + new + { + Id = new Guid("42f62587-3470-5967-77e3-f9b0cf285d90"), + Name = "Cambodia" + }, + new + { + Id = new Guid("01deb5a8-6bd7-1879-9d4b-cb73dd0e9a97"), + Name = "Cameroon" + }, + new + { + Id = new Guid("ff7c5aa2-6b56-218e-491a-42f4c67ca4a9"), + Name = "Canada" + }, + new + { + Id = new Guid("77b88575-0e8c-82d0-72bf-06f638b7485f"), + Name = "Central African Republic" + }, + new + { + Id = new Guid("758d4f58-7371-36c1-26c2-fcdb993806eb"), + Name = "Chad" + }, + new + { + Id = new Guid("97c787c7-915b-4878-3aa2-6ca1eec02f65"), + Name = "Chile" + }, + new + { + Id = new Guid("003548f7-318a-6f99-8a27-d62963b64cb5"), + Name = "China" + }, + new + { + Id = new Guid("63a948ca-178b-93da-4fdd-e6be10b49a42"), + Name = "Colombia" + }, + new + { + Id = new Guid("6d2bc2ca-2f37-3698-7f08-b7b3eeda5bf5"), + Name = "Comoros" + }, + new + { + Id = new Guid("d9e7fd6d-77f2-8e76-0174-4c17df936d4e"), + Name = "Congo (Congo-Brazzaville)" + }, + new + { + Id = new Guid("16eded64-8619-2b73-682f-a703c1cb2d76"), + Name = "Costa Rica" + }, + new + { + Id = new Guid("7915a976-5224-94f8-232f-ac163a11630c"), + Name = "Croatia" + }, + new + { + Id = new Guid("b6ed03e6-096c-3f87-093d-f3ff4bf34c24"), + Name = "Cuba" + }, + new + { + Id = new Guid("d7506bd0-454d-1b83-39e0-905836535271"), + Name = "Cyprus" + }, + new + { + Id = new Guid("caf14a3d-777d-0ee5-63a9-1c3da4e81458"), + Name = "Czechia (Czech Republic)" + }, + new + { + Id = new Guid("da82e26d-40bd-0866-0822-3d5468a36c3e"), + Name = "Democratic Republic of the Congo" + }, + new + { + Id = new Guid("57dc70e9-17ec-995b-5a60-a7c029b1476a"), + Name = "Denmark" + }, + new + { + Id = new Guid("8c6486fe-2680-4725-1ef3-3d56e3100f08"), + Name = "Djibouti" + }, + new + { + Id = new Guid("d7e310ab-99c3-0a50-2ead-57a2823433ee"), + Name = "Dominica" + }, + new + { + Id = new Guid("555a4e83-0151-7a10-2072-6cc9f4ac77c1"), + Name = "Dominican Republic" + }, + new + { + Id = new Guid("2908f020-3d75-3f9a-1a7f-020d1f8d5553"), + Name = "Ecuador" + }, + new + { + Id = new Guid("89bd993a-4eaa-6bae-8cf9-22f766fa2a1e"), + Name = "Egypt" + }, + new + { + Id = new Guid("ab1e3408-7157-2629-29a5-fbd6a61d92a9"), + Name = "El Salvador" + }, + new + { + Id = new Guid("e58f3cfd-069a-4457-23ef-9df8d7fe9ba0"), + Name = "Equatorial Guinea" + }, + new + { + Id = new Guid("5e7808be-01a7-9495-2320-314ce20871f3"), + Name = "Eritrea" + }, + new + { + Id = new Guid("5198e2c0-8107-5bcf-90b4-0054eac52295"), + Name = "Estonia" + }, + new + { + Id = new Guid("cfa8f583-23d4-1475-57ea-ef72ae7b633f"), + Name = "Eswatini (fmr. \"Swaziland\")" + }, + new + { + Id = new Guid("637e0fb3-34ed-6a1b-7524-3d6cd3155d35"), + Name = "Ethiopia" + }, + new + { + Id = new Guid("6459ce24-8398-57e0-4a31-48addb374e6d"), + Name = "Fiji" + }, + new + { + Id = new Guid("d726f074-4b1d-3043-39eb-f9b4ab9b2344"), + Name = "Finland" + }, + new + { + Id = new Guid("a5d734a1-021d-9b50-6fd4-b8f24bb96b12"), + Name = "France" + }, + new + { + Id = new Guid("a64406fb-51f7-2ed2-31af-847f9cf16783"), + Name = "Gabon" + }, + new + { + Id = new Guid("967f775b-3c8b-889d-5189-ee71f59f520e"), + Name = "Gambia" + }, + new + { + Id = new Guid("914f8571-1cac-3f1b-14ef-71aa91836616"), + Name = "Georgia" + }, + new + { + Id = new Guid("d4249520-8674-a2c1-0084-683d7aea64db"), + Name = "Germany" + }, + new + { + Id = new Guid("4fa88e4e-344a-32f8-a5ef-4ef2c33858d2"), + Name = "Ghana" + }, + new + { + Id = new Guid("a9fe165c-96e6-6bdf-99b0-68f7b2972ef6"), + Name = "Greece" + }, + new + { + Id = new Guid("6dfb0c67-2ab9-a5bc-1c58-5eaf76016b9d"), + Name = "Grenada" + }, + new + { + Id = new Guid("c8f8a591-79c3-a19e-94dd-1c96ed1aa23a"), + Name = "Guatemala" + }, + new + { + Id = new Guid("b0ac51a0-0128-4070-a49f-19b3dc5e8135"), + Name = "Guinea" + }, + new + { + Id = new Guid("d9060b41-6ea0-8efa-1dfe-ce293774947b"), + Name = "Guinea-Bissau" + }, + new + { + Id = new Guid("c79ec6ec-2f3d-0c12-8658-5ccbc1a20a77"), + Name = "Guyana" + }, + new + { + Id = new Guid("60a26e14-90ee-5838-4d27-3672a8e88c48"), + Name = "Haiti" + }, + new + { + Id = new Guid("a2c0a247-350e-85e6-9009-8106f5fd49b2"), + Name = "Holy See" + }, + new + { + Id = new Guid("d2300477-7258-17b8-7e8a-cf65f06a325f"), + Name = "Honduras" + }, + new + { + Id = new Guid("81f4a56e-5d53-47f3-52c3-2cd843434126"), + Name = "Hungary" + }, + new + { + Id = new Guid("9c239e38-640c-3fb2-0bc8-8edaace24c70"), + Name = "Iceland" + }, + new + { + Id = new Guid("a0d1f65e-307d-59fa-7792-24a5f0359889"), + Name = "India" + }, + new + { + Id = new Guid("5b9d725f-4e89-0181-74ae-ba87e96590d7"), + Name = "Indonesia" + }, + new + { + Id = new Guid("afa8b53f-45e6-391f-1c60-db81be664b1b"), + Name = "Iran" + }, + new + { + Id = new Guid("59bee04d-32a1-1e53-4a1b-599671a4a693"), + Name = "Iraq" + }, + new + { + Id = new Guid("18bd53bd-3519-69ef-1148-3453ad744c0f"), + Name = "Ireland" + }, + new + { + Id = new Guid("6704c135-5af7-88e9-16a5-ad4656fa1be2"), + Name = "Israel" + }, + new + { + Id = new Guid("cf1fcfbe-11fa-7009-0d71-d2cf5c80a334"), + Name = "Italy" + }, + new + { + Id = new Guid("038fb0db-7012-50fb-9ace-3b9f240d9627"), + Name = "Jamaica" + }, + new + { + Id = new Guid("12d9457c-1c12-9961-60cf-ec2ee534843a"), + Name = "Japan" + }, + new + { + Id = new Guid("aa9d471d-3f2f-5d42-3d01-443a83c12f59"), + Name = "Jordan" + }, + new + { + Id = new Guid("7708a52a-1d62-8f8b-0a4d-6028ed834994"), + Name = "Kazakhstan" + }, + new + { + Id = new Guid("f27f4ccb-4e04-8e05-456e-621788247647"), + Name = "Kenya" + }, + new + { + Id = new Guid("c7fc5498-271d-1027-343a-1560793d1c26"), + Name = "Kiribati" + }, + new + { + Id = new Guid("ee007dac-7417-54e4-18c2-ec6a678ba130"), + Name = "Kuwait" + }, + new + { + Id = new Guid("20bfffe5-7601-63e6-3574-9346e80d5d5c"), + Name = "Kyrgyzstan" + }, + new + { + Id = new Guid("6a5e5c1a-4d04-237e-8415-a7f93945133b"), + Name = "Laos" + }, + new + { + Id = new Guid("1e2e1979-539d-128f-538e-c30b8ba49b42"), + Name = "Latvia" + }, + new + { + Id = new Guid("29e7cce5-28a0-990c-6ded-54e96cad9caa"), + Name = "Lebanon" + }, + new + { + Id = new Guid("dbe19dde-374b-68a8-41e0-48d5195aa6f5"), + Name = "Lesotho" + }, + new + { + Id = new Guid("2092625a-45e4-166e-53cf-bb48408f1b09"), + Name = "Liberia" + }, + new + { + Id = new Guid("9d8cf3fc-222d-a56c-211b-8e8e9edf54e0"), + Name = "Libya" + }, + new + { + Id = new Guid("b232a961-1224-244f-27a1-06cba2046c22"), + Name = "Liechtenstein" + }, + new + { + Id = new Guid("a681eaeb-1fa0-12d7-93fb-e33a13c188e9"), + Name = "Lithuania" + }, + new + { + Id = new Guid("5ee9fcd4-5680-3cb4-1174-d85201e82367"), + Name = "Luxembourg" + }, + new + { + Id = new Guid("408f1ee6-42d3-a211-67c5-32f601b79bd9"), + Name = "Madagascar" + }, + new + { + Id = new Guid("341651be-9d9c-206b-9162-aad732979787"), + Name = "Malawi" + }, + new + { + Id = new Guid("40563307-5fe1-97d4-9d10-d81af5138548"), + Name = "Malaysia" + }, + new + { + Id = new Guid("43da6311-4ed9-9a74-9a46-82847f79a7c3"), + Name = "Maldives" + }, + new + { + Id = new Guid("c3700331-07c2-264c-2335-ba61bc718cac"), + Name = "Mali" + }, + new + { + Id = new Guid("1e3241f2-78b6-56e8-4c2d-4a50647973cf"), + Name = "Malta" + }, + new + { + Id = new Guid("bdf3f266-9570-2bb9-330f-9ea51c927068"), + Name = "Marshall Islands" + }, + new + { + Id = new Guid("572563f8-2f44-603d-857e-3f8230035e82"), + Name = "Mauritania" + }, + new + { + Id = new Guid("e8b389a9-0afd-4904-46af-464012f102c2"), + Name = "Mauritius" + }, + new + { + Id = new Guid("2f7432c5-405f-3f99-4bc3-35e318bd66cc"), + Name = "Mexico" + }, + new + { + Id = new Guid("94e831a3-3e52-7bb4-7616-dc0ac75c2d1d"), + Name = "Micronesia" + }, + new + { + Id = new Guid("abe01fc7-a484-7a8e-74b6-c5fa27554505"), + Name = "Moldova" + }, + new + { + Id = new Guid("6a265dd9-314e-2eb2-a4f8-3faf9c11a39d"), + Name = "Monaco" + }, + new + { + Id = new Guid("a484eabd-775b-4b7d-595b-3f5d857f5052"), + Name = "Mongolia" + }, + new + { + Id = new Guid("46fd6123-5206-2c2c-2832-953d13847069"), + Name = "Montenegro" + }, + new + { + Id = new Guid("09ee26e3-5c82-221e-0729-e47d663a949c"), + Name = "Morocco" + }, + new + { + Id = new Guid("aa6f7328-8f52-9bd1-0bba-9fb4f18a926e"), + Name = "Mozambique" + }, + new + { + Id = new Guid("4ebfeb1d-67d6-2499-5346-740f737100ee"), + Name = "Myanmar (formerly Burma)" + }, + new + { + Id = new Guid("aa29ea0b-2681-3475-6e16-1b7d164b081a"), + Name = "Namibia" + }, + new + { + Id = new Guid("d9a21a29-a0e2-71bc-7308-548cc27b19f1"), + Name = "Nauru" + }, + new + { + Id = new Guid("2c4ab1fa-60da-7c87-35b3-ac6903455853"), + Name = "Nepal" + }, + new + { + Id = new Guid("cb245d05-3293-7315-7ee1-eef8a383319c"), + Name = "Netherlands" + }, + new + { + Id = new Guid("472e0e57-77f5-9c34-8e10-a621c97108f7"), + Name = "New Zealand" + }, + new + { + Id = new Guid("350dc86e-03b2-2c20-1908-b4de7d179de7"), + Name = "Nicaragua" + }, + new + { + Id = new Guid("9b36a6c2-4739-69a2-068b-c0b3c87c6f67"), + Name = "Niger" + }, + new + { + Id = new Guid("2ca00749-35c0-511b-9c2c-b53e5a8f0a71"), + Name = "Nigeria" + }, + new + { + Id = new Guid("10ef2f04-4d96-5b5e-316f-b373a88731be"), + Name = "North Korea" + }, + new + { + Id = new Guid("51c38ab5-0b2b-2994-4eb2-c8e82fe17950"), + Name = "North Macedonia" + }, + new + { + Id = new Guid("c1c8ec1f-58ce-3931-7ad7-ad4b55c14a85"), + Name = "Norway" + }, + new + { + Id = new Guid("859adf7d-1bf9-87d1-6a9b-4a06ebab6796"), + Name = "Oman" + }, + new + { + Id = new Guid("6133196d-26d0-5f8e-5792-6215aefd668d"), + Name = "Pakistan" + }, + new + { + Id = new Guid("3881b3b6-a332-3d35-8a73-43acfbf9045b"), + Name = "Palau" + }, + new + { + Id = new Guid("9a79f7fb-27a4-811b-88c3-9de906521017"), + Name = "Palestine State" + }, + new + { + Id = new Guid("f5b0c42e-3b0e-3808-1922-fdae58ea075c"), + Name = "Panama" + }, + new + { + Id = new Guid("16ff3157-a061-2e81-5ca6-b71e3619376e"), + Name = "Papua New Guinea" + }, + new + { + Id = new Guid("1b84f08e-8e6d-5779-967c-a162c2307153"), + Name = "Paraguay" + }, + new + { + Id = new Guid("f625e01e-4a07-7ff3-0a7e-ce6e27b586ff"), + Name = "Peru" + }, + new + { + Id = new Guid("19be2963-072b-2f4b-0f85-558d90ee1770"), + Name = "Philippines" + }, + new + { + Id = new Guid("fc432d5c-66dd-5660-8186-da84b4e164a0"), + Name = "Poland" + }, + new + { + Id = new Guid("2b1486b9-0cfa-2dc6-3f70-4ee2f11955b4"), + Name = "Portugal" + }, + new + { + Id = new Guid("47ac0edf-9beb-345b-0e4b-bccb0c1a2032"), + Name = "Qatar" + }, + new + { + Id = new Guid("d5cb2660-9af9-0385-8a99-52871814043d"), + Name = "Romania" + }, + new + { + Id = new Guid("6fa56ae5-2091-39c4-0010-ae74ffa2a0f2"), + Name = "Russia" + }, + new + { + Id = new Guid("362ac8d8-6fba-a641-8272-958f9e553b54"), + Name = "Rwanda" + }, + new + { + Id = new Guid("c3553d72-9d17-04d8-6692-12a5a7250008"), + Name = "Saint Kitts and Nevis" + }, + new + { + Id = new Guid("fd3ab0e3-279a-107a-88e0-93ee1bb45ffb"), + Name = "Saint Lucia" + }, + new + { + Id = new Guid("420b0acb-a1b0-27e5-45fc-3c6e96f25361"), + Name = "Saint Vincent and the Grenadines" + }, + new + { + Id = new Guid("37425b6c-2940-370c-805d-27cb7af97f88"), + Name = "Samoa" + }, + new + { + Id = new Guid("b6667319-a515-1cf5-7392-92e15c52438d"), + Name = "San Marino" + }, + new + { + Id = new Guid("75c8834a-67e9-9ee5-65bb-e2db6a937074"), + Name = "Sao Tome and Principe" + }, + new + { + Id = new Guid("1e9ab108-4d4b-1812-21d9-5c90d7d897ea"), + Name = "Saudi Arabia" + }, + new + { + Id = new Guid("3cb2d6c7-8bb5-191d-183d-b201063d5491"), + Name = "Senegal" + }, + new + { + Id = new Guid("1995e756-0e82-9463-1627-feeb766d2d0d"), + Name = "Serbia" + }, + new + { + Id = new Guid("1ff73b0c-27c4-9d4a-3d5b-ec77a6612d56"), + Name = "Seychelles" + }, + new + { + Id = new Guid("6df0d56f-3b4e-33fe-6d5f-74da585ea5d0"), + Name = "Sierra Leone" + }, + new + { + Id = new Guid("912f9045-7a3b-151b-2c06-19f899d1787a"), + Name = "Singapore" + }, + new + { + Id = new Guid("53e7d0fc-816f-59dd-7b4a-0ade62330830"), + Name = "Slovakia" + }, + new + { + Id = new Guid("a522756f-2fd9-48d1-7443-dd1546fd8b37"), + Name = "Slovenia" + }, + new + { + Id = new Guid("5f47ed3b-0b54-95aa-93e8-16bf035c9247"), + Name = "Solomon Islands" + }, + new + { + Id = new Guid("b58da294-9556-8ece-163f-3d89514017a7"), + Name = "Somalia" + }, + new + { + Id = new Guid("03a82f52-22d5-8259-1072-429791258b72"), + Name = "South Africa" + }, + new + { + Id = new Guid("55cafe8e-1585-278e-5736-bab16f1b1b8d"), + Name = "South Korea" + }, + new + { + Id = new Guid("9d2d676f-97fb-952c-06a9-09d4e9696631"), + Name = "South Sudan" + }, + new + { + Id = new Guid("534a826b-70ef-2128-1a4c-52e23b7d5447"), + Name = "Spain" + }, + new + { + Id = new Guid("932a43ac-56dc-951e-7de5-996314e92e9c"), + Name = "Sri Lanka" + }, + new + { + Id = new Guid("6c4a7b61-3bfd-4a47-95a3-0ca86c72521f"), + Name = "Sudan" + }, + new + { + Id = new Guid("9a0a2c1d-3475-3554-9d18-b11946af6086"), + Name = "Suriname" + }, + new + { + Id = new Guid("896ef05e-0fe4-92a6-229e-63d7a26e0625"), + Name = "Sweden" + }, + new + { + Id = new Guid("bb0b41a9-7363-5922-9ce0-939412a9036e"), + Name = "Switzerland" + }, + new + { + Id = new Guid("7b9c857e-3fbd-3d19-38cf-f204da39890c"), + Name = "Syria" + }, + new + { + Id = new Guid("d7cd92d3-4522-5a78-3533-816fc61a293f"), + Name = "Tajikistan" + }, + new + { + Id = new Guid("fa81562d-1bc4-944c-86a9-6cc5af502265"), + Name = "Tanzania" + }, + new + { + Id = new Guid("439e3108-0908-4d90-6f5c-1974362b74b1"), + Name = "Thailand" + }, + new + { + Id = new Guid("47e7cc9c-4368-8ab3-056b-66a1351c24cd"), + Name = "Timor-Leste" + }, + new + { + Id = new Guid("492a6eb7-5ca3-8e50-3559-c71205b71c3b"), + Name = "Togo" + }, + new + { + Id = new Guid("e376c876-6960-270c-8744-583fb7a72f55"), + Name = "Tonga" + }, + new + { + Id = new Guid("2f7c276f-4d0d-9368-4132-c04149924bb5"), + Name = "Trinidad and Tobago" + }, + new + { + Id = new Guid("93ba288b-2a62-1880-1e20-aeb705431890"), + Name = "Tunisia" + }, + new + { + Id = new Guid("c576d8f0-5300-2436-2d17-48b699214549"), + Name = "Turkey" + }, + new + { + Id = new Guid("a9c5d1ec-319a-085c-1ee3-80ae15bd27ed"), + Name = "Turkmenistan" + }, + new + { + Id = new Guid("95938676-73d1-2031-219d-dc67ba314bdf"), + Name = "Tuvalu" + }, + new + { + Id = new Guid("2cfae83c-0f45-72d1-4624-5af1e10e6147"), + Name = "Uganda" + }, + new + { + Id = new Guid("1b837dfa-0bda-54f3-918a-beef19f691e5"), + Name = "Ukraine" + }, + new + { + Id = new Guid("f7675604-4744-6d6f-a077-67a3e0c85324"), + Name = "United Arab Emirates" + }, + new + { + Id = new Guid("8f9ec4fb-916f-90ea-5162-f486a0fc0893"), + Name = "United Kingdom" + }, + new + { + Id = new Guid("ca111c84-983b-4525-054c-d14dee3a422c"), + Name = "United States of America" + }, + new + { + Id = new Guid("ee06c3ba-4e8c-95c3-88da-6be3f23b9aaa"), + Name = "Uruguay" + }, + new + { + Id = new Guid("2f02c930-1d71-8ca6-49e7-0d3679a522ea"), + Name = "Uzbekistan" + }, + new + { + Id = new Guid("28dc2817-94b4-955d-10bc-6a8793dd386c"), + Name = "Vanuatu" + }, + new + { + Id = new Guid("9c9e3bca-5880-437f-4f18-d6998d90173f"), + Name = "Venezuela" + }, + new + { + Id = new Guid("5a3893d1-1e36-310c-7633-8f36ffa26315"), + Name = "Vietnam" + }, + new + { + Id = new Guid("a2689ae3-3643-6250-a748-8f055cc72da8"), + Name = "Yemen" + }, + new + { + Id = new Guid("be447a08-0a85-5779-8c65-cf15c2c9a5a8"), + Name = "Zambia" + }, + new + { + Id = new Guid("c776f397-182b-6d0d-09f2-4e440dc093d3"), + Name = "Zimbabwe" + }); + }); + + modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.File", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ContentType") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("nvarchar(50)"); + + b.Property("Discriminator") + .IsRequired() + .HasMaxLength(8) + .HasColumnType("nvarchar(8)"); + + b.Property("Extension") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("nvarchar(20)"); + + b.Property("IsTemp") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(300) + .HasColumnType("nvarchar(300)"); + + b.Property("Size") + .HasColumnType("bigint"); + + b.Property("UploadedOn") + .HasColumnType("datetime2"); + + b.HasKey("Id"); + + b.ToTable("File", (string)null); + + b.HasDiscriminator("Discriminator").IsComplete(true).HasValue("File"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.Product", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CompanyId") + .HasColumnType("uniqueidentifier"); + + b.Property("DefaultPictureId") + .HasColumnType("uniqueidentifier"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("nvarchar(500)"); + + b.Property("Price") + .HasPrecision(10, 2) + .HasColumnType("decimal(10,2)"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b.HasKey("Id"); + + b.HasIndex("CompanyId"); + + b.HasIndex("DefaultPictureId") + .IsUnique(); + + b.HasIndex("Title"); + + b.ToTable("Product"); + }); + + modelBuilder.Entity("ProductPicture", b => + { + b.Property("PicturesId") + .HasColumnType("uniqueidentifier"); + + b.Property("ProductId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("PicturesId", "ProductId"); + + b.HasIndex("PicturesId") + .IsUnique(); + + b.HasIndex("ProductId"); + + b.ToTable("ProductPicture"); + }); + + modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.Document", b => + { + b.HasBaseType("Monaco.Template.Backend.Domain.Model.File"); + + b.HasDiscriminator().HasValue("Document"); + }); + + modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.Image", b => + { + b.HasBaseType("Monaco.Template.Backend.Domain.Model.File"); + + b.Property("DateTaken") + .HasColumnType("datetime2"); + + b.Property("ThumbnailId") + .HasColumnType("uniqueidentifier"); + + b.HasIndex("ThumbnailId") + .IsUnique() + .HasFilter("[ThumbnailId] IS NOT NULL"); + + b.HasDiscriminator().HasValue("Image"); + }); + + modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.Company", b => + { + b.OwnsOne("Monaco.Template.Backend.Domain.Model.Address", "Address", b1 => + { + b1.Property("CompanyId") + .HasColumnType("uniqueidentifier"); + + b1.Property("City") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b1.Property("CountryId") + .HasColumnType("uniqueidentifier"); + + b1.Property("County") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b1.Property("PostCode") + .HasMaxLength(10) + .HasColumnType("nvarchar(10)"); + + b1.Property("Street") + .HasMaxLength(100) + .HasColumnType("nvarchar(100)"); + + b1.HasKey("CompanyId"); + + b1.HasIndex("CountryId"); + + b1.ToTable("Company"); + + b1.WithOwner() + .HasForeignKey("CompanyId"); + + b1.HasOne("Monaco.Template.Backend.Domain.Model.Country", "Country") + .WithMany() + .HasForeignKey("CountryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b1.Navigation("Country"); + }); + + b.Navigation("Address"); + }); + + modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.Product", b => + { + b.HasOne("Monaco.Template.Backend.Domain.Model.Company", "Company") + .WithMany("Products") + .HasForeignKey("CompanyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Monaco.Template.Backend.Domain.Model.Image", "DefaultPicture") + .WithOne() + .HasForeignKey("Monaco.Template.Backend.Domain.Model.Product", "DefaultPictureId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Company"); + + b.Navigation("DefaultPicture"); + }); + + modelBuilder.Entity("ProductPicture", b => + { + b.HasOne("Monaco.Template.Backend.Domain.Model.Image", null) + .WithMany() + .HasForeignKey("PicturesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Monaco.Template.Backend.Domain.Model.Product", null) + .WithMany() + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.ClientCascade) + .IsRequired(); + }); + + modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.Image", b => + { + b.HasOne("Monaco.Template.Backend.Domain.Model.Image", "Thumbnail") + .WithOne() + .HasForeignKey("Monaco.Template.Backend.Domain.Model.Image", "ThumbnailId"); + + b.OwnsOne("Monaco.Template.Backend.Domain.Model.GpsPosition", "Position", b1 => + { + b1.Property("ImageId") + .HasColumnType("uniqueidentifier"); + + b1.Property("Latitude") + .HasColumnType("real"); + + b1.Property("Longitude") + .HasColumnType("real"); + + b1.HasKey("ImageId"); + + b1.ToTable("File"); + + b1.WithOwner() + .HasForeignKey("ImageId"); + }); + + b.OwnsOne("Monaco.Template.Backend.Domain.Model.ImageDimensions", "Dimensions", b1 => + { + b1.Property("ImageId") + .HasColumnType("uniqueidentifier"); + + b1.Property("Height") + .HasColumnType("int"); + + b1.Property("Width") + .HasColumnType("int"); + + b1.HasKey("ImageId"); + + b1.ToTable("File"); + + b1.WithOwner() + .HasForeignKey("ImageId"); + }); + + b.Navigation("Dimensions") + .IsRequired(); + + b.Navigation("Position"); + + b.Navigation("Thumbnail"); + }); + + modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.Company", b => + { + b.Navigation("Products"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure.Migrations/Monaco.Template.Backend.Application.Infrastructure.Migrations.csproj b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure.Migrations/Monaco.Template.Backend.Application.Infrastructure.Migrations.csproj index 05c5d34..86c1f5b 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure.Migrations/Monaco.Template.Backend.Application.Infrastructure.Migrations.csproj +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure.Migrations/Monaco.Template.Backend.Application.Infrastructure.Migrations.csproj @@ -10,4 +10,8 @@ + + + + diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure/EntityConfigurations/CompanyEntityConfiguration.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure/EntityConfigurations/CompanyEntityConfiguration.cs index 3547b20..96c7005 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure/EntityConfigurations/CompanyEntityConfiguration.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure/EntityConfigurations/CompanyEntityConfiguration.cs @@ -26,6 +26,12 @@ public void Configure(EntityTypeBuilder builder) builder.Property(x => x.Version) .IsRowVersion(); + builder.HasMany(x => x.Products) + .WithOne(x => x.Company) + .HasForeignKey(x => x.CompanyId) + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + builder.OwnsOne(x => x.Address, b => { diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure/EntityConfigurations/ImageEntityConfiguration.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure/EntityConfigurations/ImageEntityConfiguration.cs index 37e17d6..29d4737 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure/EntityConfigurations/ImageEntityConfiguration.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure/EntityConfigurations/ImageEntityConfiguration.cs @@ -8,20 +8,29 @@ public class ImageEntityConfiguration : IEntityTypeConfiguration { public void Configure(EntityTypeBuilder builder) { - builder.Property(x => x.Height) - .IsRequired(); - - builder.Property(x => x.Width) - .IsRequired(); - builder.Property(x => x.DateTaken) .IsRequired(false); - builder.Property(x => x.GpsLatitude) - .IsRequired(false); + builder.OwnsOne(x => x.Dimensions, + b => + { + b.Property(x => x.Height) + .IsRequired(); + + b.Property(x => x.Width) + .IsRequired(); + }); + + builder.OwnsOne(x => x.Position, + b => + { + b.Property(x => x.Latitude) + .IsRequired(); + + b.Property(x => x.Longitude) + .IsRequired(); + }); - builder.Property(x => x.GpsLongitude) - .IsRequired(false); builder.HasOne(x => x.Thumbnail) .WithOne() diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure/EntityConfigurations/ProductEntityConfiguration.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure/EntityConfigurations/ProductEntityConfiguration.cs new file mode 100644 index 0000000..ac0bece --- /dev/null +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure/EntityConfigurations/ProductEntityConfiguration.cs @@ -0,0 +1,47 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Monaco.Template.Backend.Common.Infrastructure.EntityConfigurations.Extensions; +using Monaco.Template.Backend.Domain.Model; + +namespace Monaco.Template.Backend.Application.Infrastructure.EntityConfigurations; + +public class ProductEntityConfiguration : IEntityTypeConfiguration +{ + public void Configure(EntityTypeBuilder builder) + { + builder.ConfigureIdWithDbGeneratedValue(); + + builder.Property(x => x.Title) + .IsRequired() + .HasMaxLength(100); + + builder.Property(x => x.Description) + .IsRequired() + .HasMaxLength(500); + + builder.Property(x => x.Price) + .IsRequired() + .HasPrecision(10, 2); + + + builder.HasOne(x => x.DefaultPicture) + .WithOne() + .HasForeignKey(x => x.DefaultPictureId) + .IsRequired(); + + builder.HasMany(x => x.Pictures) + .WithMany() + .UsingEntity>("ProductPicture", + x => x.HasOne() + .WithMany() + .OnDelete(DeleteBehavior.Cascade), + x => x.HasOne() + .WithMany() + .OnDelete(DeleteBehavior.ClientCascade)) + .HasIndex($"{nameof(Product.Pictures)}Id") + .IsUnique(); //Constraint for single usage of file + + builder.HasIndex(x => x.Title) + .IsUnique(false); + } +} \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure/Monaco.Template.Backend.Application.Infrastructure.csproj b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure/Monaco.Template.Backend.Application.Infrastructure.csproj index 48c3c23..64ace0a 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure/Monaco.Template.Backend.Application.Infrastructure.csproj +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure/Monaco.Template.Backend.Application.Infrastructure.csproj @@ -7,7 +7,7 @@ - + diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/CreateCompanyHandlerTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/CreateCompanyHandlerTests.cs index edd2fee..6c4b2ef 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/CreateCompanyHandlerTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/CreateCompanyHandlerTests.cs @@ -1,31 +1,31 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Threading; -using System.Threading.Tasks; -using FluentAssertions; +using FluentAssertions; using Monaco.Template.Backend.Application.Features.Company; using Monaco.Template.Backend.Application.Infrastructure.Context; using Monaco.Template.Backend.Common.Tests; using Monaco.Template.Backend.Common.Tests.Factories; using Moq; +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Threading; +using System.Threading.Tasks; using Xunit; namespace Monaco.Template.Backend.Application.Tests.Features.Company; [ExcludeFromCodeCoverage] -[Trait("Application Commands", "Create Company")] +[Trait("Application Commands - Company", "Create")] public class CreateCompanyHandlerTests { private readonly Mock _dbContextMock = new(); - private static readonly CreateCompany.Command _command = new(It.IsAny(), // Name - It.IsAny(), // Email - It.IsAny(), // WebsiteUrl - It.IsAny(), // Street - It.IsAny(), // City - It.IsAny(), // County - It.IsAny(), // PostCode - It.IsAny()); // CountryId + private static readonly CreateCompany.Command Command = new(It.IsAny(), // Name + It.IsAny(), // Email + It.IsAny(), // WebsiteUrl + It.IsAny(), // Street + It.IsAny(), // City + It.IsAny(), // County + It.IsAny(), // PostCode + It.IsAny()); // CountryId [Theory(DisplayName = "Create new company succeeds")] @@ -36,11 +36,16 @@ public async Task CreateNewCompanySucceeds(Domain.Model.Country country) .CreateAndSetupDbSetMock([country]); var sut = new CreateCompany.Handler(_dbContextMock.Object); - var result = await sut.Handle(_command, new CancellationToken()); + var result = await sut.Handle(Command, new CancellationToken()); companyDbSetMock.Verify(x => x.Attach(It.IsAny()), Times.Once); _dbContextMock.Verify(x => x.SaveEntitiesAsync(It.IsAny()), Times.Once); - result.ValidationResult.IsValid.Should().BeTrue(); - result.ItemNotFound.Should().BeFalse(); + result.ValidationResult + .IsValid + .Should() + .BeTrue(); + result.ItemNotFound + .Should() + .BeFalse(); } -} +} \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/CreateCompanyValidatorTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/CreateCompanyValidatorTests.cs index 8b8c483..61e6cfc 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/CreateCompanyValidatorTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/CreateCompanyValidatorTests.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Threading.Tasks; -using FluentAssertions; +using FluentAssertions; using FluentValidation; using FluentValidation.TestHelper; using Monaco.Template.Backend.Application.Features.Company; @@ -10,23 +6,27 @@ using Monaco.Template.Backend.Common.Tests; using Monaco.Template.Backend.Common.Tests.Factories; using Moq; +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Threading.Tasks; using Xunit; namespace Monaco.Template.Backend.Application.Tests.Features.Company; [ExcludeFromCodeCoverage] -[Trait("Application Commands", "Create Company")] +[Trait("Application Commands - Company", "Create")] public class CreateCompanyValidatorTests { private readonly Mock _dbContextMock = new(); - private static readonly CreateCompany.Command _command = new(It.IsAny(), // Name - It.IsAny(), // Email - It.IsAny(), // WebsiteUrl - It.IsAny(), // Street - It.IsAny(), // City - It.IsAny(), // County - It.IsAny(), // PostCode - It.IsAny()); // CountryId + private readonly CreateCompany.Command _command = new(It.IsAny(), // Name + It.IsAny(), // Email + It.IsAny(), // WebsiteUrl + It.IsAny(), // Street + It.IsAny(), // City + It.IsAny(), // County + It.IsAny(), // PostCode + It.IsAny()); // CountryId [Fact(DisplayName = "Validator's rule level cascade mode is 'Stop'")] public void ValidatorRuleLevelCascadeModeIsStop() @@ -290,13 +290,13 @@ public async Task CountryIsValidDoesNotGenerateError(Domain.Model.Country countr public async Task CountryWithNullValueDoesNotGenerateErrorWhenAddressFieldsNull() { var command = _command with - { - Street = null, - City = null, - County = null, - PostCode = null, - CountryId = null - }; + { + Street = null, + City = null, + County = null, + PostCode = null, + CountryId = null + }; var sut = new CreateCompany.Validator(_dbContextMock.Object); var validationResult = await sut.TestValidateAsync(command, s => s.IncludeProperties(x => x.Street, @@ -312,13 +312,13 @@ public async Task CountryWithNullValueDoesNotGenerateErrorWhenAddressFieldsNull( public async Task CountryWithNullValueGeneratesErrorWhenAddressFieldsPresent() { var command = _command with - { - Street = string.Empty, - City = string.Empty, - County = string.Empty, - PostCode = string.Empty, - CountryId = null - }; + { + Street = string.Empty, + City = string.Empty, + County = string.Empty, + PostCode = string.Empty, + CountryId = null + }; var sut = new CreateCompany.Validator(_dbContextMock.Object); var validationResult = await sut.TestValidateAsync(command, s => s.IncludeProperties(x => x.Street, diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/DeleteCompanyHandlerTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/DeleteCompanyHandlerTests.cs index 477e447..68e748b 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/DeleteCompanyHandlerTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/DeleteCompanyHandlerTests.cs @@ -1,34 +1,98 @@ -using System; -using System.Diagnostics.CodeAnalysis; -using System.Threading; -using System.Threading.Tasks; +using AutoFixture; using FluentAssertions; using Monaco.Template.Backend.Application.Features.Company; using Monaco.Template.Backend.Application.Infrastructure.Context; +#if !excludeFilesSupport +using Monaco.Template.Backend.Application.Services.Contracts; +#endif using Monaco.Template.Backend.Common.Tests; +using Monaco.Template.Backend.Common.Tests.Factories; +using Monaco.Template.Backend.Domain.Model; using Moq; +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; using Xunit; namespace Monaco.Template.Backend.Application.Tests.Features.Company; [ExcludeFromCodeCoverage] -[Trait("Application Commands", "Delete Company")] +[Trait("Application Commands - Company", "Delete")] public class DeleteCompanyHandlerTests { private readonly Mock _dbContextMock = new(); - private static readonly DeleteCompany.Command _command = new(It.IsAny()); + private readonly DeleteCompany.Command _command = new(It.IsAny()); + #if !excludeFilesSupport + private readonly Mock _fileServiceMock = new(); + #endif - [Fact(DisplayName = "Delete company succeeds")] - public async Task DeleteCompanySucceeds() + [Theory(DisplayName = "Delete company succeeds")] + [AnonymousData(true)] + #if !excludeFilesSupport + public async Task DeleteCompanySucceeds(IFixture fixture, Domain.Model.Product[] products) + #else + public async Task DeleteCompanySucceeds(Company company) + #endif { - _dbContextMock.CreateEntityMockAndSetupDbSetMock(); + #if !excludeFilesSupport + var companyMock = new Mock(fixture.Create(), + fixture.Create(), + fixture.Create(), + fixture.Create
()); + companyMock.SetupGet(x => x.Id) + .Returns(Guid.NewGuid()); + companyMock.SetupGet(x => x.Products) + .Returns(products); + + var pictures = products.SelectMany(x => x.Pictures) + .Union(products.SelectMany(x => x.Pictures.Select(p => p.Thumbnail!))) + .ToArray(); + + _dbContextMock.CreateAndSetupDbSetMock(companyMock.Object, out var companyDbSetMock); + _dbContextMock.CreateAndSetupDbSetMock(pictures, out var imageDbSetMock); + #else + _dbContextMock.CreateAndSetupDbSetMock(company, out var companyDbSetMock); + #endif + + var command = _command with + { + #if !excludeFilesSupport + Id = companyMock.Object.Id + #else + Id = company.Id + #endif + }; + #if !excludeFilesSupport + var sut = new DeleteCompany.Handler(_dbContextMock.Object, _fileServiceMock.Object); + #else var sut = new DeleteCompany.Handler(_dbContextMock.Object); - var result = await sut.Handle(_command, new CancellationToken()); + #endif + var result = await sut.Handle(command, new CancellationToken()); + + companyDbSetMock.Verify(x => x.Remove(It.IsAny()), + Times.Once); + #if !excludeFilesSupport + imageDbSetMock.Verify(x => x.RemoveRange(It.IsAny>()), + Times.Once); + #endif + _dbContextMock.Verify(x => x.SaveEntitiesAsync(It.IsAny()), + Times.Once); + #if !excludeFilesSupport + _fileServiceMock.Verify(x => x.DeleteImagesAsync(It.IsAny(), It.IsAny()), + Times.Once); + #endif + + result.ValidationResult + .IsValid + .Should() + .BeTrue(); - _dbContextMock.Verify(x => x.Set().Remove(It.IsAny()), Times.Once); - _dbContextMock.Verify(x => x.SaveEntitiesAsync(It.IsAny()), Times.Once); - result.ValidationResult.IsValid.Should().BeTrue(); - result.ItemNotFound.Should().BeFalse(); + result.ItemNotFound + .Should() + .BeFalse(); } } diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/DeleteCompanyValidatorTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/DeleteCompanyValidatorTests.cs index 7addb55..376c216 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/DeleteCompanyValidatorTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/DeleteCompanyValidatorTests.cs @@ -15,7 +15,7 @@ namespace Monaco.Template.Backend.Application.Tests.Features.Company; [ExcludeFromCodeCoverage] -[Trait("Application Commands", "Delete Company")] +[Trait("Application Commands - Company", "Delete")] public class DeleteCompanyValidatorTests { private readonly Mock _dbContextMock = new(); diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/EditCompanyHandlerTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/EditCompanyHandlerTests.cs index dfe9339..14c5dde 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/EditCompanyHandlerTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/EditCompanyHandlerTests.cs @@ -1,32 +1,33 @@ -using System; -using System.Diagnostics.CodeAnalysis; -using System.Threading; -using System.Threading.Tasks; -using FluentAssertions; +using FluentAssertions; using Monaco.Template.Backend.Application.Features.Company; using Monaco.Template.Backend.Application.Infrastructure.Context; using Monaco.Template.Backend.Common.Tests; using Monaco.Template.Backend.Common.Tests.Factories; using Monaco.Template.Backend.Domain.Model; using Moq; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Threading; +using System.Threading.Tasks; using Xunit; namespace Monaco.Template.Backend.Application.Tests.Features.Company; [ExcludeFromCodeCoverage] -[Trait("Application Commands", "Edit Company")] +[Trait("Application Commands - Company", "Edit")] public class EditCompanyHandlerTests { private readonly Mock _dbContextMock = new(); - private static readonly EditCompany.Command _command = new(It.IsAny(), // Id - It.IsAny(), // Name - It.IsAny(), // Email - It.IsAny(), // WebSiteUrl - It.IsAny(), // Street - It.IsAny(), // City - It.IsAny(), // County - It.IsAny(), // PostCode - It.IsAny()); // CountryId + + private static readonly EditCompany.Command Command = new(It.IsAny(), // Id + It.IsAny(), // Name + It.IsAny(), // Email + It.IsAny(), // WebSiteUrl + It.IsAny(), // Street + It.IsAny(), // City + It.IsAny(), // County + It.IsAny(), // PostCode + It.IsAny()); // CountryId [Theory(DisplayName = "Edit company succeeds")] [AnonymousData] @@ -36,7 +37,7 @@ public async Task EditCompanySucceeds(Domain.Model.Country country) .CreateAndSetupDbSetMock(country); var sut = new EditCompany.Handler(_dbContextMock.Object); - var result = await sut.Handle(_command, new CancellationToken()); + var result = await sut.Handle(Command, new CancellationToken()); companyMock.Verify(x => x.Update(It.IsAny(), It.IsAny(), diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/EditCompanyValidatorTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/EditCompanyValidatorTests.cs index 661171a..271d521 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/EditCompanyValidatorTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/EditCompanyValidatorTests.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Threading.Tasks; -using FluentAssertions; +using FluentAssertions; using FluentValidation; using FluentValidation.TestHelper; using Monaco.Template.Backend.Application.Features.Company; @@ -11,24 +7,28 @@ using Monaco.Template.Backend.Common.Tests; using Monaco.Template.Backend.Common.Tests.Factories; using Moq; +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Threading.Tasks; using Xunit; namespace Monaco.Template.Backend.Application.Tests.Features.Company; [ExcludeFromCodeCoverage] -[Trait("Application Commands", "Edit Company")] +[Trait("Application Commands - Company", "Edit")] public class EditCompanyValidatorTests { private readonly Mock _dbContextMock = new(); - private static readonly EditCompany.Command _command = new(It.IsAny(), // Id - It.IsAny(), // Name - It.IsAny(), // Email - It.IsAny(), // WebSiteUrl - It.IsAny(), // Street - It.IsAny(), // City - It.IsAny(), // County - It.IsAny(), // PostCode - It.IsAny()); // CountryId + private static readonly EditCompany.Command Command = new(It.IsAny(), // Id + It.IsAny(), // Name + It.IsAny(), // Email + It.IsAny(), // WebSiteUrl + It.IsAny(), // Street + It.IsAny(), // City + It.IsAny(), // County + It.IsAny(), // PostCode + It.IsAny()); // CountryId @@ -44,7 +44,7 @@ public void ValidatorRuleLevelCascadeModeIsStop() [AnonymousData] public async Task ExistingCompanyPassesValidationCorrectly(Domain.Model.Company company) { - var command = _command with { Id = company.Id, CountryId = Guid.NewGuid() }; + var command = Command with { Id = company.Id, CountryId = Guid.NewGuid() }; _dbContextMock.CreateAndSetupDbSetMock(company); @@ -55,11 +55,11 @@ public async Task ExistingCompanyPassesValidationCorrectly(Domain.Model.Company validationResult.ShouldNotHaveAnyValidationErrors(); } - [Theory(DisplayName = "Non existing company passes validation correctly")] + [Theory(DisplayName = "Non existing company generates validation error")] [AnonymousData] - public async Task NonExistingCompanyPassesValidationCorrectly(Domain.Model.Company company, Guid id) + public async Task NonExistingCompanyGeneratesError(Domain.Model.Company company, Guid id) { - var command = _command with { Id = id, CountryId = Guid.NewGuid() }; + var command = Command with { Id = id, CountryId = Guid.NewGuid() }; _dbContextMock.CreateAndSetupDbSetMock(company); @@ -73,7 +73,7 @@ public async Task NonExistingCompanyPassesValidationCorrectly(Domain.Model.Compa [Fact(DisplayName = "Name being valid does not generate validation error")] public async Task NameDoesNotGenerateErrorWhenValid() { - var command = _command with { Name = new string(It.IsAny(), 100) }; + var command = Command with { Name = new string(It.IsAny(), 100) }; _dbContextMock.CreateAndSetupDbSetMock(new List()); @@ -86,7 +86,7 @@ public async Task NameDoesNotGenerateErrorWhenValid() [Fact(DisplayName = "Name with empty value generates validation error")] public async Task NameIsEmptyGeneratesError() { - var command = _command with { Name = string.Empty }; + var command = Command with { Name = string.Empty }; var sut = new EditCompany.Validator(_dbContextMock.Object); var validationResult = await sut.TestValidateAsync(command, s => s.IncludeProperties(x => x.Name)); @@ -100,7 +100,7 @@ public async Task NameIsEmptyGeneratesError() [Fact(DisplayName = "Name with long value generates validation error")] public async Task NameWithLongValueGeneratesError() { - var command = _command with { Name = new string(It.IsAny(), 101) }; + var command = Command with { Name = new string(It.IsAny(), 101) }; var sut = new EditCompany.Validator(_dbContextMock.Object); var validationResult = await sut.TestValidateAsync(command, s => s.IncludeProperties(x => x.Name)); @@ -116,7 +116,7 @@ public async Task NameWithLongValueGeneratesError() [AnonymousData] public async Task NameAlreadyExistsGeneratesError(Domain.Model.Company company, Guid id) { - var command = _command with { Id = id, Name = company.Name }; + var command = Command with { Id = id, Name = company.Name }; _dbContextMock.CreateAndSetupDbSetMock([company]); @@ -132,7 +132,7 @@ public async Task NameAlreadyExistsGeneratesError(Domain.Model.Company company, [Fact(DisplayName = "Email being valid does not generate validation error")] public async Task EmailIsValidDoesNotGenerateError() { - var command = _command with { Email = "valid@email.com" }; + var command = Command with { Email = "valid@email.com" }; _dbContextMock.CreateAndSetupDbSetMock(new List()); @@ -145,7 +145,7 @@ public async Task EmailIsValidDoesNotGenerateError() [Fact(DisplayName = "Email with empty value generates validation error")] public async Task EmailIsEmptyGeneratesError() { - var command = _command with { Email = string.Empty }; + var command = Command with { Email = string.Empty }; var sut = new EditCompany.Validator(_dbContextMock.Object); var validationResult = await sut.TestValidateAsync(command, s => s.IncludeProperties(x => x.Email)); @@ -160,7 +160,7 @@ public async Task EmailIsEmptyGeneratesError() [AnonymousData] public async Task EmailAddressIsInvalidGeneratesError(string email) { - var command = _command with { Email = email }; + var command = Command with { Email = email }; var sut = new EditCompany.Validator(_dbContextMock.Object); var validationResult = await sut.TestValidateAsync(command, s => s.IncludeProperties(x => x.Email)); @@ -174,7 +174,7 @@ public async Task EmailAddressIsInvalidGeneratesError(string email) [Fact(DisplayName = "Website URL with long value generates validation error")] public async Task WebsiteUrlWithLongValueGeneratesError() { - var command = _command with { WebSiteUrl = new string(It.IsAny(), 301) }; + var command = Command with { WebSiteUrl = new string(It.IsAny(), 301) }; var sut = new EditCompany.Validator(_dbContextMock.Object); var validationResult = await sut.TestValidateAsync(command, s => s.IncludeProperties(x => x.WebSiteUrl)); @@ -189,7 +189,7 @@ public async Task WebsiteUrlWithLongValueGeneratesError() [Fact(DisplayName = "Website URL with empty value does not generate validation error")] public async Task WebsiteUrlWithEmptyValueDoesNotGenerateError() { - var command = _command with { WebSiteUrl = string.Empty }; + var command = Command with { WebSiteUrl = string.Empty }; var sut = new EditCompany.Validator(_dbContextMock.Object); var validationResult = await sut.TestValidateAsync(command, s => s.IncludeProperties(x => x.WebSiteUrl)); @@ -200,7 +200,7 @@ public async Task WebsiteUrlWithEmptyValueDoesNotGenerateError() [Fact(DisplayName = "Street with long value generates validation error")] public async Task AddressWithLongValueGeneratesError() { - var command = _command with { Street = new string(It.IsAny(), 101) }; + var command = Command with { Street = new string(It.IsAny(), 101) }; var validator = new EditCompany.Validator(_dbContextMock.Object); var validationResult = await validator.TestValidateAsync(command, s => s.IncludeProperties(x => x.Street)); @@ -215,7 +215,7 @@ public async Task AddressWithLongValueGeneratesError() [Fact(DisplayName = "Street with empty value does not generate validation error")] public async Task AddressWithEmptyValueDoesNotGenerateError() { - var command = _command with { Street = string.Empty }; + var command = Command with { Street = string.Empty }; var sut = new EditCompany.Validator(_dbContextMock.Object); var validationResult = await sut.TestValidateAsync(command, s => s.IncludeProperties(x => x.Street)); @@ -226,7 +226,7 @@ public async Task AddressWithEmptyValueDoesNotGenerateError() [Fact(DisplayName = "City with long value generates validation error")] public async Task CityWithLongValueGeneratesError() { - var command = _command with { City = new string(It.IsAny(), 101) }; + var command = Command with { City = new string(It.IsAny(), 101) }; var sut = new EditCompany.Validator(_dbContextMock.Object); var validationResult = await sut.TestValidateAsync(command, s => s.IncludeProperties(x => x.City)); @@ -241,7 +241,7 @@ public async Task CityWithLongValueGeneratesError() [Fact(DisplayName = "City with empty value does not generate validation error")] public async Task CityWithEmptyValueDoesNotGenerateError() { - var command = _command with { City = string.Empty }; + var command = Command with { City = string.Empty }; var sut = new EditCompany.Validator(_dbContextMock.Object); var validationResult = await sut.TestValidateAsync(command, s => s.IncludeProperties(x => x.City)); @@ -252,7 +252,7 @@ public async Task CityWithEmptyValueDoesNotGenerateError() [Fact(DisplayName = "County with long value generates validation error")] public async Task CountyWithLongValueGeneratesError() { - var command = _command with { County = new string(It.IsAny(), 101) }; + var command = Command with { County = new string(It.IsAny(), 101) }; var sut = new EditCompany.Validator(_dbContextMock.Object); var validationResult = await sut.TestValidateAsync(command, s => s.IncludeProperties(x => x.County)); @@ -267,7 +267,7 @@ public async Task CountyWithLongValueGeneratesError() [Fact(DisplayName = "County with empty value does not generate validation error")] public async Task CountyWithEmptyValueDoesNotGenerateError() { - var command = _command with { County = string.Empty }; + var command = Command with { County = string.Empty }; var sut = new EditCompany.Validator(_dbContextMock.Object); var validationResult = await sut.TestValidateAsync(command, s => s.IncludeProperties(x => x.County)); @@ -278,7 +278,7 @@ public async Task CountyWithEmptyValueDoesNotGenerateError() [Fact(DisplayName = "Postcode with long value generates validation error")] public async Task PostcodeWithLongValueGeneratesError() { - var command = _command with { PostCode = new string(It.IsAny(), 11) }; + var command = Command with { PostCode = new string(It.IsAny(), 11) }; var sut = new EditCompany.Validator(_dbContextMock.Object); var validationResult = await sut.TestValidateAsync(command, s => s.IncludeProperties(x => x.PostCode)); @@ -293,7 +293,7 @@ public async Task PostcodeWithLongValueGeneratesError() [Fact(DisplayName = "Postcode with empty value does not generate validation error")] public async Task PostcodeWithEmptyValueDoesNotGenerateError() { - var command = _command with { PostCode = string.Empty }; + var command = Command with { PostCode = string.Empty }; var sut = new EditCompany.Validator(_dbContextMock.Object); var validationResult = await sut.TestValidateAsync(command, s => s.IncludeProperties(x => x.PostCode)); @@ -305,7 +305,7 @@ public async Task PostcodeWithEmptyValueDoesNotGenerateError() [AnonymousData(true)] public async Task CountryIsValidDoesNotGenerateError(Domain.Model.Country country) { - var command = _command with { CountryId = country.Id }; + var command = Command with { CountryId = country.Id }; _dbContextMock.CreateAndSetupDbSetMock(new List()) .CreateAndSetupDbSetMock([country]); @@ -319,7 +319,7 @@ public async Task CountryIsValidDoesNotGenerateError(Domain.Model.Country countr [Fact(DisplayName = "Country with null value does not generate validation error")] public async Task CountryWithNullValueDoesNotGenerateError() { - var command = _command with { CountryId = null }; + var command = Command with { CountryId = null }; var sut = new EditCompany.Validator(_dbContextMock.Object); var validationResult = await sut.TestValidateAsync(command, s => s.IncludeProperties(x => x.CountryId)); @@ -331,7 +331,7 @@ public async Task CountryWithNullValueDoesNotGenerateError() [AnonymousData] public async Task CountryMustExistValidation(Domain.Model.Country country) { - var command = _command with { CountryId = Guid.NewGuid() }; + var command = Command with { CountryId = Guid.NewGuid() }; _dbContextMock.CreateAndSetupDbSetMock(new List()) .CreateAndSetupDbSetMock([country]); diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/GetCompanyByIdTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/GetCompanyByIdTests.cs index 47cba27..892fd32 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/GetCompanyByIdTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/GetCompanyByIdTests.cs @@ -14,7 +14,7 @@ namespace Monaco.Template.Backend.Application.Tests.Features.Company; [ExcludeFromCodeCoverage] -[Trait("Application Queries", "Get Company by Id")] +[Trait("Application Queries - Company", "Get Company by Id")] public class GetCompanyByIdTests { private readonly Mock _dbContextMock = new(); diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/GetCompanyPageTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/GetCompanyPageTests.cs index 41be76a..0792a2b 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/GetCompanyPageTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/GetCompanyPageTests.cs @@ -1,9 +1,4 @@ -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using FluentAssertions; +using FluentAssertions; using Microsoft.Extensions.Primitives; using Monaco.Template.Backend.Application.DTOs; using Monaco.Template.Backend.Application.Features.Company; @@ -11,12 +6,17 @@ using Monaco.Template.Backend.Common.Tests; using Monaco.Template.Backend.Common.Tests.Factories; using Moq; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; using Xunit; namespace Monaco.Template.Backend.Application.Tests.Features.Company; [ExcludeFromCodeCoverage] -[Trait("Application Queries", "Get Company Page")] +[Trait("Application Queries - Company", "Get Company Page")] public class GetCompanyPageTests { private readonly Mock _dbContextMock = new(); @@ -32,8 +32,12 @@ public async Task GetCompanyPageWithoutParamsSucceeds(List var sut = new GetCompanyPage.Handler(_dbContextMock.Object); var result = await sut.Handle(query, new CancellationToken()); - result.Should().NotBeNull(); - result!.Pager.Count.Should().Be(companies.Count); + result.Should() + .NotBeNull(); + result!.Pager + .Count + .Should() + .Be(companies.Count); result.Items .Should() .HaveCount(companies.Count).And @@ -48,19 +52,25 @@ public async Task GetCompanyPageWithParamsSucceeds(List co _dbContextMock.CreateAndSetupDbSetMock(companies); var companiesSet = companies.GetRange(0, 2); var queryString = new List> - { - new (nameof(CompanyDto.Name), - new(companiesSet.Select(x => x.Name).ToArray())), - new ("sort", $"-{nameof(CompanyDto.Name)}") - }; + { + new(nameof(CompanyDto.Name), + new(companiesSet.Select(x => x.Name) + .ToArray())), + new("expand", nameof(CompanyDto.Country)), + new("sort", $"-{nameof(CompanyDto.Name)}") + }; var query = new GetCompanyPage.Query(queryString); var sut = new GetCompanyPage.Handler(_dbContextMock.Object); var result = await sut.Handle(query, new CancellationToken()); - result.Should().NotBeNull(); - result!.Pager.Count.Should().Be(companiesSet.Count); + result.Should() + .NotBeNull(); + result!.Pager + .Count + .Should() + .Be(companiesSet.Count); result.Items .Should() .HaveCount(companiesSet.Count).And diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Country/GetCountryByIdTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Country/GetCountryByIdTests.cs index 52e362b..3ceff11 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Country/GetCountryByIdTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Country/GetCountryByIdTests.cs @@ -14,7 +14,7 @@ namespace Monaco.Template.Backend.Application.Tests.Features.Country; [ExcludeFromCodeCoverage] -[Trait("Application Queries", "Get Country by Id")] +[Trait("Application Queries - Country", "Get Country by Id")] public class GetCountryByIdTests { private readonly Mock _dbContextMock = new(); diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Country/GetCountryListTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Country/GetCountryListTests.cs index 062b5ce..b0b392e 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Country/GetCountryListTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Country/GetCountryListTests.cs @@ -16,7 +16,7 @@ namespace Monaco.Template.Backend.Application.Tests.Features.Country; [ExcludeFromCodeCoverage] -[Trait("Application Queries", "Get Country List")] +[Trait("Application Queries - Country", "Get Country List")] public class GetCountryListTests { private readonly Mock _dbContextMock = new(); diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/File/CreateFileHandlerTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/File/CreateFileHandlerTests.cs new file mode 100644 index 0000000..c3df799 --- /dev/null +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/File/CreateFileHandlerTests.cs @@ -0,0 +1,90 @@ +using FluentAssertions; +using Monaco.Template.Backend.Application.Features.File; +using Monaco.Template.Backend.Application.Infrastructure.Context; +using Monaco.Template.Backend.Application.Services.Contracts; +using Monaco.Template.Backend.Common.Tests; +using Monaco.Template.Backend.Common.Tests.Factories; +using Moq; +using System; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using Xunit; + +namespace Monaco.Template.Backend.Application.Tests.Features.File; + +[ExcludeFromCodeCoverage] +[Trait("Application Commands - File", "Create")] +public class CreateFileHandlerTests +{ + private readonly Mock _fileServiceMock = new(); + private readonly Mock _dbContextMock = new(); + private static readonly CreateFile.Command Command = new(It.IsAny(), // Stream + It.IsAny(), // FileName + It.IsAny()); // ContentType + + [Theory(DisplayName = "Create new File succeeds")] + [AnonymousData] + public async Task CreateNewFileSucceeds(Domain.Model.Document file) + { + _dbContextMock.CreateAndSetupDbSetMock(Array.Empty(), out var fileDbSetMock); + _fileServiceMock.Setup(x => x.UploadAsync(It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny())) + .ReturnsAsync(file); + + var sut = new CreateFile.Handler(_dbContextMock.Object, _fileServiceMock.Object); + var result = await sut.Handle(Command, new CancellationToken()); + + _fileServiceMock.Verify(x => x.UploadAsync(It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny()), + Times.Once); + fileDbSetMock.Verify(x => x.Attach(It.IsAny()), + Times.Once); + _dbContextMock.Verify(x => x.SaveEntitiesAsync(It.IsAny()), + Times.Once); + + result.ValidationResult + .IsValid + .Should() + .BeTrue(); + result.ItemNotFound + .Should() + .BeFalse(); + result.Result + .Should() + .Be(file.Id); + } + + [Theory(DisplayName = "Create new File error deletes uploaded file from store")] + [AnonymousData] + public async Task CreateNewFileErrorDeletesFile(Domain.Model.Document file) + { + _dbContextMock.CreateAndSetupDbSetMock(Array.Empty(), out var fileDbSetMock) + .Setup(x => x.SaveEntitiesAsync(It.IsAny())) + .Throws(); + _fileServiceMock.Setup(x => x.UploadAsync(It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny())) + .ReturnsAsync(file); + + var sut = new CreateFile.Handler(_dbContextMock.Object, _fileServiceMock.Object); + var action = () => sut.Handle(Command, new CancellationToken()); + + await action.Should() + .ThrowAsync(); + + _fileServiceMock.Verify(x => x.UploadAsync(It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny()), + Times.Once); + fileDbSetMock.Verify(x => x.Attach(It.IsAny()), + Times.Once); + } +} \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/File/CreateFileValidatorTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/File/CreateFileValidatorTests.cs new file mode 100644 index 0000000..466ed01 --- /dev/null +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/File/CreateFileValidatorTests.cs @@ -0,0 +1,61 @@ +using FluentAssertions; +using FluentValidation; +using FluentValidation.TestHelper; +using Monaco.Template.Backend.Application.Features.File; +using Moq; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Threading.Tasks; +using Xunit; + +namespace Monaco.Template.Backend.Application.Tests.Features.File; + +[ExcludeFromCodeCoverage] +[Trait("Application Commands - File", "Create")] +public class CreateFileValidatorTests +{ + private static readonly CreateFile.Command Command = new(It.IsAny(), // Stream + It.IsAny(), // FileName + It.IsAny()); // ContentType + + [Fact(DisplayName = "Validator's rule level cascade mode is 'Stop'")] + public void ValidatorRuleLevelCascadeModeIsStop() + { + var sut = new CreateFile.Validator(); + + sut.RuleLevelCascadeMode + .Should() + .Be(CascadeMode.Stop); + } + + [Fact(DisplayName = "Stream being valid does not generate validation error")] + public async Task StreamDoesNotGenerateErrorWhenValid() + { + var command = Command with + { + Stream = new MemoryStream("Content"u8.ToArray()) + }; + + var sut = new CreateFile.Validator(); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.Stream)); + + validationResult.ShouldNotHaveValidationErrorFor(cmd => cmd.Stream); + } + + [Fact(DisplayName = "Stream empty generates validation error")] + public async Task StreamEmptyGeneratesError() + { + var command = Command with + { + Stream = new MemoryStream() + }; + + var sut = new CreateFile.Validator(); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.Stream)); + + validationResult.ShouldHaveValidationErrorFor(cmd => cmd.Stream) + .WithErrorCode("PredicateValidator") + .Should() + .HaveCount(1); + } +} \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/CreateProductHandlerTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/CreateProductHandlerTests.cs new file mode 100644 index 0000000..71afec2 --- /dev/null +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/CreateProductHandlerTests.cs @@ -0,0 +1,65 @@ +using FluentAssertions; +using Monaco.Template.Backend.Application.Features.Product; +using Monaco.Template.Backend.Application.Infrastructure.Context; +using Monaco.Template.Backend.Application.Services.Contracts; +using Monaco.Template.Backend.Common.Tests; +using Monaco.Template.Backend.Common.Tests.Factories; +using Monaco.Template.Backend.Domain.Model; +using Moq; +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Xunit; + +namespace Monaco.Template.Backend.Application.Tests.Features.Product; + +[ExcludeFromCodeCoverage] +[Trait("Application Commands - Product", "Create")] +public class CreateProductHandlerTests +{ + private readonly Mock _dbContextMock = new(); + private readonly Mock _fileServiceMock = new(); + private static readonly CreateProduct.Command Command = new(It.IsAny(), // Title + It.IsAny(), // Description + It.IsAny(), // Price + It.IsAny(), // CompanyId + It.IsAny(), // Pictures + It.IsAny()); // DefaultPictureId + + + [Theory(DisplayName = "Create new Product succeeds")] + [AnonymousData] + public async Task CreateNewProductSucceeds(Domain.Model.Company company, Image[] pictures) + { + _dbContextMock.CreateAndSetupDbSetMock(new List(), out var productDbSetMock) + .CreateAndSetupDbSetMock(company) + .CreateAndSetupDbSetMock(pictures); + + var command = Command with + { + CompanyId = company.Id, + Pictures = pictures.Select(x => x.Id) + .ToArray(), + DefaultPictureId = pictures.First() + .Id + }; + + var sut = new CreateProduct.Handler(_dbContextMock.Object, _fileServiceMock.Object); + var result = await sut.Handle(command, new CancellationToken()); + + productDbSetMock.Verify(x => x.Attach(It.IsAny()), Times.Once); + _dbContextMock.Verify(x => x.SaveEntitiesAsync(It.IsAny()), Times.Once); + _fileServiceMock.Verify(x => x.MakePermanentImagesAsync(It.IsAny(), It.IsAny()), Times.Once); + + result.ValidationResult + .IsValid + .Should() + .BeTrue(); + result.ItemNotFound + .Should() + .BeFalse(); + } +} \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/CreateProductValidatorTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/CreateProductValidatorTests.cs new file mode 100644 index 0000000..28b6c79 --- /dev/null +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/CreateProductValidatorTests.cs @@ -0,0 +1,389 @@ +using FluentAssertions; +using FluentValidation; +using FluentValidation.TestHelper; +using Monaco.Template.Backend.Application.Features.Product; +using Monaco.Template.Backend.Application.Infrastructure.Context; +using Monaco.Template.Backend.Common.Tests; +using Monaco.Template.Backend.Common.Tests.Factories; +using Monaco.Template.Backend.Domain.Model; +using Moq; +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Threading.Tasks; +using Xunit; + +namespace Monaco.Template.Backend.Application.Tests.Features.Product; + +[ExcludeFromCodeCoverage] +[Trait("Application Commands - Product", "Create")] +public class CreateProductValidatorTests +{ + private readonly Mock _dbContextMock = new(); + private static readonly CreateProduct.Command Command = new(It.IsAny(), // Title + It.IsAny(), // Description + It.IsAny(), // Price + It.IsAny(), // CompanyId + It.IsAny(), // Pictures + It.IsAny()); // DefaultPictureId + + [Fact(DisplayName = "Validator's rule level cascade mode is 'Stop'")] + public void ValidatorRuleLevelCascadeModeIsStop() + { + var sut = new CreateProduct.Validator(new Mock().Object); + + sut.RuleLevelCascadeMode + .Should() + .Be(CascadeMode.Stop); + } + + [Fact(DisplayName = "Title being valid does not generate validation error")] + public async Task TitleDoesNotGenerateErrorWhenValid() + { + _dbContextMock.CreateAndSetupDbSetMock(new List()); + + var command = Command with + { + Title = new string(It.IsAny(), 100) + }; + + var sut = new CreateProduct.Validator(_dbContextMock.Object); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.Title)); + + validationResult.ShouldNotHaveValidationErrorFor(cmd => cmd.Title); + } + + [Fact(DisplayName = "Title with empty value generates validation error")] + public async Task TitleIsEmptyGeneratesError() + { + var command = Command with + { + Title = string.Empty + }; + + var sut = new CreateProduct.Validator(new Mock().Object); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.Title)); + + validationResult.ShouldHaveValidationErrorFor(cmd => cmd.Title) + .WithErrorCode("NotEmptyValidator") + .Should() + .HaveCount(1); + } + + [Fact(DisplayName = "Title with long value generates validation error")] + public async Task TitleWithLongValueGeneratesError() + { + var command = Command with + { + Title = new string(It.IsAny(), 101) + }; + + var sut = new CreateProduct.Validator(new Mock().Object); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.Title)); + + validationResult.ShouldHaveValidationErrorFor(cmd => cmd.Title) + .WithErrorCode("MaximumLengthValidator") + .WithMessageArgument("MaxLength", 100) + .Should() + .HaveCount(1); + } + + [Theory(DisplayName = "Title which already exists generates validation error")] + [AnonymousData] + public async Task TitleAlreadyExistsGeneratesError(Domain.Model.Product product) + { + _dbContextMock.CreateAndSetupDbSetMock(product); + + var command = Command with + { + Title = product.Title + }; + + var sut = new CreateProduct.Validator(_dbContextMock.Object); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.Title)); + + validationResult.ShouldHaveValidationErrorFor(cmd => cmd.Title) + .WithErrorCode("AsyncPredicateValidator") + .Should() + .HaveCount(1); + } + + [Fact(DisplayName = "Description being valid does not generate validation error")] + public async Task DescriptionDoesNotGenerateErrorWhenValid() + { + _dbContextMock.CreateAndSetupDbSetMock(new List()); + + var command = Command with + { + Description = new string(It.IsAny(), 100) + }; + + var sut = new CreateProduct.Validator(_dbContextMock.Object); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.Description)); + + validationResult.ShouldNotHaveValidationErrorFor(cmd => cmd.Description); + } + + [Fact(DisplayName = "Description with empty value generates validation error")] + public async Task DescriptionIsEmptyGeneratesError() + { + var command = Command with + { + Description = string.Empty + }; + + var sut = new CreateProduct.Validator(new Mock().Object); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.Description)); + + validationResult.ShouldHaveValidationErrorFor(cmd => cmd.Description) + .WithErrorCode("NotEmptyValidator") + .Should() + .HaveCount(1); + } + + [Fact(DisplayName = "Description with long value generates validation error")] + public async Task DescriptionWithLongValueGeneratesError() + { + var command = Command with + { + Description = new string(It.IsAny(), 501) + }; + + var sut = new CreateProduct.Validator(new Mock().Object); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.Description)); + + validationResult.ShouldHaveValidationErrorFor(cmd => cmd.Description) + .WithErrorCode("MaximumLengthValidator") + .WithMessageArgument("MaxLength", 500) + .Should() + .HaveCount(1); + } + + [Fact(DisplayName = "Price being valid does not generate validation error")] + public async Task PriceDoesNotGenerateErrorWhenValid() + { + _dbContextMock.CreateAndSetupDbSetMock(new List()); + + var command = Command with + { + Price = 1m + }; + + var sut = new CreateProduct.Validator(_dbContextMock.Object); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.Price)); + + validationResult.ShouldNotHaveValidationErrorFor(cmd => cmd.Price); + } + + [Fact(DisplayName = "Price with negative value generates validation error")] + public async Task PriceIsNegativeGeneratesError() + { + + var command = Command with + { + Price = -1m + }; + + var sut = new CreateProduct.Validator(new Mock().Object); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.Price)); + + validationResult.ShouldHaveValidationErrorFor(cmd => cmd.Price) + .WithErrorCode("GreaterThanOrEqualValidator") + .Should() + .HaveCount(1); + } + + [Theory(DisplayName = "CompanyId being valid does not generate validation error")] + [AnonymousData(true)] + public async Task CompanyIdDoesNotGenerateErrorWhenValid(Domain.Model.Company[] companies) + { + _dbContextMock.CreateAndSetupDbSetMock(companies); + + var command = Command with + { + CompanyId = companies.First().Id + }; + + var sut = new CreateProduct.Validator(_dbContextMock.Object); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.CompanyId)); + + validationResult.ShouldNotHaveValidationErrorFor(cmd => cmd.CompanyId); + } + + [Fact(DisplayName = "CompanyId with empty value generates validation error")] + public async Task CompanyIdIsEmptyGeneratesError() + { + var sut = new CreateProduct.Validator(_dbContextMock.Object); + var validationResult = await sut.TestValidateAsync(Command, strategy => strategy.IncludeProperties(cmd => cmd.CompanyId)); + + validationResult.ShouldHaveValidationErrorFor(cmd => cmd.CompanyId) + .WithErrorCode("NotEmptyValidator") + .Should() + .HaveCount(1); + } + + [Fact(DisplayName = "CompanyId with non-existing value generates validation error")] + public async Task CompanyIdNotExistsGeneratesError() + { + _dbContextMock.CreateAndSetupDbSetMock(new List()); + + var command = Command with + { + CompanyId = Guid.NewGuid() + }; + + var sut = new CreateProduct.Validator(_dbContextMock.Object); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.CompanyId)); + + validationResult.ShouldHaveValidationErrorFor(cmd => cmd.CompanyId) + .WithErrorCode("AsyncPredicateValidator") + .Should() + .HaveCount(1); + } + + [Theory(DisplayName = "Pictures being valid does not generate validation error")] + [AnonymousData(true)] + public async Task PicturesDoesNotGenerateErrorWhenValid(Domain.Model.Product[] products, Image[] newPictures) + { + _dbContextMock.CreateAndSetupDbSetMock(products); + _dbContextMock.CreateAndSetupDbSetMock(newPictures); + + var picturesIds = newPictures.Select(x => x.Id) + .ToArray(); + + var command = Command with + { + Pictures = picturesIds + }; + + var sut = new CreateProduct.Validator(_dbContextMock.Object); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.Pictures)); + + validationResult.ShouldNotHaveValidationErrorFor(cmd => cmd.Pictures); + } + + [Fact(DisplayName = "Pictures empty array generates validation error")] + public async Task PictureArrayEmptyGeneratesError() + { + var command = Command with + { + Pictures = Array.Empty() + }; + + var sut = new CreateProduct.Validator(_dbContextMock.Object); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.Pictures)); + + validationResult.ShouldHaveValidationErrorFor(cmd => cmd.Pictures) + .WithErrorCode("NotEmptyValidator") + .Should() + .HaveCount(1); + } + + [Fact(DisplayName = "Pictures with empty element generates validation error")] + public async Task PictureEmptyElementGeneratesError() + { + var command = Command with + { + Pictures = new []{ Guid.Empty } + }; + + var sut = new CreateProduct.Validator(_dbContextMock.Object); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.Pictures)); + + validationResult.ShouldHaveValidationErrorFor(cmd => cmd.Pictures) + .WithErrorCode("NotEmptyValidator") + .Should() + .HaveCount(1); + } + + [Fact(DisplayName = "Pictures with non-existing element generates validation error")] + public async Task PicturesWithNonExistingElementGeneratesError() + { + _dbContextMock.CreateAndSetupDbSetMock(new List()); + + var command = Command with + { + Pictures = new[] { Guid.NewGuid() } + }; + + var sut = new CreateProduct.Validator(_dbContextMock.Object); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.Pictures)); + + validationResult.ShouldHaveValidationErrorFor(cmd => cmd.Pictures) + .WithErrorCode("AsyncPredicateValidator") + .Should() + .HaveCount(1); + } + + [Theory(DisplayName = "Pictures with another product's picture generates validation error")] + [AnonymousData(true)] + public async Task PicturesWithAnotherProductPictureGeneratesError(Domain.Model.Product[] products) + { + _dbContextMock.CreateAndSetupDbSetMock(new List()); + + var command = Command with + { + Pictures = [Guid.NewGuid()] + }; + + var sut = new CreateProduct.Validator(_dbContextMock.Object); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.Pictures)); + + validationResult.ShouldHaveValidationErrorFor(cmd => cmd.Pictures) + .WithErrorCode("AsyncPredicateValidator") + .Should() + .HaveCount(1); + } + + [Theory(DisplayName = "Default Picture being valid does not generate validation error")] + [AnonymousData(true)] + public async Task DefaultPictureDoesNotGenerateErrorWhenValid(Guid[] picturesIds) + { + var command = Command with + { + Pictures = picturesIds, + DefaultPictureId = picturesIds.First() + }; + + var sut = new CreateProduct.Validator(_dbContextMock.Object); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.DefaultPictureId)); + + validationResult.ShouldNotHaveValidationErrorFor(cmd => cmd.DefaultPictureId); + } + + [Fact(DisplayName = "Default Picture with empty value generates validation error")] + public async Task DefaultPictureIsEmptyGeneratesError() + { + var command = Command with + { + DefaultPictureId = Guid.Empty + }; + + var sut = new CreateProduct.Validator(_dbContextMock.Object); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.DefaultPictureId)); + + validationResult.ShouldHaveValidationErrorFor(cmd => cmd.DefaultPictureId) + .WithErrorCode("NotEmptyValidator") + .Should() + .HaveCount(1); + } + + [Fact(DisplayName = "Default Picture with non-existing value generates validation error")] + public async Task DefaultPictureNotExistsGeneratesError() + { + var command = Command with + { + Pictures = new[] { Guid.NewGuid() }, + DefaultPictureId = Guid.NewGuid() + }; + + var sut = new CreateProduct.Validator(_dbContextMock.Object); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.DefaultPictureId)); + + validationResult.ShouldHaveValidationErrorFor(cmd => cmd.DefaultPictureId) + .WithErrorCode("PredicateValidator") + .Should() + .HaveCount(1); + } +} \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/DeleteProductHandlerTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/DeleteProductHandlerTests.cs new file mode 100644 index 0000000..5dd3bc2 --- /dev/null +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/DeleteProductHandlerTests.cs @@ -0,0 +1,64 @@ +using FluentAssertions; +using Monaco.Template.Backend.Application.Features.Product; +using Monaco.Template.Backend.Application.Infrastructure.Context; +using Monaco.Template.Backend.Application.Services.Contracts; +using Monaco.Template.Backend.Common.Tests; +using Monaco.Template.Backend.Common.Tests.Factories; +using Monaco.Template.Backend.Domain.Model; +using Moq; +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Xunit; + +namespace Monaco.Template.Backend.Application.Tests.Features.Product; + +[ExcludeFromCodeCoverage] +[Trait("Application Commands - Product", "Delete")] +public class DeleteProductHandlerTests +{ + private readonly Mock _dbContextMock = new(); + private readonly Mock _fileServiceMock = new(); + private static readonly DeleteProduct.Command Command = new(It.IsAny()); // Id + + + [Theory(DisplayName = "Delete existing Product succeeds")] + [AnonymousData(true)] + public async Task DeleteExistingProductSucceeds(Domain.Model.Product product) + { + var pictures = product.Pictures + .Union(product.Pictures + .Select(x => x.Thumbnail!)) + .ToArray(); + _dbContextMock.CreateAndSetupDbSetMock(product, out var productDbSetMock) + .CreateAndSetupDbSetMock(pictures, out var imageDbSetMock); + + var command = Command with + { + Id = product.Id + }; + + var sut = new DeleteProduct.Handler(_dbContextMock.Object, _fileServiceMock.Object); + var result = await sut.Handle(command, new CancellationToken()); + + productDbSetMock.Verify(x => x.Remove(It.IsAny()), + Times.Once); + imageDbSetMock.Verify(x => x.RemoveRange(It.IsAny>()), + Times.Once); + _dbContextMock.Verify(x => x.SaveEntitiesAsync(It.IsAny()), + Times.Once); + _fileServiceMock.Verify(x => x.DeleteImagesAsync(It.IsAny(), It.IsAny()), + Times.Once); + + result.ValidationResult + .IsValid + .Should() + .BeTrue(); + result.ItemNotFound + .Should() + .BeFalse(); + } +} \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/DeleteProductValidatorTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/DeleteProductValidatorTests.cs new file mode 100644 index 0000000..40ef939 --- /dev/null +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/DeleteProductValidatorTests.cs @@ -0,0 +1,73 @@ +using FluentAssertions; +using FluentValidation; +using FluentValidation.TestHelper; +using Monaco.Template.Backend.Application.Features.Product; +using Monaco.Template.Backend.Application.Infrastructure.Context; +using Monaco.Template.Backend.Common.Application.Validators.Extensions; +using Monaco.Template.Backend.Common.Tests; +using Monaco.Template.Backend.Common.Tests.Factories; +using Moq; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Threading.Tasks; +using Xunit; + +namespace Monaco.Template.Backend.Application.Tests.Features.Product; + +[ExcludeFromCodeCoverage] +[Trait("Application Commands - Product", "Delete")] +public class DeleteProductValidatorTests +{ + private readonly Mock _dbContextMock = new(); + private static readonly DeleteProduct.Command Command = new(It.IsAny()); // Id + + [Fact(DisplayName = "Validator's rule level cascade mode is 'Stop'")] + public void ValidatorRuleLevelCascadeModeIsStop() + { + var sut = new DeleteProduct.Validator(new Mock().Object); + + sut.RuleLevelCascadeMode + .Should() + .Be(CascadeMode.Stop); + } + + [Theory(DisplayName = "Existing Product passes validation correctly")] + [AnonymousData] + public async Task ExistingProductPassesValidationCorrectly(Domain.Model.Product product) + { + _dbContextMock.CreateAndSetupDbSetMock(product); + + var command = Command with + { + Id = product.Id + }; + + var sut = new DeleteProduct.Validator(_dbContextMock.Object); + var validationResult = await sut.TestValidateAsync(command, s => s.IncludeRuleSets(ValidatorsExtensions.ExistsRulesetName)); + + validationResult.RuleSetsExecuted + .Should() + .Contain(ValidatorsExtensions.ExistsRulesetName); + validationResult.ShouldNotHaveAnyValidationErrors(); + } + + [Theory(DisplayName = "Non existing Product generates validation error")] + [AnonymousData] + public async Task NonExistingProductGeneratesError(Domain.Model.Product product, Guid id) + { + _dbContextMock.CreateAndSetupDbSetMock(product); + + var command = Command with + { + Id = id + }; + + var sut = new DeleteProduct.Validator(_dbContextMock.Object); + var validationResult = await sut.TestValidateAsync(command, s => s.IncludeRuleSets(ValidatorsExtensions.ExistsRulesetName)); + + validationResult.RuleSetsExecuted + .Should() + .Contain(ValidatorsExtensions.ExistsRulesetName); + validationResult.ShouldHaveValidationErrorFor(x => x.Id); + } +} \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/DownloadProductPictureTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/DownloadProductPictureTests.cs new file mode 100644 index 0000000..64d9963 --- /dev/null +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/DownloadProductPictureTests.cs @@ -0,0 +1,97 @@ +using FluentAssertions; +using Microsoft.Extensions.Primitives; +using Monaco.Template.Backend.Application.Features.Product; +using Monaco.Template.Backend.Application.Infrastructure.Context; +using Monaco.Template.Backend.Application.Services.Contracts; +using Monaco.Template.Backend.Common.Application.DTOs; +using Monaco.Template.Backend.Common.Tests; +using Monaco.Template.Backend.Common.Tests.Factories; +using Moq; +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.IO; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Xunit; + +namespace Monaco.Template.Backend.Application.Tests.Features.Product; + +[ExcludeFromCodeCoverage] +[Trait("Application Queries - Product", "Download Product Picture")] +public class DownloadProductPictureTests +{ + private readonly Mock _dbContextMock = new(); + private readonly Mock _fileServiceMock = new(); + + [Theory(DisplayName = "Get existing product picture succeeds")] + [AnonymousData(true)] + public async Task GetExistingProductPictureSucceeds(List products, string contentType) + { + _dbContextMock.CreateAndSetupDbSetMock(products); + + var product = products.First(); + var picture = product.Pictures.First(); + var pictureFileName = $"{picture.Name}{picture.Extension}"; + + _fileServiceMock.Setup(x => x.DownloadFileAsync(It.IsAny(), It.IsAny())) + .ReturnsAsync(new FileDownloadDto(new MemoryStream(), pictureFileName, contentType)); + + var query = new DownloadProductPicture.Query(product.Id, + picture.Id, + Array.Empty>()); + + var sut = new DownloadProductPicture.Handler(_dbContextMock.Object, _fileServiceMock.Object); + var result = await sut.Handle(query, new CancellationToken()); + + result.Should() + .NotBeNull(); + result!.FileName + .Should() + .Be(pictureFileName); + } + + [Theory(DisplayName = "Get existing product picture thumbnail succeeds")] + [AnonymousData(true)] + public async Task GetExistingProductPictureThumbnailSucceeds(Domain.Model.Product[] products, string contentType) + { + _dbContextMock.CreateAndSetupDbSetMock(products); + + var product = products.First(); + var picture = product.Pictures.First(); + var pictureFileName = $"{picture.Name}{picture.Extension}"; + + _fileServiceMock.Setup(x => x.DownloadFileAsync(It.IsAny(), It.IsAny())) + .ReturnsAsync(new FileDownloadDto(new MemoryStream(), pictureFileName, contentType)); + + var query = new DownloadProductPicture.Query(product.Id, + picture.Id, + new []{ new KeyValuePair("thumbnail", "true") }); + + var sut = new DownloadProductPicture.Handler(_dbContextMock.Object, _fileServiceMock.Object); + var result = await sut.Handle(query, new CancellationToken()); + + result.Should() + .NotBeNull(); + result!.FileName + .Should() + .Be(pictureFileName); + } + + [Theory(DisplayName = "Get non-existing product picture fails")] + [AnonymousData(true)] + public async Task GetNonExistingProductByIdFails(List products) + { + _dbContextMock.CreateAndSetupDbSetMock(products); + var query = new DownloadProductPicture.Query(Guid.NewGuid(), + Guid.NewGuid(), + Array.Empty>()); + + var sut = new DownloadProductPicture.Handler(_dbContextMock.Object, _fileServiceMock.Object); + var result = await sut.Handle(query, new CancellationToken()); + + result.Should() + .BeNull(); + } +} \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/EditProductHandlerTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/EditProductHandlerTests.cs new file mode 100644 index 0000000..09e57a5 --- /dev/null +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/EditProductHandlerTests.cs @@ -0,0 +1,80 @@ +using FluentAssertions; +using Monaco.Template.Backend.Application.Features.Product; +using Monaco.Template.Backend.Application.Infrastructure.Context; +using Monaco.Template.Backend.Application.Services.Contracts; +using Monaco.Template.Backend.Common.Tests; +using Monaco.Template.Backend.Common.Tests.Factories; +using Monaco.Template.Backend.Domain.Model; +using Moq; +using System; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Xunit; + +namespace Monaco.Template.Backend.Application.Tests.Features.Product; + +[ExcludeFromCodeCoverage] +[Trait("Application Commands - Product", "Edit")] +public class EditProductHandlerTests +{ + private readonly Mock _dbContextMock = new(); + private readonly Mock _fileServiceMock = new(); + private static readonly EditProduct.Command Command = new(It.IsAny(), // Id + It.IsAny(), // Title + It.IsAny(), // Description + It.IsAny(), // Price + It.IsAny(), // CompanyId + It.IsAny(), // Pictures + It.IsAny()); // DefaultPictureId + + + [Theory(DisplayName = "Edit existing Product succeeds")] + [AnonymousData(true)] + public async Task CreateNewProductSucceeds(Domain.Model.Company company, + Image[] pictures) + { + _dbContextMock.CreateEntityMockAndSetupDbSetMock(out var productMock) + .CreateAndSetupDbSetMock(company) + .CreateAndSetupDbSetMock(pictures); + productMock.SetupGet(x => x.Pictures) + .Returns(pictures); + productMock.SetupGet(x => x.Company) + .Returns(company); + + var product = productMock.Object; + + var command = Command with + { + Id = product.Id, + CompanyId = product.Company.Id, + Pictures = pictures.Select(x => x.Id) + .ToArray(), + DefaultPictureId = pictures.First() + .Id + }; + + var sut = new EditProduct.Handler(_dbContextMock.Object, _fileServiceMock.Object); + var result = await sut.Handle(command, new CancellationToken()); + + productMock.Verify(x => x.Update(It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny())); + _dbContextMock.Verify(x => x.SaveEntitiesAsync(It.IsAny()), + Times.Once); + _fileServiceMock.Verify(x => x.DeleteImagesAsync(It.IsAny(), It.IsAny()), + Times.Once); + _fileServiceMock.Verify(x => x.MakePermanentImagesAsync(It.IsAny(), It.IsAny()), + Times.Once); + + result.ValidationResult + .IsValid + .Should() + .BeTrue(); + result.ItemNotFound + .Should() + .BeFalse(); + } +} \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/EditProductValidatorTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/EditProductValidatorTests.cs new file mode 100644 index 0000000..cd47079 --- /dev/null +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/EditProductValidatorTests.cs @@ -0,0 +1,434 @@ +using FluentAssertions; +using FluentValidation; +using FluentValidation.TestHelper; +using Monaco.Template.Backend.Application.Features.Product; +using Monaco.Template.Backend.Application.Infrastructure.Context; +using Monaco.Template.Backend.Common.Application.Validators.Extensions; +using Monaco.Template.Backend.Common.Tests; +using Monaco.Template.Backend.Common.Tests.Factories; +using Monaco.Template.Backend.Domain.Model; +using Moq; +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Threading.Tasks; +using Xunit; + +namespace Monaco.Template.Backend.Application.Tests.Features.Product; + +[ExcludeFromCodeCoverage] +[Trait("Application Commands - Product", "Edit")] +public class EditProductValidatorTests +{ + private readonly Mock _dbContextMock = new(); + private static readonly EditProduct.Command Command = new(It.IsAny(), // Id + It.IsAny(), // Title + It.IsAny(), // Description + It.IsAny(), // Price + It.IsAny(), // CompanyId + It.IsAny(), // Pictures + It.IsAny()); // DefaultPictureId + + [Fact(DisplayName = "Validator's rule level cascade mode is 'Stop'")] + public void ValidatorRuleLevelCascadeModeIsStop() + { + var sut = new EditProduct.Validator(new Mock().Object); + + sut.RuleLevelCascadeMode + .Should() + .Be(CascadeMode.Stop); + } + + [Theory(DisplayName = "Existing Product passes validation correctly")] + [AnonymousData] + public async Task ExistingProductPassesValidationCorrectly(Domain.Model.Product product) + { + _dbContextMock.CreateAndSetupDbSetMock(product); + + var command = Command with + { + Id = product.Id + }; + + var sut = new EditProduct.Validator(_dbContextMock.Object); + var validationResult = await sut.TestValidateAsync(command, s => s.IncludeRuleSets(ValidatorsExtensions.ExistsRulesetName)); + + validationResult.RuleSetsExecuted + .Should() + .Contain(ValidatorsExtensions.ExistsRulesetName); + validationResult.ShouldNotHaveAnyValidationErrors(); + } + + [Theory(DisplayName = "Non existing Product generates validation error")] + [AnonymousData] + public async Task NonExistingProductGeneratesError(Domain.Model.Product product, Guid id) + { + _dbContextMock.CreateAndSetupDbSetMock(product); + + var command = Command with + { + Id = id + }; + + var sut = new EditProduct.Validator(_dbContextMock.Object); + var validationResult = await sut.TestValidateAsync(command, s => s.IncludeRuleSets(ValidatorsExtensions.ExistsRulesetName)); + + validationResult.RuleSetsExecuted + .Should() + .Contain(ValidatorsExtensions.ExistsRulesetName); + validationResult.ShouldHaveValidationErrorFor(x => x.Id); + } + + [Theory(DisplayName = "Title being valid does not generate validation error")] + [AnonymousData(true)] + public async Task TitleDoesNotGenerateErrorWhenValid(Domain.Model.Product product, Guid id) + { + _dbContextMock.CreateAndSetupDbSetMock(product); + + var command = Command with + { + Id = id, + Title = new string(It.IsAny(), 100) + }; + + var sut = new EditProduct.Validator(_dbContextMock.Object); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.Title)); + + validationResult.ShouldNotHaveValidationErrorFor(cmd => cmd.Title); + } + + [Fact(DisplayName = "Title with empty value generates validation error")] + public async Task TitleIsEmptyGeneratesError() + { + var command = Command with + { + Title = string.Empty + }; + + var sut = new EditProduct.Validator(new Mock().Object); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.Title)); + + validationResult.ShouldHaveValidationErrorFor(cmd => cmd.Title) + .WithErrorCode("NotEmptyValidator") + .Should() + .HaveCount(1); + } + + [Fact(DisplayName = "Title with long value generates validation error")] + public async Task TitleWithLongValueGeneratesError() + { + var command = Command with + { + Title = new string(It.IsAny(), 101) + }; + + var sut = new EditProduct.Validator(new Mock().Object); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.Title)); + + validationResult.ShouldHaveValidationErrorFor(cmd => cmd.Title) + .WithErrorCode("MaximumLengthValidator") + .WithMessageArgument("MaxLength", 100) + .Should() + .HaveCount(1); + } + + [Theory(DisplayName = "Title which already exists generates validation error")] + [AnonymousData(true)] + public async Task TitleAlreadyExistsGeneratesError(Domain.Model.Product product, Guid id) + { + _dbContextMock.CreateAndSetupDbSetMock(product); + + var command = Command with + { + Id = id, + Title = product.Title + }; + + var sut = new EditProduct.Validator(_dbContextMock.Object); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.Title)); + + validationResult.ShouldHaveValidationErrorFor(cmd => cmd.Title) + .WithErrorCode("AsyncPredicateValidator") + .Should() + .HaveCount(1); + } + + [Fact(DisplayName = "Description being valid does not generate validation error")] + public async Task DescriptionDoesNotGenerateErrorWhenValid() + { + _dbContextMock.CreateAndSetupDbSetMock(new List()); + + var command = Command with + { + Description = new string(It.IsAny(), 100) + }; + + var sut = new EditProduct.Validator(_dbContextMock.Object); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.Description)); + + validationResult.ShouldNotHaveValidationErrorFor(cmd => cmd.Description); + } + + [Fact(DisplayName = "Description with empty value generates validation error")] + public async Task DescriptionIsEmptyGeneratesError() + { + var command = Command with + { + Description = string.Empty + }; + + var sut = new EditProduct.Validator(new Mock().Object); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.Description)); + + validationResult.ShouldHaveValidationErrorFor(cmd => cmd.Description) + .WithErrorCode("NotEmptyValidator") + .Should() + .HaveCount(1); + } + + [Fact(DisplayName = "Description with long value generates validation error")] + public async Task DescriptionWithLongValueGeneratesError() + { + var command = Command with + { + Description = new string(It.IsAny(), 501) + }; + + var sut = new EditProduct.Validator(new Mock().Object); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.Description)); + + validationResult.ShouldHaveValidationErrorFor(cmd => cmd.Description) + .WithErrorCode("MaximumLengthValidator") + .WithMessageArgument("MaxLength", 500) + .Should() + .HaveCount(1); + } + + [Fact(DisplayName = "Price being valid does not generate validation error")] + public async Task PriceDoesNotGenerateErrorWhenValid() + { + _dbContextMock.CreateAndSetupDbSetMock(new List()); + + var command = Command with + { + Price = 1m + }; + + var sut = new EditProduct.Validator(_dbContextMock.Object); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.Price)); + + validationResult.ShouldNotHaveValidationErrorFor(cmd => cmd.Price); + } + + [Fact(DisplayName = "Price with negative value generates validation error")] + public async Task PriceIsNegativeGeneratesError() + { + + var command = Command with + { + Price = -1m + }; + + var sut = new EditProduct.Validator(new Mock().Object); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.Price)); + + validationResult.ShouldHaveValidationErrorFor(cmd => cmd.Price) + .WithErrorCode("GreaterThanOrEqualValidator") + .Should() + .HaveCount(1); + } + + [Theory(DisplayName = "CompanyId being valid does not generate validation error")] + [AnonymousData(true)] + public async Task CompanyIdDoesNotGenerateErrorWhenValid(Domain.Model.Company[] companies) + { + _dbContextMock.CreateAndSetupDbSetMock(companies); + + var command = Command with + { + CompanyId = companies.First().Id + }; + + var sut = new EditProduct.Validator(_dbContextMock.Object); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.CompanyId)); + + validationResult.ShouldNotHaveValidationErrorFor(cmd => cmd.CompanyId); + } + + [Fact(DisplayName = "CompanyId with empty value generates validation error")] + public async Task CompanyIdIsEmptyGeneratesError() + { + var sut = new EditProduct.Validator(_dbContextMock.Object); + var validationResult = await sut.TestValidateAsync(Command, strategy => strategy.IncludeProperties(cmd => cmd.CompanyId)); + + validationResult.ShouldHaveValidationErrorFor(cmd => cmd.CompanyId) + .WithErrorCode("NotEmptyValidator") + .Should() + .HaveCount(1); + } + + [Fact(DisplayName = "CompanyId with non-existing value generates validation error")] + public async Task CompanyIdNotExistsGeneratesError() + { + _dbContextMock.CreateAndSetupDbSetMock(new List()); + + var command = Command with + { + CompanyId = Guid.NewGuid() + }; + + var sut = new EditProduct.Validator(_dbContextMock.Object); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.CompanyId)); + + validationResult.ShouldHaveValidationErrorFor(cmd => cmd.CompanyId) + .WithErrorCode("AsyncPredicateValidator") + .Should() + .HaveCount(1); + } + + [Theory(DisplayName = "Pictures being valid does not generate validation error")] + [AnonymousData(true)] + public async Task PicturesDoesNotGenerateErrorWhenValid(Domain.Model.Product[] products, Image[] newPictures) + { + _dbContextMock.CreateAndSetupDbSetMock(products); + _dbContextMock.CreateAndSetupDbSetMock(newPictures); + + var picturesIds = newPictures.Select(x => x.Id) + .ToArray(); + + var command = Command with + { + Pictures = picturesIds + }; + + var sut = new EditProduct.Validator(_dbContextMock.Object); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.Pictures)); + + validationResult.ShouldNotHaveValidationErrorFor(cmd => cmd.Pictures); + } + + [Fact(DisplayName = "Pictures empty array generates validation error")] + public async Task PictureArrayEmptyGeneratesError() + { + var command = Command with + { + Pictures = Array.Empty() + }; + + var sut = new EditProduct.Validator(_dbContextMock.Object); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.Pictures)); + + validationResult.ShouldHaveValidationErrorFor(cmd => cmd.Pictures) + .WithErrorCode("NotEmptyValidator") + .Should() + .HaveCount(1); + } + + [Fact(DisplayName = "Pictures with empty element generates validation error")] + public async Task PictureEmptyElementGeneratesError() + { + var command = Command with + { + Pictures = new []{ Guid.Empty } + }; + + var sut = new EditProduct.Validator(_dbContextMock.Object); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.Pictures)); + + validationResult.ShouldHaveValidationErrorFor(cmd => cmd.Pictures) + .WithErrorCode("NotEmptyValidator") + .Should() + .HaveCount(1); + } + + [Fact(DisplayName = "Pictures with non-existing element generates validation error")] + public async Task PicturesWithNonExistingElementGeneratesError() + { + _dbContextMock.CreateAndSetupDbSetMock(new List()); + + var command = Command with + { + Pictures = new[] { Guid.NewGuid() } + }; + + var sut = new EditProduct.Validator(_dbContextMock.Object); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.Pictures)); + + validationResult.ShouldHaveValidationErrorFor(cmd => cmd.Pictures) + .WithErrorCode("AsyncPredicateValidator") + .Should() + .HaveCount(1); + } + + [Theory(DisplayName = "Pictures with another product's picture generates validation error")] + [AnonymousData(true)] + public async Task PicturesWithAnotherProductPictureGeneratesError(Domain.Model.Product[] products) + { + _dbContextMock.CreateAndSetupDbSetMock(new List()); + + var command = Command with + { + Pictures = [Guid.NewGuid()] + }; + + var sut = new EditProduct.Validator(_dbContextMock.Object); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.Pictures)); + + validationResult.ShouldHaveValidationErrorFor(cmd => cmd.Pictures) + .WithErrorCode("AsyncPredicateValidator") + .Should() + .HaveCount(1); + } + + [Theory(DisplayName = "Default Picture being valid does not generate validation error")] + [AnonymousData(true)] + public async Task DefaultPictureDoesNotGenerateErrorWhenValid(Guid[] picturesIds) + { + var command = Command with + { + Pictures = picturesIds, + DefaultPictureId = picturesIds.First() + }; + + var sut = new EditProduct.Validator(_dbContextMock.Object); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.DefaultPictureId)); + + validationResult.ShouldNotHaveValidationErrorFor(cmd => cmd.DefaultPictureId); + } + + [Fact(DisplayName = "Default Picture with empty value generates validation error")] + public async Task DefaultPictureIsEmptyGeneratesError() + { + var command = Command with + { + DefaultPictureId = Guid.Empty + }; + + var sut = new EditProduct.Validator(_dbContextMock.Object); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.DefaultPictureId)); + + validationResult.ShouldHaveValidationErrorFor(cmd => cmd.DefaultPictureId) + .WithErrorCode("NotEmptyValidator") + .Should() + .HaveCount(1); + } + + [Fact(DisplayName = "Default Picture with non-existing value generates validation error")] + public async Task DefaultPictureNotExistsGeneratesError() + { + var command = Command with + { + Pictures = new[] { Guid.NewGuid() }, + DefaultPictureId = Guid.NewGuid() + }; + + var sut = new EditProduct.Validator(_dbContextMock.Object); + var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.DefaultPictureId)); + + validationResult.ShouldHaveValidationErrorFor(cmd => cmd.DefaultPictureId) + .WithErrorCode("PredicateValidator") + .Should() + .HaveCount(1); + } +} \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/GetProductByIdTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/GetProductByIdTests.cs new file mode 100644 index 0000000..f839c72 --- /dev/null +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/GetProductByIdTests.cs @@ -0,0 +1,50 @@ +using FluentAssertions; +using Monaco.Template.Backend.Application.Features.Product; +using Monaco.Template.Backend.Application.Infrastructure.Context; +using Monaco.Template.Backend.Common.Tests; +using Monaco.Template.Backend.Common.Tests.Factories; +using Moq; +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Xunit; + +namespace Monaco.Template.Backend.Application.Tests.Features.Product; + +[ExcludeFromCodeCoverage] +[Trait("Application Queries - Product", "Get Product By Id")] +public class GetProductByIdTests +{ + private readonly Mock _dbContextMock = new(); + + [Theory(DisplayName = "Get existing product by Id succeeds")] + [AnonymousData(true)] + public async Task GetExistingProductByIdSucceeds(List products) + { + _dbContextMock.CreateAndSetupDbSetMock(products); + var product = products.First(); + var query = new GetProductById.Query(product.Id); + + var sut = new GetProductById.Handler(_dbContextMock.Object); + var result = await sut.Handle(query, new CancellationToken()); + + result.Should().NotBeNull(); + result!.Title.Should().Be(product.Title); + } + + [Theory(DisplayName = "Get non-existing product by Id fails")] + [AnonymousData(true)] + public async Task GetNonExistingProductByIdFails(List products) + { + _dbContextMock.CreateAndSetupDbSetMock(products); + var query = new GetProductById.Query(Guid.NewGuid()); + + var sut = new GetProductById.Handler(_dbContextMock.Object); + var result = await sut.Handle(query, new CancellationToken()); + + result.Should().BeNull(); + } +} \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/GetProductPageTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/GetProductPageTests.cs new file mode 100644 index 0000000..b189f5b --- /dev/null +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/GetProductPageTests.cs @@ -0,0 +1,79 @@ +using FluentAssertions; +using Microsoft.Extensions.Primitives; +using Monaco.Template.Backend.Application.DTOs; +using Monaco.Template.Backend.Application.Features.Product; +using Monaco.Template.Backend.Application.Infrastructure.Context; +using Monaco.Template.Backend.Common.Tests; +using Monaco.Template.Backend.Common.Tests.Factories; +using Moq; +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Xunit; + +namespace Monaco.Template.Backend.Application.Tests.Features.Product; + +[ExcludeFromCodeCoverage] +[Trait("Application Queries - Product", "Get Product Page")] +public class GetProductPageTests +{ + private readonly Mock _dbContextMock = new(); + + [Theory(DisplayName = "Get product page without params succeeds")] + [AnonymousData] + public async Task GetProductPageWithoutParamsSucceeds(List products) + { + _dbContextMock.CreateAndSetupDbSetMock(products); + var query = new GetProductPage.Query(Array.Empty>()); + + var sut = new GetProductPage.Handler(_dbContextMock.Object); + var result = await sut.Handle(query, new CancellationToken()); + + result.Should().NotBeNull(); + result!.Pager.Count.Should().Be(products.Count); + result.Items + .Should() + .HaveCount(products.Count).And + .Contain(x => products.Any(c => c.Title == x.Title)).And + .BeInAscendingOrder(x => x.Title); + } + + [Theory(DisplayName = "Get product page with params succeeds")] + [AnonymousData(true)] + public async Task GetProductPageWithParamsSucceeds(List products) + { + _dbContextMock.CreateAndSetupDbSetMock(products); + var productsSet = products.GetRange(0, 2); + var query = new GetProductPage.Query(new KeyValuePair[] + { + new(nameof(ProductDto.Title), + new(productsSet.Select(x => x.Title) + .ToArray())), + new("expand", + new StringValues([ + nameof(ProductDto.Company), + nameof(ProductDto.Pictures), + nameof(ProductDto.DefaultPicture) + ])), + new("sort", $"-{nameof(ProductDto.Title)}") + }); + + var sut = new GetProductPage.Handler(_dbContextMock.Object); + var result = await sut.Handle(query, new CancellationToken()); + + result.Should() + .NotBeNull(); + result!.Pager + .Count + .Should() + .Be(productsSet.Count); + result.Items + .Should() + .HaveCount(productsSet.Count).And + .Contain(x => productsSet.Any(c => c.Title == x.Title)).And + .BeInDescendingOrder(x => x.Title); + } +} \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Monaco.Template.Backend.Application.Tests.csproj b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Monaco.Template.Backend.Application.Tests.csproj index 363c38e..b9195a4 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Monaco.Template.Backend.Application.Tests.csproj +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Monaco.Template.Backend.Application.Tests.csproj @@ -26,4 +26,8 @@ + + + + diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Services/FileServiceTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Services/FileServiceTests.cs index ab0d7c1..1693616 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Services/FileServiceTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Services/FileServiceTests.cs @@ -1,18 +1,19 @@ -using MockQueryable.Moq; -using Monaco.Template.Backend.Application.Infrastructure.Context; +using ExifLibrary; +using FluentAssertions; using Monaco.Template.Backend.Application.Services; using Monaco.Template.Backend.Common.BlobStorage; using Monaco.Template.Backend.Common.BlobStorage.Contracts; +using Monaco.Template.Backend.Common.Tests.Factories; using Monaco.Template.Backend.Domain.Model; using Moq; +using SkiaSharp; using System; -using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.IO; -using System.Linq; using System.Threading; using System.Threading.Tasks; using Xunit; +using File = Monaco.Template.Backend.Domain.Model.File; namespace Monaco.Template.Backend.Application.Tests.Services; @@ -20,93 +21,450 @@ namespace Monaco.Template.Backend.Application.Tests.Services; [Trait("Application Services", "File Service")] public class FileServiceTests { + //private readonly Mock _dbContextMock = new(); + private readonly Mock _blobStorageServiceMock = new(); + private const string TxtBase64 = "TW9uYWNvIFVuaXQgVGVzdCBGaWxlIGZvciBVcGxvYWQgZG9jdW1lbnQgc3VjY2VlZHMu"; + private const string ImgBase64 = "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"; + [Fact(DisplayName = "Upload image succeeds")] public async Task UploadImageSucceeds() { - var dbContextMock = new Mock(); - var imageDbSetMock = new List().AsQueryable().BuildMockDbSet(); - dbContextMock.Setup(x => x.Set()) - .Returns(imageDbSetMock.Object); - var blobStorageServiceMock = new Mock(); + var sut = new FileService(_blobStorageServiceMock.Object); + + await using var stream = new MemoryStream(Convert.FromBase64String(ImgBase64)); + await sut.UploadImageAsync(stream, "sample-image.png", "image/png", CancellationToken.None); + stream.Close(); + + _blobStorageServiceMock.Verify(x => x.UploadTempFileAsync(It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny()), + Times.Exactly(2)); + } - var sut = new FileService(dbContextMock.Object, blobStorageServiceMock.Object); + [Fact(DisplayName = "Uploading an image file uploads an image")] + public async Task UploadingImageFileUploadsImage() + { + _blobStorageServiceMock.Setup(x => x.GetFileType(It.IsAny())) + .Returns(FileTypeEnum.Image); - const string imgBase64 = "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"; + var sut = new FileService(_blobStorageServiceMock.Object); - await using var stream = new MemoryStream(Convert.FromBase64String(imgBase64)); - await sut.UploadImage(stream, "sample-image.png", "image/png", CancellationToken.None); + await using var stream = new MemoryStream(Convert.FromBase64String(ImgBase64)); + await sut.UploadAsync(stream, "sample-image.png", "image/png", CancellationToken.None); stream.Close(); - blobStorageServiceMock.Verify(x => x.UploadTempFileAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()), Times.Exactly(2)); - dbContextMock.Verify(x => x.Set().AddAsync(It.IsAny(), It.IsAny())); - dbContextMock.Verify(x => x.SaveEntitiesAsync(It.IsAny())); + _blobStorageServiceMock.Verify(x => x.UploadTempFileAsync(It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny()), + Times.Exactly(2)); } - + [Fact(DisplayName = "Upload document succeeds")] public async Task UploadDocumentSucceeds() { - var dbContextMock = new Mock(); - var documentDbSetMock = new List().AsQueryable().BuildMockDbSet(); - dbContextMock.Setup(x => x.Set()) - .Returns(documentDbSetMock.Object); - var blobStorageServiceMock = new Mock(); + var sut = new FileService(_blobStorageServiceMock.Object); + + await using var stream = new MemoryStream(Convert.FromBase64String(TxtBase64)); + await sut.UploadDocumentAsync(stream, "sample-text-file.txt", "text/plain", CancellationToken.None); + stream.Close(); + + _blobStorageServiceMock.Verify(x => x.UploadTempFileAsync(It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny()), + Times.Exactly(1)); + } + + [Fact(DisplayName = "Error while saving document deletes it from storage")] + public async Task ErrorSavingDocumentDeletesIt() + { + var sut = new FileService(_blobStorageServiceMock.Object); - var sut = new FileService(dbContextMock.Object, blobStorageServiceMock.Object); + await using var stream = new MemoryStream(Convert.FromBase64String(TxtBase64)); + var action = () => sut.UploadDocumentAsync(null, "sample-text-file.txt", "text/plain", CancellationToken.None); - const string txtBase64 = "TW9uYWNvIFVuaXQgVGVzdCBGaWxlIGZvciBVcGxvYWQgZG9jdW1lbnQgc3VjY2VlZHMu"; + await action.Should().ThrowAsync(); + _blobStorageServiceMock.Verify(x => x.UploadTempFileAsync(It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny()), + Times.Once); + _blobStorageServiceMock.Verify(x => x.DeleteAsync(It.IsAny(), + It.IsAny(), + It.IsAny()), + Times.Once); + } - await using var stream = new MemoryStream(Convert.FromBase64String(txtBase64)); - await sut.UploadDocument(stream, "sample-text-file.txt", "text/plain", CancellationToken.None); + [Fact(DisplayName = "Uploading a text file uploads a document")] + public async Task UploadingTextFileUploadsDocument() + { + var sut = new FileService(_blobStorageServiceMock.Object); + + await using var stream = new MemoryStream(Convert.FromBase64String(TxtBase64)); + await sut.UploadAsync(stream, "sample-text-file.txt", "text/plain", CancellationToken.None); stream.Close(); - blobStorageServiceMock.Verify(x => x.UploadTempFileAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()), Times.Exactly(1)); - dbContextMock.Verify(x => x.Set().AddAsync(It.IsAny(), It.IsAny())); - dbContextMock.Verify(x => x.SaveEntitiesAsync(It.IsAny())); + _blobStorageServiceMock.Verify(x => x.UploadTempFileAsync(It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny()), + Times.Exactly(1)); } - [Fact(DisplayName = "Uploading an image file uploads an image succeeds")] - public async Task UploadingImageFileUploadsImageSucceeds() + [Theory(DisplayName = "Making Document permanent succeeds")] + [AnonymousData] + public async Task MakingDocumentPermanentSucceeds(Document document) { - var dbContextMock = new Mock(); - var imageDbSetMock = new List().AsQueryable().BuildMockDbSet(); - dbContextMock.Setup(x => x.Set()) - .Returns(imageDbSetMock.Object); - var blobStorageServiceMock = new Mock(); - blobStorageServiceMock.Setup(x => x.GetFileType(It.IsAny())) - .Returns(FileTypeEnum.Image); + var sut = new FileService(_blobStorageServiceMock.Object); - var sut = new FileService(dbContextMock.Object, blobStorageServiceMock.Object); + await sut.MakePermanentDocumentAsync(document, It.IsAny()); - const string imgBase64 = "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"; + _blobStorageServiceMock.Verify(x => x.MakePermanentAsync(It.IsAny(), It.IsAny()), + Times.Once); + } - await using var stream = new MemoryStream(Convert.FromBase64String(imgBase64)); - await sut.Upload(stream, "sample-image.png", "image/png", CancellationToken.None); - stream.Close(); + [Theory(DisplayName = "Making Documents permanent succeeds")] + [AnonymousData] + public async Task MakingDocumentsPermanentSucceeds(Document[] documents) + { + var sut = new FileService(_blobStorageServiceMock.Object); + + await sut.MakePermanentDocumentsAsync(documents, It.IsAny()); - blobStorageServiceMock.Verify(x => x.UploadTempFileAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()), Times.Exactly(2)); - dbContextMock.Verify(x => x.Set().AddAsync(It.IsAny(), It.IsAny())); - dbContextMock.Verify(x => x.SaveEntitiesAsync(It.IsAny())); + _blobStorageServiceMock.Verify(x => x.MakePermanentAsync(It.IsAny(), It.IsAny()), + Times.Exactly(documents.Length)); } - [Fact(DisplayName = "Uploading a text file uploads a document succeeds")] - public async Task UploadingTextFileUploadsDocumentSucceeds() + [Theory(DisplayName = "Making Image permanent succeeds")] + [AnonymousData(true)] + public async Task MakingImagePermanentSucceeds(Image image) { - var dbContextMock = new Mock(); - var documentDbSetMock = new List().AsQueryable().BuildMockDbSet(); - dbContextMock.Setup(x => x.Set()) - .Returns(documentDbSetMock.Object); - var blobStorageServiceMock = new Mock(); + typeof(Image) + .GetProperty(nameof(Image.ThumbnailId))! + .SetValue(image, image.Thumbnail!.Id, null); - var sut = new FileService(dbContextMock.Object, blobStorageServiceMock.Object); + var sut = new FileService(_blobStorageServiceMock.Object); - const string txtBase64 = "TW9uYWNvIFVuaXQgVGVzdCBGaWxlIGZvciBVcGxvYWQgZG9jdW1lbnQgc3VjY2VlZHMu"; + await sut.MakePermanentImageAsync(image, It.IsAny()); - await using var stream = new MemoryStream(Convert.FromBase64String(txtBase64)); - await sut.Upload(stream, "sample-text-file.txt", "text/plain", CancellationToken.None); - stream.Close(); + _blobStorageServiceMock.Verify(x => x.MakePermanentAsync(It.IsAny(), It.IsAny()), + Times.Exactly(2)); + } + + [Theory(DisplayName = "Making Images permanent succeeds")] + [AnonymousData(true)] + public async Task MakingImagesPermanentSucceeds(Image[] images) + { + foreach (var image in images) + typeof(Image) + .GetProperty(nameof(Image.ThumbnailId))! + .SetValue(image, image.Thumbnail!.Id, null); + + var sut = new FileService(_blobStorageServiceMock.Object); + + await sut.MakePermanentImagesAsync(images, It.IsAny()); + + _blobStorageServiceMock.Verify(x => x.MakePermanentAsync(It.IsAny(), It.IsAny()), + Times.Exactly(2 * images.Length)); + } + + [Theory(DisplayName = "Making File Document permanent succeeds")] + [AnonymousData] + public async Task MakingFileDocumentPermanentSucceeds(Document document) + { + var sut = new FileService(_blobStorageServiceMock.Object); + + await sut.MakePermanentFileAsync(document, It.IsAny()); + + _blobStorageServiceMock.Verify(x => x.MakePermanentAsync(It.IsAny(), It.IsAny()), + Times.Once); + } - blobStorageServiceMock.Verify(x => x.UploadTempFileAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()), Times.Exactly(1)); - dbContextMock.Verify(x => x.Set().AddAsync(It.IsAny(), It.IsAny())); - dbContextMock.Verify(x => x.SaveEntitiesAsync(It.IsAny())); + [Theory(DisplayName = "Making File Image permanent succeeds")] + [AnonymousData(true)] + public async Task MakingFileImagePermanentSucceeds(Image image) + { + typeof(Image) + .GetProperty(nameof(Image.ThumbnailId))! + .SetValue(image, image.Thumbnail!.Id, null); + + var sut = new FileService(_blobStorageServiceMock.Object); + + await sut.MakePermanentFileAsync(image, It.IsAny()); + + _blobStorageServiceMock.Verify(x => x.MakePermanentAsync(It.IsAny(), It.IsAny()), + Times.Exactly(2)); + } + + [Fact(DisplayName = "Making dummy file permanent throws exception")] + public async Task MakingDummyFilePermanentThrows() + { + var sut = new FileService(_blobStorageServiceMock.Object); + + var action = () => sut.MakePermanentFileAsync(new DummyFile(), It.IsAny()); + + await action.Should() + .ThrowAsync(); + } + + [Theory(DisplayName = "Making File Document permanent succeeds")] + [AnonymousData(true)] + public async Task MakingFilesPermanentSucceeds(Document document, Image image) + { + typeof(Image) + .GetProperty(nameof(Image.ThumbnailId))! + .SetValue(image, image.Thumbnail!.Id, null); + + var sut = new FileService(_blobStorageServiceMock.Object); + + await sut.MakePermanentFilesAsync([document, image], It.IsAny()); + + _blobStorageServiceMock.Verify(x => x.MakePermanentAsync(It.IsAny(), It.IsAny()), + Times.Exactly(3)); } + + [Theory(DisplayName = "Download Document succeeds")] + [AnonymousData] + public async Task DownloadFileSucceeds(Document document) + { + _blobStorageServiceMock.Setup(x => x.DownloadAsync(It.IsAny(), It.IsAny(), It.IsAny())) + .ReturnsAsync(new MemoryStream()); + + var sut = new FileService(_blobStorageServiceMock.Object); + + var result = await sut.DownloadFileAsync(document, It.IsAny()); + + _blobStorageServiceMock.Verify(x => x.DownloadAsync(It.IsAny(), + It.IsAny(), + It.IsAny()), + Times.Once); + result.FileName + .Should() + .Be($"{document.Name}{document.Extension}"); + result.ContentType + .Should() + .Be(document.ContentType); + } + + [Theory(DisplayName = "Delete Document succeeds")] + [AnonymousData] + public async Task DeleteDocumentSucceeds(Document document) + { + var sut = new FileService(_blobStorageServiceMock.Object); + + await sut.DeleteDocumentAsync(document, It.IsAny()); + + _blobStorageServiceMock.Verify(x => x.DeleteAsync(It.IsAny(), + It.IsAny(), + It.IsAny()), + Times.Once); + } + + [Theory(DisplayName = "Delete Documents succeeds")] + [AnonymousData] + public async Task DeleteDocumentsSucceeds(Document[] documents) + { + var sut = new FileService(_blobStorageServiceMock.Object); + + await sut.DeleteDocumentsAsync(documents, It.IsAny()); + + _blobStorageServiceMock.Verify(x => x.DeleteAsync(It.IsAny(), + It.IsAny(), + It.IsAny()), + Times.Exactly(documents.Length)); + } + + [Theory(DisplayName = "Delete Image succeeds")] + [AnonymousData(true)] + public async Task DeleteImageSucceeds(Image image) + { + typeof(Image) + .GetProperty(nameof(Image.ThumbnailId))! + .SetValue(image, image.Thumbnail!.Id, null); + + var sut = new FileService(_blobStorageServiceMock.Object); + + await sut.DeleteImageAsync(image, It.IsAny()); + + _blobStorageServiceMock.Verify(x => x.DeleteAsync(It.IsAny(), + It.IsAny(), + It.IsAny()), + Times.Exactly(2)); + } + + [Theory(DisplayName = "Delete Images succeeds")] + [AnonymousData(true)] + public async Task DeleteImagesSucceeds(Image[] images) + { + foreach (var image in images) + typeof(Image) + .GetProperty(nameof(Image.ThumbnailId))! + .SetValue(image, image.Thumbnail!.Id, null); + + var sut = new FileService(_blobStorageServiceMock.Object); + + await sut.DeleteImagesAsync(images, It.IsAny()); + + _blobStorageServiceMock.Verify(x => x.DeleteAsync(It.IsAny(), + It.IsAny(), + It.IsAny()), + Times.Exactly(2 * images.Length)); + } + + [Theory(DisplayName = "Delete File Document succeeds")] + [AnonymousData] + public async Task DeleteFileDocumentSucceeds(Document document) + { + var sut = new FileService(_blobStorageServiceMock.Object); + + await sut.DeleteFileAsync(document, It.IsAny()); + + _blobStorageServiceMock.Verify(x => x.DeleteAsync(It.IsAny(), + It.IsAny(), + It.IsAny()), + Times.Once); + } + + [Theory(DisplayName = "Delete File Image succeeds")] + [AnonymousData(true)] + public async Task DeleteFileImageSucceeds(Image image) + { + typeof(Image) + .GetProperty(nameof(Image.ThumbnailId))! + .SetValue(image, image.Thumbnail!.Id, null); + + var sut = new FileService(_blobStorageServiceMock.Object); + + await sut.DeleteFileAsync(image, It.IsAny()); + + _blobStorageServiceMock.Verify(x => x.DeleteAsync(It.IsAny(), + It.IsAny(), + It.IsAny()), + Times.Exactly(2)); + } + + [Fact(DisplayName = "Delete dummy file throws exception")] + public async Task DeleteDummyFileThrows() + { + var sut = new FileService(_blobStorageServiceMock.Object); + + var action = () => sut.DeleteFileAsync(new DummyFile(), It.IsAny()); + + await action.Should() + .ThrowAsync(); + } + + [Theory(DisplayName = "Delete Files succeeds")] + [AnonymousData(true)] + public async Task DeleteFilesSucceeds(Document document, Image image) + { + typeof(Image) + .GetProperty(nameof(Image.ThumbnailId))! + .SetValue(image, image.Thumbnail!.Id, null); + + var sut = new FileService(_blobStorageServiceMock.Object); + + await sut.DeleteFilesAsync([document, image], It.IsAny()); + + _blobStorageServiceMock.Verify(x => x.DeleteAsync(It.IsAny(), + It.IsAny(), + It.IsAny()), + Times.Exactly(3)); + } + + [Theory(DisplayName = "Copy document succeeds")] + [AnonymousData(true)] + public async Task CopyDocumentSucceeds(Document document) + { + _blobStorageServiceMock.Setup(x => x.CopyAsync(It.IsAny(), + It.IsAny(), + It.IsAny())) + .ReturnsAsync(Guid.NewGuid()); + + var sut = new FileService(_blobStorageServiceMock.Object); + await sut.CopyFileAsync(document, It.IsAny()); + + _blobStorageServiceMock.Verify(x => x.CopyAsync(It.IsAny(), + It.IsAny(), + It.IsAny()), + Times.Once); + } + + [Theory(DisplayName = "Copy image succeeds")] + [AnonymousData(true)] + public async Task CopyImageSucceeds(Image image) + { + typeof(Image) + .GetProperty(nameof(Image.ThumbnailId))! + .SetValue(image, image.Thumbnail!.Id, null); + + _blobStorageServiceMock.Setup(x => x.CopyAsync(It.IsAny(), + It.IsAny(), + It.IsAny())) + .ReturnsAsync(Guid.NewGuid()); + + var sut = new FileService(_blobStorageServiceMock.Object); + await sut.CopyFileAsync(image, It.IsAny()); + + _blobStorageServiceMock.Verify(x => x.CopyAsync(It.IsAny(), + It.IsAny(), + It.IsAny()), + Times.Exactly(2)); + } + + [Fact(DisplayName = "Get Metadata succeeds")] + public async Task GetMetadataSucceeds() + { + var sut = new FileService(_blobStorageServiceMock.Object); + + await using var stream = new MemoryStream(Convert.FromBase64String(ImgBase64)); + var result = sut.GetMetadata(stream); + + result.Count + .Should() + .Be(1); + result.Should() + .Contain(property => property.Tag == ExifTag.PNGCreationTime); + } + + [Fact(DisplayName = "Get Thumbnail succeeds")] + public async Task GetThumbnailSucceeds() + { + var sut = new FileService(_blobStorageServiceMock.Object); + + await using var stream = new MemoryStream(Convert.FromBase64String(ImgBase64)); + using var image = SKImage.FromEncodedData(stream); + var result = sut.GetThumbnail(image, 120, 120); + + result.Width + .Should() + .BeLessOrEqualTo(120); + result.Height + .Should() + .BeLessOrEqualTo(120); + } + + [Fact(DisplayName = "Get Thumbnail bigger than original keeps same size")] + public async Task GetThumbnailBiggerThanOriginalKeepsSize() + { + var sut = new FileService(_blobStorageServiceMock.Object); + + await using var stream = new MemoryStream(Convert.FromBase64String(ImgBase64)); + using var image = SKImage.FromEncodedData(stream); + var (width, height) = (image.Width, image.Height); + var result = sut.GetThumbnail(image, 1000, 1000); + + result.Width + .Should() + .Be(width); + result.Height + .Should() + .BeLessOrEqualTo(height); + } +} + +internal class DummyFile : File +{ } \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/DTOs/Extensions/FileExtensions.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/DTOs/Extensions/FileExtensions.cs index 43d8236..b54f8a4 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/DTOs/Extensions/FileExtensions.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/DTOs/Extensions/FileExtensions.cs @@ -29,8 +29,8 @@ value is null value.UploadedOn, value.IsTemp, value.DateTaken, - value.Width, - value.Height, + value.Dimensions.Width, + value.Dimensions.Height, value.ThumbnailId, value.ThumbnailId.HasValue ? value.Thumbnail.Map() : null); diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/DTOs/Extensions/ProductExtensions.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/DTOs/Extensions/ProductExtensions.cs new file mode 100644 index 0000000..974f977 --- /dev/null +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/DTOs/Extensions/ProductExtensions.cs @@ -0,0 +1,79 @@ +using LinqKit; +using Monaco.Template.Backend.Application.Features.Product; +using Monaco.Template.Backend.Domain.Model; +using System.Linq.Expressions; + +namespace Monaco.Template.Backend.Application.DTOs.Extensions; + +public static class ProductExtensions +{ + public static ProductDto? Map(this Product? value, + bool expandCompany = false, + bool expandPictures = false, + bool expandDefaultPicture = false) => + value is null + ? null + : new(value.Id, + value.Title, + value.Description, + value.Price, + value.CompanyId, + expandCompany + ? value.Company + .Map() + : null, + expandPictures + ? value.Pictures + .Select(x => x.Map()!) + .ToArray() + : null, + value.DefaultPictureId, + expandDefaultPicture + ? value.DefaultPicture + .Map() + : null); + + public static Product Map(this CreateProduct.Command value, Company company, Image[] pictures, Image defaultPicture) + { + var item = new Product(value.Title, + value.Description, + value.Price, + company); + foreach (var picture in pictures) + item.AddPicture(picture, picture == defaultPicture); + + return item; + } + + public static (Image[]newPics, Image[] deletedPics) Map(this EditProduct.Command value, Product item, Company company, Image[] pictures, Image defaultPicture) + { + item.Update(value.Title, + value.Description, + value.Price, + company); + + var deletedPics = item.Pictures + .Where(p => !pictures.Contains(p)) + .ToArray(); + deletedPics.ForEach(item.RemovePicture); + + var newPics = pictures.Where(p => p.IsTemp) + .ToArray(); + + pictures.ForEach(p => item.AddPicture(p, p == defaultPicture)); + + return (newPics, deletedPics); + } + + public static Dictionary>> GetMappedFields() => + new() + { + [nameof(ProductDto.Id)] = x => x.Id, + [nameof(ProductDto.Title)] = x => x.Title, + [nameof(ProductDto.Description)] = x => x.Description, + [nameof(ProductDto.Price)] = x => x.Price, + [nameof(ProductDto.CompanyId)] = x => x.CompanyId, + [$"{nameof(ProductDto.Company)}.{nameof(CompanyDto.Name)}"] = x => x.Company.Name, + [nameof(ProductDto.DefaultPictureId)] = x => x.DefaultPictureId + }; +} \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/DTOs/FileDownloadDto.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/DTOs/FileDownloadDto.cs deleted file mode 100644 index ec6514e..0000000 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/DTOs/FileDownloadDto.cs +++ /dev/null @@ -1,3 +0,0 @@ -namespace Monaco.Template.Backend.Application.DTOs; - -public record FileDownloadDto(Stream FileContent, string FileName, string ContentType); \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/DTOs/ProductDto.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/DTOs/ProductDto.cs new file mode 100644 index 0000000..4257dfd --- /dev/null +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/DTOs/ProductDto.cs @@ -0,0 +1,11 @@ +namespace Monaco.Template.Backend.Application.DTOs; + +public record ProductDto(Guid Id, + string Title, + string Description, + decimal Price, + Guid CompanyId, + CompanyDto? Company, + ImageDto[]? Pictures, + Guid DefaultPictureId, + ImageDto? DefaultPicture); \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/DependencyInjection/ApplicationOptions.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/DependencyInjection/ApplicationOptions.cs index 85b6f30..98b58b9 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/DependencyInjection/ApplicationOptions.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/DependencyInjection/ApplicationOptions.cs @@ -3,7 +3,7 @@ public class ApplicationOptions { public EntityFrameworkOptions EntityFramework { get; set; } = new(); -#if filesSupport +#if !excludeFilesSupport public BlobStorageOptions BlobStorage { get; set; } = new(); #endif @@ -12,7 +12,7 @@ public class EntityFrameworkOptions public string ConnectionString { get; set; } = string.Empty; public bool EnableEfSensitiveLogging { get; set; } } -#if filesSupport +#if !excludeFilesSupport public class BlobStorageOptions { diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/DependencyInjection/ServiceCollectionExtensions.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/DependencyInjection/ServiceCollectionExtensions.cs index 0354113..a606642 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/DependencyInjection/ServiceCollectionExtensions.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/DependencyInjection/ServiceCollectionExtensions.cs @@ -2,7 +2,7 @@ using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Monaco.Template.Backend.Application.Infrastructure.Context; -#if filesSupport +#if !excludeFilesSupport using Monaco.Template.Backend.Application.Services; using Monaco.Template.Backend.Application.Services.Contracts; #endif @@ -11,7 +11,7 @@ using System.Reflection; using Monaco.Template.Backend.Common.Application.Policies; using Monaco.Template.Backend.Common.Infrastructure.Context; -#if filesSupport +#if !excludeFilesSupport using Monaco.Template.Backend.Common.BlobStorage.Extensions; #endif @@ -47,7 +47,7 @@ public static IServiceCollection ConfigureApplication(this IServiceCollection se .UseLazyLoadingProxies() .EnableSensitiveDataLogging(optionsValue.EntityFramework.EnableEfSensitiveLogging)) .AddScoped(provider => provider.GetRequiredService()); -#if filesSupport +#if !excludeFilesSupport services.RegisterBlobStorageService(opts => { opts.ConnectionString = optionsValue.BlobStorage.ConnectionString; diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Company/DeleteCompany.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Company/DeleteCompany.cs index 33b6ceb..17e6940 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Company/DeleteCompany.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Company/DeleteCompany.cs @@ -2,6 +2,10 @@ using MediatR; using Microsoft.EntityFrameworkCore; using Monaco.Template.Backend.Application.Infrastructure.Context; +#if !excludeFilesSupport +using Monaco.Template.Backend.Application.Services.Contracts; +#endif +using Monaco.Template.Backend.Domain.Model; using Monaco.Template.Backend.Common.Application.Commands; using Monaco.Template.Backend.Common.Application.Commands.Contracts; using Monaco.Template.Backend.Common.Application.Validators.Extensions; @@ -25,18 +29,51 @@ public Validator(AppDbContext dbContext) public sealed class Handler : IRequestHandler { private readonly AppDbContext _dbContext; + #if !excludeFilesSupport + private readonly IFileService _fileService; + #endif + #if !excludeFilesSupport + public Handler(AppDbContext dbContext, IFileService fileService) + #else public Handler(AppDbContext dbContext) + #endif { _dbContext = dbContext; + #if !excludeFilesSupport + _fileService = fileService; + #endif } public async Task Handle(Command request, CancellationToken cancellationToken) { - var item = await _dbContext.Set().SingleAsync(x => x.Id == request.Id, cancellationToken); + var item = await _dbContext.Set() + .Include(x => x.Products) + #if !excludeFilesSupport + .ThenInclude(x => x.Pictures) + .ThenInclude(x => x.Thumbnail) + #endif + .SingleAsync(x => x.Id == request.Id, + cancellationToken); + #if !excludeFilesSupport + var pictures = item.Products + .SelectMany(x => x.Pictures) + .ToArray(); - _dbContext.Set().Remove(item); + #endif + _dbContext.Set() + .Remove(item); + #if !excludeFilesSupport + _dbContext.Set() + .RemoveRange(pictures.Union(pictures.Select(x => x.Thumbnail!) + .ToArray())); + + #endif await _dbContext.SaveEntitiesAsync(cancellationToken); + #if !excludeFilesSupport + + await _fileService.DeleteImagesAsync(pictures, cancellationToken); + #endif return new CommandResult(); } diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/File/CreateFile.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/File/CreateFile.cs index 436080e..636fa0a 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/File/CreateFile.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/File/CreateFile.cs @@ -1,5 +1,6 @@ using FluentValidation; using MediatR; +using Monaco.Template.Backend.Application.Infrastructure.Context; using Monaco.Template.Backend.Application.Services.Contracts; using Monaco.Template.Backend.Common.Application.Commands; using Monaco.Template.Backend.Common.Application.Commands.Contracts; @@ -22,20 +23,33 @@ public Validator() } } - #if filesSupport + #if !excludeFilesSupport public sealed class Handler : IRequestHandler> { + private readonly AppDbContext _dbContext; private readonly IFileService _fileService; - public Handler(IFileService fileService) + public Handler(AppDbContext dbContext, IFileService fileService) { + _dbContext = dbContext; _fileService = fileService; } public async Task> Handle(Command request, CancellationToken cancellationToken) { - var file = await _fileService.Upload(request.Stream, request.FileName, request.ContentType, cancellationToken); - + var file = await _fileService.UploadAsync(request.Stream, request.FileName, request.ContentType, cancellationToken); + + try + { + _dbContext.Set().Attach(file); + await _dbContext.SaveEntitiesAsync(cancellationToken); + } + catch + { + await _fileService.DeleteFileAsync(file, cancellationToken); + throw; + } + return new CommandResult(file.Id); } } diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/File/DeleteFile.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/File/DeleteFile.cs deleted file mode 100644 index 991c4c0..0000000 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/File/DeleteFile.cs +++ /dev/null @@ -1,43 +0,0 @@ -using FluentValidation; -using MediatR; -using Monaco.Template.Backend.Application.Infrastructure.Context; -using Monaco.Template.Backend.Application.Services.Contracts; -using Monaco.Template.Backend.Common.Application.Commands; -using Monaco.Template.Backend.Common.Application.Commands.Contracts; -using Monaco.Template.Backend.Common.Application.Validators.Extensions; - -namespace Monaco.Template.Backend.Application.Features.File; - -public sealed class DeleteFile -{ - public record Command(Guid Id) : CommandBase(Id); - - public sealed class Validator : AbstractValidator - { - public Validator(AppDbContext dbContext) - { - RuleLevelCascadeMode = CascadeMode.Stop; - - this.CheckIfExists(dbContext); - } - } - - #if filesSupport - public sealed class Handler : IRequestHandler - { - private readonly IFileService _fileService; - - public Handler(IFileService fileService) - { - _fileService = fileService; - } - - public async Task Handle(Command request, CancellationToken cancellationToken) - { - await _fileService.Delete(request.Id, cancellationToken); - - return new CommandResult(); - } - } - #endif -} \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/File/DownloadFileById.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/File/DownloadFileById.cs deleted file mode 100644 index d532020..0000000 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/File/DownloadFileById.cs +++ /dev/null @@ -1,41 +0,0 @@ -using MediatR; -using Monaco.Template.Backend.Application.DTOs; -using Monaco.Template.Backend.Application.Features.File.Extensions; -using Monaco.Template.Backend.Application.Infrastructure.Context; -using Monaco.Template.Backend.Common.Application.Queries; -using Monaco.Template.Backend.Common.BlobStorage.Contracts; - -namespace Monaco.Template.Backend.Application.Features.File; - -public sealed class DownloadFileById -{ - public record Query(Guid Id) : QueryByIdBase(Id); - - #if filesSupport - public sealed class Handler : IRequestHandler - { - private readonly AppDbContext _dbContext; - private readonly IBlobStorageService _blobStorageService; - - public Handler(AppDbContext dbContext, IBlobStorageService blobStorageService) - { - _dbContext = dbContext; - _blobStorageService = blobStorageService; - } - - public async Task Handle(Query request, CancellationToken cancellationToken) - { - var item = await _dbContext.GetFile(request.Id, cancellationToken); - - if (item is null) - return null; - - var file = await _blobStorageService.DownloadAsync(request.Id, item.IsTemp, cancellationToken); - - return new(file, - $"{item.Name}{item.Extension}", - item.ContentType); - } - } - #endif -} \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/File/Extensions/FileExtensions.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/File/Extensions/FileExtensions.cs deleted file mode 100644 index ba3aba9..0000000 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/File/Extensions/FileExtensions.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Microsoft.EntityFrameworkCore; - -namespace Monaco.Template.Backend.Application.Features.File.Extensions; - -internal static class FileExtensions -{ - internal static Task GetFile(this DbContext dbContext, Guid id, CancellationToken cancellationToken) => - dbContext.Set() - .AsNoTracking() - .SingleOrDefaultAsync(x => x.Id == id, cancellationToken); -} \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/File/GetFileById.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/File/GetFileById.cs deleted file mode 100644 index 78d520a..0000000 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/File/GetFileById.cs +++ /dev/null @@ -1,31 +0,0 @@ -using MediatR; -using Monaco.Template.Backend.Application.DTOs; -using Monaco.Template.Backend.Application.DTOs.Extensions; -using Monaco.Template.Backend.Application.Features.File.Extensions; -using Monaco.Template.Backend.Application.Infrastructure.Context; -using Monaco.Template.Backend.Common.Application.Queries; - -namespace Monaco.Template.Backend.Application.Features.File; - -public sealed class GetFileById -{ - public record Query(Guid Id) : QueryByIdBase(Id); - - #if filesSupport - public sealed class Handler : IRequestHandler - { - private readonly AppDbContext _dbContext; - - public Handler(AppDbContext dbContext) - { - _dbContext = dbContext; - } - - public async Task Handle(Query request, CancellationToken cancellationToken) - { - var item = await _dbContext.GetFile(request.Id, cancellationToken); - return item.Map(); - } - } - #endif -} \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Image/DownloadThumbnailByImageId.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Image/DownloadThumbnailByImageId.cs deleted file mode 100644 index 300870d..0000000 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Image/DownloadThumbnailByImageId.cs +++ /dev/null @@ -1,41 +0,0 @@ -using MediatR; -using Monaco.Template.Backend.Application.DTOs; -using Monaco.Template.Backend.Application.Features.Image.Extensions; -using Monaco.Template.Backend.Application.Infrastructure.Context; -using Monaco.Template.Backend.Common.Application.Queries; -using Monaco.Template.Backend.Common.BlobStorage.Contracts; - -namespace Monaco.Template.Backend.Application.Features.Image; - -public sealed class DownloadThumbnailByImageId -{ - public record Query(Guid Id) : QueryByIdBase(Id); - - #if filesSupport - public sealed class Handler : IRequestHandler - { - private readonly AppDbContext _dbContext; - private readonly IBlobStorageService _blobStorageService; - - public Handler(AppDbContext dbContext, IBlobStorageService blobStorageService) - { - _dbContext = dbContext; - _blobStorageService = blobStorageService; - } - - public async Task Handle(Query request, CancellationToken cancellationToken) - { - var item = await _dbContext.GetThumbnail(request.Id, cancellationToken); - - if (item is null) - return null; - - var file = await _blobStorageService.DownloadAsync(item.Id, item.IsTemp, cancellationToken); - - return new(file, - $"{item.Name}{item.Extension}", - item.ContentType); - } - } - #endif -} \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Image/Extensions/ImageExtensions.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Image/Extensions/ImageExtensions.cs deleted file mode 100644 index 5102402..0000000 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Image/Extensions/ImageExtensions.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Microsoft.EntityFrameworkCore; - -namespace Monaco.Template.Backend.Application.Features.Image.Extensions; - -internal static class ImageExtensions -{ - internal static Task GetImage(this DbContext dbContext, Guid id, CancellationToken cancellationToken) => - dbContext.Set() - .AsNoTracking() - .Include(x => x.Thumbnail) - .SingleOrDefaultAsync(x => x.Id == id, cancellationToken); - - internal static Task GetThumbnail(this DbContext dbContext, Guid id, CancellationToken cancellationToken) => - dbContext.Set() - .AsNoTracking() - .Where(x => x.Id == id) - .Select(x => x.Thumbnail) - .SingleOrDefaultAsync(cancellationToken); -} \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Image/GetImageById.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Image/GetImageById.cs deleted file mode 100644 index 32eb8c8..0000000 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Image/GetImageById.cs +++ /dev/null @@ -1,31 +0,0 @@ -using MediatR; -using Monaco.Template.Backend.Application.DTOs; -using Monaco.Template.Backend.Application.DTOs.Extensions; -using Monaco.Template.Backend.Application.Features.Image.Extensions; -using Monaco.Template.Backend.Application.Infrastructure.Context; -using Monaco.Template.Backend.Common.Application.Queries; - -namespace Monaco.Template.Backend.Application.Features.Image; - -public sealed class GetImageById -{ - public record Query(Guid Id) : QueryByIdBase(Id); - - #if filesSupport - public sealed class Handler : IRequestHandler - { - private readonly AppDbContext _dbContext; - - public Handler(AppDbContext dbContext) - { - _dbContext = dbContext; - } - - public async Task Handle(Query request, CancellationToken cancellationToken) - { - var item = await _dbContext.GetImage(request.Id, cancellationToken); - return item.Map(); - } - } - #endif -} \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Image/GetThumbnailByImageId.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Image/GetThumbnailByImageId.cs deleted file mode 100644 index 594b3a6..0000000 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Image/GetThumbnailByImageId.cs +++ /dev/null @@ -1,31 +0,0 @@ -using MediatR; -using Monaco.Template.Backend.Application.DTOs; -using Monaco.Template.Backend.Application.DTOs.Extensions; -using Monaco.Template.Backend.Application.Features.Image.Extensions; -using Monaco.Template.Backend.Application.Infrastructure.Context; -using Monaco.Template.Backend.Common.Application.Queries; - -namespace Monaco.Template.Backend.Application.Features.Image; - -public sealed class GetThumbnailByImageId -{ - public record Query(Guid Id) : QueryByIdBase(Id); - - #if filesSupport - public sealed class Handler : IRequestHandler - { - private readonly AppDbContext _dbContext; - - public Handler(AppDbContext dbContext) - { - _dbContext = dbContext; - } - - public async Task Handle(Query request, CancellationToken cancellationToken) - { - var item = await _dbContext.GetThumbnail(request.Id, cancellationToken); - return item.Map(); - } - } - #endif -} \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/CreateProduct.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/CreateProduct.cs new file mode 100644 index 0000000..0f59f5c --- /dev/null +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/CreateProduct.cs @@ -0,0 +1,90 @@ +using FluentValidation; +using MediatR; +using Monaco.Template.Backend.Application.DTOs.Extensions; +using Monaco.Template.Backend.Application.Features.Product.Extensions; +using Monaco.Template.Backend.Application.Infrastructure.Context; +using Monaco.Template.Backend.Application.Services.Contracts; +using Monaco.Template.Backend.Common.Application.Commands; +using Monaco.Template.Backend.Common.Application.Commands.Contracts; +using Monaco.Template.Backend.Common.Application.Validators.Extensions; +using Monaco.Template.Backend.Common.Infrastructure.Context.Extensions; + +namespace Monaco.Template.Backend.Application.Features.Product; + +public class CreateProduct +{ + public record Command(string Title, + string Description, + decimal Price, + Guid CompanyId, + Guid[] Pictures, + Guid DefaultPictureId) : CommandBase; + + public sealed class Validator : AbstractValidator + { + public Validator(AppDbContext dbContext) + { + RuleLevelCascadeMode = CascadeMode.Stop; + + RuleFor(x => x.Title) + .NotEmpty() + .MaximumLength(100) + .MustAsync(async (title, ct) => !await dbContext.ExistsAsync(x => x.Title == title, ct)) + .WithMessage("A product with the title {PropertyValue} already exists"); + + RuleFor(x => x.Description) + .NotEmpty() + .MaximumLength(500); + + RuleFor(x => x.Price) + .NotNull() + .GreaterThanOrEqualTo(0); + + RuleFor(x => x.CompanyId) + .NotEmpty() + .MustExistAsync(dbContext); + + RuleFor(x => x.Pictures) + .NotEmpty(); + + RuleForEach(cmd => cmd.Pictures) + .NotEmpty() + .MustExistAsync(dbContext) + .MustAsync(async (id, ct) => !await dbContext.ExistsAsync(x => x.Pictures.Any(p => p.Id == id), ct)) + .WithMessage("This picture is already in use by another product"); + + RuleFor(x => x.DefaultPictureId) + .NotEmpty() + .Must((cmd, id) => cmd.Pictures.Contains(id)) + .WithMessage("The default picture must exist in the Pictures array"); + } + } + + public sealed class Handler : IRequestHandler> + { + private readonly AppDbContext _dbContext; + private readonly IFileService _fileService; + + public Handler(AppDbContext dbContext, IFileService fileService) + { + _dbContext = dbContext; + _fileService = fileService; + } + + public async Task> Handle(Command request, CancellationToken cancellationToken) + { + var (company, pictures) = await _dbContext.GetProductData(request.CompanyId, request.Pictures, cancellationToken); + + var item = request.Map(company, + pictures, + pictures.Single(x => x.Id == request.DefaultPictureId)); + + _dbContext.Set().Attach(item); + await _dbContext.SaveEntitiesAsync(cancellationToken); + + await _fileService.MakePermanentImagesAsync(pictures, cancellationToken); + + return new CommandResult(item.Id); + } + } +} \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/DeleteProduct.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/DeleteProduct.cs new file mode 100644 index 0000000..c1b8e03 --- /dev/null +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/DeleteProduct.cs @@ -0,0 +1,62 @@ +using FluentValidation; +using MediatR; +using Microsoft.EntityFrameworkCore; +using Monaco.Template.Backend.Application.Infrastructure.Context; +using Monaco.Template.Backend.Application.Services.Contracts; +using Monaco.Template.Backend.Common.Application.Commands; +using Monaco.Template.Backend.Common.Application.Commands.Contracts; +using Monaco.Template.Backend.Common.Application.Validators.Extensions; +using Monaco.Template.Backend.Domain.Model; + +namespace Monaco.Template.Backend.Application.Features.Product; + +public class DeleteProduct +{ + public record Command(Guid Id) : CommandBase(Id); + + public sealed class Validator : AbstractValidator + { + public Validator(AppDbContext dbContext) + { + RuleLevelCascadeMode = CascadeMode.Stop; + + this.CheckIfExists(dbContext); + } + } + + public sealed class Handler : IRequestHandler + { + private readonly AppDbContext _dbContext; + private readonly IFileService _fileService; + + public Handler(AppDbContext dbContext, IFileService fileService) + { + _dbContext = dbContext; + _fileService = fileService; + } + + public async Task Handle(Command request, CancellationToken cancellationToken) + { + var item = await _dbContext.Set() + .Include(x => x.Pictures) + .ThenInclude(x => x.Thumbnail) + .SingleAsync(x => x.Id == request.Id, cancellationToken); + + var deletedPictures = item.Pictures + .Union(item.Pictures + .Select(x => x.Thumbnail!) + .ToArray()); + + _dbContext.Set() + .Remove(item); + _dbContext.Set() + .RemoveRange(deletedPictures); + + await _dbContext.SaveEntitiesAsync(cancellationToken); + + await _fileService.DeleteImagesAsync(item.Pictures.ToArray(), cancellationToken); + + return new CommandResult(); + } + } +} \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/DownloadProductPicture.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/DownloadProductPicture.cs new file mode 100644 index 0000000..1154e5f --- /dev/null +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/DownloadProductPicture.cs @@ -0,0 +1,51 @@ +using MediatR; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Primitives; +using Monaco.Template.Backend.Application.Infrastructure.Context; +using Monaco.Template.Backend.Application.Services.Contracts; +using Monaco.Template.Backend.Common.Application.DTOs; +using Monaco.Template.Backend.Common.Application.Queries; + +namespace Monaco.Template.Backend.Application.Features.Product; + + +public class DownloadProductPicture +{ + public record Query(Guid ProductId, + Guid PictureId, + IEnumerable> QueryString) : QueryBase(QueryString) + { + public bool? IsThumbnail => GetValueBool("thumbnail"); + }; + + public sealed class Handler : IRequestHandler + { + private readonly AppDbContext _dbContext; + private readonly IFileService _fileService; + + public Handler(AppDbContext dbContext, IFileService fileService) + { + _dbContext = dbContext; + _fileService = fileService; + } + + public async Task Handle(Query request, CancellationToken cancellationToken) + { + var query = _dbContext.Set() + .AsNoTracking() + .Where(x => x.Id == request.ProductId) + .Select(x => x.Pictures + .SingleOrDefault(p => p.Id == request.PictureId)); + + if (request.IsThumbnail.HasValue && request.IsThumbnail.Value) + query = query.Select(x => x!.Thumbnail); + + var item = await query.SingleOrDefaultAsync(cancellationToken); + + if (item is null) + return null; + + return await _fileService.DownloadFileAsync(item, cancellationToken); + } + } +} \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/EditProduct.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/EditProduct.cs new file mode 100644 index 0000000..ddfcc3d --- /dev/null +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/EditProduct.cs @@ -0,0 +1,106 @@ +using FluentValidation; +using MediatR; +using Microsoft.EntityFrameworkCore; +using Monaco.Template.Backend.Application.DTOs.Extensions; +using Monaco.Template.Backend.Application.Features.Product.Extensions; +using Monaco.Template.Backend.Application.Infrastructure.Context; +using Monaco.Template.Backend.Application.Services.Contracts; +using Monaco.Template.Backend.Common.Application.Commands; +using Monaco.Template.Backend.Common.Application.Commands.Contracts; +using Monaco.Template.Backend.Common.Application.Validators.Extensions; +using Monaco.Template.Backend.Common.Infrastructure.Context.Extensions; + +namespace Monaco.Template.Backend.Application.Features.Product; + +public class EditProduct +{ + public record Command(Guid Id, + string Title, + string Description, + decimal Price, + Guid CompanyId, + Guid[] Pictures, + Guid DefaultPictureId) : CommandBase(Id); + + public sealed class Validator : AbstractValidator + { + public Validator(AppDbContext dbContext) + { + RuleLevelCascadeMode = CascadeMode.Stop; + + this.CheckIfExists(dbContext); + + RuleFor(x => x.Title) + .NotEmpty() + .MaximumLength(100) + .MustAsync(async (cmd, title, ct) => !await dbContext.ExistsAsync(x => x.Id != cmd.Id && + x.Title == title, + ct)) + .WithMessage("Another product with the title {PropertyValue} already exists"); + + RuleFor(x => x.Description) + .NotEmpty() + .MaximumLength(500); + + RuleFor(x => x.Price) + .NotNull() + .GreaterThanOrEqualTo(0); + + RuleFor(x => x.CompanyId) + .NotEmpty() + .MustExistAsync(dbContext); + + RuleFor(x => x.Pictures) + .NotEmpty(); + + RuleForEach(cmd => cmd.Pictures) + .NotEmpty() + .MustExistAsync(dbContext) + .MustAsync(async (cmd, id, ct) => !await dbContext.ExistsAsync(x => x.Id != cmd.Id && + x.Pictures.Any(p => p.Id == id), + ct)) + .WithMessage("This picture is already in use by another product"); + + RuleFor(x => x.DefaultPictureId) + .NotEmpty() + .Must((cmd, id) => cmd.Pictures.Contains(id)) + .WithMessage("The default picture must exist in the Pictures array"); + } + } + + public sealed class Handler : IRequestHandler + { + private readonly AppDbContext _dbContext; + private readonly IFileService _fileService; + + public Handler(AppDbContext dbContext, IFileService fileService) + { + _dbContext = dbContext; + _fileService = fileService; + } + + public async Task Handle(Command request, CancellationToken cancellationToken) + { + var item = await _dbContext.Set() + .Include(x => x.Pictures) + .ThenInclude(x => x.Thumbnail) + .SingleAsync(x => x.Id == request.Id, cancellationToken); + var (company, pictures) = await _dbContext.GetProductData(request.CompanyId, request.Pictures, cancellationToken); + + var (newPics, deletedPics) = request.Map(item, + company, + pictures, + pictures.Single(x => x.Id == request.DefaultPictureId)); + + _dbContext.Set() + .RemoveRange(deletedPics); + + await _dbContext.SaveEntitiesAsync(cancellationToken); + + await Task.WhenAll(_fileService.DeleteImagesAsync(deletedPics, cancellationToken), + _fileService.MakePermanentImagesAsync(newPics, cancellationToken)); + + return new CommandResult(); + } + } +} \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/Extensions/ProductDataExtensions.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/Extensions/ProductDataExtensions.cs new file mode 100644 index 0000000..b554617 --- /dev/null +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/Extensions/ProductDataExtensions.cs @@ -0,0 +1,21 @@ +using Microsoft.EntityFrameworkCore; +using Monaco.Template.Backend.Application.Infrastructure.Context; +using Monaco.Template.Backend.Common.Infrastructure.Context.Extensions; + +namespace Monaco.Template.Backend.Application.Features.Product.Extensions; + +public static class ProductDataExtensions +{ + internal static async Task<(Domain.Model.Company, Domain.Model.Image[])> GetProductData(this AppDbContext dbContext, + Guid companyId, + Guid[] pictures, + CancellationToken cancellationToken) + { + var company = await dbContext.GetAsync(companyId, cancellationToken); + var pics = await dbContext.Set() + .Include(x => x.Thumbnail) + .Where(x => pictures.Contains(x.Id)) + .ToArrayAsync(cancellationToken); + return (company, pics); + } +} \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/GetProductById.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/GetProductById.cs new file mode 100644 index 0000000..6e1eba8 --- /dev/null +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/GetProductById.cs @@ -0,0 +1,33 @@ +using MediatR; +using Microsoft.EntityFrameworkCore; +using Monaco.Template.Backend.Application.DTOs; +using Monaco.Template.Backend.Application.DTOs.Extensions; +using Monaco.Template.Backend.Application.Infrastructure.Context; +using Monaco.Template.Backend.Common.Application.Queries; + +namespace Monaco.Template.Backend.Application.Features.Product; + + +public class GetProductById +{ + public record Query(Guid Id) : QueryByIdBase(Id); + + public sealed class Handler : IRequestHandler + { + private readonly AppDbContext _dbContext; + + public Handler(AppDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task Handle(Query request, CancellationToken cancellationToken) + { + var item = await _dbContext.Set() + .AsNoTracking() + .Include(x => x.Company) + .SingleOrDefaultAsync(x => x.Id == request.Id, cancellationToken); + return item.Map(true, true, true); + } + } +} diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/GetProductPage.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/GetProductPage.cs new file mode 100644 index 0000000..8302372 --- /dev/null +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/GetProductPage.cs @@ -0,0 +1,58 @@ +using MediatR; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Primitives; +using Monaco.Template.Backend.Application.DTOs; +using Monaco.Template.Backend.Application.DTOs.Extensions; +using Monaco.Template.Backend.Application.Infrastructure.Context; +using Monaco.Template.Backend.Common.Application.Queries; +using Monaco.Template.Backend.Common.Domain.Model; +using Monaco.Template.Backend.Common.Infrastructure.Context.Extensions; + +namespace Monaco.Template.Backend.Application.Features.Product; + + +public class GetProductPage +{ + public record Query(IEnumerable> QueryString) : QueryPagedBase(QueryString) + { + public bool ExpandCompany => Expand(nameof(ProductDto.Company)); + + public bool ExpandPictures => Expand(nameof(ProductDto.Pictures)); + + public bool ExpandDefaultPicture => Expand(nameof(ProductDto.DefaultPicture)); + } + + public sealed class Handler : IRequestHandler?> + { + private readonly AppDbContext _dbContext; + + public Handler(AppDbContext dbContext) + { + _dbContext = dbContext; + } + + public async Task?> Handle(Query request, CancellationToken cancellationToken) + { + var query = _dbContext.Set() + .AsNoTracking(); + + if (request.ExpandCompany) + query = query.Include(x => x.Company); + if (request.ExpandPictures) + query = query.Include(x => x.Pictures) + .ThenInclude(x => x.Thumbnail); + if (request.ExpandDefaultPicture) + query = query.Include(x => x.DefaultPicture); + + var page = await query.ApplyFilter(request.QueryString, ProductExtensions.GetMappedFields()) + .ApplySort(request.Sort, nameof(ProductDto.Title), ProductExtensions.GetMappedFields()) + .ToPageAsync(request.Offset, + request.Limit, + x => x.Map(request.ExpandCompany, + request.ExpandPictures, + request.ExpandDefaultPicture)!, + cancellationToken); + return page; + } + } +} \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Monaco.Template.Backend.Application.csproj b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Monaco.Template.Backend.Application.csproj index 50b281b..90d16df 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Monaco.Template.Backend.Application.csproj +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Monaco.Template.Backend.Application.csproj @@ -12,16 +12,21 @@ - + + - + + + + + diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Services/Contracts/IFileService.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Services/Contracts/IFileService.cs index 590e355..3a23c07 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Services/Contracts/IFileService.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Services/Contracts/IFileService.cs @@ -1,4 +1,5 @@ using ExifLibrary; +using Monaco.Template.Backend.Common.Application.DTOs; using Monaco.Template.Backend.Domain.Model; using SkiaSharp; using File = Monaco.Template.Backend.Domain.Model.File; @@ -7,14 +8,23 @@ namespace Monaco.Template.Backend.Application.Services.Contracts; public interface IFileService { - Task Upload(Stream stream, string fileName, string contentType, CancellationToken cancellationToken); - Task UploadDocument(Stream stream, string fileName, string contentType, CancellationToken cancellationToken); - Task UploadImage(Stream stream, string fileName, string contentType, CancellationToken cancellationToken); - Task MakePermanent(Guid id, CancellationToken cancellationToken); - Task MakePermanentPicture(Image file, CancellationToken cancellationToken); - Task MakePermanentDocument(Document file, CancellationToken cancellationToken); - Task Delete(Guid id, CancellationToken cancellationToken); - Task CopyFile(Guid id, CancellationToken cancellationToken); + Task UploadAsync(Stream stream, string fileName, string contentType, CancellationToken cancellationToken); + Task UploadDocumentAsync(Stream stream, string fileName, string contentType, CancellationToken cancellationToken); + Task UploadImageAsync(Stream stream, string fileName, string contentType, CancellationToken cancellationToken); + Task MakePermanentFileAsync(File file, CancellationToken cancellationToken); + Task MakePermanentFilesAsync(File[] files, CancellationToken cancellationToken); + Task MakePermanentImageAsync(Image image, CancellationToken cancellationToken); + Task MakePermanentImagesAsync(Image[] images, CancellationToken cancellationToken); + Task MakePermanentDocumentAsync(Document document, CancellationToken cancellationToken); + Task MakePermanentDocumentsAsync(Document[] documents, CancellationToken cancellationToken); + Task DownloadFileAsync(File item, CancellationToken cancellationToken); + Task DeleteFileAsync(File file, CancellationToken cancellationToken); + Task DeleteFilesAsync(File[] files, CancellationToken cancellationToken); + Task DeleteDocumentAsync(Document file, CancellationToken cancellationToken); + Task DeleteImageAsync(Image image, CancellationToken cancellationToken); + Task DeleteDocumentsAsync(Document[] documents, CancellationToken cancellationToken); + Task DeleteImagesAsync(Image[] images, CancellationToken cancellationToken); + Task CopyFileAsync(File file, CancellationToken cancellationToken); ExifPropertyCollection GetMetadata(Stream stream); SKImage GetThumbnail(SKImage image, int thumbnailWidth, int thumbnailHeight); } \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Services/FileService.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Services/FileService.cs index 1f61536..8c8a66a 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Services/FileService.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Services/FileService.cs @@ -1,6 +1,6 @@ using ExifLibrary; -using Monaco.Template.Backend.Application.Infrastructure.Context; using Monaco.Template.Backend.Application.Services.Contracts; +using Monaco.Template.Backend.Common.Application.DTOs; using Monaco.Template.Backend.Common.BlobStorage; using Monaco.Template.Backend.Common.BlobStorage.Contracts; using Monaco.Template.Backend.Domain.Model; @@ -12,41 +12,41 @@ namespace Monaco.Template.Backend.Application.Services; public class FileService : IFileService { - private readonly AppDbContext _dbContext; private readonly IBlobStorageService _blobStorageService; private const int ThumbnailWidth = 120; private const int ThumbnailHeight = 120; - public FileService(AppDbContext dbContext, IBlobStorageService blobStorageService) + public FileService(IBlobStorageService blobStorageService) { - _dbContext = dbContext; _blobStorageService = blobStorageService; } - public async Task Upload(Stream stream, string fileName, string contentType, CancellationToken cancellationToken) + public async Task UploadAsync(Stream stream, string fileName, string contentType, CancellationToken cancellationToken) { var fileType = _blobStorageService.GetFileType(Path.GetExtension(fileName)); return fileType switch { - FileTypeEnum.Image => await UploadImage(stream, fileName, contentType, cancellationToken), - _ => await UploadDocument(stream, fileName, contentType, cancellationToken), + FileTypeEnum.Image => await UploadImageAsync(stream, fileName, contentType, cancellationToken), + _ => await UploadDocumentAsync(stream, fileName, contentType, cancellationToken), }; } - public async Task UploadDocument(Stream stream, string fileName, string contentType, CancellationToken cancellationToken) + public async Task UploadDocumentAsync(Stream stream, string fileName, string contentType, CancellationToken cancellationToken) { - var docId = await _blobStorageService.UploadTempFileAsync(stream, fileName, contentType, cancellationToken); + var docId = await _blobStorageService.UploadTempFileAsync(stream, + fileName, + contentType, + cancellationToken); try { - return await SaveDocument(docId, - Path.GetFileNameWithoutExtension(fileName), - Path.GetExtension(fileName), - contentType, - stream.Length, - cancellationToken); + return CreateDocument(docId, + Path.GetFileNameWithoutExtension(fileName), + Path.GetExtension(fileName), + contentType, + stream.Length); } catch { @@ -55,7 +55,7 @@ public async Task UploadDocument(Stream stream, string fileName, strin } } - public async Task UploadImage(Stream stream, string fileName, string contentType, CancellationToken cancellationToken) + public async Task UploadImageAsync(Stream stream, string fileName, string contentType, CancellationToken cancellationToken) { using var image = SKImage.FromEncodedData(stream); using var thumb = GetThumbnail(image, ThumbnailWidth, ThumbnailHeight); @@ -77,19 +77,18 @@ public async Task UploadImage(Stream stream, string fileName, string cont cancellationToken)); try { - return await SaveImage(imageIds[0], - imageIds[1], - Path.GetFileNameWithoutExtension(fileName), - Path.GetExtension(fileName), - contentType, - stream.Length, - thumbStream.Length, - (image.Width, image.Height), - (thumb.Width, thumb.Height), - dateTaken, - gpsLat, - gpsLong, - cancellationToken); + return CreateImage(imageIds[0], + imageIds[1], + Path.GetFileNameWithoutExtension(fileName), + Path.GetExtension(fileName), + contentType, + stream.Length, + thumbStream.Length, + (image.Width, image.Height), + (thumb.Width, thumb.Height), + dateTaken, + gpsLat, + gpsLong); } catch { @@ -99,110 +98,99 @@ await Task.WhenAll(_blobStorageService.DeleteAsync(imageIds[0], true, cancellati } } - public async Task MakePermanent(Guid id, CancellationToken cancellationToken) - { - var file = await GetFile(id, cancellationToken); - switch (file) + public Task MakePermanentFileAsync(File file, CancellationToken cancellationToken) => + file switch { - case Image image: - await MakePermanentPicture(image, cancellationToken); - break; - case Document document: - await MakePermanentDocument(document, cancellationToken); - break; - } - } + Image image => MakePermanentImageAsync(image, cancellationToken), + Document document => MakePermanentDocumentAsync(document, cancellationToken), + _ => throw new NotImplementedException() + }; - public async Task MakePermanentPicture(Image file, CancellationToken cancellationToken) - { - file.MakePermanent(); - file.Thumbnail?.MakePermanent(); - await _dbContext.SaveEntitiesAsync(cancellationToken); + public Task MakePermanentFilesAsync(File[] files, CancellationToken cancellationToken) => + Task.WhenAll(files.Select(f => MakePermanentFileAsync(f, cancellationToken))); - await _blobStorageService.MakePermanentAsync(file.Id, cancellationToken); - if (file.ThumbnailId.HasValue) - await _blobStorageService.MakePermanentAsync(file.ThumbnailId.Value, cancellationToken); - } + public Task MakePermanentImageAsync(Image image, CancellationToken cancellationToken) => + Task.WhenAll(_blobStorageService.MakePermanentAsync(image.Id, cancellationToken), + image.ThumbnailId.HasValue + ? _blobStorageService.MakePermanentAsync(image.ThumbnailId.Value, cancellationToken) + : Task.CompletedTask); - public async Task MakePermanentDocument(Document file, CancellationToken cancellationToken) - { - file.MakePermanent(); - await _dbContext.SaveEntitiesAsync(cancellationToken); + public Task MakePermanentImagesAsync(Image[] images, CancellationToken cancellationToken) => + Task.WhenAll(images.Select(img => MakePermanentImageAsync(img, cancellationToken))); - await _blobStorageService.MakePermanentAsync(file.Id, cancellationToken); - } + public Task MakePermanentDocumentAsync(Document document, CancellationToken cancellationToken) => + _blobStorageService.MakePermanentAsync(document.Id, cancellationToken); - public async Task Delete(Guid id, CancellationToken cancellationToken) - { - var file = await GetFile(id, cancellationToken); - switch (file) - { - case Image image: - await DeleteImage(image, cancellationToken); - break; - case Document document: - await DeleteDocument(document, cancellationToken); - break; - } - } + public Task MakePermanentDocumentsAsync(Document[] documents, CancellationToken cancellationToken) => + Task.WhenAll(documents.Select(doc => MakePermanentDocumentAsync(doc, cancellationToken))); - public async Task DeleteDocument(Document file, CancellationToken cancellationToken) + public async Task DownloadFileAsync(File item, CancellationToken cancellationToken) { - _dbContext.Set().Remove(file); - await _dbContext.SaveEntitiesAsync(cancellationToken); + var file = await _blobStorageService.DownloadAsync(item.Id, item.IsTemp, cancellationToken); - await _blobStorageService.DeleteAsync(file.Id, file.IsTemp, cancellationToken); + return new(file, + $"{item.Name}{item.Extension}", + item.ContentType); } + + public Task DeleteFileAsync(File file, CancellationToken cancellationToken) => + file switch + { + Image image => DeleteImageAsync(image, cancellationToken), + Document document => DeleteDocumentAsync(document, cancellationToken), + _ => throw new NotImplementedException() + }; - public async Task DeleteImage(Image file, CancellationToken cancellationToken) - { - var thumbId = file.ThumbnailId; + public Task DeleteDocumentAsync(Document file, CancellationToken cancellationToken) => + _blobStorageService.DeleteAsync(file.Id, file.IsTemp, cancellationToken); - if (file.Thumbnail != null) - _dbContext.Set().Remove(file.Thumbnail); - _dbContext.Set().Remove(file); - await _dbContext.SaveEntitiesAsync(cancellationToken); + public Task DeleteImageAsync(Image image, CancellationToken cancellationToken) => + Task.WhenAll(_blobStorageService.DeleteAsync(image.Id, image.IsTemp, cancellationToken), + image.ThumbnailId.HasValue + ? _blobStorageService.DeleteAsync(image.ThumbnailId.Value, image.IsTemp, cancellationToken) + : Task.CompletedTask); - await Task.WhenAll(_blobStorageService.DeleteAsync(file.Id, file.IsTemp, cancellationToken), - thumbId.HasValue - ? _blobStorageService.DeleteAsync(thumbId.Value, file.IsTemp, cancellationToken) - : Task.CompletedTask); - } + public Task DeleteDocumentsAsync(Document[] documents, CancellationToken cancellationToken) => + Task.WhenAll(documents.Select(d => DeleteDocumentAsync(d, cancellationToken))); - public async Task CopyFile(Guid id, CancellationToken cancellationToken) - { - var file = await GetFile(id, cancellationToken); - var copyId = await _blobStorageService.CopyAsync(id, file.IsTemp, cancellationToken); + public Task DeleteImagesAsync(Image[] images, CancellationToken cancellationToken) => + Task.WhenAll(images.Select(img => DeleteImageAsync(img, cancellationToken))); - switch (file) - { - case Image image: - Guid? thumbCopyId = image.ThumbnailId.HasValue - ? await _blobStorageService.CopyAsync(image.ThumbnailId.Value, image.IsTemp, cancellationToken) - : null; + public Task DeleteFilesAsync(File[] files, CancellationToken cancellationToken) => + Task.WhenAll(files.Select(f => DeleteFileAsync(f, cancellationToken))); - return await SaveImage(copyId, - thumbCopyId, - image.Name, - image.Extension, - image.ContentType, - image.Size, - image.Thumbnail?.Size, - (image.Width, image.Height), - image.ThumbnailId.HasValue ? (image.Thumbnail!.Width, image.Thumbnail.Height) : null, - image.DateTaken, - image.GpsLatitude, - image.GpsLongitude, - cancellationToken); + public async Task CopyFileAsync(File file, CancellationToken cancellationToken) + { + var copyId = await _blobStorageService.CopyAsync(file.Id, file.IsTemp, cancellationToken); - default: - return await SaveDocument(copyId, - file.Name, - file.Extension, - file.ContentType, - file.Size, - cancellationToken); - } + return file switch + { + Image image => CreateImage(copyId, + image.ThumbnailId.HasValue + ? await _blobStorageService.CopyAsync(image.ThumbnailId.Value, + image.IsTemp, + cancellationToken) + : null, + image.Name, + image.Extension, + image.ContentType, + image.Size, + image.Thumbnail?.Size, + (image.Dimensions.Width, + image.Dimensions.Height), + image.ThumbnailId.HasValue + ? (image.Thumbnail!.Dimensions.Width, + image.Thumbnail.Dimensions.Height) + : null, + image.DateTaken, + image.Position?.Latitude, + image.Position?.Longitude), + _ => CreateDocument(copyId, + file.Name, + file.Extension, + file.ContentType, + file.Size) + }; } public ExifPropertyCollection GetMetadata(Stream stream) @@ -226,77 +214,52 @@ public SKImage GetThumbnail(SKImage image, int thumbnailWidth, int thumbnailHeig return SKImage.FromBitmap(scaledBitmap); } - private async Task GetFile(Guid id, CancellationToken cancellationToken) - { - return (await _dbContext.Set().FindAsync(new object[] { id }, cancellationToken))!; - } - - private async Task SaveImage(Guid imageId, - Guid? thumbnailId, - string name, - string extension, - string contentType, - long imageSize, - long? thumbSize, - (int Height, int Width) imageDimensions, - (int Height, int Width)? thumbDimensions, - DateTime? dateTaken, - float? gpsLatitude, - float? gpsLongitude, - CancellationToken cancellationToken) - { - var thumb = thumbnailId.HasValue - ? new Image(thumbnailId.Value, - name, - extension, - thumbSize!.Value, - contentType, - true, - thumbDimensions!.Value.Height, - thumbDimensions!.Value.Width, - dateTaken, - gpsLatitude, - gpsLongitude) - : null; - - var item = new Image(imageId, - name, - extension, - imageSize, - contentType, - true, - imageDimensions.Height, - imageDimensions.Width, - dateTaken, - gpsLatitude, - gpsLongitude, - thumb); - - return await Save(item, cancellationToken); - } - - private async Task SaveDocument(Guid id, - string name, - string extension, - string contentType, - long size, - CancellationToken cancellationToken) - { - var item = new Document(id, - name, - extension, - size, - contentType, - true); - - return await Save(item, cancellationToken); - } - - private async Task Save(T item, CancellationToken cancellationToken) where T : File - { - await _dbContext.Set().AddAsync(item, cancellationToken); - await _dbContext.SaveEntitiesAsync(cancellationToken); - - return item; - } + private Image CreateImage(Guid imageId, + Guid? thumbnailId, + string name, + string extension, + string contentType, + long imageSize, + long? thumbSize, + (int Height, int Width) imageDimensions, + (int Height, int Width)? thumbDimensions, + DateTime? dateTaken, + float? gpsLatitude, + float? gpsLongitude) => + new(imageId, + name, + extension, + imageSize, + contentType, + true, + imageDimensions.Height, + imageDimensions.Width, + dateTaken, + gpsLatitude, + gpsLongitude, + thumbnailId.HasValue + ? new Image(thumbnailId.Value, + name, + extension, + thumbSize!.Value, + contentType, + true, + thumbDimensions!.Value.Height, + thumbDimensions!.Value.Width, + dateTaken, + gpsLatitude, + gpsLongitude) + : null); + + private Document CreateDocument(Guid id, + string name, + string extension, + string contentType, + long size) => + new(id, + name, + extension, + size, + contentType, + true); } \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Api.Application/MediatorExtensions.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Api.Application/MediatorExtensions.cs index 9ba7dcd..b774257 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Api.Application/MediatorExtensions.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Api.Application/MediatorExtensions.cs @@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Mvc.ModelBinding; using Monaco.Template.Backend.Common.Api.Application.Enums; using Monaco.Template.Backend.Common.Application.Commands; +using Monaco.Template.Backend.Common.Application.DTOs; using Monaco.Template.Backend.Common.Application.Queries; using Monaco.Template.Backend.Common.Domain.Model; @@ -59,6 +60,59 @@ public static async Task> ExecuteQueryAsync(this : new OkObjectResult(result); } + /// + /// Executes the query passed and returns the corresponding response that can be either Ok(result) or a NotFound() result depending on whether the returned item is null or not + /// + /// The type of the item returned by the query + /// The type of the key to search the item by + /// + /// + /// + public static async Task> ExecuteQueryAsync(this IMediator mediator, + QueryByKeyBase query) + { + var item = await mediator.Send(query); + return item is null + ? new NotFoundResult() + : new OkObjectResult(item); + } + + /// + /// Executes the query passed and returns a FileStreamResult for allowing download of a file or a NotFound() result depending on whether the returned item is null or not + /// + /// + /// + /// + /// + public static async Task ExecuteFileDownloadAsync(this IMediator mediator, + QueryBase query) where TResult : FileDownloadDto + { + var item = await mediator.Send(query); + return GetFileDownload(item); + } + + /// + /// Executes the query passed and returns a FileStreamResult for allowing download of a file or a NotFound() result depending on whether the returned item is null or not + /// + /// + /// + /// + /// + public static async Task ExecuteFileDownloadAsync(this IMediator mediator, + QueryByIdBase query) where TResult : FileDownloadDto + { + var item = await mediator.Send(query); + return GetFileDownload(item); + } + + private static IActionResult GetFileDownload(TResult? item) where TResult : FileDownloadDto => + item is null + ? new NotFoundResult() + : new FileStreamResult(item.FileContent, item.ContentType) + { + FileDownloadName = item.FileName + }; + /// /// Executes the command passed and returns the corresponding response that can be either Created(result) or a NotFound() or a BadRequest() depending on the validations and processing /// diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.ApiGateway/Auth/Scopes.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.ApiGateway/Auth/Scopes.cs index 66cb00f..5939164 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.ApiGateway/Auth/Scopes.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.ApiGateway/Auth/Scopes.cs @@ -4,7 +4,7 @@ public static class Scopes { public const string CompaniesRead = "companies:read"; public const string CompaniesWrite = "companies:write"; -#if filesSupport +#if !excludeFilesSupport public const string FilesRead = "files:read"; public const string FilesWrite = "files:write"; #endif @@ -13,7 +13,7 @@ public static class Scopes { CompaniesRead, CompaniesWrite, -#if filesSupport +#if !excludeFilesSupport FilesRead, FilesWrite #endif diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.ApiGateway/reverseProxy.json b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.ApiGateway/reverseProxy.json index d4f48a9..19fbddf 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.ApiGateway/reverseProxy.json +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.ApiGateway/reverseProxy.json @@ -37,7 +37,7 @@ } ] }, - //#if (filesSupport) + //#if (!excludeFilesSupport) "FilesRead": { "ClusterId": "api", "AuthorizationPolicy": "files:read", diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Application/DTOs/FileDownloadDto.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Application/DTOs/FileDownloadDto.cs new file mode 100644 index 0000000..075c0c2 --- /dev/null +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Application/DTOs/FileDownloadDto.cs @@ -0,0 +1,5 @@ +namespace Monaco.Template.Backend.Common.Application.DTOs; + +public record FileDownloadDto(Stream FileContent, + string FileName, + string ContentType); \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Tests/Factories/Entities/AddressFactory.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Tests/Factories/Entities/AddressFactory.cs index f33a26b..9c8b141 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Tests/Factories/Entities/AddressFactory.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Tests/Factories/Entities/AddressFactory.cs @@ -39,7 +39,6 @@ public static IFixture RegisterAddressMock(this IFixture fixture) fixture.Create(), fixture.Create()?[..10], country); - mock.SetupGet(x => x.CountryId).Returns(country.Id); return mock.Object; }); return fixture; diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Tests/Factories/Entities/DocumentFactory.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Tests/Factories/Entities/DocumentFactory.cs new file mode 100644 index 0000000..a654182 --- /dev/null +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Tests/Factories/Entities/DocumentFactory.cs @@ -0,0 +1,45 @@ +using AutoFixture; +using Monaco.Template.Backend.Domain.Model; +using Moq; + +namespace Monaco.Template.Backend.Common.Tests.Factories.Entities; + +public class DocumentFactory +{ + public static Document Create() => + new Fixture().RegisterDocument() + .Create(); + + public static IEnumerable CreateMany() => + new Fixture().RegisterDocument() + .CreateMany(); +} + +public static class DocumentFactoryExtension +{ + public static IFixture RegisterDocument(this IFixture fixture) + { + fixture.Register(() => new Document(fixture.Create(), + fixture.Create(), + fixture.Create(), + fixture.Create(), + fixture.Create(), + false)); + return fixture; + } + + public static IFixture RegisterDocumentMock(this IFixture fixture) + { + fixture.Register(() => + { + var mock = new Mock(fixture.Create(), + fixture.Create(), + fixture.Create(), + fixture.Create(), + fixture.Create(), + false); + return mock.Object; + }); + return fixture; + } +} \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Tests/Factories/Entities/ImageFactory.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Tests/Factories/Entities/ImageFactory.cs new file mode 100644 index 0000000..074d348 --- /dev/null +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Tests/Factories/Entities/ImageFactory.cs @@ -0,0 +1,84 @@ +using AutoFixture; +using Monaco.Template.Backend.Domain.Model; +using Moq; + +namespace Monaco.Template.Backend.Common.Tests.Factories.Entities; + +public class ImageFactory +{ + public static Image Create() => + new Fixture().RegisterImage() + .Create(); + + public static IEnumerable CreateMany() => + new Fixture().RegisterImage() + .CreateMany(); +} + +public static class ImageFactoryExtension +{ + public static IFixture RegisterImage(this IFixture fixture) + { + fixture.Register(() => + { + var name = fixture.Create(); + const string extension = ".png"; + var size = fixture.Create(); + const string contentType = "image/png"; + + return new Image(fixture.Create(), + name, + extension, + size, + contentType, + false, + fixture.Create(), + fixture.Create(), + fixture.Create(), + null, + null, + new Image(fixture.Create(), + name, + extension, + size, + contentType, + false, + fixture.Create(), + fixture.Create())); + }); + return fixture; + } + + public static IFixture RegisterImageMock(this IFixture fixture) + { + fixture.Register(() => + { + var name = fixture.Create(); + const string extension = ".png"; + var size = fixture.Create(); + const string contentType = "image/png"; + + var mock = new Mock(fixture.Create(), + name, + extension, + size, + contentType, + false, + fixture.Create(), + fixture.Create(), + fixture.Create(), + null, + null, + new Image(fixture.Create(), + name, + extension, + size, + contentType, + false, + fixture.Create(), + fixture.Create())); + return mock.Object; + }); + return fixture; + } +} \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Tests/Factories/Entities/ProductFactory.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Tests/Factories/Entities/ProductFactory.cs new file mode 100644 index 0000000..e0cf2a5 --- /dev/null +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Tests/Factories/Entities/ProductFactory.cs @@ -0,0 +1,62 @@ +using AutoFixture; +using Monaco.Template.Backend.Domain.Model; +using Moq; + +namespace Monaco.Template.Backend.Common.Tests.Factories.Entities; + +public static class ProductFactory +{ + public static Product Create() => + new Fixture().RegisterImage() + .RegisterAddress() + .RegisterCompany() + .RegisterProduct() + .Create(); + + public static IEnumerable CreateMany() => + new Fixture().RegisterImage() + .RegisterAddress() + .RegisterCompany() + .RegisterProductMock() + .CreateMany(); +} + +public static class ProductFactoryExtension +{ + public static IFixture RegisterProduct(this IFixture fixture) + { + fixture.Register(() => + { + var product = new Product(fixture.Create(), + fixture.Create(), + fixture.Create(), + fixture.Create()); + var images = fixture.CreateMany(); + foreach (var image in images) + product.AddPicture(image); + + return product; + }); + return fixture; + } + + public static IFixture RegisterProductMock(this IFixture fixture) + { + fixture.Register(() => + { + var mock = new Mock(fixture.Create(), + fixture.Create(), + fixture.Create(), + fixture.Create()); + mock.SetupGet(x => x.Id) + .Returns(Guid.NewGuid()); + + var images = fixture.CreateMany(); + mock.SetupGet(x => x.Pictures) + .Returns(images.ToArray()); + + return mock.Object; + }); + return fixture; + } +} \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Tests/Factories/FixtureExtensions.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Tests/Factories/FixtureExtensions.cs index 1e33fb2..28668b4 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Tests/Factories/FixtureExtensions.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Tests/Factories/FixtureExtensions.cs @@ -20,7 +20,10 @@ public static IFixture RegisterFactories(this IFixture fixture) fixture.RegisterCompany() .RegisterAddress() - .RegisterCountry(); + .RegisterCountry() + .RegisterDocument() + .RegisterImage() + .RegisterProduct(); return fixture; } @@ -39,7 +42,10 @@ public static IFixture RegisterMockFactories(this IFixture fixture) fixture.RegisterCompanyMock() .RegisterAddressMock() - .RegisterCountryMock(); + .RegisterCountryMock() + .RegisterDocumentMock() + .RegisterImage() + .RegisterProductMock(); return fixture; } diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/CompanyTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/CompanyTests.cs index c15865b..0cf2783 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/CompanyTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/CompanyTests.cs @@ -2,6 +2,7 @@ using Monaco.Template.Backend.Common.Tests.Factories; using Monaco.Template.Backend.Domain.Model; using System.Diagnostics.CodeAnalysis; +using System.Linq; using Xunit; namespace Monaco.Template.Backend.Domain.Tests; @@ -29,7 +30,7 @@ public void NewCompanySucceeds(string name, sut.Version.Should().BeNull(); } - [Theory(DisplayName = "New company succeeds")] + [Theory(DisplayName = "Update company succeeds")] [AnonymousData] public void UpdateCompanySucceeds(Company sut, string name, @@ -48,4 +49,37 @@ public void UpdateCompanySucceeds(Company sut, sut.Address.Should().Be(address); sut.Version.Should().BeNull(); } + + [Theory(DisplayName = "Add product succeeds")] + [AnonymousData] + public void AddProductSucceeds(Company sut, Product product) + { + var originalProductCount = sut.Products.Count; + + sut.AddProduct(product); + + sut.Products + .Should() + .HaveCount(originalProductCount + 1); + } + + [Theory(DisplayName = "Remove product succeeds")] + [AnonymousData] + public void RemoveProductSucceeds(Company sut, Product[] products) + { + foreach (var product in products) + sut.AddProduct(product); + + var originalProductCount = sut.Products.Count; + + var deletedProduct = products.First(); + + sut.RemoveProduct(deletedProduct); + + sut.Products + .Should() + .HaveCount(originalProductCount - 1) + .And + .NotContain(deletedProduct); + } } \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/GpsPositionTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/GpsPositionTests.cs new file mode 100644 index 0000000..419fc62 --- /dev/null +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/GpsPositionTests.cs @@ -0,0 +1,28 @@ +using FluentAssertions; +using Monaco.Template.Backend.Domain.Model; +using System.Diagnostics.CodeAnalysis; +using System.Security.Cryptography; +using Xunit; + +namespace Monaco.Template.Backend.Domain.Tests; + +[ExcludeFromCodeCoverage] +[Trait("Core Domain Entities", "GpsPosition Entity")] +public class GpsPositionTests +{ + [Fact(DisplayName = "New GpsPosition succeeds")] + public void NewGpsPositionSucceeds() + { + var latitude = RandomNumberGenerator.GetInt32(-90, 90); + var longitude = RandomNumberGenerator.GetInt32(-180, 180); + + var sut = new GpsPosition(latitude, longitude); + + sut.Latitude + .Should() + .Be(latitude); + sut.Longitude + .Should() + .Be(longitude); + } +} \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/ProductTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/ProductTests.cs new file mode 100644 index 0000000..c8bdea4 --- /dev/null +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/ProductTests.cs @@ -0,0 +1,112 @@ +using FluentAssertions; +using Monaco.Template.Backend.Common.Tests.Factories; +using Monaco.Template.Backend.Domain.Model; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using Xunit; + +namespace Monaco.Template.Backend.Domain.Tests; + +[ExcludeFromCodeCoverage] +[Trait("Core Domain Entities", "Product Entity")] +public class ProductTests +{ + + [Theory(DisplayName = "New product succeeds")] + [AnonymousData] + public void NewProductSucceeds(string title, + string description, + decimal price, + Company company) + { + price *= price; //positive always + var sut = new Product(title, + description, + price, + company); + + sut.Title.Should().Be(title); + sut.Description.Should().Be(description); + sut.Price.Should().Be(price); + sut.Company.Should().Be(company); + } + + [Theory(DisplayName = "Update product succeeds")] + [AnonymousData] + public void UpdateProductSucceeds(Product sut, + string title, + string description, + decimal price, + Company company) + { + price *= price; //positive always + sut.Update(title, + description, + price, + company); + + sut.Title.Should().Be(title); + sut.Description.Should().Be(description); + sut.Price.Should().Be(price); + sut.Company.Should().Be(company); + } + + [Theory(DisplayName = "Add new picture succeeds")] + [AnonymousData] + public void AddNewPictureSucceeds(Product sut, Image picture) + { + var picturesCount = sut.Pictures.Count; + + sut.AddPicture(picture); + + sut.Pictures + .Should() + .HaveCount(picturesCount + 1) + .And + .Contain(picture); + } + + [Theory(DisplayName = "Set new picture as default succeeds")] + [AnonymousData] + public void AddNewDefaultPictureSucceeds(Product sut, Image picture) + { + var originalDefaultPicture = sut.DefaultPicture; + + sut.AddPicture(picture, true); + + sut.DefaultPicture + .Should() + .Be(picture) + .And + .NotBe(originalDefaultPicture); + } + + [Theory(DisplayName = "Remove picture succeeds")] + [AnonymousData] + public void RemovePictureSucceeds(Product sut) + { + var picturesCount = sut.Pictures.Count; + + sut.RemovePicture(sut.Pictures.First()); + + sut.Pictures + .Should() + .HaveCount(picturesCount - 1); + } + + [Theory(DisplayName = "Remove default picture succeeds")] + [AnonymousData] + public void RemoveDefaultPictureSucceeds(Product sut) + { + var picturesCount = sut.Pictures.Count; + + sut.RemovePicture(sut.DefaultPicture); + + sut.Pictures + .Should() + .HaveCount(picturesCount - 1); + sut.DefaultPicture + .Should() + .Be(sut.Pictures.First()); + } +} \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/Company.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/Company.cs index 723d7e2..086b620 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/Company.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/Company.cs @@ -30,6 +30,9 @@ public Company(string name, public Address? Address { get; private set; } + private readonly List _products = new(); + public virtual IReadOnlyList Products => _products; + public virtual void Update(string name, string email, string webSiteUrl, @@ -40,4 +43,16 @@ public virtual void Update(string name, WebSiteUrl = webSiteUrl; Address = address; } + + public void AddProduct(Product product) + { + if (!Products.Contains(product)) + _products.Add(product); + } + + public void RemoveProduct(Product product) + { + if (Products.Contains(product)) + _products.Remove(product); + } } \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/File.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/File.cs index 1f75ece..c09efb5 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/File.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/File.cs @@ -30,7 +30,7 @@ protected File(Guid id, public DateTime UploadedOn { get; protected set; } public bool IsTemp { get; protected set; } - public void MakePermanent() + public virtual void MakePermanent() { IsTemp = false; } diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/GpsPosition.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/GpsPosition.cs new file mode 100644 index 0000000..12a1bf8 --- /dev/null +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/GpsPosition.cs @@ -0,0 +1,27 @@ +using Dawn; +using Monaco.Template.Backend.Common.Domain.Model; + +namespace Monaco.Template.Backend.Domain.Model; + +public class GpsPosition : ValueObject +{ + protected GpsPosition() + { } + + public GpsPosition(float latitude, float longitude) + { + Latitude = Guard.Argument(latitude, nameof(latitude)) + .InRange(-90, 90); + Longitude = Guard.Argument(longitude, nameof(longitude)) + .InRange(-180, 180); + } + + public float Latitude { get; } + public float Longitude { get; } + + protected override IEnumerable GetEqualityComponents() + { + yield return Latitude; + yield return Longitude; + } +} \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/Image.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/Image.cs index eccf32f..ec8ef98 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/Image.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/Image.cs @@ -3,8 +3,7 @@ public class Image : File { protected Image() - { - } + { } public Image(Guid id, string name, @@ -17,22 +16,31 @@ public Image(Guid id, DateTime? dateTaken = null, float? gpsLatitude = null, float? gpsLongitude = null, - Image? thumbnail = null) : base(id, name, extension, size, contentType, isTemp) + Image? thumbnail = null) : base(id, + name, + extension, + size, + contentType, + isTemp) { - Height = height; - Width = width; + Dimensions = new(height, width); DateTaken = dateTaken; - GpsLatitude = gpsLatitude; - GpsLongitude = gpsLongitude; + Position = gpsLatitude.HasValue && gpsLongitude.HasValue + ? new(gpsLatitude.Value, gpsLongitude.Value) + : null; Thumbnail = thumbnail; } - public DateTime? DateTaken { get; private set; } - public int Height { get; private set; } - public int Width { get; private set; } - public float? GpsLatitude { get; private set; } - public float? GpsLongitude { get; private set; } + public DateTime? DateTaken { get; } + public ImageDimensions Dimensions { get; } + public GpsPosition? Position { get; } public Guid? ThumbnailId { get; private set; } - public virtual Image? Thumbnail { get; private set; } + public virtual Image? Thumbnail { get; } + + public override void MakePermanent() + { + base.MakePermanent(); + Thumbnail?.MakePermanent(); + } } \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/ImageDimensions.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/ImageDimensions.cs new file mode 100644 index 0000000..60d8fbf --- /dev/null +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/ImageDimensions.cs @@ -0,0 +1,24 @@ +using Monaco.Template.Backend.Common.Domain.Model; + +namespace Monaco.Template.Backend.Domain.Model; + +public class ImageDimensions : ValueObject +{ + protected ImageDimensions() + { } + + public ImageDimensions(int height, int width) + { + Height = height; + Width = width; + } + + public int Height { get; } + public int Width { get; } + + protected override IEnumerable GetEqualityComponents() + { + yield return Height; + yield return Width; + } +} \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/Product.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/Product.cs new file mode 100644 index 0000000..5f6704f --- /dev/null +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/Product.cs @@ -0,0 +1,66 @@ +using Monaco.Template.Backend.Common.Domain.Model; + +namespace Monaco.Template.Backend.Domain.Model; + +public class Product : Entity +{ + protected Product() + { + } + + public Product(string title, + string description, + decimal price, + Company company) + { + Title = title; + Description = description; + Price = price; + Company = company; + } + + public string Title { get; private set; } + public string Description { get; private set; } + public decimal Price { get; private set; } + + public Guid CompanyId { get; } + public virtual Company Company { get; private set; } + + private readonly List _pictures = new(); + public virtual IReadOnlyList Pictures => _pictures; + + public Guid DefaultPictureId { get; } + public virtual Image DefaultPicture { get; private set; } + + public virtual void Update(string title, + string description, + decimal price, + Company company) + { + Title = title; + Description = description; + Price = price; + Company = company; + } + + public void AddPicture(Image picture, bool @default = false) + { + if (!Pictures.Contains(picture)) + { + _pictures.Add(picture); + picture.MakePermanent(); + } + + if (@default || _pictures.Count == 1) + DefaultPicture = picture; + } + + public void RemovePicture(Image picture) + { + if (Pictures.Contains(picture)) + _pictures.Remove(picture); + + if (picture == DefaultPicture && Pictures.Any()) + DefaultPicture = Pictures[0]; + } +} \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.sln b/src/Content/Backend/Solution/Monaco.Template.Backend.sln index 702c527..74d2176 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.sln +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.sln @@ -61,7 +61,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Monaco.Template.Backend.App EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Monaco.Template.Backend.Application.Infrastructure.Migrations", "Monaco.Template.Backend.Application.Infrastructure.Migrations\Monaco.Template.Backend.Application.Infrastructure.Migrations.csproj", "{1B80E15B-FC20-4B57-A3E5-3B6B3EBDA92F}" EndProject -#if (filesSupport) +#if (!excludeFilesSupport) Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Monaco.Template.Backend.Common.BlobStorage", "Monaco.Template.Backend.Common.BlobStorage\Monaco.Template.Backend.Common.BlobStorage.csproj", "{42E51D47-B82F-4A92-B1E5-CD8BE44DE6F0}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Monaco.Template.Backend.Common.BlobStorage.Tests", "Monaco.Template.Backend.Common.BlobStorage.Tests\Monaco.Template.Backend.Common.BlobStorage.Tests.csproj", "{D8623B90-59C1-4753-A0E6-F2DBD4305C9B}" @@ -147,7 +147,7 @@ Global {1B80E15B-FC20-4B57-A3E5-3B6B3EBDA92F}.Debug|Any CPU.Build.0 = Debug|Any CPU {1B80E15B-FC20-4B57-A3E5-3B6B3EBDA92F}.Release|Any CPU.ActiveCfg = Release|Any CPU {1B80E15B-FC20-4B57-A3E5-3B6B3EBDA92F}.Release|Any CPU.Build.0 = Release|Any CPU - #if (filesSupport) + #if (!excludeFilesSupport) {42E51D47-B82F-4A92-B1E5-CD8BE44DE6F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {42E51D47-B82F-4A92-B1E5-CD8BE44DE6F0}.Debug|Any CPU.Build.0 = Debug|Any CPU {42E51D47-B82F-4A92-B1E5-CD8BE44DE6F0}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -181,7 +181,7 @@ Global #endif {E5781B96-E0CA-4762-9412-C4202E0CA08F} = {920A23AF-59DA-4453-B825-0549B1C04F5B} {B09E0906-8522-4B70-8C55-958415DAF21D} = {920A23AF-59DA-4453-B825-0549B1C04F5B} - #if (filesSupport) + #if (!excludeFilesSupport) {42E51D47-B82F-4A92-B1E5-CD8BE44DE6F0} = {8BFE9C37-2620-4156-88B8-286537954C5E} {D8623B90-59C1-4753-A0E6-F2DBD4305C9B} = {35484293-234F-40DA-B430-A95170EDE449} #endif From f63db35dcdaa9303627eea1c650e25dbefd27928 Mon Sep 17 00:00:00 2001 From: CesarD Date: Tue, 19 Dec 2023 10:24:26 +0100 Subject: [PATCH 02/21] FIX: Adding missing tests. CHORE: Replaced filesSupport flag with excludeFilesSupport one. --- .../Solution/.template.config/ide.host.json | 4 +- .../Solution/.template.config/template.json | 26 ++++-- .../Auth/Scopes.cs | 2 - .../DocumentTests.cs | 50 ++++++++++ .../ImageDimensionsTests.cs | 26 ++++++ .../ImageTests .cs | 91 +++++++++++++++++++ 6 files changed, 189 insertions(+), 10 deletions(-) create mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/DocumentTests.cs create mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/ImageDimensionsTests.cs create mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/ImageTests .cs diff --git a/src/Content/Backend/Solution/.template.config/ide.host.json b/src/Content/Backend/Solution/.template.config/ide.host.json index abf04ec..9a8085d 100644 --- a/src/Content/Backend/Solution/.template.config/ide.host.json +++ b/src/Content/Backend/Solution/.template.config/ide.host.json @@ -10,9 +10,9 @@ "isVisible": true }, { - "id": "filesSupport", + "id": "excludeFilesSupport", "name": { - "text": "Include files support and structure" + "text": "Exclude files support and structure" }, "isVisible": true }, diff --git a/src/Content/Backend/Solution/.template.config/template.json b/src/Content/Backend/Solution/.template.config/template.json index 95fcd00..2dcea4c 100644 --- a/src/Content/Backend/Solution/.template.config/template.json +++ b/src/Content/Backend/Solution/.template.config/template.json @@ -26,7 +26,7 @@ "displayName": "Exclude Common projects", "description": "Exclude all the Common.* projects from the solution generated" }, - "filesSupport": { + "excludeFilesSupport": { "type": "parameter", "datatype": "bool", "defaultValue": "false", @@ -156,25 +156,39 @@ ] }, { - "condition": "(!filesSupport)", + "condition": "(!excludeFilesSupport)", "exclude": [ "Monaco.Template.Backend.Common.BlobStorage/**/*", "Monaco.Template.Backend.Common.BlobStorage.Tests/**/*", "Monaco.Template.Backend.Api/Controllers/FilesController.cs", - "Monaco.Template.Backend.Api/Controllers/ImagesController.cs", + "Monaco.Template.Backend.Api/Controllers/ProductsController.cs", + "Monaco.Template.Backend.Api/DTOs/ProductCreateEditDto.cs", + "Monaco.Template.Backend.Api/DTOs/Extensions/ProductExtensions.cs", "Monaco.Template.Backend.Application/Features/File/**/*", - "Monaco.Template.Backend.Application/Features/Image/**/*", + "Monaco.Template.Backend.Application/Features/Product/**/*", "Monaco.Template.Backend.Application/DTOs/Extensions/FileExtensions.cs", - "Monaco.Template.Backend.Application/DTOs/File*.cs", + "Monaco.Template.Backend.Application/DTOs/FileDto.cs", "Monaco.Template.Backend.Application/DTOs/ImageDto.cs", + "Monaco.Template.Backend.Application/DTOs/ProductDto.cs", "Monaco.Template.Backend.Application/Services/**/*FileService.*", "Monaco.Template.Backend.Application.Infrastructure/EntityConfigurations/DocumentEntityConfiguration.cs", "Monaco.Template.Backend.Application.Infrastructure/EntityConfigurations/FileEntityConfiguration.cs", "Monaco.Template.Backend.Application.Infrastructure/EntityConfigurations/ImageEntityConfiguration.cs", + "Monaco.Template.Backend.Application.Infrastructure/EntityConfigurations/ProductEntityConfiguration.cs", "Monaco.Template.Backend.Application.Tests/Services/FileServiceTests.cs", + "Monaco.Template.Backend.Application.Tests/Features/File/**/*", + "Monaco.Template.Backend.Application.Tests/Features/Product/**/*", "Monaco.Template.Backend.Domain/Model/Document.cs", "Monaco.Template.Backend.Domain/Model/File.cs", - "Monaco.Template.Backend.Domain/Model/Image.cs" + "Monaco.Template.Backend.Domain/Model/GpsPosition.cs", + "Monaco.Template.Backend.Domain/Model/Image.cs", + "Monaco.Template.Backend.Domain/Model/ImageDimensions.cs", + "Monaco.Template.Backend.Domain/Model/Product.cs", + "Monaco.Template.Backend.Domain.Tests/DocumentTests.cs", + "Monaco.Template.Backend.Domain.Tests/GpsPositionTests.cs", + "Monaco.Template.Backend.Domain.Tests/ImageDimensionsTests.cs", + "Monaco.Template.Backend.Domain.Tests/ImageTests.cs", + "Monaco.Template.Backend.Domain.Tests/ProductTests.cs" ] }, { diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Auth/Scopes.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Auth/Scopes.cs index 615ed6b..169197b 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Auth/Scopes.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Auth/Scopes.cs @@ -6,7 +6,6 @@ public static class Scopes public const string CompaniesRead = "companies:read"; public const string CompaniesWrite = "companies:write"; #if !excludeFilesSupport - public const string FilesRead = "files:read"; public const string FilesWrite = "files:write"; public const string ProductsWrite = "products:write"; #endif @@ -16,7 +15,6 @@ public static class Scopes CompaniesRead, CompaniesWrite, #if !excludeFilesSupport - FilesRead, FilesWrite, ProductsWrite #endif diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/DocumentTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/DocumentTests.cs new file mode 100644 index 0000000..04bbce6 --- /dev/null +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/DocumentTests.cs @@ -0,0 +1,50 @@ +using System; +using Monaco.Template.Backend.Domain.Model; +using System.Diagnostics.CodeAnalysis; +using System.Security.Cryptography; +using FluentAssertions; +using Monaco.Template.Backend.Common.Tests.Factories; +using Xunit; + +namespace Monaco.Template.Backend.Domain.Tests; + +[ExcludeFromCodeCoverage] +[Trait("Core Domain Entities", "Document Entity")] +public class DocumentTests +{ + [Theory(DisplayName = "New Document succeeds")] + [AnonymousData] + public void NewDocumentSucceeds(Guid id, + string name, + string extension, + long size, + string contentType, + bool isTemp) + { + var sut = new Document(id, + name, + extension, + size, + contentType, + isTemp); + + sut.Id + .Should() + .Be(id); + sut.Name + .Should() + .Be(name); + sut.Extension + .Should() + .Be(extension); + sut.Size + .Should() + .Be(size); + sut.ContentType + .Should() + .Be(contentType); + sut.IsTemp + .Should() + .Be(isTemp); + } +} \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/ImageDimensionsTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/ImageDimensionsTests.cs new file mode 100644 index 0000000..bf9c311 --- /dev/null +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/ImageDimensionsTests.cs @@ -0,0 +1,26 @@ +using FluentAssertions; +using Monaco.Template.Backend.Common.Tests.Factories; +using Monaco.Template.Backend.Domain.Model; +using System.Diagnostics.CodeAnalysis; +using Xunit; + +namespace Monaco.Template.Backend.Domain.Tests; + +[ExcludeFromCodeCoverage] +[Trait("Core Domain Entities", "ImageDimensions Entity")] +public class ImageDimensionsTests +{ + [Theory(DisplayName = "New ImageDimensions succeeds")] + [AnonymousData] + public void NewImageDimensionsSucceeds(int height, int width) + { + var sut = new ImageDimensions(height, width); + + sut.Height + .Should() + .Be(height); + sut.Width + .Should() + .Be(width); + } +} \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/ImageTests .cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/ImageTests .cs new file mode 100644 index 0000000..e0549ae --- /dev/null +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/ImageTests .cs @@ -0,0 +1,91 @@ +using System; +using Monaco.Template.Backend.Domain.Model; +using System.Diagnostics.CodeAnalysis; +using System.Security.Cryptography; +using FluentAssertions; +using Monaco.Template.Backend.Common.Tests.Factories; +using Xunit; + +namespace Monaco.Template.Backend.Domain.Tests; + +[ExcludeFromCodeCoverage] +[Trait("Core Domain Entities", "Image Entity")] +public class ImageTests +{ + [Theory(DisplayName = "New Image succeeds")] + [AnonymousData] + public void NewImageSucceeds(Guid id, + string name, + string extension, + long size, + string contentType, + bool isTemp, + int height, + int width, + DateTime dateTaken, + Image thumbnail) + { + var latitude = RandomNumberGenerator.GetInt32(-90, 90); + var longitude = RandomNumberGenerator.GetInt32(-180, 180); + + var sut = new Image(id, + name, + extension, + size, + contentType, + isTemp, + height, + width, + dateTaken, + latitude, + longitude, + thumbnail); + + sut.Id + .Should() + .Be(id); + sut.Name + .Should() + .Be(name); + sut.Extension + .Should() + .Be(extension); + sut.Size + .Should() + .Be(size); + sut.ContentType + .Should() + .Be(contentType); + sut.IsTemp + .Should() + .Be(isTemp); + sut.Dimensions + .Should() + .NotBeNull(); + sut.Dimensions! + .Height + .Should() + .Be(height); + sut.Dimensions! + .Width + .Should() + .Be(width); + sut.DateTaken + .Should() + .Be(dateTaken); + sut.Position + .Should() + .NotBeNull(); + sut.Position! + .Latitude + .Should() + .Be(latitude); + sut.Position! + .Longitude + .Should() + .Be(longitude); + sut.Thumbnail + .Should() + .Be(thumbnail); + } +} \ No newline at end of file From 4b325dc5e141b45e5ce97622ca9235ee792923b3 Mon Sep 17 00:00:00 2001 From: CesarD Date: Tue, 19 Dec 2023 10:31:44 +0100 Subject: [PATCH 03/21] CHORE: Some cleanup and adding docs to API endpoints. --- .../Controllers/CompaniesController.cs | 26 +++++++++++++++ .../Controllers/FilesController.cs | 6 ++++ .../Controllers/ProductsController.cs | 32 +++++++++++++++++++ .../Features/Company/GetCompanyById.cs | 1 - 4 files changed, 64 insertions(+), 1 deletion(-) diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Controllers/CompaniesController.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Controllers/CompaniesController.cs index c623611..43579d6 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Controllers/CompaniesController.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Controllers/CompaniesController.cs @@ -28,6 +28,10 @@ public CompaniesController(IMediator mediator) _mediator = mediator; } + /// + /// Gets a list of companies + /// + /// [HttpGet] #if (!disableAuth) [Authorize(Scopes.CompaniesRead)] @@ -35,6 +39,11 @@ public CompaniesController(IMediator mediator) public Task>> Get() => _mediator.ExecuteQueryAsync(new GetCompanyPage.Query(Request.Query)); + /// + /// Gets a company by Id + /// + /// + /// [HttpGet("{id:guid}")] #if (!disableAuth) [Authorize(Scopes.CompaniesRead)] @@ -42,6 +51,12 @@ public Task>> Get() => public Task> Get(Guid id) => _mediator.ExecuteQueryAsync(new GetCompanyById.Query(id)); + /// + /// Creates a new company + /// + /// + /// + /// [HttpPost] #if (!disableAuth) [Authorize(Scopes.CompaniesWrite)] @@ -52,6 +67,12 @@ public Task> Post([FromRoute] ApiVersion apiVersion, [FromBod "api/v{0}/Companies/{1}", apiVersion); + /// + /// Edits an existing company + /// + /// + /// + /// [HttpPut("{id:guid}")] #if (!disableAuth) [Authorize(Scopes.CompaniesWrite)] @@ -61,6 +82,11 @@ public Task Put(Guid id, [FromBody] CompanyCreateEditDto dto) => ModelState, ResponseType.NoContent); + /// + /// Deletes a company + /// + /// + /// [HttpDelete("{id:guid}")] #if (!disableAuth) [Authorize(Scopes.CompaniesWrite)] diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Controllers/FilesController.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Controllers/FilesController.cs index e6834ca..1f5ed2a 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Controllers/FilesController.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Controllers/FilesController.cs @@ -24,6 +24,12 @@ public FilesController(IMediator mediator) _mediator = mediator; } + /// + /// Uploads a new file that remains as temporal until it is referenced somewhere else in the app + /// + /// + /// + /// [HttpPost] #if (!disableAuth) [Authorize(Scopes.FilesWrite)] diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Controllers/ProductsController.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Controllers/ProductsController.cs index c7e1239..ef63f42 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Controllers/ProductsController.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Controllers/ProductsController.cs @@ -25,16 +25,31 @@ public ProductsController(IMediator mediator) _mediator = mediator; } + /// + /// Gets a page of products + /// + /// [HttpGet] [AllowAnonymous] public Task>> Get() => _mediator.ExecuteQueryAsync(new GetProductPage.Query(Request.Query)); + /// + /// Gets a product by Id + /// + /// + /// [HttpGet("{id:guid}")] [AllowAnonymous] public Task> Get(Guid id) => _mediator.ExecuteQueryAsync(new GetProductById.Query(id)); + /// + /// Creates a new product + /// + /// + /// + /// [HttpPost] #if (!disableAuth) [Authorize(Scopes.ProductsWrite)] @@ -45,6 +60,12 @@ public Task> Post([FromRoute] ApiVersion apiVersion, [FromBod "api/v{0}/Products/{1}", apiVersion); + /// + /// Edits an existing product + /// + /// + /// + /// [HttpPut("{id:guid}")] #if (!disableAuth) [Authorize(Scopes.ProductsWrite)] @@ -54,6 +75,11 @@ public Task Put(Guid id, [FromBody] ProductCreateEditDto dto) => ModelState, ResponseType.NoContent); + /// + /// Deletes a product + /// + /// + /// [HttpDelete("{id:guid}")] #if (!disableAuth) [Authorize(Scopes.ProductsWrite)] @@ -62,6 +88,12 @@ public Task Delete(Guid id) => _mediator.ExecuteCommandAsync(new DeleteProduct.Command(id), ModelState); + /// + /// Downloads a picture from a product + /// + /// + /// + /// [HttpGet("{productId:guid}/Pictures/{pictureId:guid}")] [AllowAnonymous] [ProducesResponseType(typeof(FileContentResult), (int)HttpStatusCode.OK)] diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Company/GetCompanyById.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Company/GetCompanyById.cs index 9c4e54f..277ef32 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Company/GetCompanyById.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Company/GetCompanyById.cs @@ -4,7 +4,6 @@ using Monaco.Template.Backend.Application.DTOs.Extensions; using Monaco.Template.Backend.Application.Infrastructure.Context; using Monaco.Template.Backend.Common.Application.Queries; -using Monaco.Template.Backend.Common.Infrastructure.Context.Extensions; namespace Monaco.Template.Backend.Application.Features.Company; From a26a2eb4e2b63cad615e23162005cc1e326039c4 Mon Sep 17 00:00:00 2001 From: CesarD Date: Tue, 19 Dec 2023 10:32:26 +0100 Subject: [PATCH 04/21] CHORE: Removed initial migration from template. --- .../20231204192153_Init.Designer.cs | 1318 ----------------- .../Migrations/20231204192153_Init.cs | 395 ----- .../Migrations/AppDbContextModelSnapshot.cs | 1315 ---------------- 3 files changed, 3028 deletions(-) delete mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure.Migrations/Migrations/20231204192153_Init.Designer.cs delete mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure.Migrations/Migrations/20231204192153_Init.cs delete mode 100644 src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure.Migrations/Migrations/AppDbContextModelSnapshot.cs diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure.Migrations/Migrations/20231204192153_Init.Designer.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure.Migrations/Migrations/20231204192153_Init.Designer.cs deleted file mode 100644 index 2efa9a6..0000000 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure.Migrations/Migrations/20231204192153_Init.Designer.cs +++ /dev/null @@ -1,1318 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Monaco.Template.Backend.Application.Infrastructure.Context; - -#nullable disable - -namespace Monaco.Template.Backend.Application.Infrastructure.Migrations.Migrations -{ - [DbContext(typeof(AppDbContext))] - [Migration("20231204192153_Init")] - partial class Init - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "8.0.0") - .HasAnnotation("Proxies:ChangeTracking", false) - .HasAnnotation("Proxies:CheckEquality", false) - .HasAnnotation("Proxies:LazyLoading", true) - .HasAnnotation("Relational:MaxIdentifierLength", 128); - - SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); - - modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.Company", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("Email") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("nvarchar(255)"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("Version") - .IsConcurrencyToken() - .IsRequired() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("rowversion"); - - b.Property("WebSiteUrl") - .HasMaxLength(300) - .HasColumnType("nvarchar(300)"); - - b.HasKey("Id"); - - b.ToTable("Company"); - }); - - modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.Country", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.HasKey("Id"); - - b.ToTable("Country"); - - b.HasData( - new - { - Id = new Guid("5c064eff-a037-a6a3-06ec-92f662903af3"), - Name = "Afghanistan" - }, - new - { - Id = new Guid("a8b54a61-35d8-9b82-76e4-c709561d9952"), - Name = "Albania" - }, - new - { - Id = new Guid("9f420922-9842-0d2d-616d-dacee7c25db7"), - Name = "Algeria" - }, - new - { - Id = new Guid("26253117-7664-92a9-1a3c-b15cf4bf4c78"), - Name = "Andorra" - }, - new - { - Id = new Guid("ba510e09-5109-42a2-63f0-32d7ede12a5a"), - Name = "Angola" - }, - new - { - Id = new Guid("359da8da-68eb-9466-855d-f0f381f715b8"), - Name = "Antigua and Barbuda" - }, - new - { - Id = new Guid("01ec70b8-6aad-3770-a129-62c0fc294791"), - Name = "Argentina" - }, - new - { - Id = new Guid("7d62846b-1841-882f-1cc4-85e2edeea265"), - Name = "Armenia" - }, - new - { - Id = new Guid("269928e1-37c5-32e0-60c5-bc6da2b8240e"), - Name = "Australia" - }, - new - { - Id = new Guid("7fce71e6-a14d-5d96-2dc1-1fc6779e02d3"), - Name = "Austria" - }, - new - { - Id = new Guid("4cf81cef-66a5-a117-3297-884134e903ee"), - Name = "Azerbaijan" - }, - new - { - Id = new Guid("08b5d3d0-89ed-a66f-3175-05316ae4a309"), - Name = "Bahamas" - }, - new - { - Id = new Guid("d7bd1f34-6ef7-43a6-24ed-53bca003086c"), - Name = "Bahrain" - }, - new - { - Id = new Guid("0d69d315-2825-2d05-9c04-ba1ad47180ac"), - Name = "Bangladesh" - }, - new - { - Id = new Guid("52f81e1e-6903-88e8-199f-cfc5139b0c69"), - Name = "Barbados" - }, - new - { - Id = new Guid("52b13dd7-28fc-9bba-8d59-5c2209531bf5"), - Name = "Belarus" - }, - new - { - Id = new Guid("8b9ac6d0-2320-3f99-8db7-d78c5d53151a"), - Name = "Belgium" - }, - new - { - Id = new Guid("c12db9c7-7ca1-4aec-34f1-7d0bb4713ca8"), - Name = "Belize" - }, - new - { - Id = new Guid("e34dc09e-2df2-3661-90e1-f03154d45caf"), - Name = "Benin" - }, - new - { - Id = new Guid("cf59ee2f-144d-99ac-9048-eafaba1f4732"), - Name = "Bhutan" - }, - new - { - Id = new Guid("1a426c53-787f-527c-5471-c505d6403603"), - Name = "Bolivia" - }, - new - { - Id = new Guid("fae877c5-4806-05e8-2068-950cdcea6ba9"), - Name = "Bosnia and Herzegovina" - }, - new - { - Id = new Guid("e0276db5-123f-6028-9e3e-eb43f2e06c47"), - Name = "Botswana" - }, - new - { - Id = new Guid("72499e6c-80a1-32c3-2692-7216abe7815b"), - Name = "Brazil" - }, - new - { - Id = new Guid("ba408210-2ea9-8c6c-1d5d-7e33973f1c99"), - Name = "Brunei" - }, - new - { - Id = new Guid("99532f86-827d-39ba-1c01-b9795ec60bf4"), - Name = "Bulgaria" - }, - new - { - Id = new Guid("f16e701a-5dbf-a441-3305-20ac536d34dc"), - Name = "Burkina Faso" - }, - new - { - Id = new Guid("ff0258f4-35a2-220b-9d9d-f0fe28226cc3"), - Name = "Burundi" - }, - new - { - Id = new Guid("f8135306-1323-4f48-7a4b-8d0427cb075b"), - Name = "Côte d'Ivoire" - }, - new - { - Id = new Guid("4676b79b-461c-95de-9871-041d2e0b130b"), - Name = "Cabo Verde" - }, - new - { - Id = new Guid("42f62587-3470-5967-77e3-f9b0cf285d90"), - Name = "Cambodia" - }, - new - { - Id = new Guid("01deb5a8-6bd7-1879-9d4b-cb73dd0e9a97"), - Name = "Cameroon" - }, - new - { - Id = new Guid("ff7c5aa2-6b56-218e-491a-42f4c67ca4a9"), - Name = "Canada" - }, - new - { - Id = new Guid("77b88575-0e8c-82d0-72bf-06f638b7485f"), - Name = "Central African Republic" - }, - new - { - Id = new Guid("758d4f58-7371-36c1-26c2-fcdb993806eb"), - Name = "Chad" - }, - new - { - Id = new Guid("97c787c7-915b-4878-3aa2-6ca1eec02f65"), - Name = "Chile" - }, - new - { - Id = new Guid("003548f7-318a-6f99-8a27-d62963b64cb5"), - Name = "China" - }, - new - { - Id = new Guid("63a948ca-178b-93da-4fdd-e6be10b49a42"), - Name = "Colombia" - }, - new - { - Id = new Guid("6d2bc2ca-2f37-3698-7f08-b7b3eeda5bf5"), - Name = "Comoros" - }, - new - { - Id = new Guid("d9e7fd6d-77f2-8e76-0174-4c17df936d4e"), - Name = "Congo (Congo-Brazzaville)" - }, - new - { - Id = new Guid("16eded64-8619-2b73-682f-a703c1cb2d76"), - Name = "Costa Rica" - }, - new - { - Id = new Guid("7915a976-5224-94f8-232f-ac163a11630c"), - Name = "Croatia" - }, - new - { - Id = new Guid("b6ed03e6-096c-3f87-093d-f3ff4bf34c24"), - Name = "Cuba" - }, - new - { - Id = new Guid("d7506bd0-454d-1b83-39e0-905836535271"), - Name = "Cyprus" - }, - new - { - Id = new Guid("caf14a3d-777d-0ee5-63a9-1c3da4e81458"), - Name = "Czechia (Czech Republic)" - }, - new - { - Id = new Guid("da82e26d-40bd-0866-0822-3d5468a36c3e"), - Name = "Democratic Republic of the Congo" - }, - new - { - Id = new Guid("57dc70e9-17ec-995b-5a60-a7c029b1476a"), - Name = "Denmark" - }, - new - { - Id = new Guid("8c6486fe-2680-4725-1ef3-3d56e3100f08"), - Name = "Djibouti" - }, - new - { - Id = new Guid("d7e310ab-99c3-0a50-2ead-57a2823433ee"), - Name = "Dominica" - }, - new - { - Id = new Guid("555a4e83-0151-7a10-2072-6cc9f4ac77c1"), - Name = "Dominican Republic" - }, - new - { - Id = new Guid("2908f020-3d75-3f9a-1a7f-020d1f8d5553"), - Name = "Ecuador" - }, - new - { - Id = new Guid("89bd993a-4eaa-6bae-8cf9-22f766fa2a1e"), - Name = "Egypt" - }, - new - { - Id = new Guid("ab1e3408-7157-2629-29a5-fbd6a61d92a9"), - Name = "El Salvador" - }, - new - { - Id = new Guid("e58f3cfd-069a-4457-23ef-9df8d7fe9ba0"), - Name = "Equatorial Guinea" - }, - new - { - Id = new Guid("5e7808be-01a7-9495-2320-314ce20871f3"), - Name = "Eritrea" - }, - new - { - Id = new Guid("5198e2c0-8107-5bcf-90b4-0054eac52295"), - Name = "Estonia" - }, - new - { - Id = new Guid("cfa8f583-23d4-1475-57ea-ef72ae7b633f"), - Name = "Eswatini (fmr. \"Swaziland\")" - }, - new - { - Id = new Guid("637e0fb3-34ed-6a1b-7524-3d6cd3155d35"), - Name = "Ethiopia" - }, - new - { - Id = new Guid("6459ce24-8398-57e0-4a31-48addb374e6d"), - Name = "Fiji" - }, - new - { - Id = new Guid("d726f074-4b1d-3043-39eb-f9b4ab9b2344"), - Name = "Finland" - }, - new - { - Id = new Guid("a5d734a1-021d-9b50-6fd4-b8f24bb96b12"), - Name = "France" - }, - new - { - Id = new Guid("a64406fb-51f7-2ed2-31af-847f9cf16783"), - Name = "Gabon" - }, - new - { - Id = new Guid("967f775b-3c8b-889d-5189-ee71f59f520e"), - Name = "Gambia" - }, - new - { - Id = new Guid("914f8571-1cac-3f1b-14ef-71aa91836616"), - Name = "Georgia" - }, - new - { - Id = new Guid("d4249520-8674-a2c1-0084-683d7aea64db"), - Name = "Germany" - }, - new - { - Id = new Guid("4fa88e4e-344a-32f8-a5ef-4ef2c33858d2"), - Name = "Ghana" - }, - new - { - Id = new Guid("a9fe165c-96e6-6bdf-99b0-68f7b2972ef6"), - Name = "Greece" - }, - new - { - Id = new Guid("6dfb0c67-2ab9-a5bc-1c58-5eaf76016b9d"), - Name = "Grenada" - }, - new - { - Id = new Guid("c8f8a591-79c3-a19e-94dd-1c96ed1aa23a"), - Name = "Guatemala" - }, - new - { - Id = new Guid("b0ac51a0-0128-4070-a49f-19b3dc5e8135"), - Name = "Guinea" - }, - new - { - Id = new Guid("d9060b41-6ea0-8efa-1dfe-ce293774947b"), - Name = "Guinea-Bissau" - }, - new - { - Id = new Guid("c79ec6ec-2f3d-0c12-8658-5ccbc1a20a77"), - Name = "Guyana" - }, - new - { - Id = new Guid("60a26e14-90ee-5838-4d27-3672a8e88c48"), - Name = "Haiti" - }, - new - { - Id = new Guid("a2c0a247-350e-85e6-9009-8106f5fd49b2"), - Name = "Holy See" - }, - new - { - Id = new Guid("d2300477-7258-17b8-7e8a-cf65f06a325f"), - Name = "Honduras" - }, - new - { - Id = new Guid("81f4a56e-5d53-47f3-52c3-2cd843434126"), - Name = "Hungary" - }, - new - { - Id = new Guid("9c239e38-640c-3fb2-0bc8-8edaace24c70"), - Name = "Iceland" - }, - new - { - Id = new Guid("a0d1f65e-307d-59fa-7792-24a5f0359889"), - Name = "India" - }, - new - { - Id = new Guid("5b9d725f-4e89-0181-74ae-ba87e96590d7"), - Name = "Indonesia" - }, - new - { - Id = new Guid("afa8b53f-45e6-391f-1c60-db81be664b1b"), - Name = "Iran" - }, - new - { - Id = new Guid("59bee04d-32a1-1e53-4a1b-599671a4a693"), - Name = "Iraq" - }, - new - { - Id = new Guid("18bd53bd-3519-69ef-1148-3453ad744c0f"), - Name = "Ireland" - }, - new - { - Id = new Guid("6704c135-5af7-88e9-16a5-ad4656fa1be2"), - Name = "Israel" - }, - new - { - Id = new Guid("cf1fcfbe-11fa-7009-0d71-d2cf5c80a334"), - Name = "Italy" - }, - new - { - Id = new Guid("038fb0db-7012-50fb-9ace-3b9f240d9627"), - Name = "Jamaica" - }, - new - { - Id = new Guid("12d9457c-1c12-9961-60cf-ec2ee534843a"), - Name = "Japan" - }, - new - { - Id = new Guid("aa9d471d-3f2f-5d42-3d01-443a83c12f59"), - Name = "Jordan" - }, - new - { - Id = new Guid("7708a52a-1d62-8f8b-0a4d-6028ed834994"), - Name = "Kazakhstan" - }, - new - { - Id = new Guid("f27f4ccb-4e04-8e05-456e-621788247647"), - Name = "Kenya" - }, - new - { - Id = new Guid("c7fc5498-271d-1027-343a-1560793d1c26"), - Name = "Kiribati" - }, - new - { - Id = new Guid("ee007dac-7417-54e4-18c2-ec6a678ba130"), - Name = "Kuwait" - }, - new - { - Id = new Guid("20bfffe5-7601-63e6-3574-9346e80d5d5c"), - Name = "Kyrgyzstan" - }, - new - { - Id = new Guid("6a5e5c1a-4d04-237e-8415-a7f93945133b"), - Name = "Laos" - }, - new - { - Id = new Guid("1e2e1979-539d-128f-538e-c30b8ba49b42"), - Name = "Latvia" - }, - new - { - Id = new Guid("29e7cce5-28a0-990c-6ded-54e96cad9caa"), - Name = "Lebanon" - }, - new - { - Id = new Guid("dbe19dde-374b-68a8-41e0-48d5195aa6f5"), - Name = "Lesotho" - }, - new - { - Id = new Guid("2092625a-45e4-166e-53cf-bb48408f1b09"), - Name = "Liberia" - }, - new - { - Id = new Guid("9d8cf3fc-222d-a56c-211b-8e8e9edf54e0"), - Name = "Libya" - }, - new - { - Id = new Guid("b232a961-1224-244f-27a1-06cba2046c22"), - Name = "Liechtenstein" - }, - new - { - Id = new Guid("a681eaeb-1fa0-12d7-93fb-e33a13c188e9"), - Name = "Lithuania" - }, - new - { - Id = new Guid("5ee9fcd4-5680-3cb4-1174-d85201e82367"), - Name = "Luxembourg" - }, - new - { - Id = new Guid("408f1ee6-42d3-a211-67c5-32f601b79bd9"), - Name = "Madagascar" - }, - new - { - Id = new Guid("341651be-9d9c-206b-9162-aad732979787"), - Name = "Malawi" - }, - new - { - Id = new Guid("40563307-5fe1-97d4-9d10-d81af5138548"), - Name = "Malaysia" - }, - new - { - Id = new Guid("43da6311-4ed9-9a74-9a46-82847f79a7c3"), - Name = "Maldives" - }, - new - { - Id = new Guid("c3700331-07c2-264c-2335-ba61bc718cac"), - Name = "Mali" - }, - new - { - Id = new Guid("1e3241f2-78b6-56e8-4c2d-4a50647973cf"), - Name = "Malta" - }, - new - { - Id = new Guid("bdf3f266-9570-2bb9-330f-9ea51c927068"), - Name = "Marshall Islands" - }, - new - { - Id = new Guid("572563f8-2f44-603d-857e-3f8230035e82"), - Name = "Mauritania" - }, - new - { - Id = new Guid("e8b389a9-0afd-4904-46af-464012f102c2"), - Name = "Mauritius" - }, - new - { - Id = new Guid("2f7432c5-405f-3f99-4bc3-35e318bd66cc"), - Name = "Mexico" - }, - new - { - Id = new Guid("94e831a3-3e52-7bb4-7616-dc0ac75c2d1d"), - Name = "Micronesia" - }, - new - { - Id = new Guid("abe01fc7-a484-7a8e-74b6-c5fa27554505"), - Name = "Moldova" - }, - new - { - Id = new Guid("6a265dd9-314e-2eb2-a4f8-3faf9c11a39d"), - Name = "Monaco" - }, - new - { - Id = new Guid("a484eabd-775b-4b7d-595b-3f5d857f5052"), - Name = "Mongolia" - }, - new - { - Id = new Guid("46fd6123-5206-2c2c-2832-953d13847069"), - Name = "Montenegro" - }, - new - { - Id = new Guid("09ee26e3-5c82-221e-0729-e47d663a949c"), - Name = "Morocco" - }, - new - { - Id = new Guid("aa6f7328-8f52-9bd1-0bba-9fb4f18a926e"), - Name = "Mozambique" - }, - new - { - Id = new Guid("4ebfeb1d-67d6-2499-5346-740f737100ee"), - Name = "Myanmar (formerly Burma)" - }, - new - { - Id = new Guid("aa29ea0b-2681-3475-6e16-1b7d164b081a"), - Name = "Namibia" - }, - new - { - Id = new Guid("d9a21a29-a0e2-71bc-7308-548cc27b19f1"), - Name = "Nauru" - }, - new - { - Id = new Guid("2c4ab1fa-60da-7c87-35b3-ac6903455853"), - Name = "Nepal" - }, - new - { - Id = new Guid("cb245d05-3293-7315-7ee1-eef8a383319c"), - Name = "Netherlands" - }, - new - { - Id = new Guid("472e0e57-77f5-9c34-8e10-a621c97108f7"), - Name = "New Zealand" - }, - new - { - Id = new Guid("350dc86e-03b2-2c20-1908-b4de7d179de7"), - Name = "Nicaragua" - }, - new - { - Id = new Guid("9b36a6c2-4739-69a2-068b-c0b3c87c6f67"), - Name = "Niger" - }, - new - { - Id = new Guid("2ca00749-35c0-511b-9c2c-b53e5a8f0a71"), - Name = "Nigeria" - }, - new - { - Id = new Guid("10ef2f04-4d96-5b5e-316f-b373a88731be"), - Name = "North Korea" - }, - new - { - Id = new Guid("51c38ab5-0b2b-2994-4eb2-c8e82fe17950"), - Name = "North Macedonia" - }, - new - { - Id = new Guid("c1c8ec1f-58ce-3931-7ad7-ad4b55c14a85"), - Name = "Norway" - }, - new - { - Id = new Guid("859adf7d-1bf9-87d1-6a9b-4a06ebab6796"), - Name = "Oman" - }, - new - { - Id = new Guid("6133196d-26d0-5f8e-5792-6215aefd668d"), - Name = "Pakistan" - }, - new - { - Id = new Guid("3881b3b6-a332-3d35-8a73-43acfbf9045b"), - Name = "Palau" - }, - new - { - Id = new Guid("9a79f7fb-27a4-811b-88c3-9de906521017"), - Name = "Palestine State" - }, - new - { - Id = new Guid("f5b0c42e-3b0e-3808-1922-fdae58ea075c"), - Name = "Panama" - }, - new - { - Id = new Guid("16ff3157-a061-2e81-5ca6-b71e3619376e"), - Name = "Papua New Guinea" - }, - new - { - Id = new Guid("1b84f08e-8e6d-5779-967c-a162c2307153"), - Name = "Paraguay" - }, - new - { - Id = new Guid("f625e01e-4a07-7ff3-0a7e-ce6e27b586ff"), - Name = "Peru" - }, - new - { - Id = new Guid("19be2963-072b-2f4b-0f85-558d90ee1770"), - Name = "Philippines" - }, - new - { - Id = new Guid("fc432d5c-66dd-5660-8186-da84b4e164a0"), - Name = "Poland" - }, - new - { - Id = new Guid("2b1486b9-0cfa-2dc6-3f70-4ee2f11955b4"), - Name = "Portugal" - }, - new - { - Id = new Guid("47ac0edf-9beb-345b-0e4b-bccb0c1a2032"), - Name = "Qatar" - }, - new - { - Id = new Guid("d5cb2660-9af9-0385-8a99-52871814043d"), - Name = "Romania" - }, - new - { - Id = new Guid("6fa56ae5-2091-39c4-0010-ae74ffa2a0f2"), - Name = "Russia" - }, - new - { - Id = new Guid("362ac8d8-6fba-a641-8272-958f9e553b54"), - Name = "Rwanda" - }, - new - { - Id = new Guid("c3553d72-9d17-04d8-6692-12a5a7250008"), - Name = "Saint Kitts and Nevis" - }, - new - { - Id = new Guid("fd3ab0e3-279a-107a-88e0-93ee1bb45ffb"), - Name = "Saint Lucia" - }, - new - { - Id = new Guid("420b0acb-a1b0-27e5-45fc-3c6e96f25361"), - Name = "Saint Vincent and the Grenadines" - }, - new - { - Id = new Guid("37425b6c-2940-370c-805d-27cb7af97f88"), - Name = "Samoa" - }, - new - { - Id = new Guid("b6667319-a515-1cf5-7392-92e15c52438d"), - Name = "San Marino" - }, - new - { - Id = new Guid("75c8834a-67e9-9ee5-65bb-e2db6a937074"), - Name = "Sao Tome and Principe" - }, - new - { - Id = new Guid("1e9ab108-4d4b-1812-21d9-5c90d7d897ea"), - Name = "Saudi Arabia" - }, - new - { - Id = new Guid("3cb2d6c7-8bb5-191d-183d-b201063d5491"), - Name = "Senegal" - }, - new - { - Id = new Guid("1995e756-0e82-9463-1627-feeb766d2d0d"), - Name = "Serbia" - }, - new - { - Id = new Guid("1ff73b0c-27c4-9d4a-3d5b-ec77a6612d56"), - Name = "Seychelles" - }, - new - { - Id = new Guid("6df0d56f-3b4e-33fe-6d5f-74da585ea5d0"), - Name = "Sierra Leone" - }, - new - { - Id = new Guid("912f9045-7a3b-151b-2c06-19f899d1787a"), - Name = "Singapore" - }, - new - { - Id = new Guid("53e7d0fc-816f-59dd-7b4a-0ade62330830"), - Name = "Slovakia" - }, - new - { - Id = new Guid("a522756f-2fd9-48d1-7443-dd1546fd8b37"), - Name = "Slovenia" - }, - new - { - Id = new Guid("5f47ed3b-0b54-95aa-93e8-16bf035c9247"), - Name = "Solomon Islands" - }, - new - { - Id = new Guid("b58da294-9556-8ece-163f-3d89514017a7"), - Name = "Somalia" - }, - new - { - Id = new Guid("03a82f52-22d5-8259-1072-429791258b72"), - Name = "South Africa" - }, - new - { - Id = new Guid("55cafe8e-1585-278e-5736-bab16f1b1b8d"), - Name = "South Korea" - }, - new - { - Id = new Guid("9d2d676f-97fb-952c-06a9-09d4e9696631"), - Name = "South Sudan" - }, - new - { - Id = new Guid("534a826b-70ef-2128-1a4c-52e23b7d5447"), - Name = "Spain" - }, - new - { - Id = new Guid("932a43ac-56dc-951e-7de5-996314e92e9c"), - Name = "Sri Lanka" - }, - new - { - Id = new Guid("6c4a7b61-3bfd-4a47-95a3-0ca86c72521f"), - Name = "Sudan" - }, - new - { - Id = new Guid("9a0a2c1d-3475-3554-9d18-b11946af6086"), - Name = "Suriname" - }, - new - { - Id = new Guid("896ef05e-0fe4-92a6-229e-63d7a26e0625"), - Name = "Sweden" - }, - new - { - Id = new Guid("bb0b41a9-7363-5922-9ce0-939412a9036e"), - Name = "Switzerland" - }, - new - { - Id = new Guid("7b9c857e-3fbd-3d19-38cf-f204da39890c"), - Name = "Syria" - }, - new - { - Id = new Guid("d7cd92d3-4522-5a78-3533-816fc61a293f"), - Name = "Tajikistan" - }, - new - { - Id = new Guid("fa81562d-1bc4-944c-86a9-6cc5af502265"), - Name = "Tanzania" - }, - new - { - Id = new Guid("439e3108-0908-4d90-6f5c-1974362b74b1"), - Name = "Thailand" - }, - new - { - Id = new Guid("47e7cc9c-4368-8ab3-056b-66a1351c24cd"), - Name = "Timor-Leste" - }, - new - { - Id = new Guid("492a6eb7-5ca3-8e50-3559-c71205b71c3b"), - Name = "Togo" - }, - new - { - Id = new Guid("e376c876-6960-270c-8744-583fb7a72f55"), - Name = "Tonga" - }, - new - { - Id = new Guid("2f7c276f-4d0d-9368-4132-c04149924bb5"), - Name = "Trinidad and Tobago" - }, - new - { - Id = new Guid("93ba288b-2a62-1880-1e20-aeb705431890"), - Name = "Tunisia" - }, - new - { - Id = new Guid("c576d8f0-5300-2436-2d17-48b699214549"), - Name = "Turkey" - }, - new - { - Id = new Guid("a9c5d1ec-319a-085c-1ee3-80ae15bd27ed"), - Name = "Turkmenistan" - }, - new - { - Id = new Guid("95938676-73d1-2031-219d-dc67ba314bdf"), - Name = "Tuvalu" - }, - new - { - Id = new Guid("2cfae83c-0f45-72d1-4624-5af1e10e6147"), - Name = "Uganda" - }, - new - { - Id = new Guid("1b837dfa-0bda-54f3-918a-beef19f691e5"), - Name = "Ukraine" - }, - new - { - Id = new Guid("f7675604-4744-6d6f-a077-67a3e0c85324"), - Name = "United Arab Emirates" - }, - new - { - Id = new Guid("8f9ec4fb-916f-90ea-5162-f486a0fc0893"), - Name = "United Kingdom" - }, - new - { - Id = new Guid("ca111c84-983b-4525-054c-d14dee3a422c"), - Name = "United States of America" - }, - new - { - Id = new Guid("ee06c3ba-4e8c-95c3-88da-6be3f23b9aaa"), - Name = "Uruguay" - }, - new - { - Id = new Guid("2f02c930-1d71-8ca6-49e7-0d3679a522ea"), - Name = "Uzbekistan" - }, - new - { - Id = new Guid("28dc2817-94b4-955d-10bc-6a8793dd386c"), - Name = "Vanuatu" - }, - new - { - Id = new Guid("9c9e3bca-5880-437f-4f18-d6998d90173f"), - Name = "Venezuela" - }, - new - { - Id = new Guid("5a3893d1-1e36-310c-7633-8f36ffa26315"), - Name = "Vietnam" - }, - new - { - Id = new Guid("a2689ae3-3643-6250-a748-8f055cc72da8"), - Name = "Yemen" - }, - new - { - Id = new Guid("be447a08-0a85-5779-8c65-cf15c2c9a5a8"), - Name = "Zambia" - }, - new - { - Id = new Guid("c776f397-182b-6d0d-09f2-4e440dc093d3"), - Name = "Zimbabwe" - }); - }); - - modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.File", b => - { - b.Property("Id") - .HasColumnType("uniqueidentifier"); - - b.Property("ContentType") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("Discriminator") - .IsRequired() - .HasMaxLength(8) - .HasColumnType("nvarchar(8)"); - - b.Property("Extension") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("nvarchar(20)"); - - b.Property("IsTemp") - .HasColumnType("bit"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("nvarchar(300)"); - - b.Property("Size") - .HasColumnType("bigint"); - - b.Property("UploadedOn") - .HasColumnType("datetime2"); - - b.HasKey("Id"); - - b.ToTable("File", (string)null); - - b.HasDiscriminator("Discriminator").IsComplete(true).HasValue("File"); - - b.UseTphMappingStrategy(); - }); - - modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.Product", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("CompanyId") - .HasColumnType("uniqueidentifier"); - - b.Property("DefaultPictureId") - .HasColumnType("uniqueidentifier"); - - b.Property("Description") - .IsRequired() - .HasMaxLength(500) - .HasColumnType("nvarchar(500)"); - - b.Property("Price") - .HasPrecision(10, 2) - .HasColumnType("decimal(10,2)"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.HasKey("Id"); - - b.HasIndex("CompanyId"); - - b.HasIndex("DefaultPictureId") - .IsUnique(); - - b.HasIndex("Title"); - - b.ToTable("Product"); - }); - - modelBuilder.Entity("ProductPicture", b => - { - b.Property("PicturesId") - .HasColumnType("uniqueidentifier"); - - b.Property("ProductId") - .HasColumnType("uniqueidentifier"); - - b.HasKey("PicturesId", "ProductId"); - - b.HasIndex("PicturesId") - .IsUnique(); - - b.HasIndex("ProductId"); - - b.ToTable("ProductPicture"); - }); - - modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.Document", b => - { - b.HasBaseType("Monaco.Template.Backend.Domain.Model.File"); - - b.HasDiscriminator().HasValue("Document"); - }); - - modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.Image", b => - { - b.HasBaseType("Monaco.Template.Backend.Domain.Model.File"); - - b.Property("DateTaken") - .HasColumnType("datetime2"); - - b.Property("ThumbnailId") - .HasColumnType("uniqueidentifier"); - - b.HasIndex("ThumbnailId") - .IsUnique() - .HasFilter("[ThumbnailId] IS NOT NULL"); - - b.HasDiscriminator().HasValue("Image"); - }); - - modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.Company", b => - { - b.OwnsOne("Monaco.Template.Backend.Domain.Model.Address", "Address", b1 => - { - b1.Property("CompanyId") - .HasColumnType("uniqueidentifier"); - - b1.Property("City") - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b1.Property("CountryId") - .HasColumnType("uniqueidentifier"); - - b1.Property("County") - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b1.Property("PostCode") - .HasMaxLength(10) - .HasColumnType("nvarchar(10)"); - - b1.Property("Street") - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b1.HasKey("CompanyId"); - - b1.HasIndex("CountryId"); - - b1.ToTable("Company"); - - b1.WithOwner() - .HasForeignKey("CompanyId"); - - b1.HasOne("Monaco.Template.Backend.Domain.Model.Country", "Country") - .WithMany() - .HasForeignKey("CountryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b1.Navigation("Country"); - }); - - b.Navigation("Address"); - }); - - modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.Product", b => - { - b.HasOne("Monaco.Template.Backend.Domain.Model.Company", "Company") - .WithMany("Products") - .HasForeignKey("CompanyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Monaco.Template.Backend.Domain.Model.Image", "DefaultPicture") - .WithOne() - .HasForeignKey("Monaco.Template.Backend.Domain.Model.Product", "DefaultPictureId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Company"); - - b.Navigation("DefaultPicture"); - }); - - modelBuilder.Entity("ProductPicture", b => - { - b.HasOne("Monaco.Template.Backend.Domain.Model.Image", null) - .WithMany() - .HasForeignKey("PicturesId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Monaco.Template.Backend.Domain.Model.Product", null) - .WithMany() - .HasForeignKey("ProductId") - .OnDelete(DeleteBehavior.ClientCascade) - .IsRequired(); - }); - - modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.Image", b => - { - b.HasOne("Monaco.Template.Backend.Domain.Model.Image", "Thumbnail") - .WithOne() - .HasForeignKey("Monaco.Template.Backend.Domain.Model.Image", "ThumbnailId"); - - b.OwnsOne("Monaco.Template.Backend.Domain.Model.GpsPosition", "Position", b1 => - { - b1.Property("ImageId") - .HasColumnType("uniqueidentifier"); - - b1.Property("Latitude") - .HasColumnType("real"); - - b1.Property("Longitude") - .HasColumnType("real"); - - b1.HasKey("ImageId"); - - b1.ToTable("File"); - - b1.WithOwner() - .HasForeignKey("ImageId"); - }); - - b.OwnsOne("Monaco.Template.Backend.Domain.Model.ImageDimensions", "Dimensions", b1 => - { - b1.Property("ImageId") - .HasColumnType("uniqueidentifier"); - - b1.Property("Height") - .HasColumnType("int"); - - b1.Property("Width") - .HasColumnType("int"); - - b1.HasKey("ImageId"); - - b1.ToTable("File"); - - b1.WithOwner() - .HasForeignKey("ImageId"); - }); - - b.Navigation("Dimensions") - .IsRequired(); - - b.Navigation("Position"); - - b.Navigation("Thumbnail"); - }); - - modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.Company", b => - { - b.Navigation("Products"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure.Migrations/Migrations/20231204192153_Init.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure.Migrations/Migrations/20231204192153_Init.cs deleted file mode 100644 index 1dcfb82..0000000 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure.Migrations/Migrations/20231204192153_Init.cs +++ /dev/null @@ -1,395 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -#pragma warning disable CA1814 // Prefer jagged arrays over multidimensional - -namespace Monaco.Template.Backend.Application.Infrastructure.Migrations.Migrations -{ - /// - public partial class Init : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "Country", - columns: table => new - { - Id = table.Column(type: "uniqueidentifier", nullable: false), - Name = table.Column(type: "nvarchar(100)", maxLength: 100, nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Country", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "File", - columns: table => new - { - Id = table.Column(type: "uniqueidentifier", nullable: false), - Name = table.Column(type: "nvarchar(300)", maxLength: 300, nullable: false), - Extension = table.Column(type: "nvarchar(20)", maxLength: 20, nullable: false), - Size = table.Column(type: "bigint", nullable: false), - ContentType = table.Column(type: "nvarchar(50)", maxLength: 50, nullable: false), - UploadedOn = table.Column(type: "datetime2", nullable: false), - IsTemp = table.Column(type: "bit", nullable: false), - Discriminator = table.Column(type: "nvarchar(8)", maxLength: 8, nullable: false), - DateTaken = table.Column(type: "datetime2", nullable: true), - Dimensions_Height = table.Column(type: "int", nullable: true), - Dimensions_Width = table.Column(type: "int", nullable: true), - Position_Latitude = table.Column(type: "real", nullable: true), - Position_Longitude = table.Column(type: "real", nullable: true), - ThumbnailId = table.Column(type: "uniqueidentifier", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_File", x => x.Id); - table.ForeignKey( - name: "FK_File_File_ThumbnailId", - column: x => x.ThumbnailId, - principalTable: "File", - principalColumn: "Id"); - }); - - migrationBuilder.CreateTable( - name: "Company", - columns: table => new - { - Id = table.Column(type: "uniqueidentifier", nullable: false), - Name = table.Column(type: "nvarchar(100)", maxLength: 100, nullable: false), - Email = table.Column(type: "nvarchar(255)", maxLength: 255, nullable: false), - WebSiteUrl = table.Column(type: "nvarchar(300)", maxLength: 300, nullable: true), - Version = table.Column(type: "rowversion", rowVersion: true, nullable: false), - Address_Street = table.Column(type: "nvarchar(100)", maxLength: 100, nullable: true), - Address_City = table.Column(type: "nvarchar(100)", maxLength: 100, nullable: true), - Address_County = table.Column(type: "nvarchar(100)", maxLength: 100, nullable: true), - Address_PostCode = table.Column(type: "nvarchar(10)", maxLength: 10, nullable: true), - Address_CountryId = table.Column(type: "uniqueidentifier", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_Company", x => x.Id); - table.ForeignKey( - name: "FK_Company_Country_Address_CountryId", - column: x => x.Address_CountryId, - principalTable: "Country", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "Product", - columns: table => new - { - Id = table.Column(type: "uniqueidentifier", nullable: false), - Title = table.Column(type: "nvarchar(100)", maxLength: 100, nullable: false), - Description = table.Column(type: "nvarchar(500)", maxLength: 500, nullable: false), - Price = table.Column(type: "decimal(10,2)", precision: 10, scale: 2, nullable: false), - CompanyId = table.Column(type: "uniqueidentifier", nullable: false), - DefaultPictureId = table.Column(type: "uniqueidentifier", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Product", x => x.Id); - table.ForeignKey( - name: "FK_Product_Company_CompanyId", - column: x => x.CompanyId, - principalTable: "Company", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_Product_File_DefaultPictureId", - column: x => x.DefaultPictureId, - principalTable: "File", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "ProductPicture", - columns: table => new - { - PicturesId = table.Column(type: "uniqueidentifier", nullable: false), - ProductId = table.Column(type: "uniqueidentifier", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_ProductPicture", x => new { x.PicturesId, x.ProductId }); - table.ForeignKey( - name: "FK_ProductPicture_File_PicturesId", - column: x => x.PicturesId, - principalTable: "File", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_ProductPicture_Product_ProductId", - column: x => x.ProductId, - principalTable: "Product", - principalColumn: "Id"); - }); - - migrationBuilder.InsertData( - table: "Country", - columns: new[] { "Id", "Name" }, - values: new object[,] - { - { new Guid("003548f7-318a-6f99-8a27-d62963b64cb5"), "China" }, - { new Guid("01deb5a8-6bd7-1879-9d4b-cb73dd0e9a97"), "Cameroon" }, - { new Guid("01ec70b8-6aad-3770-a129-62c0fc294791"), "Argentina" }, - { new Guid("038fb0db-7012-50fb-9ace-3b9f240d9627"), "Jamaica" }, - { new Guid("03a82f52-22d5-8259-1072-429791258b72"), "South Africa" }, - { new Guid("08b5d3d0-89ed-a66f-3175-05316ae4a309"), "Bahamas" }, - { new Guid("09ee26e3-5c82-221e-0729-e47d663a949c"), "Morocco" }, - { new Guid("0d69d315-2825-2d05-9c04-ba1ad47180ac"), "Bangladesh" }, - { new Guid("10ef2f04-4d96-5b5e-316f-b373a88731be"), "North Korea" }, - { new Guid("12d9457c-1c12-9961-60cf-ec2ee534843a"), "Japan" }, - { new Guid("16eded64-8619-2b73-682f-a703c1cb2d76"), "Costa Rica" }, - { new Guid("16ff3157-a061-2e81-5ca6-b71e3619376e"), "Papua New Guinea" }, - { new Guid("18bd53bd-3519-69ef-1148-3453ad744c0f"), "Ireland" }, - { new Guid("1995e756-0e82-9463-1627-feeb766d2d0d"), "Serbia" }, - { new Guid("19be2963-072b-2f4b-0f85-558d90ee1770"), "Philippines" }, - { new Guid("1a426c53-787f-527c-5471-c505d6403603"), "Bolivia" }, - { new Guid("1b837dfa-0bda-54f3-918a-beef19f691e5"), "Ukraine" }, - { new Guid("1b84f08e-8e6d-5779-967c-a162c2307153"), "Paraguay" }, - { new Guid("1e2e1979-539d-128f-538e-c30b8ba49b42"), "Latvia" }, - { new Guid("1e3241f2-78b6-56e8-4c2d-4a50647973cf"), "Malta" }, - { new Guid("1e9ab108-4d4b-1812-21d9-5c90d7d897ea"), "Saudi Arabia" }, - { new Guid("1ff73b0c-27c4-9d4a-3d5b-ec77a6612d56"), "Seychelles" }, - { new Guid("2092625a-45e4-166e-53cf-bb48408f1b09"), "Liberia" }, - { new Guid("20bfffe5-7601-63e6-3574-9346e80d5d5c"), "Kyrgyzstan" }, - { new Guid("26253117-7664-92a9-1a3c-b15cf4bf4c78"), "Andorra" }, - { new Guid("269928e1-37c5-32e0-60c5-bc6da2b8240e"), "Australia" }, - { new Guid("28dc2817-94b4-955d-10bc-6a8793dd386c"), "Vanuatu" }, - { new Guid("2908f020-3d75-3f9a-1a7f-020d1f8d5553"), "Ecuador" }, - { new Guid("29e7cce5-28a0-990c-6ded-54e96cad9caa"), "Lebanon" }, - { new Guid("2b1486b9-0cfa-2dc6-3f70-4ee2f11955b4"), "Portugal" }, - { new Guid("2c4ab1fa-60da-7c87-35b3-ac6903455853"), "Nepal" }, - { new Guid("2ca00749-35c0-511b-9c2c-b53e5a8f0a71"), "Nigeria" }, - { new Guid("2cfae83c-0f45-72d1-4624-5af1e10e6147"), "Uganda" }, - { new Guid("2f02c930-1d71-8ca6-49e7-0d3679a522ea"), "Uzbekistan" }, - { new Guid("2f7432c5-405f-3f99-4bc3-35e318bd66cc"), "Mexico" }, - { new Guid("2f7c276f-4d0d-9368-4132-c04149924bb5"), "Trinidad and Tobago" }, - { new Guid("341651be-9d9c-206b-9162-aad732979787"), "Malawi" }, - { new Guid("350dc86e-03b2-2c20-1908-b4de7d179de7"), "Nicaragua" }, - { new Guid("359da8da-68eb-9466-855d-f0f381f715b8"), "Antigua and Barbuda" }, - { new Guid("362ac8d8-6fba-a641-8272-958f9e553b54"), "Rwanda" }, - { new Guid("37425b6c-2940-370c-805d-27cb7af97f88"), "Samoa" }, - { new Guid("3881b3b6-a332-3d35-8a73-43acfbf9045b"), "Palau" }, - { new Guid("3cb2d6c7-8bb5-191d-183d-b201063d5491"), "Senegal" }, - { new Guid("40563307-5fe1-97d4-9d10-d81af5138548"), "Malaysia" }, - { new Guid("408f1ee6-42d3-a211-67c5-32f601b79bd9"), "Madagascar" }, - { new Guid("420b0acb-a1b0-27e5-45fc-3c6e96f25361"), "Saint Vincent and the Grenadines" }, - { new Guid("42f62587-3470-5967-77e3-f9b0cf285d90"), "Cambodia" }, - { new Guid("439e3108-0908-4d90-6f5c-1974362b74b1"), "Thailand" }, - { new Guid("43da6311-4ed9-9a74-9a46-82847f79a7c3"), "Maldives" }, - { new Guid("4676b79b-461c-95de-9871-041d2e0b130b"), "Cabo Verde" }, - { new Guid("46fd6123-5206-2c2c-2832-953d13847069"), "Montenegro" }, - { new Guid("472e0e57-77f5-9c34-8e10-a621c97108f7"), "New Zealand" }, - { new Guid("47ac0edf-9beb-345b-0e4b-bccb0c1a2032"), "Qatar" }, - { new Guid("47e7cc9c-4368-8ab3-056b-66a1351c24cd"), "Timor-Leste" }, - { new Guid("492a6eb7-5ca3-8e50-3559-c71205b71c3b"), "Togo" }, - { new Guid("4cf81cef-66a5-a117-3297-884134e903ee"), "Azerbaijan" }, - { new Guid("4ebfeb1d-67d6-2499-5346-740f737100ee"), "Myanmar (formerly Burma)" }, - { new Guid("4fa88e4e-344a-32f8-a5ef-4ef2c33858d2"), "Ghana" }, - { new Guid("5198e2c0-8107-5bcf-90b4-0054eac52295"), "Estonia" }, - { new Guid("51c38ab5-0b2b-2994-4eb2-c8e82fe17950"), "North Macedonia" }, - { new Guid("52b13dd7-28fc-9bba-8d59-5c2209531bf5"), "Belarus" }, - { new Guid("52f81e1e-6903-88e8-199f-cfc5139b0c69"), "Barbados" }, - { new Guid("534a826b-70ef-2128-1a4c-52e23b7d5447"), "Spain" }, - { new Guid("53e7d0fc-816f-59dd-7b4a-0ade62330830"), "Slovakia" }, - { new Guid("555a4e83-0151-7a10-2072-6cc9f4ac77c1"), "Dominican Republic" }, - { new Guid("55cafe8e-1585-278e-5736-bab16f1b1b8d"), "South Korea" }, - { new Guid("572563f8-2f44-603d-857e-3f8230035e82"), "Mauritania" }, - { new Guid("57dc70e9-17ec-995b-5a60-a7c029b1476a"), "Denmark" }, - { new Guid("59bee04d-32a1-1e53-4a1b-599671a4a693"), "Iraq" }, - { new Guid("5a3893d1-1e36-310c-7633-8f36ffa26315"), "Vietnam" }, - { new Guid("5b9d725f-4e89-0181-74ae-ba87e96590d7"), "Indonesia" }, - { new Guid("5c064eff-a037-a6a3-06ec-92f662903af3"), "Afghanistan" }, - { new Guid("5e7808be-01a7-9495-2320-314ce20871f3"), "Eritrea" }, - { new Guid("5ee9fcd4-5680-3cb4-1174-d85201e82367"), "Luxembourg" }, - { new Guid("5f47ed3b-0b54-95aa-93e8-16bf035c9247"), "Solomon Islands" }, - { new Guid("60a26e14-90ee-5838-4d27-3672a8e88c48"), "Haiti" }, - { new Guid("6133196d-26d0-5f8e-5792-6215aefd668d"), "Pakistan" }, - { new Guid("637e0fb3-34ed-6a1b-7524-3d6cd3155d35"), "Ethiopia" }, - { new Guid("63a948ca-178b-93da-4fdd-e6be10b49a42"), "Colombia" }, - { new Guid("6459ce24-8398-57e0-4a31-48addb374e6d"), "Fiji" }, - { new Guid("6704c135-5af7-88e9-16a5-ad4656fa1be2"), "Israel" }, - { new Guid("6a265dd9-314e-2eb2-a4f8-3faf9c11a39d"), "Monaco" }, - { new Guid("6a5e5c1a-4d04-237e-8415-a7f93945133b"), "Laos" }, - { new Guid("6c4a7b61-3bfd-4a47-95a3-0ca86c72521f"), "Sudan" }, - { new Guid("6d2bc2ca-2f37-3698-7f08-b7b3eeda5bf5"), "Comoros" }, - { new Guid("6df0d56f-3b4e-33fe-6d5f-74da585ea5d0"), "Sierra Leone" }, - { new Guid("6dfb0c67-2ab9-a5bc-1c58-5eaf76016b9d"), "Grenada" }, - { new Guid("6fa56ae5-2091-39c4-0010-ae74ffa2a0f2"), "Russia" }, - { new Guid("72499e6c-80a1-32c3-2692-7216abe7815b"), "Brazil" }, - { new Guid("758d4f58-7371-36c1-26c2-fcdb993806eb"), "Chad" }, - { new Guid("75c8834a-67e9-9ee5-65bb-e2db6a937074"), "Sao Tome and Principe" }, - { new Guid("7708a52a-1d62-8f8b-0a4d-6028ed834994"), "Kazakhstan" }, - { new Guid("77b88575-0e8c-82d0-72bf-06f638b7485f"), "Central African Republic" }, - { new Guid("7915a976-5224-94f8-232f-ac163a11630c"), "Croatia" }, - { new Guid("7b9c857e-3fbd-3d19-38cf-f204da39890c"), "Syria" }, - { new Guid("7d62846b-1841-882f-1cc4-85e2edeea265"), "Armenia" }, - { new Guid("7fce71e6-a14d-5d96-2dc1-1fc6779e02d3"), "Austria" }, - { new Guid("81f4a56e-5d53-47f3-52c3-2cd843434126"), "Hungary" }, - { new Guid("859adf7d-1bf9-87d1-6a9b-4a06ebab6796"), "Oman" }, - { new Guid("896ef05e-0fe4-92a6-229e-63d7a26e0625"), "Sweden" }, - { new Guid("89bd993a-4eaa-6bae-8cf9-22f766fa2a1e"), "Egypt" }, - { new Guid("8b9ac6d0-2320-3f99-8db7-d78c5d53151a"), "Belgium" }, - { new Guid("8c6486fe-2680-4725-1ef3-3d56e3100f08"), "Djibouti" }, - { new Guid("8f9ec4fb-916f-90ea-5162-f486a0fc0893"), "United Kingdom" }, - { new Guid("912f9045-7a3b-151b-2c06-19f899d1787a"), "Singapore" }, - { new Guid("914f8571-1cac-3f1b-14ef-71aa91836616"), "Georgia" }, - { new Guid("932a43ac-56dc-951e-7de5-996314e92e9c"), "Sri Lanka" }, - { new Guid("93ba288b-2a62-1880-1e20-aeb705431890"), "Tunisia" }, - { new Guid("94e831a3-3e52-7bb4-7616-dc0ac75c2d1d"), "Micronesia" }, - { new Guid("95938676-73d1-2031-219d-dc67ba314bdf"), "Tuvalu" }, - { new Guid("967f775b-3c8b-889d-5189-ee71f59f520e"), "Gambia" }, - { new Guid("97c787c7-915b-4878-3aa2-6ca1eec02f65"), "Chile" }, - { new Guid("99532f86-827d-39ba-1c01-b9795ec60bf4"), "Bulgaria" }, - { new Guid("9a0a2c1d-3475-3554-9d18-b11946af6086"), "Suriname" }, - { new Guid("9a79f7fb-27a4-811b-88c3-9de906521017"), "Palestine State" }, - { new Guid("9b36a6c2-4739-69a2-068b-c0b3c87c6f67"), "Niger" }, - { new Guid("9c239e38-640c-3fb2-0bc8-8edaace24c70"), "Iceland" }, - { new Guid("9c9e3bca-5880-437f-4f18-d6998d90173f"), "Venezuela" }, - { new Guid("9d2d676f-97fb-952c-06a9-09d4e9696631"), "South Sudan" }, - { new Guid("9d8cf3fc-222d-a56c-211b-8e8e9edf54e0"), "Libya" }, - { new Guid("9f420922-9842-0d2d-616d-dacee7c25db7"), "Algeria" }, - { new Guid("a0d1f65e-307d-59fa-7792-24a5f0359889"), "India" }, - { new Guid("a2689ae3-3643-6250-a748-8f055cc72da8"), "Yemen" }, - { new Guid("a2c0a247-350e-85e6-9009-8106f5fd49b2"), "Holy See" }, - { new Guid("a484eabd-775b-4b7d-595b-3f5d857f5052"), "Mongolia" }, - { new Guid("a522756f-2fd9-48d1-7443-dd1546fd8b37"), "Slovenia" }, - { new Guid("a5d734a1-021d-9b50-6fd4-b8f24bb96b12"), "France" }, - { new Guid("a64406fb-51f7-2ed2-31af-847f9cf16783"), "Gabon" }, - { new Guid("a681eaeb-1fa0-12d7-93fb-e33a13c188e9"), "Lithuania" }, - { new Guid("a8b54a61-35d8-9b82-76e4-c709561d9952"), "Albania" }, - { new Guid("a9c5d1ec-319a-085c-1ee3-80ae15bd27ed"), "Turkmenistan" }, - { new Guid("a9fe165c-96e6-6bdf-99b0-68f7b2972ef6"), "Greece" }, - { new Guid("aa29ea0b-2681-3475-6e16-1b7d164b081a"), "Namibia" }, - { new Guid("aa6f7328-8f52-9bd1-0bba-9fb4f18a926e"), "Mozambique" }, - { new Guid("aa9d471d-3f2f-5d42-3d01-443a83c12f59"), "Jordan" }, - { new Guid("ab1e3408-7157-2629-29a5-fbd6a61d92a9"), "El Salvador" }, - { new Guid("abe01fc7-a484-7a8e-74b6-c5fa27554505"), "Moldova" }, - { new Guid("afa8b53f-45e6-391f-1c60-db81be664b1b"), "Iran" }, - { new Guid("b0ac51a0-0128-4070-a49f-19b3dc5e8135"), "Guinea" }, - { new Guid("b232a961-1224-244f-27a1-06cba2046c22"), "Liechtenstein" }, - { new Guid("b58da294-9556-8ece-163f-3d89514017a7"), "Somalia" }, - { new Guid("b6667319-a515-1cf5-7392-92e15c52438d"), "San Marino" }, - { new Guid("b6ed03e6-096c-3f87-093d-f3ff4bf34c24"), "Cuba" }, - { new Guid("ba408210-2ea9-8c6c-1d5d-7e33973f1c99"), "Brunei" }, - { new Guid("ba510e09-5109-42a2-63f0-32d7ede12a5a"), "Angola" }, - { new Guid("bb0b41a9-7363-5922-9ce0-939412a9036e"), "Switzerland" }, - { new Guid("bdf3f266-9570-2bb9-330f-9ea51c927068"), "Marshall Islands" }, - { new Guid("be447a08-0a85-5779-8c65-cf15c2c9a5a8"), "Zambia" }, - { new Guid("c12db9c7-7ca1-4aec-34f1-7d0bb4713ca8"), "Belize" }, - { new Guid("c1c8ec1f-58ce-3931-7ad7-ad4b55c14a85"), "Norway" }, - { new Guid("c3553d72-9d17-04d8-6692-12a5a7250008"), "Saint Kitts and Nevis" }, - { new Guid("c3700331-07c2-264c-2335-ba61bc718cac"), "Mali" }, - { new Guid("c576d8f0-5300-2436-2d17-48b699214549"), "Turkey" }, - { new Guid("c776f397-182b-6d0d-09f2-4e440dc093d3"), "Zimbabwe" }, - { new Guid("c79ec6ec-2f3d-0c12-8658-5ccbc1a20a77"), "Guyana" }, - { new Guid("c7fc5498-271d-1027-343a-1560793d1c26"), "Kiribati" }, - { new Guid("c8f8a591-79c3-a19e-94dd-1c96ed1aa23a"), "Guatemala" }, - { new Guid("ca111c84-983b-4525-054c-d14dee3a422c"), "United States of America" }, - { new Guid("caf14a3d-777d-0ee5-63a9-1c3da4e81458"), "Czechia (Czech Republic)" }, - { new Guid("cb245d05-3293-7315-7ee1-eef8a383319c"), "Netherlands" }, - { new Guid("cf1fcfbe-11fa-7009-0d71-d2cf5c80a334"), "Italy" }, - { new Guid("cf59ee2f-144d-99ac-9048-eafaba1f4732"), "Bhutan" }, - { new Guid("cfa8f583-23d4-1475-57ea-ef72ae7b633f"), "Eswatini (fmr. \"Swaziland\")" }, - { new Guid("d2300477-7258-17b8-7e8a-cf65f06a325f"), "Honduras" }, - { new Guid("d4249520-8674-a2c1-0084-683d7aea64db"), "Germany" }, - { new Guid("d5cb2660-9af9-0385-8a99-52871814043d"), "Romania" }, - { new Guid("d726f074-4b1d-3043-39eb-f9b4ab9b2344"), "Finland" }, - { new Guid("d7506bd0-454d-1b83-39e0-905836535271"), "Cyprus" }, - { new Guid("d7bd1f34-6ef7-43a6-24ed-53bca003086c"), "Bahrain" }, - { new Guid("d7cd92d3-4522-5a78-3533-816fc61a293f"), "Tajikistan" }, - { new Guid("d7e310ab-99c3-0a50-2ead-57a2823433ee"), "Dominica" }, - { new Guid("d9060b41-6ea0-8efa-1dfe-ce293774947b"), "Guinea-Bissau" }, - { new Guid("d9a21a29-a0e2-71bc-7308-548cc27b19f1"), "Nauru" }, - { new Guid("d9e7fd6d-77f2-8e76-0174-4c17df936d4e"), "Congo (Congo-Brazzaville)" }, - { new Guid("da82e26d-40bd-0866-0822-3d5468a36c3e"), "Democratic Republic of the Congo" }, - { new Guid("dbe19dde-374b-68a8-41e0-48d5195aa6f5"), "Lesotho" }, - { new Guid("e0276db5-123f-6028-9e3e-eb43f2e06c47"), "Botswana" }, - { new Guid("e34dc09e-2df2-3661-90e1-f03154d45caf"), "Benin" }, - { new Guid("e376c876-6960-270c-8744-583fb7a72f55"), "Tonga" }, - { new Guid("e58f3cfd-069a-4457-23ef-9df8d7fe9ba0"), "Equatorial Guinea" }, - { new Guid("e8b389a9-0afd-4904-46af-464012f102c2"), "Mauritius" }, - { new Guid("ee007dac-7417-54e4-18c2-ec6a678ba130"), "Kuwait" }, - { new Guid("ee06c3ba-4e8c-95c3-88da-6be3f23b9aaa"), "Uruguay" }, - { new Guid("f16e701a-5dbf-a441-3305-20ac536d34dc"), "Burkina Faso" }, - { new Guid("f27f4ccb-4e04-8e05-456e-621788247647"), "Kenya" }, - { new Guid("f5b0c42e-3b0e-3808-1922-fdae58ea075c"), "Panama" }, - { new Guid("f625e01e-4a07-7ff3-0a7e-ce6e27b586ff"), "Peru" }, - { new Guid("f7675604-4744-6d6f-a077-67a3e0c85324"), "United Arab Emirates" }, - { new Guid("f8135306-1323-4f48-7a4b-8d0427cb075b"), "Côte d'Ivoire" }, - { new Guid("fa81562d-1bc4-944c-86a9-6cc5af502265"), "Tanzania" }, - { new Guid("fae877c5-4806-05e8-2068-950cdcea6ba9"), "Bosnia and Herzegovina" }, - { new Guid("fc432d5c-66dd-5660-8186-da84b4e164a0"), "Poland" }, - { new Guid("fd3ab0e3-279a-107a-88e0-93ee1bb45ffb"), "Saint Lucia" }, - { new Guid("ff0258f4-35a2-220b-9d9d-f0fe28226cc3"), "Burundi" }, - { new Guid("ff7c5aa2-6b56-218e-491a-42f4c67ca4a9"), "Canada" } - }); - - migrationBuilder.CreateIndex( - name: "IX_Company_Address_CountryId", - table: "Company", - column: "Address_CountryId"); - - migrationBuilder.CreateIndex( - name: "IX_File_ThumbnailId", - table: "File", - column: "ThumbnailId", - unique: true, - filter: "[ThumbnailId] IS NOT NULL"); - - migrationBuilder.CreateIndex( - name: "IX_Product_CompanyId", - table: "Product", - column: "CompanyId"); - - migrationBuilder.CreateIndex( - name: "IX_Product_DefaultPictureId", - table: "Product", - column: "DefaultPictureId", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_Product_Title", - table: "Product", - column: "Title"); - - migrationBuilder.CreateIndex( - name: "IX_ProductPicture_PicturesId", - table: "ProductPicture", - column: "PicturesId", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_ProductPicture_ProductId", - table: "ProductPicture", - column: "ProductId"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "ProductPicture"); - - migrationBuilder.DropTable( - name: "Product"); - - migrationBuilder.DropTable( - name: "Company"); - - migrationBuilder.DropTable( - name: "File"); - - migrationBuilder.DropTable( - name: "Country"); - } - } -} diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure.Migrations/Migrations/AppDbContextModelSnapshot.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure.Migrations/Migrations/AppDbContextModelSnapshot.cs deleted file mode 100644 index 10d6b98..0000000 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure.Migrations/Migrations/AppDbContextModelSnapshot.cs +++ /dev/null @@ -1,1315 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Monaco.Template.Backend.Application.Infrastructure.Context; - -#nullable disable - -namespace Monaco.Template.Backend.Application.Infrastructure.Migrations.Migrations -{ - [DbContext(typeof(AppDbContext))] - partial class AppDbContextModelSnapshot : ModelSnapshot - { - protected override void BuildModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "8.0.0") - .HasAnnotation("Proxies:ChangeTracking", false) - .HasAnnotation("Proxies:CheckEquality", false) - .HasAnnotation("Proxies:LazyLoading", true) - .HasAnnotation("Relational:MaxIdentifierLength", 128); - - SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder); - - modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.Company", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("Email") - .IsRequired() - .HasMaxLength(255) - .HasColumnType("nvarchar(255)"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.Property("Version") - .IsConcurrencyToken() - .IsRequired() - .ValueGeneratedOnAddOrUpdate() - .HasColumnType("rowversion"); - - b.Property("WebSiteUrl") - .HasMaxLength(300) - .HasColumnType("nvarchar(300)"); - - b.HasKey("Id"); - - b.ToTable("Company"); - }); - - modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.Country", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.HasKey("Id"); - - b.ToTable("Country"); - - b.HasData( - new - { - Id = new Guid("5c064eff-a037-a6a3-06ec-92f662903af3"), - Name = "Afghanistan" - }, - new - { - Id = new Guid("a8b54a61-35d8-9b82-76e4-c709561d9952"), - Name = "Albania" - }, - new - { - Id = new Guid("9f420922-9842-0d2d-616d-dacee7c25db7"), - Name = "Algeria" - }, - new - { - Id = new Guid("26253117-7664-92a9-1a3c-b15cf4bf4c78"), - Name = "Andorra" - }, - new - { - Id = new Guid("ba510e09-5109-42a2-63f0-32d7ede12a5a"), - Name = "Angola" - }, - new - { - Id = new Guid("359da8da-68eb-9466-855d-f0f381f715b8"), - Name = "Antigua and Barbuda" - }, - new - { - Id = new Guid("01ec70b8-6aad-3770-a129-62c0fc294791"), - Name = "Argentina" - }, - new - { - Id = new Guid("7d62846b-1841-882f-1cc4-85e2edeea265"), - Name = "Armenia" - }, - new - { - Id = new Guid("269928e1-37c5-32e0-60c5-bc6da2b8240e"), - Name = "Australia" - }, - new - { - Id = new Guid("7fce71e6-a14d-5d96-2dc1-1fc6779e02d3"), - Name = "Austria" - }, - new - { - Id = new Guid("4cf81cef-66a5-a117-3297-884134e903ee"), - Name = "Azerbaijan" - }, - new - { - Id = new Guid("08b5d3d0-89ed-a66f-3175-05316ae4a309"), - Name = "Bahamas" - }, - new - { - Id = new Guid("d7bd1f34-6ef7-43a6-24ed-53bca003086c"), - Name = "Bahrain" - }, - new - { - Id = new Guid("0d69d315-2825-2d05-9c04-ba1ad47180ac"), - Name = "Bangladesh" - }, - new - { - Id = new Guid("52f81e1e-6903-88e8-199f-cfc5139b0c69"), - Name = "Barbados" - }, - new - { - Id = new Guid("52b13dd7-28fc-9bba-8d59-5c2209531bf5"), - Name = "Belarus" - }, - new - { - Id = new Guid("8b9ac6d0-2320-3f99-8db7-d78c5d53151a"), - Name = "Belgium" - }, - new - { - Id = new Guid("c12db9c7-7ca1-4aec-34f1-7d0bb4713ca8"), - Name = "Belize" - }, - new - { - Id = new Guid("e34dc09e-2df2-3661-90e1-f03154d45caf"), - Name = "Benin" - }, - new - { - Id = new Guid("cf59ee2f-144d-99ac-9048-eafaba1f4732"), - Name = "Bhutan" - }, - new - { - Id = new Guid("1a426c53-787f-527c-5471-c505d6403603"), - Name = "Bolivia" - }, - new - { - Id = new Guid("fae877c5-4806-05e8-2068-950cdcea6ba9"), - Name = "Bosnia and Herzegovina" - }, - new - { - Id = new Guid("e0276db5-123f-6028-9e3e-eb43f2e06c47"), - Name = "Botswana" - }, - new - { - Id = new Guid("72499e6c-80a1-32c3-2692-7216abe7815b"), - Name = "Brazil" - }, - new - { - Id = new Guid("ba408210-2ea9-8c6c-1d5d-7e33973f1c99"), - Name = "Brunei" - }, - new - { - Id = new Guid("99532f86-827d-39ba-1c01-b9795ec60bf4"), - Name = "Bulgaria" - }, - new - { - Id = new Guid("f16e701a-5dbf-a441-3305-20ac536d34dc"), - Name = "Burkina Faso" - }, - new - { - Id = new Guid("ff0258f4-35a2-220b-9d9d-f0fe28226cc3"), - Name = "Burundi" - }, - new - { - Id = new Guid("f8135306-1323-4f48-7a4b-8d0427cb075b"), - Name = "Côte d'Ivoire" - }, - new - { - Id = new Guid("4676b79b-461c-95de-9871-041d2e0b130b"), - Name = "Cabo Verde" - }, - new - { - Id = new Guid("42f62587-3470-5967-77e3-f9b0cf285d90"), - Name = "Cambodia" - }, - new - { - Id = new Guid("01deb5a8-6bd7-1879-9d4b-cb73dd0e9a97"), - Name = "Cameroon" - }, - new - { - Id = new Guid("ff7c5aa2-6b56-218e-491a-42f4c67ca4a9"), - Name = "Canada" - }, - new - { - Id = new Guid("77b88575-0e8c-82d0-72bf-06f638b7485f"), - Name = "Central African Republic" - }, - new - { - Id = new Guid("758d4f58-7371-36c1-26c2-fcdb993806eb"), - Name = "Chad" - }, - new - { - Id = new Guid("97c787c7-915b-4878-3aa2-6ca1eec02f65"), - Name = "Chile" - }, - new - { - Id = new Guid("003548f7-318a-6f99-8a27-d62963b64cb5"), - Name = "China" - }, - new - { - Id = new Guid("63a948ca-178b-93da-4fdd-e6be10b49a42"), - Name = "Colombia" - }, - new - { - Id = new Guid("6d2bc2ca-2f37-3698-7f08-b7b3eeda5bf5"), - Name = "Comoros" - }, - new - { - Id = new Guid("d9e7fd6d-77f2-8e76-0174-4c17df936d4e"), - Name = "Congo (Congo-Brazzaville)" - }, - new - { - Id = new Guid("16eded64-8619-2b73-682f-a703c1cb2d76"), - Name = "Costa Rica" - }, - new - { - Id = new Guid("7915a976-5224-94f8-232f-ac163a11630c"), - Name = "Croatia" - }, - new - { - Id = new Guid("b6ed03e6-096c-3f87-093d-f3ff4bf34c24"), - Name = "Cuba" - }, - new - { - Id = new Guid("d7506bd0-454d-1b83-39e0-905836535271"), - Name = "Cyprus" - }, - new - { - Id = new Guid("caf14a3d-777d-0ee5-63a9-1c3da4e81458"), - Name = "Czechia (Czech Republic)" - }, - new - { - Id = new Guid("da82e26d-40bd-0866-0822-3d5468a36c3e"), - Name = "Democratic Republic of the Congo" - }, - new - { - Id = new Guid("57dc70e9-17ec-995b-5a60-a7c029b1476a"), - Name = "Denmark" - }, - new - { - Id = new Guid("8c6486fe-2680-4725-1ef3-3d56e3100f08"), - Name = "Djibouti" - }, - new - { - Id = new Guid("d7e310ab-99c3-0a50-2ead-57a2823433ee"), - Name = "Dominica" - }, - new - { - Id = new Guid("555a4e83-0151-7a10-2072-6cc9f4ac77c1"), - Name = "Dominican Republic" - }, - new - { - Id = new Guid("2908f020-3d75-3f9a-1a7f-020d1f8d5553"), - Name = "Ecuador" - }, - new - { - Id = new Guid("89bd993a-4eaa-6bae-8cf9-22f766fa2a1e"), - Name = "Egypt" - }, - new - { - Id = new Guid("ab1e3408-7157-2629-29a5-fbd6a61d92a9"), - Name = "El Salvador" - }, - new - { - Id = new Guid("e58f3cfd-069a-4457-23ef-9df8d7fe9ba0"), - Name = "Equatorial Guinea" - }, - new - { - Id = new Guid("5e7808be-01a7-9495-2320-314ce20871f3"), - Name = "Eritrea" - }, - new - { - Id = new Guid("5198e2c0-8107-5bcf-90b4-0054eac52295"), - Name = "Estonia" - }, - new - { - Id = new Guid("cfa8f583-23d4-1475-57ea-ef72ae7b633f"), - Name = "Eswatini (fmr. \"Swaziland\")" - }, - new - { - Id = new Guid("637e0fb3-34ed-6a1b-7524-3d6cd3155d35"), - Name = "Ethiopia" - }, - new - { - Id = new Guid("6459ce24-8398-57e0-4a31-48addb374e6d"), - Name = "Fiji" - }, - new - { - Id = new Guid("d726f074-4b1d-3043-39eb-f9b4ab9b2344"), - Name = "Finland" - }, - new - { - Id = new Guid("a5d734a1-021d-9b50-6fd4-b8f24bb96b12"), - Name = "France" - }, - new - { - Id = new Guid("a64406fb-51f7-2ed2-31af-847f9cf16783"), - Name = "Gabon" - }, - new - { - Id = new Guid("967f775b-3c8b-889d-5189-ee71f59f520e"), - Name = "Gambia" - }, - new - { - Id = new Guid("914f8571-1cac-3f1b-14ef-71aa91836616"), - Name = "Georgia" - }, - new - { - Id = new Guid("d4249520-8674-a2c1-0084-683d7aea64db"), - Name = "Germany" - }, - new - { - Id = new Guid("4fa88e4e-344a-32f8-a5ef-4ef2c33858d2"), - Name = "Ghana" - }, - new - { - Id = new Guid("a9fe165c-96e6-6bdf-99b0-68f7b2972ef6"), - Name = "Greece" - }, - new - { - Id = new Guid("6dfb0c67-2ab9-a5bc-1c58-5eaf76016b9d"), - Name = "Grenada" - }, - new - { - Id = new Guid("c8f8a591-79c3-a19e-94dd-1c96ed1aa23a"), - Name = "Guatemala" - }, - new - { - Id = new Guid("b0ac51a0-0128-4070-a49f-19b3dc5e8135"), - Name = "Guinea" - }, - new - { - Id = new Guid("d9060b41-6ea0-8efa-1dfe-ce293774947b"), - Name = "Guinea-Bissau" - }, - new - { - Id = new Guid("c79ec6ec-2f3d-0c12-8658-5ccbc1a20a77"), - Name = "Guyana" - }, - new - { - Id = new Guid("60a26e14-90ee-5838-4d27-3672a8e88c48"), - Name = "Haiti" - }, - new - { - Id = new Guid("a2c0a247-350e-85e6-9009-8106f5fd49b2"), - Name = "Holy See" - }, - new - { - Id = new Guid("d2300477-7258-17b8-7e8a-cf65f06a325f"), - Name = "Honduras" - }, - new - { - Id = new Guid("81f4a56e-5d53-47f3-52c3-2cd843434126"), - Name = "Hungary" - }, - new - { - Id = new Guid("9c239e38-640c-3fb2-0bc8-8edaace24c70"), - Name = "Iceland" - }, - new - { - Id = new Guid("a0d1f65e-307d-59fa-7792-24a5f0359889"), - Name = "India" - }, - new - { - Id = new Guid("5b9d725f-4e89-0181-74ae-ba87e96590d7"), - Name = "Indonesia" - }, - new - { - Id = new Guid("afa8b53f-45e6-391f-1c60-db81be664b1b"), - Name = "Iran" - }, - new - { - Id = new Guid("59bee04d-32a1-1e53-4a1b-599671a4a693"), - Name = "Iraq" - }, - new - { - Id = new Guid("18bd53bd-3519-69ef-1148-3453ad744c0f"), - Name = "Ireland" - }, - new - { - Id = new Guid("6704c135-5af7-88e9-16a5-ad4656fa1be2"), - Name = "Israel" - }, - new - { - Id = new Guid("cf1fcfbe-11fa-7009-0d71-d2cf5c80a334"), - Name = "Italy" - }, - new - { - Id = new Guid("038fb0db-7012-50fb-9ace-3b9f240d9627"), - Name = "Jamaica" - }, - new - { - Id = new Guid("12d9457c-1c12-9961-60cf-ec2ee534843a"), - Name = "Japan" - }, - new - { - Id = new Guid("aa9d471d-3f2f-5d42-3d01-443a83c12f59"), - Name = "Jordan" - }, - new - { - Id = new Guid("7708a52a-1d62-8f8b-0a4d-6028ed834994"), - Name = "Kazakhstan" - }, - new - { - Id = new Guid("f27f4ccb-4e04-8e05-456e-621788247647"), - Name = "Kenya" - }, - new - { - Id = new Guid("c7fc5498-271d-1027-343a-1560793d1c26"), - Name = "Kiribati" - }, - new - { - Id = new Guid("ee007dac-7417-54e4-18c2-ec6a678ba130"), - Name = "Kuwait" - }, - new - { - Id = new Guid("20bfffe5-7601-63e6-3574-9346e80d5d5c"), - Name = "Kyrgyzstan" - }, - new - { - Id = new Guid("6a5e5c1a-4d04-237e-8415-a7f93945133b"), - Name = "Laos" - }, - new - { - Id = new Guid("1e2e1979-539d-128f-538e-c30b8ba49b42"), - Name = "Latvia" - }, - new - { - Id = new Guid("29e7cce5-28a0-990c-6ded-54e96cad9caa"), - Name = "Lebanon" - }, - new - { - Id = new Guid("dbe19dde-374b-68a8-41e0-48d5195aa6f5"), - Name = "Lesotho" - }, - new - { - Id = new Guid("2092625a-45e4-166e-53cf-bb48408f1b09"), - Name = "Liberia" - }, - new - { - Id = new Guid("9d8cf3fc-222d-a56c-211b-8e8e9edf54e0"), - Name = "Libya" - }, - new - { - Id = new Guid("b232a961-1224-244f-27a1-06cba2046c22"), - Name = "Liechtenstein" - }, - new - { - Id = new Guid("a681eaeb-1fa0-12d7-93fb-e33a13c188e9"), - Name = "Lithuania" - }, - new - { - Id = new Guid("5ee9fcd4-5680-3cb4-1174-d85201e82367"), - Name = "Luxembourg" - }, - new - { - Id = new Guid("408f1ee6-42d3-a211-67c5-32f601b79bd9"), - Name = "Madagascar" - }, - new - { - Id = new Guid("341651be-9d9c-206b-9162-aad732979787"), - Name = "Malawi" - }, - new - { - Id = new Guid("40563307-5fe1-97d4-9d10-d81af5138548"), - Name = "Malaysia" - }, - new - { - Id = new Guid("43da6311-4ed9-9a74-9a46-82847f79a7c3"), - Name = "Maldives" - }, - new - { - Id = new Guid("c3700331-07c2-264c-2335-ba61bc718cac"), - Name = "Mali" - }, - new - { - Id = new Guid("1e3241f2-78b6-56e8-4c2d-4a50647973cf"), - Name = "Malta" - }, - new - { - Id = new Guid("bdf3f266-9570-2bb9-330f-9ea51c927068"), - Name = "Marshall Islands" - }, - new - { - Id = new Guid("572563f8-2f44-603d-857e-3f8230035e82"), - Name = "Mauritania" - }, - new - { - Id = new Guid("e8b389a9-0afd-4904-46af-464012f102c2"), - Name = "Mauritius" - }, - new - { - Id = new Guid("2f7432c5-405f-3f99-4bc3-35e318bd66cc"), - Name = "Mexico" - }, - new - { - Id = new Guid("94e831a3-3e52-7bb4-7616-dc0ac75c2d1d"), - Name = "Micronesia" - }, - new - { - Id = new Guid("abe01fc7-a484-7a8e-74b6-c5fa27554505"), - Name = "Moldova" - }, - new - { - Id = new Guid("6a265dd9-314e-2eb2-a4f8-3faf9c11a39d"), - Name = "Monaco" - }, - new - { - Id = new Guid("a484eabd-775b-4b7d-595b-3f5d857f5052"), - Name = "Mongolia" - }, - new - { - Id = new Guid("46fd6123-5206-2c2c-2832-953d13847069"), - Name = "Montenegro" - }, - new - { - Id = new Guid("09ee26e3-5c82-221e-0729-e47d663a949c"), - Name = "Morocco" - }, - new - { - Id = new Guid("aa6f7328-8f52-9bd1-0bba-9fb4f18a926e"), - Name = "Mozambique" - }, - new - { - Id = new Guid("4ebfeb1d-67d6-2499-5346-740f737100ee"), - Name = "Myanmar (formerly Burma)" - }, - new - { - Id = new Guid("aa29ea0b-2681-3475-6e16-1b7d164b081a"), - Name = "Namibia" - }, - new - { - Id = new Guid("d9a21a29-a0e2-71bc-7308-548cc27b19f1"), - Name = "Nauru" - }, - new - { - Id = new Guid("2c4ab1fa-60da-7c87-35b3-ac6903455853"), - Name = "Nepal" - }, - new - { - Id = new Guid("cb245d05-3293-7315-7ee1-eef8a383319c"), - Name = "Netherlands" - }, - new - { - Id = new Guid("472e0e57-77f5-9c34-8e10-a621c97108f7"), - Name = "New Zealand" - }, - new - { - Id = new Guid("350dc86e-03b2-2c20-1908-b4de7d179de7"), - Name = "Nicaragua" - }, - new - { - Id = new Guid("9b36a6c2-4739-69a2-068b-c0b3c87c6f67"), - Name = "Niger" - }, - new - { - Id = new Guid("2ca00749-35c0-511b-9c2c-b53e5a8f0a71"), - Name = "Nigeria" - }, - new - { - Id = new Guid("10ef2f04-4d96-5b5e-316f-b373a88731be"), - Name = "North Korea" - }, - new - { - Id = new Guid("51c38ab5-0b2b-2994-4eb2-c8e82fe17950"), - Name = "North Macedonia" - }, - new - { - Id = new Guid("c1c8ec1f-58ce-3931-7ad7-ad4b55c14a85"), - Name = "Norway" - }, - new - { - Id = new Guid("859adf7d-1bf9-87d1-6a9b-4a06ebab6796"), - Name = "Oman" - }, - new - { - Id = new Guid("6133196d-26d0-5f8e-5792-6215aefd668d"), - Name = "Pakistan" - }, - new - { - Id = new Guid("3881b3b6-a332-3d35-8a73-43acfbf9045b"), - Name = "Palau" - }, - new - { - Id = new Guid("9a79f7fb-27a4-811b-88c3-9de906521017"), - Name = "Palestine State" - }, - new - { - Id = new Guid("f5b0c42e-3b0e-3808-1922-fdae58ea075c"), - Name = "Panama" - }, - new - { - Id = new Guid("16ff3157-a061-2e81-5ca6-b71e3619376e"), - Name = "Papua New Guinea" - }, - new - { - Id = new Guid("1b84f08e-8e6d-5779-967c-a162c2307153"), - Name = "Paraguay" - }, - new - { - Id = new Guid("f625e01e-4a07-7ff3-0a7e-ce6e27b586ff"), - Name = "Peru" - }, - new - { - Id = new Guid("19be2963-072b-2f4b-0f85-558d90ee1770"), - Name = "Philippines" - }, - new - { - Id = new Guid("fc432d5c-66dd-5660-8186-da84b4e164a0"), - Name = "Poland" - }, - new - { - Id = new Guid("2b1486b9-0cfa-2dc6-3f70-4ee2f11955b4"), - Name = "Portugal" - }, - new - { - Id = new Guid("47ac0edf-9beb-345b-0e4b-bccb0c1a2032"), - Name = "Qatar" - }, - new - { - Id = new Guid("d5cb2660-9af9-0385-8a99-52871814043d"), - Name = "Romania" - }, - new - { - Id = new Guid("6fa56ae5-2091-39c4-0010-ae74ffa2a0f2"), - Name = "Russia" - }, - new - { - Id = new Guid("362ac8d8-6fba-a641-8272-958f9e553b54"), - Name = "Rwanda" - }, - new - { - Id = new Guid("c3553d72-9d17-04d8-6692-12a5a7250008"), - Name = "Saint Kitts and Nevis" - }, - new - { - Id = new Guid("fd3ab0e3-279a-107a-88e0-93ee1bb45ffb"), - Name = "Saint Lucia" - }, - new - { - Id = new Guid("420b0acb-a1b0-27e5-45fc-3c6e96f25361"), - Name = "Saint Vincent and the Grenadines" - }, - new - { - Id = new Guid("37425b6c-2940-370c-805d-27cb7af97f88"), - Name = "Samoa" - }, - new - { - Id = new Guid("b6667319-a515-1cf5-7392-92e15c52438d"), - Name = "San Marino" - }, - new - { - Id = new Guid("75c8834a-67e9-9ee5-65bb-e2db6a937074"), - Name = "Sao Tome and Principe" - }, - new - { - Id = new Guid("1e9ab108-4d4b-1812-21d9-5c90d7d897ea"), - Name = "Saudi Arabia" - }, - new - { - Id = new Guid("3cb2d6c7-8bb5-191d-183d-b201063d5491"), - Name = "Senegal" - }, - new - { - Id = new Guid("1995e756-0e82-9463-1627-feeb766d2d0d"), - Name = "Serbia" - }, - new - { - Id = new Guid("1ff73b0c-27c4-9d4a-3d5b-ec77a6612d56"), - Name = "Seychelles" - }, - new - { - Id = new Guid("6df0d56f-3b4e-33fe-6d5f-74da585ea5d0"), - Name = "Sierra Leone" - }, - new - { - Id = new Guid("912f9045-7a3b-151b-2c06-19f899d1787a"), - Name = "Singapore" - }, - new - { - Id = new Guid("53e7d0fc-816f-59dd-7b4a-0ade62330830"), - Name = "Slovakia" - }, - new - { - Id = new Guid("a522756f-2fd9-48d1-7443-dd1546fd8b37"), - Name = "Slovenia" - }, - new - { - Id = new Guid("5f47ed3b-0b54-95aa-93e8-16bf035c9247"), - Name = "Solomon Islands" - }, - new - { - Id = new Guid("b58da294-9556-8ece-163f-3d89514017a7"), - Name = "Somalia" - }, - new - { - Id = new Guid("03a82f52-22d5-8259-1072-429791258b72"), - Name = "South Africa" - }, - new - { - Id = new Guid("55cafe8e-1585-278e-5736-bab16f1b1b8d"), - Name = "South Korea" - }, - new - { - Id = new Guid("9d2d676f-97fb-952c-06a9-09d4e9696631"), - Name = "South Sudan" - }, - new - { - Id = new Guid("534a826b-70ef-2128-1a4c-52e23b7d5447"), - Name = "Spain" - }, - new - { - Id = new Guid("932a43ac-56dc-951e-7de5-996314e92e9c"), - Name = "Sri Lanka" - }, - new - { - Id = new Guid("6c4a7b61-3bfd-4a47-95a3-0ca86c72521f"), - Name = "Sudan" - }, - new - { - Id = new Guid("9a0a2c1d-3475-3554-9d18-b11946af6086"), - Name = "Suriname" - }, - new - { - Id = new Guid("896ef05e-0fe4-92a6-229e-63d7a26e0625"), - Name = "Sweden" - }, - new - { - Id = new Guid("bb0b41a9-7363-5922-9ce0-939412a9036e"), - Name = "Switzerland" - }, - new - { - Id = new Guid("7b9c857e-3fbd-3d19-38cf-f204da39890c"), - Name = "Syria" - }, - new - { - Id = new Guid("d7cd92d3-4522-5a78-3533-816fc61a293f"), - Name = "Tajikistan" - }, - new - { - Id = new Guid("fa81562d-1bc4-944c-86a9-6cc5af502265"), - Name = "Tanzania" - }, - new - { - Id = new Guid("439e3108-0908-4d90-6f5c-1974362b74b1"), - Name = "Thailand" - }, - new - { - Id = new Guid("47e7cc9c-4368-8ab3-056b-66a1351c24cd"), - Name = "Timor-Leste" - }, - new - { - Id = new Guid("492a6eb7-5ca3-8e50-3559-c71205b71c3b"), - Name = "Togo" - }, - new - { - Id = new Guid("e376c876-6960-270c-8744-583fb7a72f55"), - Name = "Tonga" - }, - new - { - Id = new Guid("2f7c276f-4d0d-9368-4132-c04149924bb5"), - Name = "Trinidad and Tobago" - }, - new - { - Id = new Guid("93ba288b-2a62-1880-1e20-aeb705431890"), - Name = "Tunisia" - }, - new - { - Id = new Guid("c576d8f0-5300-2436-2d17-48b699214549"), - Name = "Turkey" - }, - new - { - Id = new Guid("a9c5d1ec-319a-085c-1ee3-80ae15bd27ed"), - Name = "Turkmenistan" - }, - new - { - Id = new Guid("95938676-73d1-2031-219d-dc67ba314bdf"), - Name = "Tuvalu" - }, - new - { - Id = new Guid("2cfae83c-0f45-72d1-4624-5af1e10e6147"), - Name = "Uganda" - }, - new - { - Id = new Guid("1b837dfa-0bda-54f3-918a-beef19f691e5"), - Name = "Ukraine" - }, - new - { - Id = new Guid("f7675604-4744-6d6f-a077-67a3e0c85324"), - Name = "United Arab Emirates" - }, - new - { - Id = new Guid("8f9ec4fb-916f-90ea-5162-f486a0fc0893"), - Name = "United Kingdom" - }, - new - { - Id = new Guid("ca111c84-983b-4525-054c-d14dee3a422c"), - Name = "United States of America" - }, - new - { - Id = new Guid("ee06c3ba-4e8c-95c3-88da-6be3f23b9aaa"), - Name = "Uruguay" - }, - new - { - Id = new Guid("2f02c930-1d71-8ca6-49e7-0d3679a522ea"), - Name = "Uzbekistan" - }, - new - { - Id = new Guid("28dc2817-94b4-955d-10bc-6a8793dd386c"), - Name = "Vanuatu" - }, - new - { - Id = new Guid("9c9e3bca-5880-437f-4f18-d6998d90173f"), - Name = "Venezuela" - }, - new - { - Id = new Guid("5a3893d1-1e36-310c-7633-8f36ffa26315"), - Name = "Vietnam" - }, - new - { - Id = new Guid("a2689ae3-3643-6250-a748-8f055cc72da8"), - Name = "Yemen" - }, - new - { - Id = new Guid("be447a08-0a85-5779-8c65-cf15c2c9a5a8"), - Name = "Zambia" - }, - new - { - Id = new Guid("c776f397-182b-6d0d-09f2-4e440dc093d3"), - Name = "Zimbabwe" - }); - }); - - modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.File", b => - { - b.Property("Id") - .HasColumnType("uniqueidentifier"); - - b.Property("ContentType") - .IsRequired() - .HasMaxLength(50) - .HasColumnType("nvarchar(50)"); - - b.Property("Discriminator") - .IsRequired() - .HasMaxLength(8) - .HasColumnType("nvarchar(8)"); - - b.Property("Extension") - .IsRequired() - .HasMaxLength(20) - .HasColumnType("nvarchar(20)"); - - b.Property("IsTemp") - .HasColumnType("bit"); - - b.Property("Name") - .IsRequired() - .HasMaxLength(300) - .HasColumnType("nvarchar(300)"); - - b.Property("Size") - .HasColumnType("bigint"); - - b.Property("UploadedOn") - .HasColumnType("datetime2"); - - b.HasKey("Id"); - - b.ToTable("File", (string)null); - - b.HasDiscriminator("Discriminator").IsComplete(true).HasValue("File"); - - b.UseTphMappingStrategy(); - }); - - modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.Product", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uniqueidentifier"); - - b.Property("CompanyId") - .HasColumnType("uniqueidentifier"); - - b.Property("DefaultPictureId") - .HasColumnType("uniqueidentifier"); - - b.Property("Description") - .IsRequired() - .HasMaxLength(500) - .HasColumnType("nvarchar(500)"); - - b.Property("Price") - .HasPrecision(10, 2) - .HasColumnType("decimal(10,2)"); - - b.Property("Title") - .IsRequired() - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b.HasKey("Id"); - - b.HasIndex("CompanyId"); - - b.HasIndex("DefaultPictureId") - .IsUnique(); - - b.HasIndex("Title"); - - b.ToTable("Product"); - }); - - modelBuilder.Entity("ProductPicture", b => - { - b.Property("PicturesId") - .HasColumnType("uniqueidentifier"); - - b.Property("ProductId") - .HasColumnType("uniqueidentifier"); - - b.HasKey("PicturesId", "ProductId"); - - b.HasIndex("PicturesId") - .IsUnique(); - - b.HasIndex("ProductId"); - - b.ToTable("ProductPicture"); - }); - - modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.Document", b => - { - b.HasBaseType("Monaco.Template.Backend.Domain.Model.File"); - - b.HasDiscriminator().HasValue("Document"); - }); - - modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.Image", b => - { - b.HasBaseType("Monaco.Template.Backend.Domain.Model.File"); - - b.Property("DateTaken") - .HasColumnType("datetime2"); - - b.Property("ThumbnailId") - .HasColumnType("uniqueidentifier"); - - b.HasIndex("ThumbnailId") - .IsUnique() - .HasFilter("[ThumbnailId] IS NOT NULL"); - - b.HasDiscriminator().HasValue("Image"); - }); - - modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.Company", b => - { - b.OwnsOne("Monaco.Template.Backend.Domain.Model.Address", "Address", b1 => - { - b1.Property("CompanyId") - .HasColumnType("uniqueidentifier"); - - b1.Property("City") - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b1.Property("CountryId") - .HasColumnType("uniqueidentifier"); - - b1.Property("County") - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b1.Property("PostCode") - .HasMaxLength(10) - .HasColumnType("nvarchar(10)"); - - b1.Property("Street") - .HasMaxLength(100) - .HasColumnType("nvarchar(100)"); - - b1.HasKey("CompanyId"); - - b1.HasIndex("CountryId"); - - b1.ToTable("Company"); - - b1.WithOwner() - .HasForeignKey("CompanyId"); - - b1.HasOne("Monaco.Template.Backend.Domain.Model.Country", "Country") - .WithMany() - .HasForeignKey("CountryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b1.Navigation("Country"); - }); - - b.Navigation("Address"); - }); - - modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.Product", b => - { - b.HasOne("Monaco.Template.Backend.Domain.Model.Company", "Company") - .WithMany("Products") - .HasForeignKey("CompanyId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Monaco.Template.Backend.Domain.Model.Image", "DefaultPicture") - .WithOne() - .HasForeignKey("Monaco.Template.Backend.Domain.Model.Product", "DefaultPictureId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Company"); - - b.Navigation("DefaultPicture"); - }); - - modelBuilder.Entity("ProductPicture", b => - { - b.HasOne("Monaco.Template.Backend.Domain.Model.Image", null) - .WithMany() - .HasForeignKey("PicturesId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Monaco.Template.Backend.Domain.Model.Product", null) - .WithMany() - .HasForeignKey("ProductId") - .OnDelete(DeleteBehavior.ClientCascade) - .IsRequired(); - }); - - modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.Image", b => - { - b.HasOne("Monaco.Template.Backend.Domain.Model.Image", "Thumbnail") - .WithOne() - .HasForeignKey("Monaco.Template.Backend.Domain.Model.Image", "ThumbnailId"); - - b.OwnsOne("Monaco.Template.Backend.Domain.Model.GpsPosition", "Position", b1 => - { - b1.Property("ImageId") - .HasColumnType("uniqueidentifier"); - - b1.Property("Latitude") - .HasColumnType("real"); - - b1.Property("Longitude") - .HasColumnType("real"); - - b1.HasKey("ImageId"); - - b1.ToTable("File"); - - b1.WithOwner() - .HasForeignKey("ImageId"); - }); - - b.OwnsOne("Monaco.Template.Backend.Domain.Model.ImageDimensions", "Dimensions", b1 => - { - b1.Property("ImageId") - .HasColumnType("uniqueidentifier"); - - b1.Property("Height") - .HasColumnType("int"); - - b1.Property("Width") - .HasColumnType("int"); - - b1.HasKey("ImageId"); - - b1.ToTable("File"); - - b1.WithOwner() - .HasForeignKey("ImageId"); - }); - - b.Navigation("Dimensions") - .IsRequired(); - - b.Navigation("Position"); - - b.Navigation("Thumbnail"); - }); - - modelBuilder.Entity("Monaco.Template.Backend.Domain.Model.Company", b => - { - b.Navigation("Products"); - }); -#pragma warning restore 612, 618 - } - } -} From a62abdc4d59d2f1fdb354d6e54ef0eadc0a9810a Mon Sep 17 00:00:00 2001 From: CesarD Date: Tue, 19 Dec 2023 10:36:16 +0100 Subject: [PATCH 05/21] CHORE: Some more cleanup. --- src/Content/Backend/Solution/.template.config/template.json | 1 + .../EntityConfigurations/FileEntityConfiguration.cs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Content/Backend/Solution/.template.config/template.json b/src/Content/Backend/Solution/.template.config/template.json index 2dcea4c..1373a88 100644 --- a/src/Content/Backend/Solution/.template.config/template.json +++ b/src/Content/Backend/Solution/.template.config/template.json @@ -167,6 +167,7 @@ "Monaco.Template.Backend.Application/Features/File/**/*", "Monaco.Template.Backend.Application/Features/Product/**/*", "Monaco.Template.Backend.Application/DTOs/Extensions/FileExtensions.cs", + "Monaco.Template.Backend.Application/DTOs/Extensions/ProductExtensions.cs", "Monaco.Template.Backend.Application/DTOs/FileDto.cs", "Monaco.Template.Backend.Application/DTOs/ImageDto.cs", "Monaco.Template.Backend.Application/DTOs/ProductDto.cs", diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure/EntityConfigurations/FileEntityConfiguration.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure/EntityConfigurations/FileEntityConfiguration.cs index ed2855a..7b9d614 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure/EntityConfigurations/FileEntityConfiguration.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure/EntityConfigurations/FileEntityConfiguration.cs @@ -12,7 +12,7 @@ public void Configure(EntityTypeBuilder builder) { builder.ConfigureIdWithDefaultAndValueGeneratedNever(); - builder.ToTable("File") + builder.ToTable(nameof(File)) .HasDiscriminator("Discriminator") .HasValue(nameof(Document)) .HasValue(nameof(Image)) From c7f755e1289f93a502577bd8ec989a6ce44f8c52 Mon Sep 17 00:00:00 2001 From: CesarD Date: Tue, 19 Dec 2023 11:24:37 +0100 Subject: [PATCH 06/21] FIX: Fixed missing API documentation config. --- .../Monaco.Template.Backend.Api.csproj | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Monaco.Template.Backend.Api.csproj b/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Monaco.Template.Backend.Api.csproj index 9fdae62..1caa24b 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Monaco.Template.Backend.Api.csproj +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Monaco.Template.Backend.Api.csproj @@ -5,6 +5,7 @@ enable enable 8ac1d4e3-61ef-452f-a386-ff3ec448fbff + True From 654e89dfdbf64f6988b4c58c642a2a98b5a0076b Mon Sep 17 00:00:00 2001 From: CesarD Date: Tue, 19 Dec 2023 13:22:27 +0100 Subject: [PATCH 07/21] FIX: Fixed file saving. --- .../Features/File/CreateFile.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/File/CreateFile.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/File/CreateFile.cs index 636fa0a..8b5caa8 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/File/CreateFile.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/File/CreateFile.cs @@ -41,7 +41,8 @@ public async Task> Handle(Command request, CancellationToke try { - _dbContext.Set().Attach(file); + await _dbContext.Set() + .AddAsync(file, cancellationToken); await _dbContext.SaveEntitiesAsync(cancellationToken); } catch From 5919d3733c30f8799bcc776e0a4fc32cc8d46ad6 Mon Sep 17 00:00:00 2001 From: CesarD Date: Tue, 19 Dec 2023 15:07:24 +0100 Subject: [PATCH 08/21] FIX: Corrected dependency between Company and Product and corresponding tests. FIX: Including missing flag conditions. --- .../Features/File/CreateFileHandlerTests.cs | 4 ++-- .../Features/Product/EditProductHandlerTests.cs | 8 +++++--- .../DTOs/Extensions/ProductExtensions.cs | 14 ++++++++------ .../Features/Product/CreateProduct.cs | 5 ++--- .../Features/Product/EditProduct.cs | 8 ++++---- .../Factories/Entities/CompanyFactory.cs | 1 + .../Factories/Entities/ProductFactory.cs | 8 ++++---- .../ProductTests.cs | 14 ++++---------- .../Model/Company.cs | 6 +++++- .../Model/Product.cs | 10 +++------- 10 files changed, 38 insertions(+), 40 deletions(-) diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/File/CreateFileHandlerTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/File/CreateFileHandlerTests.cs index c3df799..fdaf862 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/File/CreateFileHandlerTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/File/CreateFileHandlerTests.cs @@ -43,7 +43,7 @@ public async Task CreateNewFileSucceeds(Domain.Model.Document file) It.IsAny(), It.IsAny()), Times.Once); - fileDbSetMock.Verify(x => x.Attach(It.IsAny()), + fileDbSetMock.Verify(x => x.AddAsync(It.IsAny(), It.IsAny()), Times.Once); _dbContextMock.Verify(x => x.SaveEntitiesAsync(It.IsAny()), Times.Once); @@ -84,7 +84,7 @@ await action.Should() It.IsAny(), It.IsAny()), Times.Once); - fileDbSetMock.Verify(x => x.Attach(It.IsAny()), + fileDbSetMock.Verify(x => x.AddAsync(It.IsAny(), It.IsAny()), Times.Once); } } \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/EditProductHandlerTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/EditProductHandlerTests.cs index 09e57a5..986b622 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/EditProductHandlerTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/EditProductHandlerTests.cs @@ -11,6 +11,7 @@ using System.Linq; using System.Threading; using System.Threading.Tasks; +using Monaco.Template.Backend.Common.Tests.Factories.Entities; using Xunit; namespace Monaco.Template.Backend.Application.Tests.Features.Product; @@ -36,8 +37,10 @@ public async Task CreateNewProductSucceeds(Domain.Model.Company company, Image[] pictures) { _dbContextMock.CreateEntityMockAndSetupDbSetMock(out var productMock) - .CreateAndSetupDbSetMock(company) + .CreateAndSetupDbSetMock(company, out var companyDbSetMock) .CreateAndSetupDbSetMock(pictures); + companyDbSetMock.Setup(x => x.FindAsync(It.IsAny(), It.IsAny())) + .ReturnsAsync(company); productMock.SetupGet(x => x.Pictures) .Returns(pictures); productMock.SetupGet(x => x.Company) @@ -60,8 +63,7 @@ public async Task CreateNewProductSucceeds(Domain.Model.Company company, productMock.Verify(x => x.Update(It.IsAny(), It.IsAny(), - It.IsAny(), - It.IsAny())); + It.IsAny())); _dbContextMock.Verify(x => x.SaveEntitiesAsync(It.IsAny()), Times.Once); _fileServiceMock.Verify(x => x.DeleteImagesAsync(It.IsAny(), It.IsAny()), diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/DTOs/Extensions/ProductExtensions.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/DTOs/Extensions/ProductExtensions.cs index 974f977..6f7f9c1 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/DTOs/Extensions/ProductExtensions.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/DTOs/Extensions/ProductExtensions.cs @@ -33,24 +33,26 @@ value is null .Map() : null); - public static Product Map(this CreateProduct.Command value, Company company, Image[] pictures, Image defaultPicture) + public static Product Map(this CreateProduct.Command value, Image[] pictures) { + var defaultPicture = pictures.Single(x => x.Id == value.DefaultPictureId); + var item = new Product(value.Title, value.Description, - value.Price, - company); + value.Price); foreach (var picture in pictures) item.AddPicture(picture, picture == defaultPicture); return item; } - public static (Image[]newPics, Image[] deletedPics) Map(this EditProduct.Command value, Product item, Company company, Image[] pictures, Image defaultPicture) + public static (Image[]newPics, Image[] deletedPics) Map(this EditProduct.Command value, Product item, Image[] pictures) { + var defaultPicture = pictures.Single(x => x.Id == value.DefaultPictureId); + item.Update(value.Title, value.Description, - value.Price, - company); + value.Price); var deletedPics = item.Pictures .Where(p => !pictures.Contains(p)) diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/CreateProduct.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/CreateProduct.cs index 0f59f5c..4b82dbe 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/CreateProduct.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/CreateProduct.cs @@ -75,9 +75,8 @@ public async Task> Handle(Command request, CancellationToke { var (company, pictures) = await _dbContext.GetProductData(request.CompanyId, request.Pictures, cancellationToken); - var item = request.Map(company, - pictures, - pictures.Single(x => x.Id == request.DefaultPictureId)); + var item = request.Map(pictures); + company.AddProduct(item); _dbContext.Set().Attach(item); await _dbContext.SaveEntitiesAsync(cancellationToken); diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/EditProduct.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/EditProduct.cs index ddfcc3d..401d490 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/EditProduct.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/EditProduct.cs @@ -82,15 +82,15 @@ public Handler(AppDbContext dbContext, IFileService fileService) public async Task Handle(Command request, CancellationToken cancellationToken) { var item = await _dbContext.Set() + .Include(x => x.Company) .Include(x => x.Pictures) .ThenInclude(x => x.Thumbnail) .SingleAsync(x => x.Id == request.Id, cancellationToken); var (company, pictures) = await _dbContext.GetProductData(request.CompanyId, request.Pictures, cancellationToken); - var (newPics, deletedPics) = request.Map(item, - company, - pictures, - pictures.Single(x => x.Id == request.DefaultPictureId)); + var (newPics, deletedPics) = request.Map(item, pictures); + if (company != item.Company) + company.AddProduct(item); _dbContext.Set() .RemoveRange(deletedPics); diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Tests/Factories/Entities/CompanyFactory.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Tests/Factories/Entities/CompanyFactory.cs index a71ba06..309e714 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Tests/Factories/Entities/CompanyFactory.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Tests/Factories/Entities/CompanyFactory.cs @@ -37,6 +37,7 @@ public static IFixture RegisterCompanyMock(this IFixture fixture) fixture.Create(), fixture.Create
()); mock.SetupGet(x => x.Id).Returns(Guid.NewGuid()); + mock.SetupGet(x => x.Products).Returns(new List()); return mock.Object; }); return fixture; diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Tests/Factories/Entities/ProductFactory.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Tests/Factories/Entities/ProductFactory.cs index e0cf2a5..ec8a060 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Tests/Factories/Entities/ProductFactory.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Tests/Factories/Entities/ProductFactory.cs @@ -29,8 +29,7 @@ public static IFixture RegisterProduct(this IFixture fixture) { var product = new Product(fixture.Create(), fixture.Create(), - fixture.Create(), - fixture.Create()); + fixture.Create()); var images = fixture.CreateMany(); foreach (var image in images) product.AddPicture(image); @@ -46,10 +45,11 @@ public static IFixture RegisterProductMock(this IFixture fixture) { var mock = new Mock(fixture.Create(), fixture.Create(), - fixture.Create(), - fixture.Create()); + fixture.Create()); mock.SetupGet(x => x.Id) .Returns(Guid.NewGuid()); + mock.SetupGet(x => x.Company) + .Returns(fixture.Create()); var images = fixture.CreateMany(); mock.SetupGet(x => x.Pictures) diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/ProductTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/ProductTests.cs index c8bdea4..6885812 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/ProductTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/ProductTests.cs @@ -16,19 +16,16 @@ public class ProductTests [AnonymousData] public void NewProductSucceeds(string title, string description, - decimal price, - Company company) + decimal price) { price *= price; //positive always var sut = new Product(title, description, - price, - company); + price); sut.Title.Should().Be(title); sut.Description.Should().Be(description); sut.Price.Should().Be(price); - sut.Company.Should().Be(company); } [Theory(DisplayName = "Update product succeeds")] @@ -36,19 +33,16 @@ public void NewProductSucceeds(string title, public void UpdateProductSucceeds(Product sut, string title, string description, - decimal price, - Company company) + decimal price) { price *= price; //positive always sut.Update(title, description, - price, - company); + price); sut.Title.Should().Be(title); sut.Description.Should().Be(description); sut.Price.Should().Be(price); - sut.Company.Should().Be(company); } [Theory(DisplayName = "Add new picture succeeds")] diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/Company.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/Company.cs index 086b620..eed696a 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/Company.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/Company.cs @@ -29,10 +29,12 @@ public Company(string name, public byte[] Version { get; } public Address? Address { get; private set; } + #if !excludeFilesSupport private readonly List _products = new(); public virtual IReadOnlyList Products => _products; - + #endif + public virtual void Update(string name, string email, string webSiteUrl, @@ -43,6 +45,7 @@ public virtual void Update(string name, WebSiteUrl = webSiteUrl; Address = address; } + #if !excludeFilesSupport public void AddProduct(Product product) { @@ -55,4 +58,5 @@ public void RemoveProduct(Product product) if (Products.Contains(product)) _products.Remove(product); } + #endif } \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/Product.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/Product.cs index 5f6704f..a9ad034 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/Product.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/Product.cs @@ -10,13 +10,11 @@ protected Product() public Product(string title, string description, - decimal price, - Company company) + decimal price) { Title = title; Description = description; Price = price; - Company = company; } public string Title { get; private set; } @@ -33,14 +31,12 @@ public Product(string title, public virtual Image DefaultPicture { get; private set; } public virtual void Update(string title, - string description, - decimal price, - Company company) + string description, + decimal price) { Title = title; Description = description; Price = price; - Company = company; } public void AddPicture(Image picture, bool @default = false) From bb312d2c3654ce470b90a4e352728807ea103822 Mon Sep 17 00:00:00 2001 From: CesarD Date: Tue, 19 Dec 2023 15:15:42 +0100 Subject: [PATCH 09/21] FIX: Adding missing conditions for flags. --- .../Company/DeleteCompanyHandlerTests.cs | 52 +++++++++++-------- .../Features/Company/DeleteCompany.cs | 2 +- 2 files changed, 31 insertions(+), 23 deletions(-) diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/DeleteCompanyHandlerTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/DeleteCompanyHandlerTests.cs index 68e748b..7a15653 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/DeleteCompanyHandlerTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/DeleteCompanyHandlerTests.cs @@ -1,4 +1,6 @@ -using AutoFixture; +#if !excludeFilesSupport +using AutoFixture; +#endif using FluentAssertions; using Monaco.Template.Backend.Application.Features.Company; using Monaco.Template.Backend.Application.Infrastructure.Context; @@ -7,12 +9,18 @@ #endif using Monaco.Template.Backend.Common.Tests; using Monaco.Template.Backend.Common.Tests.Factories; +#if !excludeFilesSupport using Monaco.Template.Backend.Domain.Model; +#endif using Moq; using System; +#if !excludeFilesSupport using System.Collections.Generic; +#endif using System.Diagnostics.CodeAnalysis; +#if !excludeFilesSupport using System.Linq; +#endif using System.Threading; using System.Threading.Tasks; using Xunit; @@ -24,20 +32,20 @@ namespace Monaco.Template.Backend.Application.Tests.Features.Company; public class DeleteCompanyHandlerTests { private readonly Mock _dbContextMock = new(); - private readonly DeleteCompany.Command _command = new(It.IsAny()); - #if !excludeFilesSupport + private static readonly DeleteCompany.Command Command = new(It.IsAny()); +#if !excludeFilesSupport private readonly Mock _fileServiceMock = new(); - #endif +#endif [Theory(DisplayName = "Delete company succeeds")] [AnonymousData(true)] - #if !excludeFilesSupport +#if !excludeFilesSupport public async Task DeleteCompanySucceeds(IFixture fixture, Domain.Model.Product[] products) - #else - public async Task DeleteCompanySucceeds(Company company) - #endif +#else + public async Task DeleteCompanySucceeds(Domain.Model.Company company) +#endif { - #if !excludeFilesSupport +#if !excludeFilesSupport var companyMock = new Mock(fixture.Create(), fixture.Create(), fixture.Create(), @@ -53,38 +61,38 @@ public async Task DeleteCompanySucceeds(Company company) _dbContextMock.CreateAndSetupDbSetMock(companyMock.Object, out var companyDbSetMock); _dbContextMock.CreateAndSetupDbSetMock(pictures, out var imageDbSetMock); - #else +#else _dbContextMock.CreateAndSetupDbSetMock(company, out var companyDbSetMock); - #endif +#endif - var command = _command with + var command = Command with { - #if !excludeFilesSupport +#if !excludeFilesSupport Id = companyMock.Object.Id - #else +#else Id = company.Id - #endif +#endif }; - #if !excludeFilesSupport +#if !excludeFilesSupport var sut = new DeleteCompany.Handler(_dbContextMock.Object, _fileServiceMock.Object); - #else +#else var sut = new DeleteCompany.Handler(_dbContextMock.Object); - #endif +#endif var result = await sut.Handle(command, new CancellationToken()); companyDbSetMock.Verify(x => x.Remove(It.IsAny()), Times.Once); - #if !excludeFilesSupport +#if !excludeFilesSupport imageDbSetMock.Verify(x => x.RemoveRange(It.IsAny>()), Times.Once); - #endif +#endif _dbContextMock.Verify(x => x.SaveEntitiesAsync(It.IsAny()), Times.Once); - #if !excludeFilesSupport +#if !excludeFilesSupport _fileServiceMock.Verify(x => x.DeleteImagesAsync(It.IsAny(), It.IsAny()), Times.Once); - #endif +#endif result.ValidationResult .IsValid diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Company/DeleteCompany.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Company/DeleteCompany.cs index 17e6940..d4c0f0c 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Company/DeleteCompany.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Company/DeleteCompany.cs @@ -4,8 +4,8 @@ using Monaco.Template.Backend.Application.Infrastructure.Context; #if !excludeFilesSupport using Monaco.Template.Backend.Application.Services.Contracts; -#endif using Monaco.Template.Backend.Domain.Model; +#endif using Monaco.Template.Backend.Common.Application.Commands; using Monaco.Template.Backend.Common.Application.Commands.Contracts; using Monaco.Template.Backend.Common.Application.Validators.Extensions; From 3f2a4f17a0fc79d248f21b800dd0ea08f4fd751f Mon Sep 17 00:00:00 2001 From: CesarD Date: Tue, 19 Dec 2023 15:17:16 +0100 Subject: [PATCH 10/21] CHORE: Bumping Nuget version. --- src/Monaco.Template.nuspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Monaco.Template.nuspec b/src/Monaco.Template.nuspec index 7a91a71..3bee3e9 100644 --- a/src/Monaco.Template.nuspec +++ b/src/Monaco.Template.nuspec @@ -2,7 +2,7 @@ Monaco.Template - 2.2.0 + 2.3.0 Monaco Template Templates for .NET projects From 5a6ca37671e8ea58399a39a6d123af52922a3d6c Mon Sep 17 00:00:00 2001 From: CesarD Date: Tue, 19 Dec 2023 18:42:15 +0100 Subject: [PATCH 11/21] CHORE: Updated Keycloak configuration file with latest settings. --- .../Solution/.template.config/template.json | 24 ++- .../Solution/realm-export-template.json | 156 ++++++++++++------ 2 files changed, 128 insertions(+), 52 deletions(-) diff --git a/src/Content/Backend/Solution/.template.config/template.json b/src/Content/Backend/Solution/.template.config/template.json index 1373a88..d5fa732 100644 --- a/src/Content/Backend/Solution/.template.config/template.json +++ b/src/Content/Backend/Solution/.template.config/template.json @@ -565,6 +565,28 @@ "a2689ae3-3643-6250-a748-8f055cc72da8", "be447a08-0a85-5779-8c65-cf15c2c9a5a8", "c776f397-182b-6d0d-09f2-4e440dc093d3", - "d8623b90-59c1-4753-a0e6-f2dbd4305c9b" + "d8623b90-59c1-4753-a0e6-f2dbd4305c9b", + "205ad146-f5c4-4e7a-9419-8a2ea73b19d4", + "547e2363-08f5-4f67-9d5a-fed1bc883af8", + "d3d92cbf-7dea-404b-9b3b-e0e01d01b181", + "d10429c7-e0b3-47a9-ad34-a99eb2c1ae0d", + "718b5472-a9bb-4dba-a1c5-e48f8f5020e5", + "fa17826b-1ce9-4ec0-bff5-da0e1754ab7b", + "ab73883d-7755-458c-99b1-daed2e7d1fc7", + "b3df1fee-f37f-4bff-a6e6-b801324228f0", + "e38db072-8687-40eb-a35b-f9c375da1e01", + "83845f6b-6f32-43db-9de3-71299b05a7ee", + "39089091-f930-4d29-b20c-14e2a7a3a861", + "dfe90700-c265-49d6-8cdc-23855b75ef03", + "1c1a942e-ec7d-4312-aa4f-f0a571da0bce", + "6d7fab52-2a08-46ed-8a19-fe27284baa47", + "fc94d7d8-5d72-47e6-a4de-4c1512d71e16", + "6d7a94da-fbb7-4d20-b41c-472bed514830", + "c5d70775-bdc7-4826-93b1-0ba233ed4e7e", + "9b95767e-b8c7-4570-961d-13e8e59aae7c", + "d7b400a1-9455-46e1-8322-10ce0a3cbd07", + "39c225ca-9d35-42f9-b535-f477b40182df", + "54c70413-4884-4178-a662-96440d3dca17", + "f053015e-b577-42fa-9cd1-5b723eecb72c" ] } \ No newline at end of file diff --git a/src/Content/Backend/Solution/realm-export-template.json b/src/Content/Backend/Solution/realm-export-template.json index c09a489..e59668a 100644 --- a/src/Content/Backend/Solution/realm-export-template.json +++ b/src/Content/Backend/Solution/realm-export-template.json @@ -447,8 +447,8 @@ "otpPolicyCodeReusable": false, "otpSupportedApplications": [ "totpAppGoogleName", - "totpAppFreeOTPName", - "totpAppMicrosoftAuthenticatorName" + "totpAppMicrosoftAuthenticatorName", + "totpAppFreeOTPName" ], "webAuthnPolicyRpEntityName": "keycloak", "webAuthnPolicySignatureAlgorithms": [ @@ -505,6 +505,18 @@ "roles": [ "Administrator" ] + }, + { + "clientScope": "files:write", + "roles": [ + "Administrator" + ] + }, + { + "clientScope": "products:write", + "roles": [ + "Administrator" + ] } ] }, @@ -752,6 +764,9 @@ "clientId": "monaco-template-api-swagger-ui", "name": "Monaco Template API Swagger", "description": "Monaco Template API - Swagger client", + "rootUrl": "", + "adminUrl": "", + "baseUrl": "", "surrogateAuthRequired": false, "enabled": true, "alwaysDisplayInConsole": false, @@ -773,28 +788,31 @@ "frontchannelLogout": false, "protocol": "openid-connect", "attributes": { - "id.token.as.detached.signature": "false", - "saml.assertion.signature": "false", "saml.force.post.binding": "false", "saml.multivalued.roles": "false", - "saml.encrypt": "false", "post.logout.redirect.uris": "+", "oauth2.device.authorization.grant.enabled": "false", "backchannel.logout.revoke.offline.tokens": "false", - "saml.server.signature": "false", "saml.server.signature.keyinfo.ext": "false", - "use.refresh.tokens": "true", - "exclude.session.state.from.auth.response": "false", + "use.refresh.tokens": "false", "oidc.ciba.grant.enabled": "false", - "saml.artifact.binding": "false", "backchannel.logout.session.required": "true", "client_credentials.use_refresh_token": "false", - "saml_force_name_id_format": "false", "require.pushed.authorization.requests": "false", "saml.client.signature": "false", + "id.token.as.detached.signature": "false", + "saml.assertion.signature": "false", + "saml.encrypt": "false", + "saml.server.signature": "false", + "exclude.session.state.from.auth.response": "false", + "tls-client-certificate-bound-access-tokens": "false", + "saml.artifact.binding": "false", + "saml_force_name_id_format": "false", "tls.client.certificate.bound.access.tokens": "false", + "acr.loa.map": "{}", "saml.authnstatement": "false", "display.on.consent.screen": "false", + "token.response.type.bearer.lower-case": "false", "saml.onetimeuse.condition": "false" }, "authenticationFlowBindingOverrides": {}, @@ -808,11 +826,13 @@ "monaco-template-api" ], "optionalClientScopes": [ + "files:write", "address", "companies:read", "phone", "offline_access", "microprofile-jwt", + "products:write", "companies:write" ] }, @@ -886,13 +906,17 @@ "id": "4cd869a0-9d32-41d7-9769-e611a48cd9a9", "clientId": "monaco-template-front", "name": "Monaco Template Web", + "description": "", + "rootUrl": "", + "adminUrl": "", + "baseUrl": "", "surrogateAuthRequired": false, "enabled": true, "alwaysDisplayInConsole": false, "clientAuthenticatorType": "client-secret", "redirectUris": [ "*", - "http://localhost:3000", + "http://localhost:4200", "https://oauth.pstmn.io/v1/callback" ], "webOrigins": [], @@ -907,29 +931,32 @@ "frontchannelLogout": false, "protocol": "openid-connect", "attributes": { - "id.token.as.detached.signature": "false", - "saml.assertion.signature": "false", "saml.force.post.binding": "false", "saml.multivalued.roles": "false", - "saml.encrypt": "false", "post.logout.redirect.uris": "+", "oauth2.device.authorization.grant.enabled": "false", "backchannel.logout.revoke.offline.tokens": "false", - "saml.server.signature": "false", "saml.server.signature.keyinfo.ext": "false", - "use.refresh.tokens": "true", - "exclude.session.state.from.auth.response": "false", + "use.refresh.tokens": "false", "oidc.ciba.grant.enabled": "false", - "saml.artifact.binding": "false", "backchannel.logout.session.required": "true", "client_credentials.use_refresh_token": "false", - "saml_force_name_id_format": "false", "require.pushed.authorization.requests": "false", "saml.client.signature": "false", + "pkce.code.challenge.method": "S256", + "id.token.as.detached.signature": "false", + "saml.assertion.signature": "false", + "saml.encrypt": "false", + "saml.server.signature": "false", + "exclude.session.state.from.auth.response": "false", + "tls-client-certificate-bound-access-tokens": "false", + "saml.artifact.binding": "false", + "saml_force_name_id_format": "false", "tls.client.certificate.bound.access.tokens": "false", + "acr.loa.map": "{}", "saml.authnstatement": "false", "display.on.consent.screen": "false", - "pkce.code.challenge.method": "S256", + "token.response.type.bearer.lower-case": "false", "saml.onetimeuse.condition": "false" }, "authenticationFlowBindingOverrides": {}, @@ -943,11 +970,13 @@ "monaco-template-api" ], "optionalClientScopes": [ + "files:write", "address", "companies:read", "phone", "offline_access", "microprofile-jwt", + "products:write", "companies:write" ] }, @@ -1206,6 +1235,30 @@ } ] }, + { + "id": "33ff4854-2aad-4b12-9701-472d0a470c4f", + "name": "files:write", + "description": "", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "true", + "display.on.consent.screen": "false", + "gui.order": "", + "consent.screen.text": "" + } + }, + { + "id": "805aea0c-522f-4040-b380-c0dac6f55245", + "name": "products:write", + "description": "", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "true", + "display.on.consent.screen": "false", + "gui.order": "", + "consent.screen.text": "" + } + }, { "id": "194ef116-fa08-407a-b535-1d5a60356c7e", "name": "acr", @@ -1224,6 +1277,7 @@ "consentRequired": false, "config": { "id.token.claim": "true", + "userinfo.token.claim": "true", "access.token.claim": "true" } } @@ -1691,14 +1745,14 @@ "subComponents": {}, "config": { "allowed-protocol-mapper-types": [ + "oidc-usermodel-property-mapper", "oidc-usermodel-attribute-mapper", - "oidc-full-name-mapper", "oidc-address-mapper", + "oidc-full-name-mapper", "saml-role-list-mapper", + "saml-user-property-mapper", "saml-user-attribute-mapper", - "oidc-sha256-pairwise-sub-mapper", - "oidc-usermodel-property-mapper", - "saml-user-property-mapper" + "oidc-sha256-pairwise-sub-mapper" ] } }, @@ -1722,14 +1776,14 @@ "subComponents": {}, "config": { "allowed-protocol-mapper-types": [ - "oidc-full-name-mapper", + "saml-role-list-mapper", "saml-user-attribute-mapper", + "oidc-sha256-pairwise-sub-mapper", + "oidc-usermodel-property-mapper", "saml-user-property-mapper", - "saml-role-list-mapper", - "oidc-usermodel-attribute-mapper", "oidc-address-mapper", - "oidc-sha256-pairwise-sub-mapper", - "oidc-usermodel-property-mapper" + "oidc-full-name-mapper", + "oidc-usermodel-attribute-mapper" ] } }, @@ -1835,7 +1889,7 @@ "supportedLocales": [], "authenticationFlows": [ { - "id": "d5186dab-c3c4-4b19-9c3d-cdd0787d054d", + "id": "205ad146-f5c4-4e7a-9419-8a2ea73b19d4", "alias": "Account verification options", "description": "Method with which to verity the existing account", "providerId": "basic-flow", @@ -1861,7 +1915,7 @@ ] }, { - "id": "3ad8d43f-1b8e-4bd2-90dd-ed7a882ac0a2", + "id": "547e2363-08f5-4f67-9d5a-fed1bc883af8", "alias": "Authentication Options", "description": "Authentication options.", "providerId": "basic-flow", @@ -1895,7 +1949,7 @@ ] }, { - "id": "e98b79cb-6c9e-473c-b020-7c9b6b6ba3d9", + "id": "d3d92cbf-7dea-404b-9b3b-e0e01d01b181", "alias": "Browser - Conditional OTP", "description": "Flow to determine if the OTP is required for the authentication", "providerId": "basic-flow", @@ -1921,7 +1975,7 @@ ] }, { - "id": "d89c2378-e9c2-40dc-9352-6e43192ad7be", + "id": "d10429c7-e0b3-47a9-ad34-a99eb2c1ae0d", "alias": "Direct Grant - Conditional OTP", "description": "Flow to determine if the OTP is required for the authentication", "providerId": "basic-flow", @@ -1947,7 +2001,7 @@ ] }, { - "id": "8826380e-bd70-4792-9aea-7d29de403aa9", + "id": "718b5472-a9bb-4dba-a1c5-e48f8f5020e5", "alias": "First broker login - Conditional OTP", "description": "Flow to determine if the OTP is required for the authentication", "providerId": "basic-flow", @@ -1973,7 +2027,7 @@ ] }, { - "id": "09e74503-9899-45dc-8148-0d3d8746a3c3", + "id": "fa17826b-1ce9-4ec0-bff5-da0e1754ab7b", "alias": "Handle Existing Account", "description": "Handle what to do if there is existing account with same email/username like authenticated identity provider", "providerId": "basic-flow", @@ -1999,7 +2053,7 @@ ] }, { - "id": "68454eeb-b718-48bf-bb67-a2cbc5a25777", + "id": "ab73883d-7755-458c-99b1-daed2e7d1fc7", "alias": "Reset - Conditional OTP", "description": "Flow to determine if the OTP should be reset or not. Set to REQUIRED to force.", "providerId": "basic-flow", @@ -2025,7 +2079,7 @@ ] }, { - "id": "9f8ab0da-336f-4a1c-b997-ca6061caa6e7", + "id": "b3df1fee-f37f-4bff-a6e6-b801324228f0", "alias": "User creation or linking", "description": "Flow for the existing/non-existing user alternatives", "providerId": "basic-flow", @@ -2052,7 +2106,7 @@ ] }, { - "id": "a9690e57-94b3-4de7-a453-7b4711eb1e63", + "id": "e38db072-8687-40eb-a35b-f9c375da1e01", "alias": "Verify Existing Account by Re-authentication", "description": "Reauthentication of existing account", "providerId": "basic-flow", @@ -2078,7 +2132,7 @@ ] }, { - "id": "9c3710b8-3810-4600-978a-8d0cb523fe27", + "id": "83845f6b-6f32-43db-9de3-71299b05a7ee", "alias": "browser", "description": "browser based authentication", "providerId": "basic-flow", @@ -2120,7 +2174,7 @@ ] }, { - "id": "3b20d736-76b1-4f31-b8bb-4307f40dc554", + "id": "39089091-f930-4d29-b20c-14e2a7a3a861", "alias": "clients", "description": "Base authentication for clients", "providerId": "client-flow", @@ -2162,7 +2216,7 @@ ] }, { - "id": "58607617-6a87-4efe-95f2-db07a4d293a3", + "id": "dfe90700-c265-49d6-8cdc-23855b75ef03", "alias": "direct grant", "description": "OpenID Connect Resource Owner Grant", "providerId": "basic-flow", @@ -2196,7 +2250,7 @@ ] }, { - "id": "c55758f6-ba86-46b0-8d48-0aedd12e6176", + "id": "1c1a942e-ec7d-4312-aa4f-f0a571da0bce", "alias": "docker auth", "description": "Used by Docker clients to authenticate against the IDP", "providerId": "basic-flow", @@ -2214,7 +2268,7 @@ ] }, { - "id": "75788d22-37e1-4b23-bcca-7c929176fbab", + "id": "6d7fab52-2a08-46ed-8a19-fe27284baa47", "alias": "first broker login", "description": "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account", "providerId": "basic-flow", @@ -2241,7 +2295,7 @@ ] }, { - "id": "8a7860c9-e200-45bf-a6f6-353a47c9f683", + "id": "fc94d7d8-5d72-47e6-a4de-4c1512d71e16", "alias": "forms", "description": "Username, password, otp and other auth forms.", "providerId": "basic-flow", @@ -2267,7 +2321,7 @@ ] }, { - "id": "58a93edb-1989-4507-b840-8c6b2339cd1c", + "id": "6d7a94da-fbb7-4d20-b41c-472bed514830", "alias": "http challenge", "description": "An authentication flow based on challenge-response HTTP Authentication Schemes", "providerId": "basic-flow", @@ -2293,7 +2347,7 @@ ] }, { - "id": "ecb459b7-4ec9-432d-9e7f-7579e56d7d2e", + "id": "c5d70775-bdc7-4826-93b1-0ba233ed4e7e", "alias": "registration", "description": "registration flow", "providerId": "basic-flow", @@ -2312,7 +2366,7 @@ ] }, { - "id": "22121960-e79a-4349-b530-6c145d2e1296", + "id": "9b95767e-b8c7-4570-961d-13e8e59aae7c", "alias": "registration form", "description": "registration form", "providerId": "form-flow", @@ -2354,7 +2408,7 @@ ] }, { - "id": "b10d27db-2ceb-445a-a703-17bf0512ef5d", + "id": "d7b400a1-9455-46e1-8322-10ce0a3cbd07", "alias": "reset credentials", "description": "Reset credentials for a user if they forgot their password or something", "providerId": "basic-flow", @@ -2396,7 +2450,7 @@ ] }, { - "id": "3dd963c5-65cb-4b48-8a35-e7b681c8ab4c", + "id": "39c225ca-9d35-42f9-b535-f477b40182df", "alias": "saml ecp", "description": "SAML ECP Profile Authentication Flow", "providerId": "basic-flow", @@ -2416,14 +2470,14 @@ ], "authenticatorConfig": [ { - "id": "9b21e277-95c8-4186-ba65-51a82f75be53", + "id": "54c70413-4884-4178-a662-96440d3dca17", "alias": "create unique user config", "config": { "require.password.update.after.registration": "false" } }, { - "id": "4b221ac9-c081-4a71-a50f-32ea01e20599", + "id": "f053015e-b577-42fa-9cd1-5b723eecb72c", "alias": "review profile config", "config": { "update.profile.on.first.login": "missing" From f85e6fb21cedec025b26d53b764be4738a0603b6 Mon Sep 17 00:00:00 2001 From: CesarD Date: Wed, 20 Dec 2023 11:57:13 +0100 Subject: [PATCH 12/21] FIX: Fixed missing endpoints and configurations in API Gateway. FIX: Included files exclusions to the template configuration file and corrected flag descriptions. --- .../Solution/.template.config/template.json | 8 +++-- .../reverseProxy.json | 30 +++++++++---------- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/Content/Backend/Solution/.template.config/template.json b/src/Content/Backend/Solution/.template.config/template.json index d5fa732..9fcf1aa 100644 --- a/src/Content/Backend/Solution/.template.config/template.json +++ b/src/Content/Backend/Solution/.template.config/template.json @@ -30,8 +30,8 @@ "type": "parameter", "datatype": "bool", "defaultValue": "false", - "displayName": "Include files support and structure", - "description": "Include support for Azure BlobStorage and file handling structure" + "displayName": "Exclude files support and structure", + "description": "Exclude support for Azure BlobStorage and file handling structure" }, "massTransitIntegration": { "type": "parameter", @@ -144,7 +144,9 @@ "**/*.filelist", "**/*.user", "**/*.lock.json", - "**/.vs/**/*" + "**/.vs/**/*", + "**/logs/**", + "**/TestResults/**" ], "modifiers": [ { diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.ApiGateway/reverseProxy.json b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.ApiGateway/reverseProxy.json index 19fbddf..9a24755 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.ApiGateway/reverseProxy.json +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.ApiGateway/reverseProxy.json @@ -38,42 +38,42 @@ ] }, //#if (!excludeFilesSupport) - "FilesRead": { + "FilesWrite": { "ClusterId": "api", - "AuthorizationPolicy": "files:read", + "AuthorizationPolicy": "files:write", "Match": { - "Path": "/api/v1/Files/{**remainder}", - "Methods": [ "GET" ] + "Path": "/api/v1/Files", + "Methods": [ "POST" ] }, "Transforms": [ { - "PathPattern": "/api/v1/Files/{**remainder}" + "PathPattern": "/api/v1/Files" } ] }, - "FilesWrite": { + "ProductsRead": { "ClusterId": "api", - "AuthorizationPolicy": "files:write", + "AuthorizationPolicy": "anonymous", "Match": { - "Path": "/api/v1/Files/{**remainder}", - "Methods": [ "POST", "PUT", "DELETE" ] + "Path": "/api/v1/Products/{**remainder}", + "Methods": [ "GET" ] }, "Transforms": [ { - "PathPattern": "/api/v1/Files/{**remainder}" + "PathPattern": "/api/v1/Products/{**remainder}" } ] }, - "ImagesRead": { + "ProductsWrite": { "ClusterId": "api", - "AuthorizationPolicy": "files:read", + "AuthorizationPolicy": "products:write", "Match": { - "Path": "/api/v1/Images/{**remainder}", - "Methods": [ "GET" ] + "Path": "/api/v1/Products/{**remainder}", + "Methods": [ "POST", "PUT", "DELETE" ] }, "Transforms": [ { - "PathPattern": "/api/v1/Images/{**remainder}" + "PathPattern": "/api/v1/Products/{**remainder}" } ] }, From 973330df57f130c0573869050766b217050a971e Mon Sep 17 00:00:00 2001 From: CesarD Date: Wed, 20 Dec 2023 18:21:49 +0100 Subject: [PATCH 13/21] FIX: Fixes on conditions for template flags. FIX: Excluding missing files. --- .../Solution/.template.config/template.json | 5 +- .../Auth/Scopes.cs | 4 +- .../Controllers/FilesController.cs | 2 +- .../Monaco.Template.Backend.Api/Program.cs | 2 +- .../CompanyEntityConfiguration.cs | 2 + .../Company/DeleteCompanyHandlerTests.cs | 48 +++++++++---------- .../DependencyInjection/ApplicationOptions.cs | 4 +- .../ServiceCollectionExtensions.cs | 8 ++-- .../Features/Company/DeleteCompany.cs | 16 +++---- .../Features/File/CreateFile.cs | 2 +- .../Auth/Scopes.cs | 8 ++-- .../Factories/Entities/CompanyFactory.cs | 2 + .../Factories/FixtureExtensions.cs | 8 ++++ .../CompanyTests.cs | 4 ++ .../{ImageTests .cs => ImageTests.cs} | 0 .../Model/Company.cs | 4 +- 16 files changed, 69 insertions(+), 50 deletions(-) rename src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/{ImageTests .cs => ImageTests.cs} (100%) diff --git a/src/Content/Backend/Solution/.template.config/template.json b/src/Content/Backend/Solution/.template.config/template.json index 9fcf1aa..fd70e89 100644 --- a/src/Content/Backend/Solution/.template.config/template.json +++ b/src/Content/Backend/Solution/.template.config/template.json @@ -158,7 +158,7 @@ ] }, { - "condition": "(!excludeFilesSupport)", + "condition": "(excludeFilesSupport)", "exclude": [ "Monaco.Template.Backend.Common.BlobStorage/**/*", "Monaco.Template.Backend.Common.BlobStorage.Tests/**/*", @@ -181,6 +181,9 @@ "Monaco.Template.Backend.Application.Tests/Services/FileServiceTests.cs", "Monaco.Template.Backend.Application.Tests/Features/File/**/*", "Monaco.Template.Backend.Application.Tests/Features/Product/**/*", + "Monaco.Template.Backend.Common.Tests/Factories/Entities/DocumentFactory.cs", + "Monaco.Template.Backend.Common.Tests/Factories/Entities/ImageFactory.cs", + "Monaco.Template.Backend.Common.Tests/Factories/Entities/ProductFactory.cs", "Monaco.Template.Backend.Domain/Model/Document.cs", "Monaco.Template.Backend.Domain/Model/File.cs", "Monaco.Template.Backend.Domain/Model/GpsPosition.cs", diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Auth/Scopes.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Auth/Scopes.cs index 169197b..79897cb 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Auth/Scopes.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Auth/Scopes.cs @@ -5,7 +5,7 @@ public static class Scopes { public const string CompaniesRead = "companies:read"; public const string CompaniesWrite = "companies:write"; -#if !excludeFilesSupport +#if (!excludeFilesSupport) public const string FilesWrite = "files:write"; public const string ProductsWrite = "products:write"; #endif @@ -14,7 +14,7 @@ public static class Scopes { CompaniesRead, CompaniesWrite, -#if !excludeFilesSupport +#if (!excludeFilesSupport) FilesWrite, ProductsWrite #endif diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Controllers/FilesController.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Controllers/FilesController.cs index 1f5ed2a..f5fb66d 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Controllers/FilesController.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Controllers/FilesController.cs @@ -1,4 +1,4 @@ -#if !excludeFilesSupport +#if (!excludeFilesSupport) #if (!disableAuth) using Monaco.Template.Backend.Api.Auth; #endif diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Program.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Program.cs index 8d06745..d263004 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Program.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Program.cs @@ -51,7 +51,7 @@ { options.EntityFramework.ConnectionString = configuration.GetConnectionString("AppDbContext")!; options.EntityFramework.EnableEfSensitiveLogging = bool.Parse(configuration["EnableEFSensitiveLogging"] ?? "false"); -#if !excludeFilesSupport +#if (!excludeFilesSupport) options.BlobStorage.ConnectionString = configuration["BlobStorage:ConnectionString"]!; options.BlobStorage.ContainerName = configuration["BlobStorage:Container"]!; #endif diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure/EntityConfigurations/CompanyEntityConfiguration.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure/EntityConfigurations/CompanyEntityConfiguration.cs index 96c7005..c4e6999 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure/EntityConfigurations/CompanyEntityConfiguration.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure/EntityConfigurations/CompanyEntityConfiguration.cs @@ -25,12 +25,14 @@ public void Configure(EntityTypeBuilder builder) builder.Property(x => x.Version) .IsRowVersion(); + #if (!excludeFilesSupport) builder.HasMany(x => x.Products) .WithOne(x => x.Company) .HasForeignKey(x => x.CompanyId) .OnDelete(DeleteBehavior.Cascade) .IsRequired(); + #endif builder.OwnsOne(x => x.Address, b => diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/DeleteCompanyHandlerTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/DeleteCompanyHandlerTests.cs index 7a15653..4c4aaee 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/DeleteCompanyHandlerTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/DeleteCompanyHandlerTests.cs @@ -1,24 +1,24 @@ -#if !excludeFilesSupport +#if (!excludeFilesSupport) using AutoFixture; #endif using FluentAssertions; using Monaco.Template.Backend.Application.Features.Company; using Monaco.Template.Backend.Application.Infrastructure.Context; -#if !excludeFilesSupport +#if (!excludeFilesSupport) using Monaco.Template.Backend.Application.Services.Contracts; #endif using Monaco.Template.Backend.Common.Tests; using Monaco.Template.Backend.Common.Tests.Factories; -#if !excludeFilesSupport +#if (!excludeFilesSupport) using Monaco.Template.Backend.Domain.Model; #endif using Moq; using System; -#if !excludeFilesSupport +#if (!excludeFilesSupport) using System.Collections.Generic; #endif using System.Diagnostics.CodeAnalysis; -#if !excludeFilesSupport +#if (!excludeFilesSupport) using System.Linq; #endif using System.Threading; @@ -33,19 +33,19 @@ public class DeleteCompanyHandlerTests { private readonly Mock _dbContextMock = new(); private static readonly DeleteCompany.Command Command = new(It.IsAny()); -#if !excludeFilesSupport + #if (!excludeFilesSupport) private readonly Mock _fileServiceMock = new(); -#endif + #endif [Theory(DisplayName = "Delete company succeeds")] [AnonymousData(true)] -#if !excludeFilesSupport + #if (!excludeFilesSupport) public async Task DeleteCompanySucceeds(IFixture fixture, Domain.Model.Product[] products) -#else + #else public async Task DeleteCompanySucceeds(Domain.Model.Company company) -#endif + #endif { -#if !excludeFilesSupport + #if (!excludeFilesSupport) var companyMock = new Mock(fixture.Create(), fixture.Create(), fixture.Create(), @@ -61,38 +61,38 @@ public async Task DeleteCompanySucceeds(Domain.Model.Company company) _dbContextMock.CreateAndSetupDbSetMock(companyMock.Object, out var companyDbSetMock); _dbContextMock.CreateAndSetupDbSetMock(pictures, out var imageDbSetMock); -#else + #else _dbContextMock.CreateAndSetupDbSetMock(company, out var companyDbSetMock); -#endif + #endif var command = Command with { -#if !excludeFilesSupport + #if (!excludeFilesSupport) Id = companyMock.Object.Id -#else + #else Id = company.Id -#endif + #endif }; - -#if !excludeFilesSupport + + #if (!excludeFilesSupport) var sut = new DeleteCompany.Handler(_dbContextMock.Object, _fileServiceMock.Object); -#else + #else var sut = new DeleteCompany.Handler(_dbContextMock.Object); -#endif + #endif var result = await sut.Handle(command, new CancellationToken()); companyDbSetMock.Verify(x => x.Remove(It.IsAny()), Times.Once); -#if !excludeFilesSupport + #if (!excludeFilesSupport) imageDbSetMock.Verify(x => x.RemoveRange(It.IsAny>()), Times.Once); -#endif + #endif _dbContextMock.Verify(x => x.SaveEntitiesAsync(It.IsAny()), Times.Once); -#if !excludeFilesSupport + #if (!excludeFilesSupport) _fileServiceMock.Verify(x => x.DeleteImagesAsync(It.IsAny(), It.IsAny()), Times.Once); -#endif + #endif result.ValidationResult .IsValid diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/DependencyInjection/ApplicationOptions.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/DependencyInjection/ApplicationOptions.cs index 98b58b9..95db5e3 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/DependencyInjection/ApplicationOptions.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/DependencyInjection/ApplicationOptions.cs @@ -3,7 +3,7 @@ public class ApplicationOptions { public EntityFrameworkOptions EntityFramework { get; set; } = new(); -#if !excludeFilesSupport +#if (!excludeFilesSupport) public BlobStorageOptions BlobStorage { get; set; } = new(); #endif @@ -12,7 +12,7 @@ public class EntityFrameworkOptions public string ConnectionString { get; set; } = string.Empty; public bool EnableEfSensitiveLogging { get; set; } } -#if !excludeFilesSupport +#if (!excludeFilesSupport) public class BlobStorageOptions { diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/DependencyInjection/ServiceCollectionExtensions.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/DependencyInjection/ServiceCollectionExtensions.cs index a606642..5e73e10 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/DependencyInjection/ServiceCollectionExtensions.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/DependencyInjection/ServiceCollectionExtensions.cs @@ -2,7 +2,7 @@ using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Monaco.Template.Backend.Application.Infrastructure.Context; -#if !excludeFilesSupport +#if (!excludeFilesSupport) using Monaco.Template.Backend.Application.Services; using Monaco.Template.Backend.Application.Services.Contracts; #endif @@ -11,7 +11,7 @@ using System.Reflection; using Monaco.Template.Backend.Common.Application.Policies; using Monaco.Template.Backend.Common.Infrastructure.Context; -#if !excludeFilesSupport +#if (!excludeFilesSupport) using Monaco.Template.Backend.Common.BlobStorage.Extensions; #endif @@ -47,14 +47,14 @@ public static IServiceCollection ConfigureApplication(this IServiceCollection se .UseLazyLoadingProxies() .EnableSensitiveDataLogging(optionsValue.EntityFramework.EnableEfSensitiveLogging)) .AddScoped(provider => provider.GetRequiredService()); -#if !excludeFilesSupport + #if (!excludeFilesSupport) services.RegisterBlobStorageService(opts => { opts.ConnectionString = optionsValue.BlobStorage.ConnectionString; opts.ContainerName = optionsValue.BlobStorage.ContainerName; }) .AddScoped(); -#endif + #endif return services; } diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Company/DeleteCompany.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Company/DeleteCompany.cs index d4c0f0c..79987a4 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Company/DeleteCompany.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Company/DeleteCompany.cs @@ -2,7 +2,7 @@ using MediatR; using Microsoft.EntityFrameworkCore; using Monaco.Template.Backend.Application.Infrastructure.Context; -#if !excludeFilesSupport +#if (!excludeFilesSupport) using Monaco.Template.Backend.Application.Services.Contracts; using Monaco.Template.Backend.Domain.Model; #endif @@ -29,18 +29,18 @@ public Validator(AppDbContext dbContext) public sealed class Handler : IRequestHandler { private readonly AppDbContext _dbContext; - #if !excludeFilesSupport + #if (!excludeFilesSupport) private readonly IFileService _fileService; #endif - #if !excludeFilesSupport + #if (!excludeFilesSupport) public Handler(AppDbContext dbContext, IFileService fileService) #else public Handler(AppDbContext dbContext) #endif { _dbContext = dbContext; - #if !excludeFilesSupport + #if (!excludeFilesSupport) _fileService = fileService; #endif } @@ -48,14 +48,14 @@ public Handler(AppDbContext dbContext) public async Task Handle(Command request, CancellationToken cancellationToken) { var item = await _dbContext.Set() + #if (!excludeFilesSupport) .Include(x => x.Products) - #if !excludeFilesSupport .ThenInclude(x => x.Pictures) .ThenInclude(x => x.Thumbnail) #endif .SingleAsync(x => x.Id == request.Id, cancellationToken); - #if !excludeFilesSupport + #if (!excludeFilesSupport) var pictures = item.Products .SelectMany(x => x.Pictures) .ToArray(); @@ -63,14 +63,14 @@ public async Task Handle(Command request, CancellationToken canc #endif _dbContext.Set() .Remove(item); - #if !excludeFilesSupport + #if (!excludeFilesSupport) _dbContext.Set() .RemoveRange(pictures.Union(pictures.Select(x => x.Thumbnail!) .ToArray())); #endif await _dbContext.SaveEntitiesAsync(cancellationToken); - #if !excludeFilesSupport + #if (!excludeFilesSupport) await _fileService.DeleteImagesAsync(pictures, cancellationToken); #endif diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/File/CreateFile.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/File/CreateFile.cs index 8b5caa8..37ee4ce 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/File/CreateFile.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/File/CreateFile.cs @@ -23,7 +23,7 @@ public Validator() } } - #if !excludeFilesSupport + #if (!excludeFilesSupport) public sealed class Handler : IRequestHandler> { private readonly AppDbContext _dbContext; diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.ApiGateway/Auth/Scopes.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.ApiGateway/Auth/Scopes.cs index 5939164..d8f0b3b 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.ApiGateway/Auth/Scopes.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.ApiGateway/Auth/Scopes.cs @@ -4,18 +4,18 @@ public static class Scopes { public const string CompaniesRead = "companies:read"; public const string CompaniesWrite = "companies:write"; -#if !excludeFilesSupport + #if (!excludeFilesSupport) public const string FilesRead = "files:read"; public const string FilesWrite = "files:write"; -#endif + #endif public static List List => new() { CompaniesRead, CompaniesWrite, -#if !excludeFilesSupport + #if (!excludeFilesSupport) FilesRead, FilesWrite -#endif + #endif }; } \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Tests/Factories/Entities/CompanyFactory.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Tests/Factories/Entities/CompanyFactory.cs index 309e714..ced1dd9 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Tests/Factories/Entities/CompanyFactory.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Tests/Factories/Entities/CompanyFactory.cs @@ -37,7 +37,9 @@ public static IFixture RegisterCompanyMock(this IFixture fixture) fixture.Create(), fixture.Create
()); mock.SetupGet(x => x.Id).Returns(Guid.NewGuid()); + #if (!excludeFilesSupport) mock.SetupGet(x => x.Products).Returns(new List()); + #endif return mock.Object; }); return fixture; diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Tests/Factories/FixtureExtensions.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Tests/Factories/FixtureExtensions.cs index 28668b4..e932978 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Tests/Factories/FixtureExtensions.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Tests/Factories/FixtureExtensions.cs @@ -20,10 +20,14 @@ public static IFixture RegisterFactories(this IFixture fixture) fixture.RegisterCompany() .RegisterAddress() + #if (excludeFilesSupport) + .RegisterCountry(); + #else .RegisterCountry() .RegisterDocument() .RegisterImage() .RegisterProduct(); + #endif return fixture; } @@ -42,10 +46,14 @@ public static IFixture RegisterMockFactories(this IFixture fixture) fixture.RegisterCompanyMock() .RegisterAddressMock() + #if (excludeFilesSupport) + .RegisterCountryMock(); + #else .RegisterCountryMock() .RegisterDocumentMock() .RegisterImage() .RegisterProductMock(); + #endif return fixture; } diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/CompanyTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/CompanyTests.cs index 0cf2783..c7ce06f 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/CompanyTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/CompanyTests.cs @@ -2,7 +2,9 @@ using Monaco.Template.Backend.Common.Tests.Factories; using Monaco.Template.Backend.Domain.Model; using System.Diagnostics.CodeAnalysis; +#if (!excludeFilesSupport) using System.Linq; +#endif using Xunit; namespace Monaco.Template.Backend.Domain.Tests; @@ -49,6 +51,7 @@ public void UpdateCompanySucceeds(Company sut, sut.Address.Should().Be(address); sut.Version.Should().BeNull(); } + #if (!excludeFilesSupport) [Theory(DisplayName = "Add product succeeds")] [AnonymousData] @@ -82,4 +85,5 @@ public void RemoveProductSucceeds(Company sut, Product[] products) .And .NotContain(deletedProduct); } + #endif } \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/ImageTests .cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/ImageTests.cs similarity index 100% rename from src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/ImageTests .cs rename to src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/ImageTests.cs diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/Company.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/Company.cs index eed696a..117b0e7 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/Company.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/Company.cs @@ -29,7 +29,7 @@ public Company(string name, public byte[] Version { get; } public Address? Address { get; private set; } - #if !excludeFilesSupport + #if (!excludeFilesSupport) private readonly List _products = new(); public virtual IReadOnlyList Products => _products; @@ -45,7 +45,7 @@ public virtual void Update(string name, WebSiteUrl = webSiteUrl; Address = address; } - #if !excludeFilesSupport + #if (!excludeFilesSupport) public void AddProduct(Product product) { From 63bbf68fae9d88947e01f3f3406a4ea04f79b5f3 Mon Sep 17 00:00:00 2001 From: CesarD Date: Wed, 20 Dec 2023 19:21:01 +0100 Subject: [PATCH 14/21] CHORE: Refactored collection expressions to apply new syntax. CHORE: Cleanup test projects with ImplicitUsings. --- .../Auth/Scopes.cs | 22 +- .../EntityConfigurations/Seeds/CountrySeed.cs | 395 +++++++++--------- .../Company/CreateCompanyHandlerTests.cs | 4 - .../Company/CreateCompanyValidatorTests.cs | 3 - .../Company/DeleteCompanyHandlerTests.cs | 9 - .../Company/DeleteCompanyValidatorTests.cs | 4 +- .../Company/EditCompanyHandlerTests.cs | 3 - .../Company/EditCompanyValidatorTests.cs | 3 - .../Features/Company/GetCompanyByIdTests.cs | 6 +- .../Features/Company/GetCompanyPageTests.cs | 4 - .../Features/Country/GetCountryByIdTests.cs | 6 +- .../Features/Country/GetCountryListTests.cs | 6 +- .../Features/File/CreateFileHandlerTests.cs | 4 - .../Features/File/CreateFileValidatorTests.cs | 2 - .../Product/CreateProductHandlerTests.cs | 5 - .../Product/CreateProductValidatorTests.cs | 14 +- .../Product/DeleteProductHandlerTests.cs | 5 - .../Product/DeleteProductValidatorTests.cs | 2 - .../Product/DownloadProductPictureTests.cs | 6 - .../Product/EditProductHandlerTests.cs | 5 - .../Product/EditProductValidatorTests.cs | 14 +- .../Features/Product/GetProductByIdTests.cs | 5 - .../Features/Product/GetProductPageTests.cs | 5 - ....Template.Backend.Application.Tests.csproj | 2 +- .../Services/FileServiceTests.cs | 4 - .../MediatorExtensions.cs | 2 +- .../Swagger/AuthorizeCheckOperationFilter.cs | 5 +- .../Auth/Scopes.cs | 18 +- .../BlobStorageServiceTests.cs | 1 - ...te.Backend.Common.BlobStorage.Tests.csproj | 1 + .../DomainEventTests.cs | 1 - .../EntityTests.cs | 3 - .../EnumerationTests.cs | 1 - ...emplate.Backend.Common.Domain.Tests.csproj | 2 +- .../PageTests.cs | 1 - .../ValueObjectTests.cs | 1 - .../Model/Entity.cs | 2 +- .../Context/Extensions/FilterExtensions.cs | 2 +- .../Extensions/OperationsExtensions.cs | 6 +- .../Context/Extensions/SortingExtensions.cs | 4 +- .../CompanyTests.cs | 3 - .../DocumentTests.cs | 4 +- .../ImageTests.cs | 3 +- ...onaco.Template.Backend.Domain.Tests.csproj | 2 +- .../ProductTests.cs | 1 - .../Model/Company.cs | 2 +- .../Model/Product.cs | 2 +- 47 files changed, 248 insertions(+), 357 deletions(-) diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Auth/Scopes.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Auth/Scopes.cs index 79897cb..6d6abad 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Auth/Scopes.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Api/Auth/Scopes.cs @@ -5,19 +5,19 @@ public static class Scopes { public const string CompaniesRead = "companies:read"; public const string CompaniesWrite = "companies:write"; -#if (!excludeFilesSupport) + #if (!excludeFilesSupport) public const string FilesWrite = "files:write"; public const string ProductsWrite = "products:write"; -#endif + #endif - public static List List => new() - { - CompaniesRead, - CompaniesWrite, -#if (!excludeFilesSupport) - FilesWrite, - ProductsWrite -#endif - }; + public static List List => + [ + CompaniesRead, + CompaniesWrite, + #if (!excludeFilesSupport) + FilesWrite, + ProductsWrite + #endif + ]; } #endif \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure/EntityConfigurations/Seeds/CountrySeed.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure/EntityConfigurations/Seeds/CountrySeed.cs index cf9c3a4..50a445e 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure/EntityConfigurations/Seeds/CountrySeed.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Infrastructure/EntityConfigurations/Seeds/CountrySeed.cs @@ -3,202 +3,201 @@ public class CountrySeed { public static List GetCountries() => - new() - { - new { Id = new Guid("5c064eff-a037-a6a3-06ec-92f662903af3"), Name = "Afghanistan" }, - new { Id = new Guid("a8b54a61-35d8-9b82-76e4-c709561d9952"), Name = "Albania" }, - new { Id = new Guid("9f420922-9842-0d2d-616d-dacee7c25db7"), Name = "Algeria" }, - new { Id = new Guid("26253117-7664-92a9-1a3c-b15cf4bf4c78"), Name = "Andorra" }, - new { Id = new Guid("ba510e09-5109-42a2-63f0-32d7ede12a5a"), Name = "Angola" }, - new { Id = new Guid("359da8da-68eb-9466-855d-f0f381f715b8"), Name = "Antigua and Barbuda" }, - new { Id = new Guid("01ec70b8-6aad-3770-a129-62c0fc294791"), Name = "Argentina" }, - new { Id = new Guid("7d62846b-1841-882f-1cc4-85e2edeea265"), Name = "Armenia" }, - new { Id = new Guid("269928e1-37c5-32e0-60c5-bc6da2b8240e"), Name = "Australia" }, - new { Id = new Guid("7fce71e6-a14d-5d96-2dc1-1fc6779e02d3"), Name = "Austria" }, - new { Id = new Guid("4cf81cef-66a5-a117-3297-884134e903ee"), Name = "Azerbaijan" }, - new { Id = new Guid("08b5d3d0-89ed-a66f-3175-05316ae4a309"), Name = "Bahamas" }, - new { Id = new Guid("d7bd1f34-6ef7-43a6-24ed-53bca003086c"), Name = "Bahrain" }, - new { Id = new Guid("0d69d315-2825-2d05-9c04-ba1ad47180ac"), Name = "Bangladesh" }, - new { Id = new Guid("52f81e1e-6903-88e8-199f-cfc5139b0c69"), Name = "Barbados" }, - new { Id = new Guid("52b13dd7-28fc-9bba-8d59-5c2209531bf5"), Name = "Belarus" }, - new { Id = new Guid("8b9ac6d0-2320-3f99-8db7-d78c5d53151a"), Name = "Belgium" }, - new { Id = new Guid("c12db9c7-7ca1-4aec-34f1-7d0bb4713ca8"), Name = "Belize" }, - new { Id = new Guid("e34dc09e-2df2-3661-90e1-f03154d45caf"), Name = "Benin" }, - new { Id = new Guid("cf59ee2f-144d-99ac-9048-eafaba1f4732"), Name = "Bhutan" }, - new { Id = new Guid("1a426c53-787f-527c-5471-c505d6403603"), Name = "Bolivia" }, - new { Id = new Guid("fae877c5-4806-05e8-2068-950cdcea6ba9"), Name = "Bosnia and Herzegovina" }, - new { Id = new Guid("e0276db5-123f-6028-9e3e-eb43f2e06c47"), Name = "Botswana" }, - new { Id = new Guid("72499e6c-80a1-32c3-2692-7216abe7815b"), Name = "Brazil" }, - new { Id = new Guid("ba408210-2ea9-8c6c-1d5d-7e33973f1c99"), Name = "Brunei" }, - new { Id = new Guid("99532f86-827d-39ba-1c01-b9795ec60bf4"), Name = "Bulgaria" }, - new { Id = new Guid("f16e701a-5dbf-a441-3305-20ac536d34dc"), Name = "Burkina Faso" }, - new { Id = new Guid("ff0258f4-35a2-220b-9d9d-f0fe28226cc3"), Name = "Burundi" }, - new { Id = new Guid("f8135306-1323-4f48-7a4b-8d0427cb075b"), Name = "Côte d'Ivoire" }, - new { Id = new Guid("4676b79b-461c-95de-9871-041d2e0b130b"), Name = "Cabo Verde" }, - new { Id = new Guid("42f62587-3470-5967-77e3-f9b0cf285d90"), Name = "Cambodia" }, - new { Id = new Guid("01deb5a8-6bd7-1879-9d4b-cb73dd0e9a97"), Name = "Cameroon" }, - new { Id = new Guid("ff7c5aa2-6b56-218e-491a-42f4c67ca4a9"), Name = "Canada" }, - new { Id = new Guid("77b88575-0e8c-82d0-72bf-06f638b7485f"), Name = "Central African Republic" }, - new { Id = new Guid("758d4f58-7371-36c1-26c2-fcdb993806eb"), Name = "Chad" }, - new { Id = new Guid("97c787c7-915b-4878-3aa2-6ca1eec02f65"), Name = "Chile" }, - new { Id = new Guid("003548f7-318a-6f99-8a27-d62963b64cb5"), Name = "China" }, - new { Id = new Guid("63a948ca-178b-93da-4fdd-e6be10b49a42"), Name = "Colombia" }, - new { Id = new Guid("6d2bc2ca-2f37-3698-7f08-b7b3eeda5bf5"), Name = "Comoros" }, - new { Id = new Guid("d9e7fd6d-77f2-8e76-0174-4c17df936d4e"), Name = "Congo (Congo-Brazzaville)" }, - new { Id = new Guid("16eded64-8619-2b73-682f-a703c1cb2d76"), Name = "Costa Rica" }, - new { Id = new Guid("7915a976-5224-94f8-232f-ac163a11630c"), Name = "Croatia" }, - new { Id = new Guid("b6ed03e6-096c-3f87-093d-f3ff4bf34c24"), Name = "Cuba" }, - new { Id = new Guid("d7506bd0-454d-1b83-39e0-905836535271"), Name = "Cyprus" }, - new { Id = new Guid("caf14a3d-777d-0ee5-63a9-1c3da4e81458"), Name = "Czechia (Czech Republic)" }, - new { Id = new Guid("da82e26d-40bd-0866-0822-3d5468a36c3e"), Name = "Democratic Republic of the Congo" }, - new { Id = new Guid("57dc70e9-17ec-995b-5a60-a7c029b1476a"), Name = "Denmark" }, - new { Id = new Guid("8c6486fe-2680-4725-1ef3-3d56e3100f08"), Name = "Djibouti" }, - new { Id = new Guid("d7e310ab-99c3-0a50-2ead-57a2823433ee"), Name = "Dominica" }, - new { Id = new Guid("555a4e83-0151-7a10-2072-6cc9f4ac77c1"), Name = "Dominican Republic" }, - new { Id = new Guid("2908f020-3d75-3f9a-1a7f-020d1f8d5553"), Name = "Ecuador" }, - new { Id = new Guid("89bd993a-4eaa-6bae-8cf9-22f766fa2a1e"), Name = "Egypt" }, - new { Id = new Guid("ab1e3408-7157-2629-29a5-fbd6a61d92a9"), Name = "El Salvador" }, - new { Id = new Guid("e58f3cfd-069a-4457-23ef-9df8d7fe9ba0"), Name = "Equatorial Guinea" }, - new { Id = new Guid("5e7808be-01a7-9495-2320-314ce20871f3"), Name = "Eritrea" }, - new { Id = new Guid("5198e2c0-8107-5bcf-90b4-0054eac52295"), Name = "Estonia" }, - new { Id = new Guid("cfa8f583-23d4-1475-57ea-ef72ae7b633f"), Name = "Eswatini (fmr. \"Swaziland\")" }, - new { Id = new Guid("637e0fb3-34ed-6a1b-7524-3d6cd3155d35"), Name = "Ethiopia" }, - new { Id = new Guid("6459ce24-8398-57e0-4a31-48addb374e6d"), Name = "Fiji" }, - new { Id = new Guid("d726f074-4b1d-3043-39eb-f9b4ab9b2344"), Name = "Finland" }, - new { Id = new Guid("a5d734a1-021d-9b50-6fd4-b8f24bb96b12"), Name = "France" }, - new { Id = new Guid("a64406fb-51f7-2ed2-31af-847f9cf16783"), Name = "Gabon" }, - new { Id = new Guid("967f775b-3c8b-889d-5189-ee71f59f520e"), Name = "Gambia" }, - new { Id = new Guid("914f8571-1cac-3f1b-14ef-71aa91836616"), Name = "Georgia" }, - new { Id = new Guid("d4249520-8674-a2c1-0084-683d7aea64db"), Name = "Germany" }, - new { Id = new Guid("4fa88e4e-344a-32f8-a5ef-4ef2c33858d2"), Name = "Ghana" }, - new { Id = new Guid("a9fe165c-96e6-6bdf-99b0-68f7b2972ef6"), Name = "Greece" }, - new { Id = new Guid("6dfb0c67-2ab9-a5bc-1c58-5eaf76016b9d"), Name = "Grenada" }, - new { Id = new Guid("c8f8a591-79c3-a19e-94dd-1c96ed1aa23a"), Name = "Guatemala" }, - new { Id = new Guid("b0ac51a0-0128-4070-a49f-19b3dc5e8135"), Name = "Guinea" }, - new { Id = new Guid("d9060b41-6ea0-8efa-1dfe-ce293774947b"), Name = "Guinea-Bissau" }, - new { Id = new Guid("c79ec6ec-2f3d-0c12-8658-5ccbc1a20a77"), Name = "Guyana" }, - new { Id = new Guid("60a26e14-90ee-5838-4d27-3672a8e88c48"), Name = "Haiti" }, - new { Id = new Guid("a2c0a247-350e-85e6-9009-8106f5fd49b2"), Name = "Holy See" }, - new { Id = new Guid("d2300477-7258-17b8-7e8a-cf65f06a325f"), Name = "Honduras" }, - new { Id = new Guid("81f4a56e-5d53-47f3-52c3-2cd843434126"), Name = "Hungary" }, - new { Id = new Guid("9c239e38-640c-3fb2-0bc8-8edaace24c70"), Name = "Iceland" }, - new { Id = new Guid("a0d1f65e-307d-59fa-7792-24a5f0359889"), Name = "India" }, - new { Id = new Guid("5b9d725f-4e89-0181-74ae-ba87e96590d7"), Name = "Indonesia" }, - new { Id = new Guid("afa8b53f-45e6-391f-1c60-db81be664b1b"), Name = "Iran" }, - new { Id = new Guid("59bee04d-32a1-1e53-4a1b-599671a4a693"), Name = "Iraq" }, - new { Id = new Guid("18bd53bd-3519-69ef-1148-3453ad744c0f"), Name = "Ireland" }, - new { Id = new Guid("6704c135-5af7-88e9-16a5-ad4656fa1be2"), Name = "Israel" }, - new { Id = new Guid("cf1fcfbe-11fa-7009-0d71-d2cf5c80a334"), Name = "Italy" }, - new { Id = new Guid("038fb0db-7012-50fb-9ace-3b9f240d9627"), Name = "Jamaica" }, - new { Id = new Guid("12d9457c-1c12-9961-60cf-ec2ee534843a"), Name = "Japan" }, - new { Id = new Guid("aa9d471d-3f2f-5d42-3d01-443a83c12f59"), Name = "Jordan" }, - new { Id = new Guid("7708a52a-1d62-8f8b-0a4d-6028ed834994"), Name = "Kazakhstan" }, - new { Id = new Guid("f27f4ccb-4e04-8e05-456e-621788247647"), Name = "Kenya" }, - new { Id = new Guid("c7fc5498-271d-1027-343a-1560793d1c26"), Name = "Kiribati" }, - new { Id = new Guid("ee007dac-7417-54e4-18c2-ec6a678ba130"), Name = "Kuwait" }, - new { Id = new Guid("20bfffe5-7601-63e6-3574-9346e80d5d5c"), Name = "Kyrgyzstan" }, - new { Id = new Guid("6a5e5c1a-4d04-237e-8415-a7f93945133b"), Name = "Laos" }, - new { Id = new Guid("1e2e1979-539d-128f-538e-c30b8ba49b42"), Name = "Latvia" }, - new { Id = new Guid("29e7cce5-28a0-990c-6ded-54e96cad9caa"), Name = "Lebanon" }, - new { Id = new Guid("dbe19dde-374b-68a8-41e0-48d5195aa6f5"), Name = "Lesotho" }, - new { Id = new Guid("2092625a-45e4-166e-53cf-bb48408f1b09"), Name = "Liberia" }, - new { Id = new Guid("9d8cf3fc-222d-a56c-211b-8e8e9edf54e0"), Name = "Libya" }, - new { Id = new Guid("b232a961-1224-244f-27a1-06cba2046c22"), Name = "Liechtenstein" }, - new { Id = new Guid("a681eaeb-1fa0-12d7-93fb-e33a13c188e9"), Name = "Lithuania" }, - new { Id = new Guid("5ee9fcd4-5680-3cb4-1174-d85201e82367"), Name = "Luxembourg" }, - new { Id = new Guid("408f1ee6-42d3-a211-67c5-32f601b79bd9"), Name = "Madagascar" }, - new { Id = new Guid("341651be-9d9c-206b-9162-aad732979787"), Name = "Malawi" }, - new { Id = new Guid("40563307-5fe1-97d4-9d10-d81af5138548"), Name = "Malaysia" }, - new { Id = new Guid("43da6311-4ed9-9a74-9a46-82847f79a7c3"), Name = "Maldives" }, - new { Id = new Guid("c3700331-07c2-264c-2335-ba61bc718cac"), Name = "Mali" }, - new { Id = new Guid("1e3241f2-78b6-56e8-4c2d-4a50647973cf"), Name = "Malta" }, - new { Id = new Guid("bdf3f266-9570-2bb9-330f-9ea51c927068"), Name = "Marshall Islands" }, - new { Id = new Guid("572563f8-2f44-603d-857e-3f8230035e82"), Name = "Mauritania" }, - new { Id = new Guid("e8b389a9-0afd-4904-46af-464012f102c2"), Name = "Mauritius" }, - new { Id = new Guid("2f7432c5-405f-3f99-4bc3-35e318bd66cc"), Name = "Mexico" }, - new { Id = new Guid("94e831a3-3e52-7bb4-7616-dc0ac75c2d1d"), Name = "Micronesia" }, - new { Id = new Guid("abe01fc7-a484-7a8e-74b6-c5fa27554505"), Name = "Moldova" }, - new { Id = new Guid("6a265dd9-314e-2eb2-a4f8-3faf9c11a39d"), Name = "Monaco" }, - new { Id = new Guid("a484eabd-775b-4b7d-595b-3f5d857f5052"), Name = "Mongolia" }, - new { Id = new Guid("46fd6123-5206-2c2c-2832-953d13847069"), Name = "Montenegro" }, - new { Id = new Guid("09ee26e3-5c82-221e-0729-e47d663a949c"), Name = "Morocco" }, - new { Id = new Guid("aa6f7328-8f52-9bd1-0bba-9fb4f18a926e"), Name = "Mozambique" }, - new { Id = new Guid("4ebfeb1d-67d6-2499-5346-740f737100ee"), Name = "Myanmar (formerly Burma)" }, - new { Id = new Guid("aa29ea0b-2681-3475-6e16-1b7d164b081a"), Name = "Namibia" }, - new { Id = new Guid("d9a21a29-a0e2-71bc-7308-548cc27b19f1"), Name = "Nauru" }, - new { Id = new Guid("2c4ab1fa-60da-7c87-35b3-ac6903455853"), Name = "Nepal" }, - new { Id = new Guid("cb245d05-3293-7315-7ee1-eef8a383319c"), Name = "Netherlands" }, - new { Id = new Guid("472e0e57-77f5-9c34-8e10-a621c97108f7"), Name = "New Zealand" }, - new { Id = new Guid("350dc86e-03b2-2c20-1908-b4de7d179de7"), Name = "Nicaragua" }, - new { Id = new Guid("9b36a6c2-4739-69a2-068b-c0b3c87c6f67"), Name = "Niger" }, - new { Id = new Guid("2ca00749-35c0-511b-9c2c-b53e5a8f0a71"), Name = "Nigeria" }, - new { Id = new Guid("10ef2f04-4d96-5b5e-316f-b373a88731be"), Name = "North Korea" }, - new { Id = new Guid("51c38ab5-0b2b-2994-4eb2-c8e82fe17950"), Name = "North Macedonia" }, - new { Id = new Guid("c1c8ec1f-58ce-3931-7ad7-ad4b55c14a85"), Name = "Norway" }, - new { Id = new Guid("859adf7d-1bf9-87d1-6a9b-4a06ebab6796"), Name = "Oman" }, - new { Id = new Guid("6133196d-26d0-5f8e-5792-6215aefd668d"), Name = "Pakistan" }, - new { Id = new Guid("3881b3b6-a332-3d35-8a73-43acfbf9045b"), Name = "Palau" }, - new { Id = new Guid("9a79f7fb-27a4-811b-88c3-9de906521017"), Name = "Palestine State" }, - new { Id = new Guid("f5b0c42e-3b0e-3808-1922-fdae58ea075c"), Name = "Panama" }, - new { Id = new Guid("16ff3157-a061-2e81-5ca6-b71e3619376e"), Name = "Papua New Guinea" }, - new { Id = new Guid("1b84f08e-8e6d-5779-967c-a162c2307153"), Name = "Paraguay" }, - new { Id = new Guid("f625e01e-4a07-7ff3-0a7e-ce6e27b586ff"), Name = "Peru" }, - new { Id = new Guid("19be2963-072b-2f4b-0f85-558d90ee1770"), Name = "Philippines" }, - new { Id = new Guid("fc432d5c-66dd-5660-8186-da84b4e164a0"), Name = "Poland" }, - new { Id = new Guid("2b1486b9-0cfa-2dc6-3f70-4ee2f11955b4"), Name = "Portugal" }, - new { Id = new Guid("47ac0edf-9beb-345b-0e4b-bccb0c1a2032"), Name = "Qatar" }, - new { Id = new Guid("d5cb2660-9af9-0385-8a99-52871814043d"), Name = "Romania" }, - new { Id = new Guid("6fa56ae5-2091-39c4-0010-ae74ffa2a0f2"), Name = "Russia" }, - new { Id = new Guid("362ac8d8-6fba-a641-8272-958f9e553b54"), Name = "Rwanda" }, - new { Id = new Guid("c3553d72-9d17-04d8-6692-12a5a7250008"), Name = "Saint Kitts and Nevis" }, - new { Id = new Guid("fd3ab0e3-279a-107a-88e0-93ee1bb45ffb"), Name = "Saint Lucia" }, - new { Id = new Guid("420b0acb-a1b0-27e5-45fc-3c6e96f25361"), Name = "Saint Vincent and the Grenadines" }, - new { Id = new Guid("37425b6c-2940-370c-805d-27cb7af97f88"), Name = "Samoa" }, - new { Id = new Guid("b6667319-a515-1cf5-7392-92e15c52438d"), Name = "San Marino" }, - new { Id = new Guid("75c8834a-67e9-9ee5-65bb-e2db6a937074"), Name = "Sao Tome and Principe" }, - new { Id = new Guid("1e9ab108-4d4b-1812-21d9-5c90d7d897ea"), Name = "Saudi Arabia" }, - new { Id = new Guid("3cb2d6c7-8bb5-191d-183d-b201063d5491"), Name = "Senegal" }, - new { Id = new Guid("1995e756-0e82-9463-1627-feeb766d2d0d"), Name = "Serbia" }, - new { Id = new Guid("1ff73b0c-27c4-9d4a-3d5b-ec77a6612d56"), Name = "Seychelles" }, - new { Id = new Guid("6df0d56f-3b4e-33fe-6d5f-74da585ea5d0"), Name = "Sierra Leone" }, - new { Id = new Guid("912f9045-7a3b-151b-2c06-19f899d1787a"), Name = "Singapore" }, - new { Id = new Guid("53e7d0fc-816f-59dd-7b4a-0ade62330830"), Name = "Slovakia" }, - new { Id = new Guid("a522756f-2fd9-48d1-7443-dd1546fd8b37"), Name = "Slovenia" }, - new { Id = new Guid("5f47ed3b-0b54-95aa-93e8-16bf035c9247"), Name = "Solomon Islands" }, - new { Id = new Guid("b58da294-9556-8ece-163f-3d89514017a7"), Name = "Somalia" }, - new { Id = new Guid("03a82f52-22d5-8259-1072-429791258b72"), Name = "South Africa" }, - new { Id = new Guid("55cafe8e-1585-278e-5736-bab16f1b1b8d"), Name = "South Korea" }, - new { Id = new Guid("9d2d676f-97fb-952c-06a9-09d4e9696631"), Name = "South Sudan" }, - new { Id = new Guid("534a826b-70ef-2128-1a4c-52e23b7d5447"), Name = "Spain" }, - new { Id = new Guid("932a43ac-56dc-951e-7de5-996314e92e9c"), Name = "Sri Lanka" }, - new { Id = new Guid("6c4a7b61-3bfd-4a47-95a3-0ca86c72521f"), Name = "Sudan" }, - new { Id = new Guid("9a0a2c1d-3475-3554-9d18-b11946af6086"), Name = "Suriname" }, - new { Id = new Guid("896ef05e-0fe4-92a6-229e-63d7a26e0625"), Name = "Sweden" }, - new { Id = new Guid("bb0b41a9-7363-5922-9ce0-939412a9036e"), Name = "Switzerland" }, - new { Id = new Guid("7b9c857e-3fbd-3d19-38cf-f204da39890c"), Name = "Syria" }, - new { Id = new Guid("d7cd92d3-4522-5a78-3533-816fc61a293f"), Name = "Tajikistan" }, - new { Id = new Guid("fa81562d-1bc4-944c-86a9-6cc5af502265"), Name = "Tanzania" }, - new { Id = new Guid("439e3108-0908-4d90-6f5c-1974362b74b1"), Name = "Thailand" }, - new { Id = new Guid("47e7cc9c-4368-8ab3-056b-66a1351c24cd"), Name = "Timor-Leste" }, - new { Id = new Guid("492a6eb7-5ca3-8e50-3559-c71205b71c3b"), Name = "Togo" }, - new { Id = new Guid("e376c876-6960-270c-8744-583fb7a72f55"), Name = "Tonga" }, - new { Id = new Guid("2f7c276f-4d0d-9368-4132-c04149924bb5"), Name = "Trinidad and Tobago" }, - new { Id = new Guid("93ba288b-2a62-1880-1e20-aeb705431890"), Name = "Tunisia" }, - new { Id = new Guid("c576d8f0-5300-2436-2d17-48b699214549"), Name = "Turkey" }, - new { Id = new Guid("a9c5d1ec-319a-085c-1ee3-80ae15bd27ed"), Name = "Turkmenistan" }, - new { Id = new Guid("95938676-73d1-2031-219d-dc67ba314bdf"), Name = "Tuvalu" }, - new { Id = new Guid("2cfae83c-0f45-72d1-4624-5af1e10e6147"), Name = "Uganda" }, - new { Id = new Guid("1b837dfa-0bda-54f3-918a-beef19f691e5"), Name = "Ukraine" }, - new { Id = new Guid("f7675604-4744-6d6f-a077-67a3e0c85324"), Name = "United Arab Emirates" }, - new { Id = new Guid("8f9ec4fb-916f-90ea-5162-f486a0fc0893"), Name = "United Kingdom" }, - new { Id = new Guid("ca111c84-983b-4525-054c-d14dee3a422c"), Name = "United States of America" }, - new { Id = new Guid("ee06c3ba-4e8c-95c3-88da-6be3f23b9aaa"), Name = "Uruguay" }, - new { Id = new Guid("2f02c930-1d71-8ca6-49e7-0d3679a522ea"), Name = "Uzbekistan" }, - new { Id = new Guid("28dc2817-94b4-955d-10bc-6a8793dd386c"), Name = "Vanuatu" }, - new { Id = new Guid("9c9e3bca-5880-437f-4f18-d6998d90173f"), Name = "Venezuela" }, - new { Id = new Guid("5a3893d1-1e36-310c-7633-8f36ffa26315"), Name = "Vietnam" }, - new { Id = new Guid("a2689ae3-3643-6250-a748-8f055cc72da8"), Name = "Yemen" }, - new { Id = new Guid("be447a08-0a85-5779-8c65-cf15c2c9a5a8"), Name = "Zambia" }, - new { Id = new Guid("c776f397-182b-6d0d-09f2-4e440dc093d3"), Name = "Zimbabwe" } - }; + [ + new { Id = new Guid("5c064eff-a037-a6a3-06ec-92f662903af3"), Name = "Afghanistan" }, + new { Id = new Guid("a8b54a61-35d8-9b82-76e4-c709561d9952"), Name = "Albania" }, + new { Id = new Guid("9f420922-9842-0d2d-616d-dacee7c25db7"), Name = "Algeria" }, + new { Id = new Guid("26253117-7664-92a9-1a3c-b15cf4bf4c78"), Name = "Andorra" }, + new { Id = new Guid("ba510e09-5109-42a2-63f0-32d7ede12a5a"), Name = "Angola" }, + new { Id = new Guid("359da8da-68eb-9466-855d-f0f381f715b8"), Name = "Antigua and Barbuda" }, + new { Id = new Guid("01ec70b8-6aad-3770-a129-62c0fc294791"), Name = "Argentina" }, + new { Id = new Guid("7d62846b-1841-882f-1cc4-85e2edeea265"), Name = "Armenia" }, + new { Id = new Guid("269928e1-37c5-32e0-60c5-bc6da2b8240e"), Name = "Australia" }, + new { Id = new Guid("7fce71e6-a14d-5d96-2dc1-1fc6779e02d3"), Name = "Austria" }, + new { Id = new Guid("4cf81cef-66a5-a117-3297-884134e903ee"), Name = "Azerbaijan" }, + new { Id = new Guid("08b5d3d0-89ed-a66f-3175-05316ae4a309"), Name = "Bahamas" }, + new { Id = new Guid("d7bd1f34-6ef7-43a6-24ed-53bca003086c"), Name = "Bahrain" }, + new { Id = new Guid("0d69d315-2825-2d05-9c04-ba1ad47180ac"), Name = "Bangladesh" }, + new { Id = new Guid("52f81e1e-6903-88e8-199f-cfc5139b0c69"), Name = "Barbados" }, + new { Id = new Guid("52b13dd7-28fc-9bba-8d59-5c2209531bf5"), Name = "Belarus" }, + new { Id = new Guid("8b9ac6d0-2320-3f99-8db7-d78c5d53151a"), Name = "Belgium" }, + new { Id = new Guid("c12db9c7-7ca1-4aec-34f1-7d0bb4713ca8"), Name = "Belize" }, + new { Id = new Guid("e34dc09e-2df2-3661-90e1-f03154d45caf"), Name = "Benin" }, + new { Id = new Guid("cf59ee2f-144d-99ac-9048-eafaba1f4732"), Name = "Bhutan" }, + new { Id = new Guid("1a426c53-787f-527c-5471-c505d6403603"), Name = "Bolivia" }, + new { Id = new Guid("fae877c5-4806-05e8-2068-950cdcea6ba9"), Name = "Bosnia and Herzegovina" }, + new { Id = new Guid("e0276db5-123f-6028-9e3e-eb43f2e06c47"), Name = "Botswana" }, + new { Id = new Guid("72499e6c-80a1-32c3-2692-7216abe7815b"), Name = "Brazil" }, + new { Id = new Guid("ba408210-2ea9-8c6c-1d5d-7e33973f1c99"), Name = "Brunei" }, + new { Id = new Guid("99532f86-827d-39ba-1c01-b9795ec60bf4"), Name = "Bulgaria" }, + new { Id = new Guid("f16e701a-5dbf-a441-3305-20ac536d34dc"), Name = "Burkina Faso" }, + new { Id = new Guid("ff0258f4-35a2-220b-9d9d-f0fe28226cc3"), Name = "Burundi" }, + new { Id = new Guid("f8135306-1323-4f48-7a4b-8d0427cb075b"), Name = "Côte d'Ivoire" }, + new { Id = new Guid("4676b79b-461c-95de-9871-041d2e0b130b"), Name = "Cabo Verde" }, + new { Id = new Guid("42f62587-3470-5967-77e3-f9b0cf285d90"), Name = "Cambodia" }, + new { Id = new Guid("01deb5a8-6bd7-1879-9d4b-cb73dd0e9a97"), Name = "Cameroon" }, + new { Id = new Guid("ff7c5aa2-6b56-218e-491a-42f4c67ca4a9"), Name = "Canada" }, + new { Id = new Guid("77b88575-0e8c-82d0-72bf-06f638b7485f"), Name = "Central African Republic" }, + new { Id = new Guid("758d4f58-7371-36c1-26c2-fcdb993806eb"), Name = "Chad" }, + new { Id = new Guid("97c787c7-915b-4878-3aa2-6ca1eec02f65"), Name = "Chile" }, + new { Id = new Guid("003548f7-318a-6f99-8a27-d62963b64cb5"), Name = "China" }, + new { Id = new Guid("63a948ca-178b-93da-4fdd-e6be10b49a42"), Name = "Colombia" }, + new { Id = new Guid("6d2bc2ca-2f37-3698-7f08-b7b3eeda5bf5"), Name = "Comoros" }, + new { Id = new Guid("d9e7fd6d-77f2-8e76-0174-4c17df936d4e"), Name = "Congo (Congo-Brazzaville)" }, + new { Id = new Guid("16eded64-8619-2b73-682f-a703c1cb2d76"), Name = "Costa Rica" }, + new { Id = new Guid("7915a976-5224-94f8-232f-ac163a11630c"), Name = "Croatia" }, + new { Id = new Guid("b6ed03e6-096c-3f87-093d-f3ff4bf34c24"), Name = "Cuba" }, + new { Id = new Guid("d7506bd0-454d-1b83-39e0-905836535271"), Name = "Cyprus" }, + new { Id = new Guid("caf14a3d-777d-0ee5-63a9-1c3da4e81458"), Name = "Czechia (Czech Republic)" }, + new { Id = new Guid("da82e26d-40bd-0866-0822-3d5468a36c3e"), Name = "Democratic Republic of the Congo" }, + new { Id = new Guid("57dc70e9-17ec-995b-5a60-a7c029b1476a"), Name = "Denmark" }, + new { Id = new Guid("8c6486fe-2680-4725-1ef3-3d56e3100f08"), Name = "Djibouti" }, + new { Id = new Guid("d7e310ab-99c3-0a50-2ead-57a2823433ee"), Name = "Dominica" }, + new { Id = new Guid("555a4e83-0151-7a10-2072-6cc9f4ac77c1"), Name = "Dominican Republic" }, + new { Id = new Guid("2908f020-3d75-3f9a-1a7f-020d1f8d5553"), Name = "Ecuador" }, + new { Id = new Guid("89bd993a-4eaa-6bae-8cf9-22f766fa2a1e"), Name = "Egypt" }, + new { Id = new Guid("ab1e3408-7157-2629-29a5-fbd6a61d92a9"), Name = "El Salvador" }, + new { Id = new Guid("e58f3cfd-069a-4457-23ef-9df8d7fe9ba0"), Name = "Equatorial Guinea" }, + new { Id = new Guid("5e7808be-01a7-9495-2320-314ce20871f3"), Name = "Eritrea" }, + new { Id = new Guid("5198e2c0-8107-5bcf-90b4-0054eac52295"), Name = "Estonia" }, + new { Id = new Guid("cfa8f583-23d4-1475-57ea-ef72ae7b633f"), Name = "Eswatini (fmr. \"Swaziland\")" }, + new { Id = new Guid("637e0fb3-34ed-6a1b-7524-3d6cd3155d35"), Name = "Ethiopia" }, + new { Id = new Guid("6459ce24-8398-57e0-4a31-48addb374e6d"), Name = "Fiji" }, + new { Id = new Guid("d726f074-4b1d-3043-39eb-f9b4ab9b2344"), Name = "Finland" }, + new { Id = new Guid("a5d734a1-021d-9b50-6fd4-b8f24bb96b12"), Name = "France" }, + new { Id = new Guid("a64406fb-51f7-2ed2-31af-847f9cf16783"), Name = "Gabon" }, + new { Id = new Guid("967f775b-3c8b-889d-5189-ee71f59f520e"), Name = "Gambia" }, + new { Id = new Guid("914f8571-1cac-3f1b-14ef-71aa91836616"), Name = "Georgia" }, + new { Id = new Guid("d4249520-8674-a2c1-0084-683d7aea64db"), Name = "Germany" }, + new { Id = new Guid("4fa88e4e-344a-32f8-a5ef-4ef2c33858d2"), Name = "Ghana" }, + new { Id = new Guid("a9fe165c-96e6-6bdf-99b0-68f7b2972ef6"), Name = "Greece" }, + new { Id = new Guid("6dfb0c67-2ab9-a5bc-1c58-5eaf76016b9d"), Name = "Grenada" }, + new { Id = new Guid("c8f8a591-79c3-a19e-94dd-1c96ed1aa23a"), Name = "Guatemala" }, + new { Id = new Guid("b0ac51a0-0128-4070-a49f-19b3dc5e8135"), Name = "Guinea" }, + new { Id = new Guid("d9060b41-6ea0-8efa-1dfe-ce293774947b"), Name = "Guinea-Bissau" }, + new { Id = new Guid("c79ec6ec-2f3d-0c12-8658-5ccbc1a20a77"), Name = "Guyana" }, + new { Id = new Guid("60a26e14-90ee-5838-4d27-3672a8e88c48"), Name = "Haiti" }, + new { Id = new Guid("a2c0a247-350e-85e6-9009-8106f5fd49b2"), Name = "Holy See" }, + new { Id = new Guid("d2300477-7258-17b8-7e8a-cf65f06a325f"), Name = "Honduras" }, + new { Id = new Guid("81f4a56e-5d53-47f3-52c3-2cd843434126"), Name = "Hungary" }, + new { Id = new Guid("9c239e38-640c-3fb2-0bc8-8edaace24c70"), Name = "Iceland" }, + new { Id = new Guid("a0d1f65e-307d-59fa-7792-24a5f0359889"), Name = "India" }, + new { Id = new Guid("5b9d725f-4e89-0181-74ae-ba87e96590d7"), Name = "Indonesia" }, + new { Id = new Guid("afa8b53f-45e6-391f-1c60-db81be664b1b"), Name = "Iran" }, + new { Id = new Guid("59bee04d-32a1-1e53-4a1b-599671a4a693"), Name = "Iraq" }, + new { Id = new Guid("18bd53bd-3519-69ef-1148-3453ad744c0f"), Name = "Ireland" }, + new { Id = new Guid("6704c135-5af7-88e9-16a5-ad4656fa1be2"), Name = "Israel" }, + new { Id = new Guid("cf1fcfbe-11fa-7009-0d71-d2cf5c80a334"), Name = "Italy" }, + new { Id = new Guid("038fb0db-7012-50fb-9ace-3b9f240d9627"), Name = "Jamaica" }, + new { Id = new Guid("12d9457c-1c12-9961-60cf-ec2ee534843a"), Name = "Japan" }, + new { Id = new Guid("aa9d471d-3f2f-5d42-3d01-443a83c12f59"), Name = "Jordan" }, + new { Id = new Guid("7708a52a-1d62-8f8b-0a4d-6028ed834994"), Name = "Kazakhstan" }, + new { Id = new Guid("f27f4ccb-4e04-8e05-456e-621788247647"), Name = "Kenya" }, + new { Id = new Guid("c7fc5498-271d-1027-343a-1560793d1c26"), Name = "Kiribati" }, + new { Id = new Guid("ee007dac-7417-54e4-18c2-ec6a678ba130"), Name = "Kuwait" }, + new { Id = new Guid("20bfffe5-7601-63e6-3574-9346e80d5d5c"), Name = "Kyrgyzstan" }, + new { Id = new Guid("6a5e5c1a-4d04-237e-8415-a7f93945133b"), Name = "Laos" }, + new { Id = new Guid("1e2e1979-539d-128f-538e-c30b8ba49b42"), Name = "Latvia" }, + new { Id = new Guid("29e7cce5-28a0-990c-6ded-54e96cad9caa"), Name = "Lebanon" }, + new { Id = new Guid("dbe19dde-374b-68a8-41e0-48d5195aa6f5"), Name = "Lesotho" }, + new { Id = new Guid("2092625a-45e4-166e-53cf-bb48408f1b09"), Name = "Liberia" }, + new { Id = new Guid("9d8cf3fc-222d-a56c-211b-8e8e9edf54e0"), Name = "Libya" }, + new { Id = new Guid("b232a961-1224-244f-27a1-06cba2046c22"), Name = "Liechtenstein" }, + new { Id = new Guid("a681eaeb-1fa0-12d7-93fb-e33a13c188e9"), Name = "Lithuania" }, + new { Id = new Guid("5ee9fcd4-5680-3cb4-1174-d85201e82367"), Name = "Luxembourg" }, + new { Id = new Guid("408f1ee6-42d3-a211-67c5-32f601b79bd9"), Name = "Madagascar" }, + new { Id = new Guid("341651be-9d9c-206b-9162-aad732979787"), Name = "Malawi" }, + new { Id = new Guid("40563307-5fe1-97d4-9d10-d81af5138548"), Name = "Malaysia" }, + new { Id = new Guid("43da6311-4ed9-9a74-9a46-82847f79a7c3"), Name = "Maldives" }, + new { Id = new Guid("c3700331-07c2-264c-2335-ba61bc718cac"), Name = "Mali" }, + new { Id = new Guid("1e3241f2-78b6-56e8-4c2d-4a50647973cf"), Name = "Malta" }, + new { Id = new Guid("bdf3f266-9570-2bb9-330f-9ea51c927068"), Name = "Marshall Islands" }, + new { Id = new Guid("572563f8-2f44-603d-857e-3f8230035e82"), Name = "Mauritania" }, + new { Id = new Guid("e8b389a9-0afd-4904-46af-464012f102c2"), Name = "Mauritius" }, + new { Id = new Guid("2f7432c5-405f-3f99-4bc3-35e318bd66cc"), Name = "Mexico" }, + new { Id = new Guid("94e831a3-3e52-7bb4-7616-dc0ac75c2d1d"), Name = "Micronesia" }, + new { Id = new Guid("abe01fc7-a484-7a8e-74b6-c5fa27554505"), Name = "Moldova" }, + new { Id = new Guid("6a265dd9-314e-2eb2-a4f8-3faf9c11a39d"), Name = "Monaco" }, + new { Id = new Guid("a484eabd-775b-4b7d-595b-3f5d857f5052"), Name = "Mongolia" }, + new { Id = new Guid("46fd6123-5206-2c2c-2832-953d13847069"), Name = "Montenegro" }, + new { Id = new Guid("09ee26e3-5c82-221e-0729-e47d663a949c"), Name = "Morocco" }, + new { Id = new Guid("aa6f7328-8f52-9bd1-0bba-9fb4f18a926e"), Name = "Mozambique" }, + new { Id = new Guid("4ebfeb1d-67d6-2499-5346-740f737100ee"), Name = "Myanmar (formerly Burma)" }, + new { Id = new Guid("aa29ea0b-2681-3475-6e16-1b7d164b081a"), Name = "Namibia" }, + new { Id = new Guid("d9a21a29-a0e2-71bc-7308-548cc27b19f1"), Name = "Nauru" }, + new { Id = new Guid("2c4ab1fa-60da-7c87-35b3-ac6903455853"), Name = "Nepal" }, + new { Id = new Guid("cb245d05-3293-7315-7ee1-eef8a383319c"), Name = "Netherlands" }, + new { Id = new Guid("472e0e57-77f5-9c34-8e10-a621c97108f7"), Name = "New Zealand" }, + new { Id = new Guid("350dc86e-03b2-2c20-1908-b4de7d179de7"), Name = "Nicaragua" }, + new { Id = new Guid("9b36a6c2-4739-69a2-068b-c0b3c87c6f67"), Name = "Niger" }, + new { Id = new Guid("2ca00749-35c0-511b-9c2c-b53e5a8f0a71"), Name = "Nigeria" }, + new { Id = new Guid("10ef2f04-4d96-5b5e-316f-b373a88731be"), Name = "North Korea" }, + new { Id = new Guid("51c38ab5-0b2b-2994-4eb2-c8e82fe17950"), Name = "North Macedonia" }, + new { Id = new Guid("c1c8ec1f-58ce-3931-7ad7-ad4b55c14a85"), Name = "Norway" }, + new { Id = new Guid("859adf7d-1bf9-87d1-6a9b-4a06ebab6796"), Name = "Oman" }, + new { Id = new Guid("6133196d-26d0-5f8e-5792-6215aefd668d"), Name = "Pakistan" }, + new { Id = new Guid("3881b3b6-a332-3d35-8a73-43acfbf9045b"), Name = "Palau" }, + new { Id = new Guid("9a79f7fb-27a4-811b-88c3-9de906521017"), Name = "Palestine State" }, + new { Id = new Guid("f5b0c42e-3b0e-3808-1922-fdae58ea075c"), Name = "Panama" }, + new { Id = new Guid("16ff3157-a061-2e81-5ca6-b71e3619376e"), Name = "Papua New Guinea" }, + new { Id = new Guid("1b84f08e-8e6d-5779-967c-a162c2307153"), Name = "Paraguay" }, + new { Id = new Guid("f625e01e-4a07-7ff3-0a7e-ce6e27b586ff"), Name = "Peru" }, + new { Id = new Guid("19be2963-072b-2f4b-0f85-558d90ee1770"), Name = "Philippines" }, + new { Id = new Guid("fc432d5c-66dd-5660-8186-da84b4e164a0"), Name = "Poland" }, + new { Id = new Guid("2b1486b9-0cfa-2dc6-3f70-4ee2f11955b4"), Name = "Portugal" }, + new { Id = new Guid("47ac0edf-9beb-345b-0e4b-bccb0c1a2032"), Name = "Qatar" }, + new { Id = new Guid("d5cb2660-9af9-0385-8a99-52871814043d"), Name = "Romania" }, + new { Id = new Guid("6fa56ae5-2091-39c4-0010-ae74ffa2a0f2"), Name = "Russia" }, + new { Id = new Guid("362ac8d8-6fba-a641-8272-958f9e553b54"), Name = "Rwanda" }, + new { Id = new Guid("c3553d72-9d17-04d8-6692-12a5a7250008"), Name = "Saint Kitts and Nevis" }, + new { Id = new Guid("fd3ab0e3-279a-107a-88e0-93ee1bb45ffb"), Name = "Saint Lucia" }, + new { Id = new Guid("420b0acb-a1b0-27e5-45fc-3c6e96f25361"), Name = "Saint Vincent and the Grenadines" }, + new { Id = new Guid("37425b6c-2940-370c-805d-27cb7af97f88"), Name = "Samoa" }, + new { Id = new Guid("b6667319-a515-1cf5-7392-92e15c52438d"), Name = "San Marino" }, + new { Id = new Guid("75c8834a-67e9-9ee5-65bb-e2db6a937074"), Name = "Sao Tome and Principe" }, + new { Id = new Guid("1e9ab108-4d4b-1812-21d9-5c90d7d897ea"), Name = "Saudi Arabia" }, + new { Id = new Guid("3cb2d6c7-8bb5-191d-183d-b201063d5491"), Name = "Senegal" }, + new { Id = new Guid("1995e756-0e82-9463-1627-feeb766d2d0d"), Name = "Serbia" }, + new { Id = new Guid("1ff73b0c-27c4-9d4a-3d5b-ec77a6612d56"), Name = "Seychelles" }, + new { Id = new Guid("6df0d56f-3b4e-33fe-6d5f-74da585ea5d0"), Name = "Sierra Leone" }, + new { Id = new Guid("912f9045-7a3b-151b-2c06-19f899d1787a"), Name = "Singapore" }, + new { Id = new Guid("53e7d0fc-816f-59dd-7b4a-0ade62330830"), Name = "Slovakia" }, + new { Id = new Guid("a522756f-2fd9-48d1-7443-dd1546fd8b37"), Name = "Slovenia" }, + new { Id = new Guid("5f47ed3b-0b54-95aa-93e8-16bf035c9247"), Name = "Solomon Islands" }, + new { Id = new Guid("b58da294-9556-8ece-163f-3d89514017a7"), Name = "Somalia" }, + new { Id = new Guid("03a82f52-22d5-8259-1072-429791258b72"), Name = "South Africa" }, + new { Id = new Guid("55cafe8e-1585-278e-5736-bab16f1b1b8d"), Name = "South Korea" }, + new { Id = new Guid("9d2d676f-97fb-952c-06a9-09d4e9696631"), Name = "South Sudan" }, + new { Id = new Guid("534a826b-70ef-2128-1a4c-52e23b7d5447"), Name = "Spain" }, + new { Id = new Guid("932a43ac-56dc-951e-7de5-996314e92e9c"), Name = "Sri Lanka" }, + new { Id = new Guid("6c4a7b61-3bfd-4a47-95a3-0ca86c72521f"), Name = "Sudan" }, + new { Id = new Guid("9a0a2c1d-3475-3554-9d18-b11946af6086"), Name = "Suriname" }, + new { Id = new Guid("896ef05e-0fe4-92a6-229e-63d7a26e0625"), Name = "Sweden" }, + new { Id = new Guid("bb0b41a9-7363-5922-9ce0-939412a9036e"), Name = "Switzerland" }, + new { Id = new Guid("7b9c857e-3fbd-3d19-38cf-f204da39890c"), Name = "Syria" }, + new { Id = new Guid("d7cd92d3-4522-5a78-3533-816fc61a293f"), Name = "Tajikistan" }, + new { Id = new Guid("fa81562d-1bc4-944c-86a9-6cc5af502265"), Name = "Tanzania" }, + new { Id = new Guid("439e3108-0908-4d90-6f5c-1974362b74b1"), Name = "Thailand" }, + new { Id = new Guid("47e7cc9c-4368-8ab3-056b-66a1351c24cd"), Name = "Timor-Leste" }, + new { Id = new Guid("492a6eb7-5ca3-8e50-3559-c71205b71c3b"), Name = "Togo" }, + new { Id = new Guid("e376c876-6960-270c-8744-583fb7a72f55"), Name = "Tonga" }, + new { Id = new Guid("2f7c276f-4d0d-9368-4132-c04149924bb5"), Name = "Trinidad and Tobago" }, + new { Id = new Guid("93ba288b-2a62-1880-1e20-aeb705431890"), Name = "Tunisia" }, + new { Id = new Guid("c576d8f0-5300-2436-2d17-48b699214549"), Name = "Turkey" }, + new { Id = new Guid("a9c5d1ec-319a-085c-1ee3-80ae15bd27ed"), Name = "Turkmenistan" }, + new { Id = new Guid("95938676-73d1-2031-219d-dc67ba314bdf"), Name = "Tuvalu" }, + new { Id = new Guid("2cfae83c-0f45-72d1-4624-5af1e10e6147"), Name = "Uganda" }, + new { Id = new Guid("1b837dfa-0bda-54f3-918a-beef19f691e5"), Name = "Ukraine" }, + new { Id = new Guid("f7675604-4744-6d6f-a077-67a3e0c85324"), Name = "United Arab Emirates" }, + new { Id = new Guid("8f9ec4fb-916f-90ea-5162-f486a0fc0893"), Name = "United Kingdom" }, + new { Id = new Guid("ca111c84-983b-4525-054c-d14dee3a422c"), Name = "United States of America" }, + new { Id = new Guid("ee06c3ba-4e8c-95c3-88da-6be3f23b9aaa"), Name = "Uruguay" }, + new { Id = new Guid("2f02c930-1d71-8ca6-49e7-0d3679a522ea"), Name = "Uzbekistan" }, + new { Id = new Guid("28dc2817-94b4-955d-10bc-6a8793dd386c"), Name = "Vanuatu" }, + new { Id = new Guid("9c9e3bca-5880-437f-4f18-d6998d90173f"), Name = "Venezuela" }, + new { Id = new Guid("5a3893d1-1e36-310c-7633-8f36ffa26315"), Name = "Vietnam" }, + new { Id = new Guid("a2689ae3-3643-6250-a748-8f055cc72da8"), Name = "Yemen" }, + new { Id = new Guid("be447a08-0a85-5779-8c65-cf15c2c9a5a8"), Name = "Zambia" }, + new { Id = new Guid("c776f397-182b-6d0d-09f2-4e440dc093d3"), Name = "Zimbabwe" } + ]; } \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/CreateCompanyHandlerTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/CreateCompanyHandlerTests.cs index 6c4b2ef..f92abb0 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/CreateCompanyHandlerTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/CreateCompanyHandlerTests.cs @@ -4,11 +4,7 @@ using Monaco.Template.Backend.Common.Tests; using Monaco.Template.Backend.Common.Tests.Factories; using Moq; -using System; -using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -using System.Threading; -using System.Threading.Tasks; using Xunit; namespace Monaco.Template.Backend.Application.Tests.Features.Company; diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/CreateCompanyValidatorTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/CreateCompanyValidatorTests.cs index 61e6cfc..680c66b 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/CreateCompanyValidatorTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/CreateCompanyValidatorTests.cs @@ -6,10 +6,7 @@ using Monaco.Template.Backend.Common.Tests; using Monaco.Template.Backend.Common.Tests.Factories; using Moq; -using System; -using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -using System.Threading.Tasks; using Xunit; namespace Monaco.Template.Backend.Application.Tests.Features.Company; diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/DeleteCompanyHandlerTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/DeleteCompanyHandlerTests.cs index 4c4aaee..004cbf6 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/DeleteCompanyHandlerTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/DeleteCompanyHandlerTests.cs @@ -13,16 +13,7 @@ using Monaco.Template.Backend.Domain.Model; #endif using Moq; -using System; -#if (!excludeFilesSupport) -using System.Collections.Generic; -#endif using System.Diagnostics.CodeAnalysis; -#if (!excludeFilesSupport) -using System.Linq; -#endif -using System.Threading; -using System.Threading.Tasks; using Xunit; namespace Monaco.Template.Backend.Application.Tests.Features.Company; diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/DeleteCompanyValidatorTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/DeleteCompanyValidatorTests.cs index 376c216..50e5eca 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/DeleteCompanyValidatorTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/DeleteCompanyValidatorTests.cs @@ -1,6 +1,4 @@ -using System; -using System.Diagnostics.CodeAnalysis; -using System.Threading.Tasks; +using System.Diagnostics.CodeAnalysis; using FluentAssertions; using FluentValidation; using FluentValidation.TestHelper; diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/EditCompanyHandlerTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/EditCompanyHandlerTests.cs index 14c5dde..e331514 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/EditCompanyHandlerTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/EditCompanyHandlerTests.cs @@ -5,10 +5,7 @@ using Monaco.Template.Backend.Common.Tests.Factories; using Monaco.Template.Backend.Domain.Model; using Moq; -using System; using System.Diagnostics.CodeAnalysis; -using System.Threading; -using System.Threading.Tasks; using Xunit; namespace Monaco.Template.Backend.Application.Tests.Features.Company; diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/EditCompanyValidatorTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/EditCompanyValidatorTests.cs index 271d521..e87c9eb 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/EditCompanyValidatorTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/EditCompanyValidatorTests.cs @@ -7,10 +7,7 @@ using Monaco.Template.Backend.Common.Tests; using Monaco.Template.Backend.Common.Tests.Factories; using Moq; -using System; -using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -using System.Threading.Tasks; using Xunit; namespace Monaco.Template.Backend.Application.Tests.Features.Company; diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/GetCompanyByIdTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/GetCompanyByIdTests.cs index 892fd32..f6a9912 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/GetCompanyByIdTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/GetCompanyByIdTests.cs @@ -1,8 +1,4 @@ -using System; -using System.Diagnostics.CodeAnalysis; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; +using System.Diagnostics.CodeAnalysis; using FluentAssertions; using Monaco.Template.Backend.Application.Features.Company; using Monaco.Template.Backend.Application.Infrastructure.Context; diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/GetCompanyPageTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/GetCompanyPageTests.cs index 0792a2b..e4c0b52 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/GetCompanyPageTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/GetCompanyPageTests.cs @@ -6,11 +6,7 @@ using Monaco.Template.Backend.Common.Tests; using Monaco.Template.Backend.Common.Tests.Factories; using Moq; -using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; using Xunit; namespace Monaco.Template.Backend.Application.Tests.Features.Company; diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Country/GetCountryByIdTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Country/GetCountryByIdTests.cs index 3ceff11..c12b3b0 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Country/GetCountryByIdTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Country/GetCountryByIdTests.cs @@ -1,8 +1,4 @@ -using System; -using System.Diagnostics.CodeAnalysis; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; +using System.Diagnostics.CodeAnalysis; using FluentAssertions; using Monaco.Template.Backend.Application.Features.Country; using Monaco.Template.Backend.Application.Infrastructure.Context; diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Country/GetCountryListTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Country/GetCountryListTests.cs index b0b392e..4f9d373 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Country/GetCountryListTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Country/GetCountryListTests.cs @@ -1,8 +1,4 @@ -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; +using System.Diagnostics.CodeAnalysis; using FluentAssertions; using Microsoft.Extensions.Primitives; using Monaco.Template.Backend.Application.DTOs; diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/File/CreateFileHandlerTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/File/CreateFileHandlerTests.cs index fdaf862..cf25cb9 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/File/CreateFileHandlerTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/File/CreateFileHandlerTests.cs @@ -5,11 +5,7 @@ using Monaco.Template.Backend.Common.Tests; using Monaco.Template.Backend.Common.Tests.Factories; using Moq; -using System; using System.Diagnostics.CodeAnalysis; -using System.IO; -using System.Threading; -using System.Threading.Tasks; using Xunit; namespace Monaco.Template.Backend.Application.Tests.Features.File; diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/File/CreateFileValidatorTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/File/CreateFileValidatorTests.cs index 466ed01..e2fd6eb 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/File/CreateFileValidatorTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/File/CreateFileValidatorTests.cs @@ -4,8 +4,6 @@ using Monaco.Template.Backend.Application.Features.File; using Moq; using System.Diagnostics.CodeAnalysis; -using System.IO; -using System.Threading.Tasks; using Xunit; namespace Monaco.Template.Backend.Application.Tests.Features.File; diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/CreateProductHandlerTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/CreateProductHandlerTests.cs index 71afec2..bbaa8f5 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/CreateProductHandlerTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/CreateProductHandlerTests.cs @@ -6,12 +6,7 @@ using Monaco.Template.Backend.Common.Tests.Factories; using Monaco.Template.Backend.Domain.Model; using Moq; -using System; -using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; using Xunit; namespace Monaco.Template.Backend.Application.Tests.Features.Product; diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/CreateProductValidatorTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/CreateProductValidatorTests.cs index 28b6c79..6eff43d 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/CreateProductValidatorTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/CreateProductValidatorTests.cs @@ -7,11 +7,7 @@ using Monaco.Template.Backend.Common.Tests.Factories; using Monaco.Template.Backend.Domain.Model; using Moq; -using System; -using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -using System.Linq; -using System.Threading.Tasks; using Xunit; namespace Monaco.Template.Backend.Application.Tests.Features.Product; @@ -268,8 +264,8 @@ public async Task PictureArrayEmptyGeneratesError() { var command = Command with { - Pictures = Array.Empty() - }; + Pictures = [] + }; var sut = new CreateProduct.Validator(_dbContextMock.Object); var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.Pictures)); @@ -285,7 +281,7 @@ public async Task PictureEmptyElementGeneratesError() { var command = Command with { - Pictures = new []{ Guid.Empty } + Pictures = [Guid.Empty] }; var sut = new CreateProduct.Validator(_dbContextMock.Object); @@ -304,7 +300,7 @@ public async Task PicturesWithNonExistingElementGeneratesError() var command = Command with { - Pictures = new[] { Guid.NewGuid() } + Pictures = [Guid.NewGuid()] }; var sut = new CreateProduct.Validator(_dbContextMock.Object); @@ -374,7 +370,7 @@ public async Task DefaultPictureNotExistsGeneratesError() { var command = Command with { - Pictures = new[] { Guid.NewGuid() }, + Pictures = [Guid.NewGuid()], DefaultPictureId = Guid.NewGuid() }; diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/DeleteProductHandlerTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/DeleteProductHandlerTests.cs index 5dd3bc2..939abf3 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/DeleteProductHandlerTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/DeleteProductHandlerTests.cs @@ -6,12 +6,7 @@ using Monaco.Template.Backend.Common.Tests.Factories; using Monaco.Template.Backend.Domain.Model; using Moq; -using System; -using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; using Xunit; namespace Monaco.Template.Backend.Application.Tests.Features.Product; diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/DeleteProductValidatorTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/DeleteProductValidatorTests.cs index 40ef939..24e5039 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/DeleteProductValidatorTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/DeleteProductValidatorTests.cs @@ -7,9 +7,7 @@ using Monaco.Template.Backend.Common.Tests; using Monaco.Template.Backend.Common.Tests.Factories; using Moq; -using System; using System.Diagnostics.CodeAnalysis; -using System.Threading.Tasks; using Xunit; namespace Monaco.Template.Backend.Application.Tests.Features.Product; diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/DownloadProductPictureTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/DownloadProductPictureTests.cs index 64d9963..2883f16 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/DownloadProductPictureTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/DownloadProductPictureTests.cs @@ -7,13 +7,7 @@ using Monaco.Template.Backend.Common.Tests; using Monaco.Template.Backend.Common.Tests.Factories; using Moq; -using System; -using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -using System.IO; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; using Xunit; namespace Monaco.Template.Backend.Application.Tests.Features.Product; diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/EditProductHandlerTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/EditProductHandlerTests.cs index 986b622..718f537 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/EditProductHandlerTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/EditProductHandlerTests.cs @@ -6,12 +6,7 @@ using Monaco.Template.Backend.Common.Tests.Factories; using Monaco.Template.Backend.Domain.Model; using Moq; -using System; using System.Diagnostics.CodeAnalysis; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Monaco.Template.Backend.Common.Tests.Factories.Entities; using Xunit; namespace Monaco.Template.Backend.Application.Tests.Features.Product; diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/EditProductValidatorTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/EditProductValidatorTests.cs index cd47079..b716e3c 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/EditProductValidatorTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/EditProductValidatorTests.cs @@ -8,11 +8,7 @@ using Monaco.Template.Backend.Common.Tests.Factories; using Monaco.Template.Backend.Domain.Model; using Moq; -using System; -using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -using System.Linq; -using System.Threading.Tasks; using Xunit; namespace Monaco.Template.Backend.Application.Tests.Features.Product; @@ -313,8 +309,8 @@ public async Task PictureArrayEmptyGeneratesError() { var command = Command with { - Pictures = Array.Empty() - }; + Pictures = [] + }; var sut = new EditProduct.Validator(_dbContextMock.Object); var validationResult = await sut.TestValidateAsync(command, strategy => strategy.IncludeProperties(cmd => cmd.Pictures)); @@ -330,7 +326,7 @@ public async Task PictureEmptyElementGeneratesError() { var command = Command with { - Pictures = new []{ Guid.Empty } + Pictures = [Guid.Empty] }; var sut = new EditProduct.Validator(_dbContextMock.Object); @@ -349,7 +345,7 @@ public async Task PicturesWithNonExistingElementGeneratesError() var command = Command with { - Pictures = new[] { Guid.NewGuid() } + Pictures = [Guid.NewGuid()] }; var sut = new EditProduct.Validator(_dbContextMock.Object); @@ -419,7 +415,7 @@ public async Task DefaultPictureNotExistsGeneratesError() { var command = Command with { - Pictures = new[] { Guid.NewGuid() }, + Pictures = [Guid.NewGuid()], DefaultPictureId = Guid.NewGuid() }; diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/GetProductByIdTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/GetProductByIdTests.cs index f839c72..b8983ba 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/GetProductByIdTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/GetProductByIdTests.cs @@ -4,12 +4,7 @@ using Monaco.Template.Backend.Common.Tests; using Monaco.Template.Backend.Common.Tests.Factories; using Moq; -using System; -using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; using Xunit; namespace Monaco.Template.Backend.Application.Tests.Features.Product; diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/GetProductPageTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/GetProductPageTests.cs index b189f5b..bd5fe02 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/GetProductPageTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Product/GetProductPageTests.cs @@ -6,12 +6,7 @@ using Monaco.Template.Backend.Common.Tests; using Monaco.Template.Backend.Common.Tests.Factories; using Moq; -using System; -using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; using Xunit; namespace Monaco.Template.Backend.Application.Tests.Features.Product; diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Monaco.Template.Backend.Application.Tests.csproj b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Monaco.Template.Backend.Application.Tests.csproj index b9195a4..2ce43ec 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Monaco.Template.Backend.Application.Tests.csproj +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Monaco.Template.Backend.Application.Tests.csproj @@ -3,7 +3,7 @@ net8.0 enable - + enable false diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Services/FileServiceTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Services/FileServiceTests.cs index 1693616..4d404da 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Services/FileServiceTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Services/FileServiceTests.cs @@ -7,11 +7,7 @@ using Monaco.Template.Backend.Domain.Model; using Moq; using SkiaSharp; -using System; using System.Diagnostics.CodeAnalysis; -using System.IO; -using System.Threading; -using System.Threading.Tasks; using Xunit; using File = Monaco.Template.Backend.Domain.Model.File; diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Api.Application/MediatorExtensions.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Api.Application/MediatorExtensions.cs index b774257..48f6d5c 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Api.Application/MediatorExtensions.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Api.Application/MediatorExtensions.cs @@ -136,7 +136,7 @@ public static async Task> ExecuteCommandAsync(thi if (result.ValidationResult.IsValid) { - var parameters = (uriParams ?? Array.Empty()).Append(result.Result!); + var parameters = (uriParams ?? []).Append(result.Result!); return new CreatedResult(string.Format(resultUri, parameters.ToArray()), result.Result); } diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Api/Swagger/AuthorizeCheckOperationFilter.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Api/Swagger/AuthorizeCheckOperationFilter.cs index 621714b..7e58249 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Api/Swagger/AuthorizeCheckOperationFilter.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Api/Swagger/AuthorizeCheckOperationFilter.cs @@ -39,9 +39,6 @@ public void Apply(OpenApiOperation operation, OperationFilterContext context) } }; - operation.Security = new List - { - new() { [oAuthScheme] = new List { _audience } } - }; + operation.Security = [new OpenApiSecurityRequirement { [oAuthScheme] = new List { _audience } }]; } } \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.ApiGateway/Auth/Scopes.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.ApiGateway/Auth/Scopes.cs index d8f0b3b..06c0732 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.ApiGateway/Auth/Scopes.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.ApiGateway/Auth/Scopes.cs @@ -9,13 +9,13 @@ public static class Scopes public const string FilesWrite = "files:write"; #endif - public static List List => new() - { - CompaniesRead, - CompaniesWrite, - #if (!excludeFilesSupport) - FilesRead, - FilesWrite - #endif - }; + public static List List => + [ + CompaniesRead, + CompaniesWrite, + #if (!excludeFilesSupport) + FilesRead, + FilesWrite + #endif + ]; } \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.BlobStorage.Tests/BlobStorageServiceTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.BlobStorage.Tests/BlobStorageServiceTests.cs index c4cf2a9..a336b5f 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.BlobStorage.Tests/BlobStorageServiceTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.BlobStorage.Tests/BlobStorageServiceTests.cs @@ -2,7 +2,6 @@ using FluentAssertions; using Moq; using Xunit; -using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; namespace Monaco.Template.Backend.Common.BlobStorage.Tests; diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.BlobStorage.Tests/Monaco.Template.Backend.Common.BlobStorage.Tests.csproj b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.BlobStorage.Tests/Monaco.Template.Backend.Common.BlobStorage.Tests.csproj index 8176c5e..8e4c642 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.BlobStorage.Tests/Monaco.Template.Backend.Common.BlobStorage.Tests.csproj +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.BlobStorage.Tests/Monaco.Template.Backend.Common.BlobStorage.Tests.csproj @@ -3,6 +3,7 @@ net8.0 enable + enable false diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Domain.Tests/DomainEventTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Domain.Tests/DomainEventTests.cs index 678da62..ebf62f2 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Domain.Tests/DomainEventTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Domain.Tests/DomainEventTests.cs @@ -1,7 +1,6 @@ using FluentAssertions; using Monaco.Template.Backend.Common.Domain.Model; using Monaco.Template.Backend.Common.Tests.Factories; -using System; using System.Diagnostics.CodeAnalysis; using Xunit; diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Domain.Tests/EntityTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Domain.Tests/EntityTests.cs index dbcd066..e60a510 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Domain.Tests/EntityTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Domain.Tests/EntityTests.cs @@ -3,10 +3,7 @@ using Monaco.Template.Backend.Common.Domain.Model; using Monaco.Template.Backend.Common.Tests.Factories; using Moq; -using System; -using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -using System.Linq; using Xunit; namespace Monaco.Template.Backend.Common.Domain.Tests; diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Domain.Tests/EnumerationTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Domain.Tests/EnumerationTests.cs index 13bb95e..5901a72 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Domain.Tests/EnumerationTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Domain.Tests/EnumerationTests.cs @@ -3,7 +3,6 @@ using Monaco.Template.Backend.Common.Domain.Model; using Monaco.Template.Backend.Common.Tests.Factories; using Moq; -using System; using System.Diagnostics.CodeAnalysis; using Xunit; diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Domain.Tests/Monaco.Template.Backend.Common.Domain.Tests.csproj b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Domain.Tests/Monaco.Template.Backend.Common.Domain.Tests.csproj index beffc76..8460225 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Domain.Tests/Monaco.Template.Backend.Common.Domain.Tests.csproj +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Domain.Tests/Monaco.Template.Backend.Common.Domain.Tests.csproj @@ -3,7 +3,7 @@ net8.0 enable - + enable false diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Domain.Tests/PageTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Domain.Tests/PageTests.cs index d554cb6..5705417 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Domain.Tests/PageTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Domain.Tests/PageTests.cs @@ -1,7 +1,6 @@ using FluentAssertions; using Monaco.Template.Backend.Common.Domain.Model; using Monaco.Template.Backend.Common.Tests.Factories; -using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using Xunit; diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Domain.Tests/ValueObjectTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Domain.Tests/ValueObjectTests.cs index f265f79..4447c19 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Domain.Tests/ValueObjectTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Domain.Tests/ValueObjectTests.cs @@ -1,7 +1,6 @@ using FluentAssertions; using Monaco.Template.Backend.Common.Domain.Model; using Monaco.Template.Backend.Common.Tests.Factories; -using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using Xunit; diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Domain/Model/Entity.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Domain/Model/Entity.cs index 36ef5a9..985447f 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Domain/Model/Entity.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Domain/Model/Entity.cs @@ -19,7 +19,7 @@ protected Entity(Guid id) : this() public virtual Guid Id { get; } - private readonly List _domainEvents = new(); + private readonly List _domainEvents = []; /// /// List that holds Domain Events for this entity instance /// diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Infrastructure/Context/Extensions/FilterExtensions.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Infrastructure/Context/Extensions/FilterExtensions.cs index 20b7690..a86fef8 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Infrastructure/Context/Extensions/FilterExtensions.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Infrastructure/Context/Extensions/FilterExtensions.cs @@ -126,7 +126,7 @@ private static Expression> GetOperationExpression(string fieldK else // otherwise searches with Contains { expression = Expression.Call(expression, - type.GetMethod(nameof(string.Contains), new[] { type })!, + type.GetMethod(nameof(string.Contains), [type])!, Expression.Constant(Convert.ChangeType(strValue, type))); if (not) expression = Expression.Not(expression); } diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Infrastructure/Context/Extensions/OperationsExtensions.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Infrastructure/Context/Extensions/OperationsExtensions.cs index 15a42b3..2fb12a7 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Infrastructure/Context/Extensions/OperationsExtensions.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Infrastructure/Context/Extensions/OperationsExtensions.cs @@ -26,13 +26,13 @@ public static Task ExistsAsync(this DbContext dbContext, public static async Task GetAsync(this DbContext dbContext, Guid id, CancellationToken cancellationToken) where T : class => - (await dbContext.Set().FindAsync(new object?[] { id }, cancellationToken))!; + (await dbContext.Set().FindAsync([id], cancellationToken))!; public static IQueryable Set(this DbContext context, Type t) => (IQueryable)context.GetType() .GetMethod("Set", Type.EmptyTypes)? .MakeGenericMethod(t) - .Invoke(context, Array.Empty())!; + .Invoke(context, [])!; public static async Task> GetListByIdsAsync(this DbContext dbContext, Guid[] items, @@ -41,5 +41,5 @@ public static async Task> GetListByIdsAsync(this DbContext dbContext, ? await dbContext.Set() .Where(x => items.Contains(x.Id)) .ToListAsync(cancellationToken) - : new(); + : []; } \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Infrastructure/Context/Extensions/SortingExtensions.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Infrastructure/Context/Extensions/SortingExtensions.cs index 8ebafd4..fe21492 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Infrastructure/Context/Extensions/SortingExtensions.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Infrastructure/Context/Extensions/SortingExtensions.cs @@ -64,7 +64,7 @@ private static IOrderedQueryable GetOrderedQuery(this IQueryable source var methodCallExpression = (MethodCallExpression)sortMethod.Body; var method = methodCallExpression.Method.GetGenericMethodDefinition(); var genericSortMethod = method.MakeGenericMethod(typeof(T), bodyExpression.Type); - return (IOrderedQueryable)genericSortMethod.Invoke(source, new object[] { source, sortLambda })!; + return (IOrderedQueryable)genericSortMethod.Invoke(source, [source, sortLambda])!; } private static IOrderedEnumerable GetOrderedQuery(this IEnumerable source, Expression> expression, bool ascending, bool firstSort) @@ -83,7 +83,7 @@ private static IOrderedEnumerable GetOrderedQuery(this IEnumerable sour var meth = methodCallExpression.Method.GetGenericMethodDefinition(); var genericSortMethod = meth.MakeGenericMethod(typeof(T), bodyExpression.Type); - return (IOrderedEnumerable)genericSortMethod.Invoke(source, new object[] { source, sortLambda.Compile() })!; + return (IOrderedEnumerable)genericSortMethod.Invoke(source, [source, sortLambda.Compile()])!; } private static Dictionary ProcessSortParam(IEnumerable sortFields, diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/CompanyTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/CompanyTests.cs index c7ce06f..1b77a8a 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/CompanyTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/CompanyTests.cs @@ -2,9 +2,6 @@ using Monaco.Template.Backend.Common.Tests.Factories; using Monaco.Template.Backend.Domain.Model; using System.Diagnostics.CodeAnalysis; -#if (!excludeFilesSupport) -using System.Linq; -#endif using Xunit; namespace Monaco.Template.Backend.Domain.Tests; diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/DocumentTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/DocumentTests.cs index 04bbce6..792a847 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/DocumentTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/DocumentTests.cs @@ -1,7 +1,5 @@ -using System; -using Monaco.Template.Backend.Domain.Model; +using Monaco.Template.Backend.Domain.Model; using System.Diagnostics.CodeAnalysis; -using System.Security.Cryptography; using FluentAssertions; using Monaco.Template.Backend.Common.Tests.Factories; using Xunit; diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/ImageTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/ImageTests.cs index e0549ae..d53bb7e 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/ImageTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/ImageTests.cs @@ -1,5 +1,4 @@ -using System; -using Monaco.Template.Backend.Domain.Model; +using Monaco.Template.Backend.Domain.Model; using System.Diagnostics.CodeAnalysis; using System.Security.Cryptography; using FluentAssertions; diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/Monaco.Template.Backend.Domain.Tests.csproj b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/Monaco.Template.Backend.Domain.Tests.csproj index 8928880..ccde562 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/Monaco.Template.Backend.Domain.Tests.csproj +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/Monaco.Template.Backend.Domain.Tests.csproj @@ -3,7 +3,7 @@ net8.0 enable - + enable false diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/ProductTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/ProductTests.cs index 6885812..2876591 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/ProductTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/ProductTests.cs @@ -2,7 +2,6 @@ using Monaco.Template.Backend.Common.Tests.Factories; using Monaco.Template.Backend.Domain.Model; using System.Diagnostics.CodeAnalysis; -using System.Linq; using Xunit; namespace Monaco.Template.Backend.Domain.Tests; diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/Company.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/Company.cs index 117b0e7..dd539ff 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/Company.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/Company.cs @@ -31,7 +31,7 @@ public Company(string name, public Address? Address { get; private set; } #if (!excludeFilesSupport) - private readonly List _products = new(); + private readonly List _products = []; public virtual IReadOnlyList Products => _products; #endif diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/Product.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/Product.cs index a9ad034..fbf684f 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/Product.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain/Model/Product.cs @@ -24,7 +24,7 @@ public Product(string title, public Guid CompanyId { get; } public virtual Company Company { get; private set; } - private readonly List _pictures = new(); + private readonly List _pictures = []; public virtual IReadOnlyList Pictures => _pictures; public Guid DefaultPictureId { get; } From feb0f1ebb46eb2fb503133c8df62ff93339cdf73 Mon Sep 17 00:00:00 2001 From: CesarD Date: Thu, 21 Dec 2023 09:29:43 +0100 Subject: [PATCH 15/21] CHORE: Cleanup. --- .../Monaco.Template.Backend.Application.csproj | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Monaco.Template.Backend.Application.csproj b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Monaco.Template.Backend.Application.csproj index 90d16df..4c99955 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Monaco.Template.Backend.Application.csproj +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Monaco.Template.Backend.Application.csproj @@ -25,8 +25,4 @@ - - - - From 364acea0ca0b35cf993255e09747dae3a019fd2d Mon Sep 17 00:00:00 2001 From: CesarD Date: Thu, 21 Dec 2023 09:31:41 +0100 Subject: [PATCH 16/21] CHORE: More cleanup. --- .../Monaco.Template.Backend.Application.Tests.csproj | 6 +----- .../Monaco.Template.Backend.Common.Api.Application.csproj | 4 ---- .../Monaco.Template.Backend.Common.Infrastructure.csproj | 6 ------ 3 files changed, 1 insertion(+), 15 deletions(-) diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Monaco.Template.Backend.Application.Tests.csproj b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Monaco.Template.Backend.Application.Tests.csproj index 2ce43ec..a3b3ea0 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Monaco.Template.Backend.Application.Tests.csproj +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Monaco.Template.Backend.Application.Tests.csproj @@ -1,4 +1,4 @@ - + net8.0 @@ -26,8 +26,4 @@ - - - - diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Api.Application/Monaco.Template.Backend.Common.Api.Application.csproj b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Api.Application/Monaco.Template.Backend.Common.Api.Application.csproj index c7e81a7..eef00dd 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Api.Application/Monaco.Template.Backend.Common.Api.Application.csproj +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Api.Application/Monaco.Template.Backend.Common.Api.Application.csproj @@ -28,8 +28,4 @@ - - - - diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Infrastructure/Monaco.Template.Backend.Common.Infrastructure.csproj b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Infrastructure/Monaco.Template.Backend.Common.Infrastructure.csproj index e43332d..f5cf9e0 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Infrastructure/Monaco.Template.Backend.Common.Infrastructure.csproj +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Common.Infrastructure/Monaco.Template.Backend.Common.Infrastructure.csproj @@ -18,12 +18,6 @@ $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb - - - - - - From 2a85556421d4ebcc0b0d05d6e3c46e92bebd32e7 Mon Sep 17 00:00:00 2001 From: CesarD Date: Thu, 21 Dec 2023 13:09:06 +0100 Subject: [PATCH 17/21] CHORE: Optimizing company retrieval query. --- .../Features/Product/Extensions/ProductDataExtensions.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/Extensions/ProductDataExtensions.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/Extensions/ProductDataExtensions.cs index b554617..55aa351 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/Extensions/ProductDataExtensions.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application/Features/Product/Extensions/ProductDataExtensions.cs @@ -1,6 +1,5 @@ using Microsoft.EntityFrameworkCore; using Monaco.Template.Backend.Application.Infrastructure.Context; -using Monaco.Template.Backend.Common.Infrastructure.Context.Extensions; namespace Monaco.Template.Backend.Application.Features.Product.Extensions; @@ -11,7 +10,9 @@ public static class ProductDataExtensions Guid[] pictures, CancellationToken cancellationToken) { - var company = await dbContext.GetAsync(companyId, cancellationToken); + var company = await dbContext.Set() + .Include(x => x.Products) + .SingleAsync(x => x.Id == companyId, cancellationToken); var pics = await dbContext.Set() .Include(x => x.Thumbnail) .Where(x => pictures.Contains(x.Id)) From 37a95c0035de4429c6f0deb8c0b8c8b8aa87b22f Mon Sep 17 00:00:00 2001 From: CesarD Date: Fri, 22 Dec 2023 19:21:56 +0100 Subject: [PATCH 18/21] FIX: Corrected command mock scope and naming --- .../Company/CreateCompanyValidatorTests.cs | 58 +++++++++---------- .../Company/DeleteCompanyValidatorTests.cs | 6 +- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/CreateCompanyValidatorTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/CreateCompanyValidatorTests.cs index 680c66b..46418fd 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/CreateCompanyValidatorTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/CreateCompanyValidatorTests.cs @@ -16,14 +16,14 @@ namespace Monaco.Template.Backend.Application.Tests.Features.Company; public class CreateCompanyValidatorTests { private readonly Mock _dbContextMock = new(); - private readonly CreateCompany.Command _command = new(It.IsAny(), // Name - It.IsAny(), // Email - It.IsAny(), // WebsiteUrl - It.IsAny(), // Street - It.IsAny(), // City - It.IsAny(), // County - It.IsAny(), // PostCode - It.IsAny()); // CountryId + private static readonly CreateCompany.Command Command = new(It.IsAny(), // Name + It.IsAny(), // Email + It.IsAny(), // WebsiteUrl + It.IsAny(), // Street + It.IsAny(), // City + It.IsAny(), // County + It.IsAny(), // PostCode + It.IsAny()); // CountryId [Fact(DisplayName = "Validator's rule level cascade mode is 'Stop'")] public void ValidatorRuleLevelCascadeModeIsStop() @@ -36,7 +36,7 @@ public void ValidatorRuleLevelCascadeModeIsStop() [Fact(DisplayName = "Name being valid does not generate validation error")] public async Task NameDoesNotGenerateErrorWhenValid() { - var command = _command with { Name = new string(It.IsAny(), 100) }; + var command = Command with { Name = new string(It.IsAny(), 100) }; _dbContextMock.CreateAndSetupDbSetMock(new List()); @@ -49,7 +49,7 @@ public async Task NameDoesNotGenerateErrorWhenValid() [Fact(DisplayName = "Name with empty value generates validation error")] public async Task NameIsEmptyGeneratesError() { - var command = _command with { Name = string.Empty }; + var command = Command with { Name = string.Empty }; var sut = new CreateCompany.Validator(_dbContextMock.Object); var validationResult = await sut.TestValidateAsync(command, s => s.IncludeProperties(x => x.Name)); @@ -63,7 +63,7 @@ public async Task NameIsEmptyGeneratesError() [Fact(DisplayName = "Name with long value generates validation error")] public async Task NameWithLongValueGeneratesError() { - var command = _command with { Name = new string(It.IsAny(), 101) }; + var command = Command with { Name = new string(It.IsAny(), 101) }; var sut = new CreateCompany.Validator(_dbContextMock.Object); var validationResult = await sut.TestValidateAsync(command, s => s.IncludeProperties(x => x.Name)); @@ -79,7 +79,7 @@ public async Task NameWithLongValueGeneratesError() [AnonymousData] public async Task NameAlreadyExistsGeneratesError(Domain.Model.Company company) { - var command = _command with { Name = company.Name }; + var command = Command with { Name = company.Name }; _dbContextMock.CreateAndSetupDbSetMock([company]); @@ -95,7 +95,7 @@ public async Task NameAlreadyExistsGeneratesError(Domain.Model.Company company) [Fact(DisplayName = "Email being valid does not generate validation error")] public async Task EmailIsValidDoesNotGenerateError() { - var command = _command with { Email = "valid@email.com" }; + var command = Command with { Email = "valid@email.com" }; _dbContextMock.CreateAndSetupDbSetMock(new List()); @@ -108,7 +108,7 @@ public async Task EmailIsValidDoesNotGenerateError() [Fact(DisplayName = "Email with empty value generates validation error")] public async Task EmailIsEmptyGeneratesError() { - var command = _command with { Email = string.Empty }; + var command = Command with { Email = string.Empty }; var sut = new CreateCompany.Validator(_dbContextMock.Object); var validationResult = await sut.TestValidateAsync(command, s => s.IncludeProperties(x => x.Email)); @@ -123,7 +123,7 @@ public async Task EmailIsEmptyGeneratesError() [AnonymousData] public async Task EmailAddressIsInvalidGeneratesError(string email) { - var command = _command with { Email = email }; + var command = Command with { Email = email }; var sut = new CreateCompany.Validator(_dbContextMock.Object); var validationResult = await sut.TestValidateAsync(command, s => s.IncludeProperties(x => x.Email)); @@ -137,7 +137,7 @@ public async Task EmailAddressIsInvalidGeneratesError(string email) [Fact(DisplayName = "Website URL with long value generates validation error")] public async Task WebsiteUrlWithLongValueGeneratesError() { - var command = _command with { WebSiteUrl = new string(It.IsAny(), 301) }; + var command = Command with { WebSiteUrl = new string(It.IsAny(), 301) }; var sut = new CreateCompany.Validator(_dbContextMock.Object); var validationResult = await sut.TestValidateAsync(command, s => s.IncludeProperties(x => x.WebSiteUrl)); @@ -152,7 +152,7 @@ public async Task WebsiteUrlWithLongValueGeneratesError() [Fact(DisplayName = "Website URL with empty value does not generate validation error")] public async Task WebsiteUrlWithEmptyValueDoesNotGenerateError() { - var command = _command with { WebSiteUrl = string.Empty }; + var command = Command with { WebSiteUrl = string.Empty }; var sut = new CreateCompany.Validator(_dbContextMock.Object); var validationResult = await sut.TestValidateAsync(command, s => s.IncludeProperties(x => x.WebSiteUrl)); @@ -163,7 +163,7 @@ public async Task WebsiteUrlWithEmptyValueDoesNotGenerateError() [Fact(DisplayName = "Street with long value generates validation error")] public async Task StreetWithLongValueGeneratesError() { - var command = _command with { Street = new string(It.IsAny(), 101) }; + var command = Command with { Street = new string(It.IsAny(), 101) }; var validator = new CreateCompany.Validator(_dbContextMock.Object); var validationResult = await validator.TestValidateAsync(command, s => s.IncludeProperties(x => x.Street)); @@ -178,7 +178,7 @@ public async Task StreetWithLongValueGeneratesError() [Fact(DisplayName = "Street with empty value does not generate validation error")] public async Task StreetWithEmptyValueDoesNotGenerateError() { - var command = _command with { Street = string.Empty }; + var command = Command with { Street = string.Empty }; var sut = new CreateCompany.Validator(_dbContextMock.Object); var validationResult = await sut.TestValidateAsync(command, s => s.IncludeProperties(x => x.Street)); @@ -189,7 +189,7 @@ public async Task StreetWithEmptyValueDoesNotGenerateError() [Fact(DisplayName = "City with long value generates validation error")] public async Task CityWithLongValueGeneratesError() { - var command = _command with { City = new string(It.IsAny(), 101) }; + var command = Command with { City = new string(It.IsAny(), 101) }; var sut = new CreateCompany.Validator(_dbContextMock.Object); var validationResult = await sut.TestValidateAsync(command, s => s.IncludeProperties(x => x.City)); @@ -204,7 +204,7 @@ public async Task CityWithLongValueGeneratesError() [Fact(DisplayName = "City with empty value does not generate validation error")] public async Task CityWithEmptyValueDoesNotGenerateError() { - var command = _command with { City = string.Empty }; + var command = Command with { City = string.Empty }; var sut = new CreateCompany.Validator(_dbContextMock.Object); var validationResult = await sut.TestValidateAsync(command, s => s.IncludeProperties(x => x.City)); @@ -215,7 +215,7 @@ public async Task CityWithEmptyValueDoesNotGenerateError() [Fact(DisplayName = "County with long value generates validation error")] public async Task CountyWithLongValueGeneratesError() { - var command = _command with { County = new string(It.IsAny(), 101) }; + var command = Command with { County = new string(It.IsAny(), 101) }; var sut = new CreateCompany.Validator(_dbContextMock.Object); var validationResult = await sut.TestValidateAsync(command, s => s.IncludeProperties(x => x.County)); @@ -230,7 +230,7 @@ public async Task CountyWithLongValueGeneratesError() [Fact(DisplayName = "County with empty value does not generate validation error")] public async Task CountyWithEmptyValueDoesNotGenerateError() { - var command = _command with { County = string.Empty }; + var command = Command with { County = string.Empty }; var sut = new CreateCompany.Validator(_dbContextMock.Object); var validationResult = await sut.TestValidateAsync(command, s => s.IncludeProperties(x => x.County)); @@ -241,7 +241,7 @@ public async Task CountyWithEmptyValueDoesNotGenerateError() [Fact(DisplayName = "Postcode with long value generates validation error")] public async Task PostcodeWithLongValueGeneratesError() { - var command = _command with { PostCode = new string(It.IsAny(), 11) }; + var command = Command with { PostCode = new string(It.IsAny(), 11) }; var sut = new CreateCompany.Validator(_dbContextMock.Object); var validationResult = await sut.TestValidateAsync(command, s => s.IncludeProperties(x => x.PostCode)); @@ -256,7 +256,7 @@ public async Task PostcodeWithLongValueGeneratesError() [Fact(DisplayName = "Postcode with empty value does not generate validation error")] public async Task PostcodeWithEmptyValueDoesNotGenerateError() { - var command = _command with { PostCode = string.Empty }; + var command = Command with { PostCode = string.Empty }; var sut = new CreateCompany.Validator(_dbContextMock.Object); var validationResult = await sut.TestValidateAsync(command, s => s.IncludeProperties(x => x.PostCode)); @@ -268,7 +268,7 @@ public async Task PostcodeWithEmptyValueDoesNotGenerateError() [AnonymousData(true)] public async Task CountryIsValidDoesNotGenerateError(Domain.Model.Country country) { - var command = _command with { CountryId = country.Id }; + var command = Command with { CountryId = country.Id }; _dbContextMock.CreateAndSetupDbSetMock(new List()) .CreateAndSetupDbSetMock([country]); @@ -286,7 +286,7 @@ public async Task CountryIsValidDoesNotGenerateError(Domain.Model.Country countr [Fact(DisplayName = "Country with null value does not generate validation error when Address fields null")] public async Task CountryWithNullValueDoesNotGenerateErrorWhenAddressFieldsNull() { - var command = _command with + var command = Command with { Street = null, City = null, @@ -308,7 +308,7 @@ public async Task CountryWithNullValueDoesNotGenerateErrorWhenAddressFieldsNull( [Fact(DisplayName = "Country with null value generates validation error when Address fields present")] public async Task CountryWithNullValueGeneratesErrorWhenAddressFieldsPresent() { - var command = _command with + var command = Command with { Street = string.Empty, City = string.Empty, @@ -331,7 +331,7 @@ public async Task CountryWithNullValueGeneratesErrorWhenAddressFieldsPresent() [AnonymousData] public async Task CountryMustExistValidation(Domain.Model.Country country) { - var command = _command with { CountryId = Guid.NewGuid() }; + var command = Command with { CountryId = Guid.NewGuid() }; _dbContextMock.CreateAndSetupDbSetMock(new List()) .CreateAndSetupDbSetMock(country); diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/DeleteCompanyValidatorTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/DeleteCompanyValidatorTests.cs index 50e5eca..2822626 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/DeleteCompanyValidatorTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Features/Company/DeleteCompanyValidatorTests.cs @@ -17,7 +17,7 @@ namespace Monaco.Template.Backend.Application.Tests.Features.Company; public class DeleteCompanyValidatorTests { private readonly Mock _dbContextMock = new(); - private static readonly DeleteCompany.Command _command = new(It.IsAny()); + private static readonly DeleteCompany.Command Command = new(It.IsAny()); [Fact(DisplayName = "Validator's rule level cascade mode is 'Stop'")] public void ValidatorRuleLevelCascadeModeIsStop() @@ -31,7 +31,7 @@ public void ValidatorRuleLevelCascadeModeIsStop() [AnonymousData] public async Task ExistingCompanyPassesValidationCorrectly(Domain.Model.Company company) { - var command = _command with { Id = company.Id }; + var command = Command with { Id = company.Id }; _dbContextMock.CreateAndSetupDbSetMock(company); @@ -46,7 +46,7 @@ public async Task ExistingCompanyPassesValidationCorrectly(Domain.Model.Company [AnonymousData] public async Task NonExistingCompanyPassesValidationCorrectly(Domain.Model.Company company, Guid id) { - var command = _command with { Id = id }; + var command = Command with { Id = id }; _dbContextMock.CreateAndSetupDbSetMock(company); From 416228770052c3d1b422bcf72f68e28b289d9512 Mon Sep 17 00:00:00 2001 From: CesarD Date: Fri, 22 Dec 2023 19:54:17 +0100 Subject: [PATCH 19/21] FIX: Include missing cases for GpsPostion tests. CHORE: Cleanup. --- .../GpsPositionTests.cs | 16 ++++++++++++-- .../ImageTests.cs | 22 +++++++++---------- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/GpsPositionTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/GpsPositionTests.cs index 419fc62..c70345b 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/GpsPositionTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/GpsPositionTests.cs @@ -10,8 +10,8 @@ namespace Monaco.Template.Backend.Domain.Tests; [Trait("Core Domain Entities", "GpsPosition Entity")] public class GpsPositionTests { - [Fact(DisplayName = "New GpsPosition succeeds")] - public void NewGpsPositionSucceeds() + [Fact(DisplayName = "New GpsPosition with valid values succeeds")] + public void NewGpsPositionWithValidValuesSucceeds() { var latitude = RandomNumberGenerator.GetInt32(-90, 90); var longitude = RandomNumberGenerator.GetInt32(-180, 180); @@ -25,4 +25,16 @@ public void NewGpsPositionSucceeds() .Should() .Be(longitude); } + + [InlineData(-91, 0)] + [InlineData(91, 0)] + [InlineData(0, -181)] + [InlineData(0, 181)] + [Theory(DisplayName = "New GpsPosition with invalid positions fails")] + public void NewGpsPositionWithInvalidPositionsFails(int latitude, int longitude) + { + var sut = () => new GpsPosition(latitude, longitude); + sut.Should() + .Throw(); + } } \ No newline at end of file diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/ImageTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/ImageTests.cs index d53bb7e..0f8ab79 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/ImageTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Domain.Tests/ImageTests.cs @@ -14,15 +14,15 @@ public class ImageTests [Theory(DisplayName = "New Image succeeds")] [AnonymousData] public void NewImageSucceeds(Guid id, - string name, - string extension, - long size, - string contentType, - bool isTemp, - int height, - int width, - DateTime dateTaken, - Image thumbnail) + string name, + string extension, + long size, + string contentType, + bool isTemp, + int height, + int width, + DateTime dateTaken, + Image thumbnail) { var latitude = RandomNumberGenerator.GetInt32(-90, 90); var longitude = RandomNumberGenerator.GetInt32(-180, 180); @@ -61,11 +61,11 @@ public void NewImageSucceeds(Guid id, sut.Dimensions .Should() .NotBeNull(); - sut.Dimensions! + sut.Dimensions .Height .Should() .Be(height); - sut.Dimensions! + sut.Dimensions .Width .Should() .Be(width); From c59ba47218a2458081dce38869e5b8d57f7cd432 Mon Sep 17 00:00:00 2001 From: CesarD Date: Fri, 22 Dec 2023 19:57:39 +0100 Subject: [PATCH 20/21] CHORE: Cleanup --- .../Services/FileServiceTests.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Services/FileServiceTests.cs b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Services/FileServiceTests.cs index 4d404da..2ef82ed 100644 --- a/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Services/FileServiceTests.cs +++ b/src/Content/Backend/Solution/Monaco.Template.Backend.Application.Tests/Services/FileServiceTests.cs @@ -17,7 +17,6 @@ namespace Monaco.Template.Backend.Application.Tests.Services; [Trait("Application Services", "File Service")] public class FileServiceTests { - //private readonly Mock _dbContextMock = new(); private readonly Mock _blobStorageServiceMock = new(); private const string TxtBase64 = "TW9uYWNvIFVuaXQgVGVzdCBGaWxlIGZvciBVcGxvYWQgZG9jdW1lbnQgc3VjY2VlZHMu"; private const string ImgBase64 = "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"; From 60dfb6ca6c7df93e89c013ed8624d08459ae7583 Mon Sep 17 00:00:00 2001 From: CesarD Date: Sat, 23 Dec 2023 16:07:50 +0100 Subject: [PATCH 21/21] CHORE: Cleanup of template's random GUIDs list. --- .../Solution/.template.config/template.json | 97 +++++++++---------- 1 file changed, 46 insertions(+), 51 deletions(-) diff --git a/src/Content/Backend/Solution/.template.config/template.json b/src/Content/Backend/Solution/.template.config/template.json index fd70e89..df61822 100644 --- a/src/Content/Backend/Solution/.template.config/template.json +++ b/src/Content/Backend/Solution/.template.config/template.json @@ -225,12 +225,11 @@ } ], "guids": [ - "8ac1d4e3-61ef-452f-a386-ff3ec448fbff", - "4c76f225-faad-42ec-801b-9ad3b505b7f5", "1095fb23-b2a1-4fd6-bc12-433529eea56e", "8bfe9c37-2620-4156-88b8-286537954c5e", "35484293-234f-40da-b430-a95170ede449", "29dfbc35-3da6-4c68-aa97-5cce06d80917", + "9a19103f-16f7-4668-be54-9a1e7a4f7556", "426a6ab4-95f6-46ac-ab6d-98c4612f74e5", "78120def-b581-4d6b-92d7-1735070acb7f", "bfd5f082-8402-45de-8aba-ebb354bd2858", @@ -250,11 +249,10 @@ "71313461-6a79-47b3-aeb9-5668a88935f2", "1b80e15b-fc20-4b57-a3e5-3b6b3ebda92f", "42e51d47-b82f-4a92-b1e5-cd8be44de6f0", + "d8623b90-59c1-4753-a0e6-f2dbd4305c9b", "42c5f44e-1221-43df-a6f5-4cb2cbef8d72", - "eda2cf1e-7707-458d-b91b-956b9a9be260", "80c3602f-f30d-4f1c-83f4-3e8395bdce25", "c11e0fa2-baf7-44ae-9db9-28ce239042b6", - "b0464d8d-2dbd-461a-9861-38c0747b23a6", "95c05d66-9802-411a-9f82-4b9ab0b34685", "4a5cb9f2-340b-483c-83d7-7324fc61cde4", "05648945-7e90-42ec-a4dc-233fd52cddfe", @@ -283,13 +281,16 @@ "9ec31276-3997-49d7-a842-0a36564a180d", "d34a41a6-7c64-408a-a378-3df70edc20d9", "9522c83e-dbc9-4fde-a61f-9a37a5ab89ee", + "7d7112cb-ffed-4b52-b440-3fdbd7a63c5a", "c443d55b-32e6-47e9-a057-96a7eab1d688", "4857a3cf-f3b0-48ac-94cc-3b2384696b44", "6c345596-0966-47ed-b41b-6ba41319908c", + "2a0fe481-1bc6-4fa4-a02d-0aace321c60e", + "cc450c6d-bf28-45e4-9148-6bb7d4187641", + "53405b4d-d952-47d8-9bc7-8f52a15522e8", "4aee08a5-4691-4a57-9d87-e02dc59fe3ab", "ed97a0b3-c82c-471f-89dc-b48e738381fa", "a1a76a9c-e22e-4e5a-aeec-e71b381ca77e", - "cc450c6d-bf28-45e4-9148-6bb7d4187641", "b6049a46-fbd1-4368-a72b-364c284f01e0", "09fb98e3-c6c4-4151-bf3c-1fbc804b080e", "4cd869a0-9d32-41d7-9769-e611a48cd9a9", @@ -307,6 +308,10 @@ "d5d68e01-42f1-488c-ab96-471596a2b750", "7149fad9-2c54-4b91-975b-e893f9a3d094", "c385dd5b-f501-4fb6-8b16-f381618d090a", + "33ff4854-2aad-4b12-9701-472d0a470c4f", + "805aea0c-522f-4040-b380-c0dac6f55245", + "194ef116-fa08-407a-b535-1d5a60356c7e", + "a0f31e04-653c-4783-8bb0-d4a689c1a36e", "d07a981d-4198-4f2c-be6c-acddc3aa98d3", "1a374de2-4ee9-4869-902a-12f53ad70a45", "070fdddb-0a0a-4a2c-b655-6111c2d653dc", @@ -348,33 +353,46 @@ "160cb3d9-53e2-42e4-bc12-4437386c6367", "6cd2e74a-bf15-4eb2-9e61-f96ff1469358", "8511446d-af34-4a9f-935d-38ab0a062688", - "e0705766-2e91-4735-b9fa-8590bc4faae9", - "c8675fd0-5ddb-4628-82d4-fb063859505e", - "d686d005-b309-4551-bfb1-d71a4f6e0d11", - "7f4c80ee-159d-4ae4-b928-47ac3684d45b", - "0c134675-a8e6-4146-a67e-bdd048197008", - "362c21ef-ac96-43cf-8aba-51e4e16bfa25", - "2533aeba-e2b1-41c4-9d1a-a07cd95fbc18", - "e0a5b338-b3b0-41cf-ae0f-cc4cabe5c1f2", - "b1dbc131-9a1b-4a9c-a985-b7fb4d2a0127", - "adef851f-c566-4eb1-bd8a-692cd3a37704", - "fec3ed3d-3aef-48d2-a699-ed31349121da", - "d5c72026-48b1-4b49-86e3-160fb70fd05a", - "feaf9331-9f7a-4143-9247-27a0ea83f7e9", - "c0336213-5b51-431b-b324-67f774557d54", - "10ce57b2-2a55-43de-914a-56c517f43242", - "c87701f8-addf-44e1-a630-113b6a1871ca", - "dd4429b1-7ecc-4239-9ee3-6dc0c57c7492", - "0d500e1f-2389-45d0-8603-45ff007e0314", - "92d80a4c-c3c1-4a81-a72d-6044516e63f7", - "e05767a5-c141-4f01-b7a2-4efb5e2a26a3", - "82f114ba-9845-4838-9a3b-83bc743050bd", - "f8db2596-279d-4254-b6fe-1b8224d9aee5", + "205ad146-f5c4-4e7a-9419-8a2ea73b19d4", + "547e2363-08f5-4f67-9d5a-fed1bc883af8", + "d3d92cbf-7dea-404b-9b3b-e0e01d01b181", + "d10429c7-e0b3-47a9-ad34-a99eb2c1ae0d", + "718b5472-a9bb-4dba-a1c5-e48f8f5020e5", + "fa17826b-1ce9-4ec0-bff5-da0e1754ab7b", + "ab73883d-7755-458c-99b1-daed2e7d1fc7", + "b3df1fee-f37f-4bff-a6e6-b801324228f0", + "e38db072-8687-40eb-a35b-f9c375da1e01", + "83845f6b-6f32-43db-9de3-71299b05a7ee", + "39089091-f930-4d29-b20c-14e2a7a3a861", + "dfe90700-c265-49d6-8cdc-23855b75ef03", + "1c1a942e-ec7d-4312-aa4f-f0a571da0bce", + "6d7fab52-2a08-46ed-8a19-fe27284baa47", + "fc94d7d8-5d72-47e6-a4de-4c1512d71e16", + "6d7a94da-fbb7-4d20-b41c-472bed514830", + "c5d70775-bdc7-4826-93b1-0ba233ed4e7e", + "9b95767e-b8c7-4570-961d-13e8e59aae7c", + "d7b400a1-9455-46e1-8322-10ce0a3cbd07", + "39c225ca-9d35-42f9-b535-f477b40182df", + "54c70413-4884-4178-a662-96440d3dca17", + "f053015e-b577-42fa-9cd1-5b723eecb72c", + "8ac1d4e3-61ef-452f-a386-ff3ec448fbff", + "4c76f225-faad-42ec-801b-9ad3b505b7f5", "c176b6ce-f931-4ad5-a61e-dad4a01180e6", "2281fe14-3548-4060-b503-3b26bcfd0000", "1724c39a-e51c-46bb-9db9-1227e9edd406", "30b0dc89-e29c-4867-a17d-3af74695ecc0", "0ebc0704-58e0-4202-8cbb-d818a3fdfb5a", + "a2fe74e1-b743-11d0-ae1a-00a0c90fffc3", + "90a6b3a7-c1a3-4009-a288-e2ff89e96fa0", + "a6c744a8-0e4a-4fc6-886a-064283054674", + "1fc202d4-d401-403c-9834-5b218574bb67", + "13b12e3e-c1b4-4539-9371-4fe9a0d523fc", + "116d2292-e37d-41cd-a077-ebacac4c8cc4", + "aa2115a1-9712-457b-9047-dbb71ca2cdd2", + "0174dea2-fdbe-4ef1-8f99-c0beae78880f", + "75188d03-9892-4ae2-abf1-207126247ce5", + "1c4feeaa-4718-4aa9-859d-94ce25d182ba", + "ae27a6b0-e345-4288-96df-5eaf394ee369", "5c064eff-a037-a6a3-06ec-92f662903af3", "a8b54a61-35d8-9b82-76e4-c709561d9952", "9f420922-9842-0d2d-616d-dacee7c25db7", @@ -569,29 +587,6 @@ "5a3893d1-1e36-310c-7633-8f36ffa26315", "a2689ae3-3643-6250-a748-8f055cc72da8", "be447a08-0a85-5779-8c65-cf15c2c9a5a8", - "c776f397-182b-6d0d-09f2-4e440dc093d3", - "d8623b90-59c1-4753-a0e6-f2dbd4305c9b", - "205ad146-f5c4-4e7a-9419-8a2ea73b19d4", - "547e2363-08f5-4f67-9d5a-fed1bc883af8", - "d3d92cbf-7dea-404b-9b3b-e0e01d01b181", - "d10429c7-e0b3-47a9-ad34-a99eb2c1ae0d", - "718b5472-a9bb-4dba-a1c5-e48f8f5020e5", - "fa17826b-1ce9-4ec0-bff5-da0e1754ab7b", - "ab73883d-7755-458c-99b1-daed2e7d1fc7", - "b3df1fee-f37f-4bff-a6e6-b801324228f0", - "e38db072-8687-40eb-a35b-f9c375da1e01", - "83845f6b-6f32-43db-9de3-71299b05a7ee", - "39089091-f930-4d29-b20c-14e2a7a3a861", - "dfe90700-c265-49d6-8cdc-23855b75ef03", - "1c1a942e-ec7d-4312-aa4f-f0a571da0bce", - "6d7fab52-2a08-46ed-8a19-fe27284baa47", - "fc94d7d8-5d72-47e6-a4de-4c1512d71e16", - "6d7a94da-fbb7-4d20-b41c-472bed514830", - "c5d70775-bdc7-4826-93b1-0ba233ed4e7e", - "9b95767e-b8c7-4570-961d-13e8e59aae7c", - "d7b400a1-9455-46e1-8322-10ce0a3cbd07", - "39c225ca-9d35-42f9-b535-f477b40182df", - "54c70413-4884-4178-a662-96440d3dca17", - "f053015e-b577-42fa-9cd1-5b723eecb72c" + "c776f397-182b-6d0d-09f2-4e440dc093d3" ] } \ No newline at end of file