diff --git a/AppyNox.sln b/AppyNox.sln index 10ffbc5d..8a20cee5 100644 --- a/AppyNox.sln +++ b/AppyNox.sln @@ -48,8 +48,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{A21BCC3E EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UnitTests", "UnitTests", "{14E3528C-2F6B-4296-BAD1-E91F32F679EC}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AppyNox.Services.Base.Infrastructure.UnitTest", "src\Services\.BaseService\Tests\UnitTests\AppyNox.Services.Base.Infrastructure.UnitTest\AppyNox.Services.Base.Infrastructure.UnitTest.csproj", "{10490B79-2C4D-4B86-83DF-A2574AD3DE04}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AppyNox.Services.Coupon.Application.UnitTest", "src\Services\CouponService\Tests\UnitTests\AppyNox.Services.Coupon.Application.UnitTest\AppyNox.Services.Coupon.Application.UnitTest.csproj", "{44427A10-C34F-441E-AE0D-EE1B09D991A6}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "IntegrationTests", "IntegrationTests", "{9C257B11-A2A1-4E1E-88DD-845E02E0B60F}" @@ -230,10 +228,6 @@ Global {05B687CB-E54A-4705-955C-5CA6AF7E9F25}.Debug|Any CPU.Build.0 = Debug|Any CPU {05B687CB-E54A-4705-955C-5CA6AF7E9F25}.Release|Any CPU.ActiveCfg = Release|Any CPU {05B687CB-E54A-4705-955C-5CA6AF7E9F25}.Release|Any CPU.Build.0 = Release|Any CPU - {10490B79-2C4D-4B86-83DF-A2574AD3DE04}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {10490B79-2C4D-4B86-83DF-A2574AD3DE04}.Debug|Any CPU.Build.0 = Debug|Any CPU - {10490B79-2C4D-4B86-83DF-A2574AD3DE04}.Release|Any CPU.ActiveCfg = Release|Any CPU - {10490B79-2C4D-4B86-83DF-A2574AD3DE04}.Release|Any CPU.Build.0 = Release|Any CPU {44427A10-C34F-441E-AE0D-EE1B09D991A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {44427A10-C34F-441E-AE0D-EE1B09D991A6}.Debug|Any CPU.Build.0 = Debug|Any CPU {44427A10-C34F-441E-AE0D-EE1B09D991A6}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -355,7 +349,6 @@ Global {05B687CB-E54A-4705-955C-5CA6AF7E9F25} = {ACE959CF-8213-4670-A525-7FE188336843} {A21BCC3E-A75C-40B5-91B1-2253953B59AA} = {87C72E4A-C538-412C-8256-FCC0808B6B66} {14E3528C-2F6B-4296-BAD1-E91F32F679EC} = {A21BCC3E-A75C-40B5-91B1-2253953B59AA} - {10490B79-2C4D-4B86-83DF-A2574AD3DE04} = {14E3528C-2F6B-4296-BAD1-E91F32F679EC} {44427A10-C34F-441E-AE0D-EE1B09D991A6} = {ACE959CF-8213-4670-A525-7FE188336843} {9C257B11-A2A1-4E1E-88DD-845E02E0B60F} = {5BAC57A7-56E7-4E7C-9118-24F61870BA91} {7D9414BD-3672-4CD5-BD70-79C31A3C50D2} = {A21BCC3E-A75C-40B5-91B1-2253953B59AA} diff --git a/src/Services/.BaseService/AppyNox.Services.Base.API/ApiServiceBuilder.cs b/src/Services/.BaseService/AppyNox.Services.Base.API/ApiServiceBuilder.cs index f55d1e92..5cb8e87c 100644 --- a/src/Services/.BaseService/AppyNox.Services.Base.API/ApiServiceBuilder.cs +++ b/src/Services/.BaseService/AppyNox.Services.Base.API/ApiServiceBuilder.cs @@ -1,6 +1,5 @@ using AppyNox.Services.Base.API.Constants; using AppyNox.Services.Base.API.Extensions; -using AppyNox.Services.Base.API.Filters; using AppyNox.Services.Base.Application.Interfaces.Loggers; using AppyNox.Services.Base.Infrastructure.Extensions; using AppyNox.Services.Base.Infrastructure.Services.LoggerService; @@ -9,7 +8,6 @@ using Microsoft.AspNetCore.Builder; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Localization; using Microsoft.Extensions.Logging; using Microsoft.OpenApi.Models; using Serilog; @@ -28,7 +26,6 @@ public class ApiServiceOptions public bool UseConsulKV { get; set; } public Action ConfigureLayers { get; set; } public IEnumerable Versions { get; set; } = [NoxVersions.v1_0]; - public bool UseDynamicRequestBodyOperationFilter { get; set; } = true; #nullable enable } @@ -122,11 +119,6 @@ private static void ConfigureSwagger(this WebApplicationBuilder builder, ApiServ var serviceName = builder.Configuration["Consul:ServiceName"]; builder.Services.AddSwaggerGen(opt => { - if(options.UseDynamicRequestBodyOperationFilter) - { - opt.OperationFilter(); - } - foreach(var version in options.Versions) { opt.SwaggerDoc($"v{version}", new OpenApiInfo { Title = serviceName, Version = version }); diff --git a/src/Services/.BaseService/AppyNox.Services.Base.API/Attributes/SwaggerDynamicRequestBodyAttribute.cs b/src/Services/.BaseService/AppyNox.Services.Base.API/Attributes/SwaggerDynamicRequestBodyAttribute.cs deleted file mode 100644 index 9a8e1346..00000000 --- a/src/Services/.BaseService/AppyNox.Services.Base.API/Attributes/SwaggerDynamicRequestBodyAttribute.cs +++ /dev/null @@ -1,12 +0,0 @@ -using AppyNox.Services.Base.Core.Enums; - -namespace AppyNox.Services.Base.API.Attributes; - -[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] -public class SwaggerDynamicRequestBodyAttribute(Type entityType, DtoLevelMappingTypes mappingType, bool isPaginatedListResponse = false) : Attribute -{ - public Type EntityType { get; } = entityType; - public DtoLevelMappingTypes MappingType { get; } = mappingType; - - public bool IsPaginatedListResponse { get; } = isPaginatedListResponse; -} \ No newline at end of file diff --git a/src/Services/.BaseService/AppyNox.Services.Base.API/Filters/DynamicRequestBodyOperationFilter.cs b/src/Services/.BaseService/AppyNox.Services.Base.API/Filters/DynamicRequestBodyOperationFilter.cs deleted file mode 100644 index e95ff8b0..00000000 --- a/src/Services/.BaseService/AppyNox.Services.Base.API/Filters/DynamicRequestBodyOperationFilter.cs +++ /dev/null @@ -1,355 +0,0 @@ -using AppyNox.Services.Base.API.Attributes; -using AppyNox.Services.Base.API.Exceptions.Base; -using AppyNox.Services.Base.API.Wrappers; -using AppyNox.Services.Base.Application.DtoUtilities; -using AppyNox.Services.Base.Application.Interfaces.Loggers; -using AppyNox.Services.Base.Core.Common; -using Microsoft.OpenApi.Any; -using Microsoft.OpenApi.Models; -using Swashbuckle.AspNetCore.SwaggerGen; -using System.Collections; -using System.Collections.Concurrent; -using System.Text.Json; -using System.Text.Json.Serialization; - -namespace AppyNox.Services.Base.API.Filters; - -public class DynamicRequestBodyOperationFilter(IDtoMappingRegistryBase mappingService, INoxApiLogger logger) : IOperationFilter -{ - private readonly IDtoMappingRegistryBase _mappingService = mappingService; - - private static readonly JsonSerializerOptions _serializerOptions = new() - { - WriteIndented = true, - PropertyNamingPolicy = JsonNamingPolicy.CamelCase - }; - - // Caches - private static readonly ConcurrentDictionary _paginatedExampleCache = new(); - private static readonly ConcurrentDictionary _exampleCache = new(); - - public void Apply(OpenApiOperation operation, OperationFilterContext context) - { - try - { - if (context.ApiDescription.HttpMethod == null) - { - return; - } - - if (context.ApiDescription.HttpMethod.Equals("GET", StringComparison.OrdinalIgnoreCase)) - { - HandleGetOperation(operation, context); - } - else if (context.ApiDescription.HttpMethod.Equals("POST", StringComparison.OrdinalIgnoreCase)) - { - HandlePostOperation(operation, context); - } - } - catch (Exception ex) - { - var attribute = context.MethodInfo - .GetCustomAttributes(true) - .OfType() - .FirstOrDefault(); - - logger.LogCritical(ex, $"DynamicRequestBodyOperationFilter ERROR for '{attribute!.EntityType}' '{attribute!.MappingType}' on " + - $"Controller '{context.MethodInfo.Name}'."); - throw; - } - } - - private void HandlePostOperation(OpenApiOperation operation, OperationFilterContext context) - { - var attribute = context.MethodInfo - .GetCustomAttributes(true) - .OfType() - .FirstOrDefault(); - - if (attribute != null) - { - var possibleTypes = _mappingService.GetDtoTypesForEntity(attribute.EntityType, attribute.MappingType); - if (possibleTypes != null && possibleTypes.Count != 0) - { - var oneOfSchema = new OpenApiSchema - { - OneOf = possibleTypes.Select(type => context.SchemaGenerator.GenerateSchema(type.Value, context.SchemaRepository)).ToList() - }; - - var mediaType = new OpenApiMediaType - { - Schema = oneOfSchema, - Examples = new Dictionary() - }; - - foreach (var type in possibleTypes) - { - var exampleInstance = CreateExampleInstance(type.Value); - var displayName = type.Key; - mediaType.Examples.Add(displayName, new OpenApiExample - { - Summary = $"Example for {displayName}", - Value = new OpenApiString(JsonSerializer.Serialize(exampleInstance, _serializerOptions)) - }); - } - - operation.RequestBody = new OpenApiRequestBody - { - Content = new Dictionary - { - ["application/json"] = mediaType - } - }; - } - } - } - - private void HandleGetOperation(OpenApiOperation operation, OperationFilterContext context) - { - var attribute = context.MethodInfo - .GetCustomAttributes(true) - .OfType() - .FirstOrDefault(); - - if (attribute != null) - { - var possibleTypes = _mappingService.GetDtoTypesForEntity(attribute.EntityType, attribute.MappingType); - if (possibleTypes != null && possibleTypes.Any()) - { - OpenApiSchema schemaToUse; - if (attribute.IsPaginatedListResponse) - { - // If response should be paginated, wrap possible types in PaginatedList schema - schemaToUse = GeneratePaginatedListSchema(possibleTypes.Values, context); - } - else - { - // If response is not paginated, directly use the possible types - var dataOneOfSchema = new OpenApiSchema - { - OneOf = possibleTypes.Select(type => context.SchemaGenerator.GenerateSchema(type.Value, context.SchemaRepository)).ToList() - }; - schemaToUse = GenerateNoxApiResponseSchema(dataOneOfSchema); - } - - if (!operation.Responses.ContainsKey("200")) - operation.Responses.Add("200", new OpenApiResponse { Description = "OK" }); - - var mediaType = new OpenApiMediaType - { - Schema = schemaToUse, - Examples = new Dictionary() - }; - - GenerateExamplesForSchema(mediaType, possibleTypes, context, attribute.IsPaginatedListResponse); - - operation.Responses["200"].Content.Clear(); - operation.Responses["200"].Content.Add("application/json", mediaType); - } - } - } - - #region [ Get Operation Private Methods ] - - private static void GenerateExamplesForSchema(OpenApiMediaType mediaType, Dictionary possibleTypes, OperationFilterContext context, bool isPaginated) - { - foreach (var type in possibleTypes) - { - var exampleInstance = isPaginated - ? CreatePaginatedExampleInstance(type.Value) - : new NoxApiResponse(CreateExampleInstance(type.Value)!); - var displayName = type.Key; - mediaType.Examples.Add(displayName, new OpenApiExample - { - Summary = $"Example for {displayName}", - Value = new OpenApiString(JsonSerializer.Serialize(exampleInstance, _serializerOptions)) - }); - } - } - - private static OpenApiSchema GenerateNoxApiResponseSchema(OpenApiSchema dataOneOfSchema) - { - return new OpenApiSchema - { - Type = "object", - Properties = new Dictionary - { - ["message"] = new OpenApiSchema { Type = "string" }, - ["version"] = new OpenApiSchema { Type = "string" }, - ["hasError"] = new OpenApiSchema { Type = "boolean" }, - ["code"] = new OpenApiSchema { Type = "integer", Format = "int32" }, - ["result"] = new OpenApiSchema - { - Type = "object", - Properties = new Dictionary - { - ["data"] = dataOneOfSchema, - ["error"] = new OpenApiSchema { Type = "string" } - } - } - }, - Required = new HashSet - { - "message", - "version", - "hasError", - "code", - "result" - } - }; - } - - private static OpenApiSchema GeneratePaginatedListSchema(IEnumerable possibleTypes, OperationFilterContext context) - { - var itemOneOfSchema = new OpenApiSchema - { - OneOf = possibleTypes.Select(type => context.SchemaGenerator.GenerateSchema(type, context.SchemaRepository)).ToList() - }; - - var paginatedListSchema = new OpenApiSchema - { - Type = "object", - Properties = new Dictionary - { - ["itemsCount"] = new OpenApiSchema { Type = "integer", Format = "int32" }, - ["totalCount"] = new OpenApiSchema { Type = "integer", Format = "int32" }, - ["currentPage"] = new OpenApiSchema { Type = "integer", Format = "int32" }, - ["pageSize"] = new OpenApiSchema { Type = "integer", Format = "int32" }, - ["items"] = new OpenApiSchema - { - Type = "array", - Items = itemOneOfSchema - } - }, - Required = new HashSet { "itemsCount", "totalCount", "currentPage", "pageSize", "items" } - }; - - return GenerateNoxApiResponseSchema(paginatedListSchema); - } - - private static NoxApiResponse CreatePaginatedExampleInstance(Type itemType) - { - string typeName = itemType.FullName - ?? throw new NoxApiException("Type name cannot be null", (int)NoxApiExceptionCode.SwaggerGenerationException); - - if (_paginatedExampleCache.TryGetValue(typeName, out object? instance)) - { - return new NoxApiResponse(instance, "Get Request Successful."); - } - - var exampleItem = CreateExampleInstance(itemType); - var listType = typeof(PaginatedList<>).MakeGenericType([itemType]); - var paginatedListInstance = Activator.CreateInstance(listType); - - var itemsList = Activator.CreateInstance(typeof(List<>).MakeGenericType(itemType)); - - var addMethod = itemsList!.GetType().GetMethod("Add"); - addMethod?.Invoke(itemsList, [exampleItem!]); - paginatedListInstance!.GetType().GetProperty("Items")?.SetValue(paginatedListInstance, itemsList); - - // Manually set to 0 to prevent negative values - var itemsCountProperty = listType.GetProperty("ItemsCount"); - itemsCountProperty?.SetValue(paginatedListInstance, 1); - - var totalCountProperty = listType.GetProperty("TotalCount"); - totalCountProperty?.SetValue(paginatedListInstance, 1); - - var currentPageProperty = listType.GetProperty("CurrentPage"); - currentPageProperty?.SetValue(paginatedListInstance, 1); - - var pageSizeProperty = listType.GetProperty("PageSize"); - pageSizeProperty?.SetValue(paginatedListInstance, 1); - - _paginatedExampleCache.TryAdd(typeName, paginatedListInstance); - - return new NoxApiResponse(paginatedListInstance, "Get Request Successful."); - } - - #endregion - - private static object CreateExampleInstance(Type type) - { - string typeName = type.FullName - ?? throw new NoxApiException("Type name cannot be null", (int)NoxApiExceptionCode.SwaggerGenerationException); - - if (_exampleCache.TryGetValue(typeName, out object? instance)) - { - return instance; - } - - instance = Activator.CreateInstance(type); - - foreach (var property in type.GetProperties()) - { - if (Attribute.IsDefined(property, typeof(JsonIgnoreAttribute))) - { - continue; // Skip the current iteration if JsonIgnore is found - } - - if (property.PropertyType == typeof(string)) - { - property.SetValue(instance, "Sample Text", null); - } - else if (property.PropertyType == typeof(int) || property.PropertyType == typeof(int?)) - { - property.SetValue(instance, 1, null); - } - else if (property.PropertyType == typeof(long) || property.PropertyType == typeof(long?)) - { - property.SetValue(instance, 1L, null); - } - else if (property.PropertyType == typeof(double) || property.PropertyType == typeof(double?)) - { - property.SetValue(instance, 1.0, null); - } - else if (property.PropertyType == typeof(decimal) || property.PropertyType == typeof(decimal?)) - { - property.SetValue(instance, 1.0m, null); - } - else if (property.PropertyType == typeof(Guid) || property.PropertyType == typeof(Guid?)) - { - property.SetValue(instance, Guid.NewGuid(), null); - } - else if (property.PropertyType == typeof(bool)) - { - property.SetValue(instance, true, null); - } - else if (property.PropertyType == typeof(DateTime) || property.PropertyType == typeof(DateTime?)) - { - property.SetValue(instance, DateTime.Now, null); - } - else if (property.PropertyType != typeof(string) && typeof(IEnumerable).IsAssignableFrom(property.PropertyType)) - { - Type elementType = property.PropertyType.GetGenericArguments()[0]; - IList listInstance = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(elementType))!; - var elementInstance = CreateExampleInstance(elementType); - if (elementInstance != null) - { - listInstance.Add(elementInstance); - } - property.SetValue(instance, listInstance); - } - else if (property.PropertyType.IsEnum || (Nullable.GetUnderlyingType(property.PropertyType) != null && Nullable.GetUnderlyingType(property.PropertyType)!.IsEnum)) - { - // Handle both enums and nullable enums - var enumType = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType; - var enumValues = Enum.GetValues(enumType); - if (enumValues.Length > 0) - { - property.SetValue(instance, enumValues.GetValue(0), null); - } - } - else if (!property.PropertyType.IsPrimitive && !property.PropertyType.IsEnum && property.PropertyType != typeof(string)) - { - var complexInstance = CreateExampleInstance(property.PropertyType); - if (complexInstance != null) - { - property.SetValue(instance, complexInstance); - } - } - } - _exampleCache.TryAdd(typeName, instance - ?? throw new NoxApiException($"Could not instantiate example instance for {type.Name}", (int)NoxApiExceptionCode.SwaggerGenerationException)); - return instance; - } -} \ No newline at end of file diff --git a/src/Services/.BaseService/AppyNox.Services.Base.API/Middleware/NoxResponseWrapperMiddleware.cs b/src/Services/.BaseService/AppyNox.Services.Base.API/Middleware/NoxResponseWrapperMiddleware.cs index 0d28a7d6..0716a90b 100644 --- a/src/Services/.BaseService/AppyNox.Services.Base.API/Middleware/NoxResponseWrapperMiddleware.cs +++ b/src/Services/.BaseService/AppyNox.Services.Base.API/Middleware/NoxResponseWrapperMiddleware.cs @@ -56,16 +56,16 @@ public async Task Invoke(HttpContext context) { if (string.IsNullOrEmpty(noxApiResponse?.Message)) { - noxApiResponse!.Message = NoxApiResourceService.RequestSuccessful.Format(context.Request.Method); + noxApiResponse.Message = NoxApiResourceService.RequestSuccessful.Format(context.Request.Method); } await WriteResponseAsync(context, originalBodyStream, noxApiResponse); } else { object? resultBody = DeserializeJson(bodyAsText); - NoxApiResultObject result = new(resultBody, null); + NoxApiResultObject result = new(resultBody, null); string message = NoxApiResourceService.RequestSuccessful.Format(context.Request.Method); - NoxApiResponse wrappedResponse = new(result, message, _options.ApiVersion, false, context.Response.StatusCode); + NoxApiResponse wrappedResponse = new(result, message, _options.ApiVersion, false, context.Response.StatusCode); await WriteResponseAsync(context, originalBodyStream, wrappedResponse); } } @@ -73,8 +73,8 @@ public async Task Invoke(HttpContext context) { string apiError = WrapUnsuccessfulError(context.Response.StatusCode); string message = NoxApiResourceService.RequestUnsuccessful.Format(context.Request.Method); - NoxApiResultObject errorResponse = new(null, apiError); - NoxApiResponse wrappedResponse = new(errorResponse, message, _options.ApiVersion, true, context.Response.StatusCode); + NoxApiResultObject errorResponse = new(null, apiError); + NoxApiResponse wrappedResponse = new(errorResponse, message, _options.ApiVersion, true, context.Response.StatusCode); await WriteResponseAsync(context, originalBodyStream, wrappedResponse); } } @@ -130,12 +130,12 @@ private static string WrapUnsuccessfulError(int statusCode) } } - private (bool, NoxApiResponse?) TryGetNoxApiResponse(string responseBody) + private (bool, NoxApiResponse?) TryGetNoxApiResponse(string responseBody) { try { - NoxApiResponsePOCO? response = JsonSerializer.Deserialize(responseBody, _jsonSerializeOptions); - return (response != null && response.Result != null, new NoxApiResponse(response!.Result!, response.Message, response.Version, response.HasError, response.Code)); + NoxApiResponsePOCO? response = JsonSerializer.Deserialize>(responseBody, _jsonSerializeOptions); + return (response != null && response.Result != null, new NoxApiResponse(response!.Result!, response.Message, response.Version, response.HasError, response.Code)); } catch { @@ -151,20 +151,20 @@ private async Task HandleKnownExceptionAsync(HttpContext context, NoxException e ? new NoxApiValidationExceptionWrapObject(exception, correlationId, fluentException.ValidationResult.Errors.AsEnumerable()) : new NoxApiExceptionWrapObject(exception, correlationId); - NoxApiResultObject errorResponse = new(null, errorResponseBody); - NoxApiResponse wrappedResponse = new(errorResponse, NoxApiResourceService.NoxExceptionThrown, _options.ApiVersion, true, exception.StatusCode); + NoxApiResultObject errorResponse = new(null, errorResponseBody); + NoxApiResponse wrappedResponse = new(errorResponse, NoxApiResourceService.NoxExceptionThrown, _options.ApiVersion, true, exception.StatusCode); await WriteResponseAsync(context, originalBodyStream, wrappedResponse); } private async Task HandleUnknownExceptionAsync(HttpContext context, Exception exception, Stream originalBodyStream) { var errorResponseBody = new { exception.Message, exception.StackTrace }; - NoxApiResultObject errorResponse = new(null, errorResponseBody); - NoxApiResponse wrappedResponse = new(errorResponse, NoxApiResourceService.UnknownExceptionThrown, _options.ApiVersion, true, StatusCodes.Status500InternalServerError); + NoxApiResultObject errorResponse = new(null, errorResponseBody); + NoxApiResponse wrappedResponse = new(errorResponse, NoxApiResourceService.UnknownExceptionThrown, _options.ApiVersion, true, StatusCodes.Status500InternalServerError); await WriteResponseAsync(context, originalBodyStream, wrappedResponse); } - private async Task WriteResponseAsync(HttpContext context, Stream originalBodyStream, NoxApiResponse response) + private async Task WriteResponseAsync(HttpContext context, Stream originalBodyStream, NoxApiResponse response) { context.Response.StatusCode = response.Code; diff --git a/src/Services/.BaseService/AppyNox.Services.Base.API/ViewModels/QueryParametersViewModel.cs b/src/Services/.BaseService/AppyNox.Services.Base.API/ViewModels/QueryParametersViewModel.cs deleted file mode 100644 index 836f0d59..00000000 --- a/src/Services/.BaseService/AppyNox.Services.Base.API/ViewModels/QueryParametersViewModel.cs +++ /dev/null @@ -1,49 +0,0 @@ -using AppyNox.Services.Base.Core.Enums; -using AppyNox.Services.Base.Infrastructure.Repositories.Common; - -namespace AppyNox.Services.Base.API.ViewModels; - -/// -/// Represents a view model for query parameters, extending the base query parameters with additional functionality. -/// Use for v1.0 endpoints -/// -public class QueryParametersViewModel : QueryParametersBase -{ - #region [ Hidden Properties ] - - /// - /// Gets or sets the access type for the query, allowing only protected access. Hides it from Swagger. - /// - protected new DtoLevelMappingTypes AccessType - { - get => base.AccessType; - set => base.AccessType = value; - } - - #endregion -} - -public class QueryParametersViewModelBasic : QueryParametersViewModel -{ - #region [ Hidden Properties ] - - /// - /// Gets or sets the access type for the query, allowing only protected access. Hides it from Swagger. - /// - protected new DtoLevelMappingTypes AccessType - { - get => base.AccessType; - } - - protected new string Access - { - get => base.Access; - } - - protected new string DetailLevel - { - get => base.DetailLevel; - } - - #endregion -} \ No newline at end of file diff --git a/src/Services/.BaseService/AppyNox.Services.Base.API/Wrappers/NoxApiResponse.cs b/src/Services/.BaseService/AppyNox.Services.Base.API/Wrappers/NoxApiResponse.cs index 1d8adb4a..98844f0f 100644 --- a/src/Services/.BaseService/AppyNox.Services.Base.API/Wrappers/NoxApiResponse.cs +++ b/src/Services/.BaseService/AppyNox.Services.Base.API/Wrappers/NoxApiResponse.cs @@ -4,7 +4,7 @@ namespace AppyNox.Services.Base.API.Wrappers; -public class NoxApiResponse +public class NoxApiResponse { #region [ Properties ] @@ -25,18 +25,18 @@ public class NoxApiResponse public int Code { get; internal set; } [JsonPropertyName("result")] - public NoxApiResultObject Result { get; set; } + public NoxApiResultObject Result { get; set; } #endregion #region [ Constructors ] - public NoxApiResponse(object result, string message = "", string version = "1.0", bool hasError = false, int code = (int)HttpStatusCode.OK) - : this(new NoxApiResultObject(result, null), message, version, hasError, code) + public NoxApiResponse(TData result, string message = "", string version = "1.0", bool hasError = false, int code = (int)HttpStatusCode.OK) + : this(new NoxApiResultObject(result, null), message, version, hasError, code) { } - internal NoxApiResponse(NoxApiResultObject result, string message, string version, bool hasError, int code) + internal NoxApiResponse(NoxApiResultObject result, string message, string version, bool hasError, int code) { Result = result; Message = message; @@ -45,7 +45,7 @@ internal NoxApiResponse(NoxApiResultObject result, string message, string versio Code = code; } - internal NoxApiResponse(NoxApiResponsePOCO noxApiResponsePOCO) + internal NoxApiResponse(NoxApiResponsePOCO noxApiResponsePOCO) { Result = noxApiResponsePOCO.Result; Message = noxApiResponsePOCO.Message; diff --git a/src/Services/.BaseService/AppyNox.Services.Base.API/Wrappers/NoxApiResponsePOCO.cs b/src/Services/.BaseService/AppyNox.Services.Base.API/Wrappers/NoxApiResponsePOCO.cs index 9dd43b25..3bc8547a 100644 --- a/src/Services/.BaseService/AppyNox.Services.Base.API/Wrappers/NoxApiResponsePOCO.cs +++ b/src/Services/.BaseService/AppyNox.Services.Base.API/Wrappers/NoxApiResponsePOCO.cs @@ -2,7 +2,7 @@ namespace AppyNox.Services.Base.API.Wrappers; -internal class NoxApiResponsePOCO +internal class NoxApiResponsePOCO { #region [ Properties ] @@ -14,7 +14,7 @@ internal class NoxApiResponsePOCO public int Code { get; set; } - public NoxApiResultObject Result { get; set; } = null!; + public NoxApiResultObject Result { get; set; } = null!; #endregion } \ No newline at end of file diff --git a/src/Services/.BaseService/AppyNox.Services.Base.API/Wrappers/Results/NoxApiResultObject.cs b/src/Services/.BaseService/AppyNox.Services.Base.API/Wrappers/Results/NoxApiResultObject.cs index cf1e36a8..1e839f5d 100644 --- a/src/Services/.BaseService/AppyNox.Services.Base.API/Wrappers/Results/NoxApiResultObject.cs +++ b/src/Services/.BaseService/AppyNox.Services.Base.API/Wrappers/Results/NoxApiResultObject.cs @@ -1,10 +1,10 @@ namespace AppyNox.Services.Base.API.Wrappers.Results; -public class NoxApiResultObject(object? data, object? error) +public class NoxApiResultObject(TData? data, object? error) { #region [ Properties ] - public object? Data { get; set; } = data; + public TData? Data { get; set; } = data; public object? Error { get; set; } = error; diff --git a/src/Services/.BaseService/AppyNox.Services.Base.Application/ApplicationServiceBuilder.cs b/src/Services/.BaseService/AppyNox.Services.Base.Application/ApplicationServiceBuilder.cs index 39d8927c..d6d3b03c 100644 --- a/src/Services/.BaseService/AppyNox.Services.Base.Application/ApplicationServiceBuilder.cs +++ b/src/Services/.BaseService/AppyNox.Services.Base.Application/ApplicationServiceBuilder.cs @@ -1,6 +1,4 @@ -using AppyNox.Services.Base.Application.DtoUtilities; -using AppyNox.Services.Base.Application.Exceptions.Base; -using AppyNox.Services.Base.Application.Interfaces.Loggers; +using AppyNox.Services.Base.Application.Interfaces.Loggers; using AppyNox.Services.Base.Application.MediatR.Behaviors; using FluentValidation; using MediatR; @@ -24,8 +22,6 @@ public class ApplicationSetupOptions public bool UseFluentValidation { get; set; } = true; public bool UseDtoMappingRegistry { get; set; } = true; public bool UseMediatR { get; set; } = true; - public Func DtoMappingRegistryFactory { get; set; } - #nullable enable } @@ -63,16 +59,6 @@ public static IServiceCollection AddApplicationServices(this IServiceCollection logger.LogInformation($"-{serviceName}- FluentValidation enabled...", false); } - if (options.UseDtoMappingRegistry) - { - if (options.DtoMappingRegistryFactory is null) - { - throw new NoxApplicationException("DtoMappingRegistryFactory was null!"); - } - services.AddSingleton(typeof(IDtoMappingRegistryBase), options.DtoMappingRegistryFactory); - logger.LogInformation($"-{serviceName}- DtoMappingRegistry enabled...", false); - } - if(options.UseMediatR) { services.AddMediatR(cfg => diff --git a/src/Services/.BaseService/AppyNox.Services.Base.Application/AppyNox.Services.Base.Application.csproj b/src/Services/.BaseService/AppyNox.Services.Base.Application/AppyNox.Services.Base.Application.csproj index 390dd6be..13ef55e1 100644 --- a/src/Services/.BaseService/AppyNox.Services.Base.Application/AppyNox.Services.Base.Application.csproj +++ b/src/Services/.BaseService/AppyNox.Services.Base.Application/AppyNox.Services.Base.Application.csproj @@ -24,12 +24,6 @@ preview - - - - - - @@ -44,12 +38,6 @@ - - - - - - diff --git a/src/Services/.BaseService/AppyNox.Services.Base.Application/DtoUtilities/DtoMappingRegistryBase.cs b/src/Services/.BaseService/AppyNox.Services.Base.Application/DtoUtilities/DtoMappingRegistryBase.cs deleted file mode 100644 index fdae9df9..00000000 --- a/src/Services/.BaseService/AppyNox.Services.Base.Application/DtoUtilities/DtoMappingRegistryBase.cs +++ /dev/null @@ -1,149 +0,0 @@ -using AppyNox.Services.Base.Application.Exceptions; -using AppyNox.Services.Base.Application.Extensions; -using AppyNox.Services.Base.Core.Enums; -using AppyNox.Services.Base.Core.Extensions; - -namespace AppyNox.Services.Base.Application.DtoUtilities -{ - /// - /// Provides a base implementation for a registry managing mappings between entities and their corresponding DTOs. - /// - public abstract class DtoMappingRegistryBase : IDtoMappingRegistryBase - { - #region [ Fields ] - - private readonly Dictionary<(Type entityType, DtoLevelMappingTypes mappingType, Enum detailLevel), Type> _entityDetailLevelToDtoTypeMappings; - - private readonly Dictionary> _entityToDtoDetailLevelMappings; - - #endregion - - #region [ Protected Constructors ] - - protected DtoMappingRegistryBase() - { - _entityDetailLevelToDtoTypeMappings = []; - _entityToDtoDetailLevelMappings = []; - } - - #endregion - - #region [ Public Methods ] - - public Type GetDtoType(DtoLevelMappingTypes detailLevelEnum, Type entityType, string detailLevelDescription) - { - Enum detailLevel = NoxEnumExtensions.GetEnumValueFromDisplayName(GetDetailLevelType(detailLevelEnum, entityType), detailLevelDescription); - - if (_entityDetailLevelToDtoTypeMappings.TryGetValue((entityType, detailLevelEnum, detailLevel), out var dtoType)) - { - return dtoType; - } - throw new DtoDetailLevelNotFoundException(entityType, detailLevel); - } - - public Dictionary GetDetailLevelTypes(Type entityType) - { - if (_entityToDtoDetailLevelMappings.TryGetValue(entityType, out var detailLevelMappings)) - { - return detailLevelMappings; - } - - throw new AccessTypeNotFoundException(entityType); - } - - public Dictionary GetDtoTypesForEntity(Type entityType, DtoLevelMappingTypes mappingType) - { - Dictionary result = []; - - if (_entityToDtoDetailLevelMappings.TryGetValue(entityType, out var entityAllDtoLevelMappings)) - { - if (entityAllDtoLevelMappings.TryGetValue(mappingType, out var entityDtoLevelMappings)) - { - if (entityDtoLevelMappings is Type actualEnumType && actualEnumType.IsEnum) - { - foreach (Enum value in Enum.GetValues(actualEnumType)) - { - var key = (entityType, mappingType, value); - if (_entityDetailLevelToDtoTypeMappings.TryGetValue(key, out var dtoType) && dtoType != null) - { - result.Add(value.GetDisplayName(), dtoType); - } - } - } - else - { - throw new DtoTypesForEntityException("The provided type is not an enum or is null."); - } - } - else - { - throw new DtoTypesForEntityException("Mapping type not found."); - } - } - else - { - throw new DtoTypesForEntityException("Entity type not found in mappings."); - } - - return result; - } - - #endregion - - #region [ Protected Methods ] - - /// - /// Registers entity to DTO mappings. This method should be implemented in derived classes. - /// - protected abstract void RegisterDtos(); - - /// - /// Registers a mapping between an entity type and a DTO type. - /// - /// The entity type. - /// The DTO type. - /// The attribute used to determine the detail level of the mapping. - protected void RegisterMapping(Type entityType, Type dtoType, Attribute attribute) - { - string dtoName = dtoType.Name; - DtoLevelMappingTypes desiredMapping = DtoLevelMappingTypes.DataAccess; - - if (dtoName.Contains("Create")) - { - desiredMapping = DtoLevelMappingTypes.Create; - } - else if (dtoName.Contains("Update")) - { - desiredMapping = DtoLevelMappingTypes.Update; - } - - Enum detailLevel = GetDetailLevelBase(attribute, desiredMapping); - - if (!_entityToDtoDetailLevelMappings.TryGetValue(entityType, out var mappings)) - { - mappings = []; - _entityToDtoDetailLevelMappings.Add(entityType, mappings); - } - - mappings[desiredMapping] = detailLevel.GetType(); - _entityDetailLevelToDtoTypeMappings[(entityType, desiredMapping, detailLevel)] = dtoType; - } - - protected abstract Enum GetDetailLevelBase(Attribute attribute, DtoLevelMappingTypes mappingType); - - #endregion - - #region [ Private Methods ] - - public Type GetDetailLevelType(DtoLevelMappingTypes type, Type entityType) - { - var map = _entityToDtoDetailLevelMappings.GetValueOrDefault(entityType) - ?? throw new AccessTypeNotFoundException(entityType, type.ToString()); - - return map.GetValueOrDefault(type) - ?? throw new AccessTypeNotFoundException(entityType, type.ToString()); - } - - #endregion - } -} \ No newline at end of file diff --git a/src/Services/.BaseService/AppyNox.Services.Base.Application/DtoUtilities/IDtoMappingRegistryBase.cs b/src/Services/.BaseService/AppyNox.Services.Base.Application/DtoUtilities/IDtoMappingRegistryBase.cs deleted file mode 100644 index 15bb7e59..00000000 --- a/src/Services/.BaseService/AppyNox.Services.Base.Application/DtoUtilities/IDtoMappingRegistryBase.cs +++ /dev/null @@ -1,52 +0,0 @@ -using AppyNox.Services.Base.Core.Enums; -using AppyNox.Services.Base.Application.Exceptions; - -namespace AppyNox.Services.Base.Application.DtoUtilities -{ - /// - /// Defines the contract for a registry managing mappings between entities and their corresponding DTOs. - /// - public interface IDtoMappingRegistryBase - { - #region [ Public Methods ] - - /// - /// Retrieves the DTO type associated with a given entity type and detail level. - /// - /// The DTO detail level type. - /// The entity type. - /// The DTO type associated with the specified entity and detail level. - Type GetDetailLevelType(DtoLevelMappingTypes type, Type entityType); - - /// - /// Gets the dictionary of detail level types for a specific entity type. - /// - /// The entity type. - /// A dictionary mapping detail level types to DTO types for the specified entity. - Dictionary GetDetailLevelTypes(Type entityType); - - /// - /// Retrieves the specific DTO type based on the detail level, entity type, and detail level description. - /// - /// The DTO detail level enumeration. - /// The entity type. - /// The description of the detail level. - /// The specific DTO type. - Type GetDtoType(DtoLevelMappingTypes detailLevelEnum, Type entityType, string detailLevelDescription); - - /// - /// Retrieves a list of DTO types associated with a given entity type and mapping type. - /// This method is used to dynamically determine the relevant data transfer object (DTO) types - /// based on the operation context (like creating, reading, or updating an entity). - /// - /// The type of the entity for which DTO types are required. - /// The mapping type that specifies the kind of operation context (e.g., DataAccess, Create, Update). - /// A dictionary of Type objects representing the DTOs as value and their enum Display name as key applicable to the specified entity type and mapping type. - /// The dictionary contains only valid types and excludes null values. It may be empty if no applicable DTO types are found. - /// Thrown when the entity type is not found in mappings, mapping type is not found, - /// or the provided type is not an enum or is null. - Dictionary GetDtoTypesForEntity(Type entityType, DtoLevelMappingTypes mappingType); - - #endregion - } -} \ No newline at end of file diff --git a/src/Services/.BaseService/AppyNox.Services.Base.Application/Extensions/ServiceCollectionExtensions.cs b/src/Services/.BaseService/AppyNox.Services.Base.Application/Extensions/ServiceCollectionExtensions.cs index 280218a2..791a2682 100644 --- a/src/Services/.BaseService/AppyNox.Services.Base.Application/Extensions/ServiceCollectionExtensions.cs +++ b/src/Services/.BaseService/AppyNox.Services.Base.Application/Extensions/ServiceCollectionExtensions.cs @@ -22,24 +22,24 @@ public static class ServiceCollectionExtensions /// /// /// The updated after registration. - public static IServiceCollection AddAnemicEntityCommands(this IServiceCollection services) + public static IServiceCollection AddAnemicEntityCommands(this IServiceCollection services) where TEntity : class, IEntityWithGuid { // Register GetAllEntitiesQueryHandler - services.AddTransient, PaginatedList>, - GetAllEntitiesQueryHandler>(); + services.AddTransient, PaginatedList>, + GetAllEntitiesQueryHandler>(); // Register GetEntityByIdQueryHandler - services.AddTransient, object>, - GetEntityByIdQueryHandler>(); + services.AddTransient, TDto>, + GetEntityByIdQueryHandler>(); // Register CreateEntityCommandHandler - services.AddTransient, Guid>, - CreateEntityCommandHandler>(); + services.AddTransient, Guid>, + CreateEntityCommandHandler>(); // Register UpdateEntityCommandHandler - services.AddTransient>, - UpdateEntityCommandHandler>(); + services.AddTransient>, + UpdateEntityCommandHandler>(); // Register DeleteEntityCommandHandler services.AddTransient>, @@ -61,21 +61,21 @@ public static IServiceCollection AddAnemicEntityCommands(this IServiceC /// /// /// The updated after registration. - public static IServiceCollection AddNoxEntityCommands(this IServiceCollection services) + public static IServiceCollection AddNoxEntityCommands(this IServiceCollection services) where TEntity : class, IHasStronglyTypedId where TId : NoxId { // Register GetAllNoxEntitiesQueryHandler - services.AddTransient, PaginatedList>, - GetAllNoxEntitiesQueryHandler>(); + services.AddTransient, PaginatedList>, + GetAllNoxEntitiesQueryHandler>(); // Register GetNoxEntityByIdQueryHandler - services.AddTransient, object>, - GetNoxEntityByIdQueryHandler>(); + services.AddTransient, TDto>, + GetNoxEntityByIdQueryHandler>(); // Register CreateNoxEntityCommandHandler - services.AddTransient, Guid>, - CreateNoxEntityCommandHandler>(); + services.AddTransient, Guid>, + CreateNoxEntityCommandHandler>(); // Register DeleteNoxEntityCommandHandler services.AddTransient>, @@ -84,5 +84,16 @@ public static IServiceCollection AddNoxEntityCommands(this IServic return services; } + public static IServiceCollection AddNoxEntityCompositeCreateCommand(this IServiceCollection services) + where TEntity : class, IHasStronglyTypedId + where TId : NoxId + { + // Register CreateNoxEntityCommandHandler + services.AddTransient, Guid>, + CreateNoxEntityCommandHandler>(); + + return services; + } + #endregion } \ No newline at end of file diff --git a/src/Services/.BaseService/AppyNox.Services.Base.Application/Interfaces/Repositories/IQueryParameters.cs b/src/Services/.BaseService/AppyNox.Services.Base.Application/Interfaces/Repositories/IQueryParameters.cs index bf82dc7e..908299a7 100644 --- a/src/Services/.BaseService/AppyNox.Services.Base.Application/Interfaces/Repositories/IQueryParameters.cs +++ b/src/Services/.BaseService/AppyNox.Services.Base.Application/Interfaces/Repositories/IQueryParameters.cs @@ -9,23 +9,6 @@ public interface IQueryParameters { #region [ Properties ] - /// - /// Gets or sets the access level as a string. Primarily used for conversion. - /// - string Access { get; set; } - - /// - /// Gets the access type for the query, indicating the level of data access required. This field is not set from request - /// parameters, but is instead converted from Access(string) property. - /// - DtoLevelMappingTypes AccessType { get; } - - /// - /// Gets or sets the detail level for the query as a string. - /// This property then will be converted to related Enum type of the TEntity using DtoMappingRegistry. - /// - string DetailLevel { get; set; } - /// /// Gets or sets the page number for pagination. /// diff --git a/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/BaseHandler.cs b/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/BaseHandler.cs index c0ae72de..1908ec1c 100644 --- a/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/BaseHandler.cs +++ b/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/BaseHandler.cs @@ -1,8 +1,5 @@ -using AppyNox.Services.Base.Application.DtoUtilities; -using AppyNox.Services.Base.Application.Exceptions; +using AppyNox.Services.Base.Application.Exceptions; using AppyNox.Services.Base.Application.Interfaces.Caches; -using AppyNox.Services.Base.Application.Interfaces.Loggers; -using AppyNox.Services.Base.Application.Interfaces.Repositories; using AutoMapper; using FluentValidation; using FluentValidation.Internal; @@ -12,15 +9,12 @@ namespace AppyNox.Services.Base.Application.MediatR; public abstract class BaseHandler( IMapper mapper, - IDtoMappingRegistryBase dtoMappingRegistry, IServiceProvider serviceProvider) { #region [ Fields ] protected readonly IMapper Mapper = mapper; - protected readonly IDtoMappingRegistryBase DtoMappingRegistry = dtoMappingRegistry; - protected readonly IServiceProvider ServiceProvider = serviceProvider; protected readonly Type EntityType = typeof(TEntity); @@ -34,33 +28,21 @@ public abstract class BaseHandler( #region [ Protected Methods ] - /// - /// Gets the type of DTO (Data Transfer Object) based on the specified query parameters. - /// - /// The query parameters specifying access type, entity type, and detail level. - /// The type of DTO mapped for the given query parameters. - - protected Type GetDtoType(IQueryParameters queryParameters) - { - return DtoMappingRegistry.GetDtoType(queryParameters.AccessType, EntityType, queryParameters.DetailLevel); ; - } - /// /// Performs validation on a given DTO using FluentValidation /// - /// The type of the DTO to validate /// The DTO object to validate /// Thrown if validator for the DTO is not found in Dependency Injection Container /// Thrown if DTO validation is not succeed - protected void FluentValidate(Type dtoType, dynamic dtoObject) + protected void FluentValidate(TDto dtoObject) { - Type genericType = typeof(IValidator<>).MakeGenericType(dtoType); - IValidator validator = ServiceProvider.GetService(genericType) as IValidator ?? throw new ValidatorNotFoundException(dtoType); - var context = new ValidationContext(dtoObject, new PropertyChain(), new DefaultValidatorSelector()); + Type genericType = typeof(IValidator); + IValidator validator = ServiceProvider.GetService(genericType) as IValidator ?? throw new ValidatorNotFoundException(typeof(TDto)); + var context = new ValidationContext(dtoObject, new PropertyChain(), new DefaultValidatorSelector()); var validationResult = validator.Validate(context); if (!validationResult.IsValid) { - throw new NoxFluentValidationException(dtoType, validationResult); + throw new NoxFluentValidationException(typeof(TDto), validationResult); } } diff --git a/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Commands/GenericEntityCommands.cs b/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Commands/GenericEntityCommands.cs index c551a5bb..75aa8540 100644 --- a/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Commands/GenericEntityCommands.cs +++ b/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Commands/GenericEntityCommands.cs @@ -8,7 +8,7 @@ namespace AppyNox.Services.Base.Application.MediatR.Commands; [SuppressMessage("Sonar Code Smell", "S2326:Unused type parameters should be removed", Justification = "TEntity is used to specify the type of entity being created")] -public record CreateEntityCommand(dynamic Dto, string DetailLevel, NoxCommandExtensions Extensions = default!) +public record CreateEntityCommand(TDto Dto, NoxCommandExtensions Extensions = default!) : IRequest, IHaveNoxCommandExtensions where TEntity : IEntityWithGuid; @@ -18,16 +18,16 @@ public record DeleteEntityCommand(Guid Id, bool ForceDelete = false, No where TEntity : IEntityWithGuid; [SuppressMessage("Sonar Code Smell", "S2326:Unused type parameters should be removed", Justification = "TEntity is used to specify the type of entity being created")] -public record UpdateEntityCommand(Guid Id, dynamic Dto, string DetailLevel, NoxCommandExtensions Extensions = default!) +public record UpdateEntityCommand(Guid Id, TDto Dto, NoxCommandExtensions Extensions = default!) : IRequest, IHaveNoxCommandExtensions where TEntity : IEntityWithGuid; [SuppressMessage("Sonar Code Smell", "S2326:Unused type parameters should be removed", Justification = "TEntity is used to specify the type of entity being created")] -public record GetAllEntitiesQuery(IQueryParameters QueryParameters, NoxCommandExtensions Extensions = default!) - : IRequest>, IHaveNoxCommandExtensions +public record GetAllEntitiesQuery(IQueryParameters QueryParameters, NoxCommandExtensions Extensions = default!) + : IRequest>, IHaveNoxCommandExtensions where TEntity : IEntityWithGuid; [SuppressMessage("Sonar Code Smell", "S2326:Unused type parameters should be removed", Justification = "TEntity is used to specify the type of entity being created")] -public record GetEntityByIdQuery(Guid Id, IQueryParameters QueryParameters, bool Track = false, NoxCommandExtensions Extensions = default!) - : IRequest, IHaveNoxCommandExtensions +public record GetEntityByIdQuery(Guid Id, IQueryParameters QueryParameters, bool Track = false, NoxCommandExtensions Extensions = default!) + : IRequest, IHaveNoxCommandExtensions where TEntity : IEntityWithGuid; \ No newline at end of file diff --git a/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Commands/NoxEntityCommands.cs b/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Commands/NoxEntityCommands.cs index 8376589b..3fba9f66 100644 --- a/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Commands/NoxEntityCommands.cs +++ b/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Commands/NoxEntityCommands.cs @@ -9,18 +9,18 @@ namespace AppyNox.Services.Base.Application.MediatR.Commands; [SuppressMessage("Sonar Code Smell", "S2326:Unused type parameters should be removed", Justification = "TEntity is used to specify the type of entity being created")] -public record GetAllNoxEntitiesQuery(IQueryParameters QueryParameters, NoxCommandExtensions Extensions = default!) - : IRequest>, IHaveNoxCommandExtensions +public record GetAllNoxEntitiesQuery(IQueryParameters QueryParameters, NoxCommandExtensions Extensions = default!) + : IRequest>, IHaveNoxCommandExtensions where TEntity : class, IHasStronglyTypedId; [SuppressMessage("Sonar Code Smell", "S2326:Unused type parameters should be removed", Justification = "TEntity is used to specify the type of entity being created")] -public record GetNoxEntityByIdQuery(TId Id, IQueryParameters QueryParameters, bool Track = false, NoxCommandExtensions Extensions = default!) - : IRequest, IHaveNoxCommandExtensions +public record GetNoxEntityByIdQuery(TId Id, IQueryParameters QueryParameters, bool Track = false, NoxCommandExtensions Extensions = default!) + : IRequest, IHaveNoxCommandExtensions where TEntity : class, IHasStronglyTypedId where TId : NoxId; [SuppressMessage("Sonar Code Smell", "S2326:Unused type parameters should be removed", Justification = "TEntity is used to specify the type of entity being created")] -public record CreateNoxEntityCommand(dynamic Dto, string DetailLevel, NoxCommandExtensions Extensions = default!) +public record CreateNoxEntityCommand(TDto Dto, NoxCommandExtensions Extensions = default!) : IRequest, IHaveNoxCommandExtensions where TEntity : class, IHasStronglyTypedId; diff --git a/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Handlers/Anemic/CreateEntityCommandHandler.cs b/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Handlers/Anemic/CreateEntityCommandHandler.cs index 485d8566..51f30ca2 100644 --- a/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Handlers/Anemic/CreateEntityCommandHandler.cs +++ b/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Handlers/Anemic/CreateEntityCommandHandler.cs @@ -1,28 +1,24 @@ -using AppyNox.Services.Base.Application.DtoUtilities; -using AppyNox.Services.Base.Application.Exceptions.Base; +using AppyNox.Services.Base.Application.Exceptions.Base; using AppyNox.Services.Base.Application.Interfaces.Caches; using AppyNox.Services.Base.Application.Interfaces.Loggers; using AppyNox.Services.Base.Application.Interfaces.Repositories; using AppyNox.Services.Base.Application.MediatR.Commands; -using AppyNox.Services.Base.Core.Enums; using AppyNox.Services.Base.Core.Exceptions.Base; using AppyNox.Services.Base.Domain.Interfaces; using AutoMapper; using MediatR; -using System.Text.Json; namespace AppyNox.Services.Base.Application.MediatR.Handlers.Anemic; -internal sealed class CreateEntityCommandHandler( +internal sealed class CreateEntityCommandHandler( IGenericRepository repository, IMapper mapper, - IDtoMappingRegistryBase dtoMappingRegistry, IServiceProvider serviceProvider, - INoxApplicationLogger> logger, + INoxApplicationLogger> logger, IUnitOfWork unitOfWork, ICacheService cacheService) - : BaseHandler(mapper, dtoMappingRegistry, serviceProvider), - IRequestHandler, Guid> + : BaseHandler(mapper, serviceProvider), + IRequestHandler, Guid> where TEntity : class, IEntityWithGuid { #region [ Fields ] @@ -37,27 +33,19 @@ internal sealed class CreateEntityCommandHandler( #region [ Public Methods ] - public async Task Handle(CreateEntityCommand request, CancellationToken cancellationToken) + public async Task Handle(CreateEntityCommand request, CancellationToken cancellationToken) { try { logger.LogInformation($"Adding new entity of type '{typeof(TEntity).Name}'"); - Type entityType = typeof(TEntity); - - #region [ Dynamic Dto Convertion ] - - Type dtoType = DtoMappingRegistry.GetDtoType(DtoLevelMappingTypes.Create, entityType, request.DetailLevel); - dynamic? dtoObject = JsonSerializer.Deserialize(request.Dto, dtoType, options: JsonSerializerOptions); - - #endregion #region [ FluentValidation ] - FluentValidate(dtoType, dtoObject); + FluentValidate(request.Dto); #endregion - TEntity mappedEntity = Mapper.Map(dtoObject, dtoType, entityType); + TEntity mappedEntity = Mapper.Map(request.Dto); await _repository.AddAsync(mappedEntity); await _unitOfWork.SaveChangesAsync(); await UpdateTotalCountOnCache(_cacheService, $"total-count-{typeof(TEntity).Name}", true); diff --git a/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Handlers/Anemic/DeleteEntityCommandHandler.cs b/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Handlers/Anemic/DeleteEntityCommandHandler.cs index b0221736..29054f69 100644 --- a/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Handlers/Anemic/DeleteEntityCommandHandler.cs +++ b/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Handlers/Anemic/DeleteEntityCommandHandler.cs @@ -1,5 +1,4 @@ -using AppyNox.Services.Base.Application.DtoUtilities; -using AppyNox.Services.Base.Application.Exceptions.Base; +using AppyNox.Services.Base.Application.Exceptions.Base; using AppyNox.Services.Base.Application.Interfaces.Caches; using AppyNox.Services.Base.Application.Interfaces.Loggers; using AppyNox.Services.Base.Application.Interfaces.Repositories; @@ -14,12 +13,11 @@ namespace AppyNox.Services.Base.Application.MediatR.Handlers.Anemic; internal sealed class DeleteEntityCommandHandler( IGenericRepository repository, IMapper mapper, - IDtoMappingRegistryBase dtoMappingRegistry, IServiceProvider serviceProvider, INoxApplicationLogger> logger, IUnitOfWork unitOfWork, ICacheService cacheService) - : BaseHandler(mapper, dtoMappingRegistry, serviceProvider), + : BaseHandler(mapper, serviceProvider), IRequestHandler> where TEntity : class, IEntityWithGuid { diff --git a/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Handlers/Anemic/GetAllEntitiesQueryHandler.cs b/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Handlers/Anemic/GetAllEntitiesQueryHandler.cs index de23a677..c7451a67 100644 --- a/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Handlers/Anemic/GetAllEntitiesQueryHandler.cs +++ b/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Handlers/Anemic/GetAllEntitiesQueryHandler.cs @@ -1,5 +1,4 @@ -using AppyNox.Services.Base.Application.DtoUtilities; -using AppyNox.Services.Base.Application.Exceptions.Base; +using AppyNox.Services.Base.Application.Exceptions.Base; using AppyNox.Services.Base.Application.Interfaces.Caches; using AppyNox.Services.Base.Application.Interfaces.Loggers; using AppyNox.Services.Base.Application.Interfaces.Repositories; @@ -12,15 +11,14 @@ namespace AppyNox.Services.Base.Application.MediatR.Handlers.Anemic; -internal class GetAllEntitiesQueryHandler( +internal class GetAllEntitiesQueryHandler( IGenericRepository repository, IMapper mapper, - IDtoMappingRegistryBase dtoMappingRegistry, IServiceProvider serviceProvider, - INoxApplicationLogger> logger, + INoxApplicationLogger> logger, ICacheService cacheService) - : BaseHandler(mapper, dtoMappingRegistry, serviceProvider), - IRequestHandler, PaginatedList> + : BaseHandler(mapper, serviceProvider), + IRequestHandler, PaginatedList> where TEntity : class, IEntityWithGuid { #region [ Fields ] @@ -35,16 +33,15 @@ internal class GetAllEntitiesQueryHandler( #region [ Public Methods ] - public async Task> Handle(GetAllEntitiesQuery request, CancellationToken cancellationToken) + public async Task> Handle(GetAllEntitiesQuery request, CancellationToken cancellationToken) { try { logger.LogInformation($"Fetching entities of type '{typeof(TEntity).Name}'"); - var dtoType = GetDtoType(request.QueryParameters); var paginatedEntityList = await _repository.GetAllAsync(request.QueryParameters, _cacheService); - var mappedItems = _mapper.Map(paginatedEntityList.Items, paginatedEntityList.Items.GetType(), typeof(IEnumerable<>).MakeGenericType(dtoType)) - as IEnumerable; - return new PaginatedList + var mappedItems = _mapper.Map>(paginatedEntityList.Items); + + return new PaginatedList { Items = mappedItems!, // risky ItemsCount = paginatedEntityList.ItemsCount, diff --git a/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Handlers/Anemic/GetEntityByIdQueryHandler.cs b/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Handlers/Anemic/GetEntityByIdQueryHandler.cs index 161052d9..27ca65c9 100644 --- a/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Handlers/Anemic/GetEntityByIdQueryHandler.cs +++ b/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Handlers/Anemic/GetEntityByIdQueryHandler.cs @@ -1,9 +1,7 @@ -using AppyNox.Services.Base.Application.DtoUtilities; -using AppyNox.Services.Base.Application.Exceptions.Base; +using AppyNox.Services.Base.Application.Exceptions.Base; using AppyNox.Services.Base.Application.Interfaces.Loggers; using AppyNox.Services.Base.Application.Interfaces.Repositories; using AppyNox.Services.Base.Application.MediatR.Commands; -using AppyNox.Services.Base.Core.Common; using AppyNox.Services.Base.Core.Exceptions.Base; using AppyNox.Services.Base.Domain.Interfaces; using AutoMapper; @@ -11,14 +9,13 @@ namespace AppyNox.Services.Base.Application.MediatR.Handlers.Anemic; -internal class GetEntityByIdQueryHandler( +internal class GetEntityByIdQueryHandler( IGenericRepository repository, IMapper mapper, - IDtoMappingRegistryBase dtoMappingRegistry, IServiceProvider serviceProvider, - INoxApplicationLogger> logger) - : BaseHandler(mapper, dtoMappingRegistry, serviceProvider), - IRequestHandler, object> + INoxApplicationLogger> logger) + : BaseHandler(mapper, serviceProvider), + IRequestHandler, TDto> where TEntity : class, IEntityWithGuid { #region [ Fields ] @@ -31,14 +28,13 @@ internal class GetEntityByIdQueryHandler( #region [ Public Methods ] - public async Task Handle(GetEntityByIdQuery request, CancellationToken cancellationToken) + public async Task Handle(GetEntityByIdQuery request, CancellationToken cancellationToken) { try { logger.LogInformation($"Fetching entity of type {typeof(TEntity).Name} with ID: {request.Id}."); - var dtoType = GetDtoType(request.QueryParameters); var entity = await _repository.GetByIdAsync(request.Id, request.QueryParameters.IncludeDeleted, request.Track); - return _mapper.Map(entity, typeof(TEntity), dtoType); + return _mapper.Map(entity); } catch (Exception ex) when (ex is INoxException) { diff --git a/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Handlers/Anemic/UpdateEntityCommandHandler.cs b/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Handlers/Anemic/UpdateEntityCommandHandler.cs index 65de51b7..86bb4874 100644 --- a/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Handlers/Anemic/UpdateEntityCommandHandler.cs +++ b/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Handlers/Anemic/UpdateEntityCommandHandler.cs @@ -1,13 +1,9 @@ using AppyNox.Services.Base.Application.Dtos; -using AppyNox.Services.Base.Application.DtoUtilities; using AppyNox.Services.Base.Application.Exceptions.Base; using AppyNox.Services.Base.Application.Interfaces.Loggers; using AppyNox.Services.Base.Application.Interfaces.Repositories; using AppyNox.Services.Base.Application.Localization; using AppyNox.Services.Base.Application.MediatR.Commands; -using AppyNox.Services.Base.Core.AsyncLocals; -using AppyNox.Services.Base.Core.Common; -using AppyNox.Services.Base.Core.Enums; using AppyNox.Services.Base.Core.Exceptions.Base; using AppyNox.Services.Base.Core.Extensions; using AppyNox.Services.Base.Domain.Interfaces; @@ -15,19 +11,17 @@ using MediatR; using System.Dynamic; using System.Net; -using System.Text.Json; namespace AppyNox.Services.Base.Application.MediatR.Handlers.Anemic; -internal class UpdateEntityCommandHandler( +internal class UpdateEntityCommandHandler( IGenericRepository repository, IMapper mapper, - IDtoMappingRegistryBase dtoMappingRegistry, IServiceProvider serviceProvider, - INoxApplicationLogger> logger, + INoxApplicationLogger> logger, IUnitOfWork unitOfWork) - : BaseHandler(mapper, dtoMappingRegistry, serviceProvider), - IRequestHandler> + : BaseHandler(mapper, serviceProvider), + IRequestHandler> where TEntity : class, IEntityWithGuid { #region [ Fields ] @@ -40,27 +34,20 @@ internal class UpdateEntityCommandHandler( #region [ Public Methods ] - public async Task Handle(UpdateEntityCommand request, CancellationToken cancellationToken) + public async Task Handle(UpdateEntityCommand request, CancellationToken cancellationToken) { try { - #region [ Dynamic Dto Convertion ] - - Type dtoType = DtoMappingRegistry.GetDtoType(DtoLevelMappingTypes.Update, typeof(TEntity), request.DetailLevel); - dynamic dtoObject = JsonSerializer.Deserialize(request.Dto, dtoType, options: JsonSerializerOptions); - - #endregion - #region [ Controls Before Update ] - if (dtoObject is not IUpdateDto) + if (request.Dto is not IUpdateDto) { throw new NoxApplicationException( NoxApplicationResourceService.IUpdateDtoNullId, (int)NoxApplicationExceptionCode.IUpdateDtoNullId, (int)HttpStatusCode.UnprocessableContent); } - if (dtoObject is IUpdateDto updateDto && !updateDto.Id.Equals(request.Id)) + if (request.Dto is IUpdateDto updateDto && !updateDto.Id.Equals(request.Id)) { throw new NoxApplicationException( NoxApplicationResourceService.MismatchedIdInUpdate.Format(updateDto.Id, request.Id), @@ -77,11 +64,11 @@ public async Task Handle(UpdateEntityCommand request, CancellationToken #region [ FluentValidation ] - FluentValidate(dtoType, dtoObject); + FluentValidate(request.Dto); #endregion - _repository.Update(existingEntity, dtoObject); + _repository.Update(existingEntity, request.Dto); await _unitOfWork.SaveChangesAsync(); } catch (Exception ex) when (ex is INoxException) diff --git a/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Handlers/DDD/CreateNoxEntityCommandHandler.cs b/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Handlers/DDD/CreateNoxEntityCommandHandler.cs index 037da16b..84bc6d49 100644 --- a/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Handlers/DDD/CreateNoxEntityCommandHandler.cs +++ b/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Handlers/DDD/CreateNoxEntityCommandHandler.cs @@ -1,28 +1,24 @@ -using AppyNox.Services.Base.Application.DtoUtilities; -using AppyNox.Services.Base.Application.Exceptions.Base; +using AppyNox.Services.Base.Application.Exceptions.Base; using AppyNox.Services.Base.Application.Interfaces.Caches; using AppyNox.Services.Base.Application.Interfaces.Loggers; using AppyNox.Services.Base.Application.Interfaces.Repositories; using AppyNox.Services.Base.Application.MediatR.Commands; -using AppyNox.Services.Base.Core.Enums; using AppyNox.Services.Base.Core.Exceptions.Base; using AppyNox.Services.Base.Domain.DDD.Interfaces; using AutoMapper; using MediatR; -using System.Text.Json; namespace AppyNox.Services.Base.Application.MediatR.Handlers.DDD; -internal sealed class CreateNoxEntityCommandHandler( +internal sealed class CreateNoxEntityCommandHandler( INoxRepository repository, IMapper mapper, - IDtoMappingRegistryBase dtoMappingRegistry, IServiceProvider serviceProvider, - INoxApplicationLogger> logger, + INoxApplicationLogger> logger, IUnitOfWork unitOfWork, ICacheService cacheService) - : BaseHandler(mapper, dtoMappingRegistry, serviceProvider), - IRequestHandler, Guid> + : BaseHandler(mapper, serviceProvider), + IRequestHandler, Guid> where TEntity : class, IHasStronglyTypedId { #region [ Fields ] @@ -37,27 +33,15 @@ internal sealed class CreateNoxEntityCommandHandler( #region [ Public Methods ] - public async Task Handle(CreateNoxEntityCommand request, CancellationToken cancellationToken) + public async Task Handle(CreateNoxEntityCommand request, CancellationToken cancellationToken) { try { logger.LogInformation($"Adding new entity of type '{typeof(TEntity).Name}'"); - Type entityType = typeof(TEntity); - #region [ Dynamic Dto Convertion ] + FluentValidate(request.Dto); - Type dtoType = DtoMappingRegistry.GetDtoType(DtoLevelMappingTypes.Create, entityType, request.DetailLevel); - dynamic? dtoObject = JsonSerializer.Deserialize(request.Dto, dtoType, options: JsonSerializerOptions); - - #endregion - - #region [ FluentValidation ] - - FluentValidate(dtoType, dtoObject); - - #endregion - - TEntity mappedEntity = Mapper.Map(dtoObject, dtoType, entityType); + TEntity mappedEntity = Mapper.Map(request.Dto); await _repository.AddAsync(mappedEntity); await _unitOfWork.SaveChangesAsync(); await UpdateTotalCountOnCache(_cacheService, $"total-count-{typeof(TEntity).Name}", true); diff --git a/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Handlers/DDD/DeleteNoxEntityCommandHandler.cs b/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Handlers/DDD/DeleteNoxEntityCommandHandler.cs index c87a3fa2..3f80dd34 100644 --- a/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Handlers/DDD/DeleteNoxEntityCommandHandler.cs +++ b/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Handlers/DDD/DeleteNoxEntityCommandHandler.cs @@ -1,5 +1,4 @@ -using AppyNox.Services.Base.Application.DtoUtilities; -using AppyNox.Services.Base.Application.Exceptions.Base; +using AppyNox.Services.Base.Application.Exceptions.Base; using AppyNox.Services.Base.Application.Interfaces.Caches; using AppyNox.Services.Base.Application.Interfaces.Loggers; using AppyNox.Services.Base.Application.Interfaces.Repositories; @@ -15,12 +14,11 @@ namespace AppyNox.Services.Base.Application.MediatR.Handlers.DDD; internal sealed class DeleteNoxEntityCommandHandler( INoxRepository repository, IMapper mapper, - IDtoMappingRegistryBase dtoMappingRegistry, IServiceProvider serviceProvider, INoxApplicationLogger> logger, IUnitOfWork unitOfWork, ICacheService cacheService) - : BaseHandler(mapper, dtoMappingRegistry, serviceProvider), + : BaseHandler(mapper, serviceProvider), IRequestHandler> where TEntity : class, IHasStronglyTypedId where TId : NoxId diff --git a/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Handlers/DDD/GetAllNoxEntitiesQueryHandler.cs b/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Handlers/DDD/GetAllNoxEntitiesQueryHandler.cs index e79b7857..3d32d2e5 100644 --- a/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Handlers/DDD/GetAllNoxEntitiesQueryHandler.cs +++ b/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Handlers/DDD/GetAllNoxEntitiesQueryHandler.cs @@ -1,5 +1,4 @@ -using AppyNox.Services.Base.Application.DtoUtilities; -using AppyNox.Services.Base.Application.Exceptions.Base; +using AppyNox.Services.Base.Application.Exceptions.Base; using AppyNox.Services.Base.Application.Interfaces.Caches; using AppyNox.Services.Base.Application.Interfaces.Loggers; using AppyNox.Services.Base.Application.Interfaces.Repositories; @@ -12,15 +11,14 @@ namespace AppyNox.Services.Base.Application.MediatR.Handlers.DDD; -internal class GetAllNoxEntitiesQueryHandler( +internal class GetAllNoxEntitiesQueryHandler( INoxRepository repository, IMapper mapper, - IDtoMappingRegistryBase dtoMappingRegistry, IServiceProvider serviceProvider, - INoxApplicationLogger> logger, + INoxApplicationLogger> logger, ICacheService cacheService) - : BaseHandler(mapper, dtoMappingRegistry, serviceProvider), - IRequestHandler, PaginatedList> + : BaseHandler(mapper, serviceProvider), + IRequestHandler, PaginatedList> where TEntity : class, IHasStronglyTypedId { #region [ Fields ] @@ -35,16 +33,15 @@ internal class GetAllNoxEntitiesQueryHandler( #region [ Public Methods ] - public async Task> Handle(GetAllNoxEntitiesQuery request, CancellationToken cancellationToken) + public async Task> Handle(GetAllNoxEntitiesQuery request, CancellationToken cancellationToken) { try { logger.LogInformation($"Fetching entities of type '{typeof(TEntity).Name}'"); - var dtoType = GetDtoType(request.QueryParameters); var paginatedEntityList = await _repository.GetAllAsync(request.QueryParameters, _cacheService); - var mappedItems = _mapper.Map(paginatedEntityList.Items, paginatedEntityList.Items.GetType(), typeof(IEnumerable<>).MakeGenericType(dtoType)) - as IEnumerable; - return new PaginatedList + var mappedItems = _mapper.Map>(paginatedEntityList.Items); + + return new PaginatedList { Items = mappedItems!, // risky ItemsCount = paginatedEntityList.ItemsCount, diff --git a/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Handlers/DDD/GetNoxEntityByIdQueryHandler.cs b/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Handlers/DDD/GetNoxEntityByIdQueryHandler.cs index 4653cd2b..93e4e950 100644 --- a/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Handlers/DDD/GetNoxEntityByIdQueryHandler.cs +++ b/src/Services/.BaseService/AppyNox.Services.Base.Application/MediatR/Handlers/DDD/GetNoxEntityByIdQueryHandler.cs @@ -1,5 +1,4 @@ -using AppyNox.Services.Base.Application.DtoUtilities; -using AppyNox.Services.Base.Application.Exceptions.Base; +using AppyNox.Services.Base.Application.Exceptions.Base; using AppyNox.Services.Base.Application.Interfaces.Loggers; using AppyNox.Services.Base.Application.Interfaces.Repositories; using AppyNox.Services.Base.Application.MediatR.Commands; @@ -11,14 +10,13 @@ namespace AppyNox.Services.Base.Application.MediatR.Handlers.DDD; -internal class GetNoxEntityByIdQueryHandler( +internal class GetNoxEntityByIdQueryHandler( INoxRepository repository, IMapper mapper, - IDtoMappingRegistryBase dtoMappingRegistry, IServiceProvider serviceProvider, - INoxApplicationLogger> logger) - : BaseHandler(mapper, dtoMappingRegistry, serviceProvider), - IRequestHandler, object> + INoxApplicationLogger> logger) + : BaseHandler(mapper, serviceProvider), + IRequestHandler, TDto> where TEntity : class, IHasStronglyTypedId where TId : NoxId { @@ -32,14 +30,13 @@ internal class GetNoxEntityByIdQueryHandler( #region [ Public Methods ] - public async Task Handle(GetNoxEntityByIdQuery request, CancellationToken cancellationToken) + public async Task Handle(GetNoxEntityByIdQuery request, CancellationToken cancellationToken) { try { logger.LogInformation($"Fetching entity of type {typeof(TEntity).Name} with ID: {request.Id}."); - var dtoType = GetDtoType(request.QueryParameters); - var entity = await _repository.GetByIdAsync(request.Id, request.QueryParameters.IncludeDeleted, request.Track); - return _mapper.Map(entity, typeof(TEntity), dtoType); + TEntity entity = await _repository.GetByIdAsync(request.Id, request.QueryParameters.IncludeDeleted, request.Track); + return _mapper.Map(entity); } catch (Exception ex) when (ex is INoxException) { diff --git a/src/Services/.BaseService/AppyNox.Services.Base.Infrastructure/Repositories/Common/QueryParameters.cs b/src/Services/.BaseService/AppyNox.Services.Base.Infrastructure/Repositories/Common/QueryParameters.cs index 674c327c..e6f0705a 100644 --- a/src/Services/.BaseService/AppyNox.Services.Base.Infrastructure/Repositories/Common/QueryParameters.cs +++ b/src/Services/.BaseService/AppyNox.Services.Base.Infrastructure/Repositories/Common/QueryParameters.cs @@ -1,6 +1,4 @@ -using AppyNox.Services.Base.Core.Enums; - -namespace AppyNox.Services.Base.Infrastructure.Repositories.Common; +namespace AppyNox.Services.Base.Infrastructure.Repositories.Common; /// /// Represents specific query parameters for data retrieval. diff --git a/src/Services/.BaseService/AppyNox.Services.Base.Infrastructure/Repositories/Common/QueryParametersBase.cs b/src/Services/.BaseService/AppyNox.Services.Base.Infrastructure/Repositories/Common/QueryParametersBase.cs index 609b8236..5910a016 100644 --- a/src/Services/.BaseService/AppyNox.Services.Base.Infrastructure/Repositories/Common/QueryParametersBase.cs +++ b/src/Services/.BaseService/AppyNox.Services.Base.Infrastructure/Repositories/Common/QueryParametersBase.cs @@ -1,7 +1,4 @@ -using AppyNox.Services.Base.Application.Constants; -using AppyNox.Services.Base.Application.Extensions; -using AppyNox.Services.Base.Application.Interfaces.Repositories; -using AppyNox.Services.Base.Core.Enums; +using AppyNox.Services.Base.Application.Interfaces.Repositories; using System.ComponentModel.DataAnnotations; namespace AppyNox.Services.Base.Infrastructure.Repositories.Common; @@ -18,45 +15,7 @@ public abstract class QueryParametersBase : IQueryParameters [Range(1, 100, ErrorMessage = "Page size must be between 1 and 100.")] public int PageSize { get; set; } = 10; - - public DtoLevelMappingTypes AccessType { get; set; } = DtoLevelMappingTypes.DataAccess; - - /// - /// Used only for converting AccessType, do not use this variable in code. - /// - public string Access - { - get => string.Empty; - - set - { - AccessType = Enum.TryParse(value, true, out var result) - ? result - : DtoLevelMappingTypes.DataAccess; - } - } - - private string _detailLevel = CommonDetailLevels.Simple; - - public string DetailLevel - { - get => _detailLevel; - - set - { - if (value.Equals("Simple", StringComparison.OrdinalIgnoreCase) || value.IsNullOrEmpty()) - { - _detailLevel = CommonDetailLevels.Simple; - } - else - { - _detailLevel = value; - } - } - } - public string SortBy { get; set; } = string.Empty; - public string Filter { get; set; } = string.Empty; public bool IncludeDeleted { get; set; } diff --git a/src/Services/.BaseService/Tests/IntegrationTests/AppyNox.Services.Base.IntegrationTests/Wrapper/Helpers/NoxResponseUnwrapper.cs b/src/Services/.BaseService/Tests/IntegrationTests/AppyNox.Services.Base.IntegrationTests/Wrapper/Helpers/NoxResponseUnwrapper.cs index 7a7249e9..f6ef0e1a 100644 --- a/src/Services/.BaseService/Tests/IntegrationTests/AppyNox.Services.Base.IntegrationTests/Wrapper/Helpers/NoxResponseUnwrapper.cs +++ b/src/Services/.BaseService/Tests/IntegrationTests/AppyNox.Services.Base.IntegrationTests/Wrapper/Helpers/NoxResponseUnwrapper.cs @@ -1,5 +1,7 @@ using AppyNox.Services.Base.API.Wrappers; +using AppyNox.Services.Base.API.Wrappers.Results; using System.Text.Json; +using static MassTransit.ValidationResultExtensions; namespace AppyNox.Services.Base.IntegrationTests.Wrapper.Helpers; @@ -7,17 +9,33 @@ public static class NoxResponseUnwrapper { #region [ Public Methods ] - public static async Task UnwrapResponse(HttpResponseMessage response, JsonSerializerOptions? jsonSerializerOptions = null) + public static async Task> UnwrapResponse(HttpResponseMessage response, JsonSerializerOptions? jsonSerializerOptions = null) { string jsonResponse = await response.Content.ReadAsStringAsync(); - NoxApiResponsePOCO responsePOCO = JsonSerializer.Deserialize(jsonResponse, jsonSerializerOptions) - ?? throw new Exception("Unwrapper - Response was null"); + NoxApiResponsePOCO? responsePOCO; + try + { + responsePOCO = JsonSerializer.Deserialize>(jsonResponse, jsonSerializerOptions) + ?? throw new Exception("Could not parsed."); + } + catch (Exception) + { + NoxApiResponsePOCO responsePOCO2 = JsonSerializer.Deserialize>(jsonResponse, jsonSerializerOptions)!; + responsePOCO = new NoxApiResponsePOCO() + { + Message = responsePOCO2.Message, + Code = responsePOCO2.Code, + HasError = responsePOCO2.HasError, + Version = responsePOCO2.Version, + Result = new NoxApiResultObject(default, responsePOCO2.Result?.Error) + }; + } responsePOCO.Code = (int)response.StatusCode; if (!responsePOCO.HasError) { - return new NoxApiResponse(responsePOCO); + return new NoxApiResponse(responsePOCO); } string? errorJson = responsePOCO.Result.Error?.ToString(); @@ -41,13 +59,13 @@ public static async Task UnwrapResponse(HttpResponseMessage resp responsePOCO.Result.Error = errorJson; } } - return new NoxApiResponse(responsePOCO); + return new NoxApiResponse(responsePOCO); } - public static T UnwrapData(string jsonResponse, JsonSerializerOptions? jsonSerializerOptions = null) + public static TData UnwrapData(string jsonResponse, JsonSerializerOptions? jsonSerializerOptions = null) { - var dataElement = ExtractDataElement(jsonResponse, jsonSerializerOptions); - return JsonSerializer.Deserialize(dataElement.GetRawText(), jsonSerializerOptions) + var dataElement = ExtractDataElement(jsonResponse, jsonSerializerOptions); + return JsonSerializer.Deserialize(dataElement.GetRawText(), jsonSerializerOptions) ?? throw new Exception("Unwrapper - Unwrapped Object was null"); } @@ -55,9 +73,9 @@ public static T UnwrapData(string jsonResponse, JsonSerializerOptions? jsonSe #region [ Private Methods ] - private static JsonElement ExtractDataElement(string jsonResponse, JsonSerializerOptions? jsonSerializerOptions = null) + private static JsonElement ExtractDataElement(string jsonResponse, JsonSerializerOptions? jsonSerializerOptions = null) { - var apiResponse = JsonSerializer.Deserialize(jsonResponse, jsonSerializerOptions); + var apiResponse = JsonSerializer.Deserialize>(jsonResponse, jsonSerializerOptions); if (apiResponse?.Result != null && apiResponse.Result.Data is JsonElement dataElement) { diff --git a/src/Services/.BaseService/Tests/UnitTests/AppyNox.Services.Base.Application.UnitTests/AppyNox.Services.Base.Application.UnitTests.csproj b/src/Services/.BaseService/Tests/UnitTests/AppyNox.Services.Base.Application.UnitTests/AppyNox.Services.Base.Application.UnitTests.csproj index 5422e8b7..b37707aa 100644 --- a/src/Services/.BaseService/Tests/UnitTests/AppyNox.Services.Base.Application.UnitTests/AppyNox.Services.Base.Application.UnitTests.csproj +++ b/src/Services/.BaseService/Tests/UnitTests/AppyNox.Services.Base.Application.UnitTests/AppyNox.Services.Base.Application.UnitTests.csproj @@ -23,7 +23,11 @@ + + + + diff --git a/src/Services/.BaseService/Tests/UnitTests/AppyNox.Services.Base.Application.UnitTests/CQRSFixtures/NoxApplicationTestFixture.cs b/src/Services/.BaseService/Tests/UnitTests/AppyNox.Services.Base.Application.UnitTests/CQRSFixtures/NoxApplicationTestFixture.cs index d2510219..8aaefd2b 100644 --- a/src/Services/.BaseService/Tests/UnitTests/AppyNox.Services.Base.Application.UnitTests/CQRSFixtures/NoxApplicationTestFixture.cs +++ b/src/Services/.BaseService/Tests/UnitTests/AppyNox.Services.Base.Application.UnitTests/CQRSFixtures/NoxApplicationTestFixture.cs @@ -3,10 +3,11 @@ using AppyNox.Services.Base.Application.Interfaces.Repositories; using AppyNox.Services.Base.Application.Localization; using AppyNox.Services.Base.Application.UnitTests.Stubs; -using AppyNox.Services.Base.Core.Enums; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Localization; using Moq; +using Serilog; +using Serilog.Sinks.InMemory; namespace AppyNox.Services.Base.Application.UnitTests.CQRSFixtures; @@ -40,21 +41,28 @@ public NoxApplicationTestFixture() MockQueryParameters = new Mock(); MockQueryParameters.Setup(p => p.PageNumber).Returns(1); MockQueryParameters.Setup(p => p.PageSize).Returns(10); - MockQueryParameters.Setup(p => p.AccessType).Returns(DtoLevelMappingTypes.DataAccess); - MockQueryParameters.Setup(p => p.Access).Returns(string.Empty); - MockQueryParameters.Setup(p => p.DetailLevel).Returns("Simple"); #endregion #region [ Localization ] - var localizer = new Mock(); - localizer.Setup(l => l[It.IsAny()]).Returns(new LocalizedString("key", "mock value")); + InMemorySink inMemorySink = new(); + Log.Logger = new LoggerConfiguration() + .WriteTo.Sink(inMemorySink) + .CreateLogger(); - var localizerFactory = new Mock(); - localizerFactory.Setup(lf => lf.Create(typeof(NoxApplicationResourceService))).Returns(localizer.Object); + ServiceCollection.AddLogging(builder => + { + builder.AddSerilog(); + }); - NoxApplicationResourceService.Initialize(localizerFactory.Object); + ServiceCollection.AddScoped(typeof(INoxApplicationLogger<>), typeof(NoxApplicationLoggerStub<>)); + + ServiceCollection.AddLocalization(); + + var serviceProvider = ServiceCollection.BuildServiceProvider(); + var factory = serviceProvider.GetRequiredService(); + NoxApplicationResourceService.Initialize(factory); #endregion diff --git a/src/Services/.BaseService/Tests/UnitTests/AppyNox.Services.Base.Infrastructure.UnitTest/AppyNox.Services.Base.Infrastructure.UnitTest.csproj b/src/Services/.BaseService/Tests/UnitTests/AppyNox.Services.Base.Infrastructure.UnitTest/AppyNox.Services.Base.Infrastructure.UnitTest.csproj deleted file mode 100644 index 6bfa35bb..00000000 --- a/src/Services/.BaseService/Tests/UnitTests/AppyNox.Services.Base.Infrastructure.UnitTest/AppyNox.Services.Base.Infrastructure.UnitTest.csproj +++ /dev/null @@ -1,29 +0,0 @@ - - - - net8.0 - enable - enable - - false - true - - - - - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - - - - - - - - diff --git a/src/Services/.BaseService/Tests/UnitTests/AppyNox.Services.Base.Infrastructure.UnitTest/GlobalUsings.cs b/src/Services/.BaseService/Tests/UnitTests/AppyNox.Services.Base.Infrastructure.UnitTest/GlobalUsings.cs deleted file mode 100644 index 8c927eb7..00000000 --- a/src/Services/.BaseService/Tests/UnitTests/AppyNox.Services.Base.Infrastructure.UnitTest/GlobalUsings.cs +++ /dev/null @@ -1 +0,0 @@ -global using Xunit; \ No newline at end of file diff --git a/src/Services/.BaseService/Tests/UnitTests/AppyNox.Services.Base.Infrastructure.UnitTest/RepositoryTests/CommonTests/QueryParameterTests.cs b/src/Services/.BaseService/Tests/UnitTests/AppyNox.Services.Base.Infrastructure.UnitTest/RepositoryTests/CommonTests/QueryParameterTests.cs deleted file mode 100644 index d95f31ed..00000000 --- a/src/Services/.BaseService/Tests/UnitTests/AppyNox.Services.Base.Infrastructure.UnitTest/RepositoryTests/CommonTests/QueryParameterTests.cs +++ /dev/null @@ -1,286 +0,0 @@ -using AppyNox.Services.Base.Application.Constants; -using AppyNox.Services.Base.Core.Enums; -using AppyNox.Services.Base.Core.Extensions; -using AppyNox.Services.Base.Infrastructure.Repositories.Common; - -namespace AppyNox.Services.Base.Infrastructure.UnitTest.RepositoryTests.CommonTests -{ - public class QueryParameterTests - { - #region [ Fields ] - - private const string _uncommonDetail = "UncommonDetail"; - - #endregion - - #region [ Public Constructors ] - - [Fact] - public void BaseQueryParameterInitializationShouldBeCorrect() - { - QueryParameters queryParameters = new(); - - Assert.Equal(1, queryParameters.PageNumber); - Assert.Equal(10, queryParameters.PageSize); - Assert.Equal(DtoLevelMappingTypes.DataAccess, queryParameters.AccessType); - Assert.Equal(CommonDetailLevels.Simple, queryParameters.DetailLevel); - Assert.Equal(string.Empty, queryParameters.Access); - } - - #endregion - - #region [ DataAccess Tests ] - - /// - /// Access = "" - /// DetailLevel = "Simple" - /// - [Fact] - public void DataAccess_InitializationForSimpleShouldBeCorrect() - { - QueryParameters queryParameters = new() - { - Access = string.Empty - }; - - Assert.Equal(1, queryParameters.PageNumber); - Assert.Equal(10, queryParameters.PageSize); - Assert.Equal(DtoLevelMappingTypes.DataAccess, queryParameters.AccessType); - Assert.Equal(CommonDetailLevels.Simple, queryParameters.DetailLevel); - Assert.Equal(string.Empty, queryParameters.Access); - } - - /// - /// Access = "" - /// DetailLevel = "simple" - /// for case insensitive testing - /// - [Fact] - public void DataAccess_InitializationForSimpleDetailLevelCaseInsensitiveShouldBeCorrect() - { - QueryParameters queryParameters = new() - { - Access = string.Empty, - DetailLevel = "simple" - }; - - Assert.Equal(1, queryParameters.PageNumber); - Assert.Equal(10, queryParameters.PageSize); - Assert.Equal(DtoLevelMappingTypes.DataAccess, queryParameters.AccessType); - Assert.Equal(CommonDetailLevels.Simple, queryParameters.DetailLevel); - Assert.Equal(string.Empty, queryParameters.Access); - } - - /// - /// Access = "DataAccess" - /// DetailLevel = "simple" - /// - [Fact] - public void DataAccess_InitializationForSimpleDetailLevelCaseInsensitiveShouldBeCorrectWithAccess() - { - QueryParameters queryParameters = new() - { - Access = DtoLevelMappingTypes.DataAccess.GetDisplayName(), - DetailLevel = "simple" - }; - - Assert.Equal(1, queryParameters.PageNumber); - Assert.Equal(10, queryParameters.PageSize); - Assert.Equal(DtoLevelMappingTypes.DataAccess, queryParameters.AccessType); - Assert.Equal(CommonDetailLevels.Simple, queryParameters.DetailLevel); - Assert.Equal(string.Empty, queryParameters.Access); - } - - /// - /// Access = "" - /// DetailLevel = "UncommonDetail" - /// - [Fact] - public void DataAccess_InitializationForNoneShouldBeCorrect() - { - QueryParameters queryParameters = new() - { - Access = string.Empty, - DetailLevel = _uncommonDetail - }; - - Assert.Equal(1, queryParameters.PageNumber); - Assert.Equal(10, queryParameters.PageSize); - Assert.Equal(DtoLevelMappingTypes.DataAccess, queryParameters.AccessType); - Assert.Equal(_uncommonDetail, queryParameters.DetailLevel); - Assert.Equal(string.Empty, queryParameters.Access); - } - - #endregion - - #region [ Update Tests ] - - /// - /// Access = "Update" - /// DetailLevel = "" - /// - [Fact] - public void Update_InitializationForSimpleShouldBeCorrect() - { - QueryParameters queryParameters = new() - { - Access = DtoLevelMappingTypes.Update.GetDisplayName(), - DetailLevel = string.Empty - }; - - Assert.Equal(1, queryParameters.PageNumber); - Assert.Equal(10, queryParameters.PageSize); - Assert.Equal(DtoLevelMappingTypes.Update, queryParameters.AccessType); - Assert.Equal(CommonDetailLevels.Simple, queryParameters.DetailLevel); - Assert.Equal(string.Empty, queryParameters.Access); - } - - /// - /// Access = "Update" - /// DetailLevel = "Simple" - /// - [Fact] - public void Update_InitializationForSimpleWithAccessAndDetailLevelShouldBeCorrect() - { - QueryParameters queryParameters = new() - { - Access = DtoLevelMappingTypes.Update.GetDisplayName(), - DetailLevel = CommonDetailLevels.Simple - }; - - Assert.Equal(1, queryParameters.PageNumber); - Assert.Equal(10, queryParameters.PageSize); - Assert.Equal(DtoLevelMappingTypes.Update, queryParameters.AccessType); - Assert.Equal(CommonDetailLevels.Simple, queryParameters.DetailLevel); - Assert.Equal(string.Empty, queryParameters.Access); - } - - /// - /// Access = "update" - /// DetailLevel = "simple" - /// for case insensitive testing - /// - [Fact] - public void Update_InitializationForSimpleDetailLevelAndAccessCaseInsensitiveShouldBeCorrect() - { - QueryParameters queryParameters = new() - { - Access = "update", - DetailLevel = "simple" - }; - - Assert.Equal(1, queryParameters.PageNumber); - Assert.Equal(10, queryParameters.PageSize); - Assert.Equal(DtoLevelMappingTypes.Update, queryParameters.AccessType); - Assert.Equal(CommonDetailLevels.Simple, queryParameters.DetailLevel); - Assert.Equal(string.Empty, queryParameters.Access); - } - - /// - /// Access = "update" - /// DetailLevel = "Extended" - /// - [Fact] - public void Update_InitializationForExtendedShouldBeCorrect() - { - QueryParameters queryParameters = new() - { - Access = "update", - DetailLevel = "Extended" - }; - - Assert.Equal(1, queryParameters.PageNumber); - Assert.Equal(10, queryParameters.PageSize); - Assert.Equal(DtoLevelMappingTypes.Update, queryParameters.AccessType); - Assert.Equal(CommonDetailLevels.Extended, queryParameters.DetailLevel); - Assert.Equal(string.Empty, queryParameters.Access); - } - - #endregion - - #region [ Create Tests ] - - /// - /// Access = "Create" - /// DetailLevel = "" - /// - [Fact] - public void Create_InitializationForSimpleShouldBeCorrect() - { - QueryParameters queryParameters = new() - { - Access = DtoLevelMappingTypes.Create.GetDisplayName(), - DetailLevel = string.Empty - }; - - Assert.Equal(1, queryParameters.PageNumber); - Assert.Equal(10, queryParameters.PageSize); - Assert.Equal(DtoLevelMappingTypes.Create, queryParameters.AccessType); - Assert.Equal(CommonDetailLevels.Simple, queryParameters.DetailLevel); - Assert.Equal(string.Empty, queryParameters.Access); - } - - /// - /// Access = "Create" - /// DetailLevel = "Simple" - /// - [Fact] - public void Create_InitializationForSimpleWithAccessAndDetailLevelShouldBeCorrect() - { - QueryParameters queryParameters = new() - { - Access = DtoLevelMappingTypes.Create.GetDisplayName(), - DetailLevel = CommonDetailLevels.Simple - }; - - Assert.Equal(1, queryParameters.PageNumber); - Assert.Equal(10, queryParameters.PageSize); - Assert.Equal(DtoLevelMappingTypes.Create, queryParameters.AccessType); - Assert.Equal(CommonDetailLevels.Simple, queryParameters.DetailLevel); - Assert.Equal(string.Empty, queryParameters.Access); - } - - /// - /// Access = "create" - /// DetailLevel = "simple" - /// for case insensitive testing - /// - [Fact] - public void Create_InitializationForSimpleDetailLevelAndAccessCaseInsensitiveShouldBeCorrect() - { - QueryParameters queryParameters = new() - { - Access = "create", - DetailLevel = "simple" - }; - - Assert.Equal(1, queryParameters.PageNumber); - Assert.Equal(10, queryParameters.PageSize); - Assert.Equal(DtoLevelMappingTypes.Create, queryParameters.AccessType); - Assert.Equal(CommonDetailLevels.Simple, queryParameters.DetailLevel); - Assert.Equal(string.Empty, queryParameters.Access); - } - - /// - /// Access = "create" - /// DetailLevel = "Extended" - /// - [Fact] - public void Create_InitializationForExtendedAccessCaseInsensitiveShouldBeCorrect() - { - QueryParameters queryParameters = new() - { - Access = "create", - DetailLevel = CommonDetailLevels.Extended - }; - - Assert.Equal(1, queryParameters.PageNumber); - Assert.Equal(10, queryParameters.PageSize); - Assert.Equal(DtoLevelMappingTypes.Create, queryParameters.AccessType); - Assert.Equal(CommonDetailLevels.Extended, queryParameters.DetailLevel); - Assert.Equal(string.Empty, queryParameters.Access); - } - - #endregion - } -} \ No newline at end of file diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/AppyNox.Services.Coupon.Application.csproj b/src/Services/CouponService/AppyNox.Services.Coupon.Application/AppyNox.Services.Coupon.Application.csproj index def2ce6e..13600c56 100644 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/AppyNox.Services.Coupon.Application.csproj +++ b/src/Services/CouponService/AppyNox.Services.Coupon.Application/AppyNox.Services.Coupon.Application.csproj @@ -6,16 +6,11 @@ enable preview - - + - - - - diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/DependencyInjection.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/DependencyInjection.cs index ddc29ba6..d4cc4cee 100644 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/DependencyInjection.cs +++ b/src/Services/CouponService/AppyNox.Services.Coupon.Application/DependencyInjection.cs @@ -1,9 +1,12 @@ using AppyNox.Services.Base.Application; using AppyNox.Services.Base.Application.Extensions; using AppyNox.Services.Base.Application.Interfaces.Loggers; -using AppyNox.Services.Coupon.Application.DtoUtilities; +using AppyNox.Services.Base.Application.MediatR.Commands; +using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models; +using AppyNox.Services.Coupon.Application.Dtos.TicketDtos.Models; using AppyNox.Services.Coupon.Domain.Coupons; using AppyNox.Services.Coupon.Domain.Entities; +using MediatR; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using System.Reflection; @@ -23,12 +26,13 @@ public static IServiceCollection AddCouponApplication(this IServiceCollection se options.UseAutoMapper = true; options.UseFluentValidation = true; options.UseDtoMappingRegistry = true; - options.DtoMappingRegistryFactory = provider => new DtoMappingRegistry(); options.UseMediatR = true; }); - services.AddNoxEntityCommands(); - services.AddAnemicEntityCommands(); + services.AddNoxEntityCommands(); + services.AddNoxEntityCompositeCreateCommand(); + + services.AddAnemicEntityCommands(); return services; } diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/DtoUtilities/DtoMappingRegistry.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/DtoUtilities/DtoMappingRegistry.cs deleted file mode 100644 index 89e1f7eb..00000000 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/DtoUtilities/DtoMappingRegistry.cs +++ /dev/null @@ -1,134 +0,0 @@ -using AppyNox.Services.Base.Application.DtoUtilities; -using AppyNox.Services.Base.Core.Enums; -using AppyNox.Services.Coupon.Application.Dtos.CouponDetailDtos.DetailLevel; -using AppyNox.Services.Coupon.Application.Dtos.CouponDetailTagDtos.DetailLevel; -using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.DetailLevel; -using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.Base; -using AppyNox.Services.Coupon.Application.Dtos.TicketDtos.DetailLevel; -using AppyNox.Services.Coupon.Application.Dtos.TicketTagDtos.DetailLevel; -using AppyNox.Services.Coupon.Application.Exceptions.Base; -using AppyNox.Services.Coupon.Domain.Coupons; -using AppyNox.Services.Coupon.Domain.Entities; -using System.Data; -using System.Reflection; - -namespace AppyNox.Services.Coupon.Application.DtoUtilities -{ - public class DtoMappingRegistry : DtoMappingRegistryBase - { - #region [ Public Methods ] - - public DtoMappingRegistry() - : base() - { - RegisterDtos(); - } - - public static Enum GetDetailLevel(Attribute attribute, DtoLevelMappingTypes mappingType) - { - if (attribute is CouponDetailLevelAttribute couponDetailAttribute) - { - return mappingType switch - { - DtoLevelMappingTypes.DataAccess => couponDetailAttribute.DataAccessDetailLevel, - DtoLevelMappingTypes.Create => couponDetailAttribute.CreateDetailLevel, - DtoLevelMappingTypes.Update => couponDetailAttribute.UpdateDetailLevel, - _ => couponDetailAttribute.DataAccessDetailLevel - }; - } - else if (attribute is CouponDetailDetailLevelAttribute couponDetailDetailAttribute) - { - return mappingType switch - { - DtoLevelMappingTypes.DataAccess => couponDetailDetailAttribute.DataAccessDetailLevel, - DtoLevelMappingTypes.Create => couponDetailDetailAttribute.CreateDetailLevel, - DtoLevelMappingTypes.Update => couponDetailDetailAttribute.UpdateDetailLevel, - _ => couponDetailDetailAttribute.DataAccessDetailLevel - }; - } - else if (attribute is CouponDetailTagDetailLevelAttribute couponDetailTagDetailAttribute) - { - return mappingType switch - { - DtoLevelMappingTypes.DataAccess => couponDetailTagDetailAttribute.DataAccessDetailLevel, - DtoLevelMappingTypes.Create => couponDetailTagDetailAttribute.CreateDetailLevel, - DtoLevelMappingTypes.Update => couponDetailTagDetailAttribute.UpdateDetailLevel, - _ => couponDetailTagDetailAttribute.DataAccessDetailLevel - }; - } - else if (attribute is TicketDetailLevelAttribute ticketDetailLevelAttribute) - { - return mappingType switch - { - DtoLevelMappingTypes.DataAccess => ticketDetailLevelAttribute.DataAccessDetailLevel, - DtoLevelMappingTypes.Create => ticketDetailLevelAttribute.CreateDetailLevel, - DtoLevelMappingTypes.Update => ticketDetailLevelAttribute.UpdateDetailLevel, - _ => ticketDetailLevelAttribute.DataAccessDetailLevel - }; - } - else if (attribute is TicketTagDetailLevelAttribute ticketTagDetailLevelAttribute) - { - return mappingType switch - { - DtoLevelMappingTypes.DataAccess => ticketTagDetailLevelAttribute.DataAccessDetailLevel, - DtoLevelMappingTypes.Create => ticketTagDetailLevelAttribute.CreateDetailLevel, - DtoLevelMappingTypes.Update => ticketTagDetailLevelAttribute.UpdateDetailLevel, - _ => ticketTagDetailLevelAttribute.DataAccessDetailLevel - }; - } - throw new NoxCouponApplicationException( - "Unsupported attribute type for detail level mapping. Check DtoMappingRegistry", - (int)NoxCouponApplicationExceptionCode.DtoMappingRegistryError); - } - - #endregion - - #region [ Protected Methods ] - - protected override void RegisterDtos() - { - var dtoTypes = Assembly.GetAssembly(typeof(CouponSimpleDto))? - .GetTypes() - .Where(t => t.Namespace != null && t.Namespace.Contains("Application.Dtos") && t.Namespace.Contains("Models")) - .ToList(); - - if (dtoTypes == null) - return; - - foreach (var dtoType in dtoTypes) - { - var attributes = Attribute.GetCustomAttributes(dtoType); - foreach (var attribute in attributes) - { - if (attribute is CouponDetailLevelAttribute couponAttribute) - { - RegisterMapping(typeof(Domain.Coupons.Coupon), dtoType, couponAttribute); - } - else if (attribute is CouponDetailDetailLevelAttribute couponDetailAttribute) - { - RegisterMapping(typeof(CouponDetail), dtoType, couponDetailAttribute); - } - else if (attribute is CouponDetailTagDetailLevelAttribute couponDetailTagAttribute) - { - RegisterMapping(typeof(CouponDetailTag), dtoType, couponDetailTagAttribute); - } - else if (attribute is TicketDetailLevelAttribute ticketDetailLevelAttribute) - { - RegisterMapping(typeof(Ticket), dtoType, ticketDetailLevelAttribute); - } - else if (attribute is TicketTagDetailLevelAttribute ticketTagDetailLevelAttribute) - { - RegisterMapping(typeof(TicketTag), dtoType, ticketTagDetailLevelAttribute); - } - } - } - } - - protected override Enum GetDetailLevelBase(Attribute attribute, DtoLevelMappingTypes mappingType) - { - return GetDetailLevel(attribute, mappingType); - } - - #endregion - } -} \ No newline at end of file diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailDtos/DetailLevel/CouponDetailDetailLevelAttribute.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailDtos/DetailLevel/CouponDetailDetailLevelAttribute.cs deleted file mode 100644 index 1105dc1f..00000000 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailDtos/DetailLevel/CouponDetailDetailLevelAttribute.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace AppyNox.Services.Coupon.Application.Dtos.CouponDetailDtos.DetailLevel -{ - public enum CouponDetailDataAccessDetailLevel - { - [Display(Name = "Simple")] - Simple, - - [Display(Name = "WithAllRelations")] - WithAllRelations - } - - public enum CouponDetailCreateDetailLevel - { - [Display(Name = "Simple")] - Simple, - - [Display(Name = "Extended")] - Extended - } - - public enum CouponDetailUpdateDetailLevel - { - [Display(Name = "Simple")] - Simple, - - [Display(Name = "Extended")] - Extended - } - - [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)] - public class CouponDetailDetailLevelAttribute : Attribute - { - #region [ Public Constructors ] - - public CouponDetailDetailLevelAttribute(CouponDetailDataAccessDetailLevel dataAccessDetailLevel) - { - DataAccessDetailLevel = dataAccessDetailLevel; - } - - public CouponDetailDetailLevelAttribute(CouponDetailCreateDetailLevel createDetailLevel) - { - CreateDetailLevel = createDetailLevel; - } - - public CouponDetailDetailLevelAttribute(CouponDetailUpdateDetailLevel updateDetailLevel) - { - UpdateDetailLevel = updateDetailLevel; - } - - #endregion - - #region [ Properties ] - - public CouponDetailDataAccessDetailLevel DataAccessDetailLevel { get; } - - public CouponDetailCreateDetailLevel CreateDetailLevel { get; } - - public CouponDetailUpdateDetailLevel UpdateDetailLevel { get; } - - #endregion - } -} \ No newline at end of file diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailDtos/Models/Basic/CouponDetailBulkCreateDto.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailDtos/Models/CouponDetailCompositeCreateDto.cs similarity index 71% rename from src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailDtos/Models/Basic/CouponDetailBulkCreateDto.cs rename to src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailDtos/Models/CouponDetailCompositeCreateDto.cs index b87a55c9..c8a1bfea 100644 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailDtos/Models/Basic/CouponDetailBulkCreateDto.cs +++ b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailDtos/Models/CouponDetailCompositeCreateDto.cs @@ -1,9 +1,9 @@ -using AppyNox.Services.Coupon.Application.Dtos.CouponDetailTagDtos.Models.Basic; +using AppyNox.Services.Coupon.Application.Dtos.CouponDetailTagDtos.Models; -namespace AppyNox.Services.Coupon.Application.Dtos.CouponDetailDtos.Models.Basic; +namespace AppyNox.Services.Coupon.Application.Dtos.CouponDetailDtos.Models; // No need for detail level for nested bulk dtos -public class CouponDetailBulkCreateDto +public class CouponDetailCompositeCreateDto { #region [ Properties ] @@ -19,7 +19,7 @@ public class CouponDetailBulkCreateDto #region [ Relations ] - public IEnumerable? CouponDetailTags { get; set; } + public IEnumerable? CouponDetailTags { get; set; } #endregion } \ No newline at end of file diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailDtos/Models/Basic/CouponDetailSimpleDto.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailDtos/Models/CouponDetailDto.cs similarity index 68% rename from src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailDtos/Models/Basic/CouponDetailSimpleDto.cs rename to src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailDtos/Models/CouponDetailDto.cs index d953d33a..3d6488ff 100644 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailDtos/Models/Basic/CouponDetailSimpleDto.cs +++ b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailDtos/Models/CouponDetailDto.cs @@ -1,11 +1,10 @@ using AppyNox.Services.Base.Domain.Interfaces; -using AppyNox.Services.Coupon.Application.Dtos.CouponDetailDtos.DetailLevel; -using AppyNox.Services.Coupon.Application.Dtos.CouponDetailTagDtos.Models.Basic; +using AppyNox.Services.Coupon.Application.Dtos.CouponDetailDtos.Models.ValueObjects; +using AppyNox.Services.Coupon.Application.Dtos.CouponDetailTagDtos.Models; -namespace AppyNox.Services.Coupon.Application.Dtos.CouponDetailDtos.Models.Basic; +namespace AppyNox.Services.Coupon.Application.Dtos.CouponDetailDtos.Models; -[CouponDetailDetailLevel(CouponDetailDataAccessDetailLevel.Simple)] -public class CouponDetailSimpleDto : IHasCode +public class CouponDetailDto : IHasCode { #region [ Properties ] @@ -23,7 +22,7 @@ public class CouponDetailSimpleDto : IHasCode #region [ Relations ] - public ICollection? CouponDetailTags { get; set; } + public ICollection? CouponDetailTags { get; set; } #endregion } \ No newline at end of file diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailDtos/Models/Basic/CouponDetailIdDto.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailDtos/Models/ValueObjects/CouponDetailIdDto.cs similarity index 86% rename from src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailDtos/Models/Basic/CouponDetailIdDto.cs rename to src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailDtos/Models/ValueObjects/CouponDetailIdDto.cs index 58a47004..6c422c09 100644 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailDtos/Models/Basic/CouponDetailIdDto.cs +++ b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailDtos/Models/ValueObjects/CouponDetailIdDto.cs @@ -1,4 +1,4 @@ -namespace AppyNox.Services.Coupon.Application.Dtos.CouponDetailDtos.Models.Basic; +namespace AppyNox.Services.Coupon.Application.Dtos.CouponDetailDtos.Models.ValueObjects; public class CouponDetailIdDto { diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailDtos/Profiles/CouponDetailProfile.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailDtos/Profiles/CouponDetailProfile.cs index b5db5f65..7c1a6780 100644 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailDtos/Profiles/CouponDetailProfile.cs +++ b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailDtos/Profiles/CouponDetailProfile.cs @@ -1,5 +1,5 @@ -using AppyNox.Services.Coupon.Application.Dtos.CouponDetailDtos.Models.Basic; -using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.Base; +using AppyNox.Services.Coupon.Application.Dtos.CouponDetailDtos.Models; +using AppyNox.Services.Coupon.Application.Dtos.CouponDetailDtos.Models.ValueObjects; using AppyNox.Services.Coupon.Domain.Coupons; using AppyNox.Services.Coupon.Domain.Coupons.Builders; using AutoMapper; @@ -12,7 +12,7 @@ public class CouponDetailProfile : Profile public CouponDetailProfile() { - CreateMap() + CreateMap() .ConstructUsing((src, context) => { return new CouponDetailBuilder() @@ -21,7 +21,7 @@ public CouponDetailProfile() .Build(); }); - CreateMap().ReverseMap(); + CreateMap().ReverseMap(); CreateMap().ReverseMap(); } diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailTagDtos/DetailLevel/CouponDetailTagDetailLevelAttribute.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailTagDtos/DetailLevel/CouponDetailTagDetailLevelAttribute.cs deleted file mode 100644 index 9f3e79cb..00000000 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailTagDtos/DetailLevel/CouponDetailTagDetailLevelAttribute.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace AppyNox.Services.Coupon.Application.Dtos.CouponDetailTagDtos.DetailLevel; - -public enum CouponDetailTagDataAccessDetailLevel -{ - [Display(Name = "Simple")] - Simple, - - [Display(Name = "WithAllRelations")] - WithAllRelations -} - -public enum CouponDetailTagCreateDetailLevel -{ - [Display(Name = "Simple")] - Simple, - - [Display(Name = "Extended")] - Extended -} - -public enum CouponDetailTagUpdateDetailLevel -{ - [Display(Name = "Simple")] - Simple, - - [Display(Name = "Extended")] - Extended -} - -[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)] -public class CouponDetailTagDetailLevelAttribute : Attribute -{ - #region [ Public Constructors ] - - public CouponDetailTagDetailLevelAttribute(CouponDetailTagDataAccessDetailLevel dataAccessDetailLevel) - { - DataAccessDetailLevel = dataAccessDetailLevel; - } - - public CouponDetailTagDetailLevelAttribute(CouponDetailTagCreateDetailLevel createDetailLevel) - { - CreateDetailLevel = createDetailLevel; - } - - public CouponDetailTagDetailLevelAttribute(CouponDetailTagUpdateDetailLevel updateDetailLevel) - { - UpdateDetailLevel = updateDetailLevel; - } - - #endregion - - #region [ Properties ] - - public CouponDetailTagDataAccessDetailLevel DataAccessDetailLevel { get; } - - public CouponDetailTagCreateDetailLevel CreateDetailLevel { get; } - - public CouponDetailTagUpdateDetailLevel UpdateDetailLevel { get; } - - #endregion -} \ No newline at end of file diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailTagDtos/Models/Basic/CouponDetailTagBulkCreateDto.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailTagDtos/Models/Basic/CouponDetailTagBulkCreateDto.cs deleted file mode 100644 index c0d0a584..00000000 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailTagDtos/Models/Basic/CouponDetailTagBulkCreateDto.cs +++ /dev/null @@ -1,13 +0,0 @@ -using AppyNox.Services.Coupon.Application.Dtos.CouponDetailDtos.Models.Basic; - -namespace AppyNox.Services.Coupon.Application.Dtos.CouponDetailTagDtos.Models.Basic; - -// No need for detail level for nested bulk dtos -public class CouponDetailTagBulkCreateDto -{ - #region [ Properties ] - - public string Tag { get; set; } = string.Empty; - - #endregion -} \ No newline at end of file diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailTagDtos/Models/CouponDetailTagCompositeCreateDto.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailTagDtos/Models/CouponDetailTagCompositeCreateDto.cs new file mode 100644 index 00000000..9aa14f42 --- /dev/null +++ b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailTagDtos/Models/CouponDetailTagCompositeCreateDto.cs @@ -0,0 +1,11 @@ +namespace AppyNox.Services.Coupon.Application.Dtos.CouponDetailTagDtos.Models; + +// No need for detail level for nested bulk dtos +public class CouponDetailTagCompositeCreateDto +{ + #region [ Properties ] + + public string Tag { get; set; } = string.Empty; + + #endregion +} \ No newline at end of file diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailTagDtos/Models/Basic/CouponDetailTagSimpleDto.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailTagDtos/Models/CouponDetailTagDto.cs similarity index 65% rename from src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailTagDtos/Models/Basic/CouponDetailTagSimpleDto.cs rename to src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailTagDtos/Models/CouponDetailTagDto.cs index 57a0c088..5d23f4d1 100644 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailTagDtos/Models/Basic/CouponDetailTagSimpleDto.cs +++ b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailTagDtos/Models/CouponDetailTagDto.cs @@ -1,9 +1,8 @@ -using AppyNox.Services.Coupon.Application.Dtos.CouponDetailTagDtos.DetailLevel; +using AppyNox.Services.Coupon.Application.Dtos.CouponDetailTagDtos.Models.ValueObjects; -namespace AppyNox.Services.Coupon.Application.Dtos.CouponDetailTagDtos.Models.Basic; +namespace AppyNox.Services.Coupon.Application.Dtos.CouponDetailTagDtos.Models; -[CouponDetailTagDetailLevel(CouponDetailTagDataAccessDetailLevel.Simple)] -public class CouponDetailTagSimpleDto +public class CouponDetailTagDto { #region [ Properties ] diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailTagDtos/Models/Basic/CouponDetailTagIdDto.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailTagDtos/Models/ValueObjects/CouponDetailTagIdDto.cs similarity index 85% rename from src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailTagDtos/Models/Basic/CouponDetailTagIdDto.cs rename to src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailTagDtos/Models/ValueObjects/CouponDetailTagIdDto.cs index c155f320..5a40d920 100644 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailTagDtos/Models/Basic/CouponDetailTagIdDto.cs +++ b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailTagDtos/Models/ValueObjects/CouponDetailTagIdDto.cs @@ -1,4 +1,4 @@ -namespace AppyNox.Services.Coupon.Application.Dtos.CouponDetailTagDtos.Models.Basic; +namespace AppyNox.Services.Coupon.Application.Dtos.CouponDetailTagDtos.Models.ValueObjects; public class CouponDetailTagIdDto { diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailTagDtos/Profiles/CouponDetailTagProfile.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailTagDtos/Profiles/CouponDetailTagProfile.cs index 0ace130e..6fb85392 100644 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailTagDtos/Profiles/CouponDetailTagProfile.cs +++ b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDetailTagDtos/Profiles/CouponDetailTagProfile.cs @@ -1,4 +1,5 @@ -using AppyNox.Services.Coupon.Application.Dtos.CouponDetailTagDtos.Models.Basic; +using AppyNox.Services.Coupon.Application.Dtos.CouponDetailTagDtos.Models; +using AppyNox.Services.Coupon.Application.Dtos.CouponDetailTagDtos.Models.ValueObjects; using AppyNox.Services.Coupon.Domain.Coupons; using AppyNox.Services.Coupon.Domain.Coupons.Builders; using AutoMapper; @@ -11,7 +12,7 @@ public class CouponDetailTagProfile : Profile public CouponDetailTagProfile() { - CreateMap() + CreateMap() .ConstructUsing((src, context) => { return new CouponDetailTagBuilder() @@ -20,7 +21,7 @@ public CouponDetailTagProfile() .Build(); }); - CreateMap().ReverseMap(); + CreateMap().ReverseMap(); CreateMap().ReverseMap(); } diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/DetailLevel/CouponDetailLevelAttribute.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/DetailLevel/CouponDetailLevelAttribute.cs deleted file mode 100644 index 59ab9388..00000000 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/DetailLevel/CouponDetailLevelAttribute.cs +++ /dev/null @@ -1,71 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace AppyNox.Services.Coupon.Application.Dtos.CouponDtos.DetailLevel -{ - #region [ Enums ] - - public enum CouponDataAccessDetailLevel - { - [Display(Name = "Simple")] - Simple, - - [Display(Name = "WithAllRelations")] - WithAllRelations - } - - public enum CouponCreateDetailLevel - { - [Display(Name = "Simple")] - Simple, - - [Display(Name = "Bulk")] - Bulk, - - [Display(Name = "Extended")] - Extended - } - - public enum CouponUpdateDetailLevel - { - [Display(Name = "Simple")] - Simple, - - [Display(Name = "Extended")] - Extended - } - - #endregion - - [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)] - public class CouponDetailLevelAttribute : Attribute - { - #region [ Public Constructors ] - - public CouponDetailLevelAttribute(CouponDataAccessDetailLevel dataAccessDetailLevel) - { - DataAccessDetailLevel = dataAccessDetailLevel; - } - - public CouponDetailLevelAttribute(CouponCreateDetailLevel createDetailLevel) - { - CreateDetailLevel = createDetailLevel; - } - - public CouponDetailLevelAttribute(CouponUpdateDetailLevel updateDetailLevel) - { - UpdateDetailLevel = updateDetailLevel; - } - - #endregion - - #region [ Properties ] - - public CouponDataAccessDetailLevel DataAccessDetailLevel { get; } - - public CouponCreateDetailLevel CreateDetailLevel { get; } - - public CouponUpdateDetailLevel UpdateDetailLevel { get; } - - #endregion - } -} \ No newline at end of file diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/Base/CouponSimpleDto.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/Base/CouponSimpleDto.cs deleted file mode 100644 index 1441e992..00000000 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/Base/CouponSimpleDto.cs +++ /dev/null @@ -1,14 +0,0 @@ -using AppyNox.Services.Base.Application.Dtos; -using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.DetailLevel; - -namespace AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.Base; - -[CouponDetailLevel(CouponDataAccessDetailLevel.Simple)] -public class CouponSimpleDto : CouponSimpleCreateDto, IAuditDto -{ - #region [ IAuditDto ] - - public AuditInformation AuditInformation { get; set; } = default!; - - #endregion -} \ No newline at end of file diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/Base/CouponSimpleUpdateDto.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/Base/CouponSimpleUpdateDto.cs deleted file mode 100644 index c95fd171..00000000 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/Base/CouponSimpleUpdateDto.cs +++ /dev/null @@ -1,13 +0,0 @@ -using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.DetailLevel; - -namespace AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.Base; - -[CouponDetailLevel(CouponUpdateDetailLevel.Simple)] -public class CouponSimpleUpdateDto : CouponSimpleCreateDto -{ - #region [ Properties ] - - public CouponIdDto Id { get; set; } = default!; - - #endregion -} \ No newline at end of file diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/Base/CouponBulkCreateDto.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/CouponCompositeCreateDto.cs similarity index 62% rename from src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/Base/CouponBulkCreateDto.cs rename to src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/CouponCompositeCreateDto.cs index ccbcfb16..f623b6fd 100644 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/Base/CouponBulkCreateDto.cs +++ b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/CouponCompositeCreateDto.cs @@ -1,11 +1,10 @@ using AppyNox.Services.Base.Domain.Interfaces; -using AppyNox.Services.Coupon.Application.Dtos.CouponDetailDtos.Models.Basic; -using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.DetailLevel; +using AppyNox.Services.Coupon.Application.Dtos.CouponDetailDtos.Models; +using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.ValueObjects; -namespace AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.Base; +namespace AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models; -[CouponDetailLevel(CouponCreateDetailLevel.Bulk)] -public class CouponBulkCreateDto : IHasCode +public class CouponCompositeCreateDto : IHasCode { #region [ Properties ] @@ -13,7 +12,7 @@ public class CouponBulkCreateDto : IHasCode public AmountDto Amount { get; set; } = default!; - public CouponDetailBulkCreateDto CouponDetail { get; set; } = default!; + public CouponDetailCompositeCreateDto CouponDetail { get; set; } = default!; #endregion diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/Base/CouponSimpleCreateDto.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/CouponCreateDto.cs similarity index 72% rename from src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/Base/CouponSimpleCreateDto.cs rename to src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/CouponCreateDto.cs index 70c5f4f2..f19233ce 100644 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/Base/CouponSimpleCreateDto.cs +++ b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/CouponCreateDto.cs @@ -1,11 +1,10 @@ using AppyNox.Services.Base.Domain.Interfaces; -using AppyNox.Services.Coupon.Application.Dtos.CouponDetailDtos.Models.Basic; -using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.DetailLevel; +using AppyNox.Services.Coupon.Application.Dtos.CouponDetailDtos.Models.ValueObjects; +using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.ValueObjects; -namespace AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.Base; +namespace AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models; -[CouponDetailLevel(CouponCreateDetailLevel.Simple)] -public class CouponSimpleCreateDto : IHasCode +public class CouponCreateDto : IHasCode { #region [ Properties ] @@ -15,6 +14,8 @@ public class CouponSimpleCreateDto : IHasCode public CouponDetailIdDto CouponDetailId { get; set; } = default!; + public string? Detail { get; set; } + #endregion #region [ IHasCode ] diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/CouponDto.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/CouponDto.cs new file mode 100644 index 00000000..9b845e4f --- /dev/null +++ b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/CouponDto.cs @@ -0,0 +1,22 @@ +using AppyNox.Services.Base.Application.Dtos; +using AppyNox.Services.Coupon.Application.Dtos.CouponDetailDtos.Models; +using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.ValueObjects; + +namespace AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models; + +public class CouponDto : CouponCreateDto, IAuditDto +{ + #region [ IAuditDto ] + + public AuditInformation AuditInformation { get; set; } = default!; + + #endregion + + #region [ Relations ] + + public CouponIdDto Id { get; set; } = default!; + + public CouponDetailDto CouponDetail { get; set; } = null!; + + #endregion +} \ No newline at end of file diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/CouponUpdateDto.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/CouponUpdateDto.cs new file mode 100644 index 00000000..5509b264 --- /dev/null +++ b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/CouponUpdateDto.cs @@ -0,0 +1,12 @@ +using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.ValueObjects; + +namespace AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models; + +public class CouponUpdateDto : CouponCreateDto +{ + #region [ Properties ] + + public CouponIdDto Id { get; set; } = default!; + + #endregion +} \ No newline at end of file diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/Extended/CouponExtendedCreateDto.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/Extended/CouponExtendedCreateDto.cs deleted file mode 100644 index 238ef265..00000000 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/Extended/CouponExtendedCreateDto.cs +++ /dev/null @@ -1,14 +0,0 @@ -using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.DetailLevel; -using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.Base; - -namespace AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.Extended; - -[CouponDetailLevel(CouponCreateDetailLevel.Extended)] -public class CouponExtendedCreateDto : CouponSimpleCreateDto -{ - #region [ Properties ] - - public string? Detail { get; set; } - - #endregion -} \ No newline at end of file diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/Extended/CouponExtendedUpdateDto.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/Extended/CouponExtendedUpdateDto.cs deleted file mode 100644 index 1dea8d03..00000000 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/Extended/CouponExtendedUpdateDto.cs +++ /dev/null @@ -1,14 +0,0 @@ -using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.DetailLevel; -using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.Base; - -namespace AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.Extended; - -[CouponDetailLevel(CouponUpdateDetailLevel.Extended)] -public class CouponExtendedUpdateDto : CouponExtendedCreateDto -{ - #region Properties - - public CouponIdDto Id { get; set; } = default!; - - #endregion -} \ No newline at end of file diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/Extended/CouponWithAllRelationsDto.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/Extended/CouponWithAllRelationsDto.cs deleted file mode 100644 index ae988dd7..00000000 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/Extended/CouponWithAllRelationsDto.cs +++ /dev/null @@ -1,17 +0,0 @@ -using AppyNox.Services.Coupon.Application.Dtos.CouponDetailDtos.Models.Basic; -using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.DetailLevel; -using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.Base; - -namespace AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.Extended; - -[CouponDetailLevel(CouponDataAccessDetailLevel.WithAllRelations)] -public class CouponWithAllRelationsDto : CouponExtendedCreateDto -{ - #region [ Relations ] - - public CouponIdDto Id { get; set; } = default!; - - public CouponDetailSimpleDto CouponDetail { get; set; } = null!; - - #endregion -} \ No newline at end of file diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/Base/AmountDto.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/ValueObjects/AmountDto.cs similarity index 90% rename from src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/Base/AmountDto.cs rename to src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/ValueObjects/AmountDto.cs index 9b380e00..cb8fa121 100644 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/Base/AmountDto.cs +++ b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/ValueObjects/AmountDto.cs @@ -1,4 +1,4 @@ -namespace AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.Base; +namespace AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.ValueObjects; public class AmountDto { diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/Base/CouponIdDto.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/ValueObjects/CouponIdDto.cs similarity index 88% rename from src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/Base/CouponIdDto.cs rename to src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/ValueObjects/CouponIdDto.cs index d20e3d54..fe11714f 100644 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/Base/CouponIdDto.cs +++ b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Models/ValueObjects/CouponIdDto.cs @@ -1,4 +1,4 @@ -namespace AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.Base; +namespace AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.ValueObjects; public class CouponIdDto { diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Profiles/CouponProfile.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Profiles/CouponProfile.cs index 2b0f4124..f2a89dd8 100644 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Profiles/CouponProfile.cs +++ b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/CouponDtos/Profiles/CouponProfile.cs @@ -1,6 +1,6 @@ using AppyNox.Services.Base.Application.Extensions; -using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.Base; -using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.Extended; +using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models; +using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.ValueObjects; using AppyNox.Services.Coupon.Domain.Coupons; using AppyNox.Services.Coupon.Domain.Coupons.Builders; using AutoMapper; @@ -14,7 +14,7 @@ public class CouponProfile : Profile public CouponProfile() { - CreateMap() + CreateMap() .ConstructUsing((src, context) => { return new CouponBuilder() @@ -25,7 +25,7 @@ public CouponProfile() .Build(); }); - CreateMap() + CreateMap() .ConstructUsing((src, context) => { return new CouponBuilder() @@ -35,19 +35,7 @@ public CouponProfile() .Build(); }); - CreateMap() - .ConstructUsing((src, context) => - { - return new CouponBuilder() - .WithDetails(src.Code, src.Description, src.Detail) - .WithAmount(context.Mapper.Map(src.Amount)) - .WithCouponDetailId(context.Mapper.Map(src.CouponDetailId)) - .Build(); - }); - - CreateMap().MapAuditInformation(); - - CreateMap(); + CreateMap().MapAuditInformation(); CreateMap().ReverseMap(); diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketDtos/DetailLevel/TicketDetailLevelAttribute.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketDtos/DetailLevel/TicketDetailLevelAttribute.cs deleted file mode 100644 index 9706a691..00000000 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketDtos/DetailLevel/TicketDetailLevelAttribute.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace AppyNox.Services.Coupon.Application.Dtos.TicketDtos.DetailLevel; - -public enum TicketDataAccessDetailLevel -{ - [Display(Name = "Simple")] - Simple, - - [Display(Name = "Extended")] - Extended, -} - -public enum TicketCreateDetailLevel -{ - [Display(Name = "Simple")] - Simple -} - -public enum TicketUpdateDetailLevel -{ - [Display(Name = "Simple")] - Simple -} - -[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)] -public class TicketDetailLevelAttribute : Attribute -{ - #region [ Public Constructors ] - - public TicketDetailLevelAttribute(TicketDataAccessDetailLevel dataAccessDetailLevel) - { - DataAccessDetailLevel = dataAccessDetailLevel; - } - - public TicketDetailLevelAttribute(TicketCreateDetailLevel createDetailLevel) - { - CreateDetailLevel = createDetailLevel; - } - - public TicketDetailLevelAttribute(TicketUpdateDetailLevel updateDetailLevel) - { - UpdateDetailLevel = updateDetailLevel; - } - - #endregion - - #region [ Properties ] - - public TicketDataAccessDetailLevel DataAccessDetailLevel { get; } - - public TicketCreateDetailLevel CreateDetailLevel { get; } - - public TicketUpdateDetailLevel UpdateDetailLevel { get; } - - #endregion -} \ No newline at end of file diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketDtos/Models/Basic/TicketSimpleDto.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketDtos/Models/Basic/TicketSimpleDto.cs deleted file mode 100644 index 61c995df..00000000 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketDtos/Models/Basic/TicketSimpleDto.cs +++ /dev/null @@ -1,14 +0,0 @@ -using AppyNox.Services.Base.Application.Dtos; -using AppyNox.Services.Coupon.Application.Dtos.TicketDtos.DetailLevel; - -namespace AppyNox.Services.Coupon.Application.Dtos.TicketDtos.Models.Basic; - -[TicketDetailLevel(TicketDataAccessDetailLevel.Simple)] -public class TicketSimpleDto : TicketSimpleCreateDto, IAuditDto -{ - #region [ Properties ] - - public AuditInformation AuditInformation { get; set; } = default!; - - #endregion -} \ No newline at end of file diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketDtos/Models/Extended/TicketExtendedDto.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketDtos/Models/Extended/TicketExtendedDto.cs deleted file mode 100644 index e53107de..00000000 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketDtos/Models/Extended/TicketExtendedDto.cs +++ /dev/null @@ -1,18 +0,0 @@ -using AppyNox.Services.Base.Application.Dtos; -using AppyNox.Services.Coupon.Application.Dtos.TicketDtos.DetailLevel; -using AppyNox.Services.Coupon.Application.Dtos.TicketDtos.Models.Basic; -using AppyNox.Services.Coupon.Application.Dtos.TicketTagDtos.Models.Basic; - -namespace AppyNox.Services.Coupon.Application.Dtos.TicketDtos.Models.Extended; - -[TicketDetailLevel(TicketDataAccessDetailLevel.Extended)] -public class TicketExtendedDto : TicketSimpleDto, IAuditDto -{ - #region [ Relations ] - - public Guid Id { get; set; } - - public IEnumerable? Tags { get; set; } - - #endregion -} \ No newline at end of file diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketDtos/Models/Basic/TicketSimpleCreateDto.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketDtos/Models/TicketCreateDto.cs similarity index 62% rename from src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketDtos/Models/Basic/TicketSimpleCreateDto.cs rename to src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketDtos/Models/TicketCreateDto.cs index f8c5580f..b09c3d6b 100644 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketDtos/Models/Basic/TicketSimpleCreateDto.cs +++ b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketDtos/Models/TicketCreateDto.cs @@ -1,10 +1,8 @@ -using AppyNox.Services.Coupon.Application.Dtos.TicketDtos.DetailLevel; -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; -namespace AppyNox.Services.Coupon.Application.Dtos.TicketDtos.Models.Basic; +namespace AppyNox.Services.Coupon.Application.Dtos.TicketDtos.Models; -[TicketDetailLevel(TicketCreateDetailLevel.Simple)] -public class TicketSimpleCreateDto +public class TicketCreateDto { #region [ Properties ] diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketDtos/Models/TicketDto.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketDtos/Models/TicketDto.cs new file mode 100644 index 00000000..51db6c6e --- /dev/null +++ b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketDtos/Models/TicketDto.cs @@ -0,0 +1,21 @@ +using AppyNox.Services.Base.Application.Dtos; +using AppyNox.Services.Coupon.Application.Dtos.TicketTagDtos.Models; + +namespace AppyNox.Services.Coupon.Application.Dtos.TicketDtos.Models; + +public class TicketDto : TicketCreateDto, IAuditDto +{ + #region [ Properties ] + + public Guid Id { get; set; } + + public AuditInformation AuditInformation { get; set; } = default!; + + #endregion + + #region [ Relations ] + + public IEnumerable? Tags { get; set; } + + #endregion +} \ No newline at end of file diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketDtos/Models/Basic/TicketSimpleUpdateDto.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketDtos/Models/TicketUpdateDto.cs similarity index 62% rename from src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketDtos/Models/Basic/TicketSimpleUpdateDto.cs rename to src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketDtos/Models/TicketUpdateDto.cs index af761ec1..aa209276 100644 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketDtos/Models/Basic/TicketSimpleUpdateDto.cs +++ b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketDtos/Models/TicketUpdateDto.cs @@ -1,10 +1,8 @@ using AppyNox.Services.Base.Application.Dtos; -using AppyNox.Services.Coupon.Application.Dtos.TicketDtos.DetailLevel; -namespace AppyNox.Services.Coupon.Application.Dtos.TicketDtos.Models.Basic; +namespace AppyNox.Services.Coupon.Application.Dtos.TicketDtos.Models; -[TicketDetailLevel(TicketUpdateDetailLevel.Simple)] -public class TicketSimpleUpdateDto : IUpdateDto +public class TicketUpdateDto : IUpdateDto { #region [ Properties ] diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketDtos/Profiles/TicketProfile.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketDtos/Profiles/TicketProfile.cs index 63c9cabe..3d19779e 100644 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketDtos/Profiles/TicketProfile.cs +++ b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketDtos/Profiles/TicketProfile.cs @@ -1,6 +1,5 @@ using AppyNox.Services.Base.Application.Extensions; -using AppyNox.Services.Coupon.Application.Dtos.TicketDtos.Models.Basic; -using AppyNox.Services.Coupon.Application.Dtos.TicketDtos.Models.Extended; +using AppyNox.Services.Coupon.Application.Dtos.TicketDtos.Models; using AppyNox.Services.Coupon.Domain.Entities; using AutoMapper; @@ -12,11 +11,9 @@ public class TicketProfile : Profile public TicketProfile() { - CreateMap().MapAuditInformation(); - CreateMap() - .IncludeBase(); - CreateMap(); - CreateMap(); + CreateMap().MapAuditInformation(); + CreateMap(); + CreateMap(); } #endregion diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketTagDtos/DetailLevel/TicketTagDetailLevelAttribute.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketTagDtos/DetailLevel/TicketTagDetailLevelAttribute.cs deleted file mode 100644 index 1355db92..00000000 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketTagDtos/DetailLevel/TicketTagDetailLevelAttribute.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace AppyNox.Services.Coupon.Application.Dtos.TicketTagDtos.DetailLevel; - -public enum TicketTagDataAccessDetailLevel -{ - [Display(Name = "Simple")] - Simple -} - -public enum TicketTagCreateDetailLevel -{ - [Display(Name = "Simple")] - Simple -} - -public enum TicketTagUpdateDetailLevel -{ - [Display(Name = "Simple")] - Simple -} - -[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)] -public class TicketTagDetailLevelAttribute : Attribute -{ - #region [ Public Constructors ] - - public TicketTagDetailLevelAttribute(TicketTagDataAccessDetailLevel dataAccessDetailLevel) - { - DataAccessDetailLevel = dataAccessDetailLevel; - } - - public TicketTagDetailLevelAttribute(TicketTagCreateDetailLevel createDetailLevel) - { - CreateDetailLevel = createDetailLevel; - } - - public TicketTagDetailLevelAttribute(TicketTagUpdateDetailLevel updateDetailLevel) - { - UpdateDetailLevel = updateDetailLevel; - } - - #endregion - - #region [ Properties ] - - public TicketTagDataAccessDetailLevel DataAccessDetailLevel { get; } - - public TicketTagCreateDetailLevel CreateDetailLevel { get; } - - public TicketTagUpdateDetailLevel UpdateDetailLevel { get; } - - #endregion -} \ No newline at end of file diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketTagDtos/Models/Basic/TicketTagSimpleCreateDto.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketTagDtos/Models/Basic/TicketTagSimpleCreateDto.cs deleted file mode 100644 index 6f4dc917..00000000 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketTagDtos/Models/Basic/TicketTagSimpleCreateDto.cs +++ /dev/null @@ -1,13 +0,0 @@ -using AppyNox.Services.Coupon.Application.Dtos.TicketTagDtos.DetailLevel; - -namespace AppyNox.Services.Coupon.Application.Dtos.TicketTagDtos.Models.Basic; - -[TicketTagDetailLevel(TicketTagCreateDetailLevel.Simple)] -public class TicketTagSimpleCreateDto -{ - #region [ Properties ] - - public string Description { get; set; } = string.Empty; - - #endregion -} \ No newline at end of file diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketTagDtos/Models/Basic/TicketTagSimpleDto.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketTagDtos/Models/Basic/TicketTagSimpleDto.cs deleted file mode 100644 index 55779a67..00000000 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketTagDtos/Models/Basic/TicketTagSimpleDto.cs +++ /dev/null @@ -1,8 +0,0 @@ -using AppyNox.Services.Coupon.Application.Dtos.TicketDtos.DetailLevel; - -namespace AppyNox.Services.Coupon.Application.Dtos.TicketTagDtos.Models.Basic; - -[TicketDetailLevel(TicketDataAccessDetailLevel.Simple)] -public class TicketTagSimpleDto : TicketTagSimpleCreateDto -{ -} \ No newline at end of file diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketTagDtos/Models/Basic/TicketTagSimpleUpdateDto.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketTagDtos/Models/Basic/TicketTagSimpleUpdateDto.cs deleted file mode 100644 index 7a4df640..00000000 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketTagDtos/Models/Basic/TicketTagSimpleUpdateDto.cs +++ /dev/null @@ -1,13 +0,0 @@ -using AppyNox.Services.Coupon.Application.Dtos.TicketTagDtos.DetailLevel; - -namespace AppyNox.Services.Coupon.Application.Dtos.TicketTagDtos.Models.Basic; - -[TicketTagDetailLevel(TicketTagUpdateDetailLevel.Simple)] -public class TicketTagSimpleUpdateDto : TicketTagSimpleCreateDto -{ - #region [ Properties ] - - public Guid Id { get; set; } - - #endregion -} \ No newline at end of file diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketTagDtos/Models/TicketTagCreateDto.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketTagDtos/Models/TicketTagCreateDto.cs new file mode 100644 index 00000000..0df84b14 --- /dev/null +++ b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketTagDtos/Models/TicketTagCreateDto.cs @@ -0,0 +1,11 @@ + +namespace AppyNox.Services.Coupon.Application.Dtos.TicketTagDtos.Models; + +public class TicketTagCreateDto +{ + #region [ Properties ] + + public string Description { get; set; } = string.Empty; + + #endregion +} \ No newline at end of file diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketTagDtos/Models/TicketTagDto.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketTagDtos/Models/TicketTagDto.cs new file mode 100644 index 00000000..b5884331 --- /dev/null +++ b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketTagDtos/Models/TicketTagDto.cs @@ -0,0 +1,6 @@ + +namespace AppyNox.Services.Coupon.Application.Dtos.TicketTagDtos.Models; + +public class TicketTagDto : TicketTagCreateDto +{ +} \ No newline at end of file diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketTagDtos/Models/TicketTagUpdateDto.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketTagDtos/Models/TicketTagUpdateDto.cs new file mode 100644 index 00000000..06b5ca40 --- /dev/null +++ b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketTagDtos/Models/TicketTagUpdateDto.cs @@ -0,0 +1,11 @@ + +namespace AppyNox.Services.Coupon.Application.Dtos.TicketTagDtos.Models; + +public class TicketTagUpdateDto : TicketTagCreateDto +{ + #region [ Properties ] + + public Guid Id { get; set; } + + #endregion +} \ No newline at end of file diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketTagDtos/Profiles/TicketTagProfile.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketTagDtos/Profiles/TicketTagProfile.cs index 73c5c4b2..18a62606 100644 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketTagDtos/Profiles/TicketTagProfile.cs +++ b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Dtos/TicketTagDtos/Profiles/TicketTagProfile.cs @@ -1,4 +1,4 @@ -using AppyNox.Services.Coupon.Application.Dtos.TicketTagDtos.Models.Basic; +using AppyNox.Services.Coupon.Application.Dtos.TicketTagDtos.Models; using AppyNox.Services.Coupon.Domain.Entities; using AutoMapper; @@ -10,9 +10,9 @@ public class TicketTagProfile : Profile public TicketTagProfile() { - CreateMap(); - CreateMap(); - CreateMap(); + CreateMap(); + CreateMap(); + CreateMap(); } #endregion diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/MediatR/Commands/CouponCommands.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/MediatR/Commands/CouponCommands.cs index 3d87a23a..2d935a92 100644 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/MediatR/Commands/CouponCommands.cs +++ b/src/Services/CouponService/AppyNox.Services.Coupon.Application/MediatR/Commands/CouponCommands.cs @@ -1,9 +1,8 @@ -using AppyNox.Services.Base.Domain.Interfaces; -using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.Extended; +using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models; using MediatR; using System.Diagnostics.CodeAnalysis; namespace AppyNox.Services.Coupon.Application.MediatR.Commands; [SuppressMessage("Sonar Code Smell", "S2326:Unused type parameters should be removed", Justification = "TEntity is used to specify the type of entity being created")] -public record UpdateCouponCommand(Guid Id, CouponExtendedUpdateDto Dto) : IRequest; \ No newline at end of file +public record UpdateCouponCommand(Guid Id, CouponUpdateDto Dto) : IRequest; \ No newline at end of file diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/MediatR/Handlers/UpdateCouponCommandHandler.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/MediatR/Handlers/UpdateCouponCommandHandler.cs index 322dc220..35cc8ba8 100644 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/MediatR/Handlers/UpdateCouponCommandHandler.cs +++ b/src/Services/CouponService/AppyNox.Services.Coupon.Application/MediatR/Handlers/UpdateCouponCommandHandler.cs @@ -1,10 +1,9 @@ using AppyNox.Services.Base.Application.Exceptions; using AppyNox.Services.Base.Application.Interfaces.Loggers; using AppyNox.Services.Base.Application.Interfaces.Repositories; -using AppyNox.Services.Base.Core.AsyncLocals; using AppyNox.Services.Base.Core.Exceptions.Base; -using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.Base; -using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.Extended; +using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models; +using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.ValueObjects; using AppyNox.Services.Coupon.Application.Exceptions.Base; using AppyNox.Services.Coupon.Application.MediatR.Commands; using AppyNox.Services.Coupon.Domain.Coupons; @@ -19,7 +18,7 @@ namespace AppyNox.Services.Coupon.Application.MediatR.Handlers; public class UpdateCouponCommandHandler( INoxRepository repository, IMapper mapper, - IValidator validator, + IValidator validator, INoxApplicationLogger logger, IUnitOfWork unitOfWork) @@ -35,7 +34,7 @@ public class UpdateCouponCommandHandler( private readonly INoxApplicationLogger _logger = logger; - private readonly IValidator _validator = validator; + private readonly IValidator _validator = validator; #endregion @@ -56,7 +55,7 @@ public async Task Handle(UpdateCouponCommand request, CancellationToken cancella var validationResult = _validator.Validate(request.Dto); if (!validationResult.IsValid) { - throw new NoxFluentValidationException(typeof(CouponExtendedUpdateDto), validationResult); + throw new NoxFluentValidationException(typeof(CouponUpdateDto), validationResult); } #endregion diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Validators/Coupon/Create/CouponSimpleCreateValidator.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Validators/Coupon/Create/CouponCompositeCreateValidator.cs similarity index 86% rename from src/Services/CouponService/AppyNox.Services.Coupon.Application/Validators/Coupon/Create/CouponSimpleCreateValidator.cs rename to src/Services/CouponService/AppyNox.Services.Coupon.Application/Validators/Coupon/Create/CouponCompositeCreateValidator.cs index 6d62a94e..ca822f21 100644 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Validators/Coupon/Create/CouponSimpleCreateValidator.cs +++ b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Validators/Coupon/Create/CouponCompositeCreateValidator.cs @@ -1,14 +1,14 @@ using AppyNox.Services.Base.Application.Validators; -using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.Base; +using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models; using FluentValidation; namespace AppyNox.Services.Coupon.Application.Validators.Coupon.Create { - public class CouponSimpleCreateValidator : DtoValidatorBase + public class CouponCompositeCreateValidator : DtoValidatorBase { #region [ Public Constructors ] - public CouponSimpleCreateValidator() + public CouponCompositeCreateValidator() { RuleFor(coupon => coupon.Amount.DiscountAmount) .NotNull().WithMessage("Discount Amount can not be null") diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Validators/Coupon/Create/CouponBulkCreateValidator.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Validators/Coupon/Create/CouponCreateValidator.cs similarity index 66% rename from src/Services/CouponService/AppyNox.Services.Coupon.Application/Validators/Coupon/Create/CouponBulkCreateValidator.cs rename to src/Services/CouponService/AppyNox.Services.Coupon.Application/Validators/Coupon/Create/CouponCreateValidator.cs index 2460b6b2..ffdd57a8 100644 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Validators/Coupon/Create/CouponBulkCreateValidator.cs +++ b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Validators/Coupon/Create/CouponCreateValidator.cs @@ -1,14 +1,15 @@ -using AppyNox.Services.Base.Application.Validators; -using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.Base; +using AppyNox.Services.Base.Application.Extensions; +using AppyNox.Services.Base.Application.Validators; +using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models; using FluentValidation; namespace AppyNox.Services.Coupon.Application.Validators.Coupon.Create { - public class CouponBulkCreateValidator : DtoValidatorBase + public class CouponCreateValidator : DtoValidatorBase { #region [ Public Constructors ] - public CouponBulkCreateValidator() + public CouponCreateValidator() { RuleFor(coupon => coupon.Amount.DiscountAmount) .NotNull().WithMessage("Discount Amount can not be null") @@ -20,6 +21,9 @@ public CouponBulkCreateValidator() RuleFor(coupon => coupon.Description) .NotNull().WithMessage("Description can not be null"); + + RuleFor(coupon => coupon.Detail) + .MaximumLength(60).When(coupon => !coupon.Detail.IsNullOrEmpty()).WithMessage("Detail cannot be longer than 60 characters"); } #endregion diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Validators/Coupon/Create/CouponExtendedCreateValidator.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Validators/Coupon/Create/CouponExtendedCreateValidator.cs deleted file mode 100644 index eb8af0a7..00000000 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Validators/Coupon/Create/CouponExtendedCreateValidator.cs +++ /dev/null @@ -1,23 +0,0 @@ -using AppyNox.Services.Base.Application.Extensions; -using AppyNox.Services.Base.Application.Validators; -using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.Extended; -using FluentValidation; - -namespace AppyNox.Services.Coupon.Application.Validators.Coupon.Create -{ - public class CouponExtendedCreateValidator : DtoValidatorBase - { - #region [ Public Constructors ] - - public CouponExtendedCreateValidator(CouponSimpleCreateValidator validator) - { - RuleFor(o => o) - .SetValidator(validator); - - RuleFor(coupon => coupon.Detail) - .MaximumLength(60).When(coupon => !coupon.Detail.IsNullOrEmpty()).WithMessage("Detail cannot be longer than 60 characters"); - } - - #endregion - } -} \ No newline at end of file diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Validators/Coupon/Update/CouponExtendedUpdateValidator.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Validators/Coupon/Update/CouponExtendedUpdateValidator.cs deleted file mode 100644 index 3e5a9f22..00000000 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Validators/Coupon/Update/CouponExtendedUpdateValidator.cs +++ /dev/null @@ -1,24 +0,0 @@ -using AppyNox.Services.Base.Application.Validators; -using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.Extended; -using AppyNox.Services.Coupon.Application.Validators.Coupon.Create; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace AppyNox.Services.Coupon.Application.Validators.Coupon.Update -{ - public class CouponExtendedUpdateValidator : DtoValidatorBase - { - #region Public Constructors - - public CouponExtendedUpdateValidator(CouponExtendedCreateValidator validator) - { - RuleFor(o => o) - .SetValidator(validator); - } - - #endregion - } -} \ No newline at end of file diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Validators/Coupon/Update/CouponSimpleUpdateValidator.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Validators/Coupon/Update/CouponUpdateValidator.cs similarity index 53% rename from src/Services/CouponService/AppyNox.Services.Coupon.Application/Validators/Coupon/Update/CouponSimpleUpdateValidator.cs rename to src/Services/CouponService/AppyNox.Services.Coupon.Application/Validators/Coupon/Update/CouponUpdateValidator.cs index 9af50f6c..a7db753d 100644 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Validators/Coupon/Update/CouponSimpleUpdateValidator.cs +++ b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Validators/Coupon/Update/CouponUpdateValidator.cs @@ -1,19 +1,14 @@ using AppyNox.Services.Base.Application.Validators; -using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.Base; +using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models; using AppyNox.Services.Coupon.Application.Validators.Coupon.Create; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace AppyNox.Services.Coupon.Application.Validators.Coupon.Update { - public class CouponSimpleUpdateValidator : DtoValidatorBase + public class CouponUpdateValidator : DtoValidatorBase { - #region Public Constructors + #region [ Public Constructors ] - public CouponSimpleUpdateValidator(CouponSimpleCreateValidator validator) + public CouponUpdateValidator(CouponCreateValidator validator) { RuleFor(o => o) .SetValidator(validator); diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Validators/Ticket/Create/TicketSimpleCreateValidator.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Validators/Ticket/Create/TicketSimpleCreateValidator.cs index 987f0676..153986f5 100644 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Validators/Ticket/Create/TicketSimpleCreateValidator.cs +++ b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Validators/Ticket/Create/TicketSimpleCreateValidator.cs @@ -1,10 +1,10 @@ using AppyNox.Services.Base.Application.Validators; -using AppyNox.Services.Coupon.Application.Dtos.TicketDtos.Models.Basic; +using AppyNox.Services.Coupon.Application.Dtos.TicketDtos.Models; using FluentValidation; namespace AppyNox.Services.Coupon.Application.Validators.Ticket.Create; -public class TicketSimpleCreateValidator : DtoValidatorBase +public class TicketSimpleCreateValidator : DtoValidatorBase { #region [ Public Constructors ] diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Validators/Ticket/Update/TicketSimpleUpdateValidator.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Validators/Ticket/Update/TicketSimpleUpdateValidator.cs index 86957820..47cf42b5 100644 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Application/Validators/Ticket/Update/TicketSimpleUpdateValidator.cs +++ b/src/Services/CouponService/AppyNox.Services.Coupon.Application/Validators/Ticket/Update/TicketSimpleUpdateValidator.cs @@ -1,11 +1,11 @@ using AppyNox.Services.Base.Application.Validators; -using AppyNox.Services.Coupon.Application.Dtos.TicketDtos.Models.Basic; +using AppyNox.Services.Coupon.Application.Dtos.TicketDtos.Models; using AppyNox.Services.Coupon.Application.Validators.Ticket.Create; using FluentValidation; namespace AppyNox.Services.Coupon.Application.Validators.Ticket.Update; -public class TicketSimpleUpdateValidator : DtoValidatorBase +public class TicketSimpleUpdateValidator : DtoValidatorBase { #region [ Public Constructors ] diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Domain/Coupons/Builders/CouponBuilder.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Domain/Coupons/Builders/CouponBuilder.cs index adba898a..990c9f95 100644 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Domain/Coupons/Builders/CouponBuilder.cs +++ b/src/Services/CouponService/AppyNox.Services.Coupon.Domain/Coupons/Builders/CouponBuilder.cs @@ -111,12 +111,12 @@ private void Validate() { if (BulkCreate && _couponDetail == null) { - throw new DomainException(CouponDomainResourceService.CouponDetailInBulkNotNull, + throw new DomainException(CouponDomainResourceService.CouponDetailInComposeNotNull, (int)ExceptionCode.CouponBuilderValidation); } if (BulkCreate && (_couponDetailId != null && !_couponDetailId.Value.Equals(Guid.Empty))) { - throw new DomainException(CouponDomainResourceService.CouponDetailIdShouldBeEmptyInBulk, + throw new DomainException(CouponDomainResourceService.CouponDetailIdShouldBeEmptyInCompose, (int)ExceptionCode.CouponBuilderValidation); } if (!BulkCreate && (_couponDetailId == null || _couponDetailId.Value.Equals(Guid.Empty))) @@ -126,7 +126,7 @@ private void Validate() } if (!BulkCreate && _couponDetail != null) { - throw new DomainException(CouponDomainResourceService.CouponDetailShouldBeEmptyInBulk, + throw new DomainException(CouponDomainResourceService.CouponDetailShouldBeEmptyInCompose, (int)ExceptionCode.CouponBuilderValidation); } } diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Domain/Localization/CouponDomainResourceService.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Domain/Localization/CouponDomainResourceService.cs index 2e3de4db..07dd30af 100644 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Domain/Localization/CouponDomainResourceService.cs +++ b/src/Services/CouponService/AppyNox.Services.Coupon.Domain/Localization/CouponDomainResourceService.cs @@ -43,9 +43,9 @@ public static class CouponDomainResourceService internal static LocalizedString AmountNotNull => GetMessage("AmountNotNull"); /// - /// CouponDetail can not be null in bulk creation. + /// CouponDetail can not be null in composite creation. /// - internal static LocalizedString CouponDetailInBulkNotNull => GetMessage("CouponDetailInBulkNotNull"); + internal static LocalizedString CouponDetailInComposeNotNull => GetMessage("CouponDetailInComposeNotNull"); /// /// CouponDetailId is mandatory. @@ -53,14 +53,14 @@ public static class CouponDomainResourceService internal static LocalizedString CouponDetailIdMandatory => GetMessage("CouponDetailIdMandatory"); /// - /// CouponDetailId should not be provided in bulk creation. + /// CouponDetailId should not be provided in composite creation. /// - internal static LocalizedString CouponDetailIdShouldBeEmptyInBulk => GetMessage("CouponDetailIdShouldBeEmptyInBulk"); + internal static LocalizedString CouponDetailIdShouldBeEmptyInCompose => GetMessage("CouponDetailIdShouldBeEmptyInCompose"); /// - /// CouponDetail should not be provided in bulk creation. + /// CouponDetail should not be provided in composite creation. /// - internal static LocalizedString CouponDetailShouldBeEmptyInBulk => GetMessage("CouponDetailShouldBeEmptyInBulk"); + internal static LocalizedString CouponDetailShouldBeEmptyInCompose => GetMessage("CouponDetailShouldBeEmptyInCompose"); #endregion diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Domain/Localization/CouponDomainResourceService.en-US.resx b/src/Services/CouponService/AppyNox.Services.Coupon.Domain/Localization/CouponDomainResourceService.en-US.resx index 1af7de15..00c72c01 100644 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Domain/Localization/CouponDomainResourceService.en-US.resx +++ b/src/Services/CouponService/AppyNox.Services.Coupon.Domain/Localization/CouponDomainResourceService.en-US.resx @@ -117,4 +117,34 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + Amount must be set before it can be accessed. + + + Code must be set before it can be accessed. + + + CouponDetailId is mandatory. + + + CouponDetailId must be set before it can be accessed. + + + CouponDetailId should not be provided in composite creation. + + + CouponDetail can not be null in composite creation. + + + CouponDetail must be set before it can be accessed. + + + CouponDetail should not be provided in composite creation. + + + Tag must be set before it can be accessed. + + + CouponDetailTags must be set before it can be accessed. + \ No newline at end of file diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Domain/Localization/CouponDomainResourceService.resx b/src/Services/CouponService/AppyNox.Services.Coupon.Domain/Localization/CouponDomainResourceService.resx index 1af7de15..00c72c01 100644 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Domain/Localization/CouponDomainResourceService.resx +++ b/src/Services/CouponService/AppyNox.Services.Coupon.Domain/Localization/CouponDomainResourceService.resx @@ -117,4 +117,34 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + Amount must be set before it can be accessed. + + + Code must be set before it can be accessed. + + + CouponDetailId is mandatory. + + + CouponDetailId must be set before it can be accessed. + + + CouponDetailId should not be provided in composite creation. + + + CouponDetail can not be null in composite creation. + + + CouponDetail must be set before it can be accessed. + + + CouponDetail should not be provided in composite creation. + + + Tag must be set before it can be accessed. + + + CouponDetailTags must be set before it can be accessed. + \ No newline at end of file diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Domain/Localization/CouponDomainResourceService.tr-TR.resx b/src/Services/CouponService/AppyNox.Services.Coupon.Domain/Localization/CouponDomainResourceService.tr-TR.resx index 1af7de15..c716024d 100644 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Domain/Localization/CouponDomainResourceService.tr-TR.resx +++ b/src/Services/CouponService/AppyNox.Services.Coupon.Domain/Localization/CouponDomainResourceService.tr-TR.resx @@ -117,4 +117,34 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + Tutarın erişilebilmesi için önceden ayarlanması gerekir. + + + Kodun erişilebilmesi için ayarlanması gerekir. + + + CouponDetailId zorunludur. + + + CouponDetailId'nin erişilebilmesi için ayarlanması gerekir. + + + Bileşik oluşturmada CouponDetailId sağlanmamalıdır. + + + CouponDetail bileşik oluşturmada boş olamaz. + + + CouponDetail'e erişilebilmesi için ayarlanması gerekir. + + + Bileşik oluşturmada CouponDetail sağlanmamalıdır. + + + Etiketin erişilebilmesi için ayarlanması gerekir. + + + CouponDetailTag'lerin erişilebilmesi için ayarlanması gerekir. + \ No newline at end of file diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.Infrastructure/Repositories/CouponRepository.cs b/src/Services/CouponService/AppyNox.Services.Coupon.Infrastructure/Repositories/CouponRepository.cs index 6b95dc42..292c88c6 100644 --- a/src/Services/CouponService/AppyNox.Services.Coupon.Infrastructure/Repositories/CouponRepository.cs +++ b/src/Services/CouponService/AppyNox.Services.Coupon.Infrastructure/Repositories/CouponRepository.cs @@ -3,7 +3,6 @@ using AppyNox.Services.Base.Application.Interfaces.Repositories; using AppyNox.Services.Base.Core.Common; using AppyNox.Services.Base.Infrastructure.Repositories; -using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.Extended; using AppyNox.Services.Coupon.Infrastructure.Data; using Microsoft.EntityFrameworkCore; using System.Linq.Dynamic.Core; @@ -60,7 +59,7 @@ public async Task> GetAllEfCoreAsync(IQueryParameters .Take(queryParameters.PageSize) .ToListAsync(); - _logger.LogInformation($"Successfully retrieved entities. Type: '{typeof(CouponWithAllRelationsDto).Name}'."); + _logger.LogInformation($"Successfully retrieved entities. Type: '{typeof(CouponRoot).Name}'."); return new PaginatedList { Items = entities, diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.WebAPI/Controllers/v1_0/CouponsController.cs b/src/Services/CouponService/AppyNox.Services.Coupon.WebAPI/Controllers/v1_0/CouponsController.cs index 1fc0d369..1192ac75 100644 --- a/src/Services/CouponService/AppyNox.Services.Coupon.WebAPI/Controllers/v1_0/CouponsController.cs +++ b/src/Services/CouponService/AppyNox.Services.Coupon.WebAPI/Controllers/v1_0/CouponsController.cs @@ -1,13 +1,12 @@ -using AppyNox.Services.Base.API.Attributes; -using AppyNox.Services.Base.API.Constants; +using AppyNox.Services.Base.API.Constants; using AppyNox.Services.Base.API.Controllers; -using AppyNox.Services.Base.API.ViewModels; +using AppyNox.Services.Base.API.Wrappers; using AppyNox.Services.Base.Application.Interfaces.Loggers; using AppyNox.Services.Base.Application.MediatR; using AppyNox.Services.Base.Application.MediatR.Commands; -using AppyNox.Services.Base.Core.Enums; +using AppyNox.Services.Base.Infrastructure.Repositories.Common; +using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models; using AppyNox.Services.Coupon.Domain.Coupons; -using AppyNox.Services.Coupon.Domain.Coupons.Builders; using Asp.Versioning; using MediatR; using Microsoft.AspNetCore.Authorization; @@ -32,27 +31,23 @@ public class CouponsController(IMediator mediator, INoxApiLogger GetAll([FromQuery] QueryParametersViewModel queryParameters) + public async Task>>> GetAll([FromQuery] QueryParameters queryParameters) { - logger.LogInformation("sa"); - return base.Ok(await _mediator.Send(new GetAllNoxEntitiesQuery(queryParameters))); + return base.Ok(await _mediator.Send(new GetAllNoxEntitiesQuery(queryParameters))); } [HttpGet("{id}")] [Authorize(Coupons.View)] - [SwaggerDynamicRequestBody(typeof(CouponAggreagate), DtoLevelMappingTypes.DataAccess)] - public async Task GetById(Guid id, [FromQuery] QueryParametersViewModel queryParameters) + public async Task GetById(Guid id, [FromQuery] QueryParameters queryParameters) { - return base.Ok(await _mediator.Send(new GetNoxEntityByIdQuery(new CouponId(id), queryParameters))); + return base.Ok(await _mediator.Send(new GetNoxEntityByIdQuery(new CouponId(id), queryParameters))); } [HttpPost] [Authorize(Coupons.Create)] - [SwaggerDynamicRequestBody(typeof(CouponAggreagate), DtoLevelMappingTypes.Create)] - public async Task Create([FromBody] dynamic couponDto, string detailLevel = "Simple") + public async Task Create([FromBody] CouponCreateDto couponDto) { - Guid result = await _mediator.Send(new CreateNoxEntityCommand(couponDto, detailLevel)); + Guid result = await _mediator.Send(new CreateNoxEntityCommand(couponDto)); return CreatedAtAction(nameof(GetById), new { id = result }, result); } @@ -61,19 +56,20 @@ public async Task Create([FromBody] dynamic couponDto, string det [Authorize(Coupons.Delete)] public async Task Delete(Guid id) { - var t1 = new NoxCommandAction(TestBeh); - var t2 = new NoxCommandAction(TestBeh2); + var t1 = new NoxCommandAction(NoxCommandActionMethodTest1); + var t2 = new NoxCommandAction(NoxCommandActionMethodTest2); NoxCommandExtensions extensions = new(t1, t2); await _mediator.Send(new DeleteNoxEntityCommand(new CouponId(id), false, extensions)); return NoContent(); } - private void TestBeh() + // Below methods are for manual testing + private void NoxCommandActionMethodTest1() { Console.WriteLine(1); } - private void TestBeh2() + private void NoxCommandActionMethodTest2() { Console.WriteLine(2); } diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.WebAPI/Controllers/v1_0/TicketsController.cs b/src/Services/CouponService/AppyNox.Services.Coupon.WebAPI/Controllers/v1_0/TicketsController.cs index 240c4841..3815050d 100644 --- a/src/Services/CouponService/AppyNox.Services.Coupon.WebAPI/Controllers/v1_0/TicketsController.cs +++ b/src/Services/CouponService/AppyNox.Services.Coupon.WebAPI/Controllers/v1_0/TicketsController.cs @@ -1,9 +1,8 @@ -using AppyNox.Services.Base.API.Attributes; -using AppyNox.Services.Base.API.Constants; +using AppyNox.Services.Base.API.Constants; using AppyNox.Services.Base.API.Controllers; -using AppyNox.Services.Base.API.ViewModels; using AppyNox.Services.Base.Application.MediatR.Commands; -using AppyNox.Services.Base.Core.Enums; +using AppyNox.Services.Base.Infrastructure.Repositories.Common; +using AppyNox.Services.Coupon.Application.Dtos.TicketDtos.Models; using AppyNox.Services.Coupon.Domain.Entities; using Asp.Versioning; using MediatR; @@ -27,35 +26,32 @@ public class TicketsController(IMediator mediator) : NoxController [HttpGet] [AllowAnonymous] - [SwaggerDynamicRequestBody(typeof(Ticket), DtoLevelMappingTypes.DataAccess, true)] - public async Task GetAll([FromQuery] QueryParametersViewModel queryParameters) + public async Task GetAll([FromQuery] QueryParameters queryParameters) { - return base.Ok(await _mediator.Send(new GetAllEntitiesQuery(queryParameters))); + return base.Ok(await _mediator.Send(new GetAllEntitiesQuery(queryParameters))); } [HttpGet("{id}")] [AllowAnonymous] - [SwaggerDynamicRequestBody(typeof(Ticket), DtoLevelMappingTypes.DataAccess)] - public async Task GetById(Guid id, [FromQuery] QueryParametersViewModel queryParameters) + public async Task GetById(Guid id, [FromQuery] QueryParameters queryParameters) { - return base.Ok(await _mediator.Send(new GetEntityByIdQuery(id, queryParameters))); + return base.Ok(await _mediator.Send(new GetEntityByIdQuery(id, queryParameters))); } [HttpPost] [AllowAnonymous] - [SwaggerDynamicRequestBody(typeof(Ticket), DtoLevelMappingTypes.Create, true)] - public async Task Create([FromBody] dynamic ticketDto, string detailLevel = "Simple") + public async Task Create([FromBody] TicketCreateDto ticketDto) { - Guid result = await _mediator.Send(new CreateEntityCommand(ticketDto, detailLevel)); + Guid result = await _mediator.Send(new CreateEntityCommand(ticketDto)); return CreatedAtAction(nameof(GetById), new { id = result }, result); } [HttpPut("{id}")] [AllowAnonymous] - public async Task Update(Guid id, [FromBody] dynamic ticketEntity, string detailLevel = "Simple") + public async Task Update(Guid id, [FromBody] TicketUpdateDto ticketEntity) { - await _mediator.Send(new UpdateEntityCommand(id, ticketEntity, detailLevel)); + await _mediator.Send(new UpdateEntityCommand(id, ticketEntity)); return NoContent(); } diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.WebAPI/Controllers/v1_1/CouponsController .cs b/src/Services/CouponService/AppyNox.Services.Coupon.WebAPI/Controllers/v1_1/CouponsController .cs index 1a931a43..6d0aa5e5 100644 --- a/src/Services/CouponService/AppyNox.Services.Coupon.WebAPI/Controllers/v1_1/CouponsController .cs +++ b/src/Services/CouponService/AppyNox.Services.Coupon.WebAPI/Controllers/v1_1/CouponsController .cs @@ -1,11 +1,10 @@ using AppyNox.Services.Base.API.Constants; using AppyNox.Services.Base.API.Controllers; -using AppyNox.Services.Base.API.ViewModels; using AppyNox.Services.Base.Application.MediatR.Commands; using AppyNox.Services.Base.Core.AsyncLocals; using AppyNox.Services.Base.Core.Common; -using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.Base; -using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.Extended; +using AppyNox.Services.Base.Infrastructure.Repositories.Common; +using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models; using AppyNox.Services.Coupon.Application.MediatR.Commands; using AppyNox.Services.Coupon.Domain.Coupons; using AppyNox.Services.Coupon.Infrastructure.Authentication; @@ -42,25 +41,32 @@ public class CouponsController( [HttpGet] [Authorize(Coupons.View)] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(PaginatedList))] - public async Task GetAll([FromQuery] QueryParametersViewModelBasic queryParameters) + public async Task GetAll([FromQuery] QueryParameters queryParameters) { - PaginatedList response = await _mediator.Send(new GetAllNoxEntitiesQuery(queryParameters)); + PaginatedList response = await _mediator.Send(new GetAllNoxEntitiesQuery(queryParameters)); return Ok(response); } [HttpGet("{id}")] [Authorize(Coupons.View)] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(CouponSimpleDto))] - public async Task GetById(Guid id, [FromQuery] QueryParametersViewModelBasic queryParameters) + public async Task GetById(Guid id, [FromQuery] QueryParameters queryParameters) { - return base.Ok(await _mediator.Send(new GetNoxEntityByIdQuery(new CouponId(id), queryParameters))); + return base.Ok(await _mediator.Send(new GetNoxEntityByIdQuery(new CouponId(id), queryParameters))); + } + + [HttpPost] + [Authorize(Coupons.Create)] + public async Task Create([FromBody] CouponCompositeCreateDto couponDto) + { + Guid result = await _mediator.Send(new CreateNoxEntityCommand(couponDto)); + + return CreatedAtAction(nameof(GetById), new { id = result }, result); } [HttpPut("{id}")] [Authorize(Coupons.Edit)] - public async Task Update(Guid id, [FromBody] CouponExtendedUpdateDto couponDto) + public async Task Update(Guid id, [FromBody] CouponUpdateDto couponDto) { await _mediator.Send(new UpdateCouponCommand(id, couponDto)); return NoContent(); @@ -102,11 +108,11 @@ public IActionResult GetCouponDummyToken() [HttpGet] [Authorize(CouponCustomJwt.CustomView)] - [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(PaginatedList))] + [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(PaginatedList))] [Route("/api/v{version:apiVersion}/coupons/getwithcustomjwt")] - public async Task GetAllCustomAsync([FromQuery] QueryParametersViewModelBasic queryParameters) + public async Task GetAllCustomAsync([FromQuery] QueryParameters queryParameters) { - PaginatedList response = await _mediator.Send(new GetAllNoxEntitiesQuery(queryParameters)); + PaginatedList response = await _mediator.Send(new GetAllNoxEntitiesQuery(queryParameters)); return Ok(response); } diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.WebAPI/Program.cs b/src/Services/CouponService/AppyNox.Services.Coupon.WebAPI/Program.cs index e890b0b3..d7abf5cf 100644 --- a/src/Services/CouponService/AppyNox.Services.Coupon.WebAPI/Program.cs +++ b/src/Services/CouponService/AppyNox.Services.Coupon.WebAPI/Program.cs @@ -1,9 +1,11 @@ using AppyNox.Services.Base.API; +using AppyNox.Services.Base.API.Constants; using AppyNox.Services.Base.Infrastructure.Extensions; using AppyNox.Services.Coupon.Application; using AppyNox.Services.Coupon.Domain; using AppyNox.Services.Coupon.Infrastructure; using AppyNox.Services.Coupon.Infrastructure.Data; +using System; var builder = WebApplication.CreateBuilder(args); @@ -23,6 +25,7 @@ await builder.AddApiServices(options => app.ConfigureNoxApi(options => { + options.Versions = [NoxVersions.v1_0, NoxVersions.v1_1]; options.LocalizationServices = (localizerFactory) => { localizerFactory.AddCouponDomainLocalizationService(); diff --git a/src/Services/CouponService/AppyNox.Services.Coupon.WebAPI/appsettings.Development.json b/src/Services/CouponService/AppyNox.Services.Coupon.WebAPI/appsettings.Development.json index 016892a7..5494fd19 100644 --- a/src/Services/CouponService/AppyNox.Services.Coupon.WebAPI/appsettings.Development.json +++ b/src/Services/CouponService/AppyNox.Services.Coupon.WebAPI/appsettings.Development.json @@ -49,7 +49,7 @@ "Tags": [ "Coupon", "Coupons" ], "HealthCheckServiceHost": "host.docker.internal", "HealthCheckUrl": "api/health", - "HealthCheckIntervalSeconds": 30, + "HealthCheckIntervalSeconds": 5, "HealthCheckTimeoutSeconds": 5 }, "Redis": { @@ -61,7 +61,7 @@ }, "MessageBroker": { "Host": "rabbitmq://localhost", - "Username": "guest", - "Password": "guest" + "Username": "HappiCorp", + "Password": "HappiCorp" } } \ No newline at end of file diff --git a/src/Services/CouponService/Tests/IntegrationTests/AppyNox.Services.Coupon.WebAPI.IntegrationTest/Controllers/v1_0/CouponApiTest.cs b/src/Services/CouponService/Tests/IntegrationTests/AppyNox.Services.Coupon.WebAPI.IntegrationTest/Controllers/v1_0/CouponApiTest.cs index e4e088c5..3d1e8e59 100644 --- a/src/Services/CouponService/Tests/IntegrationTests/AppyNox.Services.Coupon.WebAPI.IntegrationTest/Controllers/v1_0/CouponApiTest.cs +++ b/src/Services/CouponService/Tests/IntegrationTests/AppyNox.Services.Coupon.WebAPI.IntegrationTest/Controllers/v1_0/CouponApiTest.cs @@ -5,10 +5,11 @@ using AppyNox.Services.Base.IntegrationTests.URIs; using AppyNox.Services.Base.IntegrationTests.Wrapper; using AppyNox.Services.Base.IntegrationTests.Wrapper.Helpers; -using AppyNox.Services.Coupon.Application.Dtos.CouponDetailDtos.Models.Basic; -using AppyNox.Services.Coupon.Application.Dtos.CouponDetailTagDtos.Models.Basic; -using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.Base; -using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.Extended; +using AppyNox.Services.Coupon.Application.Dtos.CouponDetailDtos.Models; +using AppyNox.Services.Coupon.Application.Dtos.CouponDetailDtos.Models.ValueObjects; +using AppyNox.Services.Coupon.Application.Dtos.CouponDetailTagDtos.Models; +using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models; +using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.ValueObjects; using AppyNox.Services.Coupon.Domain.Exceptions.Base; using AppyNox.Services.Coupon.WebAPI.IntegrationTest.Fixtures; using System.Linq.Dynamic.Core; @@ -43,15 +44,13 @@ public async Task GetAll_ShouldReturnSuccessStatusCode() { // Act var response = await _client.GetAsync($"{_serviceURIs.CouponServiceURI}/v{NoxVersions.v1_0}/coupons"); - - var jsonResponse = await response.Content.ReadAsStringAsync(); - - var coupons = NoxResponseUnwrapper.UnwrapData>(jsonResponse, _jsonSerializerOptions); + var wrappedResponse = await NoxResponseUnwrapper.UnwrapResponse>(response, _jsonSerializerOptions); // Assert response.EnsureSuccessStatusCode(); Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(coupons.Items); + Assert.NotNull(wrappedResponse.Result.Data); + Assert.NotNull(wrappedResponse.Result.Data.Items); } [Fact] @@ -76,13 +75,12 @@ public async Task GetById_ShouldReturnSuccessStatusCode() // Act var response = await _client.GetAsync(requestUri); - var jsonResponse = await response.Content.ReadAsStringAsync(); - var couponObj = NoxResponseUnwrapper.UnwrapData(jsonResponse, _jsonSerializerOptions); + var wrappedResponse = await NoxResponseUnwrapper.UnwrapResponse(response, _jsonSerializerOptions); // Assert response.EnsureSuccessStatusCode(); Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(couponObj); + Assert.NotNull(wrappedResponse.Result.Data); #endregion } @@ -96,7 +94,7 @@ public async Task Create_ShouldAddNewCoupon() // Arrange var requestUri = $"{_serviceURIs.CouponServiceURI}/v{NoxVersions.v1_0}/coupons"; - CouponSimpleCreateDto couponSimpleCreateDto = new() + CouponCreateDto couponSimpleCreateDto = new() { Code = "ffff2", Amount = new AmountDto() @@ -108,84 +106,27 @@ public async Task Create_ShouldAddNewCoupon() CouponDetailId = new CouponDetailIdDto() { Value = new Guid("ec80532f-58f0-4690-b40c-2133b067d5f2") - } - }; - var jsonRequest = JsonSerializer.Serialize(couponSimpleCreateDto); - var content = new StringContent(jsonRequest, Encoding.UTF8, "application/json"); - - // Act - HttpResponseMessage response = await _client.PostAsync(requestUri, content); - string jsonResponse = await response.Content.ReadAsStringAsync(); - Guid id = NoxResponseUnwrapper.UnwrapData(jsonResponse, _jsonSerializerOptions); - - // Assert - response.EnsureSuccessStatusCode(); - Assert.Equal(HttpStatusCode.Created, response.StatusCode); - Assert.NotEqual(id, Guid.Empty); - - #endregion - - #region [ Get Coupons ] - - // Act - var coupon = _couponApiTestFixture.DbContext.Coupons.Where("Id == @0", new CouponId(id)).FirstOrDefault(); - - // Assert - Assert.NotNull(coupon); - - #endregion - } - - [Fact] - [Order(4)] - public async Task BulkCreate_ShouldAddNewCoupon() - { - #region [ Create Coupon ] - - // Arrange - var requestUri = $"{_serviceURIs.CouponServiceURI}/v{NoxVersions.v1_0}/coupons?DetailLevel=Bulk"; - - CouponBulkCreateDto couponSimpleCreateDto = new() - { - Code = "ffff2", - Amount = new AmountDto() - { - MinAmount = 12, - DiscountAmount = 2, }, - Description = "string", - CouponDetail = new CouponDetailBulkCreateDto() - { - Code = "test1", - Detail = "testdetail", - CouponDetailTags = - [ - new CouponDetailTagBulkCreateDto - { - Tag = "DummyTag" - } - ] - } + Detail = "detail" }; var jsonRequest = JsonSerializer.Serialize(couponSimpleCreateDto); var content = new StringContent(jsonRequest, Encoding.UTF8, "application/json"); // Act HttpResponseMessage response = await _client.PostAsync(requestUri, content); - string jsonResponse = await response.Content.ReadAsStringAsync(); - Guid id = NoxResponseUnwrapper.UnwrapData(jsonResponse, _jsonSerializerOptions); + NoxApiResponse wrappedResponse = await NoxResponseUnwrapper.UnwrapResponse(response, _jsonSerializerOptions); // Assert response.EnsureSuccessStatusCode(); Assert.Equal(HttpStatusCode.Created, response.StatusCode); - Assert.NotEqual(id, Guid.Empty); + Assert.NotEqual(wrappedResponse.Result.Data, Guid.Empty); #endregion #region [ Get Coupons ] // Act - var coupon = _couponApiTestFixture.DbContext.Coupons.Where("Id == @0", new CouponId(id)).FirstOrDefault(); + var coupon = _couponApiTestFixture.DbContext.Coupons.Where("Id == @0", new CouponId(wrappedResponse.Result.Data)).FirstOrDefault(); // Assert Assert.NotNull(coupon); @@ -194,7 +135,7 @@ public async Task BulkCreate_ShouldAddNewCoupon() } [Fact] - [Order(5)] + [Order(4)] public async Task Create_ShouldThrowValidationException() { #region [ Create Coupon ] @@ -202,7 +143,7 @@ public async Task Create_ShouldThrowValidationException() // Arrange var requestUri = $"{_serviceURIs.CouponServiceURI}/v{NoxVersions.v1_0}/coupons"; - CouponSimpleCreateDto couponSimpleCreateDto = new() + CouponCreateDto couponSimpleCreateDto = new() { Code = "ffff2", Amount = new AmountDto() @@ -221,7 +162,7 @@ public async Task Create_ShouldThrowValidationException() // Act HttpResponseMessage response = await _client.PostAsync(requestUri, content); - NoxApiResponse unwrappedResponse = await NoxResponseUnwrapper.UnwrapResponse(response, _jsonSerializerOptions); + NoxApiResponse unwrappedResponse = await NoxResponseUnwrapper.UnwrapResponse(response, _jsonSerializerOptions); // Assert Assert.True(unwrappedResponse.HasError); @@ -239,7 +180,7 @@ public async Task Create_ShouldThrowValidationException() } [Fact] - [Order(6)] + [Order(5)] public async Task Create_ShouldThrowDomainException() { #region [ Create Coupon ] @@ -247,7 +188,7 @@ public async Task Create_ShouldThrowDomainException() // Arrange var requestUri = $"{_serviceURIs.CouponServiceURI}/v{NoxVersions.v1_0}/coupons"; - CouponSimpleCreateDto couponSimpleCreateDto = new() + CouponCreateDto couponSimpleCreateDto = new() { Code = "ffff2", Amount = new AmountDto() @@ -266,7 +207,7 @@ public async Task Create_ShouldThrowDomainException() // Act HttpResponseMessage response = await _client.PostAsync(requestUri, content); - NoxApiResponse unwrappedResponse = await NoxResponseUnwrapper.UnwrapResponse(response, _jsonSerializerOptions); + NoxApiResponse unwrappedResponse = await NoxResponseUnwrapper.UnwrapResponse(response, _jsonSerializerOptions); // Assert Assert.True(unwrappedResponse.HasError); @@ -284,7 +225,7 @@ public async Task Create_ShouldThrowDomainException() } [Fact] - [Order(7)] + [Order(6)] public async Task Delete_ShouldDeleteEntity() { #region [ Get Coupon ] diff --git a/src/Services/CouponService/Tests/IntegrationTests/AppyNox.Services.Coupon.WebAPI.IntegrationTest/Controllers/v1_0/TicketApiTest.cs b/src/Services/CouponService/Tests/IntegrationTests/AppyNox.Services.Coupon.WebAPI.IntegrationTest/Controllers/v1_0/TicketApiTest.cs index 81e49c57..b431be85 100644 --- a/src/Services/CouponService/Tests/IntegrationTests/AppyNox.Services.Coupon.WebAPI.IntegrationTest/Controllers/v1_0/TicketApiTest.cs +++ b/src/Services/CouponService/Tests/IntegrationTests/AppyNox.Services.Coupon.WebAPI.IntegrationTest/Controllers/v1_0/TicketApiTest.cs @@ -3,21 +3,16 @@ using AppyNox.Services.Base.Application.Exceptions.Base; using AppyNox.Services.Base.Core.Common; using AppyNox.Services.Base.Infrastructure.Repositories; -using AppyNox.Services.Base.Infrastructure.Services.LoggerService; using AppyNox.Services.Base.IntegrationTests.Stubs; using AppyNox.Services.Base.IntegrationTests.URIs; using AppyNox.Services.Base.IntegrationTests.Wrapper; using AppyNox.Services.Base.IntegrationTests.Wrapper.Helpers; -using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.Base; -using AppyNox.Services.Coupon.Application.Dtos.TicketDtos.Models.Basic; -using AppyNox.Services.Coupon.Application.Dtos.TicketDtos.Models.Extended; +using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models; +using AppyNox.Services.Coupon.Application.Dtos.TicketDtos.Models; using AppyNox.Services.Coupon.Domain.Entities; using AppyNox.Services.Coupon.Infrastructure.Repositories; using AppyNox.Services.Coupon.WebAPI.IntegrationTest.Fixtures; -using Castle.Core.Logging; using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Logging; -using Moq; using System.Linq.Dynamic.Core; using System.Net; using System.Text; @@ -50,14 +45,13 @@ public async Task GetAll_ShouldReturnSuccessStatusCode() // Act var response = await _client.GetAsync($"{_serviceURIs.CouponServiceURI}/v{NoxVersions.v1_0}/tickets"); - var jsonResponse = await response.Content.ReadAsStringAsync(); - - var coupons = NoxResponseUnwrapper.UnwrapData>(jsonResponse, _jsonSerializerOptions); + var wrappedResponse = await NoxResponseUnwrapper.UnwrapResponse>(response, _jsonSerializerOptions); // Assert response.EnsureSuccessStatusCode(); Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(coupons.Items); + Assert.NotNull(wrappedResponse.Result.Data); + Assert.NotNull(wrappedResponse.Result.Data.Items); } [Fact] @@ -82,13 +76,12 @@ public async Task GetById_ShouldReturnSuccessStatusCode() // Act var response = await _client.GetAsync(requestUri); - var jsonResponse = await response.Content.ReadAsStringAsync(); - var ticketObj = NoxResponseUnwrapper.UnwrapData(jsonResponse, _jsonSerializerOptions); + var wrappedResponse = await NoxResponseUnwrapper.UnwrapResponse(response, _jsonSerializerOptions); // Assert response.EnsureSuccessStatusCode(); Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(ticketObj); + Assert.NotNull(wrappedResponse.Result.Data); #endregion } @@ -102,7 +95,7 @@ public async Task Create_ShouldAddNewTicket() // Arrange var requestUri = $"{_serviceURIs.CouponServiceURI}/v{NoxVersions.v1_0}/tickets"; - TicketSimpleCreateDto ticketSimpleCreateDto = new() + TicketCreateDto ticketSimpleCreateDto = new() { Title = "new title", Content = "new content", @@ -113,8 +106,8 @@ public async Task Create_ShouldAddNewTicket() // Act HttpResponseMessage response = await _client.PostAsync(requestUri, content); - string jsonResponse = await response.Content.ReadAsStringAsync(); - Guid id = NoxResponseUnwrapper.UnwrapData(jsonResponse, _jsonSerializerOptions); + NoxApiResponse wrappedResponse = await NoxResponseUnwrapper.UnwrapResponse(response, _jsonSerializerOptions); + Guid id = wrappedResponse.Result.Data; // Assert response.EnsureSuccessStatusCode(); @@ -143,7 +136,7 @@ public async Task Create_ShouldThrowValidationException() // Arrange var requestUri = $"{_serviceURIs.CouponServiceURI}/v{NoxVersions.v1_0}/tickets"; - TicketSimpleCreateDto ticketSimpleCreateDto = new() + TicketCreateDto ticketSimpleCreateDto = new() { Title = string.Empty, Content = "new content" @@ -153,7 +146,7 @@ public async Task Create_ShouldThrowValidationException() // Act HttpResponseMessage response = await _client.PostAsync(requestUri, content); - NoxApiResponse unwrappedResponse = await NoxResponseUnwrapper.UnwrapResponse(response, _jsonSerializerOptions); + NoxApiResponse unwrappedResponse = await NoxResponseUnwrapper.UnwrapResponse(response, _jsonSerializerOptions); // Assert Assert.True(unwrappedResponse.HasError); @@ -201,7 +194,7 @@ public async Task Update_ShouldUpdateTicket() string updatedTitle = "updated title"; string updatedContent = "updated content"; - TicketSimpleUpdateDto ticketSimpleUpdateDto = new() + TicketUpdateDto ticketSimpleUpdateDto = new() { Title = updatedTitle, Content = updatedContent, diff --git a/src/Services/CouponService/Tests/IntegrationTests/AppyNox.Services.Coupon.WebAPI.IntegrationTest/Controllers/v1_1/CouponApiTestV1_1.cs b/src/Services/CouponService/Tests/IntegrationTests/AppyNox.Services.Coupon.WebAPI.IntegrationTest/Controllers/v1_1/CouponApiTestV1_1.cs index 52dda3dc..bab24456 100644 --- a/src/Services/CouponService/Tests/IntegrationTests/AppyNox.Services.Coupon.WebAPI.IntegrationTest/Controllers/v1_1/CouponApiTestV1_1.cs +++ b/src/Services/CouponService/Tests/IntegrationTests/AppyNox.Services.Coupon.WebAPI.IntegrationTest/Controllers/v1_1/CouponApiTestV1_1.cs @@ -1,10 +1,14 @@ using AppyNox.Services.Base.API.Constants; +using AppyNox.Services.Base.API.Wrappers; using AppyNox.Services.Base.Infrastructure.Repositories; using AppyNox.Services.Base.IntegrationTests.Stubs; using AppyNox.Services.Base.IntegrationTests.URIs; -using AppyNox.Services.Coupon.Application.Dtos.CouponDetailDtos.Models.Basic; -using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.Base; -using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.Extended; +using AppyNox.Services.Base.IntegrationTests.Wrapper.Helpers; +using AppyNox.Services.Coupon.Application.Dtos.CouponDetailDtos.Models; +using AppyNox.Services.Coupon.Application.Dtos.CouponDetailDtos.Models.ValueObjects; +using AppyNox.Services.Coupon.Application.Dtos.CouponDetailTagDtos.Models; +using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models; +using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.ValueObjects; using AppyNox.Services.Coupon.Domain.Coupons; using AppyNox.Services.Coupon.Domain.Coupons.Builders; using AppyNox.Services.Coupon.Infrastructure.Repositories; @@ -68,7 +72,7 @@ public async Task Update_ShouldUpdateCoupon() int minimumAmount = coupon.Amount.MinAmount + 10; string detail = "This detail is modified"; - CouponExtendedUpdateDto couponExtendedUpdateDto = new() + CouponUpdateDto couponExtendedUpdateDto = new() { Code = "test1", Amount = new AmountDto() @@ -115,5 +119,62 @@ public async Task Update_ShouldUpdateCoupon() #endregion } + [Fact] + [Order(2)] + public async Task CompositeCreate_ShouldAddNewCoupon() + { + #region [ Create Coupon ] + + // Arrange + var requestUri = $"{_serviceURIs.CouponServiceURI}/v{NoxVersions.v1_1}/coupons"; + + CouponCompositeCreateDto couponSimpleCreateDto = new() + { + Code = "ffff2", + Amount = new AmountDto() + { + MinAmount = 12, + DiscountAmount = 2, + }, + Description = "string", + CouponDetail = new CouponDetailCompositeCreateDto() + { + Code = "test1", + Detail = "testdetail", + CouponDetailTags = + [ + new CouponDetailTagCompositeCreateDto + { + Tag = "DummyTag" + } + ] + } + }; + var jsonRequest = JsonSerializer.Serialize(couponSimpleCreateDto); + var content = new StringContent(jsonRequest, Encoding.UTF8, "application/json"); + + // Act + HttpResponseMessage response = await _client.PostAsync(requestUri, content); + NoxApiResponse wrappedResponse = await NoxResponseUnwrapper.UnwrapResponse(response, _jsonSerializerOptions); + Guid id = wrappedResponse.Result.Data; + + // Assert + response.EnsureSuccessStatusCode(); + Assert.Equal(HttpStatusCode.Created, response.StatusCode); + Assert.NotEqual(id, Guid.Empty); + + #endregion + + #region [ Get Coupons ] + + // Act + var coupon = _couponApiTestFixture.DbContext.Coupons.Where("Id == @0", new CouponId(id)).FirstOrDefault(); + + // Assert + Assert.NotNull(coupon); + + #endregion + } + #endregion } \ No newline at end of file diff --git a/src/Services/CouponService/Tests/UnitTests/AppyNox.Services.Coupon.Application.UnitTest/CQRSTests/CouponDddCQRSUnitTest.cs b/src/Services/CouponService/Tests/UnitTests/AppyNox.Services.Coupon.Application.UnitTest/CQRSTests/CouponDddCQRSUnitTest.cs index db1ba7d3..ac1bb670 100644 --- a/src/Services/CouponService/Tests/UnitTests/AppyNox.Services.Coupon.Application.UnitTest/CQRSTests/CouponDddCQRSUnitTest.cs +++ b/src/Services/CouponService/Tests/UnitTests/AppyNox.Services.Coupon.Application.UnitTest/CQRSTests/CouponDddCQRSUnitTest.cs @@ -1,23 +1,24 @@ using AppyNox.Services.Base.Application.Exceptions.Base; using AppyNox.Services.Base.Application.Interfaces.Caches; using AppyNox.Services.Base.Application.Interfaces.Repositories; +using AppyNox.Services.Base.Application.Localization; using AppyNox.Services.Base.Application.MediatR; using AppyNox.Services.Base.Application.MediatR.Commands; using AppyNox.Services.Base.Application.UnitTests.CQRSFixtures; using AppyNox.Services.Base.Application.UnitTests.Stubs; using AppyNox.Services.Base.Core.AsyncLocals; using AppyNox.Services.Base.Core.Common; -using AppyNox.Services.Base.Core.Extensions; -using AppyNox.Services.Coupon.Application.Dtos.CouponDetailDtos.Models.Basic; -using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.DetailLevel; -using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.Base; +using AppyNox.Services.Coupon.Application.Dtos.CouponDetailDtos.Models.ValueObjects; +using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models; +using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.ValueObjects; using AppyNox.Services.Coupon.Domain.Coupons; using AppyNox.Services.Coupon.Domain.Coupons.Builders; +using AppyNox.Services.Coupon.Domain.Localization; using MediatR; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Localization; using Moq; -using System; using System.Text.Json; using CouponAggregate = AppyNox.Services.Coupon.Domain.Coupons.Coupon; using NCEHelper = AppyNox.Services.Base.Application.UnitTests.Helpers.NoxCommandExtensionsHelper; @@ -67,7 +68,7 @@ public CouponDddCQRSUnitTest(NoxApplicationTestFixture fixture) CouponDetail newDetail = new CouponDetailBuilder().WithDetails("test01", "testdetail").Build(); CouponAggregate couponEntity = new CouponBuilder().WithDetails("code", "description", "detail").WithAmount(10, 15).WithCouponDetail(newDetail).MarkAsBulkCreate().Build(); - CouponSimpleDto couponSimpleDto = new() + CouponDto couponSimpleDto = new() { Code = "code", Description = "description", @@ -84,6 +85,12 @@ public CouponDddCQRSUnitTest(NoxApplicationTestFixture fixture) .ReturnsAsync(couponEntity); #endregion + + #region [ Localizer ] + + InitializeRealLocalizer(); + + #endregion } #endregion @@ -94,7 +101,7 @@ public CouponDddCQRSUnitTest(NoxApplicationTestFixture fixture) public async Task GetAllEntitiesQuery_ShouldSuccess() { // Act - var result = await _mediator.Send(new GetAllNoxEntitiesQuery(_fixture.MockQueryParameters.Object)); + var result = await _mediator.Send(new GetAllNoxEntitiesQuery(_fixture.MockQueryParameters.Object)); // Assert Assert.NotNull(result); @@ -107,7 +114,7 @@ public async Task GetAllEntitiesQuery_ShouldCallActions() NoxCommandExtensions extensions = new([new(NCEHelper.DummyMethod1, RunType.Before), new(NCEHelper.DummyMethod2, RunType.After, suspendOnFailure: false)]); // Act - var result = await _mediator.Send(new GetAllNoxEntitiesQuery(_fixture.MockQueryParameters.Object, extensions)); + var result = await _mediator.Send(new GetAllNoxEntitiesQuery(_fixture.MockQueryParameters.Object, extensions)); // Assert Assert.NotNull(result); @@ -123,7 +130,7 @@ public async Task GetAllEntitiesQuery_ShouldActionFail() NoxCommandExtensions extensions = new([new(NCEHelper.DummyMethod1), new(NCEHelper.DummyMethod2, RunType.After)]); // Act - var exception = await Assert.ThrowsAsync(() => _mediator.Send(new GetAllNoxEntitiesQuery(_fixture.MockQueryParameters.Object, extensions))); + var exception = await Assert.ThrowsAsync(() => _mediator.Send(new GetAllNoxEntitiesQuery(_fixture.MockQueryParameters.Object, extensions))); // Assert Assert.Equal(RunStatus.Finished, extensions.Actions[0].Status); @@ -136,11 +143,11 @@ public async Task GetAllEntitiesQuery_ShouldActionFail() public async Task GetEntityByIdQuery_ShouldSuccess() { // Act - var result = await _mediator.Send(new GetNoxEntityByIdQuery(It.IsAny(), _fixture.MockQueryParameters.Object)); + var result = await _mediator.Send(new GetNoxEntityByIdQuery(It.IsAny(), _fixture.MockQueryParameters.Object)); // Assert Assert.NotNull(result); - Assert.True(result is CouponSimpleDto); + Assert.True(result is CouponDto); } [Fact] @@ -150,11 +157,11 @@ public async Task GetEntityByIdQuery_ShouldCallActions() NoxCommandExtensions extensions = new([new(NCEHelper.DummyMethod1, RunType.Before), new(NCEHelper.DummyMethod2, RunType.After, suspendOnFailure: false)]); // Act - var result = await _mediator.Send(new GetNoxEntityByIdQuery(It.IsAny(), _fixture.MockQueryParameters.Object, Extensions: extensions)); + var result = await _mediator.Send(new GetNoxEntityByIdQuery(It.IsAny(), _fixture.MockQueryParameters.Object, Extensions: extensions)); // Assert Assert.NotNull(result); - Assert.True(result is CouponSimpleDto); + Assert.True(result is CouponDto); Assert.Equal(RunStatus.Finished, extensions.Actions[0].Status); Assert.Equal(RunStatus.ExitedWithError, extensions.Actions[1].Status); Assert.Equal("B0MA0", string.Concat(extensions.RunOrderHistory)); @@ -164,34 +171,34 @@ public async Task GetEntityByIdQuery_ShouldCallActions() public async Task CreateEntityCommand_ShouldSuccess() { // Prepare - string jsonData = @" + CouponCompositeCreateDto dto = new() { - ""code"": ""fffj9"", - ""amount"":{ - ""discountAmount"": 2, - ""minAmount"": 13 - }, - ""description"": ""string"", - ""couponDetail"" : { - ""detail"" : ""details detail"", - ""code"":""deta1"", - ""couponDetailTags"": [ - { - ""tag"" : ""tag1"" - }, - { - ""tag"":""tag2"" - } - ] - } - }"; - JsonDocument jsonDocument = JsonDocument.Parse(jsonData); - JsonElement root = jsonDocument.RootElement; + Code = "fffj9", + Amount = new() + { + DiscountAmount = 2, + MinAmount = 13 + }, + Description = "Description", + CouponDetail = new() + { + Code = "Deta1", + CouponDetailTags = [ + new() + { + Tag = "Tag1" + }, + new() + { + Tag = "Tag2" + } + ] + } + }; NoxContext.UserId = Guid.Parse("a8bfc75b-2ac3-47e2-b013-8b8a1efba45d"); // Act - var result = await _mediator - .Send(new CreateNoxEntityCommand(root, CouponCreateDetailLevel.Bulk.GetDisplayName())); + var result = await _mediator.Send(new CreateNoxEntityCommand(dto)); // Assert Assert.True(Guid.TryParse(result.ToString(), out _)); @@ -204,34 +211,34 @@ public async Task CreateEntityCommand_ShouldCallActions() NoxCommandExtensions extensions = new([new(NCEHelper.DummyMethod1, RunType.Before), new(NCEHelper.DummyMethod2, RunType.After, suspendOnFailure: false)]); // Prepare - string jsonData = @" + CouponCompositeCreateDto dto = new() { - ""code"": ""fffj9"", - ""amount"":{ - ""discountAmount"": 2, - ""minAmount"": 13 - }, - ""description"": ""string"", - ""couponDetail"" : { - ""detail"" : ""details detail"", - ""code"":""deta1"", - ""couponDetailTags"": [ - { - ""tag"" : ""tag1"" - }, - { - ""tag"":""tag2"" - } - ] - } - }"; - JsonDocument jsonDocument = JsonDocument.Parse(jsonData); - JsonElement root = jsonDocument.RootElement; + Code = "fffj9", + Amount = new() + { + DiscountAmount = 2, + MinAmount = 13 + }, + Description = "Description", + CouponDetail = new() + { + Code = "Deta1", + CouponDetailTags = [ + new() + { + Tag = "Tag1" + }, + new() + { + Tag = "Tag2" + } + ] + } + }; NoxContext.UserId = Guid.Parse("a8bfc75b-2ac3-47e2-b013-8b8a1efba45d"); // Act - var result = await _mediator - .Send(new CreateNoxEntityCommand(root, CouponCreateDetailLevel.Bulk.GetDisplayName(), extensions)); + var result = await _mediator.Send(new CreateNoxEntityCommand(dto, extensions)); // Assert Assert.True(Guid.TryParse(result.ToString(), out _)); @@ -348,4 +355,11 @@ public void DeleteEntityCommand_ShouldCallActionsMixed2() } #endregion + + private void InitializeRealLocalizer() + { + var factory = _serviceProvider.GetRequiredService(); + CouponDomainResourceService.Initialize(factory); + } + } \ No newline at end of file diff --git a/src/Services/CouponService/Tests/UnitTests/AppyNox.Services.Coupon.Application.UnitTest/CQRSTests/TicketAnemicCQRSUnitTest.cs b/src/Services/CouponService/Tests/UnitTests/AppyNox.Services.Coupon.Application.UnitTest/CQRSTests/TicketAnemicCQRSUnitTest.cs index 2d409b30..1d47645b 100644 --- a/src/Services/CouponService/Tests/UnitTests/AppyNox.Services.Coupon.Application.UnitTest/CQRSTests/TicketAnemicCQRSUnitTest.cs +++ b/src/Services/CouponService/Tests/UnitTests/AppyNox.Services.Coupon.Application.UnitTest/CQRSTests/TicketAnemicCQRSUnitTest.cs @@ -7,7 +7,7 @@ using AppyNox.Services.Base.Application.UnitTests.Stubs; using AppyNox.Services.Base.Core.AsyncLocals; using AppyNox.Services.Base.Core.Common; -using AppyNox.Services.Coupon.Application.Dtos.TicketDtos.Models.Basic; +using AppyNox.Services.Coupon.Application.Dtos.TicketDtos.Models; using AppyNox.Services.Coupon.Domain.Entities; using MediatR; using Microsoft.Extensions.Configuration; @@ -61,7 +61,7 @@ public TicketAnemicCQRSUnitTest(NoxApplicationTestFixture fixture) TicketTag mockTag = new(); Ticket mockTicket = new(); - TicketSimpleDto mockTicketSimpleDto = new(); + TicketDto mockTicketSimpleDto = new(); mockRepository.Setup(repo => repo.GetAllAsync(It.IsAny(), It.IsAny())) .ReturnsAsync(new Mock>().Object); @@ -83,7 +83,7 @@ public TicketAnemicCQRSUnitTest(NoxApplicationTestFixture fixture) public async Task GetAllEntitiesQuery_ShouldSuccess() { // Act - var result = await _mediator.Send(new GetAllEntitiesQuery(_fixture.MockQueryParameters.Object)); + var result = await _mediator.Send(new GetAllEntitiesQuery(_fixture.MockQueryParameters.Object)); // Assert Assert.NotNull(result); @@ -96,7 +96,7 @@ public async Task GetAllEntitiesQuery_ShouldCallActions() NoxCommandExtensions extensions = new([new(NCEHelper.DummyMethod1, RunType.Before), new(NCEHelper.DummyMethod2, RunType.After, suspendOnFailure: false)]); // Act - var result = await _mediator.Send(new GetAllEntitiesQuery(_fixture.MockQueryParameters.Object, extensions)); + var result = await _mediator.Send(new GetAllEntitiesQuery(_fixture.MockQueryParameters.Object, extensions)); // Assert Assert.NotNull(result); @@ -109,11 +109,11 @@ public async Task GetAllEntitiesQuery_ShouldCallActions() public async Task GetEntityByIdQuery_ShouldSuccess() { // Act - var result = await _mediator.Send(new GetEntityByIdQuery(It.IsAny(), _fixture.MockQueryParameters.Object)); + var result = await _mediator.Send(new GetEntityByIdQuery(It.IsAny(), _fixture.MockQueryParameters.Object)); // Assert Assert.NotNull(result); - Assert.True(result is TicketSimpleDto); + Assert.True(result is TicketDto); } [Fact] public async Task GetEntityByIdQuery_ShouldCallActions() @@ -122,11 +122,11 @@ public async Task GetEntityByIdQuery_ShouldCallActions() NoxCommandExtensions extensions = new([new(NCEHelper.DummyMethod1, RunType.Before), new(NCEHelper.DummyMethod2, RunType.After, suspendOnFailure: false)]); // Act - var result = await _mediator.Send(new GetEntityByIdQuery(It.IsAny(), _fixture.MockQueryParameters.Object, Extensions: extensions)); + var result = await _mediator.Send(new GetEntityByIdQuery(It.IsAny(), _fixture.MockQueryParameters.Object, Extensions: extensions)); // Assert Assert.NotNull(result); - Assert.True(result is TicketSimpleDto); + Assert.True(result is TicketDto); Assert.Equal(RunStatus.Finished, extensions.Actions[0].Status); Assert.Equal(RunStatus.ExitedWithError, extensions.Actions[1].Status); Assert.Equal("B0MA0", string.Concat(extensions.RunOrderHistory)); @@ -136,18 +136,16 @@ public async Task GetEntityByIdQuery_ShouldCallActions() public async Task CreateEntityCommand_ShouldSuccess() { // Prepare - string jsonData = @"{ - ""title"":""Title nwe2"", - ""content"": ""Ticket content new2"", - ""reportDate"": ""2024-06-16T11:36:05.3303319Z"" - }"; - JsonDocument jsonDocument = JsonDocument.Parse(jsonData); - JsonElement root = jsonDocument.RootElement; + TicketCreateDto dto = new() + { + Title = "Title new", + Content = "Ticket content new", + ReportDate = DateTime.Now, + }; NoxContext.UserId = Guid.Parse("a8bfc75b-2ac3-47e2-b013-8b8a1efba45d"); // Act - var result = await _mediator - .Send(new CreateEntityCommand(root, CommonDetailLevels.Simple)); + var result = await _mediator.Send(new CreateEntityCommand(dto)); // Assert Assert.True(Guid.TryParse(result.ToString(), out _)); @@ -159,18 +157,16 @@ public async Task CreateEntityCommand_ShouldCallActions() // Prepare NoxCommandExtensions extensions = new([new(NCEHelper.DummyMethod1, RunType.Before), new(NCEHelper.DummyMethod2, RunType.After, suspendOnFailure: false)]); - string jsonData = @"{ - ""title"":""Title nwe2"", - ""content"": ""Ticket content new2"", - ""reportDate"": ""2024-06-16T11:36:05.3303319Z"" - }"; - JsonDocument jsonDocument = JsonDocument.Parse(jsonData); - JsonElement root = jsonDocument.RootElement; + TicketCreateDto dto = new() + { + Title = "Title new", + Content = "Ticket content new", + ReportDate = DateTime.Now, + }; NoxContext.UserId = Guid.Parse("a8bfc75b-2ac3-47e2-b013-8b8a1efba45d"); // Act - var result = await _mediator - .Send(new CreateEntityCommand(root, CommonDetailLevels.Simple, extensions)); + var result = await _mediator.Send(new CreateEntityCommand(dto, extensions)); // Assert Assert.True(Guid.TryParse(result.ToString(), out _)); @@ -184,22 +180,18 @@ public void UpdateEntityCommand_ShouldSuccess() { // Prepare Guid id = new(); - var updateBody = new + TicketUpdateDto dto = new() { Id = id, Title = "t1", Content = "c1" }; - string jsonString = JsonSerializer.Serialize(updateBody); - JsonDocument jsonDocument = JsonDocument.Parse(jsonString); - JsonElement root = jsonDocument.RootElement; - NoxContext.UserId = Guid.Parse("a8bfc75b-2ac3-47e2-b013-8b8a1efba45d"); // Act var result = _mediator - .Send(new UpdateEntityCommand(id, root, CommonDetailLevels.Simple)); + .Send(new UpdateEntityCommand(id, dto)); // Assert Assert.NotNull(result); @@ -213,22 +205,18 @@ public void UpdateEntityCommand_ShouldCallActions() NoxCommandExtensions extensions = new([new(NCEHelper.DummyMethod1, RunType.Before), new(NCEHelper.DummyMethod2, RunType.After, suspendOnFailure: false)]); Guid id = new(); - var updateBody = new + TicketUpdateDto dto = new() { Id = id, Title = "t1", Content = "c1" }; - string jsonString = JsonSerializer.Serialize(updateBody); - JsonDocument jsonDocument = JsonDocument.Parse(jsonString); - JsonElement root = jsonDocument.RootElement; - NoxContext.UserId = Guid.Parse("a8bfc75b-2ac3-47e2-b013-8b8a1efba45d"); // Act var result = _mediator - .Send(new UpdateEntityCommand(id, root, CommonDetailLevels.Simple, extensions)); + .Send(new UpdateEntityCommand(id, dto, extensions)); // Assert Assert.NotNull(result); diff --git a/src/Services/CouponService/Tests/UnitTests/AppyNox.Services.Coupon.Application.UnitTest/DtoTests/CouponDtoMappingRegistryUnitTest.cs b/src/Services/CouponService/Tests/UnitTests/AppyNox.Services.Coupon.Application.UnitTest/DtoTests/CouponDtoMappingRegistryUnitTest.cs deleted file mode 100644 index e84f238c..00000000 --- a/src/Services/CouponService/Tests/UnitTests/AppyNox.Services.Coupon.Application.UnitTest/DtoTests/CouponDtoMappingRegistryUnitTest.cs +++ /dev/null @@ -1,137 +0,0 @@ -using AppyNox.Services.Base.Core.Enums; -using AppyNox.Services.Base.Core.Extensions; -using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.DetailLevel; -using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.Base; -using AppyNox.Services.Coupon.Application.Dtos.CouponDtos.Models.Extended; -using AppyNox.Services.Coupon.Application.DtoUtilities; -using AppyNox.Services.Coupon.Application.UnitTest.DtoTests.Fixtures; -using AppyNox.Services.Coupon.Domain.Coupons; -using CouponAggreagate = AppyNox.Services.Coupon.Domain.Coupons.Coupon; - -namespace AppyNox.Services.Coupon.Application.UnitTest.DtoTests; - -[Collection("DtoMappingRegistry Collection")] -public class CouponDtoMappingRegistryUnitTest(DtoMappingRegistryFixture fixture) -{ - #region [ Fields ] - - private readonly DtoMappingRegistry _registry = fixture.Registry; - - #endregion - - #region [ Dto Level Mapping Types ] - - [Fact] - public void CouponDataAccessDtoLevelMappingTypesShouldBeAvailable() - { - // Act - var result = _registry.GetDetailLevelTypes(typeof(CouponAggreagate)).GetValueOrDefault(DtoLevelMappingTypes.DataAccess); - - // Assert - Assert.NotNull(result); - } - - [Fact] - public void CouponUpdateDtoLevelMappingTypesShouldBeAvailable() - { - // Act - var result = _registry.GetDetailLevelTypes(typeof(CouponAggreagate)).GetValueOrDefault(DtoLevelMappingTypes.Update); - - // Assert - Assert.NotNull(result); - } - - [Fact] - public void CouponCreateDtoLevelMappingTypesShouldBeAvailable() - { - // Act - var result = _registry.GetDetailLevelTypes(typeof(CouponAggreagate)).GetValueOrDefault(DtoLevelMappingTypes.Create); - - // Assert - Assert.NotNull(result); - } - - #endregion - - #region [ Get Dto Types ] - - #region [ DataAccess ] - - [Fact] - public void CouponDataAccessSimpleShouldReturnCouponSimpleDto() - { - // Act - var result = _registry.GetDtoType(DtoLevelMappingTypes.DataAccess, typeof(CouponAggreagate), CouponDataAccessDetailLevel.Simple.GetDisplayName()); - - // Assert - Assert.NotNull(result); - Assert.Equal(typeof(CouponSimpleDto), result); - } - - [Fact] - public void CouponDataAccessExtendedShouldReturnCouponWithAllRelationsDto() - { - // Act - var result = _registry.GetDtoType(DtoLevelMappingTypes.DataAccess, typeof(CouponAggreagate), CouponDataAccessDetailLevel.WithAllRelations.GetDisplayName()); - - // Assert - Assert.NotNull(result); - Assert.Equal(typeof(CouponWithAllRelationsDto), result); - } - - #endregion - - #region [ Create ] - - [Fact] - public void CouponCreateSimpleShouldReturnCouponSimpleCreateDto() - { - // Act - var result = _registry.GetDtoType(DtoLevelMappingTypes.Create, typeof(CouponAggreagate), CouponCreateDetailLevel.Simple.GetDisplayName()); - - // Assert - Assert.NotNull(result); - Assert.Equal(typeof(CouponSimpleCreateDto), result); - } - - [Fact] - public void CouponCreateExtendedShouldReturnCouponExtendedCreateDto() - { - // Act - var result = _registry.GetDtoType(DtoLevelMappingTypes.Create, typeof(CouponAggreagate), CouponCreateDetailLevel.Extended.GetDisplayName()); - - // Assert - Assert.NotNull(result); - Assert.Equal(typeof(CouponExtendedCreateDto), result); - } - - #endregion - - #region [ Update ] - - [Fact] - public void CouponUpdateSimpleShouldReturnCouponSimpleUpdateDto() - { - // Act - var result = _registry.GetDtoType(DtoLevelMappingTypes.Update, typeof(CouponAggreagate), CouponUpdateDetailLevel.Simple.GetDisplayName()); - - // Assert - Assert.NotNull(result); - Assert.Equal(typeof(CouponSimpleUpdateDto), result); - } - - [Fact] - public void CouponUpdateExtendedShouldReturnCouponExtendedUpdateDto() - { - // Act - var result = _registry.GetDtoType(DtoLevelMappingTypes.Update, typeof(CouponAggreagate), CouponUpdateDetailLevel.Extended.GetDisplayName()); - - // Assert - Assert.NotNull(result); - Assert.Equal(typeof(CouponExtendedUpdateDto), result); - } - - #endregion - - #endregion -} \ No newline at end of file diff --git a/src/Services/CouponService/Tests/UnitTests/AppyNox.Services.Coupon.Application.UnitTest/DtoTests/Fixtures/DtoMappingRegistryCollection.cs b/src/Services/CouponService/Tests/UnitTests/AppyNox.Services.Coupon.Application.UnitTest/DtoTests/Fixtures/DtoMappingRegistryCollection.cs deleted file mode 100644 index 529faba7..00000000 --- a/src/Services/CouponService/Tests/UnitTests/AppyNox.Services.Coupon.Application.UnitTest/DtoTests/Fixtures/DtoMappingRegistryCollection.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace AppyNox.Services.Coupon.Application.UnitTest.DtoTests.Fixtures -{ - [CollectionDefinition("DtoMappingRegistry Collection")] - public class DtoMappingRegistryCollection : ICollectionFixture - { - } -} \ No newline at end of file diff --git a/src/Services/CouponService/Tests/UnitTests/AppyNox.Services.Coupon.Application.UnitTest/DtoTests/Fixtures/DtoMappingRegistryFixture.cs b/src/Services/CouponService/Tests/UnitTests/AppyNox.Services.Coupon.Application.UnitTest/DtoTests/Fixtures/DtoMappingRegistryFixture.cs deleted file mode 100644 index 38c76d40..00000000 --- a/src/Services/CouponService/Tests/UnitTests/AppyNox.Services.Coupon.Application.UnitTest/DtoTests/Fixtures/DtoMappingRegistryFixture.cs +++ /dev/null @@ -1,31 +0,0 @@ -using AppyNox.Services.Coupon.Application.DtoUtilities; - -namespace AppyNox.Services.Coupon.Application.UnitTest.DtoTests.Fixtures -{ - public class DtoMappingRegistryFixture : IDisposable - { - #region [ Public Constructors ] - - public DtoMappingRegistryFixture() - { - Registry = new DtoMappingRegistry(); - } - - #endregion - - #region [ Properties ] - - public DtoMappingRegistry Registry { get; } - - #endregion - - #region [ Public Methods ] - - public void Dispose() - { - GC.SuppressFinalize(this); - } - - #endregion - } -} \ No newline at end of file diff --git a/src/Services/CouponService/Tests/UnitTests/AppyNox.Services.Coupon.Application.UnitTest/DtoTests/TicketDtoMappingRegistryUnitTest.cs b/src/Services/CouponService/Tests/UnitTests/AppyNox.Services.Coupon.Application.UnitTest/DtoTests/TicketDtoMappingRegistryUnitTest.cs deleted file mode 100644 index 2493733e..00000000 --- a/src/Services/CouponService/Tests/UnitTests/AppyNox.Services.Coupon.Application.UnitTest/DtoTests/TicketDtoMappingRegistryUnitTest.cs +++ /dev/null @@ -1,114 +0,0 @@ -using AppyNox.Services.Base.Application.Constants; -using AppyNox.Services.Base.Core.Enums; -using AppyNox.Services.Coupon.Application.Dtos.TicketDtos.DetailLevel; -using AppyNox.Services.Coupon.Application.Dtos.TicketDtos.Models.Basic; -using AppyNox.Services.Coupon.Application.Dtos.TicketDtos.Models.Extended; -using AppyNox.Services.Coupon.Application.DtoUtilities; -using AppyNox.Services.Coupon.Application.UnitTest.DtoTests.Fixtures; -using AppyNox.Services.Coupon.Domain.Entities; - -namespace AppyNox.Services.Coupon.Application.UnitTest.DtoTests; - -[Collection("DtoMappingRegistry Collection")] -public class TicketDtoMappingRegistryUnitTest(DtoMappingRegistryFixture fixture) -{ - #region [ Fields ] - - private readonly DtoMappingRegistry _registry = fixture.Registry; - - #endregion - - #region [ Dto Level Mapping Types ] - - [Fact] - public void TicketDataAccessDtoLevelMappingTypesShouldBeAvailable() - { - // Act - var result = _registry.GetDetailLevelTypes(typeof(Ticket)).GetValueOrDefault(DtoLevelMappingTypes.DataAccess); - - // Assert - Assert.NotNull(result); - } - - [Fact] - public void TicketUpdateDtoLevelMappingTypesShouldBeAvailable() - { - // Act - var result = _registry.GetDetailLevelTypes(typeof(Ticket)).GetValueOrDefault(DtoLevelMappingTypes.Update); - - // Assert - Assert.NotNull(result); - } - - [Fact] - public void TicketCreateDtoLevelMappingTypesShouldBeAvailable() - { - // Act - var result = _registry.GetDetailLevelTypes(typeof(Ticket)).GetValueOrDefault(DtoLevelMappingTypes.Create); - - // Assert - Assert.NotNull(result); - } - - #endregion - - #region [ Get Dto Types ] - - #region [ DataAccess ] - - [Fact] - public void TicketDataAccessSimpleShouldReturnTicketSimpleDto() - { - // Act - var result = _registry.GetDtoType(DtoLevelMappingTypes.DataAccess, typeof(Ticket), CommonDetailLevels.Simple); - - // Assert - Assert.NotNull(result); - Assert.Equal(typeof(TicketSimpleDto), result); - } - - [Fact] - public void TicketDataAccessExtendedShouldReturnTicketExtendedDto() - { - // Act - var result = _registry.GetDtoType(DtoLevelMappingTypes.DataAccess, typeof(Ticket), CommonDetailLevels.Extended); - - // Assert - Assert.NotNull(result); - Assert.Equal(typeof(TicketExtendedDto), result); - } - - #endregion - - #region [ Create ] - - [Fact] - public void TicketCreateSimpleShouldReturnCouponSimpleCreateDto() - { - // Act - var result = _registry.GetDtoType(DtoLevelMappingTypes.Create, typeof(Ticket), CommonDetailLevels.Simple); - - // Assert - Assert.NotNull(result); - Assert.Equal(typeof(TicketSimpleCreateDto), result); - } - - #endregion - - #region [ Update ] - - [Fact] - public void CouponUpdateSimpleShouldReturnCouponSimpleUpdateDto() - { - // Act - var result = _registry.GetDtoType(DtoLevelMappingTypes.Update, typeof(Ticket), CommonDetailLevels.Simple); - - // Assert - Assert.NotNull(result); - Assert.Equal(typeof(TicketSimpleUpdateDto), result); - } - - #endregion - - #endregion -} \ No newline at end of file diff --git a/src/Services/CouponService/Tests/UnitTests/AppyNox.Services.Coupon.Infrastructure.UnitTest/RepositoryTests/CouponRepositoryUnitTest.cs b/src/Services/CouponService/Tests/UnitTests/AppyNox.Services.Coupon.Infrastructure.UnitTest/RepositoryTests/CouponRepositoryUnitTest.cs index 36124aa6..032dbce8 100644 --- a/src/Services/CouponService/Tests/UnitTests/AppyNox.Services.Coupon.Infrastructure.UnitTest/RepositoryTests/CouponRepositoryUnitTest.cs +++ b/src/Services/CouponService/Tests/UnitTests/AppyNox.Services.Coupon.Infrastructure.UnitTest/RepositoryTests/CouponRepositoryUnitTest.cs @@ -68,8 +68,6 @@ public async Task GetAllAsync_ShouldReturnEntity() var repository = new CouponRepository(context, _couponRepositoryLogger, _noxRepositoryBaseLogger, _cacheService); QueryParameters queryParameters = new() { - Access = string.Empty, - DetailLevel = "Simple", PageNumber = 1, PageSize = 1, }; @@ -89,8 +87,6 @@ public async Task GetAllAsync_ShouldApplySorting() var repository = new CouponRepository(context, _couponRepositoryLogger, _noxRepositoryBaseLogger, _cacheService); QueryParameters queryParameters = new() { - Access = string.Empty, - DetailLevel = "WithAllRelations", PageNumber = 1, PageSize = 2, SortBy = "code asc, CouponDetail.Detail desc" @@ -115,8 +111,6 @@ public async Task GetAllAsync_ShouldRefuseWrongSortBy(string sortBy) var repository = new CouponRepository(context, _couponRepositoryLogger, _noxRepositoryBaseLogger, _cacheService); QueryParameters queryParameters = new() { - Access = string.Empty, - DetailLevel = "WithAllRelations", PageNumber = 1, PageSize = 2, SortBy = sortBy @@ -138,8 +132,6 @@ public async Task GetAllAsync_ShouldSortCorrectly(string sortBy, bool ascending) var repository = new CouponRepository(context, _couponRepositoryLogger, _noxRepositoryBaseLogger, _cacheService); QueryParameters queryParameters = new() { - Access = string.Empty, - DetailLevel = "WithAllRelations", PageNumber = 1, PageSize = 2, SortBy = sortBy @@ -171,8 +163,6 @@ public async Task GetAllAsync_ShouldRefuseMaliciousSort(string sort) var repository = new CouponRepository(context, _couponRepositoryLogger, _noxRepositoryBaseLogger, _cacheService); QueryParameters queryParameters = new() { - Access = string.Empty, - DetailLevel = "WithAllRelations", PageNumber = 1, PageSize = 2, SortBy = sort @@ -201,8 +191,6 @@ public async Task GetAllAsync_ShouldApplyFiltering(string filter, int size) var repository = new CouponRepository(context, _couponRepositoryLogger, _noxRepositoryBaseLogger, _cacheService); QueryParameters queryParameters = new() { - Access = string.Empty, - DetailLevel = "WithAllRelations", PageNumber = 1, PageSize = 3, Filter = filter @@ -225,8 +213,6 @@ public async Task GetAllAsync_ShouldRefuseWrongFilter(string filter) var repository = new CouponRepository(context, _couponRepositoryLogger, _noxRepositoryBaseLogger, _cacheService); QueryParameters queryParameters = new() { - Access = string.Empty, - DetailLevel = "WithAllRelations", PageNumber = 1, PageSize = 2, Filter = filter @@ -250,8 +236,6 @@ public async Task GetAllAsync_ShouldRefuseMaliciousFilter(string filter) var repository = new CouponRepository(context, _couponRepositoryLogger, _noxRepositoryBaseLogger, _cacheService); QueryParameters queryParameters = new() { - Access = string.Empty, - DetailLevel = "WithAllRelations", PageNumber = 1, PageSize = 2, Filter = filter @@ -273,8 +257,6 @@ public async Task GetAllAsync_ShouldPaginationReturnTwo() var repository = new CouponRepository(context, _couponRepositoryLogger, _noxRepositoryBaseLogger, _cacheService); QueryParameters queryParameters = new() { - Access = string.Empty, - DetailLevel = "Simple", PageNumber = 1, PageSize = 2, }; @@ -296,8 +278,6 @@ public async Task GetAllAsync_ShouldPaginationReturnCorrectEntity() var repository = new CouponRepository(context, _couponRepositoryLogger, _noxRepositoryBaseLogger, _cacheService); QueryParameters queryParameters = new() { - Access = string.Empty, - DetailLevel = "Simple", PageNumber = 2, PageSize = 1, }; @@ -320,8 +300,6 @@ public async Task GetAllAsync_ShouldPaginationReturnFifty() var repository = new CouponRepository(context, _couponRepositoryLogger, _noxRepositoryBaseLogger, _cacheService); QueryParameters queryParameters = new() { - Access = string.Empty, - DetailLevel = "Simple", PageNumber = 1, PageSize = 50, }; @@ -343,8 +321,6 @@ public async Task GetAllAsync_ShouldPaginationReturnFiftyAndCorrectEntities() var repository = new CouponRepository(context, _couponRepositoryLogger, _noxRepositoryBaseLogger, _cacheService); QueryParameters queryParameters = new() { - Access = string.Empty, - DetailLevel = "Simple", PageNumber = 5, PageSize = 5, }; diff --git a/src/Services/CouponService/Tests/UnitTests/AppyNox.Services.Coupon.Infrastructure.UnitTest/RepositoryTests/GenericTicketRepositoryTest.cs b/src/Services/CouponService/Tests/UnitTests/AppyNox.Services.Coupon.Infrastructure.UnitTest/RepositoryTests/GenericTicketRepositoryTest.cs index 717096a5..afd53a2d 100644 --- a/src/Services/CouponService/Tests/UnitTests/AppyNox.Services.Coupon.Infrastructure.UnitTest/RepositoryTests/GenericTicketRepositoryTest.cs +++ b/src/Services/CouponService/Tests/UnitTests/AppyNox.Services.Coupon.Infrastructure.UnitTest/RepositoryTests/GenericTicketRepositoryTest.cs @@ -5,7 +5,7 @@ using AppyNox.Services.Base.Infrastructure.Repositories.Common; using AppyNox.Services.Base.Infrastructure.UnitTests.Fixtures; using AppyNox.Services.Base.Infrastructure.UnitTests.Stubs; -using AppyNox.Services.Coupon.Application.Dtos.TicketDtos.Models.Basic; +using AppyNox.Services.Coupon.Application.Dtos.TicketDtos.Models; using AppyNox.Services.Coupon.Domain.Entities; using AppyNox.Services.Coupon.Domain.Localization; using AppyNox.Services.Coupon.Infrastructure.Data; @@ -60,8 +60,6 @@ public async Task GetAllAsync_ShouldReturnEntity() var repository = new GenericRepository(context, _genericRepositoryLogger); QueryParameters queryParameters = new() { - Access = string.Empty, - DetailLevel = CommonDetailLevels.Simple, PageNumber = 1, PageSize = 1, }; @@ -81,8 +79,6 @@ public async Task GetAllAsync_ShouldPaginationReturnTwo() var repository = new GenericRepository(context, _genericRepositoryLogger); QueryParameters queryParameters = new() { - Access = string.Empty, - DetailLevel = "Simple", PageNumber = 1, PageSize = 2, }; @@ -104,8 +100,6 @@ public async Task GetAllAsync_ShouldPaginationReturnCorrectEntity() var repository = new GenericRepository(context, _genericRepositoryLogger); QueryParameters queryParameters = new() { - Access = string.Empty, - DetailLevel = "Simple", PageNumber = 2, PageSize = 1, }; @@ -129,8 +123,6 @@ public async Task GetAllAsync_ShouldPaginationReturnFifty() var repository = new GenericRepository(context, _genericRepositoryLogger); QueryParameters queryParameters = new() { - Access = string.Empty, - DetailLevel = "Simple", PageNumber = 1, PageSize = 50, }; @@ -152,8 +144,6 @@ public async Task GetAllAsync_ShouldPaginationReturnFiftyAndCorrectEntities() var repository = new GenericRepository(context, _genericRepositoryLogger); QueryParameters queryParameters = new() { - Access = string.Empty, - DetailLevel = "Simple", PageNumber = 5, PageSize = 5, }; @@ -270,7 +260,7 @@ public async Task UpdateAsync_ShouldUpdateTicket() DateTime reportDate = existingTicket.ReportDate; // Create the update dto - TicketSimpleUpdateDto ticketSimpleUpdateDto = new() { Id = id, Content = content, Title = title}; + TicketUpdateDto ticketSimpleUpdateDto = new() { Id = id, Content = content, Title = title}; repository.Update(existingTicket, ticketSimpleUpdateDto); await unitOfWork.SaveChangesAsync(); diff --git a/src/Services/LicenseService/AppyNox.Services.License.Application/DependencyInjection.cs b/src/Services/LicenseService/AppyNox.Services.License.Application/DependencyInjection.cs index 416fb248..b2dc7d9f 100644 --- a/src/Services/LicenseService/AppyNox.Services.License.Application/DependencyInjection.cs +++ b/src/Services/LicenseService/AppyNox.Services.License.Application/DependencyInjection.cs @@ -1,10 +1,9 @@ using AppyNox.Services.Base.Application; -using AppyNox.Services.Base.Application.DtoUtilities; using AppyNox.Services.Base.Application.Extensions; using AppyNox.Services.Base.Application.Interfaces.Loggers; -using AppyNox.Services.License.Application.Dtos.DtoUtilities; +using AppyNox.Services.License.Application.Dtos.LicenseDtos.Models; +using AppyNox.Services.License.Application.Dtos.ProductDtos.Models; using AppyNox.Services.License.Domain.Entities; -using FluentValidation; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using System.Reflection; @@ -24,12 +23,11 @@ public static IServiceCollection AddLicenseApplication(this IServiceCollection s options.UseAutoMapper = true; options.UseFluentValidation = true; options.UseDtoMappingRegistry = true; - options.DtoMappingRegistryFactory = provider => new DtoMappingRegistry(); options.UseMediatR = true; }); - services.AddNoxEntityCommands(); - services.AddNoxEntityCommands(); + services.AddNoxEntityCommands(); + services.AddNoxEntityCommands(); return services; } diff --git a/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/DtoUtilities/DtoMappingRegistry.cs b/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/DtoUtilities/DtoMappingRegistry.cs deleted file mode 100644 index b9c6a5f7..00000000 --- a/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/DtoUtilities/DtoMappingRegistry.cs +++ /dev/null @@ -1,90 +0,0 @@ -using AppyNox.Services.Base.Application.DtoUtilities; -using AppyNox.Services.Base.Application.Interfaces.Exceptions; -using AppyNox.Services.Base.Core.Enums; -using AppyNox.Services.License.Application.Dtos.LicenseDtos.DetailLevel; -using AppyNox.Services.License.Application.Dtos.LicenseDtos.Models.Base; -using AppyNox.Services.License.Application.Dtos.ProductDtos.DetailLevel; -using AppyNox.Services.License.Application.Exceptions; -using AppyNox.Services.License.Domain.Entities; -using System.Data; -using System.Net; -using System.Reflection; - -namespace AppyNox.Services.License.Application.Dtos.DtoUtilities; - -public class DtoMappingRegistry : DtoMappingRegistryBase -{ - #region [ Public Methods ] - - public DtoMappingRegistry() - : base() - { - RegisterDtos(); - } - - public static Enum GetDetailLevel(Attribute attribute, DtoLevelMappingTypes mappingType) - { - if (attribute is LicenseDetailLevelAttribute licenseDetailAttribute) - { - return mappingType switch - { - DtoLevelMappingTypes.DataAccess => licenseDetailAttribute.DataAccessDetailLevel, - DtoLevelMappingTypes.Create => licenseDetailAttribute.CreateDetailLevel, - DtoLevelMappingTypes.Update => licenseDetailAttribute.UpdateDetailLevel, - _ => licenseDetailAttribute.DataAccessDetailLevel - }; - } - else if (attribute is ProductDetailLevelAttribute productDetailAttribute) - { - return mappingType switch - { - DtoLevelMappingTypes.DataAccess => productDetailAttribute.DataAccessDetailLevel, - DtoLevelMappingTypes.Create => productDetailAttribute.CreateDetailLevel, - DtoLevelMappingTypes.Update => productDetailAttribute.UpdateDetailLevel, - _ => productDetailAttribute.DataAccessDetailLevel - }; - } - - throw new NoxLicenseApplicationException( - "Unsupported attribute type for detail level mapping. Check DtoMappingRegistry", - (int)NoxLicenseApplicationExceptionCode.DtoMappingRegistryError); - } - - #endregion - - #region [ Protected Methods ] - - protected override void RegisterDtos() - { - var dtoTypes = Assembly.GetAssembly(typeof(LicenseSimpleDto))? - .GetTypes() - .Where(t => t.Namespace != null && t.Namespace.Contains("Application.Dtos") && t.Namespace.Contains("Models")) - .ToList(); - - if (dtoTypes == null) - return; - - foreach (var dtoType in dtoTypes) - { - var attributes = Attribute.GetCustomAttributes(dtoType); - foreach (var attribute in attributes) - { - if (attribute is LicenseDetailLevelAttribute licenseAttribute) - { - RegisterMapping(typeof(LicenseEntity), dtoType, licenseAttribute); - } - else if (attribute is ProductDetailLevelAttribute productAttribute) - { - RegisterMapping(typeof(ProductEntity), dtoType, productAttribute); - } - } - } - } - - protected override Enum GetDetailLevelBase(Attribute attribute, DtoLevelMappingTypes mappingType) - { - return GetDetailLevel(attribute, mappingType); - } - - #endregion -} \ No newline at end of file diff --git a/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/LicenseDtos/DetailLevel/LicenseDetailLevelAttribute.cs b/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/LicenseDtos/DetailLevel/LicenseDetailLevelAttribute.cs deleted file mode 100644 index 3f2f0ffb..00000000 --- a/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/LicenseDtos/DetailLevel/LicenseDetailLevelAttribute.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace AppyNox.Services.License.Application.Dtos.LicenseDtos.DetailLevel -{ - #region [ Enums ] - - public enum LicenseDataAccessDetailLevel - { - [Display(Name = "Simple")] - Simple - } - - public enum LicenseCreateDetailLevel - { - [Display(Name = "Simple")] - Simple - } - - public enum LicenseUpdateDetailLevel - { - [Display(Name = "Simple")] - Simple - } - - #endregion - - [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)] - public class LicenseDetailLevelAttribute : Attribute - { - #region [ Public Constructors ] - - public LicenseDetailLevelAttribute(LicenseDataAccessDetailLevel dataAccessDetailLevel) - { - DataAccessDetailLevel = dataAccessDetailLevel; - } - - public LicenseDetailLevelAttribute(LicenseCreateDetailLevel createDetailLevel) - { - CreateDetailLevel = createDetailLevel; - } - - public LicenseDetailLevelAttribute(LicenseUpdateDetailLevel updateDetailLevel) - { - UpdateDetailLevel = updateDetailLevel; - } - - #endregion - - #region [ Properties ] - - public LicenseDataAccessDetailLevel DataAccessDetailLevel { get; } - - public LicenseCreateDetailLevel CreateDetailLevel { get; } - - public LicenseUpdateDetailLevel UpdateDetailLevel { get; } - - #endregion - } -} \ No newline at end of file diff --git a/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/LicenseDtos/Models/Base/LicenseSimpleUpdateDto.cs b/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/LicenseDtos/Models/Base/LicenseSimpleUpdateDto.cs deleted file mode 100644 index 2ae4f270..00000000 --- a/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/LicenseDtos/Models/Base/LicenseSimpleUpdateDto.cs +++ /dev/null @@ -1,15 +0,0 @@ -using AppyNox.Services.Base.Application.Dtos; -using AppyNox.Services.License.Application.Dtos.LicenseDtos.DetailLevel; - -namespace AppyNox.Services.License.Application.Dtos.LicenseDtos.Models.Base -{ - [LicenseDetailLevel(LicenseUpdateDetailLevel.Simple)] - public class LicenseSimpleUpdateDto : LicenseSimpleCreateDto - { - #region [ Properties ] - - public LicenseIdDto Id { get; set; } = default!; - - #endregion - } -} \ No newline at end of file diff --git a/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/LicenseDtos/Models/Base/LicenseSimpleCreateDto.cs b/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/LicenseDtos/Models/LicenseCreateDto.cs similarity index 78% rename from src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/LicenseDtos/Models/Base/LicenseSimpleCreateDto.cs rename to src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/LicenseDtos/Models/LicenseCreateDto.cs index 1e0cfbb2..6ac7881e 100644 --- a/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/LicenseDtos/Models/Base/LicenseSimpleCreateDto.cs +++ b/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/LicenseDtos/Models/LicenseCreateDto.cs @@ -1,11 +1,9 @@ using AppyNox.Services.Base.Domain.Interfaces; -using AppyNox.Services.License.Application.Dtos.LicenseDtos.DetailLevel; using AppyNox.Services.License.Application.Dtos.ProductDtos.Models.Base; -namespace AppyNox.Services.License.Application.Dtos.LicenseDtos.Models.Base; +namespace AppyNox.Services.License.Application.Dtos.LicenseDtos.Models; -[LicenseDetailLevel(LicenseCreateDetailLevel.Simple)] -public class LicenseSimpleCreateDto : IHasCode +public class LicenseCreateDto : IHasCode { #region [ Properties ] diff --git a/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/LicenseDtos/Models/Base/LicenseSimpleDto.cs b/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/LicenseDtos/Models/LicenseDto.cs similarity index 54% rename from src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/LicenseDtos/Models/Base/LicenseSimpleDto.cs rename to src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/LicenseDtos/Models/LicenseDto.cs index e06b0c4e..99780782 100644 --- a/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/LicenseDtos/Models/Base/LicenseSimpleDto.cs +++ b/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/LicenseDtos/Models/LicenseDto.cs @@ -1,10 +1,8 @@ using AppyNox.Services.Base.Application.Dtos; -using AppyNox.Services.License.Application.Dtos.LicenseDtos.DetailLevel; -namespace AppyNox.Services.License.Application.Dtos.LicenseDtos.Models.Base +namespace AppyNox.Services.License.Application.Dtos.LicenseDtos.Models { - [LicenseDetailLevel(LicenseDataAccessDetailLevel.Simple)] - public class LicenseSimpleDto : LicenseSimpleCreateDto, IAuditDto + public class LicenseDto : LicenseCreateDto, IAuditDto { #region [ IAuditDto ] diff --git a/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/LicenseDtos/Models/LicenseUpdateDto.cs b/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/LicenseDtos/Models/LicenseUpdateDto.cs new file mode 100644 index 00000000..d9001b5e --- /dev/null +++ b/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/LicenseDtos/Models/LicenseUpdateDto.cs @@ -0,0 +1,13 @@ +using AppyNox.Services.License.Application.Dtos.LicenseDtos.Models.ValueObjects; + +namespace AppyNox.Services.License.Application.Dtos.LicenseDtos.Models +{ + public class LicenseUpdateDto : LicenseCreateDto + { + #region [ Properties ] + + public LicenseIdDto Id { get; set; } = default!; + + #endregion + } +} \ No newline at end of file diff --git a/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/LicenseDtos/Models/Base/LicenseIdDto.cs b/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/LicenseDtos/Models/ValueObjects/LicenseIdDto.cs similarity index 87% rename from src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/LicenseDtos/Models/Base/LicenseIdDto.cs rename to src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/LicenseDtos/Models/ValueObjects/LicenseIdDto.cs index 6d520221..e21fb896 100644 --- a/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/LicenseDtos/Models/Base/LicenseIdDto.cs +++ b/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/LicenseDtos/Models/ValueObjects/LicenseIdDto.cs @@ -1,4 +1,4 @@ -namespace AppyNox.Services.License.Application.Dtos.LicenseDtos.Models.Base; +namespace AppyNox.Services.License.Application.Dtos.LicenseDtos.Models.ValueObjects; public class LicenseIdDto { diff --git a/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/LicenseDtos/Mappings/LicenseMapping.cs b/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/LicenseDtos/Profiles/LicenseProfile.cs similarity index 50% rename from src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/LicenseDtos/Mappings/LicenseMapping.cs rename to src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/LicenseDtos/Profiles/LicenseProfile.cs index 4c9eb378..b23bd917 100644 --- a/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/LicenseDtos/Mappings/LicenseMapping.cs +++ b/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/LicenseDtos/Profiles/LicenseProfile.cs @@ -1,20 +1,21 @@ -using AppyNox.Services.License.Application.Dtos.LicenseDtos.Models.Base; +using AppyNox.Services.License.Application.Dtos.LicenseDtos.Models; +using AppyNox.Services.License.Application.Dtos.LicenseDtos.Models.ValueObjects; using AppyNox.Services.License.Domain.Entities; using AutoMapper; namespace AppyNox.Services.License.Application.Dtos.LicenseDtos.Mappings { - public class LicenseMapping : Profile + public class LicenseProfile : Profile { #region [ Public Constructors ] - public LicenseMapping() + public LicenseProfile() { - CreateMap().ReverseMap(); + CreateMap().ReverseMap(); - CreateMap().ReverseMap(); + CreateMap().ReverseMap(); - CreateMap(); + CreateMap(); CreateMap().ReverseMap(); } diff --git a/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/ProductDtos/DetailLevel/ProductDetailLevelAttribute.cs b/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/ProductDtos/DetailLevel/ProductDetailLevelAttribute.cs deleted file mode 100644 index 8f6b3d48..00000000 --- a/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/ProductDtos/DetailLevel/ProductDetailLevelAttribute.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace AppyNox.Services.License.Application.Dtos.ProductDtos.DetailLevel -{ - #region [ Enums ] - - public enum ProductDataAccessDetailLevel - { - [Display(Name = "Simple")] - Simple - } - - public enum ProductCreateDetailLevel - { - [Display(Name = "Simple")] - Simple - } - - public enum ProductUpdateDetailLevel - { - [Display(Name = "Simple")] - Simple - } - - #endregion - - [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)] - public class ProductDetailLevelAttribute : Attribute - { - #region [ Public Constructors ] - - public ProductDetailLevelAttribute(ProductDataAccessDetailLevel dataAccessDetailLevel) - { - DataAccessDetailLevel = dataAccessDetailLevel; - } - - public ProductDetailLevelAttribute(ProductCreateDetailLevel createDetailLevel) - { - CreateDetailLevel = createDetailLevel; - } - - public ProductDetailLevelAttribute(ProductUpdateDetailLevel updateDetailLevel) - { - UpdateDetailLevel = updateDetailLevel; - } - - #endregion - - #region [ Properties ] - - public ProductDataAccessDetailLevel DataAccessDetailLevel { get; } - - public ProductCreateDetailLevel CreateDetailLevel { get; } - - public ProductUpdateDetailLevel UpdateDetailLevel { get; } - - #endregion - } -} \ No newline at end of file diff --git a/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/ProductDtos/Models/Base/ProductSimpleDto.cs b/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/ProductDtos/Models/Base/ProductSimpleDto.cs deleted file mode 100644 index 8656f4bf..00000000 --- a/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/ProductDtos/Models/Base/ProductSimpleDto.cs +++ /dev/null @@ -1,14 +0,0 @@ -using AppyNox.Services.License.Application.Dtos.ProductDtos.DetailLevel; - -namespace AppyNox.Services.License.Application.Dtos.ProductDtos.Models.Base -{ - [ProductDetailLevel(ProductDataAccessDetailLevel.Simple)] - public class ProductSimpleDto : ProductSimpleCreateDto - { - #region [ Properties ] - - public ProductIdDto Id { get; set; } = default!; - - #endregion - } -} \ No newline at end of file diff --git a/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/ProductDtos/Models/Base/ProductSimpleUpdateDto.cs b/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/ProductDtos/Models/Base/ProductSimpleUpdateDto.cs deleted file mode 100644 index 27c57625..00000000 --- a/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/ProductDtos/Models/Base/ProductSimpleUpdateDto.cs +++ /dev/null @@ -1,15 +0,0 @@ -using AppyNox.Services.Base.Application.Dtos; -using AppyNox.Services.License.Application.Dtos.ProductDtos.DetailLevel; - -namespace AppyNox.Services.License.Application.Dtos.ProductDtos.Models.Base -{ - [ProductDetailLevel(ProductUpdateDetailLevel.Simple)] - public class ProductSimpleUpdateDto : ProductSimpleCreateDto - { - #region [ Properties ] - - public ProductIdDto Id { get; set; } = default!; - - #endregion - } -} \ No newline at end of file diff --git a/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/ProductDtos/Models/Base/ProductSimpleCreateDto.cs b/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/ProductDtos/Models/ProductCreateDto.cs similarity index 61% rename from src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/ProductDtos/Models/Base/ProductSimpleCreateDto.cs rename to src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/ProductDtos/Models/ProductCreateDto.cs index f257a7cf..e11b6086 100644 --- a/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/ProductDtos/Models/Base/ProductSimpleCreateDto.cs +++ b/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/ProductDtos/Models/ProductCreateDto.cs @@ -1,10 +1,8 @@ using AppyNox.Services.Base.Domain.Interfaces; -using AppyNox.Services.License.Application.Dtos.ProductDtos.DetailLevel; -namespace AppyNox.Services.License.Application.Dtos.ProductDtos.Models.Base; +namespace AppyNox.Services.License.Application.Dtos.ProductDtos.Models; -[ProductDetailLevel(ProductCreateDetailLevel.Simple)] -public class ProductSimpleCreateDto : IHasCode +public class ProductCreateDto : IHasCode { #region [ Properties ] diff --git a/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/ProductDtos/Models/ProductDto.cs b/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/ProductDtos/Models/ProductDto.cs new file mode 100644 index 00000000..cb923815 --- /dev/null +++ b/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/ProductDtos/Models/ProductDto.cs @@ -0,0 +1,13 @@ +using AppyNox.Services.License.Application.Dtos.ProductDtos.Models.Base; + +namespace AppyNox.Services.License.Application.Dtos.ProductDtos.Models +{ + public class ProductDto : ProductCreateDto + { + #region [ Properties ] + + public ProductIdDto Id { get; set; } = default!; + + #endregion + } +} \ No newline at end of file diff --git a/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/ProductDtos/Models/ProductUpdateDto.cs b/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/ProductDtos/Models/ProductUpdateDto.cs new file mode 100644 index 00000000..b8fdeb47 --- /dev/null +++ b/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/ProductDtos/Models/ProductUpdateDto.cs @@ -0,0 +1,13 @@ +using AppyNox.Services.License.Application.Dtos.ProductDtos.Models.Base; + +namespace AppyNox.Services.License.Application.Dtos.ProductDtos.Models +{ + public class ProductUpdateDto : ProductCreateDto + { + #region [ Properties ] + + public ProductIdDto Id { get; set; } = default!; + + #endregion + } +} \ No newline at end of file diff --git a/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/ProductDtos/Models/Base/ProductIdDto.cs b/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/ProductDtos/Models/ValueObjects/ProductIdDto.cs similarity index 100% rename from src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/ProductDtos/Models/Base/ProductIdDto.cs rename to src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/ProductDtos/Models/ValueObjects/ProductIdDto.cs diff --git a/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/ProductDtos/Mappings/ProductMappings.cs b/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/ProductDtos/Profiles/ProductProfile.cs similarity index 51% rename from src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/ProductDtos/Mappings/ProductMappings.cs rename to src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/ProductDtos/Profiles/ProductProfile.cs index 6c3dedf2..a6e1b341 100644 --- a/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/ProductDtos/Mappings/ProductMappings.cs +++ b/src/Services/LicenseService/AppyNox.Services.License.Application/Dtos/ProductDtos/Profiles/ProductProfile.cs @@ -1,20 +1,21 @@ -using AppyNox.Services.License.Application.Dtos.ProductDtos.Models.Base; +using AppyNox.Services.License.Application.Dtos.ProductDtos.Models; +using AppyNox.Services.License.Application.Dtos.ProductDtos.Models.Base; using AppyNox.Services.License.Domain.Entities; using AutoMapper; namespace AppyNox.Services.License.Application.Dtos.ProductDtos.Mappings { - public class ProductMappings : Profile + public class ProductProfile : Profile { #region [ Public Constructors ] - public ProductMappings() + public ProductProfile() { - CreateMap().ReverseMap(); + CreateMap().ReverseMap(); - CreateMap().ReverseMap(); + CreateMap().ReverseMap(); - CreateMap(); + CreateMap(); CreateMap().ReverseMap(); } diff --git a/src/Services/LicenseService/AppyNox.Services.License.Application/Validators/License/Create/LicenseSimpleCreateValidator.cs b/src/Services/LicenseService/AppyNox.Services.License.Application/Validators/License/Create/LicenseSimpleCreateValidator.cs index dcede365..d2440c91 100644 --- a/src/Services/LicenseService/AppyNox.Services.License.Application/Validators/License/Create/LicenseSimpleCreateValidator.cs +++ b/src/Services/LicenseService/AppyNox.Services.License.Application/Validators/License/Create/LicenseSimpleCreateValidator.cs @@ -1,10 +1,10 @@ using AppyNox.Services.Base.Application.Validators; -using AppyNox.Services.License.Application.Dtos.LicenseDtos.Models.Base; +using AppyNox.Services.License.Application.Dtos.LicenseDtos.Models; using FluentValidation; namespace AppyNox.Services.License.Application.Validators.License.Create { - public class LicenseSimpleCreateValidator : DtoValidatorBase + public class LicenseSimpleCreateValidator : DtoValidatorBase { #region [ Public Constructors ] diff --git a/src/Services/LicenseService/AppyNox.Services.License.Application/Validators/License/Update/LicenseSimpleUpdateValidator.cs b/src/Services/LicenseService/AppyNox.Services.License.Application/Validators/License/Update/LicenseSimpleUpdateValidator.cs index 63e36ede..4f681c11 100644 --- a/src/Services/LicenseService/AppyNox.Services.License.Application/Validators/License/Update/LicenseSimpleUpdateValidator.cs +++ b/src/Services/LicenseService/AppyNox.Services.License.Application/Validators/License/Update/LicenseSimpleUpdateValidator.cs @@ -1,10 +1,10 @@ using AppyNox.Services.Base.Application.Validators; -using AppyNox.Services.License.Application.Dtos.LicenseDtos.Models.Base; +using AppyNox.Services.License.Application.Dtos.LicenseDtos.Models; using AppyNox.Services.License.Application.Validators.License.Create; namespace AppyNox.Services.License.Application.Validators.License.Update { - public class LicenseSimpleUpdateValidator : DtoValidatorBase + public class LicenseSimpleUpdateValidator : DtoValidatorBase { #region [ Public Constructors ] diff --git a/src/Services/LicenseService/AppyNox.Services.License.Application/Validators/Product/Create/ProductSimpleCreateValidator.cs b/src/Services/LicenseService/AppyNox.Services.License.Application/Validators/Product/Create/ProductSimpleCreateValidator.cs index 2cc58eba..41930f58 100644 --- a/src/Services/LicenseService/AppyNox.Services.License.Application/Validators/Product/Create/ProductSimpleCreateValidator.cs +++ b/src/Services/LicenseService/AppyNox.Services.License.Application/Validators/Product/Create/ProductSimpleCreateValidator.cs @@ -1,10 +1,10 @@ using AppyNox.Services.Base.Application.Validators; -using AppyNox.Services.License.Application.Dtos.ProductDtos.Models.Base; +using AppyNox.Services.License.Application.Dtos.ProductDtos.Models; using FluentValidation; namespace AppyNox.Services.License.Application.Validators.Product.Create { - public class ProductSimpleCreateValidator : DtoValidatorBase + public class ProductSimpleCreateValidator : DtoValidatorBase { #region [ Public Constructors ] diff --git a/src/Services/LicenseService/AppyNox.Services.License.Application/Validators/Product/Update/ProductUpdateCreateValidator.cs b/src/Services/LicenseService/AppyNox.Services.License.Application/Validators/Product/Update/ProductUpdateCreateValidator.cs index 194f21ac..abc97cbf 100644 --- a/src/Services/LicenseService/AppyNox.Services.License.Application/Validators/Product/Update/ProductUpdateCreateValidator.cs +++ b/src/Services/LicenseService/AppyNox.Services.License.Application/Validators/Product/Update/ProductUpdateCreateValidator.cs @@ -1,11 +1,11 @@ using AppyNox.Services.Base.Application.Validators; -using AppyNox.Services.License.Application.Dtos.ProductDtos.Models.Base; +using AppyNox.Services.License.Application.Dtos.ProductDtos.Models; using AppyNox.Services.License.Application.Validators.Product.Create; using FluentValidation; namespace AppyNox.Services.License.Application.Validators.Product.Update { - public class ProductUpdateCreateValidator : DtoValidatorBase + public class ProductUpdateCreateValidator : DtoValidatorBase { #region [ Public Constructors ] diff --git a/src/Services/LicenseService/AppyNox.Services.License.WebAPI/Controllers/v1_0/LicensesController.cs b/src/Services/LicenseService/AppyNox.Services.License.WebAPI/Controllers/v1_0/LicensesController.cs index d44f4a97..e067c425 100644 --- a/src/Services/LicenseService/AppyNox.Services.License.WebAPI/Controllers/v1_0/LicensesController.cs +++ b/src/Services/LicenseService/AppyNox.Services.License.WebAPI/Controllers/v1_0/LicensesController.cs @@ -1,8 +1,7 @@ using AppyNox.Services.Base.API.Constants; -using AppyNox.Services.Base.API.Helpers; -using AppyNox.Services.Base.API.ViewModels; using AppyNox.Services.Base.Application.MediatR.Commands; using AppyNox.Services.Base.Infrastructure.Repositories.Common; +using AppyNox.Services.License.Application.Dtos.LicenseDtos.Models; using AppyNox.Services.License.Application.MediatR.Commands; using AppyNox.Services.License.Application.Permission; using AppyNox.Services.License.Domain.Entities; @@ -28,23 +27,23 @@ public class LicensesController(IMediator mediator) : Controller [HttpGet] [Authorize(Permissions.Licenses.View)] - public async Task GetAll([FromQuery] QueryParametersViewModel queryParameters) + public async Task GetAll([FromQuery] QueryParameters queryParameters) { - return Ok(await _mediator.Send(new GetAllNoxEntitiesQuery(queryParameters))); + return Ok(await _mediator.Send(new GetAllNoxEntitiesQuery(queryParameters))); } [HttpGet("{id}")] [Authorize(Permissions.Licenses.View)] - public async Task GetById(Guid id, [FromQuery] QueryParametersViewModel queryParameters) + public async Task GetById(Guid id, [FromQuery] QueryParameters queryParameters) { - return Ok(await _mediator.Send(new GetNoxEntityByIdQuery(new LicenseId(id), queryParameters))); + return Ok(await _mediator.Send(new GetNoxEntityByIdQuery(new LicenseId(id), queryParameters))); } [HttpPost] [Authorize(Permissions.Licenses.Create)] - public async Task Create([FromBody] dynamic licenseDto, string detailLevel = "Simple") + public async Task Create([FromBody] LicenseCreateDto licenseDto) { - Guid result = await _mediator.Send(new CreateNoxEntityCommand(licenseDto, detailLevel)); + Guid result = await _mediator.Send(new CreateNoxEntityCommand(licenseDto)); return CreatedAtAction(nameof(GetById), new { id = result }, result); } diff --git a/src/Services/LicenseService/AppyNox.Services.License.WebAPI/Controllers/v1_0/ProductsController.cs b/src/Services/LicenseService/AppyNox.Services.License.WebAPI/Controllers/v1_0/ProductsController.cs index 25c1c6ff..d2745c93 100644 --- a/src/Services/LicenseService/AppyNox.Services.License.WebAPI/Controllers/v1_0/ProductsController.cs +++ b/src/Services/LicenseService/AppyNox.Services.License.WebAPI/Controllers/v1_0/ProductsController.cs @@ -1,8 +1,7 @@ using AppyNox.Services.Base.API.Constants; -using AppyNox.Services.Base.API.Helpers; -using AppyNox.Services.Base.API.ViewModels; using AppyNox.Services.Base.Application.MediatR.Commands; using AppyNox.Services.Base.Infrastructure.Repositories.Common; +using AppyNox.Services.License.Application.Dtos.ProductDtos.Models; using AppyNox.Services.License.Application.Permission; using AppyNox.Services.License.Domain.Entities; using Asp.Versioning; @@ -27,23 +26,23 @@ public class ProductsController(IMediator mediator) : Controller [HttpGet] [Authorize(Permissions.Products.View)] - public async Task GetAll([FromQuery] QueryParametersViewModel queryParameters) + public async Task GetAll([FromQuery] QueryParameters queryParameters) { - return Ok(await _mediator.Send(new GetAllNoxEntitiesQuery(queryParameters))); + return Ok(await _mediator.Send(new GetAllNoxEntitiesQuery(queryParameters))); } [HttpGet("{id}")] [Authorize(Permissions.Products.View)] - public async Task GetById(Guid id, [FromQuery] QueryParametersViewModel queryParameters) + public async Task GetById(Guid id, [FromQuery] QueryParameters queryParameters) { - return Ok(await _mediator.Send(new GetNoxEntityByIdQuery(new ProductId(id), queryParameters))); + return Ok(await _mediator.Send(new GetNoxEntityByIdQuery(new ProductId(id), queryParameters))); } [HttpPost] [Authorize(Permissions.Products.Create)] - public async Task Create([FromBody] dynamic productDto, string detailLevel = "Simple") + public async Task Create([FromBody] ProductCreateDto productDto) { - Guid result = await _mediator.Send(new CreateNoxEntityCommand(productDto, detailLevel)); + Guid result = await _mediator.Send(new CreateNoxEntityCommand(productDto)); return CreatedAtAction(nameof(GetById), new { id = result }, result); } diff --git a/src/Services/LicenseService/AppyNox.Services.License.WebAPI/appsettings.Development.json b/src/Services/LicenseService/AppyNox.Services.License.WebAPI/appsettings.Development.json index abab281f..baea2524 100644 --- a/src/Services/LicenseService/AppyNox.Services.License.WebAPI/appsettings.Development.json +++ b/src/Services/LicenseService/AppyNox.Services.License.WebAPI/appsettings.Development.json @@ -47,8 +47,8 @@ }, "MessageBroker": { "Host": "rabbitmq://localhost", - "Username": "guest", - "Password": "guest" + "Username": "HappiCorp", + "Password": "HappiCorp" }, "Redis": { "ConnectionString": "localhost:6379" diff --git a/src/Services/LicenseService/Tests/IntegrationTests/AppyNox.Services.License.WebAPI.IntegrationTest/Controllers/LicenseApiTest.cs b/src/Services/LicenseService/Tests/IntegrationTests/AppyNox.Services.License.WebAPI.IntegrationTest/Controllers/LicenseApiTest.cs index 661ff93a..ea482049 100644 --- a/src/Services/LicenseService/Tests/IntegrationTests/AppyNox.Services.License.WebAPI.IntegrationTest/Controllers/LicenseApiTest.cs +++ b/src/Services/LicenseService/Tests/IntegrationTests/AppyNox.Services.License.WebAPI.IntegrationTest/Controllers/LicenseApiTest.cs @@ -1,8 +1,9 @@ using AppyNox.Services.Base.API.Constants; +using AppyNox.Services.Base.API.Wrappers; using AppyNox.Services.Base.Core.Common; using AppyNox.Services.Base.IntegrationTests.URIs; using AppyNox.Services.Base.IntegrationTests.Wrapper.Helpers; -using AppyNox.Services.License.Application.Dtos.LicenseDtos.Models.Base; +using AppyNox.Services.License.Application.Dtos.LicenseDtos.Models; using AppyNox.Services.License.Domain.Entities; using AppyNox.Services.License.WebAPI.IntegrationTest.Fixtures; using System.Linq.Dynamic.Core; @@ -37,14 +38,13 @@ public async Task GetAll_ShouldReturnSuccessStatusCode() // Act var response = await _client.GetAsync($"{_serviceURIs.LicenseServiceURI}/v{NoxVersions.v1_0}/licenses"); - var jsonResponse = await response.Content.ReadAsStringAsync(); - - var licenses = NoxResponseUnwrapper.UnwrapData>(jsonResponse, jsonSerializerOptions: _jsonSerializerOptions); + var wrappedResponse= await NoxResponseUnwrapper.UnwrapResponse>(response, jsonSerializerOptions: _jsonSerializerOptions); // Assert response.EnsureSuccessStatusCode(); Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(licenses.Items); + Assert.NotNull(wrappedResponse.Result.Data); + Assert.NotNull(wrappedResponse.Result.Data.Items); } [Fact] @@ -69,13 +69,12 @@ public async Task GetById_ShouldReturnSuccessStatusCode() // Act var response = await _client.GetAsync(requestUri); - var jsonResponse = await response.Content.ReadAsStringAsync(); - var licenseObj = NoxResponseUnwrapper.UnwrapData(jsonResponse, jsonSerializerOptions: _jsonSerializerOptions); + var noxApiResponse = await NoxResponseUnwrapper.UnwrapResponse(response, jsonSerializerOptions: _jsonSerializerOptions); // Assert response.EnsureSuccessStatusCode(); Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(licenseObj); + Assert.NotNull(noxApiResponse.Result.Data); #endregion } @@ -89,26 +88,36 @@ public async Task Create_ShouldAddNewLicense() // Arrange var requestUri = $"{_serviceURIs.LicenseServiceURI}/v{NoxVersions.v1_0}/licenses"; var uniqueCode = "ffff2"; - var requestBody = new + LicenseCreateDto dto = new() { - code = uniqueCode, - description = "string", - licenseKey = "4547a28a-ce2c-4d84-b791-466d7aedd2bb", - expirationDate = "2025-01-03T20:30:02.928Z", - maxUsers = 2, - maxMacAddresses = 3, - productId = new + Code = uniqueCode, + Description = "string", + LicenseKey = "4547a28a-ce2c-4d84-b791-466d7aedd2bb", + ExpirationDate = DateTime.Now, + MaxUsers = 2, + MaxMacAddresses = 3, + ProductId = new() { - value = "9991492a-118c-4f20-ac8c-76410d57957c" + Value = new Guid("9991492a-118c-4f20-ac8c-76410d57957c") } }; - var jsonRequest = JsonSerializer.Serialize(requestBody); + var jsonRequest = JsonSerializer.Serialize(new + { + dto.Code, + dto.Description, + dto.LicenseKey, + ExpirationDate = dto.ExpirationDate.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.fffZ"), + dto.MaxUsers, + dto.MaxMacAddresses, + dto.ProductId + }); var content = new StringContent(jsonRequest, Encoding.UTF8, "application/json"); // Act HttpResponseMessage response = await _client.PostAsync(requestUri, content); - string jsonResponse = await response.Content.ReadAsStringAsync(); - Guid id = NoxResponseUnwrapper.UnwrapData(jsonResponse, _jsonSerializerOptions); + var jsonData = response.Content.ReadAsStringAsync(); + NoxApiResponse wrappedResponse = await NoxResponseUnwrapper.UnwrapResponse(response, _jsonSerializerOptions); + Guid id = wrappedResponse.Result.Data; // Assert response.EnsureSuccessStatusCode(); diff --git a/src/Services/LicenseService/Tests/IntegrationTests/AppyNox.Services.License.WebAPI.IntegrationTest/Controllers/ProductApiTest.cs b/src/Services/LicenseService/Tests/IntegrationTests/AppyNox.Services.License.WebAPI.IntegrationTest/Controllers/ProductApiTest.cs index 586290d3..764de642 100644 --- a/src/Services/LicenseService/Tests/IntegrationTests/AppyNox.Services.License.WebAPI.IntegrationTest/Controllers/ProductApiTest.cs +++ b/src/Services/LicenseService/Tests/IntegrationTests/AppyNox.Services.License.WebAPI.IntegrationTest/Controllers/ProductApiTest.cs @@ -1,8 +1,9 @@ using AppyNox.Services.Base.API.Constants; +using AppyNox.Services.Base.API.Wrappers; using AppyNox.Services.Base.Core.Common; using AppyNox.Services.Base.IntegrationTests.URIs; using AppyNox.Services.Base.IntegrationTests.Wrapper.Helpers; -using AppyNox.Services.License.Application.Dtos.ProductDtos.Models.Base; +using AppyNox.Services.License.Application.Dtos.ProductDtos.Models; using AppyNox.Services.License.Domain.Entities; using AppyNox.Services.License.WebAPI.IntegrationTest.Fixtures; using System.Linq.Dynamic.Core; @@ -37,14 +38,13 @@ public async Task GetAll_ShouldReturnSuccessStatusCode() // Act var response = await _client.GetAsync($"{_serviceURIs.LicenseServiceURI}/v{NoxVersions.v1_0}/products"); - var jsonResponse = await response.Content.ReadAsStringAsync(); - - var products = NoxResponseUnwrapper.UnwrapData>(jsonResponse, jsonSerializerOptions: _jsonSerializerOptions); + var wrappedResponse = await NoxResponseUnwrapper.UnwrapResponse>(response, jsonSerializerOptions: _jsonSerializerOptions); // Assert response.EnsureSuccessStatusCode(); Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(products.Items); + Assert.NotNull(wrappedResponse.Result.Data); + Assert.NotNull(wrappedResponse.Result.Data.Items); } [Fact] @@ -69,13 +69,12 @@ public async Task GetById_ShouldReturnSuccessStatusCode() // Act var response = await _client.GetAsync(requestUri); - var jsonResponse = await response.Content.ReadAsStringAsync(); - var productObj = NoxResponseUnwrapper.UnwrapData(jsonResponse, jsonSerializerOptions: _jsonSerializerOptions); + var wrappedResponse = await NoxResponseUnwrapper.UnwrapResponse(response, jsonSerializerOptions: _jsonSerializerOptions); // Assert response.EnsureSuccessStatusCode(); Assert.Equal(HttpStatusCode.OK, response.StatusCode); - Assert.NotNull(productObj); + Assert.NotNull(wrappedResponse.Result.Data); #endregion } @@ -88,18 +87,18 @@ public async Task Create_ShouldAddNewProduct() // Arrange var requestUri = $"{_serviceURIs.LicenseServiceURI}/v{NoxVersions.v1_0}/products"; - var requestBody = new + ProductCreateDto dto = new() { - name = "NewProduct", - code = "drop1" + Name = "NewProduct", + Code = "drop1" }; - var jsonRequest = JsonSerializer.Serialize(requestBody); + var jsonRequest = JsonSerializer.Serialize(dto); var content = new StringContent(jsonRequest, Encoding.UTF8, "application/json"); // Act HttpResponseMessage response = await _client.PostAsync(requestUri, content); - string jsonResponse = await response.Content.ReadAsStringAsync(); - Guid id = NoxResponseUnwrapper.UnwrapData(jsonResponse, _jsonSerializerOptions); + NoxApiResponse wrappedResponse = await NoxResponseUnwrapper.UnwrapResponse(response, _jsonSerializerOptions); + Guid id = wrappedResponse.Result.Data; // Assert response.EnsureSuccessStatusCode(); diff --git a/src/Services/LicenseService/Tests/UnitTests/AppyNox.Services.License.Application.UnitTest/AppyNox.Services.License.Application.UnitTest.csproj b/src/Services/LicenseService/Tests/UnitTests/AppyNox.Services.License.Application.UnitTest/AppyNox.Services.License.Application.UnitTest.csproj index 6fe1651a..01367318 100644 --- a/src/Services/LicenseService/Tests/UnitTests/AppyNox.Services.License.Application.UnitTest/AppyNox.Services.License.Application.UnitTest.csproj +++ b/src/Services/LicenseService/Tests/UnitTests/AppyNox.Services.License.Application.UnitTest/AppyNox.Services.License.Application.UnitTest.csproj @@ -27,4 +27,8 @@ + + + + diff --git a/src/Services/LicenseService/Tests/UnitTests/AppyNox.Services.License.Application.UnitTest/CQRSTests/LicenseCQRSUnitTests.cs b/src/Services/LicenseService/Tests/UnitTests/AppyNox.Services.License.Application.UnitTest/CQRSTests/LicenseCQRSUnitTests.cs index 2f3404e5..7140ca4a 100644 --- a/src/Services/LicenseService/Tests/UnitTests/AppyNox.Services.License.Application.UnitTest/CQRSTests/LicenseCQRSUnitTests.cs +++ b/src/Services/LicenseService/Tests/UnitTests/AppyNox.Services.License.Application.UnitTest/CQRSTests/LicenseCQRSUnitTests.cs @@ -6,8 +6,7 @@ using AppyNox.Services.Base.Core.AsyncLocals; using AppyNox.Services.Base.Core.Common; using AppyNox.Services.Base.Core.Extensions; -using AppyNox.Services.License.Application.Dtos.LicenseDtos.DetailLevel; -using AppyNox.Services.License.Application.Dtos.LicenseDtos.Models.Base; +using AppyNox.Services.License.Application.Dtos.LicenseDtos.Models; using AppyNox.Services.License.Application.Dtos.ProductDtos.Models.Base; using AppyNox.Services.License.Domain.Entities; using MediatR; @@ -70,7 +69,7 @@ public LicenseCQRSUnitTests(NoxApplicationTestFixture fixture) new ProductId(Guid.NewGuid()) ); - LicenseSimpleDto licenseSimpleDto = new() + LicenseDto licenseSimpleDto = new() { Code = "code", Description = "description", @@ -101,7 +100,7 @@ public LicenseCQRSUnitTests(NoxApplicationTestFixture fixture) public async Task GetAllEntitiesQuery_ShouldSuccess() { // Act - var result = await _mediator.Send(new GetAllNoxEntitiesQuery(_fixture.MockQueryParameters.Object)); + var result = await _mediator.Send(new GetAllNoxEntitiesQuery(_fixture.MockQueryParameters.Object)); // Assert Assert.NotNull(result); @@ -111,35 +110,35 @@ public async Task GetAllEntitiesQuery_ShouldSuccess() public async Task GetEntityByIdQuery_ShouldSuccess() { // Act - var result = await _mediator.Send(new GetNoxEntityByIdQuery(It.IsAny(), _fixture.MockQueryParameters.Object)); + var result = await _mediator.Send(new GetNoxEntityByIdQuery(It.IsAny(), _fixture.MockQueryParameters.Object)); // Assert Assert.NotNull(result); - Assert.True(result is LicenseSimpleDto); + Assert.True(result is LicenseDto); } [Fact] public async Task CreateEntityCommand_ShouldSuccess() { // Prepare - string jsonData = @"{ - ""code"": ""LK002"", - ""expirationDate"": ""2025-01-03T20:30:02.928Z"", - ""licenseKey"": ""00b7fb79-9a1c-4786-abb9-1ea9bd7f379esssssssssssssss"", - ""description"": ""new description"", - ""maxUsers"" : 4, - ""maxMacAddresses"" : 3, - ""productId"" : { - ""value"" : ""9991492a-118c-4f20-ac8c-76410d57957c"" - } - }"; - JsonDocument jsonDocument = JsonDocument.Parse(jsonData); - JsonElement root = jsonDocument.RootElement; + LicenseCreateDto dto = new() + { + Code = "LK002", + ExpirationDate = DateTime.UtcNow, + LicenseKey = Guid.NewGuid().ToString(), + Description = "Description", + MaxUsers = 4, + MaxMacAddresses = 3, + ProductId = new() + { + Value = Guid.NewGuid() + } + }; NoxContext.UserId = Guid.Parse("a8bfc75b-2ac3-47e2-b013-8b8a1efba45d"); // Act var result = await _mediator - .Send(new CreateNoxEntityCommand(root, LicenseCreateDetailLevel.Simple.GetDisplayName())); + .Send(new CreateNoxEntityCommand(dto)); // Assert Assert.True(Guid.TryParse(result.ToString(), out _)); diff --git a/src/Services/LicenseService/Tests/UnitTests/AppyNox.Services.License.Application.UnitTest/DtoTests/DtoMappingRegistryUnitTests/LicenseDtoMappingRegistryUnitTest.cs b/src/Services/LicenseService/Tests/UnitTests/AppyNox.Services.License.Application.UnitTest/DtoTests/DtoMappingRegistryUnitTests/LicenseDtoMappingRegistryUnitTest.cs deleted file mode 100644 index 74c872a5..00000000 --- a/src/Services/LicenseService/Tests/UnitTests/AppyNox.Services.License.Application.UnitTest/DtoTests/DtoMappingRegistryUnitTests/LicenseDtoMappingRegistryUnitTest.cs +++ /dev/null @@ -1,103 +0,0 @@ -using AppyNox.Services.Base.Core.Enums; -using AppyNox.Services.Base.Core.Extensions; -using AppyNox.Services.License.Application.Dtos.DtoUtilities; -using AppyNox.Services.License.Application.Dtos.LicenseDtos.DetailLevel; -using AppyNox.Services.License.Application.Dtos.LicenseDtos.Models.Base; -using AppyNox.Services.License.Application.UnitTest.DtoTests.Fixtures; -using AppyNox.Services.License.Domain.Entities; - -namespace AppyNox.Services.License.Application.UnitTest.DtoTests.DtoMappingRegistryUnitTests -{ - [Collection("DtoMappingRegistry Collection")] - public class LicenseDtoMappingRegistryUnitTest(DtoMappingRegistryFixture fixture) - { - #region [ Fields ] - - private readonly DtoMappingRegistry _registry = fixture.Registry; - - #endregion - - #region [ Dto Level Mapping Types ] - - [Fact] - public void LicenseDataAccessDtoLevelMappingTypesShouldBeAvailable() - { - // Act - var result = _registry.GetDetailLevelTypes(typeof(LicenseEntity)).GetValueOrDefault(DtoLevelMappingTypes.DataAccess); - - // Assert - Assert.NotNull(result); - } - - [Fact] - public void LicenseUpdateDtoLevelMappingTypesShouldBeAvailable() - { - // Act - var result = _registry.GetDetailLevelTypes(typeof(LicenseEntity)).GetValueOrDefault(DtoLevelMappingTypes.Update); - - // Assert - Assert.NotNull(result); - } - - [Fact] - public void LicenseCreateDtoLevelMappingTypesShouldBeAvailable() - { - // Act - var result = _registry.GetDetailLevelTypes(typeof(LicenseEntity)).GetValueOrDefault(DtoLevelMappingTypes.Create); - - // Assert - Assert.NotNull(result); - } - - #endregion - - #region [ Get Dto Types ] - - #region [ DataAccess ] - - [Fact] - public void LicenseDataAccessSimpleShouldReturnLicenseSimpleDto() - { - // Act - var result = _registry.GetDtoType(DtoLevelMappingTypes.DataAccess, typeof(LicenseEntity), LicenseDataAccessDetailLevel.Simple.GetDisplayName()); - - // Assert - Assert.NotNull(result); - Assert.Equal(typeof(LicenseSimpleDto), result); - } - - #endregion - - #region [ Create ] - - [Fact] - public void LicenseCreateSimpleShouldReturnLicenseSimpleCreateDto() - { - // Act - var result = _registry.GetDtoType(DtoLevelMappingTypes.Create, typeof(LicenseEntity), LicenseCreateDetailLevel.Simple.GetDisplayName()); - - // Assert - Assert.NotNull(result); - Assert.Equal(typeof(LicenseSimpleCreateDto), result); - } - - #endregion - - #region [ Update ] - - [Fact] - public void LicenseUpdateSimpleShouldReturnLicenseSimpleUpdateDto() - { - // Act - var result = _registry.GetDtoType(DtoLevelMappingTypes.Update, typeof(LicenseEntity), LicenseUpdateDetailLevel.Simple.GetDisplayName()); - - // Assert - Assert.NotNull(result); - Assert.Equal(typeof(LicenseSimpleUpdateDto), result); - } - - #endregion - - #endregion - } -} \ No newline at end of file diff --git a/src/Services/LicenseService/Tests/UnitTests/AppyNox.Services.License.Application.UnitTest/DtoTests/DtoMappingRegistryUnitTests/ProductDtoMappingRegistryUnitTest.cs b/src/Services/LicenseService/Tests/UnitTests/AppyNox.Services.License.Application.UnitTest/DtoTests/DtoMappingRegistryUnitTests/ProductDtoMappingRegistryUnitTest.cs deleted file mode 100644 index 6459ced2..00000000 --- a/src/Services/LicenseService/Tests/UnitTests/AppyNox.Services.License.Application.UnitTest/DtoTests/DtoMappingRegistryUnitTests/ProductDtoMappingRegistryUnitTest.cs +++ /dev/null @@ -1,103 +0,0 @@ -using AppyNox.Services.Base.Core.Enums; -using AppyNox.Services.Base.Core.Extensions; -using AppyNox.Services.License.Application.Dtos.DtoUtilities; -using AppyNox.Services.License.Application.Dtos.ProductDtos.DetailLevel; -using AppyNox.Services.License.Application.Dtos.ProductDtos.Models.Base; -using AppyNox.Services.License.Application.UnitTest.DtoTests.Fixtures; -using AppyNox.Services.License.Domain.Entities; - -namespace AppyNox.Services.License.Application.UnitTest.DtoTests.DtoMappingRegistryUnitTests -{ - [Collection("DtoMappingRegistry Collection")] - public class ProductDtoMappingRegistryUnitTest(DtoMappingRegistryFixture fixture) - { - #region [ Fields ] - - private readonly DtoMappingRegistry _registry = fixture.Registry; - - #endregion - - #region [ Dto Level Mapping Types ] - - [Fact] - public void ProductDataAccessDtoLevelMappingTypesShouldBeAvailable() - { - // Act - var result = _registry.GetDetailLevelTypes(typeof(ProductEntity)).GetValueOrDefault(DtoLevelMappingTypes.DataAccess); - - // Assert - Assert.NotNull(result); - } - - [Fact] - public void ProductUpdateDtoLevelMappingTypesShouldBeAvailable() - { - // Act - var result = _registry.GetDetailLevelTypes(typeof(ProductEntity)).GetValueOrDefault(DtoLevelMappingTypes.Update); - - // Assert - Assert.NotNull(result); - } - - [Fact] - public void ProductCreateDtoLevelMappingTypesShouldBeAvailable() - { - // Act - var result = _registry.GetDetailLevelTypes(typeof(ProductEntity)).GetValueOrDefault(DtoLevelMappingTypes.Create); - - // Assert - Assert.NotNull(result); - } - - #endregion - - #region [ Get Dto Types ] - - #region [ DataAccess ] - - [Fact] - public void ProductDataAccessSimpleShouldReturnProductSimpleDto() - { - // Act - var result = _registry.GetDtoType(DtoLevelMappingTypes.DataAccess, typeof(ProductEntity), ProductDataAccessDetailLevel.Simple.GetDisplayName()); - - // Assert - Assert.NotNull(result); - Assert.Equal(typeof(ProductSimpleDto), result); - } - - #endregion - - #region [ Create ] - - [Fact] - public void ProductCreateSimpleShouldReturnProductSimpleCreateDto() - { - // Act - var result = _registry.GetDtoType(DtoLevelMappingTypes.Create, typeof(ProductEntity), ProductCreateDetailLevel.Simple.GetDisplayName()); - - // Assert - Assert.NotNull(result); - Assert.Equal(typeof(ProductSimpleCreateDto), result); - } - - #endregion - - #region [ Update ] - - [Fact] - public void ProductUpdateSimpleShouldReturnProductSimpleUpdateDto() - { - // Act - var result = _registry.GetDtoType(DtoLevelMappingTypes.Update, typeof(ProductEntity), ProductUpdateDetailLevel.Simple.GetDisplayName()); - - // Assert - Assert.NotNull(result); - Assert.Equal(typeof(ProductSimpleUpdateDto), result); - } - - #endregion - - #endregion - } -} \ No newline at end of file diff --git a/src/Services/LicenseService/Tests/UnitTests/AppyNox.Services.License.Application.UnitTest/DtoTests/Fixtures/DtoMappingRegistryCollection.cs b/src/Services/LicenseService/Tests/UnitTests/AppyNox.Services.License.Application.UnitTest/DtoTests/Fixtures/DtoMappingRegistryCollection.cs deleted file mode 100644 index 4ed33f60..00000000 --- a/src/Services/LicenseService/Tests/UnitTests/AppyNox.Services.License.Application.UnitTest/DtoTests/Fixtures/DtoMappingRegistryCollection.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace AppyNox.Services.License.Application.UnitTest.DtoTests.Fixtures -{ - [CollectionDefinition("DtoMappingRegistry Collection")] - public class DtoMappingRegistryCollection : ICollectionFixture - { - } -} \ No newline at end of file diff --git a/src/Services/LicenseService/Tests/UnitTests/AppyNox.Services.License.Application.UnitTest/DtoTests/Fixtures/DtoMappingRegistryFixture.cs b/src/Services/LicenseService/Tests/UnitTests/AppyNox.Services.License.Application.UnitTest/DtoTests/Fixtures/DtoMappingRegistryFixture.cs deleted file mode 100644 index cf7f05dc..00000000 --- a/src/Services/LicenseService/Tests/UnitTests/AppyNox.Services.License.Application.UnitTest/DtoTests/Fixtures/DtoMappingRegistryFixture.cs +++ /dev/null @@ -1,31 +0,0 @@ -using AppyNox.Services.License.Application.Dtos.DtoUtilities; - -namespace AppyNox.Services.License.Application.UnitTest.DtoTests.Fixtures -{ - public class DtoMappingRegistryFixture : IDisposable - { - #region [ Public Constructors ] - - public DtoMappingRegistryFixture() - { - Registry = new DtoMappingRegistry(); - } - - #endregion - - #region [ Properties ] - - public DtoMappingRegistry Registry { get; } - - #endregion - - #region [ Public Methods ] - - public void Dispose() - { - GC.SuppressFinalize(this); - } - - #endregion - } -} \ No newline at end of file diff --git a/src/Services/LicenseService/Tests/UnitTests/AppyNox.Services.License.Application.UnitTest/FluentValidation/LicenseSimpleCreateValidatorUnitTest.cs b/src/Services/LicenseService/Tests/UnitTests/AppyNox.Services.License.Application.UnitTest/FluentValidation/LicenseSimpleCreateValidatorUnitTest.cs index ec761c9e..8a464e36 100644 --- a/src/Services/LicenseService/Tests/UnitTests/AppyNox.Services.License.Application.UnitTest/FluentValidation/LicenseSimpleCreateValidatorUnitTest.cs +++ b/src/Services/LicenseService/Tests/UnitTests/AppyNox.Services.License.Application.UnitTest/FluentValidation/LicenseSimpleCreateValidatorUnitTest.cs @@ -1,4 +1,4 @@ -using AppyNox.Services.License.Application.Dtos.LicenseDtos.Models.Base; +using AppyNox.Services.License.Application.Dtos.LicenseDtos.Models; using AppyNox.Services.License.Application.Dtos.ProductDtos.Models.Base; using AppyNox.Services.License.Application.Validators.License.Create; @@ -114,9 +114,9 @@ public async Task Validate_ProductId_ShouldMatchExpected(string? productId, bool #region [ Private Methods ] - private static LicenseSimpleCreateDto CreateValidDto() + private static LicenseCreateDto CreateValidDto() { - return new LicenseSimpleCreateDto + return new LicenseCreateDto { Code = "ABCDE", Description = "Valid Description", diff --git a/src/Services/LicenseService/Tests/UnitTests/AppyNox.Services.License.Application.UnitTest/FluentValidation/ProductSimpleCreateValidatorUnitTest.cs b/src/Services/LicenseService/Tests/UnitTests/AppyNox.Services.License.Application.UnitTest/FluentValidation/ProductSimpleCreateValidatorUnitTest.cs index 689fbc16..e8c509f9 100644 --- a/src/Services/LicenseService/Tests/UnitTests/AppyNox.Services.License.Application.UnitTest/FluentValidation/ProductSimpleCreateValidatorUnitTest.cs +++ b/src/Services/LicenseService/Tests/UnitTests/AppyNox.Services.License.Application.UnitTest/FluentValidation/ProductSimpleCreateValidatorUnitTest.cs @@ -1,4 +1,4 @@ -using AppyNox.Services.License.Application.Dtos.ProductDtos.Models.Base; +using AppyNox.Services.License.Application.Dtos.ProductDtos.Models; using AppyNox.Services.License.Application.Validators.Product.Create; namespace AppyNox.Services.License.Application.UnitTest.FluentValidation @@ -48,9 +48,9 @@ public async Task Validate_Name_ShouldMatchExpected(string? name, bool expectedI #region [ Private Methods ] - private static ProductSimpleCreateDto CreateValidDto() + private static ProductCreateDto CreateValidDto() { - return new ProductSimpleCreateDto + return new ProductCreateDto { Name = "ValidName", Code = "PROD1" diff --git a/src/Services/LicenseService/Tests/UnitTests/AppyNox.Services.License.Infrastructure.UnitTest/RepositoryTests/LicenseRepositoryUnitTest.cs b/src/Services/LicenseService/Tests/UnitTests/AppyNox.Services.License.Infrastructure.UnitTest/RepositoryTests/LicenseRepositoryUnitTest.cs index 84dc9cdd..d767503c 100644 --- a/src/Services/LicenseService/Tests/UnitTests/AppyNox.Services.License.Infrastructure.UnitTest/RepositoryTests/LicenseRepositoryUnitTest.cs +++ b/src/Services/LicenseService/Tests/UnitTests/AppyNox.Services.License.Infrastructure.UnitTest/RepositoryTests/LicenseRepositoryUnitTest.cs @@ -37,8 +37,6 @@ public async Task GetAllAsync_ShouldReturnEntity() LicenseRepository repository = new(context, _noxRepositoryLogger, unitOfWork); QueryParameters queryParameters = new() { - Access = string.Empty, - DetailLevel = "Simple", PageNumber = 1, PageSize = 1, }; @@ -58,8 +56,6 @@ public async Task GetAllAsync_ShouldPaginationReturnTwo() LicenseRepository repository = new(context, _noxRepositoryLogger, unitOfWork); QueryParameters queryParameters = new() { - Access = string.Empty, - DetailLevel = "Simple", PageNumber = 1, PageSize = 2, }; @@ -81,8 +77,6 @@ public async Task GetAllAsync_ShouldPaginationReturnCorrectEntity() LicenseRepository repository = new(context, _noxRepositoryLogger, unitOfWork); QueryParameters queryParameters = new() { - Access = string.Empty, - DetailLevel = "Simple", PageNumber = 2, PageSize = 1, }; @@ -105,8 +99,6 @@ public async Task GetAllAsync_ShouldPaginationReturnFifty() LicenseRepository repository = new(context, _noxRepositoryLogger, unitOfWork); QueryParameters queryParameters = new() { - Access = string.Empty, - DetailLevel = "Simple", PageNumber = 1, PageSize = 50, }; @@ -127,8 +119,6 @@ public async Task GetAllAsync_ShouldPaginationReturnFiftyAndCorrectEntities() LicenseRepository repository = new(context, _noxRepositoryLogger, unitOfWork); QueryParameters queryParameters = new() { - Access = string.Empty, - DetailLevel = "Simple", PageNumber = 5, PageSize = 5, }; diff --git a/src/Services/LicenseService/Tests/UnitTests/AppyNox.Services.License.Infrastructure.UnitTest/RepositoryTests/ProductRepositoryUnitTest.cs b/src/Services/LicenseService/Tests/UnitTests/AppyNox.Services.License.Infrastructure.UnitTest/RepositoryTests/ProductRepositoryUnitTest.cs index 92924ba9..a9aebb44 100644 --- a/src/Services/LicenseService/Tests/UnitTests/AppyNox.Services.License.Infrastructure.UnitTest/RepositoryTests/ProductRepositoryUnitTest.cs +++ b/src/Services/LicenseService/Tests/UnitTests/AppyNox.Services.License.Infrastructure.UnitTest/RepositoryTests/ProductRepositoryUnitTest.cs @@ -37,8 +37,6 @@ public async Task GetAllAsync_ShouldReturnEntity() ProductRepository repository = new(context, _noxRepositoryLoggerStub); QueryParameters queryParameters = new() { - Access = string.Empty, - DetailLevel = "Simple", PageNumber = 1, PageSize = 1, }; @@ -57,8 +55,6 @@ public async Task GetAllAsync_ShouldPaginationReturnTwo() ProductRepository repository = new(context, _noxRepositoryLoggerStub); QueryParameters queryParameters = new() { - Access = string.Empty, - DetailLevel = "Simple", PageNumber = 1, PageSize = 2, }; @@ -80,8 +76,6 @@ public async Task GetAllAsync_ShouldPaginationReturnCorrectEntity() ProductRepository repository = new(context, _noxRepositoryLoggerStub); QueryParameters queryParameters = new() { - Access = string.Empty, - DetailLevel = "Simple", PageNumber = 2, PageSize = 1, }; @@ -102,8 +96,6 @@ public async Task GetAllAsync_ShouldPaginationReturnFifty() ProductRepository repository = new(context, _noxRepositoryLoggerStub); QueryParameters queryParameters = new() { - Access = string.Empty, - DetailLevel = "Simple", PageNumber = 1, PageSize = 50, }; @@ -123,8 +115,6 @@ public async Task GetAllAsync_ShouldPaginationReturnFiftyAndCorrectEntities() ProductRepository repository = new(context, _noxRepositoryLoggerStub); QueryParameters queryParameters = new() { - Access = string.Empty, - DetailLevel = "Simple", PageNumber = 5, PageSize = 5, }; diff --git a/src/Services/SsoService/AppyNox.Services.Sso.Application/DTOs/AccountDtos/Models/LoginResultDto.cs b/src/Services/SsoService/AppyNox.Services.Sso.Application/DTOs/AccountDtos/Models/LoginResultDto.cs new file mode 100644 index 00000000..dfc548ec --- /dev/null +++ b/src/Services/SsoService/AppyNox.Services.Sso.Application/DTOs/AccountDtos/Models/LoginResultDto.cs @@ -0,0 +1,7 @@ +namespace AppyNox.Services.Sso.Application.DTOs.AccountDtos.Models; + +public class LoginResultDto +{ + public string Token { get; set; } = default!; + public string RefreshToken { get; set; } = default!; +} diff --git a/src/Services/SsoService/AppyNox.Services.Sso.Application/DependencyInjection.cs b/src/Services/SsoService/AppyNox.Services.Sso.Application/DependencyInjection.cs index f51829a0..39c8d953 100644 --- a/src/Services/SsoService/AppyNox.Services.Sso.Application/DependencyInjection.cs +++ b/src/Services/SsoService/AppyNox.Services.Sso.Application/DependencyInjection.cs @@ -1,10 +1,7 @@ using AppyNox.Services.Base.Application; -using AppyNox.Services.Base.Application.DtoUtilities; using AppyNox.Services.Base.Application.Interfaces.Loggers; -using FluentValidation; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; using System.Reflection; namespace AppyNox.Services.Sso.Application diff --git a/src/Services/SsoService/AppyNox.Services.Sso.WebAPI/Controllers/Authentication/AuthenticationController.cs b/src/Services/SsoService/AppyNox.Services.Sso.WebAPI/Controllers/Authentication/AuthenticationController.cs index 71212a13..e6b9b5bd 100644 --- a/src/Services/SsoService/AppyNox.Services.Sso.WebAPI/Controllers/Authentication/AuthenticationController.cs +++ b/src/Services/SsoService/AppyNox.Services.Sso.WebAPI/Controllers/Authentication/AuthenticationController.cs @@ -35,8 +35,6 @@ public class AuthenticationController( private readonly ICustomTokenManager _customTokenManager = customTokenManager; - private readonly IValidator _loginDtoValidator = loginDtoValidator; - private readonly IValidator _refreshTokenDtoValidator = refreshTokenDtoValidator; private readonly IMediator _mediator = mediator; @@ -47,11 +45,11 @@ public class AuthenticationController( [HttpPost] [Route("connect/token")] - public async Task Authenticate([FromBody] LoginDto userCredential) + public async Task> Authenticate([FromBody] LoginDto userCredential) { var result = await _mediator.Send(new AuthenticateCommand(userCredential)); - return new NoxApiResponse(new { result.Token, result.RefreshToken }, NoxSsoApiResourceService.SignInSuccessful); + return new NoxApiResponse(new LoginResultDto() { Token = result.Token, RefreshToken = result.RefreshToken }, NoxSsoApiResourceService.SignInSuccessful); } [HttpGet] @@ -63,7 +61,7 @@ public async Task Verify(string token, string audience) } [HttpPost("refresh")] - public async Task Refresh([FromBody] RefreshTokenDto model) + public async Task> Refresh([FromBody] RefreshTokenDto model) { var validationResult = await _refreshTokenDtoValidator.ValidateAsync(model); if (!validationResult.IsValid) @@ -96,7 +94,7 @@ public async Task Refresh([FromBody] RefreshTokenDto model) var newRefreshToken = _customTokenManager.CreateRefreshToken(); await _customUserManager.SaveRefreshToken(userId, newRefreshToken); - return Ok(new { Token = newJwtToken, RefreshToken = newRefreshToken }); + return new NoxApiResponse(new LoginResultDto() { Token = newJwtToken, RefreshToken = newRefreshToken }); } #endregion diff --git a/src/Services/SsoService/AppyNox.Services.Sso.WebAPI/Program.cs b/src/Services/SsoService/AppyNox.Services.Sso.WebAPI/Program.cs index 35d6ee9a..f026e0f0 100644 --- a/src/Services/SsoService/AppyNox.Services.Sso.WebAPI/Program.cs +++ b/src/Services/SsoService/AppyNox.Services.Sso.WebAPI/Program.cs @@ -17,7 +17,6 @@ await builder.AddApiServices(options => { options.SetupHostName = "CouponHost"; options.UseConsulKV = true; - options.UseDynamicRequestBodyOperationFilter = false; options.ConfigureLayers = (services, logger, configuration) => { services diff --git a/src/Services/SsoService/Tests/IntegrationTests/AppyNox.Services.Sso.WebAPI.IntegrationTest/Controllers/v1.0/AuthenticationApiTest.cs b/src/Services/SsoService/Tests/IntegrationTests/AppyNox.Services.Sso.WebAPI.IntegrationTest/Controllers/v1.0/AuthenticationApiTest.cs index ce57e65a..51d31844 100644 --- a/src/Services/SsoService/Tests/IntegrationTests/AppyNox.Services.Sso.WebAPI.IntegrationTest/Controllers/v1.0/AuthenticationApiTest.cs +++ b/src/Services/SsoService/Tests/IntegrationTests/AppyNox.Services.Sso.WebAPI.IntegrationTest/Controllers/v1.0/AuthenticationApiTest.cs @@ -4,6 +4,7 @@ using AppyNox.Services.Base.IntegrationTests.URIs; using AppyNox.Services.Base.IntegrationTests.Wrapper; using AppyNox.Services.Base.IntegrationTests.Wrapper.Helpers; +using AppyNox.Services.Sso.Application.DTOs.AccountDtos.Models; using AppyNox.Services.Sso.Application.DTOs.RefreshTokenDtos.Models; using AppyNox.Services.Sso.Infrastructure.Exceptions.Base; using AppyNox.Services.Sso.WebAPI.Exceptions.Base; @@ -56,7 +57,7 @@ public async Task ConnectToken_ShouldReturnToken(string username, string passwor string uri = $"{_serviceURIs.SsoServiceURI}/v{NoxVersions.v1_0}/authentication/connect/token"; HttpResponseMessage response = await _client.PostAsync(uri, content); - NoxApiResponse wrappedResponse = await NoxResponseUnwrapper.UnwrapResponse(response, jsonSerializerOptions: _jsonSerializerOptions); + NoxApiResponse wrappedResponse = await NoxResponseUnwrapper.UnwrapResponse(response, jsonSerializerOptions: _jsonSerializerOptions); // Assert response.EnsureSuccessStatusCode(); @@ -64,22 +65,15 @@ public async Task ConnectToken_ShouldReturnToken(string username, string passwor Assert.NotNull(wrappedResponse.Result); Assert.False(wrappedResponse.HasError); - string? resultDataObject = wrappedResponse.Result.Data?.ToString(); - Assert.NotNull(resultDataObject); - string? token = string.Empty; - using (JsonDocument doc = JsonDocument.Parse(resultDataObject)) - { - JsonElement root = doc.RootElement; - token = root.GetProperty("token").GetString(); - } - Assert.False(string.IsNullOrEmpty(token)); + Assert.NotNull(wrappedResponse.Result.Data); + Assert.False(string.IsNullOrEmpty(wrappedResponse.Result.Data.Token)); #endregion #region [ Verify Token ] // Act - uri = $"{_serviceURIs.SsoServiceURI}/v{NoxVersions.v1_0}/authentication/verify-token/{token}?audience={audience}"; + uri = $"{_serviceURIs.SsoServiceURI}/v{NoxVersions.v1_0}/authentication/verify-token/{wrappedResponse.Result.Data.Token}?audience={audience}"; response = await _client.GetAsync(uri); // Assert @@ -115,7 +109,7 @@ public async Task ConnectToken_ShouldReturnCorrectErrorResponse(string username, string uri = $"{_serviceURIs.SsoServiceURI}/v{NoxVersions.v1_0}/authentication/connect/token"; HttpResponseMessage response = await _client.PostAsync(uri, content); - NoxApiResponse wrappedResponse = await NoxResponseUnwrapper.UnwrapResponse(response, jsonSerializerOptions: _jsonSerializerOptions); + NoxApiResponse wrappedResponse = await NoxResponseUnwrapper.UnwrapResponse(response, jsonSerializerOptions: _jsonSerializerOptions); NoxApiExceptionWrapObjectPOCO? errorObject = (wrappedResponse.Result.Error as NoxApiExceptionWrapObjectPOCO); // Assert @@ -153,7 +147,7 @@ public async Task ConnectToken_ShouldReturnCorrectValidationResponse(string user string uri = $"{_serviceURIs.SsoServiceURI}/v{NoxVersions.v1_0}/authentication/connect/token"; HttpResponseMessage response = await _client.PostAsync(uri, content); - NoxApiResponse wrappedResponse = await NoxResponseUnwrapper.UnwrapResponse(response, jsonSerializerOptions: _jsonSerializerOptions); + NoxApiResponse wrappedResponse = await NoxResponseUnwrapper.UnwrapResponse(response, jsonSerializerOptions: _jsonSerializerOptions); NoxApiValidationExceptionWrapObjectPOCO? errorObject = (wrappedResponse.Result.Error as NoxApiValidationExceptionWrapObjectPOCO); // Assert @@ -193,7 +187,7 @@ public async Task RefreshToken_ShouldReturnToken(string username, string passwor string uri = $"{_serviceURIs.SsoServiceURI}/v{NoxVersions.v1_0}/authentication/connect/token"; HttpResponseMessage response = await _client.PostAsync(uri, content); - NoxApiResponse wrappedResponse = await NoxResponseUnwrapper.UnwrapResponse(response, jsonSerializerOptions: _jsonSerializerOptions); + NoxApiResponse wrappedResponse = await NoxResponseUnwrapper.UnwrapResponse(response, jsonSerializerOptions: _jsonSerializerOptions); // Assert response.EnsureSuccessStatusCode(); @@ -201,16 +195,9 @@ public async Task RefreshToken_ShouldReturnToken(string username, string passwor Assert.NotNull(wrappedResponse.Result); Assert.False(wrappedResponse.HasError); - string? resultDataObject = wrappedResponse.Result.Data?.ToString(); - Assert.NotNull(resultDataObject); - string? token = string.Empty; - string? refreshToken = string.Empty; - using (JsonDocument doc = JsonDocument.Parse(resultDataObject)) - { - JsonElement root = doc.RootElement; - token = root.GetProperty("token").GetString(); - refreshToken = root.GetProperty("refreshToken").GetString(); - } + Assert.NotNull(wrappedResponse.Result.Data); + string? token = wrappedResponse.Result.Data.Token; + string? refreshToken = wrappedResponse.Result.Data.RefreshToken; Assert.False(string.IsNullOrEmpty(token)); Assert.False(string.IsNullOrEmpty(refreshToken)); @@ -237,7 +224,7 @@ public async Task RefreshToken_ShouldReturnToken(string username, string passwor ); HttpResponseMessage refreshResponse = await _client.PostAsync(uri, content); - NoxApiResponse refreshWrappedResponse = await NoxResponseUnwrapper.UnwrapResponse(refreshResponse, jsonSerializerOptions: _jsonSerializerOptions); + NoxApiResponse refreshWrappedResponse = await NoxResponseUnwrapper.UnwrapResponse(refreshResponse, jsonSerializerOptions: _jsonSerializerOptions); // Assert refreshResponse.EnsureSuccessStatusCode(); @@ -245,16 +232,10 @@ public async Task RefreshToken_ShouldReturnToken(string username, string passwor Assert.NotNull(refreshWrappedResponse.Result); Assert.False(refreshWrappedResponse.HasError); - string? refreshResultDataObject = refreshWrappedResponse.Result.Data?.ToString(); - Assert.NotNull(refreshResultDataObject); - string? newToken = string.Empty; - string? newRefreshToken = string.Empty; - using (JsonDocument doc = JsonDocument.Parse(refreshResultDataObject)) - { - JsonElement root = doc.RootElement; - newToken = root.GetProperty("token").GetString(); - newRefreshToken = root.GetProperty("refreshToken").GetString(); - } + Assert.NotNull(refreshWrappedResponse.Result.Data); + string? newToken = refreshWrappedResponse.Result.Data.Token; + string? newRefreshToken = refreshWrappedResponse.Result.Data.RefreshToken; + Assert.False(string.IsNullOrEmpty(newToken)); Assert.False(string.IsNullOrEmpty(newRefreshToken)); Assert.NotEqual(token, newToken); @@ -296,7 +277,7 @@ public async Task RefreshToken_ShouldReturnCorrectErrorResponse(bool useVerified string loginUri = $"{_serviceURIs.SsoServiceURI}/v{NoxVersions.v1_0}/authentication/connect/token"; HttpResponseMessage response = await _client.PostAsync(loginUri, loginContent); - NoxApiResponse wrappedResponse = await NoxResponseUnwrapper.UnwrapResponse(response, jsonSerializerOptions: _jsonSerializerOptions); + NoxApiResponse wrappedResponse = await NoxResponseUnwrapper.UnwrapResponse(response, jsonSerializerOptions: _jsonSerializerOptions); // Assert response.EnsureSuccessStatusCode(); @@ -304,15 +285,11 @@ public async Task RefreshToken_ShouldReturnCorrectErrorResponse(bool useVerified Assert.NotNull(wrappedResponse.Result); Assert.False(wrappedResponse.HasError); - string? resultDataObject = wrappedResponse.Result.Data?.ToString(); - Assert.NotNull(resultDataObject); + Assert.NotNull(wrappedResponse.Result.Data); + + token = useVerifiedToken ? wrappedResponse.Result.Data.Token ?? throw new Exception("token was null") : "dummyToken"; + refreshToken = useVerifiedRefreshToken ? wrappedResponse.Result.Data.RefreshToken ?? throw new Exception("refresh token was null") : "dummyRefreshToken"; - using (JsonDocument doc = JsonDocument.Parse(resultDataObject)) - { - JsonElement root = doc.RootElement; - token = useVerifiedToken ? root.GetProperty("token").GetString() ?? throw new Exception("token was null") : "dummyToken"; - refreshToken = useVerifiedRefreshToken ? root.GetProperty("refreshToken").GetString() ?? throw new Exception("refresh token was null") : "dummyRefreshToken"; - } Assert.NotNull(token); Assert.NotNull(refreshToken); } @@ -338,7 +315,7 @@ public async Task RefreshToken_ShouldReturnCorrectErrorResponse(bool useVerified ); HttpResponseMessage refreshResponse = await _client.PostAsync(uri, content); - NoxApiResponse refreshWrappedResponse = await NoxResponseUnwrapper.UnwrapResponse(refreshResponse, jsonSerializerOptions: _jsonSerializerOptions); + NoxApiResponse refreshWrappedResponse = await NoxResponseUnwrapper.UnwrapResponse(refreshResponse, jsonSerializerOptions: _jsonSerializerOptions); NoxApiExceptionWrapObjectPOCO? wrapObjectPOCO = refreshWrappedResponse.Result.Error as NoxApiExceptionWrapObjectPOCO; // Assert @@ -371,7 +348,7 @@ public async Task RefreshToken_ShouldReturnCorrectValidationResponse(string toke string uri = $"{_serviceURIs.SsoServiceURI}/v{NoxVersions.v1_0}/authentication/refresh"; HttpResponseMessage response = await _client.PostAsync(uri, content); - NoxApiResponse wrappedResponse = await NoxResponseUnwrapper.UnwrapResponse(response, jsonSerializerOptions: _jsonSerializerOptions); + NoxApiResponse wrappedResponse = await NoxResponseUnwrapper.UnwrapResponse(response, jsonSerializerOptions: _jsonSerializerOptions); NoxApiValidationExceptionWrapObjectPOCO? errorObject = (wrappedResponse.Result.Error as NoxApiValidationExceptionWrapObjectPOCO); // Assert