diff --git a/Applications/AdminApi/src/AdminApi/Extensions/IServiceCollectionExtensions.cs b/Applications/AdminApi/src/AdminApi/Extensions/IServiceCollectionExtensions.cs index 6d25450e67..819ae1ad82 100644 --- a/Applications/AdminApi/src/AdminApi/Extensions/IServiceCollectionExtensions.cs +++ b/Applications/AdminApi/src/AdminApi/Extensions/IServiceCollectionExtensions.cs @@ -10,7 +10,6 @@ using Backbone.Modules.Devices.Application.Devices.Commands.RegisterDevice; using Backbone.Modules.Devices.Application.Devices.DTOs; using FluentValidation; -using FluentValidation.AspNetCore; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.OData; using Microsoft.OData.ModelBuilder; @@ -21,13 +20,9 @@ public static class IServiceCollectionExtensions { public static IServiceCollection AddCustomFluentValidation(this IServiceCollection services) { - services.AddFluentValidationAutoValidation(config => { config.DisableDataAnnotationsValidation = true; }); - ValidatorOptions.Global.DisplayNameResolver = (_, member, _) => member != null ? char.ToLowerInvariant(member.Name[0]) + member.Name[1..] : null; - services.AddValidatorsFromAssemblyContaining(); - return services; } diff --git a/Applications/ConsumerApi/src/Extensions/IServiceCollectionExtensions.cs b/Applications/ConsumerApi/src/Extensions/IServiceCollectionExtensions.cs index 6f4f9d8973..02df710416 100644 --- a/Applications/ConsumerApi/src/Extensions/IServiceCollectionExtensions.cs +++ b/Applications/ConsumerApi/src/Extensions/IServiceCollectionExtensions.cs @@ -12,7 +12,6 @@ using Backbone.Modules.Devices.Infrastructure.Persistence.Database; using Backbone.Modules.Devices.Infrastructure.PushNotifications.Connectors.Sse; using FluentValidation; -using FluentValidation.AspNetCore; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Diagnostics.HealthChecks; @@ -154,13 +153,9 @@ public static IServiceCollection AddCustomOpenIddict(this IServiceCollection ser public static IServiceCollection AddCustomFluentValidation(this IServiceCollection services) { - services.AddFluentValidationAutoValidation(config => { config.DisableDataAnnotationsValidation = true; }); - ValidatorOptions.Global.DisplayNameResolver = (_, member, _) => member != null ? char.ToLowerInvariant(member.Name[0]) + member.Name[1..] : null; - services.AddValidatorsFromAssemblyContaining(); - return services; } diff --git a/Applications/ConsumerApi/src/Mvc/JsonConverters/Challenges/ChallengeIdJsonConverter.cs b/Applications/ConsumerApi/src/Mvc/JsonConverters/Challenges/ChallengeIdJsonConverter.cs deleted file mode 100644 index 3beb60b330..0000000000 --- a/Applications/ConsumerApi/src/Mvc/JsonConverters/Challenges/ChallengeIdJsonConverter.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Text.Json; -using System.Text.Json.Serialization; -using Backbone.BuildingBlocks.Domain; -using Backbone.Modules.Challenges.Domain.Ids; - -namespace Backbone.ConsumerApi.Mvc.JsonConverters.Challenges; - -public class ChallengeIdJsonConverter : JsonConverter -{ - public override bool CanConvert(Type objectType) - { - return objectType == typeof(ChallengeId); - } - - public override ChallengeId Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - var id = reader.GetString() ?? throw new JsonException("The id cannot be null."); - try - { - return ChallengeId.Parse(id); - } - catch (InvalidIdException ex) - { - throw new JsonException(ex.Message); - } - } - - public override void Write(Utf8JsonWriter writer, ChallengeId value, JsonSerializerOptions options) - { - writer.WriteStringValue(value.Value); - } -} diff --git a/Applications/ConsumerApi/src/Mvc/JsonConverters/Files/FileIdJsonConverter.cs b/Applications/ConsumerApi/src/Mvc/JsonConverters/Files/FileIdJsonConverter.cs deleted file mode 100644 index 81ba312c6f..0000000000 --- a/Applications/ConsumerApi/src/Mvc/JsonConverters/Files/FileIdJsonConverter.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Text.Json; -using System.Text.Json.Serialization; -using Backbone.BuildingBlocks.Domain; -using Backbone.Modules.Files.Domain.Entities; - -namespace Backbone.ConsumerApi.Mvc.JsonConverters.Files; - -public class FileIdJsonConverter : JsonConverter -{ - public override bool CanConvert(Type objectType) - { - return objectType == typeof(FileId); - } - - public override FileId Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - var id = reader.GetString() ?? throw new JsonException("The id cannot be null."); - try - { - return FileId.Parse(id); - } - catch (InvalidIdException ex) - { - throw new JsonException(ex.Message); - } - } - - public override void Write(Utf8JsonWriter writer, FileId value, JsonSerializerOptions options) - { - writer.WriteStringValue(value.Value); - } -} diff --git a/Applications/ConsumerApi/src/Mvc/JsonConverters/Messages/FileIdJsonConverter.cs b/Applications/ConsumerApi/src/Mvc/JsonConverters/Messages/FileIdJsonConverter.cs deleted file mode 100644 index f3d80ba5cf..0000000000 --- a/Applications/ConsumerApi/src/Mvc/JsonConverters/Messages/FileIdJsonConverter.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Text.Json; -using System.Text.Json.Serialization; -using Backbone.BuildingBlocks.Domain; -using Backbone.Modules.Messages.Domain.Ids; - -namespace Backbone.ConsumerApi.Mvc.JsonConverters.Messages; - -public class FileIdJsonConverter : JsonConverter -{ - public override bool CanConvert(Type objectType) - { - return objectType == typeof(FileId); - } - - public override FileId Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - var id = reader.GetString() ?? throw new JsonException("The id cannot be null."); - try - { - return FileId.Parse(id); - } - catch (InvalidIdException ex) - { - throw new JsonException(ex.Message); - } - } - - public override void Write(Utf8JsonWriter writer, FileId value, JsonSerializerOptions options) - { - writer.WriteStringValue(value.Value); - } -} diff --git a/Applications/ConsumerApi/src/Mvc/JsonConverters/Messages/MessageIdJsonConverter.cs b/Applications/ConsumerApi/src/Mvc/JsonConverters/Messages/MessageIdJsonConverter.cs deleted file mode 100644 index a62d481879..0000000000 --- a/Applications/ConsumerApi/src/Mvc/JsonConverters/Messages/MessageIdJsonConverter.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Text.Json; -using System.Text.Json.Serialization; -using Backbone.BuildingBlocks.Domain; -using Backbone.Modules.Messages.Domain.Ids; - -namespace Backbone.ConsumerApi.Mvc.JsonConverters.Messages; - -public class MessageIdJsonConverter : JsonConverter -{ - public override bool CanConvert(Type objectType) - { - return objectType == typeof(MessageId); - } - - public override MessageId Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - var id = reader.GetString() ?? throw new JsonException("The id cannot be null."); - try - { - return MessageId.Parse(id); - } - catch (InvalidIdException ex) - { - throw new JsonException(ex.Message); - } - } - - public override void Write(Utf8JsonWriter writer, MessageId value, JsonSerializerOptions options) - { - writer.WriteStringValue(value.Value); - } -} diff --git a/Applications/ConsumerApi/src/Mvc/JsonConverters/Messages/RelationshipIdJsonConverter.cs b/Applications/ConsumerApi/src/Mvc/JsonConverters/Messages/RelationshipIdJsonConverter.cs deleted file mode 100644 index 67f1ff8eaf..0000000000 --- a/Applications/ConsumerApi/src/Mvc/JsonConverters/Messages/RelationshipIdJsonConverter.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Text.Json; -using System.Text.Json.Serialization; -using Backbone.BuildingBlocks.Domain; -using Backbone.Modules.Messages.Domain.Ids; - -namespace Backbone.ConsumerApi.Mvc.JsonConverters.Messages; - -public class RelationshipIdJsonConverter : JsonConverter -{ - public override bool CanConvert(Type objectType) - { - return objectType == typeof(RelationshipId); - } - - public override RelationshipId Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - var id = reader.GetString() ?? throw new JsonException("The id cannot be null."); - try - { - return RelationshipId.Parse(id); - } - catch (InvalidIdException ex) - { - throw new JsonException(ex.Message); - } - } - - public override void Write(Utf8JsonWriter writer, RelationshipId value, JsonSerializerOptions options) - { - writer.WriteStringValue(value.Value); - } -} diff --git a/Applications/ConsumerApi/src/Mvc/JsonConverters/Relationships/RelationshipIdJsonConverter.cs b/Applications/ConsumerApi/src/Mvc/JsonConverters/Relationships/RelationshipIdJsonConverter.cs deleted file mode 100644 index 25739746f4..0000000000 --- a/Applications/ConsumerApi/src/Mvc/JsonConverters/Relationships/RelationshipIdJsonConverter.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Text.Json; -using System.Text.Json.Serialization; -using Backbone.BuildingBlocks.Domain; -using Backbone.Modules.Relationships.Domain.Aggregates.Relationships; - -namespace Backbone.ConsumerApi.Mvc.JsonConverters.Relationships; - -public class RelationshipIdJsonConverter : JsonConverter -{ - public override bool CanConvert(Type objectType) - { - return objectType == typeof(RelationshipId); - } - - public override RelationshipId Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - var id = reader.GetString() ?? throw new JsonException("The id cannot be null."); - try - { - return RelationshipId.Parse(id); - } - catch (InvalidIdException ex) - { - throw new JsonException(ex.Message); - } - } - - public override void Write(Utf8JsonWriter writer, RelationshipId value, JsonSerializerOptions options) - { - writer.WriteStringValue(value.Value); - } -} diff --git a/Applications/ConsumerApi/src/Mvc/JsonConverters/Relationships/RelationshipTemplateIdJsonConverter.cs b/Applications/ConsumerApi/src/Mvc/JsonConverters/Relationships/RelationshipTemplateIdJsonConverter.cs deleted file mode 100644 index 1f2bdd14b8..0000000000 --- a/Applications/ConsumerApi/src/Mvc/JsonConverters/Relationships/RelationshipTemplateIdJsonConverter.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System.Text.Json; -using System.Text.Json.Serialization; -using Backbone.BuildingBlocks.Domain; -using Backbone.Modules.Relationships.Domain.Aggregates.RelationshipTemplates; - -namespace Backbone.ConsumerApi.Mvc.JsonConverters.Relationships; - -public class RelationshipTemplateIdJsonConverter : JsonConverter -{ - public override bool CanConvert(Type objectType) - { - return objectType == typeof(RelationshipTemplateId); - } - - public override RelationshipTemplateId Read(ref Utf8JsonReader reader, Type typeToConvert, - JsonSerializerOptions options) - { - var id = reader.GetString() ?? throw new JsonException("The id cannot be null."); - try - { - return RelationshipTemplateId.Parse(id); - } - catch (InvalidIdException ex) - { - throw new JsonException(ex.Message); - } - } - - public override void Write(Utf8JsonWriter writer, RelationshipTemplateId value, JsonSerializerOptions options) - { - writer.WriteStringValue(value.Value); - } -} diff --git a/Applications/ConsumerApi/src/Mvc/JsonConverters/Synchronization/DatawalletIdJsonConverter.cs b/Applications/ConsumerApi/src/Mvc/JsonConverters/Synchronization/DatawalletIdJsonConverter.cs deleted file mode 100644 index cdfc2c6cbe..0000000000 --- a/Applications/ConsumerApi/src/Mvc/JsonConverters/Synchronization/DatawalletIdJsonConverter.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Text.Json; -using System.Text.Json.Serialization; -using Backbone.BuildingBlocks.Domain; -using Backbone.Modules.Synchronization.Domain.Entities; - -namespace Backbone.ConsumerApi.Mvc.JsonConverters.Synchronization; - -public class DatawalletIdJsonConverter : JsonConverter -{ - public override bool CanConvert(Type objectType) - { - return objectType == typeof(DatawalletId); - } - - public override DatawalletId Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - var id = reader.GetString() ?? throw new JsonException("The id cannot be null."); - try - { - return DatawalletId.Parse(id); - } - catch (InvalidIdException ex) - { - throw new JsonException(ex.Message); - } - } - - public override void Write(Utf8JsonWriter writer, DatawalletId value, JsonSerializerOptions options) - { - writer.WriteStringValue(value.Value); - } -} diff --git a/Applications/ConsumerApi/src/Mvc/JsonConverters/Synchronization/DatawalletModificationIdJsonConverter.cs b/Applications/ConsumerApi/src/Mvc/JsonConverters/Synchronization/DatawalletModificationIdJsonConverter.cs deleted file mode 100644 index d04d865022..0000000000 --- a/Applications/ConsumerApi/src/Mvc/JsonConverters/Synchronization/DatawalletModificationIdJsonConverter.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Text.Json; -using System.Text.Json.Serialization; -using Backbone.BuildingBlocks.Domain; -using Backbone.Modules.Synchronization.Domain.Entities; - -namespace Backbone.ConsumerApi.Mvc.JsonConverters.Synchronization; - -public class DatawalletModificationIdJsonConverter : JsonConverter -{ - public override bool CanConvert(Type objectType) - { - return objectType == typeof(DatawalletModificationId); - } - - public override DatawalletModificationId Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - var id = reader.GetString() ?? throw new JsonException("The id cannot be null."); - try - { - return DatawalletModificationId.Parse(id); - } - catch (InvalidIdException ex) - { - throw new JsonException(ex.Message); - } - } - - public override void Write(Utf8JsonWriter writer, DatawalletModificationId value, JsonSerializerOptions options) - { - writer.WriteStringValue(value.Value); - } -} diff --git a/Applications/ConsumerApi/src/Mvc/JsonConverters/Synchronization/ExternalEventIdJsonConverter.cs b/Applications/ConsumerApi/src/Mvc/JsonConverters/Synchronization/ExternalEventIdJsonConverter.cs deleted file mode 100644 index afaf23e40d..0000000000 --- a/Applications/ConsumerApi/src/Mvc/JsonConverters/Synchronization/ExternalEventIdJsonConverter.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Text.Json; -using System.Text.Json.Serialization; -using Backbone.BuildingBlocks.Domain; -using Backbone.Modules.Synchronization.Domain.Entities.Sync; - -namespace Backbone.ConsumerApi.Mvc.JsonConverters.Synchronization; - -public class ExternalEventIdJsonConverter : JsonConverter -{ - public override bool CanConvert(Type objectType) - { - return objectType == typeof(ExternalEventId); - } - - public override ExternalEventId Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - var id = reader.GetString() ?? throw new JsonException("The id cannot be null."); - try - { - return ExternalEventId.Parse(id); - } - catch (InvalidIdException ex) - { - throw new JsonException(ex.Message); - } - } - - public override void Write(Utf8JsonWriter writer, ExternalEventId value, JsonSerializerOptions options) - { - writer.WriteStringValue(value.Value); - } -} diff --git a/Applications/ConsumerApi/src/Mvc/JsonConverters/Synchronization/SyncErrorIdJsonConverter.cs b/Applications/ConsumerApi/src/Mvc/JsonConverters/Synchronization/SyncErrorIdJsonConverter.cs deleted file mode 100644 index 3f11c4fde7..0000000000 --- a/Applications/ConsumerApi/src/Mvc/JsonConverters/Synchronization/SyncErrorIdJsonConverter.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Text.Json; -using System.Text.Json.Serialization; -using Backbone.BuildingBlocks.Domain; -using Backbone.Modules.Synchronization.Domain.Entities.Sync; - -namespace Backbone.ConsumerApi.Mvc.JsonConverters.Synchronization; - -public class SyncErrorIdJsonConverter : JsonConverter -{ - public override bool CanConvert(Type objectType) - { - return objectType == typeof(SyncErrorId); - } - - public override SyncErrorId Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - var id = reader.GetString() ?? throw new JsonException("The id cannot be null."); - try - { - return SyncErrorId.Parse(id); - } - catch (InvalidIdException ex) - { - throw new JsonException(ex.Message); - } - } - - public override void Write(Utf8JsonWriter writer, SyncErrorId value, JsonSerializerOptions options) - { - writer.WriteStringValue(value.Value); - } -} diff --git a/Applications/ConsumerApi/src/Mvc/JsonConverters/Synchronization/SyncRunIdJsonConverter.cs b/Applications/ConsumerApi/src/Mvc/JsonConverters/Synchronization/SyncRunIdJsonConverter.cs deleted file mode 100644 index 8222c14236..0000000000 --- a/Applications/ConsumerApi/src/Mvc/JsonConverters/Synchronization/SyncRunIdJsonConverter.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Text.Json; -using System.Text.Json.Serialization; -using Backbone.BuildingBlocks.Domain; -using Backbone.Modules.Synchronization.Domain.Entities.Sync; - -namespace Backbone.ConsumerApi.Mvc.JsonConverters.Synchronization; - -public class SyncRunIdJsonConverter : JsonConverter -{ - public override bool CanConvert(Type objectType) - { - return objectType == typeof(SyncRunId); - } - - public override SyncRunId Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - var id = reader.GetString() ?? throw new JsonException("The id cannot be null."); - try - { - return SyncRunId.Parse(id); - } - catch (InvalidIdException ex) - { - throw new JsonException(ex.Message); - } - } - - public override void Write(Utf8JsonWriter writer, SyncRunId value, JsonSerializerOptions options) - { - writer.WriteStringValue(value.Value); - } -} diff --git a/Applications/ConsumerApi/src/Mvc/JsonConverters/Tokens/TokenIdJsonConverter.cs b/Applications/ConsumerApi/src/Mvc/JsonConverters/Tokens/TokenIdJsonConverter.cs deleted file mode 100644 index 4121903309..0000000000 --- a/Applications/ConsumerApi/src/Mvc/JsonConverters/Tokens/TokenIdJsonConverter.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.Text.Json; -using System.Text.Json.Serialization; -using Backbone.BuildingBlocks.Domain; -using Backbone.Modules.Tokens.Domain.Entities; - -namespace Backbone.ConsumerApi.Mvc.JsonConverters.Tokens; - -public class TokenIdJsonConverter : JsonConverter -{ - public override bool CanConvert(Type objectType) - { - return objectType == typeof(TokenId); - } - - public override TokenId Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) - { - var id = reader.GetString() ?? throw new JsonException("The id cannot be null."); - try - { - return TokenId.Parse(id); - } - catch (InvalidIdException ex) - { - throw new JsonException(ex.Message); - } - } - - public override void Write(Utf8JsonWriter writer, TokenId value, JsonSerializerOptions options) - { - writer.WriteStringValue(value.Value); - } -} diff --git a/Backbone.Tests.ArchUnit/StronglyTypedIds.cs b/Backbone.Tests.ArchUnit/StronglyTypedIds.cs new file mode 100644 index 0000000000..55875cf1d9 --- /dev/null +++ b/Backbone.Tests.ArchUnit/StronglyTypedIds.cs @@ -0,0 +1,54 @@ +using ArchUnitNET.Domain; +using ArchUnitNET.Domain.Extensions; +using ArchUnitNET.Fluent.Conditions; +using ArchUnitNET.xUnit; +using Backbone.BuildingBlocks.Domain.StronglyTypedIds.Records; +using MediatR; +using static ArchUnitNET.Fluent.ArchRuleDefinition; + +namespace Backbone.Backbone.Tests.ArchUnit; + +public class StronglyTypedIds +{ + private static readonly IObjectProvider NON_ABSTRACT_CLASSES_IMPLEMENTING_IREQUEST = + Classes() + .That().AreAssignableTo(typeof(IRequest<>)).Or().AreAssignableTo(typeof(IRequest)).As("Classes that implement 'IRequest'") + .And().AreNotAbstract(); + + [Fact] + public void StronglyTypedIdsShouldHaveIsValidMethod() + { + Classes().That().AreAssignableTo(typeof(StronglyTypedId)) + .And().AreNotAbstract() + .Should().FollowCustomCondition(type => + { + var methods = type.GetMethodMembers().ToArray(); + + var isValidMethodExists = methods.Any(m => m.NameStartsWith("IsValid(") && + m.IsStatic == true && + m.Visibility == Visibility.Public && + m.Parameters.Count() == 1 && + m.Parameters.Single().FullName == typeof(string).FullName && + m.ReturnType.FullName == typeof(bool).FullName); + + const string errorMessage = "should have a method with the following signature: 'public static boolean IsValid(string stringValue)'."; + + return new ConditionResult(type, isValidMethodExists, isValidMethodExists ? string.Empty : errorMessage); + }, "should have a static IsValid method with a single parameter of type 'string'.") + .Check(Backbone.ARCHITECTURE); + } + + [Fact] + public void NoStronglyTypedIdsInMediatrCommandsAndQueries() + { + Classes().That().Are(NON_ABSTRACT_CLASSES_IMPLEMENTING_IREQUEST) + .Should().FollowCustomCondition(type => + { + var valueObjectDoesNotExist = !type.GetPropertyMembers().Any(f => f.Type.IsAssignableTo(typeof(StronglyTypedId).FullName)); + const string errorMessage = $"{nameof(type)} should use string instead of value objects "; + + return new ConditionResult(type, valueObjectDoesNotExist, valueObjectDoesNotExist ? string.Empty : errorMessage); + }, "Should use string instead of value objects in Mediatr Commands and Queries.") + .Check(Backbone.ARCHITECTURE); + } +} diff --git a/BuildingBlocks/src/BuildingBlocks.Application.Abstractions/BuildingBlocks.Application.Abstractions.csproj b/BuildingBlocks/src/BuildingBlocks.Application.Abstractions/BuildingBlocks.Application.Abstractions.csproj index ccf3d89271..cca5337d1f 100644 --- a/BuildingBlocks/src/BuildingBlocks.Application.Abstractions/BuildingBlocks.Application.Abstractions.csproj +++ b/BuildingBlocks/src/BuildingBlocks.Application.Abstractions/BuildingBlocks.Application.Abstractions.csproj @@ -1,4 +1,4 @@ - + Enmeshed.BuildingBlocks.Application.Abstractions @@ -10,7 +10,6 @@ - diff --git a/BuildingBlocks/src/BuildingBlocks.Application.Abstractions/Infrastructure/Mapping/IHaveCustomMapping.cs b/BuildingBlocks/src/BuildingBlocks.Application.Abstractions/Infrastructure/Mapping/IHaveCustomMapping.cs deleted file mode 100644 index 0bb471498d..0000000000 --- a/BuildingBlocks/src/BuildingBlocks.Application.Abstractions/Infrastructure/Mapping/IHaveCustomMapping.cs +++ /dev/null @@ -1,8 +0,0 @@ -using AutoMapper; - -namespace Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.Mapping; - -public interface IHaveCustomMapping -{ - void CreateMappings(Profile configuration); -} diff --git a/BuildingBlocks/src/BuildingBlocks.Application.Abstractions/Infrastructure/Mapping/IMapTo.cs b/BuildingBlocks/src/BuildingBlocks.Application.Abstractions/Infrastructure/Mapping/IMapTo.cs deleted file mode 100644 index 3c73141047..0000000000 --- a/BuildingBlocks/src/BuildingBlocks.Application.Abstractions/Infrastructure/Mapping/IMapTo.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.Mapping; - -// ReSharper disable once UnusedTypeParameter -public interface IMapTo; diff --git a/BuildingBlocks/src/BuildingBlocks.Application/AutoMapper/AutoMapperProfileBase.cs b/BuildingBlocks/src/BuildingBlocks.Application/AutoMapper/AutoMapperProfileBase.cs deleted file mode 100644 index bfc178abba..0000000000 --- a/BuildingBlocks/src/BuildingBlocks.Application/AutoMapper/AutoMapperProfileBase.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System.Reflection; -using AutoMapper; - -namespace Backbone.BuildingBlocks.Application.AutoMapper; - -public abstract class AutoMapperProfileBase : Profile -{ - private readonly Assembly _assemblyWithTypes; - - protected AutoMapperProfileBase(Assembly assemblyWithTypes) - { - _assemblyWithTypes = assemblyWithTypes; - - LoadStandardMappings(); - LoadCustomMappings(); - LoadConverters(); - - AllowNullCollections = true; - } - - private void LoadConverters() - { - } - - private void LoadStandardMappings() - { - var mapsFrom = MapperProfileHelper.LoadStandardMappings(_assemblyWithTypes); - - foreach (var map in mapsFrom) CreateMap(map.Source, map.Destination).ReverseMap(); - } - - private void LoadCustomMappings() - { - var mapsFrom = MapperProfileHelper.LoadCustomMappings(_assemblyWithTypes); - - foreach (var map in mapsFrom) map.CreateMappings(this); - } -} diff --git a/BuildingBlocks/src/BuildingBlocks.Application/AutoMapper/MapperProfileHelper.cs b/BuildingBlocks/src/BuildingBlocks.Application/AutoMapper/MapperProfileHelper.cs deleted file mode 100644 index c177457c18..0000000000 --- a/BuildingBlocks/src/BuildingBlocks.Application/AutoMapper/MapperProfileHelper.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System.Reflection; -using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.Mapping; - -namespace Backbone.BuildingBlocks.Application.AutoMapper; - -internal static class MapperProfileHelper -{ - public static IEnumerable LoadStandardMappings(Assembly rootAssembly) - { - var types = rootAssembly.GetExportedTypes(); - - var mapsFrom = ( - from type in types - from @interface in type.GetInterfaces() - where - @interface.IsGenericType && @interface.GetGenericTypeDefinition() == typeof(IMapTo<>) && - !type.IsAbstract && - !type.IsInterface - select new Map(@interface.GetGenericArguments().First(), type)).ToList(); - - return mapsFrom; - } - - public static IEnumerable LoadCustomMappings(Assembly rootAssembly) - { - var types = rootAssembly.GetExportedTypes(); - - var mapsFrom = ( - from type in types - from @interface in type.GetInterfaces() - where - typeof(IHaveCustomMapping).IsAssignableFrom(@interface) && - !type.IsAbstract && - !type.IsInterface - select (IHaveCustomMapping)Activator.CreateInstance(type)!).ToList(); - - return mapsFrom; - } -} - -public sealed class Map -{ - public Map(Type source, Type destination) - { - Source = source; - Destination = destination; - } - - public Type Source { get; set; } - public Type Destination { get; set; } -} diff --git a/BuildingBlocks/src/BuildingBlocks.Application/Extensions/ValidatorExtensions.cs b/BuildingBlocks/src/BuildingBlocks.Application/Extensions/ValidatorExtensions.cs new file mode 100644 index 0000000000..026122663b --- /dev/null +++ b/BuildingBlocks/src/BuildingBlocks.Application/Extensions/ValidatorExtensions.cs @@ -0,0 +1,36 @@ +using System.Collections.Concurrent; +using System.Reflection; +using Backbone.BuildingBlocks.Application.Abstractions.Exceptions; +using Backbone.BuildingBlocks.Application.FluentValidation; +using Backbone.BuildingBlocks.Domain.StronglyTypedIds.Records; +using FluentValidation; + +namespace Backbone.BuildingBlocks.Application.Extensions; + +public static class ValidatorExtensions +{ + private static readonly ConcurrentDictionary IS_VALID_CACHE = new(); + + public static IRuleBuilderOptions In(this IRuleBuilder ruleBuilder, + params TProperty[] validOptions) + { + return ruleBuilder + .SetValidator(new ValueInValidator(validOptions)) + .WithErrorCode(GenericApplicationErrors.Validation.InvalidPropertyValue().Code); + } + + public static IRuleBuilderOptions ValidId(this IRuleBuilder ruleBuilder) where TId : StronglyTypedId + { + if (!IS_VALID_CACHE.TryGetValue(typeof(TId), out var method)) + { + method = typeof(TId).GetMethod("IsValid", BindingFlags.Public | BindingFlags.Static) ?? + throw new Exception($"Type '{typeof(TId)}' does not implement required 'IsValid' method."); + IS_VALID_CACHE.TryAdd(typeof(TId), method); + } + + return ruleBuilder + .Must(x => (bool)method.Invoke(null, [x])!) + .WithErrorCode(GenericApplicationErrors.Validation.InvalidPropertyValue().Code) + .WithMessage("The ID is not valid. Check length, prefix and the used characters."); + } +} diff --git a/BuildingBlocks/src/BuildingBlocks.Application/FluentValidation/ValueInValidator.cs b/BuildingBlocks/src/BuildingBlocks.Application/FluentValidation/ValueInValidator.cs index c7004b955e..a3af8c11df 100644 --- a/BuildingBlocks/src/BuildingBlocks.Application/FluentValidation/ValueInValidator.cs +++ b/BuildingBlocks/src/BuildingBlocks.Application/FluentValidation/ValueInValidator.cs @@ -1,5 +1,4 @@ using System.Collections; -using Backbone.BuildingBlocks.Application.Abstractions.Exceptions; using FluentValidation; using FluentValidation.Validators; @@ -56,14 +55,3 @@ protected override string GetDefaultMessageTemplate(string errorCode) return "'{PropertyName}' must have one of the following values: {ValidValues}"; } } - -public static class ValidatorExtensions -{ - public static IRuleBuilderOptions In(this IRuleBuilder ruleBuilder, - params TProperty[] validOptions) - { - return ruleBuilder - .SetValidator(new ValueInValidator(validOptions)) - .WithErrorCode(GenericApplicationErrors.Validation.InvalidPropertyValue().Code); - } -} diff --git a/BuildingBlocks/src/UnitTestTools/FluentValidation/Extensions.cs b/BuildingBlocks/src/UnitTestTools/FluentValidation/Extensions.cs index 55608b956d..053f4de543 100644 --- a/BuildingBlocks/src/UnitTestTools/FluentValidation/Extensions.cs +++ b/BuildingBlocks/src/UnitTestTools/FluentValidation/Extensions.cs @@ -1,6 +1,8 @@ using System.Text.RegularExpressions; +using FluentAssertions; using FluentValidation; using FluentValidation.Results; +using FluentValidation.TestHelper; using Xunit.Sdk; namespace Backbone.UnitTestTools.FluentValidation; @@ -31,3 +33,33 @@ public static IEnumerable ShouldHaveValidationErrorForItemWit return validationResult.Errors; } } + +public static class ValidationTestExtensions +{ + public static void ShouldHaveValidationErrorForItem(this TestValidationResult testValidationResult, string propertyName, string expectedErrorCode, string expectedErrorMessage) + { + var errorsForProperty = testValidationResult.ShouldHaveValidationErrorFor(propertyName); + errorsForProperty.Should().Contain(r => r.ErrorCode == expectedErrorCode && r.ErrorMessage == expectedErrorMessage); + } + + public static void ShouldHaveValidationErrorForItemInCollection(this TestValidationResult testValidationResult, string collectionWithInvalidId, int indexWithInvalidId, + string expectedErrorCode, string expectedErrorMessage) + { + var errorsForProperty = testValidationResult.ShouldHaveValidationErrorFor($"{collectionWithInvalidId}[{indexWithInvalidId}]"); + errorsForProperty.Should().Contain(r => r.ErrorCode == expectedErrorCode && r.ErrorMessage == expectedErrorMessage); + } + + public static void ShouldHaveValidationErrorForId(this TestValidationResult testValidationResult, string propertyWithInvalidId) + { + var errorsForProperty = testValidationResult.ShouldHaveValidationErrorFor(propertyWithInvalidId); + errorsForProperty.Should().Contain(r => + r.ErrorCode == "error.platform.validation.invalidPropertyValue" && r.ErrorMessage == "The ID is not valid. Check length, prefix and the used characters."); + } + + public static void ShouldHaveValidationErrorForIdInCollection(this TestValidationResult testValidationResult, string collectionWithInvalidId, int indexWithInvalidId) + { + var errorsForProperty = testValidationResult.ShouldHaveValidationErrorFor($"{collectionWithInvalidId}[{indexWithInvalidId}]"); + errorsForProperty.Should().Contain(r => + r.ErrorCode == "error.platform.validation.invalidPropertyValue" && r.ErrorMessage == "The ID is not valid. Check length, prefix and the used characters."); + } +} diff --git a/BuildingBlocks/test/BuildingBlocks.Application.Tests/FluentValidation/ValueInValidatorTests.cs b/BuildingBlocks/test/BuildingBlocks.Application.Tests/FluentValidation/ValueInValidatorTests.cs index b94bb80ee0..4fb1cc564c 100644 --- a/BuildingBlocks/test/BuildingBlocks.Application.Tests/FluentValidation/ValueInValidatorTests.cs +++ b/BuildingBlocks/test/BuildingBlocks.Application.Tests/FluentValidation/ValueInValidatorTests.cs @@ -1,4 +1,4 @@ -using Backbone.BuildingBlocks.Application.FluentValidation; +using Backbone.BuildingBlocks.Application.Extensions; using Backbone.UnitTestTools.BaseClasses; using FluentAssertions; using FluentValidation; diff --git a/Modules/Challenges/src/Challenges.Application/AutoMapper/AutoMapperProfile.cs b/Modules/Challenges/src/Challenges.Application/AutoMapper/AutoMapperProfile.cs deleted file mode 100644 index 1401d17f2b..0000000000 --- a/Modules/Challenges/src/Challenges.Application/AutoMapper/AutoMapperProfile.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Reflection; -using AutoMapper; -using Backbone.BuildingBlocks.Application.AutoMapper; - -namespace Backbone.Modules.Challenges.Application.AutoMapper; - -public class AutoMapperProfile : AutoMapperProfileBase -{ - public AutoMapperProfile() : base(Assembly.GetExecutingAssembly()) { } - - public static IMapper CreateMapper() - { - var profile = new AutoMapperProfile(); - var config = new MapperConfiguration(cfg => cfg.AddProfile(profile)); - var mapper = config.CreateMapper(); - return mapper; - } -} diff --git a/Modules/Challenges/src/Challenges.Application/Challenges/Commands/DeleteChallengesOfIdentity/DeleteChallengesOfIdentityCommand.cs b/Modules/Challenges/src/Challenges.Application/Challenges/Commands/DeleteChallengesOfIdentity/DeleteChallengesOfIdentityCommand.cs index 81bc2ff190..6831fb2d91 100644 --- a/Modules/Challenges/src/Challenges.Application/Challenges/Commands/DeleteChallengesOfIdentity/DeleteChallengesOfIdentityCommand.cs +++ b/Modules/Challenges/src/Challenges.Application/Challenges/Commands/DeleteChallengesOfIdentity/DeleteChallengesOfIdentityCommand.cs @@ -1,14 +1,13 @@ -using Backbone.DevelopmentKit.Identity.ValueObjects; -using MediatR; +using MediatR; namespace Backbone.Modules.Challenges.Application.Challenges.Commands.DeleteChallengesOfIdentity; public class DeleteChallengesOfIdentityCommand : IRequest { - public DeleteChallengesOfIdentityCommand(IdentityAddress identityAddress) + public DeleteChallengesOfIdentityCommand(string identityAddress) { IdentityAddress = identityAddress; } - public IdentityAddress IdentityAddress { get; set; } + public string IdentityAddress { get; set; } } diff --git a/Modules/Challenges/src/Challenges.Application/Challenges/Commands/DeleteChallengesOfIdentity/Validator.cs b/Modules/Challenges/src/Challenges.Application/Challenges/Commands/DeleteChallengesOfIdentity/Validator.cs index 67a3ad0d4c..814f924bd8 100644 --- a/Modules/Challenges/src/Challenges.Application/Challenges/Commands/DeleteChallengesOfIdentity/Validator.cs +++ b/Modules/Challenges/src/Challenges.Application/Challenges/Commands/DeleteChallengesOfIdentity/Validator.cs @@ -1,8 +1,13 @@ -using Backbone.DevelopmentKit.Identity.ValueObjects; +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.DevelopmentKit.Identity.ValueObjects; using FluentValidation; namespace Backbone.Modules.Challenges.Application.Challenges.Commands.DeleteChallengesOfIdentity; + public class Validator : AbstractValidator { - public Validator() => RuleFor(x => x.IdentityAddress).Must(x => IdentityAddress.IsValid(x)); + public Validator() + { + RuleFor(x => x.IdentityAddress).ValidId(); + } } diff --git a/Modules/Challenges/src/Challenges.Application/Challenges/Queries/GetChallengeById/GetChallengeByIdQuery.cs b/Modules/Challenges/src/Challenges.Application/Challenges/Queries/GetChallengeById/GetChallengeByIdQuery.cs index 066fdc57a4..a271bba697 100644 --- a/Modules/Challenges/src/Challenges.Application/Challenges/Queries/GetChallengeById/GetChallengeByIdQuery.cs +++ b/Modules/Challenges/src/Challenges.Application/Challenges/Queries/GetChallengeById/GetChallengeByIdQuery.cs @@ -1,10 +1,9 @@ using Backbone.Modules.Challenges.Application.Challenges.DTOs; -using Backbone.Modules.Challenges.Domain.Ids; using MediatR; namespace Backbone.Modules.Challenges.Application.Challenges.Queries.GetChallengeById; public class GetChallengeByIdQuery : IRequest { - public required ChallengeId Id { get; set; } + public required string Id { get; set; } } diff --git a/Modules/Challenges/src/Challenges.Application/Challenges/Queries/GetChallengeById/Handler.cs b/Modules/Challenges/src/Challenges.Application/Challenges/Queries/GetChallengeById/Handler.cs index 05a26dcc13..91c9624d19 100644 --- a/Modules/Challenges/src/Challenges.Application/Challenges/Queries/GetChallengeById/Handler.cs +++ b/Modules/Challenges/src/Challenges.Application/Challenges/Queries/GetChallengeById/Handler.cs @@ -1,6 +1,7 @@ using Backbone.BuildingBlocks.Application.Abstractions.Exceptions; using Backbone.Modules.Challenges.Application.Challenges.DTOs; using Backbone.Modules.Challenges.Application.Infrastructure.Persistence.Repository; +using Backbone.Modules.Challenges.Domain.Ids; using MediatR; namespace Backbone.Modules.Challenges.Application.Challenges.Queries.GetChallengeById; @@ -16,7 +17,7 @@ public Handler(IChallengesRepository challengesRepository) public async Task Handle(GetChallengeByIdQuery request, CancellationToken cancellationToken) { - var challenge = await _challengesRepository.Find(request.Id, cancellationToken); + var challenge = await _challengesRepository.Find(ChallengeId.Parse(request.Id), cancellationToken); if (challenge.IsExpired()) { diff --git a/Modules/Challenges/src/Challenges.Application/Challenges/Queries/GetChallengeById/Validator.cs b/Modules/Challenges/src/Challenges.Application/Challenges/Queries/GetChallengeById/Validator.cs new file mode 100644 index 0000000000..eb3fa18332 --- /dev/null +++ b/Modules/Challenges/src/Challenges.Application/Challenges/Queries/GetChallengeById/Validator.cs @@ -0,0 +1,13 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.Modules.Challenges.Domain.Ids; +using FluentValidation; + +namespace Backbone.Modules.Challenges.Application.Challenges.Queries.GetChallengeById; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleFor(x => x.Id).ValidId(); + } +} diff --git a/Modules/Challenges/src/Challenges.Application/Extensions/ApplicationServiceCollectionExtensions.cs b/Modules/Challenges/src/Challenges.Application/Extensions/ApplicationServiceCollectionExtensions.cs index 8515e26d1d..26a8aa0450 100644 --- a/Modules/Challenges/src/Challenges.Application/Extensions/ApplicationServiceCollectionExtensions.cs +++ b/Modules/Challenges/src/Challenges.Application/Extensions/ApplicationServiceCollectionExtensions.cs @@ -1,6 +1,5 @@ using Backbone.BuildingBlocks.Application.Abstractions.Exceptions; using Backbone.BuildingBlocks.Application.MediatR; -using Backbone.Modules.Challenges.Application.AutoMapper; using Backbone.Modules.Challenges.Application.Challenges.Commands.CreateChallenge; using FluentValidation; using MediatR; @@ -19,7 +18,6 @@ public static void AddApplication(this IServiceCollection services) .AddOpenBehavior(typeof(RequestValidationBehavior<,>)) .AddOpenBehavior(typeof(QuotaEnforcerBehavior<,>)) ); - services.AddAutoMapper(typeof(AutoMapperProfile).Assembly); services.AddValidatorsFromAssembly(typeof(CreateChallengeCommandValidator).Assembly); } } diff --git a/Modules/Challenges/test/Challenges.Application.Tests/Tests/Challenges/Commands/DeleteChallengesOfIdentity/ValidatorTests.cs b/Modules/Challenges/test/Challenges.Application.Tests/Tests/Challenges/Commands/DeleteChallengesOfIdentity/ValidatorTests.cs new file mode 100644 index 0000000000..bf34df6923 --- /dev/null +++ b/Modules/Challenges/test/Challenges.Application.Tests/Tests/Challenges/Commands/DeleteChallengesOfIdentity/ValidatorTests.cs @@ -0,0 +1,37 @@ +using Backbone.Modules.Challenges.Application.Challenges.Commands.DeleteChallengesOfIdentity; +using Backbone.UnitTestTools.BaseClasses; +using Backbone.UnitTestTools.Data; +using Backbone.UnitTestTools.FluentValidation; +using FluentValidation.TestHelper; +using Xunit; + +namespace Backbone.Modules.Challenges.Application.Tests.Tests.Challenges.Commands.DeleteChallengesOfIdentity; + +public class ValidatorTests : AbstractTestsBase +{ + [Fact] + public void Happy_path() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new DeleteChallengesOfIdentityCommand(TestDataGenerator.CreateRandomIdentityAddress())); + + // Assert + validationResult.ShouldNotHaveAnyValidationErrors(); + } + + [Fact] + public void Fails_when_identity_address_is_invalid() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new DeleteChallengesOfIdentityCommand("invalid-identity-address")); + + // Assert + validationResult.ShouldHaveValidationErrorForId(nameof(DeleteChallengesOfIdentityCommand.IdentityAddress)); + } +} diff --git a/Modules/Challenges/test/Challenges.Application.Tests/Tests/Challenges/Queries/GetChallengeById/ValidatorTests.cs b/Modules/Challenges/test/Challenges.Application.Tests/Tests/Challenges/Queries/GetChallengeById/ValidatorTests.cs new file mode 100644 index 0000000000..896790be85 --- /dev/null +++ b/Modules/Challenges/test/Challenges.Application.Tests/Tests/Challenges/Queries/GetChallengeById/ValidatorTests.cs @@ -0,0 +1,38 @@ +using Backbone.Modules.Challenges.Application.Challenges.Queries.GetChallengeById; +using Backbone.Modules.Challenges.Domain.Ids; +using Backbone.UnitTestTools.BaseClasses; +using Backbone.UnitTestTools.FluentValidation; +using FluentValidation.TestHelper; +using Xunit; +using Validator = Backbone.Modules.Challenges.Application.Challenges.Queries.GetChallengeById.Validator; + +namespace Backbone.Modules.Challenges.Application.Tests.Tests.Challenges.Queries.GetChallengeById; + +public class ValidatorTests : AbstractTestsBase +{ + [Fact] + public void Happy_path() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new GetChallengeByIdQuery { Id = ChallengeId.New() }); + + // Assert + validationResult.ShouldNotHaveAnyValidationErrors(); + } + + [Fact] + public void Fails_when_challenge_id_is_invalid() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new GetChallengeByIdQuery { Id = "some-invalid-challenge-id" }); + + // Assert + validationResult.ShouldHaveValidationErrorForId(nameof(GetChallengeByIdQuery.Id)); + } +} diff --git a/Modules/Devices/src/Devices.Application/AutoMapper/AutoMapperProfile.cs b/Modules/Devices/src/Devices.Application/AutoMapper/AutoMapperProfile.cs deleted file mode 100644 index b55b7a5bd1..0000000000 --- a/Modules/Devices/src/Devices.Application/AutoMapper/AutoMapperProfile.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Reflection; -using AutoMapper; -using Backbone.BuildingBlocks.Application.AutoMapper; - -namespace Backbone.Modules.Devices.Application.AutoMapper; - -public class AutoMapperProfile : AutoMapperProfileBase -{ - public AutoMapperProfile() : base(Assembly.GetExecutingAssembly()) { } - - public static IMapper CreateMapper() - { - var profile = new AutoMapperProfile(); - var config = new MapperConfiguration(cfg => { cfg.AddProfile(profile); }); - var mapper = config.CreateMapper(); - return mapper; - } -} diff --git a/Modules/Devices/src/Devices.Application/Clients/Commands/ChangeClientSecret/ChangeClientSecretCommandValidator.cs b/Modules/Devices/src/Devices.Application/Clients/Commands/ChangeClientSecret/Validator.cs similarity index 62% rename from Modules/Devices/src/Devices.Application/Clients/Commands/ChangeClientSecret/ChangeClientSecretCommandValidator.cs rename to Modules/Devices/src/Devices.Application/Clients/Commands/ChangeClientSecret/Validator.cs index 5bc565add3..b88555cd0e 100644 --- a/Modules/Devices/src/Devices.Application/Clients/Commands/ChangeClientSecret/ChangeClientSecretCommandValidator.cs +++ b/Modules/Devices/src/Devices.Application/Clients/Commands/ChangeClientSecret/Validator.cs @@ -2,9 +2,10 @@ using FluentValidation; namespace Backbone.Modules.Devices.Application.Clients.Commands.ChangeClientSecret; -public class ChangeClientSecretCommandValidator : AbstractValidator + +public class Validator : AbstractValidator { - public ChangeClientSecretCommandValidator() + public Validator() { RuleFor(c => c.ClientId).DetailedNotEmpty(); } diff --git a/Modules/Devices/src/Devices.Application/Clients/Commands/CreateClient/CreateClientCommandValidator.cs b/Modules/Devices/src/Devices.Application/Clients/Commands/CreateClient/Validator.cs similarity index 99% rename from Modules/Devices/src/Devices.Application/Clients/Commands/CreateClient/CreateClientCommandValidator.cs rename to Modules/Devices/src/Devices.Application/Clients/Commands/CreateClient/Validator.cs index 6d773b26c9..99ac37da1f 100644 --- a/Modules/Devices/src/Devices.Application/Clients/Commands/CreateClient/CreateClientCommandValidator.cs +++ b/Modules/Devices/src/Devices.Application/Clients/Commands/CreateClient/Validator.cs @@ -2,6 +2,7 @@ using FluentValidation; namespace Backbone.Modules.Devices.Application.Clients.Commands.CreateClient; + public class CreateClientCommandValidator : AbstractValidator { public CreateClientCommandValidator() diff --git a/Modules/Devices/src/Devices.Application/Clients/Commands/DeleteClient/DeleteClientCommandValidator.cs b/Modules/Devices/src/Devices.Application/Clients/Commands/DeleteClient/Validator.cs similarity index 100% rename from Modules/Devices/src/Devices.Application/Clients/Commands/DeleteClient/DeleteClientCommandValidator.cs rename to Modules/Devices/src/Devices.Application/Clients/Commands/DeleteClient/Validator.cs diff --git a/Modules/Devices/src/Devices.Application/Clients/Commands/UpdateClient/UpdateClientCommandValidator.cs b/Modules/Devices/src/Devices.Application/Clients/Commands/UpdateClient/Validator.cs similarity index 99% rename from Modules/Devices/src/Devices.Application/Clients/Commands/UpdateClient/UpdateClientCommandValidator.cs rename to Modules/Devices/src/Devices.Application/Clients/Commands/UpdateClient/Validator.cs index 3e161d3333..eb8a622ca8 100644 --- a/Modules/Devices/src/Devices.Application/Clients/Commands/UpdateClient/UpdateClientCommandValidator.cs +++ b/Modules/Devices/src/Devices.Application/Clients/Commands/UpdateClient/Validator.cs @@ -2,6 +2,7 @@ using FluentValidation; namespace Backbone.Modules.Devices.Application.Clients.Commands.UpdateClient; + public class UpdateClientCommandValidator : AbstractValidator { public UpdateClientCommandValidator() diff --git a/Modules/Devices/src/Devices.Application/Clients/DTOs/ClientDTO.cs b/Modules/Devices/src/Devices.Application/Clients/DTOs/ClientDTO.cs index f6dd28e784..a8e4e50105 100644 --- a/Modules/Devices/src/Devices.Application/Clients/DTOs/ClientDTO.cs +++ b/Modules/Devices/src/Devices.Application/Clients/DTOs/ClientDTO.cs @@ -1,6 +1,7 @@ using Backbone.Modules.Devices.Domain.Entities; namespace Backbone.Modules.Devices.Application.Clients.DTOs; + public class ClientDTO { public ClientDTO(OAuthClient client, int numberOfIdentities) diff --git a/Modules/Devices/src/Devices.Application/Clients/Queries/GetClient/Handler.cs b/Modules/Devices/src/Devices.Application/Clients/Queries/GetClient/Handler.cs index 700037be4c..f0e6b23fe8 100644 --- a/Modules/Devices/src/Devices.Application/Clients/Queries/GetClient/Handler.cs +++ b/Modules/Devices/src/Devices.Application/Clients/Queries/GetClient/Handler.cs @@ -5,6 +5,7 @@ using MediatR; namespace Backbone.Modules.Devices.Application.Clients.Queries.GetClient; + public class Handler : IRequestHandler { private readonly IOAuthClientsRepository _oAuthClientsRepository; diff --git a/Modules/Devices/src/Devices.Application/Clients/Queries/ListClients/Handler.cs b/Modules/Devices/src/Devices.Application/Clients/Queries/ListClients/Handler.cs index 3520a566e8..7b72cf9a8a 100644 --- a/Modules/Devices/src/Devices.Application/Clients/Queries/ListClients/Handler.cs +++ b/Modules/Devices/src/Devices.Application/Clients/Queries/ListClients/Handler.cs @@ -1,4 +1,3 @@ -using Backbone.Modules.Devices.Application.Clients.DTOs; using Backbone.Modules.Devices.Application.Infrastructure.Persistence.Repository; using MediatR; @@ -12,6 +11,7 @@ public Handler(IOAuthClientsRepository oAuthClientsRepository) { _oAuthClientsRepository = oAuthClientsRepository; } + public async Task Handle(ListClientsQuery request, CancellationToken cancellationToken) { var clients = (await _oAuthClientsRepository.FindAll(cancellationToken)).ToList(); @@ -19,6 +19,6 @@ public async Task Handle(ListClientsQuery request, Cancella var clientIds = clients.Select(c => c.ClientId).ToList(); var numberOfIdentitiesByClient = await _oAuthClientsRepository.CountIdentities(clientIds, cancellationToken); - return new ListClientsResponse(clients.Select(client => new ClientDTO(client, numberOfIdentitiesByClient[client.ClientId])).ToList()); + return new ListClientsResponse(clients, numberOfIdentitiesByClient); } } diff --git a/Modules/Devices/src/Devices.Application/Clients/Queries/ListClients/ListClientsResponse.cs b/Modules/Devices/src/Devices.Application/Clients/Queries/ListClients/ListClientsResponse.cs index cf6fa5e159..7894e11b7a 100644 --- a/Modules/Devices/src/Devices.Application/Clients/Queries/ListClients/ListClientsResponse.cs +++ b/Modules/Devices/src/Devices.Application/Clients/Queries/ListClients/ListClientsResponse.cs @@ -1,8 +1,13 @@ using Backbone.BuildingBlocks.Application.CQRS.BaseClasses; using Backbone.Modules.Devices.Application.Clients.DTOs; +using Backbone.Modules.Devices.Domain.Entities; namespace Backbone.Modules.Devices.Application.Clients.Queries.ListClients; + public class ListClientsResponse : CollectionResponseBase { - public ListClientsResponse(IEnumerable items) : base(items) { } + public ListClientsResponse(IEnumerable clients, IReadOnlyDictionary numberOfIdentitiesByClient) : base(clients.Select(client => + new ClientDTO(client, numberOfIdentitiesByClient[client.ClientId]))) + { + } } diff --git a/Modules/Devices/src/Devices.Application/DTOs/IdentityDeletionProcessOverviewDTO.cs b/Modules/Devices/src/Devices.Application/DTOs/IdentityDeletionProcessOverviewDTO.cs index 4771fa0382..59c5603406 100644 --- a/Modules/Devices/src/Devices.Application/DTOs/IdentityDeletionProcessOverviewDTO.cs +++ b/Modules/Devices/src/Devices.Application/DTOs/IdentityDeletionProcessOverviewDTO.cs @@ -1,4 +1,3 @@ -using Backbone.DevelopmentKit.Identity.ValueObjects; using Backbone.Modules.Devices.Domain.Entities.Identities; namespace Backbone.Modules.Devices.Application.DTOs; @@ -17,7 +16,7 @@ public IdentityDeletionProcessOverviewDTO(IdentityDeletionProcess process) ApprovalReminder3SentAt = process.ApprovalReminder3SentAt; ApprovedAt = process.ApprovedAt; - ApprovedByDevice = process.ApprovedByDevice; + ApprovedByDevice = process.ApprovedByDevice?.Value; GracePeriodEndsAt = process.GracePeriodEndsAt; @@ -36,7 +35,7 @@ public IdentityDeletionProcessOverviewDTO(IdentityDeletionProcess process) public DateTime? ApprovalReminder3SentAt { get; set; } public DateTime? ApprovedAt { get; set; } - public DeviceId? ApprovedByDevice { get; set; } + public string? ApprovedByDevice { get; set; } public DateTime? GracePeriodEndsAt { get; set; } diff --git a/Modules/Devices/src/Devices.Application/DTOs/IdentitySummaryDTO.cs b/Modules/Devices/src/Devices.Application/DTOs/IdentitySummaryDTO.cs index 2354585c44..e0f99c99a4 100644 --- a/Modules/Devices/src/Devices.Application/DTOs/IdentitySummaryDTO.cs +++ b/Modules/Devices/src/Devices.Application/DTOs/IdentitySummaryDTO.cs @@ -14,15 +14,7 @@ public IdentitySummaryDTO(Identity identity) CreatedAt = identity.CreatedAt; Status = identity.Status; - Devices = identity.Devices.Select(d => new DeviceDTO - { - CreatedAt = d.CreatedAt, - CreatedByDevice = d.CreatedByDevice, - Id = d.Id, - LastLogin = new LastLoginInformation { Time = d.User.LastLoginAt }, - Username = d.User.UserName!, - CommunicationLanguage = d.CommunicationLanguage - }); + Devices = identity.Devices.Select(d => new DeviceDTO(d)); NumberOfDevices = identity.Devices.Count; IdentityVersion = identity.IdentityVersion; diff --git a/Modules/Devices/src/Devices.Application/Devices/Commands/ChangePassword/ChangePasswordCommandValidator.cs b/Modules/Devices/src/Devices.Application/Devices/Commands/ChangePassword/Validator.cs similarity index 72% rename from Modules/Devices/src/Devices.Application/Devices/Commands/ChangePassword/ChangePasswordCommandValidator.cs rename to Modules/Devices/src/Devices.Application/Devices/Commands/ChangePassword/Validator.cs index b134592ac1..93cd8083ca 100644 --- a/Modules/Devices/src/Devices.Application/Devices/Commands/ChangePassword/ChangePasswordCommandValidator.cs +++ b/Modules/Devices/src/Devices.Application/Devices/Commands/ChangePassword/Validator.cs @@ -4,9 +4,9 @@ namespace Backbone.Modules.Devices.Application.Devices.Commands.ChangePassword; // ReSharper disable once UnusedMember.Global -public class ChangePasswordCommandValidator : AbstractValidator +public class Validator : AbstractValidator { - public ChangePasswordCommandValidator() + public Validator() { RuleFor(c => c.OldPassword).DetailedNotEmpty(); RuleFor(c => c.NewPassword).DetailedNotEmpty(); diff --git a/Modules/Devices/src/Devices.Application/Devices/Commands/DeleteDevice/DeleteDeviceValidator.cs b/Modules/Devices/src/Devices.Application/Devices/Commands/DeleteDevice/DeleteDeviceValidator.cs deleted file mode 100644 index 61a989b256..0000000000 --- a/Modules/Devices/src/Devices.Application/Devices/Commands/DeleteDevice/DeleteDeviceValidator.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Backbone.BuildingBlocks.Application.FluentValidation; -using FluentValidation; - -namespace Backbone.Modules.Devices.Application.Devices.Commands.DeleteDevice; - -// ReSharper disable once UnusedMember.Global -public class DeleteDeviceValidator : AbstractValidator -{ - public DeleteDeviceValidator() - { - RuleFor(c => c.DeviceId).DetailedNotEmpty(); - } -} diff --git a/Modules/Devices/src/Devices.Application/Devices/Commands/DeleteDevice/Validator.cs b/Modules/Devices/src/Devices.Application/Devices/Commands/DeleteDevice/Validator.cs new file mode 100644 index 0000000000..a99ffeb698 --- /dev/null +++ b/Modules/Devices/src/Devices.Application/Devices/Commands/DeleteDevice/Validator.cs @@ -0,0 +1,14 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.DevelopmentKit.Identity.ValueObjects; +using FluentValidation; + +namespace Backbone.Modules.Devices.Application.Devices.Commands.DeleteDevice; + +// ReSharper disable once UnusedMember.Global +public class Validator : AbstractValidator +{ + public Validator() + { + RuleFor(c => c.DeviceId).ValidId(); + } +} diff --git a/Modules/Devices/src/Devices.Application/Devices/Commands/RegisterDevice/Handler.cs b/Modules/Devices/src/Devices.Application/Devices/Commands/RegisterDevice/Handler.cs index 1d209ddd9d..8a8dd35121 100644 --- a/Modules/Devices/src/Devices.Application/Devices/Commands/RegisterDevice/Handler.cs +++ b/Modules/Devices/src/Devices.Application/Devices/Commands/RegisterDevice/Handler.cs @@ -46,13 +46,7 @@ public async Task Handle(RegisterDeviceCommand command, _logger.CreatedDevice(); - return new RegisterDeviceResponse - { - Id = user.DeviceId, - Username = user.UserName!, - CreatedByDevice = user.Device.CreatedByDevice, - CreatedAt = user.Device.CreatedAt - }; + return new RegisterDeviceResponse(user); } } diff --git a/Modules/Devices/src/Devices.Application/Devices/Commands/RegisterDevice/RegisterDeviceResponse.cs b/Modules/Devices/src/Devices.Application/Devices/Commands/RegisterDevice/RegisterDeviceResponse.cs index 5e12db88bf..2775faedc7 100644 --- a/Modules/Devices/src/Devices.Application/Devices/Commands/RegisterDevice/RegisterDeviceResponse.cs +++ b/Modules/Devices/src/Devices.Application/Devices/Commands/RegisterDevice/RegisterDeviceResponse.cs @@ -1,11 +1,19 @@ -using Backbone.DevelopmentKit.Identity.ValueObjects; +using Backbone.Modules.Devices.Domain.Entities.Identities; namespace Backbone.Modules.Devices.Application.Devices.Commands.RegisterDevice; public class RegisterDeviceResponse { - public required DeviceId Id { get; set; } - public required string Username { get; set; } - public required DateTime CreatedAt { get; set; } - public required DeviceId CreatedByDevice { get; set; } + public RegisterDeviceResponse(ApplicationUser user) + { + Id = user.DeviceId; + Username = user.UserName!; + CreatedByDevice = user.Device.CreatedByDevice; + CreatedAt = user.Device.CreatedAt; + } + + public string Id { get; set; } + public string Username { get; set; } + public DateTime CreatedAt { get; set; } + public string CreatedByDevice { get; set; } } diff --git a/Modules/Devices/src/Devices.Application/Devices/Commands/RegisterDevice/RegisterDeviceCommandValidator.cs b/Modules/Devices/src/Devices.Application/Devices/Commands/RegisterDevice/Validator.cs similarity index 100% rename from Modules/Devices/src/Devices.Application/Devices/Commands/RegisterDevice/RegisterDeviceCommandValidator.cs rename to Modules/Devices/src/Devices.Application/Devices/Commands/RegisterDevice/Validator.cs diff --git a/Modules/Devices/src/Devices.Application/Devices/DTOs/DeviceDTO.cs b/Modules/Devices/src/Devices.Application/Devices/DTOs/DeviceDTO.cs index 8f30c9b76b..ea9e655fe5 100644 --- a/Modules/Devices/src/Devices.Application/Devices/DTOs/DeviceDTO.cs +++ b/Modules/Devices/src/Devices.Application/Devices/DTOs/DeviceDTO.cs @@ -1,30 +1,25 @@ -using AutoMapper; -using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.Mapping; -using Backbone.DevelopmentKit.Identity.ValueObjects; using Backbone.Modules.Devices.Domain.Entities.Identities; namespace Backbone.Modules.Devices.Application.Devices.DTOs; -public class DeviceDTO : IHaveCustomMapping +public class DeviceDTO { - public required DeviceId Id { get; set; } - public required string Username { get; set; } - public required DateTime CreatedAt { get; set; } - public required DeviceId CreatedByDevice { get; set; } - public required LastLoginInformation LastLogin { get; set; } - public required string CommunicationLanguage { get; set; } - - public void CreateMappings(Profile configuration) + public DeviceDTO(Device device) { - configuration - .CreateMap() - .ForMember(dto => dto.LastLogin, - expression => expression.MapFrom(device => new LastLoginInformation { Time = device.User.LastLoginAt })) - .ForMember(dto => dto.Username, - expression => expression.MapFrom(device => device.User.UserName)) - .ForMember(dto => dto.CommunicationLanguage, - expression => expression.MapFrom(device => device.CommunicationLanguage.Value)); + Id = device.Id; + Username = device.User.UserName!; + CreatedAt = device.CreatedAt; + CreatedByDevice = device.CreatedByDevice; + LastLogin = new LastLoginInformation { Time = device.User.LastLoginAt }; + CommunicationLanguage = device.CommunicationLanguage; } + + public string Id { get; set; } + public string Username { get; set; } + public DateTime CreatedAt { get; set; } + public string CreatedByDevice { get; set; } + public LastLoginInformation LastLogin { get; set; } + public string CommunicationLanguage { get; set; } } public class LastLoginInformation diff --git a/Modules/Devices/src/Devices.Application/Devices/Queries/GetActiveDevice/Handler.cs b/Modules/Devices/src/Devices.Application/Devices/Queries/GetActiveDevice/Handler.cs index 28ab7896d4..7dd18a02e8 100644 --- a/Modules/Devices/src/Devices.Application/Devices/Queries/GetActiveDevice/Handler.cs +++ b/Modules/Devices/src/Devices.Application/Devices/Queries/GetActiveDevice/Handler.cs @@ -1,4 +1,3 @@ -using AutoMapper; using Backbone.BuildingBlocks.Application.Abstractions.Exceptions; using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.UserContext; using Backbone.Modules.Devices.Application.Devices.DTOs; @@ -10,13 +9,11 @@ namespace Backbone.Modules.Devices.Application.Devices.Queries.GetActiveDevice; public class Handler : IRequestHandler { - private readonly IMapper _mapper; private readonly IUserContext _userContext; private readonly IIdentitiesRepository _identitiesRepository; - public Handler(IMapper mapper, IUserContext userContext, IIdentitiesRepository identitiesRepository) + public Handler(IUserContext userContext, IIdentitiesRepository identitiesRepository) { - _mapper = mapper; _userContext = userContext; _identitiesRepository = identitiesRepository; } @@ -24,7 +21,6 @@ public Handler(IMapper mapper, IUserContext userContext, IIdentitiesRepository i public async Task Handle(GetActiveDeviceQuery request, CancellationToken cancellationToken) { var device = await _identitiesRepository.GetDeviceById(_userContext.GetDeviceId(), cancellationToken) ?? throw new NotFoundException(nameof(Device)); - var deviceDTO = _mapper.Map(device); - return deviceDTO; + return new DeviceDTO(device); } } diff --git a/Modules/Devices/src/Devices.Application/Devices/Queries/ListDevices/Handler.cs b/Modules/Devices/src/Devices.Application/Devices/Queries/ListDevices/Handler.cs index 8d05f93769..172905a365 100644 --- a/Modules/Devices/src/Devices.Application/Devices/Queries/ListDevices/Handler.cs +++ b/Modules/Devices/src/Devices.Application/Devices/Queries/ListDevices/Handler.cs @@ -1,7 +1,5 @@ -using AutoMapper; using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.UserContext; using Backbone.DevelopmentKit.Identity.ValueObjects; -using Backbone.Modules.Devices.Application.Devices.DTOs; using Backbone.Modules.Devices.Application.Infrastructure.Persistence.Repository; using MediatR; @@ -10,23 +8,17 @@ namespace Backbone.Modules.Devices.Application.Devices.Queries.ListDevices; public class Handler : IRequestHandler { private readonly IdentityAddress _activeIdentity; - private readonly IMapper _mapper; private readonly IIdentitiesRepository _identitiesRepository; - public Handler(IMapper mapper, IUserContext userContext, IIdentitiesRepository devicesRepository) + public Handler(IUserContext userContext, IIdentitiesRepository devicesRepository) { - _mapper = mapper; _activeIdentity = userContext.GetAddress(); _identitiesRepository = devicesRepository; } public async Task Handle(ListDevicesQuery request, CancellationToken cancellationToken) { - - var dbPaginationResult = await _identitiesRepository.FindAllDevicesOfIdentity(_activeIdentity, request.Ids, request.PaginationFilter, cancellationToken); - - var items = _mapper.Map(dbPaginationResult.ItemsOnPage); - - return new ListDevicesResponse(items, request.PaginationFilter, dbPaginationResult.TotalNumberOfItems); + var dbPaginationResult = await _identitiesRepository.FindAllDevicesOfIdentity(_activeIdentity, request.Ids.Select(DeviceId.Parse), request.PaginationFilter, cancellationToken); + return new ListDevicesResponse(dbPaginationResult, request.PaginationFilter); } } diff --git a/Modules/Devices/src/Devices.Application/Devices/Queries/ListDevices/ListDevicesQuery.cs b/Modules/Devices/src/Devices.Application/Devices/Queries/ListDevices/ListDevicesQuery.cs index c447ec90cc..21ba2c5ab1 100644 --- a/Modules/Devices/src/Devices.Application/Devices/Queries/ListDevices/ListDevicesQuery.cs +++ b/Modules/Devices/src/Devices.Application/Devices/Queries/ListDevices/ListDevicesQuery.cs @@ -1,17 +1,16 @@ using Backbone.BuildingBlocks.Application.Pagination; -using Backbone.DevelopmentKit.Identity.ValueObjects; using MediatR; namespace Backbone.Modules.Devices.Application.Devices.Queries.ListDevices; public class ListDevicesQuery : IRequest { - public ListDevicesQuery(PaginationFilter paginationFilter, IEnumerable ids) + public ListDevicesQuery(PaginationFilter paginationFilter, IEnumerable ids) { PaginationFilter = paginationFilter; Ids = ids; } public PaginationFilter PaginationFilter { get; set; } - public IEnumerable Ids { get; set; } + public IEnumerable Ids { get; set; } } diff --git a/Modules/Devices/src/Devices.Application/Devices/Queries/ListDevices/ListDevicesResponse.cs b/Modules/Devices/src/Devices.Application/Devices/Queries/ListDevices/ListDevicesResponse.cs index 1233ccc5bd..7eda837c24 100644 --- a/Modules/Devices/src/Devices.Application/Devices/Queries/ListDevices/ListDevicesResponse.cs +++ b/Modules/Devices/src/Devices.Application/Devices/Queries/ListDevices/ListDevicesResponse.cs @@ -1,9 +1,14 @@ +using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.Persistence.Database; using Backbone.BuildingBlocks.Application.Pagination; using Backbone.Modules.Devices.Application.Devices.DTOs; +using Backbone.Modules.Devices.Domain.Entities.Identities; namespace Backbone.Modules.Devices.Application.Devices.Queries.ListDevices; public class ListDevicesResponse : PagedResponse { - public ListDevicesResponse(IEnumerable items, PaginationFilter previousPaginationFilter, int totalRecords) : base(items, previousPaginationFilter, totalRecords) { } + public ListDevicesResponse(DbPaginationResult dbPaginationResult, PaginationFilter previousPaginationFilter) : base(dbPaginationResult.ItemsOnPage.Select(d => new DeviceDTO(d)), + previousPaginationFilter, dbPaginationResult.TotalNumberOfItems) + { + } } diff --git a/Modules/Devices/src/Devices.Application/Devices/Queries/ListDevices/Validator.cs b/Modules/Devices/src/Devices.Application/Devices/Queries/ListDevices/Validator.cs new file mode 100644 index 0000000000..2acbb5d489 --- /dev/null +++ b/Modules/Devices/src/Devices.Application/Devices/Queries/ListDevices/Validator.cs @@ -0,0 +1,13 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.DevelopmentKit.Identity.ValueObjects; +using FluentValidation; + +namespace Backbone.Modules.Devices.Application.Devices.Queries.ListDevices; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleForEach(x => x.Ids).ValidId(); + } +} diff --git a/Modules/Devices/src/Devices.Application/Extensions/IServiceCollectionExtensions.cs b/Modules/Devices/src/Devices.Application/Extensions/IServiceCollectionExtensions.cs index acffa0742f..662cf365b8 100644 --- a/Modules/Devices/src/Devices.Application/Extensions/IServiceCollectionExtensions.cs +++ b/Modules/Devices/src/Devices.Application/Extensions/IServiceCollectionExtensions.cs @@ -1,9 +1,8 @@ using System.Reflection; using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.EventBus; using Backbone.BuildingBlocks.Application.MediatR; -using Backbone.Modules.Devices.Application.AutoMapper; -using Backbone.Modules.Devices.Application.Clients.Commands.DeleteClient; using Backbone.Modules.Devices.Application.Devices.Commands.RegisterDevice; +using Backbone.Modules.Devices.Application.Devices.Queries.ListDevices; using FluentValidation; using Microsoft.Extensions.DependencyInjection; @@ -19,8 +18,7 @@ public static void AddApplication(this IServiceCollection services) .AddOpenBehavior(typeof(RequestValidationBehavior<,>)) .AddOpenBehavior(typeof(QuotaEnforcerBehavior<,>)) ); - services.AddAutoMapper(typeof(AutoMapperProfile).Assembly); - services.AddValidatorsFromAssembly(typeof(DeleteClientCommandValidator).Assembly); + services.AddValidatorsFromAssembly(typeof(Validator).Assembly); services.AddScoped(); AddEventHandlers(services); diff --git a/Modules/Devices/src/Devices.Application/Identities/Commands/ApproveDeletionProcess/Validator.cs b/Modules/Devices/src/Devices.Application/Identities/Commands/ApproveDeletionProcess/Validator.cs new file mode 100644 index 0000000000..84ef2e661a --- /dev/null +++ b/Modules/Devices/src/Devices.Application/Identities/Commands/ApproveDeletionProcess/Validator.cs @@ -0,0 +1,13 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.Modules.Devices.Domain.Entities.Identities; +using FluentValidation; + +namespace Backbone.Modules.Devices.Application.Identities.Commands.ApproveDeletionProcess; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleFor(x => x.DeletionProcessId).ValidId(); + } +} diff --git a/Modules/Devices/src/Devices.Application/Identities/Commands/CancelDeletionProcessAsOwner/Handler.cs b/Modules/Devices/src/Devices.Application/Identities/Commands/CancelDeletionProcessAsOwner/Handler.cs index ddb3f13748..94587ea3e5 100644 --- a/Modules/Devices/src/Devices.Application/Identities/Commands/CancelDeletionProcessAsOwner/Handler.cs +++ b/Modules/Devices/src/Devices.Application/Identities/Commands/CancelDeletionProcessAsOwner/Handler.cs @@ -1,11 +1,9 @@ using Backbone.BuildingBlocks.Application.Abstractions.Exceptions; -using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.EventBus; using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.UserContext; using Backbone.BuildingBlocks.Application.PushNotifications; using Backbone.BuildingBlocks.Domain; using Backbone.Modules.Devices.Application.Infrastructure.Persistence.Repository; using Backbone.Modules.Devices.Application.Infrastructure.PushNotifications.DeletionProcess; -using Backbone.Modules.Devices.Domain.DomainEvents.Outgoing; using Backbone.Modules.Devices.Domain.Entities.Identities; using MediatR; @@ -27,7 +25,6 @@ public Handler(IIdentitiesRepository identitiesRepository, IUserContext userCont public async Task Handle(CancelDeletionProcessAsOwnerCommand request, CancellationToken cancellationToken) { var identity = await _identitiesRepository.FindByAddress(_userContext.GetAddress(), cancellationToken, true) ?? throw new NotFoundException(nameof(Identity)); - var oldTierId = identity.TierId; var deviceId = _userContext.GetDeviceId(); var deletionProcessIdResult = IdentityDeletionProcessId.Create(request.DeletionProcessId); @@ -40,7 +37,6 @@ public async Task Handle(CancelDeletionPro var deletionProcess = identity.CancelDeletionProcessAsOwner(deletionProcessId, deviceId); await _identitiesRepository.Update(identity, cancellationToken); - var newTierId = identity.TierId; await _notificationSender.SendNotification(identity.Address, new DeletionProcessCancelledByOwnerNotification(), cancellationToken); diff --git a/Modules/Devices/src/Devices.Application/Identities/Commands/CancelDeletionProcessAsOwner/Validator.cs b/Modules/Devices/src/Devices.Application/Identities/Commands/CancelDeletionProcessAsOwner/Validator.cs new file mode 100644 index 0000000000..4805c249d6 --- /dev/null +++ b/Modules/Devices/src/Devices.Application/Identities/Commands/CancelDeletionProcessAsOwner/Validator.cs @@ -0,0 +1,13 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.Modules.Devices.Domain.Entities.Identities; +using FluentValidation; + +namespace Backbone.Modules.Devices.Application.Identities.Commands.CancelDeletionProcessAsOwner; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleFor(x => x.DeletionProcessId).ValidId(); + } +} diff --git a/Modules/Devices/src/Devices.Application/Identities/Commands/CancelDeletionProcessAsSupport/Handler.cs b/Modules/Devices/src/Devices.Application/Identities/Commands/CancelDeletionProcessAsSupport/Handler.cs index 8d4665b7c5..1a59bede66 100644 --- a/Modules/Devices/src/Devices.Application/Identities/Commands/CancelDeletionProcessAsSupport/Handler.cs +++ b/Modules/Devices/src/Devices.Application/Identities/Commands/CancelDeletionProcessAsSupport/Handler.cs @@ -1,6 +1,5 @@ using Backbone.BuildingBlocks.Application.Abstractions.Exceptions; using Backbone.BuildingBlocks.Application.PushNotifications; -using Backbone.BuildingBlocks.Domain; using Backbone.Modules.Devices.Application.Infrastructure.Persistence.Repository; using Backbone.Modules.Devices.Application.Infrastructure.PushNotifications.DeletionProcess; using Backbone.Modules.Devices.Domain.Entities.Identities; @@ -23,12 +22,7 @@ public async Task Handle(CancelDeletionAsSuppor { var identity = await _identitiesRepository.FindByAddress(request.Address, cancellationToken, track: true) ?? throw new NotFoundException(nameof(Identity)); - var deletionProcessIdResult = IdentityDeletionProcessId.Create(request.DeletionProcessId); - - if (deletionProcessIdResult.IsFailure) - throw new DomainException(deletionProcessIdResult.Error); - - var deletionProcessId = deletionProcessIdResult.Value; + var deletionProcessId = IdentityDeletionProcessId.Create(request.DeletionProcessId).Value; var deletionProcess = identity.CancelDeletionProcessAsSupport(deletionProcessId); diff --git a/Modules/Devices/src/Devices.Application/Identities/Commands/CancelDeletionProcessAsSupport/Validator.cs b/Modules/Devices/src/Devices.Application/Identities/Commands/CancelDeletionProcessAsSupport/Validator.cs new file mode 100644 index 0000000000..de999933d1 --- /dev/null +++ b/Modules/Devices/src/Devices.Application/Identities/Commands/CancelDeletionProcessAsSupport/Validator.cs @@ -0,0 +1,15 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.DevelopmentKit.Identity.ValueObjects; +using Backbone.Modules.Devices.Domain.Entities.Identities; +using FluentValidation; + +namespace Backbone.Modules.Devices.Application.Identities.Commands.CancelDeletionProcessAsSupport; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleFor(x => x.Address).ValidId(); + RuleFor(x => x.DeletionProcessId).ValidId(); + } +} diff --git a/Modules/Devices/src/Devices.Application/Identities/Commands/CreateIdentity/CreateIdentityResponse.cs b/Modules/Devices/src/Devices.Application/Identities/Commands/CreateIdentity/CreateIdentityResponse.cs index 9505bcf173..b28d9838ed 100644 --- a/Modules/Devices/src/Devices.Application/Identities/Commands/CreateIdentity/CreateIdentityResponse.cs +++ b/Modules/Devices/src/Devices.Application/Identities/Commands/CreateIdentity/CreateIdentityResponse.cs @@ -1,17 +1,15 @@ -using Backbone.DevelopmentKit.Identity.ValueObjects; - namespace Backbone.Modules.Devices.Application.Identities.Commands.CreateIdentity; public class CreateIdentityResponse { - public required IdentityAddress Address { get; set; } + public required string Address { get; set; } public required DateTime CreatedAt { get; set; } public required CreateIdentityResponseDevice Device { get; set; } } public class CreateIdentityResponseDevice { - public required DeviceId Id { get; set; } + public required string Id { get; set; } public required string Username { get; set; } public required DateTime CreatedAt { get; set; } } diff --git a/Modules/Devices/src/Devices.Application/Identities/Commands/CreateIdentity/CreateIdentityCommandValidator.cs b/Modules/Devices/src/Devices.Application/Identities/Commands/CreateIdentity/Validator.cs similarity index 100% rename from Modules/Devices/src/Devices.Application/Identities/Commands/CreateIdentity/CreateIdentityCommandValidator.cs rename to Modules/Devices/src/Devices.Application/Identities/Commands/CreateIdentity/Validator.cs diff --git a/Modules/Devices/src/Devices.Application/Identities/Commands/DeleteIdentity/Handler.cs b/Modules/Devices/src/Devices.Application/Identities/Commands/DeleteIdentity/Handler.cs index 9dffa8c7f7..73a435abde 100644 --- a/Modules/Devices/src/Devices.Application/Identities/Commands/DeleteIdentity/Handler.cs +++ b/Modules/Devices/src/Devices.Application/Identities/Commands/DeleteIdentity/Handler.cs @@ -3,6 +3,7 @@ using MediatR; namespace Backbone.Modules.Devices.Application.Identities.Commands.DeleteIdentity; + public class Handler : IRequestHandler { private readonly IIdentitiesRepository _identitiesRepository; diff --git a/Modules/Devices/src/Devices.Application/Identities/Commands/DeleteIdentity/Validator.cs b/Modules/Devices/src/Devices.Application/Identities/Commands/DeleteIdentity/Validator.cs index 83a76b0147..9cf4f9fd81 100644 --- a/Modules/Devices/src/Devices.Application/Identities/Commands/DeleteIdentity/Validator.cs +++ b/Modules/Devices/src/Devices.Application/Identities/Commands/DeleteIdentity/Validator.cs @@ -1,8 +1,13 @@ -using Backbone.DevelopmentKit.Identity.ValueObjects; +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.DevelopmentKit.Identity.ValueObjects; using FluentValidation; namespace Backbone.Modules.Devices.Application.Identities.Commands.DeleteIdentity; + public class Validator : AbstractValidator { - public Validator() => RuleFor(x => x.IdentityAddress).Must(IdentityAddress.IsValid); + public Validator() + { + RuleFor(x => x.IdentityAddress).ValidId(); + } } diff --git a/Modules/Devices/src/Devices.Application/Identities/Commands/LogDeletionProcess/Validator.cs b/Modules/Devices/src/Devices.Application/Identities/Commands/LogDeletionProcess/Validator.cs new file mode 100644 index 0000000000..2aeb1b04b1 --- /dev/null +++ b/Modules/Devices/src/Devices.Application/Identities/Commands/LogDeletionProcess/Validator.cs @@ -0,0 +1,13 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.DevelopmentKit.Identity.ValueObjects; +using FluentValidation; + +namespace Backbone.Modules.Devices.Application.Identities.Commands.LogDeletionProcess; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleFor(x => x.IdentityAddress).ValidId(); + } +} diff --git a/Modules/Devices/src/Devices.Application/Identities/Commands/RejectDeletionProcess/Validator.cs b/Modules/Devices/src/Devices.Application/Identities/Commands/RejectDeletionProcess/Validator.cs new file mode 100644 index 0000000000..67c1065739 --- /dev/null +++ b/Modules/Devices/src/Devices.Application/Identities/Commands/RejectDeletionProcess/Validator.cs @@ -0,0 +1,13 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.Modules.Devices.Domain.Entities.Identities; +using FluentValidation; + +namespace Backbone.Modules.Devices.Application.Identities.Commands.RejectDeletionProcess; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleFor(x => x.DeletionProcessId).ValidId(); + } +} diff --git a/Modules/Devices/src/Devices.Application/Identities/Commands/SendDeletionProcessApprovalReminders/Handler.cs b/Modules/Devices/src/Devices.Application/Identities/Commands/SendDeletionProcessApprovalReminders/Handler.cs index 419dcfe951..2d0546f6b4 100644 --- a/Modules/Devices/src/Devices.Application/Identities/Commands/SendDeletionProcessApprovalReminders/Handler.cs +++ b/Modules/Devices/src/Devices.Application/Identities/Commands/SendDeletionProcessApprovalReminders/Handler.cs @@ -15,7 +15,6 @@ public class Handler : IRequestHandler _logger; - public Handler(IIdentitiesRepository identitiesRepository, IPushNotificationSender pushNotificationSender, ILogger logger) { _identitiesRepository = identitiesRepository; diff --git a/Modules/Devices/src/Devices.Application/Identities/Commands/StartDeletionProcessAsSupport/Validator.cs b/Modules/Devices/src/Devices.Application/Identities/Commands/StartDeletionProcessAsSupport/Validator.cs new file mode 100644 index 0000000000..dca6e97bff --- /dev/null +++ b/Modules/Devices/src/Devices.Application/Identities/Commands/StartDeletionProcessAsSupport/Validator.cs @@ -0,0 +1,13 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.DevelopmentKit.Identity.ValueObjects; +using FluentValidation; + +namespace Backbone.Modules.Devices.Application.Identities.Commands.StartDeletionProcessAsSupport; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleFor(x => x.IdentityAddress).ValidId(); + } +} diff --git a/Modules/Devices/src/Devices.Application/Identities/Commands/UpdateIdentity/Handler.cs b/Modules/Devices/src/Devices.Application/Identities/Commands/UpdateIdentity/Handler.cs index 73a565f0a2..3db8c8e6c7 100644 --- a/Modules/Devices/src/Devices.Application/Identities/Commands/UpdateIdentity/Handler.cs +++ b/Modules/Devices/src/Devices.Application/Identities/Commands/UpdateIdentity/Handler.cs @@ -1,11 +1,8 @@ using Backbone.BuildingBlocks.Application.Abstractions.Exceptions; -using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.EventBus; using Backbone.Modules.Devices.Application.Infrastructure.Persistence.Repository; using Backbone.Modules.Devices.Domain.Aggregates.Tier; -using Backbone.Modules.Devices.Domain.DomainEvents.Outgoing; using Backbone.Modules.Devices.Domain.Entities.Identities; using MediatR; -using ApplicationException = Backbone.BuildingBlocks.Application.Abstractions.Exceptions.ApplicationException; namespace Backbone.Modules.Devices.Application.Identities.Commands.UpdateIdentity; @@ -23,16 +20,9 @@ public Handler(IIdentitiesRepository identitiesRepository, ITiersRepository tier public async Task Handle(UpdateIdentityCommand request, CancellationToken cancellationToken) { var newTierIdResult = TierId.Create(request.TierId); - if (!newTierIdResult.IsSuccess) - { - throw new ApplicationException(new ApplicationError(newTierIdResult.Error.Code, newTierIdResult.Error.Message)); - } - var identity = await _identitiesRepository.FindByAddress(request.Address, cancellationToken, track: true) ?? throw new NotFoundException(nameof(Identity)); - var tiers = await _tiersRepository.FindByIds(new List() { identity.TierId, newTierIdResult.Value }, cancellationToken); - - var oldTier = tiers.Single(t => t.Id == identity.TierId); + var tiers = await _tiersRepository.FindByIds(new List { identity.TierId, newTierIdResult.Value }, cancellationToken); var newTier = tiers.SingleOrDefault(t => t.Id == newTierIdResult.Value) ?? throw new NotFoundException(nameof(Tier)); identity.ChangeTier(newTier.Id); diff --git a/Modules/Devices/src/Devices.Application/Identities/Commands/UpdateIdentity/UpdateIdentityCommandValidator.cs b/Modules/Devices/src/Devices.Application/Identities/Commands/UpdateIdentity/UpdateIdentityCommandValidator.cs deleted file mode 100644 index 78fe1aa3f4..0000000000 --- a/Modules/Devices/src/Devices.Application/Identities/Commands/UpdateIdentity/UpdateIdentityCommandValidator.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Backbone.BuildingBlocks.Application.FluentValidation; -using FluentValidation; - -namespace Backbone.Modules.Devices.Application.Identities.Commands.UpdateIdentity; -public class UpdateIdentityCommandValidator : AbstractValidator -{ - public UpdateIdentityCommandValidator() - { - RuleFor(c => c.Address).DetailedNotEmpty(); - RuleFor(c => c.TierId).DetailedNotEmpty(); - } -} diff --git a/Modules/Devices/src/Devices.Application/Identities/Commands/UpdateIdentity/Validator.cs b/Modules/Devices/src/Devices.Application/Identities/Commands/UpdateIdentity/Validator.cs new file mode 100644 index 0000000000..a0dcd37de3 --- /dev/null +++ b/Modules/Devices/src/Devices.Application/Identities/Commands/UpdateIdentity/Validator.cs @@ -0,0 +1,15 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.DevelopmentKit.Identity.ValueObjects; +using Backbone.Modules.Devices.Domain.Aggregates.Tier; +using FluentValidation; + +namespace Backbone.Modules.Devices.Application.Identities.Commands.UpdateIdentity; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleFor(x => x.Address).ValidId(); + RuleFor(c => c.TierId).ValidId(); + } +} diff --git a/Modules/Devices/src/Devices.Application/Identities/Queries/GetDeletionProcessAsOwner/Validator.cs b/Modules/Devices/src/Devices.Application/Identities/Queries/GetDeletionProcessAsOwner/Validator.cs new file mode 100644 index 0000000000..0d98808140 --- /dev/null +++ b/Modules/Devices/src/Devices.Application/Identities/Queries/GetDeletionProcessAsOwner/Validator.cs @@ -0,0 +1,13 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.Modules.Devices.Domain.Entities.Identities; +using FluentValidation; + +namespace Backbone.Modules.Devices.Application.Identities.Queries.GetDeletionProcessAsOwner; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleFor(x => x.Id).ValidId(); + } +} diff --git a/Modules/Devices/src/Devices.Application/Identities/Queries/GetDeletionProcessAsSupport/Validator.cs b/Modules/Devices/src/Devices.Application/Identities/Queries/GetDeletionProcessAsSupport/Validator.cs new file mode 100644 index 0000000000..97ade62318 --- /dev/null +++ b/Modules/Devices/src/Devices.Application/Identities/Queries/GetDeletionProcessAsSupport/Validator.cs @@ -0,0 +1,15 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.DevelopmentKit.Identity.ValueObjects; +using Backbone.Modules.Devices.Domain.Entities.Identities; +using FluentValidation; + +namespace Backbone.Modules.Devices.Application.Identities.Queries.GetDeletionProcessAsSupport; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleFor(x => x.IdentityAddress).ValidId(); + RuleFor(x => x.DeletionProcessId).ValidId(); + } +} diff --git a/Modules/Devices/src/Devices.Application/Identities/Queries/GetDeletionProcessesAsSupport/Validator.cs b/Modules/Devices/src/Devices.Application/Identities/Queries/GetDeletionProcessesAsSupport/Validator.cs new file mode 100644 index 0000000000..a3e7acd173 --- /dev/null +++ b/Modules/Devices/src/Devices.Application/Identities/Queries/GetDeletionProcessesAsSupport/Validator.cs @@ -0,0 +1,13 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.DevelopmentKit.Identity.ValueObjects; +using FluentValidation; + +namespace Backbone.Modules.Devices.Application.Identities.Queries.GetDeletionProcessesAsSupport; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleFor(x => x.IdentityAddress).ValidId(); + } +} diff --git a/Modules/Devices/src/Devices.Application/Identities/Queries/GetDeletionProcessesAuditLogs/Validator.cs b/Modules/Devices/src/Devices.Application/Identities/Queries/GetDeletionProcessesAuditLogs/Validator.cs new file mode 100644 index 0000000000..33c128927a --- /dev/null +++ b/Modules/Devices/src/Devices.Application/Identities/Queries/GetDeletionProcessesAuditLogs/Validator.cs @@ -0,0 +1,13 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.DevelopmentKit.Identity.ValueObjects; +using FluentValidation; + +namespace Backbone.Modules.Devices.Application.Identities.Queries.GetDeletionProcessesAuditLogs; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleFor(x => x.IdentityAddress).ValidId(); + } +} diff --git a/Modules/Devices/src/Devices.Application/Identities/Queries/GetIdentity/GetIdentityQuery.cs b/Modules/Devices/src/Devices.Application/Identities/Queries/GetIdentity/GetIdentityQuery.cs index 5bdb7bb751..3148f0a538 100644 --- a/Modules/Devices/src/Devices.Application/Identities/Queries/GetIdentity/GetIdentityQuery.cs +++ b/Modules/Devices/src/Devices.Application/Identities/Queries/GetIdentity/GetIdentityQuery.cs @@ -1,6 +1,7 @@ using MediatR; namespace Backbone.Modules.Devices.Application.Identities.Queries.GetIdentity; + public class GetIdentityQuery : IRequest { public GetIdentityQuery(string address) diff --git a/Modules/Devices/src/Devices.Application/Identities/Queries/GetIdentity/GetIdentityResponse.cs b/Modules/Devices/src/Devices.Application/Identities/Queries/GetIdentity/GetIdentityResponse.cs index 4f7b8fdb2c..c75a8d62b4 100644 --- a/Modules/Devices/src/Devices.Application/Identities/Queries/GetIdentity/GetIdentityResponse.cs +++ b/Modules/Devices/src/Devices.Application/Identities/Queries/GetIdentity/GetIdentityResponse.cs @@ -2,6 +2,7 @@ using Backbone.Modules.Devices.Domain.Entities.Identities; namespace Backbone.Modules.Devices.Application.Identities.Queries.GetIdentity; + public class GetIdentityResponse : IdentitySummaryDTO { public GetIdentityResponse(Identity identity) : base(identity) { } diff --git a/Modules/Devices/src/Devices.Application/Identities/Queries/GetIdentity/Validator.cs b/Modules/Devices/src/Devices.Application/Identities/Queries/GetIdentity/Validator.cs new file mode 100644 index 0000000000..1accc5b8aa --- /dev/null +++ b/Modules/Devices/src/Devices.Application/Identities/Queries/GetIdentity/Validator.cs @@ -0,0 +1,13 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.DevelopmentKit.Identity.ValueObjects; +using FluentValidation; + +namespace Backbone.Modules.Devices.Application.Identities.Queries.GetIdentity; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleFor(x => x.Address).ValidId(); + } +} diff --git a/Modules/Devices/src/Devices.Application/Identities/Queries/GetOwnIdentity/GetOwnIdentityResponse.cs b/Modules/Devices/src/Devices.Application/Identities/Queries/GetOwnIdentity/GetOwnIdentityResponse.cs index ba84afac70..b938847511 100644 --- a/Modules/Devices/src/Devices.Application/Identities/Queries/GetOwnIdentity/GetOwnIdentityResponse.cs +++ b/Modules/Devices/src/Devices.Application/Identities/Queries/GetOwnIdentity/GetOwnIdentityResponse.cs @@ -2,6 +2,7 @@ using Backbone.Modules.Devices.Domain.Entities.Identities; namespace Backbone.Modules.Devices.Application.Identities.Queries.GetOwnIdentity; + public class GetOwnIdentityResponse : OwnIdentityDTO { public GetOwnIdentityResponse(Identity identity) : base(identity) { } diff --git a/Modules/Devices/src/Devices.Application/Identities/Queries/ListIdentities/Handler.cs b/Modules/Devices/src/Devices.Application/Identities/Queries/ListIdentities/Handler.cs index fa77915539..c2e8721444 100644 --- a/Modules/Devices/src/Devices.Application/Identities/Queries/ListIdentities/Handler.cs +++ b/Modules/Devices/src/Devices.Application/Identities/Queries/ListIdentities/Handler.cs @@ -1,5 +1,4 @@ using System.Linq.Expressions; -using Backbone.Modules.Devices.Application.DTOs; using Backbone.Modules.Devices.Application.Infrastructure.Persistence.Repository; using Backbone.Modules.Devices.Domain.Entities.Identities; using MediatR; @@ -21,8 +20,6 @@ public async Task Handle(ListIdentitiesQuery request, Ca (request.Status == null || i.Status == request.Status); var identities = await _identitiesRepository.Find(filter, cancellationToken); - var identityDtos = identities.Select(i => new IdentitySummaryDTO(i)).ToList(); - - return new ListIdentitiesResponse(identityDtos); + return new ListIdentitiesResponse(identities); } } diff --git a/Modules/Devices/src/Devices.Application/Identities/Queries/ListIdentities/ListIdentitiesQuery.cs b/Modules/Devices/src/Devices.Application/Identities/Queries/ListIdentities/ListIdentitiesQuery.cs index 0c66a83832..8cd2f794c6 100644 --- a/Modules/Devices/src/Devices.Application/Identities/Queries/ListIdentities/ListIdentitiesQuery.cs +++ b/Modules/Devices/src/Devices.Application/Identities/Queries/ListIdentities/ListIdentitiesQuery.cs @@ -1,4 +1,3 @@ -using Backbone.DevelopmentKit.Identity.ValueObjects; using Backbone.Modules.Devices.Domain.Entities.Identities; using MediatR; @@ -6,12 +5,12 @@ namespace Backbone.Modules.Devices.Application.Identities.Queries.ListIdentities public class ListIdentitiesQuery : IRequest { - public ListIdentitiesQuery(IEnumerable? addresses = null, IdentityStatus? status = null) + public ListIdentitiesQuery(List? addresses = null, IdentityStatus? status = null) { Addresses = addresses; Status = status; } - public IEnumerable? Addresses { get; set; } + public List? Addresses { get; set; } public IdentityStatus? Status { get; set; } } diff --git a/Modules/Devices/src/Devices.Application/Identities/Queries/ListIdentities/ListIdentitiesResponse.cs b/Modules/Devices/src/Devices.Application/Identities/Queries/ListIdentities/ListIdentitiesResponse.cs index 3cbe69e6c5..29db72da56 100644 --- a/Modules/Devices/src/Devices.Application/Identities/Queries/ListIdentities/ListIdentitiesResponse.cs +++ b/Modules/Devices/src/Devices.Application/Identities/Queries/ListIdentities/ListIdentitiesResponse.cs @@ -1,11 +1,12 @@ using Backbone.BuildingBlocks.Application.CQRS.BaseClasses; using Backbone.Modules.Devices.Application.DTOs; +using Backbone.Modules.Devices.Domain.Entities.Identities; namespace Backbone.Modules.Devices.Application.Identities.Queries.ListIdentities; public class ListIdentitiesResponse : CollectionResponseBase { - public ListIdentitiesResponse(IEnumerable items) : base(items) + public ListIdentitiesResponse(IEnumerable items) : base(items.Select(i => new IdentitySummaryDTO(i))) { } } diff --git a/Modules/Devices/src/Devices.Application/Identities/Queries/ListIdentities/Validator.cs b/Modules/Devices/src/Devices.Application/Identities/Queries/ListIdentities/Validator.cs new file mode 100644 index 0000000000..0973a1d285 --- /dev/null +++ b/Modules/Devices/src/Devices.Application/Identities/Queries/ListIdentities/Validator.cs @@ -0,0 +1,13 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.DevelopmentKit.Identity.ValueObjects; +using FluentValidation; + +namespace Backbone.Modules.Devices.Application.Identities.Queries.ListIdentities; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleForEach(x => x.Addresses).ValidId(); + } +} diff --git a/Modules/Devices/src/Devices.Application/PushNotifications/Commands/DeleteDeviceRegistration/Handler.cs b/Modules/Devices/src/Devices.Application/PushNotifications/Commands/DeleteDeviceRegistration/Handler.cs index 29ee2ae952..16bf3435e3 100644 --- a/Modules/Devices/src/Devices.Application/PushNotifications/Commands/DeleteDeviceRegistration/Handler.cs +++ b/Modules/Devices/src/Devices.Application/PushNotifications/Commands/DeleteDeviceRegistration/Handler.cs @@ -4,7 +4,8 @@ using MediatR; namespace Backbone.Modules.Devices.Application.PushNotifications.Commands.DeleteDeviceRegistration; -internal class Handler : IRequestHandler + +public class Handler : IRequestHandler { private readonly IPushNotificationRegistrationService _pushRegistrationService; private readonly DeviceId _activeDevice; @@ -15,7 +16,6 @@ public Handler(IPushNotificationRegistrationService pushRegistrationService, IUs _activeDevice = userContext.GetDeviceId(); } - public async Task Handle(DeleteDeviceRegistrationCommand request, CancellationToken cancellationToken) { await _pushRegistrationService.DeleteRegistration(_activeDevice, cancellationToken); diff --git a/Modules/Devices/src/Devices.Application/PushNotifications/Commands/DeletePnsRegistrationsOfIdentity/DeletePnsRegistrationsOfIdentityCommand.cs b/Modules/Devices/src/Devices.Application/PushNotifications/Commands/DeletePnsRegistrationsOfIdentity/DeletePnsRegistrationsOfIdentityCommand.cs index 33bf6b9a43..17437cbb0a 100644 --- a/Modules/Devices/src/Devices.Application/PushNotifications/Commands/DeletePnsRegistrationsOfIdentity/DeletePnsRegistrationsOfIdentityCommand.cs +++ b/Modules/Devices/src/Devices.Application/PushNotifications/Commands/DeletePnsRegistrationsOfIdentity/DeletePnsRegistrationsOfIdentityCommand.cs @@ -1,13 +1,12 @@ -using Backbone.DevelopmentKit.Identity.ValueObjects; -using MediatR; +using MediatR; namespace Backbone.Modules.Devices.Application.PushNotifications.Commands.DeletePnsRegistrationsOfIdentity; public class DeletePnsRegistrationsOfIdentityCommand : IRequest { - public DeletePnsRegistrationsOfIdentityCommand(IdentityAddress identityAddress) + public DeletePnsRegistrationsOfIdentityCommand(string identityAddress) { IdentityAddress = identityAddress; } - public IdentityAddress IdentityAddress { get; set; } + public string IdentityAddress { get; set; } } diff --git a/Modules/Devices/src/Devices.Application/PushNotifications/Commands/DeletePnsRegistrationsOfIdentity/Validator.cs b/Modules/Devices/src/Devices.Application/PushNotifications/Commands/DeletePnsRegistrationsOfIdentity/Validator.cs index 21cdec7d1d..b6c524dc37 100644 --- a/Modules/Devices/src/Devices.Application/PushNotifications/Commands/DeletePnsRegistrationsOfIdentity/Validator.cs +++ b/Modules/Devices/src/Devices.Application/PushNotifications/Commands/DeletePnsRegistrationsOfIdentity/Validator.cs @@ -1,8 +1,13 @@ -using Backbone.DevelopmentKit.Identity.ValueObjects; +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.DevelopmentKit.Identity.ValueObjects; using FluentValidation; namespace Backbone.Modules.Devices.Application.PushNotifications.Commands.DeletePnsRegistrationsOfIdentity; + public class Validator : AbstractValidator { - public Validator() => RuleFor(x => x.IdentityAddress).Must(x => IdentityAddress.IsValid(x)); + public Validator() + { + RuleFor(x => x.IdentityAddress).ValidId(); + } } diff --git a/Modules/Devices/src/Devices.Application/PushNotifications/Commands/UpdateDeviceRegistration/UpdateDeviceRegistrationValidator.cs b/Modules/Devices/src/Devices.Application/PushNotifications/Commands/UpdateDeviceRegistration/Validator.cs similarity index 82% rename from Modules/Devices/src/Devices.Application/PushNotifications/Commands/UpdateDeviceRegistration/UpdateDeviceRegistrationValidator.cs rename to Modules/Devices/src/Devices.Application/PushNotifications/Commands/UpdateDeviceRegistration/Validator.cs index fc5b637372..60ef9f50d7 100644 --- a/Modules/Devices/src/Devices.Application/PushNotifications/Commands/UpdateDeviceRegistration/UpdateDeviceRegistrationValidator.cs +++ b/Modules/Devices/src/Devices.Application/PushNotifications/Commands/UpdateDeviceRegistration/Validator.cs @@ -1,13 +1,14 @@ using Backbone.BuildingBlocks.Application.Abstractions.Exceptions; +using Backbone.BuildingBlocks.Application.Extensions; using Backbone.BuildingBlocks.Application.FluentValidation; using FluentValidation; namespace Backbone.Modules.Devices.Application.PushNotifications.Commands.UpdateDeviceRegistration; // ReSharper disable once UnusedMember.Global -public class UpdateDeviceRegistrationValidator : AbstractValidator +public class Validator : AbstractValidator { - public UpdateDeviceRegistrationValidator() + public Validator() { RuleFor(dto => dto.Platform).In("fcm", "apns", "dummy", "sse"); diff --git a/Modules/Devices/src/Devices.Application/Tiers/Commands/CreateTier/CreateTierCommandValidator.cs b/Modules/Devices/src/Devices.Application/Tiers/Commands/CreateTier/Validator.cs similarity index 71% rename from Modules/Devices/src/Devices.Application/Tiers/Commands/CreateTier/CreateTierCommandValidator.cs rename to Modules/Devices/src/Devices.Application/Tiers/Commands/CreateTier/Validator.cs index d0a3e489ef..1eb23365a9 100644 --- a/Modules/Devices/src/Devices.Application/Tiers/Commands/CreateTier/CreateTierCommandValidator.cs +++ b/Modules/Devices/src/Devices.Application/Tiers/Commands/CreateTier/Validator.cs @@ -4,9 +4,9 @@ namespace Backbone.Modules.Devices.Application.Tiers.Commands.CreateTier; -public class CreateTierCommandValidator : AbstractValidator +public class Validator : AbstractValidator { - public CreateTierCommandValidator() + public Validator() { RuleFor(t => t.Name) .Valid(TierName.Validate); diff --git a/Modules/Devices/src/Devices.Application/Tiers/Commands/DeleteTier/DeleteTierCommandValidator.cs b/Modules/Devices/src/Devices.Application/Tiers/Commands/DeleteTier/DeleteTierCommandValidator.cs deleted file mode 100644 index fa5ddac539..0000000000 --- a/Modules/Devices/src/Devices.Application/Tiers/Commands/DeleteTier/DeleteTierCommandValidator.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Backbone.BuildingBlocks.Application.FluentValidation; -using FluentValidation; - -namespace Backbone.Modules.Devices.Application.Tiers.Commands.DeleteTier; - -public class DeleteTierCommandValidator : AbstractValidator -{ - public DeleteTierCommandValidator() - { - RuleFor(c => c.TierId).DetailedNotEmpty(); - } -} diff --git a/Modules/Devices/src/Devices.Application/Tiers/Commands/DeleteTier/Validator.cs b/Modules/Devices/src/Devices.Application/Tiers/Commands/DeleteTier/Validator.cs new file mode 100644 index 0000000000..727e8b68da --- /dev/null +++ b/Modules/Devices/src/Devices.Application/Tiers/Commands/DeleteTier/Validator.cs @@ -0,0 +1,13 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.Modules.Devices.Domain.Aggregates.Tier; +using FluentValidation; + +namespace Backbone.Modules.Devices.Application.Tiers.Commands.DeleteTier; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleFor(c => c.TierId).ValidId(); + } +} diff --git a/Modules/Devices/src/Devices.Application/Tiers/DTOs/TierDTO.cs b/Modules/Devices/src/Devices.Application/Tiers/DTOs/TierDTO.cs index e9ce10e1d0..b40b3d2292 100644 --- a/Modules/Devices/src/Devices.Application/Tiers/DTOs/TierDTO.cs +++ b/Modules/Devices/src/Devices.Application/Tiers/DTOs/TierDTO.cs @@ -2,12 +2,12 @@ namespace Backbone.Modules.Devices.Application.Tiers.DTOs; public class TierDTO { - public string Id { get; set; } - public string Name { get; set; } - public TierDTO(string id, string name) { Id = id; Name = name; } + + public string Id { get; set; } + public string Name { get; set; } } diff --git a/Modules/Devices/src/Devices.Application/Tiers/Queries/ListTiers/Handler.cs b/Modules/Devices/src/Devices.Application/Tiers/Queries/ListTiers/Handler.cs index 2f362054e6..095254528a 100644 --- a/Modules/Devices/src/Devices.Application/Tiers/Queries/ListTiers/Handler.cs +++ b/Modules/Devices/src/Devices.Application/Tiers/Queries/ListTiers/Handler.cs @@ -1,8 +1,8 @@ using Backbone.Modules.Devices.Application.Infrastructure.Persistence.Repository; -using Backbone.Modules.Devices.Application.Tiers.DTOs; using MediatR; namespace Backbone.Modules.Devices.Application.Tiers.Queries.ListTiers; + public class Handler : IRequestHandler { private readonly ITiersRepository _tierRepository; @@ -15,8 +15,6 @@ public Handler(ITiersRepository repository) public async Task Handle(ListTiersQuery request, CancellationToken cancellationToken) { var dbPaginationResult = await _tierRepository.FindAll(request.PaginationFilter, cancellationToken); - var tierDtos = dbPaginationResult.ItemsOnPage.Select(el => new TierDTO(el.Id, el.Name)).ToList(); - - return new ListTiersResponse(tierDtos, request.PaginationFilter, dbPaginationResult.TotalNumberOfItems); + return new ListTiersResponse(dbPaginationResult, request.PaginationFilter); } } diff --git a/Modules/Devices/src/Devices.Application/Tiers/Queries/ListTiers/ListTiersResponse.cs b/Modules/Devices/src/Devices.Application/Tiers/Queries/ListTiers/ListTiersResponse.cs index 38b7842376..19a14a2f7d 100644 --- a/Modules/Devices/src/Devices.Application/Tiers/Queries/ListTiers/ListTiersResponse.cs +++ b/Modules/Devices/src/Devices.Application/Tiers/Queries/ListTiers/ListTiersResponse.cs @@ -1,8 +1,14 @@ +using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.Persistence.Database; using Backbone.BuildingBlocks.Application.Pagination; using Backbone.Modules.Devices.Application.Tiers.DTOs; +using Backbone.Modules.Devices.Domain.Aggregates.Tier; namespace Backbone.Modules.Devices.Application.Tiers.Queries.ListTiers; + public class ListTiersResponse : PagedResponse { - public ListTiersResponse(IEnumerable items, PaginationFilter previousPaginationFilter, int totalRecords) : base(items, previousPaginationFilter, totalRecords) { } + public ListTiersResponse(DbPaginationResult dbPaginationResult, PaginationFilter previousPaginationFilter) : base(dbPaginationResult.ItemsOnPage.Select(el => new TierDTO(el.Id, el.Name)), + previousPaginationFilter, dbPaginationResult.TotalNumberOfItems) + { + } } diff --git a/Modules/Devices/src/Devices.Application/Users/Commands/SeedTestUsers/SeedTestUsersCommand.cs b/Modules/Devices/src/Devices.Application/Users/Commands/SeedTestUsers/SeedTestUsersCommand.cs index e6afe199a4..fb9d91cb13 100644 --- a/Modules/Devices/src/Devices.Application/Users/Commands/SeedTestUsers/SeedTestUsersCommand.cs +++ b/Modules/Devices/src/Devices.Application/Users/Commands/SeedTestUsers/SeedTestUsersCommand.cs @@ -1,4 +1,5 @@ using MediatR; namespace Backbone.Modules.Devices.Application.Users.Commands.SeedTestUsers; + public class SeedTestUsersCommand : IRequest; diff --git a/Modules/Devices/src/Devices.ConsumerApi/Controllers/DevicesController.cs b/Modules/Devices/src/Devices.ConsumerApi/Controllers/DevicesController.cs index 60d2bf51c7..ea00ab4ce2 100644 --- a/Modules/Devices/src/Devices.ConsumerApi/Controllers/DevicesController.cs +++ b/Modules/Devices/src/Devices.ConsumerApi/Controllers/DevicesController.cs @@ -72,7 +72,7 @@ public async Task ChangePassword(ChangePasswordCommand request, C [HttpGet] [ProducesResponseType(typeof(PagedHttpResponseEnvelope), StatusCodes.Status200OK)] - public async Task ListDevices([FromQuery] PaginationFilter paginationFilter, [FromQuery] IEnumerable ids, CancellationToken cancellationToken) + public async Task ListDevices([FromQuery] PaginationFilter paginationFilter, [FromQuery] IEnumerable ids, CancellationToken cancellationToken) { paginationFilter.PageSize ??= _options.Pagination.DefaultPageSize; diff --git a/Modules/Devices/src/Devices.Domain/Aggregates/PushNotifications/DevicePushIdentifier.cs b/Modules/Devices/src/Devices.Domain/Aggregates/PushNotifications/DevicePushIdentifier.cs index 01c0dca525..0847c2dd29 100644 --- a/Modules/Devices/src/Devices.Domain/Aggregates/PushNotifications/DevicePushIdentifier.cs +++ b/Modules/Devices/src/Devices.Domain/Aggregates/PushNotifications/DevicePushIdentifier.cs @@ -10,8 +10,8 @@ namespace Backbone.Modules.Devices.Domain.Aggregates.PushNotifications; public record DevicePushIdentifier : StronglyTypedId { public const int MAX_LENGTH = DEFAULT_MAX_LENGTH; - private const string PREFIX = "DPI"; + private static readonly StronglyTypedIdHelpers UTILS = new(PREFIX, DEFAULT_VALID_CHARS, MAX_LENGTH); private DevicePushIdentifier(string stringValue) : base(stringValue) { @@ -28,6 +28,11 @@ public static DevicePushIdentifier Parse(string stringValue) return new DevicePushIdentifier(stringValue); } + public static bool IsValid(string stringValue) + { + return UTILS.IsValid(stringValue); + } + public class DevicePushIdentifierTypeConverter : TypeConverter { public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType) diff --git a/Modules/Devices/src/Devices.Domain/Aggregates/Tier/TierId.cs b/Modules/Devices/src/Devices.Domain/Aggregates/Tier/TierId.cs index efdb09029c..2a3dbc0bd2 100644 --- a/Modules/Devices/src/Devices.Domain/Aggregates/Tier/TierId.cs +++ b/Modules/Devices/src/Devices.Domain/Aggregates/Tier/TierId.cs @@ -14,6 +14,11 @@ public record TierId : StronglyTypedId private TierId(string value) : base(value) { } + public static bool IsValid(string stringValue) + { + return UTILS.IsValid(stringValue); + } + public static TierId Generate() { var randomPart = StringUtils.Generate(DEFAULT_VALID_CHARS, DEFAULT_MAX_LENGTH_WITHOUT_PREFIX); diff --git a/Modules/Devices/src/Devices.Domain/Entities/Identities/IdentityDeletionProcessAuditLogEntryId.cs b/Modules/Devices/src/Devices.Domain/Entities/Identities/IdentityDeletionProcessAuditLogEntryId.cs index cf80bf6c79..2beafa6fc4 100644 --- a/Modules/Devices/src/Devices.Domain/Entities/Identities/IdentityDeletionProcessAuditLogEntryId.cs +++ b/Modules/Devices/src/Devices.Domain/Entities/Identities/IdentityDeletionProcessAuditLogEntryId.cs @@ -30,4 +30,9 @@ public static Result Create return Result.Success(new IdentityDeletionProcessAuditLogEntryId(value)); } + + public static bool IsValid(string stringValue) + { + return UTILS.IsValid(stringValue); + } } diff --git a/Modules/Devices/src/Devices.Domain/Entities/Identities/IdentityDeletionProcessId.cs b/Modules/Devices/src/Devices.Domain/Entities/Identities/IdentityDeletionProcessId.cs index a4189e8eb2..59bc600804 100644 --- a/Modules/Devices/src/Devices.Domain/Entities/Identities/IdentityDeletionProcessId.cs +++ b/Modules/Devices/src/Devices.Domain/Entities/Identities/IdentityDeletionProcessId.cs @@ -21,6 +21,16 @@ public static IdentityDeletionProcessId Generate() return new IdentityDeletionProcessId(PREFIX + randomPart); } + public static bool IsValid(string stringValue) + { + return UTILS.IsValid(stringValue); + } + + public static DomainError? Validate(string value) + { + return UTILS.Validate(value); + } + public static Result Create(string value) { var validationError = UTILS.Validate(value); diff --git a/Modules/Devices/test/Devices.Application.Tests/Tests/AutoMapper/AutoMapperProfileTests.cs b/Modules/Devices/test/Devices.Application.Tests/Tests/AutoMapper/AutoMapperProfileTests.cs deleted file mode 100644 index 626195661f..0000000000 --- a/Modules/Devices/test/Devices.Application.Tests/Tests/AutoMapper/AutoMapperProfileTests.cs +++ /dev/null @@ -1,19 +0,0 @@ -using AutoMapper; -using Backbone.Modules.Devices.Application.AutoMapper; -using Backbone.UnitTestTools.BaseClasses; -using Xunit; - -namespace Backbone.Modules.Devices.Application.Tests.Tests.AutoMapper; - -public class AutoMapperProfileTests : AbstractTestsBase -{ - [Fact] - public void ProfileIsValid() - { - // Arrange - var configuration = new MapperConfiguration(cfg => cfg.AddProfile()); - - // Act & Assert - configuration.AssertConfigurationIsValid(); - } -} diff --git a/Modules/Devices/test/Devices.Application.Tests/Tests/Devices/Commands/DeleteDevice/ValidatorTests.cs b/Modules/Devices/test/Devices.Application.Tests/Tests/Devices/Commands/DeleteDevice/ValidatorTests.cs new file mode 100644 index 0000000000..f073dd70f0 --- /dev/null +++ b/Modules/Devices/test/Devices.Application.Tests/Tests/Devices/Commands/DeleteDevice/ValidatorTests.cs @@ -0,0 +1,37 @@ +using Backbone.DevelopmentKit.Identity.ValueObjects; +using Backbone.Modules.Devices.Application.Devices.Commands.DeleteDevice; +using Backbone.UnitTestTools.BaseClasses; +using Backbone.UnitTestTools.FluentValidation; +using FluentValidation.TestHelper; +using Xunit; + +namespace Backbone.Modules.Devices.Application.Tests.Tests.Devices.Commands.DeleteDevice; + +public class ValidatorTests : AbstractTestsBase +{ + [Fact] + public void Happy_path() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new DeleteDeviceCommand { DeviceId = DeviceId.New() }); + + // Assert + validationResult.ShouldNotHaveAnyValidationErrors(); + } + + [Fact] + public void Fails_when_device_id_is_invalid() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new DeleteDeviceCommand { DeviceId = "some-invalid-device-id" }); + + // Assert + validationResult.ShouldHaveValidationErrorForId(nameof(DeleteDeviceCommand.DeviceId)); + } +} diff --git a/Modules/Devices/test/Devices.Application.Tests/Tests/Devices/Queries/ListDevices/ValidatorTests.cs b/Modules/Devices/test/Devices.Application.Tests/Tests/Devices/Queries/ListDevices/ValidatorTests.cs new file mode 100644 index 0000000000..06a96812e3 --- /dev/null +++ b/Modules/Devices/test/Devices.Application.Tests/Tests/Devices/Queries/ListDevices/ValidatorTests.cs @@ -0,0 +1,40 @@ +using Backbone.BuildingBlocks.Application.Pagination; +using Backbone.DevelopmentKit.Identity.ValueObjects; +using Backbone.Modules.Devices.Application.Devices.Queries.ListDevices; +using Backbone.UnitTestTools.BaseClasses; +using Backbone.UnitTestTools.FluentValidation; +using FluentValidation.TestHelper; +using Xunit; + +namespace Backbone.Modules.Devices.Application.Tests.Tests.Devices.Queries.ListDevices; + +public class ValidatorTests : AbstractTestsBase +{ + [Fact] + public void Happy_path() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new ListDevicesQuery(new PaginationFilter(), [DeviceId.New().Value])); + + // Assert + validationResult.ShouldNotHaveAnyValidationErrors(); + } + + [Fact] + public void Fails_when_device_id_is_invalid() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new ListDevicesQuery(new PaginationFilter(), ["some-invalid-device-id"])); + + // Assert + validationResult.ShouldHaveValidationErrorForIdInCollection( + collectionWithInvalidId: nameof(ListDevicesQuery.Ids), + indexWithInvalidId: 0); + } +} diff --git a/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/ApproveDeletionProcess/ValidatorTests.cs b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/ApproveDeletionProcess/ValidatorTests.cs new file mode 100644 index 0000000000..d4436b3bb7 --- /dev/null +++ b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/ApproveDeletionProcess/ValidatorTests.cs @@ -0,0 +1,37 @@ +using Backbone.Modules.Devices.Application.Identities.Commands.ApproveDeletionProcess; +using Backbone.Modules.Devices.Domain.Entities.Identities; +using Backbone.UnitTestTools.BaseClasses; +using Backbone.UnitTestTools.FluentValidation; +using FluentValidation.TestHelper; +using Xunit; + +namespace Backbone.Modules.Devices.Application.Tests.Tests.Identities.Commands.ApproveDeletionProcess; + +public class ValidatorTests : AbstractTestsBase +{ + [Fact] + public void Happy_path() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new ApproveDeletionProcessCommand(IdentityDeletionProcessId.Generate())); + + // Assert + validationResult.ShouldNotHaveAnyValidationErrors(); + } + + [Fact] + public void Fails_when_deletion_process_id_is_invalid() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new ApproveDeletionProcessCommand("invalid-deletion-process-id")); + + // Assert + validationResult.ShouldHaveValidationErrorForId(nameof(ApproveDeletionProcessCommand.DeletionProcessId)); + } +} diff --git a/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/CancelDeletionProcessAsOwner/ValidatorTests.cs b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/CancelDeletionProcessAsOwner/ValidatorTests.cs new file mode 100644 index 0000000000..373eb40088 --- /dev/null +++ b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/CancelDeletionProcessAsOwner/ValidatorTests.cs @@ -0,0 +1,37 @@ +using Backbone.Modules.Devices.Application.Identities.Commands.CancelDeletionProcessAsOwner; +using Backbone.Modules.Devices.Domain.Entities.Identities; +using Backbone.UnitTestTools.BaseClasses; +using Backbone.UnitTestTools.FluentValidation; +using FluentValidation.TestHelper; +using Xunit; + +namespace Backbone.Modules.Devices.Application.Tests.Tests.Identities.Commands.CancelDeletionProcessAsOwner; + +public class ValidatorTests : AbstractTestsBase +{ + [Fact] + public void Happy_path() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new CancelDeletionProcessAsOwnerCommand(IdentityDeletionProcessId.Generate())); + + // Assert + validationResult.ShouldNotHaveAnyValidationErrors(); + } + + [Fact] + public void Fails_when_deletion_process_id_is_invalid() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new CancelDeletionProcessAsOwnerCommand("invalid-deletion-process-id")); + + // Assert + validationResult.ShouldHaveValidationErrorForId(nameof(CancelDeletionProcessAsOwnerCommand.DeletionProcessId)); + } +} diff --git a/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/CancelDeletionProcessAsSupport/ValidatorTests.cs b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/CancelDeletionProcessAsSupport/ValidatorTests.cs new file mode 100644 index 0000000000..0d6dfb45ec --- /dev/null +++ b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/CancelDeletionProcessAsSupport/ValidatorTests.cs @@ -0,0 +1,50 @@ +using Backbone.Modules.Devices.Application.Identities.Commands.CancelDeletionProcessAsSupport; +using Backbone.Modules.Devices.Domain.Entities.Identities; +using Backbone.UnitTestTools.BaseClasses; +using Backbone.UnitTestTools.FluentValidation; +using FluentValidation.TestHelper; +using Xunit; + +namespace Backbone.Modules.Devices.Application.Tests.Tests.Identities.Commands.CancelDeletionProcessAsSupport; + +public class ValidatorTests : AbstractTestsBase +{ + [Fact] + public void Happy_path() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new CancelDeletionAsSupportCommand(UnitTestTools.Data.TestDataGenerator.CreateRandomIdentityAddress(), IdentityDeletionProcessId.Generate())); + + // Assert + validationResult.ShouldNotHaveAnyValidationErrors(); + } + + [Fact] + public void Fails_when_identity_address_is_invalid() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new CancelDeletionAsSupportCommand("invalid-identity-address", IdentityDeletionProcessId.Generate())); + + // Assert + validationResult.ShouldHaveValidationErrorForId(nameof(CancelDeletionAsSupportCommand.Address)); + } + + [Fact] + public void Fails_when_deletion_process_id_is_invalid() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new CancelDeletionAsSupportCommand(UnitTestTools.Data.TestDataGenerator.CreateRandomIdentityAddress(), "invalid-deletion-process-id")); + + // Assert + validationResult.ShouldHaveValidationErrorForId(nameof(CancelDeletionAsSupportCommand.DeletionProcessId)); + } +} diff --git a/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/DeleteIdentity/ValidatorTests.cs b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/DeleteIdentity/ValidatorTests.cs new file mode 100644 index 0000000000..7ecd490d36 --- /dev/null +++ b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/DeleteIdentity/ValidatorTests.cs @@ -0,0 +1,36 @@ +using Backbone.Modules.Devices.Application.Identities.Commands.DeleteIdentity; +using Backbone.UnitTestTools.BaseClasses; +using Backbone.UnitTestTools.FluentValidation; +using FluentValidation.TestHelper; +using Xunit; + +namespace Backbone.Modules.Devices.Application.Tests.Tests.Identities.Commands.DeleteIdentity; + +public class ValidatorTests : AbstractTestsBase +{ + [Fact] + public void Happy_path() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new DeleteIdentityCommand(UnitTestTools.Data.TestDataGenerator.CreateRandomIdentityAddress())); + + // Assert + validationResult.ShouldNotHaveAnyValidationErrors(); + } + + [Fact] + public void Fails_when_identity_address_is_invalid() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new DeleteIdentityCommand("invalid-identity-address")); + + // Assert + validationResult.ShouldHaveValidationErrorForId(nameof(DeleteIdentityCommand.IdentityAddress)); + } +} diff --git a/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/LogDeletionProcess/ValidatorTests.cs b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/LogDeletionProcess/ValidatorTests.cs new file mode 100644 index 0000000000..4ab2b6651a --- /dev/null +++ b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/LogDeletionProcess/ValidatorTests.cs @@ -0,0 +1,36 @@ +using Backbone.Modules.Devices.Application.Identities.Commands.LogDeletionProcess; +using Backbone.UnitTestTools.BaseClasses; +using Backbone.UnitTestTools.FluentValidation; +using FluentValidation.TestHelper; +using Xunit; + +namespace Backbone.Modules.Devices.Application.Tests.Tests.Identities.Commands.LogDeletionProcess; + +public class ValidatorTests : AbstractTestsBase +{ + [Fact] + public void Happy_path() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new LogDeletionProcessCommand(UnitTestTools.Data.TestDataGenerator.CreateRandomIdentityAddress(), "aggregateType")); + + // Assert + validationResult.ShouldNotHaveAnyValidationErrors(); + } + + [Fact] + public void Fails_when_identity_address_is_invalid() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new LogDeletionProcessCommand("invalid-identity-address", "aggregateType")); + + // Assert + validationResult.ShouldHaveValidationErrorForId(nameof(LogDeletionProcessCommand.IdentityAddress)); + } +} diff --git a/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/RejectDeletionProcess/ValidatorTests.cs b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/RejectDeletionProcess/ValidatorTests.cs new file mode 100644 index 0000000000..d1c1f7655c --- /dev/null +++ b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/RejectDeletionProcess/ValidatorTests.cs @@ -0,0 +1,37 @@ +using Backbone.Modules.Devices.Application.Identities.Commands.RejectDeletionProcess; +using Backbone.Modules.Devices.Domain.Entities.Identities; +using Backbone.UnitTestTools.BaseClasses; +using Backbone.UnitTestTools.FluentValidation; +using FluentValidation.TestHelper; +using Xunit; + +namespace Backbone.Modules.Devices.Application.Tests.Tests.Identities.Commands.RejectDeletionProcess; + +public class ValidatorTests : AbstractTestsBase +{ + [Fact] + public void Happy_path() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new RejectDeletionProcessCommand(IdentityDeletionProcessId.Generate())); + + // Assert + validationResult.ShouldNotHaveAnyValidationErrors(); + } + + [Fact] + public void Fails_when_deletion_process_id_is_invalid() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new RejectDeletionProcessCommand("invalid-deletion-process-id")); + + // Assert + validationResult.ShouldHaveValidationErrorForId(nameof(RejectDeletionProcessCommand.DeletionProcessId)); + } +} diff --git a/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/StartDeletionProcessAsSupport/ValidatorTests.cs b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/StartDeletionProcessAsSupport/ValidatorTests.cs new file mode 100644 index 0000000000..f95ce90f51 --- /dev/null +++ b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/StartDeletionProcessAsSupport/ValidatorTests.cs @@ -0,0 +1,36 @@ +using Backbone.Modules.Devices.Application.Identities.Commands.StartDeletionProcessAsSupport; +using Backbone.UnitTestTools.BaseClasses; +using Backbone.UnitTestTools.FluentValidation; +using FluentValidation.TestHelper; +using Xunit; + +namespace Backbone.Modules.Devices.Application.Tests.Tests.Identities.Commands.StartDeletionProcessAsSupport; + +public class ValidatorTests : AbstractTestsBase +{ + [Fact] + public void Happy_path() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new StartDeletionProcessAsSupportCommand(UnitTestTools.Data.TestDataGenerator.CreateRandomIdentityAddress())); + + // Assert + validationResult.ShouldNotHaveAnyValidationErrors(); + } + + [Fact] + public void Fails_when_identity_address_is_invalid() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new StartDeletionProcessAsSupportCommand("invalid-identity-address")); + + // Assert + validationResult.ShouldHaveValidationErrorForId(nameof(StartDeletionProcessAsSupportCommand.IdentityAddress)); + } +} diff --git a/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/UpdateIdentity/ValidatorTests.cs b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/UpdateIdentity/ValidatorTests.cs new file mode 100644 index 0000000000..f6e4599219 --- /dev/null +++ b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Commands/UpdateIdentity/ValidatorTests.cs @@ -0,0 +1,50 @@ +using Backbone.Modules.Devices.Application.Identities.Commands.UpdateIdentity; +using Backbone.Modules.Devices.Domain.Aggregates.Tier; +using Backbone.UnitTestTools.BaseClasses; +using Backbone.UnitTestTools.FluentValidation; +using FluentValidation.TestHelper; +using Xunit; + +namespace Backbone.Modules.Devices.Application.Tests.Tests.Identities.Commands.UpdateIdentity; + +public class ValidatorTests : AbstractTestsBase +{ + [Fact] + public void Happy_path() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new UpdateIdentityCommand { Address = UnitTestTools.Data.TestDataGenerator.CreateRandomIdentityAddress(), TierId = TierId.Generate() }); + + // Assert + validationResult.ShouldNotHaveAnyValidationErrors(); + } + + [Fact] + public void Fails_when_identity_address_is_invalid() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new UpdateIdentityCommand { Address = "some-invalid-address", TierId = TierId.Generate() }); + + // Assert + validationResult.ShouldHaveValidationErrorForId(nameof(UpdateIdentityCommand.Address)); + } + + [Fact] + public void Fails_when_tier_id_is_invalid() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new UpdateIdentityCommand { Address = UnitTestTools.Data.TestDataGenerator.CreateRandomIdentityAddress(), TierId = "some-invalid-tier-id" }); + + // Assert + validationResult.ShouldHaveValidationErrorForId(nameof(UpdateIdentityCommand.TierId)); + } +} diff --git a/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Queries/GetDeletionProcessAsOwner/ValidatorTests.cs b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Queries/GetDeletionProcessAsOwner/ValidatorTests.cs new file mode 100644 index 0000000000..081043d6bc --- /dev/null +++ b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Queries/GetDeletionProcessAsOwner/ValidatorTests.cs @@ -0,0 +1,37 @@ +using Backbone.Modules.Devices.Application.Identities.Queries.GetDeletionProcessAsOwner; +using Backbone.Modules.Devices.Domain.Entities.Identities; +using Backbone.UnitTestTools.BaseClasses; +using Backbone.UnitTestTools.FluentValidation; +using FluentValidation.TestHelper; +using Xunit; + +namespace Backbone.Modules.Devices.Application.Tests.Tests.Identities.Queries.GetDeletionProcessAsOwner; + +public class ValidatorTests : AbstractTestsBase +{ + [Fact] + public void Happy_path() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new GetDeletionProcessAsOwnerQuery { Id = IdentityDeletionProcessId.Generate() }); + + // Assert + validationResult.ShouldNotHaveAnyValidationErrors(); + } + + [Fact] + public void Fails_when_deletion_process_id_is_invalid() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new GetDeletionProcessAsOwnerQuery { Id = "some-invalid-deletion-process-id" }); + + // Assert + validationResult.ShouldHaveValidationErrorForId(nameof(GetDeletionProcessAsOwnerQuery.Id)); + } +} diff --git a/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Queries/GetDeletionProcessAsSupport/ValidatorTests.cs b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Queries/GetDeletionProcessAsSupport/ValidatorTests.cs new file mode 100644 index 0000000000..aa784d0c64 --- /dev/null +++ b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Queries/GetDeletionProcessAsSupport/ValidatorTests.cs @@ -0,0 +1,50 @@ +using Backbone.Modules.Devices.Application.Identities.Queries.GetDeletionProcessAsSupport; +using Backbone.Modules.Devices.Domain.Entities.Identities; +using Backbone.UnitTestTools.BaseClasses; +using Backbone.UnitTestTools.FluentValidation; +using FluentValidation.TestHelper; +using Xunit; + +namespace Backbone.Modules.Devices.Application.Tests.Tests.Identities.Queries.GetDeletionProcessAsSupport; + +public class ValidatorTests : AbstractTestsBase +{ + [Fact] + public void Happy_path() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new GetDeletionProcessAsSupportQuery(UnitTestTools.Data.TestDataGenerator.CreateRandomIdentityAddress(), IdentityDeletionProcessId.Generate())); + + // Assert + validationResult.ShouldNotHaveAnyValidationErrors(); + } + + [Fact] + public void Fails_when_identity_address_is_invalid() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new GetDeletionProcessAsSupportQuery("invalid-identity-address", IdentityDeletionProcessId.Generate())); + + // Assert + validationResult.ShouldHaveValidationErrorForId(nameof(GetDeletionProcessAsSupportQuery.IdentityAddress)); + } + + [Fact] + public void Fails_when_deletion_process_id_is_invalid() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new GetDeletionProcessAsSupportQuery(UnitTestTools.Data.TestDataGenerator.CreateRandomIdentityAddress(), "invalid-deletion-process-id")); + + // Assert + validationResult.ShouldHaveValidationErrorForId(nameof(GetDeletionProcessAsSupportQuery.DeletionProcessId)); + } +} diff --git a/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Queries/GetDeletionProcessesAsSupport/ValidatorTests.cs b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Queries/GetDeletionProcessesAsSupport/ValidatorTests.cs new file mode 100644 index 0000000000..3ea493acd8 --- /dev/null +++ b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Queries/GetDeletionProcessesAsSupport/ValidatorTests.cs @@ -0,0 +1,36 @@ +using Backbone.Modules.Devices.Application.Identities.Queries.GetDeletionProcessesAsSupport; +using Backbone.UnitTestTools.BaseClasses; +using Backbone.UnitTestTools.FluentValidation; +using FluentValidation.TestHelper; +using Xunit; + +namespace Backbone.Modules.Devices.Application.Tests.Tests.Identities.Queries.GetDeletionProcessesAsSupport; + +public class ValidatorTests : AbstractTestsBase +{ + [Fact] + public void Happy_path() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new GetDeletionProcessesAsSupportQuery(UnitTestTools.Data.TestDataGenerator.CreateRandomIdentityAddress())); + + // Assert + validationResult.ShouldNotHaveAnyValidationErrors(); + } + + [Fact] + public void Fails_when_identity_address_is_invalid() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new GetDeletionProcessesAsSupportQuery("some-invalid-address")); + + // Assert + validationResult.ShouldHaveValidationErrorForId(nameof(GetDeletionProcessesAsSupportQuery.IdentityAddress)); + } +} diff --git a/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Queries/GetDeletionProcessesAuditLogs/ValidatorTests.cs b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Queries/GetDeletionProcessesAuditLogs/ValidatorTests.cs new file mode 100644 index 0000000000..e64754d6cd --- /dev/null +++ b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Queries/GetDeletionProcessesAuditLogs/ValidatorTests.cs @@ -0,0 +1,36 @@ +using Backbone.Modules.Devices.Application.Identities.Queries.GetDeletionProcessesAuditLogs; +using Backbone.UnitTestTools.BaseClasses; +using Backbone.UnitTestTools.FluentValidation; +using FluentValidation.TestHelper; +using Xunit; + +namespace Backbone.Modules.Devices.Application.Tests.Tests.Identities.Queries.GetDeletionProcessesAuditLogs; + +public class ValidatorTests : AbstractTestsBase +{ + [Fact] + public void Happy_path() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new GetDeletionProcessesAuditLogsQuery(UnitTestTools.Data.TestDataGenerator.CreateRandomIdentityAddress())); + + // Assert + validationResult.ShouldNotHaveAnyValidationErrors(); + } + + [Fact] + public void Fails_when_identity_address_is_invalid() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new GetDeletionProcessesAuditLogsQuery("some-invalid-address")); + + // Assert + validationResult.ShouldHaveValidationErrorForId(nameof(GetDeletionProcessesAuditLogsQuery.IdentityAddress)); + } +} diff --git a/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Queries/GetIdentity/ValidatorTests.cs b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Queries/GetIdentity/ValidatorTests.cs new file mode 100644 index 0000000000..5eded05cad --- /dev/null +++ b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Queries/GetIdentity/ValidatorTests.cs @@ -0,0 +1,36 @@ +using Backbone.Modules.Devices.Application.Identities.Queries.GetIdentity; +using Backbone.UnitTestTools.BaseClasses; +using Backbone.UnitTestTools.FluentValidation; +using FluentValidation.TestHelper; +using Xunit; + +namespace Backbone.Modules.Devices.Application.Tests.Tests.Identities.Queries.GetIdentity; + +public class ValidatorTests : AbstractTestsBase +{ + [Fact] + public void Happy_path() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new GetIdentityQuery(UnitTestTools.Data.TestDataGenerator.CreateRandomIdentityAddress())); + + // Assert + validationResult.ShouldNotHaveAnyValidationErrors(); + } + + [Fact] + public void Fails_when_identity_address_is_invalid() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new GetIdentityQuery("some-invalid-address")); + + // Assert + validationResult.ShouldHaveValidationErrorForId(nameof(GetIdentityQuery.Address)); + } +} diff --git a/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Queries/ListIdentities/ValidatorTests.cs b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Queries/ListIdentities/ValidatorTests.cs new file mode 100644 index 0000000000..1408b6bb9d --- /dev/null +++ b/Modules/Devices/test/Devices.Application.Tests/Tests/Identities/Queries/ListIdentities/ValidatorTests.cs @@ -0,0 +1,39 @@ +using Backbone.Modules.Devices.Application.Identities.Queries.ListIdentities; +using Backbone.Modules.Devices.Domain.Entities.Identities; +using Backbone.UnitTestTools.BaseClasses; +using Backbone.UnitTestTools.FluentValidation; +using FluentValidation.TestHelper; +using Xunit; + +namespace Backbone.Modules.Devices.Application.Tests.Tests.Identities.Queries.ListIdentities; + +public class ValidatorTests : AbstractTestsBase +{ + [Fact] + public void Happy_path() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new ListIdentitiesQuery([UnitTestTools.Data.TestDataGenerator.CreateRandomIdentityAddress()], IdentityStatus.Active)); + + // Assert + validationResult.ShouldNotHaveAnyValidationErrors(); + } + + [Fact] + public void Fails_when_identity_address_is_invalid() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new ListIdentitiesQuery(["some-invalid-address"], IdentityStatus.Active)); + + // Assert + validationResult.ShouldHaveValidationErrorForIdInCollection( + collectionWithInvalidId: nameof(ListIdentitiesQuery.Addresses), + indexWithInvalidId: 0); + } +} diff --git a/Modules/Devices/test/Devices.Application.Tests/Tests/PushNotifications/DeletePnsRegistrationsOfIdentity/ValidatorTests.cs b/Modules/Devices/test/Devices.Application.Tests/Tests/PushNotifications/DeletePnsRegistrationsOfIdentity/ValidatorTests.cs new file mode 100644 index 0000000000..dd267b2321 --- /dev/null +++ b/Modules/Devices/test/Devices.Application.Tests/Tests/PushNotifications/DeletePnsRegistrationsOfIdentity/ValidatorTests.cs @@ -0,0 +1,36 @@ +using Backbone.Modules.Devices.Application.PushNotifications.Commands.DeletePnsRegistrationsOfIdentity; +using Backbone.UnitTestTools.BaseClasses; +using Backbone.UnitTestTools.FluentValidation; +using FluentValidation.TestHelper; +using Xunit; + +namespace Backbone.Modules.Devices.Application.Tests.Tests.PushNotifications.DeletePnsRegistrationsOfIdentity; + +public class ValidatorTests : AbstractTestsBase +{ + [Fact] + public void Happy_path() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new DeletePnsRegistrationsOfIdentityCommand(UnitTestTools.Data.TestDataGenerator.CreateRandomIdentityAddress())); + + // Assert + validationResult.ShouldNotHaveAnyValidationErrors(); + } + + [Fact] + public void Fails_when_identity_address_is_invalid() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new DeletePnsRegistrationsOfIdentityCommand("some-invalid-address")); + + // Assert + validationResult.ShouldHaveValidationErrorForId(nameof(DeletePnsRegistrationsOfIdentityCommand.IdentityAddress)); + } +} diff --git a/Modules/Devices/test/Devices.Application.Tests/Tests/PushNotifications/HandlerTests.cs b/Modules/Devices/test/Devices.Application.Tests/Tests/PushNotifications/UpdateDeviceRegistration/HandlerTests.cs similarity index 98% rename from Modules/Devices/test/Devices.Application.Tests/Tests/PushNotifications/HandlerTests.cs rename to Modules/Devices/test/Devices.Application.Tests/Tests/PushNotifications/UpdateDeviceRegistration/HandlerTests.cs index 65b1da1927..951a0b3399 100644 --- a/Modules/Devices/test/Devices.Application.Tests/Tests/PushNotifications/HandlerTests.cs +++ b/Modules/Devices/test/Devices.Application.Tests/Tests/PushNotifications/UpdateDeviceRegistration/HandlerTests.cs @@ -9,7 +9,7 @@ using Xunit; using static Backbone.UnitTestTools.Data.TestDataGenerator; -namespace Backbone.Modules.Devices.Application.Tests.Tests.PushNotifications; +namespace Backbone.Modules.Devices.Application.Tests.Tests.PushNotifications.UpdateDeviceRegistration; public class HandlerTests : AbstractTestsBase { diff --git a/Modules/Devices/test/Devices.Application.Tests/Tests/Tiers/Commands/CreateTier/CreateTierCommandValidatorTests.cs b/Modules/Devices/test/Devices.Application.Tests/Tests/Tiers/Commands/CreateTier/CreateTierCommandValidatorTests.cs deleted file mode 100644 index 208da54072..0000000000 --- a/Modules/Devices/test/Devices.Application.Tests/Tests/Tiers/Commands/CreateTier/CreateTierCommandValidatorTests.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Backbone.Modules.Devices.Application.Tiers.Commands.CreateTier; -using Backbone.UnitTestTools.BaseClasses; -using FluentAssertions; -using FluentValidation.TestHelper; -using Xunit; - -namespace Backbone.Modules.Devices.Application.Tests.Tests.Tiers.Commands.CreateTier; - -public class CreateTierCommandValidatorTests : AbstractTestsBase -{ - - [Theory] - [InlineData("tr")] - [InlineData("a-tier-name-with-more-than-30-characters")] - public void Validation_fails_for_invalid_tier_name(string value) - { - var validator = new CreateTierCommandValidator(); - var validationResult = validator.TestValidate(new CreateTierCommand(value)); - - validationResult.ShouldHaveValidationErrorFor(x => x.Name); - validationResult.Errors.Should().HaveCount(1); - validationResult.Errors.First().ErrorCode.Should().Be("error.platform.validation.invalidTierName"); - validationResult.Errors.First().ErrorMessage.Should().Contain("Tier Name length must be between"); - } -} diff --git a/Modules/Devices/test/Devices.Application.Tests/Tests/Tiers/Commands/CreateTier/ValidatorTests.cs b/Modules/Devices/test/Devices.Application.Tests/Tests/Tiers/Commands/CreateTier/ValidatorTests.cs new file mode 100644 index 0000000000..5d16006e8b --- /dev/null +++ b/Modules/Devices/test/Devices.Application.Tests/Tests/Tiers/Commands/CreateTier/ValidatorTests.cs @@ -0,0 +1,30 @@ +using Backbone.Modules.Devices.Application.Tiers.Commands.CreateTier; +using Backbone.Modules.Devices.Domain.Aggregates.Tier; +using Backbone.UnitTestTools.BaseClasses; +using Backbone.UnitTestTools.FluentValidation; +using FluentValidation.TestHelper; +using Xunit; +using Validator = Backbone.Modules.Devices.Application.Tiers.Commands.CreateTier.Validator; + +namespace Backbone.Modules.Devices.Application.Tests.Tests.Tiers.Commands.CreateTier; + +public class ValidatorTests : AbstractTestsBase +{ + [Theory] + [InlineData("tr")] + [InlineData("a-tier-name-with-more-than-30-characters")] + public void Validation_fails_for_invalid_tier_name(string value) + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new CreateTierCommand(value)); + + // Assert + validationResult.ShouldHaveValidationErrorForItem( + propertyName: nameof(CreateTierCommand.Name), + expectedErrorCode: "error.platform.validation.invalidTierName", + expectedErrorMessage: $"Tier Name length must be between {TierName.MIN_LENGTH} and {TierName.MAX_LENGTH}"); + } +} diff --git a/Modules/Devices/test/Devices.Application.Tests/Tests/Tiers/Commands/DeleteTier/ValidatorTests.cs b/Modules/Devices/test/Devices.Application.Tests/Tests/Tiers/Commands/DeleteTier/ValidatorTests.cs new file mode 100644 index 0000000000..00dcf3850b --- /dev/null +++ b/Modules/Devices/test/Devices.Application.Tests/Tests/Tiers/Commands/DeleteTier/ValidatorTests.cs @@ -0,0 +1,37 @@ +using Backbone.Modules.Devices.Application.Tiers.Commands.DeleteTier; +using Backbone.Modules.Devices.Domain.Aggregates.Tier; +using Backbone.UnitTestTools.BaseClasses; +using Backbone.UnitTestTools.FluentValidation; +using FluentValidation.TestHelper; +using Xunit; + +namespace Backbone.Modules.Devices.Application.Tests.Tests.Tiers.Commands.DeleteTier; + +public class ValidatorTests : AbstractTestsBase +{ + [Fact] + public void Happy_path() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new DeleteTierCommand(TierId.Generate())); + + // Assert + validationResult.ShouldNotHaveAnyValidationErrors(); + } + + [Fact] + public void Fails_when_tier_id_is_invalid() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new DeleteTierCommand("invalid-tier_id")); + + // Assert + validationResult.ShouldHaveValidationErrorForId(nameof(DeleteTierCommand.TierId)); + } +} diff --git a/Modules/Files/src/Files.Application/AutoMapper/AutoMapperProfile.cs b/Modules/Files/src/Files.Application/AutoMapper/AutoMapperProfile.cs deleted file mode 100644 index af714a78d8..0000000000 --- a/Modules/Files/src/Files.Application/AutoMapper/AutoMapperProfile.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Reflection; -using AutoMapper; -using Backbone.BuildingBlocks.Application.AutoMapper; - -namespace Backbone.Modules.Files.Application.AutoMapper; - -public class AutoMapperProfile : AutoMapperProfileBase -{ - public AutoMapperProfile() : base(Assembly.GetExecutingAssembly()) { } - - public static IMapper CreateMapper() - { - var profile = new AutoMapperProfile(); - var config = new MapperConfiguration(cfg => cfg.AddProfile(profile)); - var mapper = config.CreateMapper(); - return mapper; - } -} diff --git a/Modules/Files/src/Files.Application/Extensions/IServiceCollectionExtensions.cs b/Modules/Files/src/Files.Application/Extensions/IServiceCollectionExtensions.cs index e29a819317..62607c9f81 100644 --- a/Modules/Files/src/Files.Application/Extensions/IServiceCollectionExtensions.cs +++ b/Modules/Files/src/Files.Application/Extensions/IServiceCollectionExtensions.cs @@ -1,5 +1,4 @@ using Backbone.BuildingBlocks.Application.MediatR; -using Backbone.Modules.Files.Application.AutoMapper; using Backbone.Modules.Files.Application.Files.Commands.CreateFile; using FluentValidation; using Microsoft.Extensions.DependencyInjection; @@ -16,7 +15,6 @@ public static void AddApplication(this IServiceCollection services) .AddOpenBehavior(typeof(RequestValidationBehavior<,>)) .AddOpenBehavior(typeof(QuotaEnforcerBehavior<,>)) ); - services.AddAutoMapper(typeof(AutoMapperProfile)); - services.AddValidatorsFromAssemblyContaining(); + services.AddValidatorsFromAssemblyContaining(); } } diff --git a/Modules/Files/src/Files.Application/Files/Commands/CreateFile/CreateFileCommand.cs b/Modules/Files/src/Files.Application/Files/Commands/CreateFile/CreateFileCommand.cs index bc529ed2f8..12f10fae74 100644 --- a/Modules/Files/src/Files.Application/Files/Commands/CreateFile/CreateFileCommand.cs +++ b/Modules/Files/src/Files.Application/Files/Commands/CreateFile/CreateFileCommand.cs @@ -1,5 +1,4 @@ using Backbone.BuildingBlocks.Application.Attributes; -using Backbone.DevelopmentKit.Identity.ValueObjects; using MediatR; namespace Backbone.Modules.Files.Application.Files.Commands.CreateFile; @@ -9,7 +8,7 @@ public class CreateFileCommand : IRequest { public required byte[] FileContent { get; set; } - public required IdentityAddress Owner { get; set; } + public required string Owner { get; set; } public required byte[] OwnerSignature { get; set; } public required byte[] CipherHash { get; set; } diff --git a/Modules/Files/src/Files.Application/Files/Commands/CreateFile/CreateFileResponse.cs b/Modules/Files/src/Files.Application/Files/Commands/CreateFile/CreateFileResponse.cs index a65527bda0..f9f871d480 100644 --- a/Modules/Files/src/Files.Application/Files/Commands/CreateFile/CreateFileResponse.cs +++ b/Modules/Files/src/Files.Application/Files/Commands/CreateFile/CreateFileResponse.cs @@ -1,36 +1,42 @@ -using AutoMapper; -using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.Mapping; -using Backbone.DevelopmentKit.Identity.ValueObjects; -using Backbone.Modules.Files.Domain.Entities; using File = Backbone.Modules.Files.Domain.Entities.File; namespace Backbone.Modules.Files.Application.Files.Commands.CreateFile; -public class CreateFileResponse : IHaveCustomMapping +public class CreateFileResponse { - public required FileId Id { get; set; } + public CreateFileResponse(File file) + { + Id = file.Id; + CreatedAt = file.CreatedAt; + CreatedBy = file.CreatedBy; + CreatedByDevice = file.CreatedByDevice; + ModifiedAt = file.ModifiedAt; + ModifiedBy = file.ModifiedBy; + DeletedAt = file.DeletedAt; + DeletedBy = file.DeletedBy?.Value; + Owner = file.Owner; + OwnerSignature = file.OwnerSignature; + CipherSize = file.CipherSize; + CipherHash = file.CipherHash; + ExpiresAt = file.ExpiresAt; + } - public required DateTime CreatedAt { get; set; } - public required IdentityAddress CreatedBy { get; set; } - public required DeviceId CreatedByDevice { get; set; } + public string Id { get; set; } - public required DateTime ModifiedAt { get; set; } - public required IdentityAddress ModifiedBy { get; set; } - public DateTime? DeletedAt { get; set; } - public IdentityAddress? DeletedBy { get; set; } + public DateTime CreatedAt { get; set; } + public string CreatedBy { get; set; } + public string CreatedByDevice { get; set; } - public required IdentityAddress Owner { get; set; } - public required byte[] OwnerSignature { get; set; } + public DateTime ModifiedAt { get; set; } + public string ModifiedBy { get; set; } + public DateTime? DeletedAt { get; set; } + public string? DeletedBy { get; set; } - public required long CipherSize { get; set; } - public required byte[] CipherHash { get; set; } + public string Owner { get; set; } + public byte[] OwnerSignature { get; set; } - public required DateTime ExpiresAt { get; set; } + public long CipherSize { get; set; } + public byte[] CipherHash { get; set; } - public void CreateMappings(Profile configuration) - { - configuration - .CreateMap() - .ForMember(dto => dto.OwnerSignature, c => c.MapFrom(f => f.OwnerSignature.Length == 0 ? null : f.OwnerSignature)); - } + public DateTime ExpiresAt { get; set; } } diff --git a/Modules/Files/src/Files.Application/Files/Commands/CreateFile/Handler.cs b/Modules/Files/src/Files.Application/Files/Commands/CreateFile/Handler.cs index efa0ffc7eb..e004d5cf17 100644 --- a/Modules/Files/src/Files.Application/Files/Commands/CreateFile/Handler.cs +++ b/Modules/Files/src/Files.Application/Files/Commands/CreateFile/Handler.cs @@ -1,8 +1,5 @@ -using AutoMapper; -using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.EventBus; using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.UserContext; using Backbone.Modules.Files.Application.Infrastructure.Persistence.Repository; -using Backbone.Modules.Files.Domain.DomainEvents.Out; using MediatR; using File = Backbone.Modules.Files.Domain.Entities.File; @@ -10,14 +7,12 @@ namespace Backbone.Modules.Files.Application.Files.Commands.CreateFile; public class Handler : IRequestHandler { - private readonly IMapper _mapper; private readonly IFilesRepository _filesRepository; private readonly IUserContext _userContext; - public Handler(IUserContext userContext, IMapper mapper, IFilesRepository filesRepository) + public Handler(IUserContext userContext, IFilesRepository filesRepository) { _userContext = userContext; - _mapper = mapper; _filesRepository = filesRepository; } @@ -40,8 +35,6 @@ await _filesRepository.Add( cancellationToken ); - var response = _mapper.Map(file); - - return response; + return new CreateFileResponse(file); } } diff --git a/Modules/Files/src/Files.Application/Files/Commands/CreateFile/CreateFileCommandValidator.cs b/Modules/Files/src/Files.Application/Files/Commands/CreateFile/Validator.cs similarity index 76% rename from Modules/Files/src/Files.Application/Files/Commands/CreateFile/CreateFileCommandValidator.cs rename to Modules/Files/src/Files.Application/Files/Commands/CreateFile/Validator.cs index cb34cbb4ff..2fd8bdadfd 100644 --- a/Modules/Files/src/Files.Application/Files/Commands/CreateFile/CreateFileCommandValidator.cs +++ b/Modules/Files/src/Files.Application/Files/Commands/CreateFile/Validator.cs @@ -1,14 +1,16 @@ using Backbone.BuildingBlocks.Application.Abstractions.Exceptions; +using Backbone.BuildingBlocks.Application.Extensions; using Backbone.BuildingBlocks.Application.FluentValidation; +using Backbone.DevelopmentKit.Identity.ValueObjects; using Backbone.Tooling; using Backbone.Tooling.Extensions; using FluentValidation; namespace Backbone.Modules.Files.Application.Files.Commands.CreateFile; -public class CreateFileCommandValidator : AbstractValidator +public class Validator : AbstractValidator { - public CreateFileCommandValidator() + public Validator() { RuleFor(r => r.FileContent) .DetailedNotNull() @@ -22,8 +24,8 @@ public CreateFileCommandValidator() .DetailedNotEmpty() .GreaterThan(SystemTime.UtcNow).WithMessage("'{PropertyName}' must be in the future.").WithErrorCode(GenericApplicationErrors.Validation.InvalidPropertyValue().Code); - RuleFor(m => m.Owner) - .DetailedNotEmpty(); + RuleFor(f => f.Owner) + .ValidId(); RuleFor(m => m.OwnerSignature) .NumberOfBytes(1, 512); diff --git a/Modules/Files/src/Files.Application/Files/DTOs/FileMetadataDTO.cs b/Modules/Files/src/Files.Application/Files/DTOs/FileMetadataDTO.cs index 114dbadea4..e5ce37c209 100644 --- a/Modules/Files/src/Files.Application/Files/DTOs/FileMetadataDTO.cs +++ b/Modules/Files/src/Files.Application/Files/DTOs/FileMetadataDTO.cs @@ -1,41 +1,50 @@ -using AutoMapper; -using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.Mapping; -using Backbone.DevelopmentKit.Identity.ValueObjects; -using Backbone.Modules.Files.Domain.Entities; using File = Backbone.Modules.Files.Domain.Entities.File; namespace Backbone.Modules.Files.Application.Files.DTOs; -public class FileMetadataDTO : IHaveCustomMapping +public class FileMetadataDTO { - public required FileId Id { get; set; } + public FileMetadataDTO(File file) + { + Id = file.Id; + CreatedAt = file.CreatedAt; + CreatedBy = file.CreatedBy; + CreatedByDevice = file.CreatedByDevice; + ModifiedAt = file.ModifiedAt; + ModifiedBy = file.ModifiedBy; + ModifiedByDevice = file.ModifiedByDevice; + DeletedAt = file.DeletedAt; + DeletedBy = file.DeletedBy?.Value; + DeletedByDevice = file.DeletedByDevice?.Value; + Owner = file.Owner; + OwnerSignature = file.OwnerSignature; + CipherSize = file.CipherSize; + CipherHash = file.CipherHash; + ExpiresAt = file.ExpiresAt; + EncryptedProperties = file.EncryptedProperties; + } - public required DateTime CreatedAt { get; set; } - public required IdentityAddress CreatedBy { get; set; } - public required DeviceId CreatedByDevice { get; set; } + public string Id { get; set; } - public required DateTime ModifiedAt { get; set; } - public required IdentityAddress ModifiedBy { get; set; } - public required DeviceId ModifiedByDevice { get; set; } + public DateTime CreatedAt { get; set; } + public string CreatedBy { get; set; } + public string CreatedByDevice { get; set; } - public DateTime? DeletedAt { get; set; } - public IdentityAddress? DeletedBy { get; set; } - public DeviceId? DeletedByDevice { get; set; } + public DateTime ModifiedAt { get; set; } + public string ModifiedBy { get; set; } + public string ModifiedByDevice { get; set; } - public required IdentityAddress Owner { get; set; } - public required byte[] OwnerSignature { get; set; } + public DateTime? DeletedAt { get; set; } + public string? DeletedBy { get; set; } + public string? DeletedByDevice { get; set; } - public required long CipherSize { get; set; } - public required byte[] CipherHash { get; set; } + public string Owner { get; set; } + public byte[] OwnerSignature { get; set; } - public required DateTime ExpiresAt { get; set; } + public long CipherSize { get; set; } + public byte[] CipherHash { get; set; } - public required byte[] EncryptedProperties { get; set; } + public DateTime ExpiresAt { get; set; } - public void CreateMappings(Profile configuration) - { - configuration - .CreateMap() - .ForMember(dto => dto.OwnerSignature, c => c.MapFrom(f => f.OwnerSignature.Length == 0 ? null : f.OwnerSignature)); - } + public byte[] EncryptedProperties { get; set; } } diff --git a/Modules/Files/src/Files.Application/Files/Queries/GetFileContent/GetFileContentQuery.cs b/Modules/Files/src/Files.Application/Files/Queries/GetFileContent/GetFileContentQuery.cs index 8c4c5edaeb..ecfbefc23f 100644 --- a/Modules/Files/src/Files.Application/Files/Queries/GetFileContent/GetFileContentQuery.cs +++ b/Modules/Files/src/Files.Application/Files/Queries/GetFileContent/GetFileContentQuery.cs @@ -1,9 +1,8 @@ -using Backbone.Modules.Files.Domain.Entities; using MediatR; namespace Backbone.Modules.Files.Application.Files.Queries.GetFileContent; public class GetFileContentQuery : IRequest { - public required FileId Id { get; set; } + public required string Id { get; set; } } diff --git a/Modules/Files/src/Files.Application/Files/Queries/GetFileContent/Handler.cs b/Modules/Files/src/Files.Application/Files/Queries/GetFileContent/Handler.cs index 2884f80c0b..25bbe5e95e 100644 --- a/Modules/Files/src/Files.Application/Files/Queries/GetFileContent/Handler.cs +++ b/Modules/Files/src/Files.Application/Files/Queries/GetFileContent/Handler.cs @@ -1,6 +1,8 @@ using Backbone.BuildingBlocks.Application.Abstractions.Exceptions; using Backbone.Modules.Files.Application.Infrastructure.Persistence.Repository; +using Backbone.Modules.Files.Domain.Entities; using MediatR; +using File = System.IO.File; namespace Backbone.Modules.Files.Application.Files.Queries.GetFileContent; @@ -15,7 +17,7 @@ public Handler(IFilesRepository filesRepository) public async Task Handle(GetFileContentQuery request, CancellationToken cancellationToken) { - var file = await _filesRepository.Find(request.Id, cancellationToken) ?? throw new NotFoundException(nameof(File)); + var file = await _filesRepository.Find(FileId.Parse(request.Id), cancellationToken) ?? throw new NotFoundException(nameof(File)); return new GetFileContentResponse() { FileContent = file.Content diff --git a/Modules/Files/src/Files.Application/Files/Queries/GetFileContent/Validator.cs b/Modules/Files/src/Files.Application/Files/Queries/GetFileContent/Validator.cs new file mode 100644 index 0000000000..47a697dd1e --- /dev/null +++ b/Modules/Files/src/Files.Application/Files/Queries/GetFileContent/Validator.cs @@ -0,0 +1,13 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.Modules.Files.Domain.Entities; +using FluentValidation; + +namespace Backbone.Modules.Files.Application.Files.Queries.GetFileContent; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleFor(x => x.Id).ValidId(); + } +} diff --git a/Modules/Files/src/Files.Application/Files/Queries/GetFileMetadata/GetFileMetadataQuery.cs b/Modules/Files/src/Files.Application/Files/Queries/GetFileMetadata/GetFileMetadataQuery.cs index 147276c9ee..0d83b0b057 100644 --- a/Modules/Files/src/Files.Application/Files/Queries/GetFileMetadata/GetFileMetadataQuery.cs +++ b/Modules/Files/src/Files.Application/Files/Queries/GetFileMetadata/GetFileMetadataQuery.cs @@ -1,10 +1,9 @@ using Backbone.Modules.Files.Application.Files.DTOs; -using Backbone.Modules.Files.Domain.Entities; using MediatR; namespace Backbone.Modules.Files.Application.Files.Queries.GetFileMetadata; public class GetFileMetadataQuery : IRequest { - public required FileId Id { get; set; } + public required string Id { get; set; } } diff --git a/Modules/Files/src/Files.Application/Files/Queries/GetFileMetadata/Handler.cs b/Modules/Files/src/Files.Application/Files/Queries/GetFileMetadata/Handler.cs index e063c2d1c1..321e18f5fd 100644 --- a/Modules/Files/src/Files.Application/Files/Queries/GetFileMetadata/Handler.cs +++ b/Modules/Files/src/Files.Application/Files/Queries/GetFileMetadata/Handler.cs @@ -1,25 +1,24 @@ -using AutoMapper; using Backbone.BuildingBlocks.Application.Abstractions.Exceptions; using Backbone.Modules.Files.Application.Files.DTOs; using Backbone.Modules.Files.Application.Infrastructure.Persistence.Repository; +using Backbone.Modules.Files.Domain.Entities; using MediatR; +using File = Backbone.Modules.Files.Domain.Entities.File; namespace Backbone.Modules.Files.Application.Files.Queries.GetFileMetadata; public class Handler : IRequestHandler { private readonly IFilesRepository _filesRepository; - private readonly IMapper _mapper; - public Handler(IFilesRepository filesRepository, IMapper mapper) + public Handler(IFilesRepository filesRepository) { _filesRepository = filesRepository; - _mapper = mapper; } public async Task Handle(GetFileMetadataQuery request, CancellationToken cancellationToken) { - var file = await _filesRepository.Find(request.Id, cancellationToken, fillContent: false) ?? throw new NotFoundException(nameof(File)); - return _mapper.Map(file); + var file = await _filesRepository.Find(FileId.Parse(request.Id), cancellationToken, fillContent: false) ?? throw new NotFoundException(nameof(File)); + return new FileMetadataDTO(file); } } diff --git a/Modules/Files/src/Files.Application/Files/Queries/GetFileMetadata/Validator.cs b/Modules/Files/src/Files.Application/Files/Queries/GetFileMetadata/Validator.cs new file mode 100644 index 0000000000..c7fbfe89d3 --- /dev/null +++ b/Modules/Files/src/Files.Application/Files/Queries/GetFileMetadata/Validator.cs @@ -0,0 +1,13 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.Modules.Files.Domain.Entities; +using FluentValidation; + +namespace Backbone.Modules.Files.Application.Files.Queries.GetFileMetadata; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleFor(x => x.Id).ValidId(); + } +} diff --git a/Modules/Files/src/Files.Application/Files/Queries/ListFileMetadata/Handler.cs b/Modules/Files/src/Files.Application/Files/Queries/ListFileMetadata/Handler.cs index 1041aa3f9a..7a30684b8b 100644 --- a/Modules/Files/src/Files.Application/Files/Queries/ListFileMetadata/Handler.cs +++ b/Modules/Files/src/Files.Application/Files/Queries/ListFileMetadata/Handler.cs @@ -1,7 +1,6 @@ -using AutoMapper; using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.UserContext; -using Backbone.Modules.Files.Application.Files.DTOs; using Backbone.Modules.Files.Application.Infrastructure.Persistence.Repository; +using Backbone.Modules.Files.Domain.Entities; using MediatR; namespace Backbone.Modules.Files.Application.Files.Queries.ListFileMetadata; @@ -10,24 +9,16 @@ public class Handler : IRequestHandler Handle(ListFileMetadataQuery request, CancellationToken cancellationToken) { - var dbPaginationResult = await _filesRepository.FindFilesByCreator(request.Ids, _userContext.GetAddress(), request.PaginationFilter, cancellationToken); - - var items = _mapper.Map(dbPaginationResult.ItemsOnPage); - - var response = new ListFileMetadataResponse(items, request.PaginationFilter, dbPaginationResult.TotalNumberOfItems); - - return response; + var dbPaginationResult = await _filesRepository.FindFilesByCreator(request.Ids.Select(FileId.Parse), _userContext.GetAddress(), request.PaginationFilter, cancellationToken); + return new ListFileMetadataResponse(dbPaginationResult, request.PaginationFilter); } } diff --git a/Modules/Files/src/Files.Application/Files/Queries/ListFileMetadata/ListFileMetadataQuery.cs b/Modules/Files/src/Files.Application/Files/Queries/ListFileMetadata/ListFileMetadataQuery.cs index a4447b5111..be4d19c63b 100644 --- a/Modules/Files/src/Files.Application/Files/Queries/ListFileMetadata/ListFileMetadataQuery.cs +++ b/Modules/Files/src/Files.Application/Files/Queries/ListFileMetadata/ListFileMetadataQuery.cs @@ -1,12 +1,11 @@ using Backbone.BuildingBlocks.Application.Pagination; -using Backbone.Modules.Files.Domain.Entities; using MediatR; namespace Backbone.Modules.Files.Application.Files.Queries.ListFileMetadata; public class ListFileMetadataQuery : IRequest { - public ListFileMetadataQuery(PaginationFilter paginationFilter, IEnumerable ids) + public ListFileMetadataQuery(PaginationFilter paginationFilter, IEnumerable ids) { PaginationFilter = paginationFilter; Ids = ids; @@ -14,5 +13,5 @@ public ListFileMetadataQuery(PaginationFilter paginationFilter, IEnumerable Ids { get; set; } + public IEnumerable Ids { get; set; } } diff --git a/Modules/Files/src/Files.Application/Files/Queries/ListFileMetadata/ListFileMetadataResponse.cs b/Modules/Files/src/Files.Application/Files/Queries/ListFileMetadata/ListFileMetadataResponse.cs index db9943c041..609e3e12a3 100644 --- a/Modules/Files/src/Files.Application/Files/Queries/ListFileMetadata/ListFileMetadataResponse.cs +++ b/Modules/Files/src/Files.Application/Files/Queries/ListFileMetadata/ListFileMetadataResponse.cs @@ -1,9 +1,14 @@ +using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.Persistence.Database; using Backbone.BuildingBlocks.Application.Pagination; using Backbone.Modules.Files.Application.Files.DTOs; +using File = Backbone.Modules.Files.Domain.Entities.File; namespace Backbone.Modules.Files.Application.Files.Queries.ListFileMetadata; public class ListFileMetadataResponse : PagedResponse { - public ListFileMetadataResponse(IEnumerable items, PaginationFilter previousFilter, int totalRecords) : base(items, previousFilter, totalRecords) { } + public ListFileMetadataResponse(DbPaginationResult dbPaginationResult, PaginationFilter previousFilter) : base(dbPaginationResult.ItemsOnPage.Select(f => new FileMetadataDTO(f)), + previousFilter, dbPaginationResult.TotalNumberOfItems) + { + } } diff --git a/Modules/Files/src/Files.Application/Files/Queries/ListFileMetadata/Validator.cs b/Modules/Files/src/Files.Application/Files/Queries/ListFileMetadata/Validator.cs new file mode 100644 index 0000000000..ec3f2c0506 --- /dev/null +++ b/Modules/Files/src/Files.Application/Files/Queries/ListFileMetadata/Validator.cs @@ -0,0 +1,13 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.Modules.Files.Domain.Entities; +using FluentValidation; + +namespace Backbone.Modules.Files.Application.Files.Queries.ListFileMetadata; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleForEach(x => x.Ids).ValidId(); + } +} diff --git a/Modules/Files/src/Files.Application/Identities/Commands/DeleteFilesOfIdentity/DeleteFilesOfIdentityCommand.cs b/Modules/Files/src/Files.Application/Identities/Commands/DeleteFilesOfIdentity/DeleteFilesOfIdentityCommand.cs index 870d142eb1..258f704675 100644 --- a/Modules/Files/src/Files.Application/Identities/Commands/DeleteFilesOfIdentity/DeleteFilesOfIdentityCommand.cs +++ b/Modules/Files/src/Files.Application/Identities/Commands/DeleteFilesOfIdentity/DeleteFilesOfIdentityCommand.cs @@ -1,14 +1,13 @@ -using Backbone.DevelopmentKit.Identity.ValueObjects; -using MediatR; +using MediatR; namespace Backbone.Modules.Files.Application.Identities.Commands.DeleteFilesOfIdentity; public class DeleteFilesOfIdentityCommand : IRequest { - public DeleteFilesOfIdentityCommand(IdentityAddress identityAddress) + public DeleteFilesOfIdentityCommand(string identityAddress) { IdentityAddress = identityAddress; } - public IdentityAddress IdentityAddress { get; set; } + public string IdentityAddress { get; set; } } diff --git a/Modules/Files/src/Files.Application/Identities/Commands/DeleteFilesOfIdentity/Validator.cs b/Modules/Files/src/Files.Application/Identities/Commands/DeleteFilesOfIdentity/Validator.cs index efc8ba307e..9809a1c09a 100644 --- a/Modules/Files/src/Files.Application/Identities/Commands/DeleteFilesOfIdentity/Validator.cs +++ b/Modules/Files/src/Files.Application/Identities/Commands/DeleteFilesOfIdentity/Validator.cs @@ -1,8 +1,13 @@ -using Backbone.DevelopmentKit.Identity.ValueObjects; +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.DevelopmentKit.Identity.ValueObjects; using FluentValidation; namespace Backbone.Modules.Files.Application.Identities.Commands.DeleteFilesOfIdentity; + public class Validator : AbstractValidator { - public Validator() => RuleFor(x => x.IdentityAddress).Must(x => IdentityAddress.IsValid(x)); + public Validator() + { + RuleFor(x => x.IdentityAddress).ValidId(); + } } diff --git a/Modules/Files/src/Files.ConsumerApi/Controllers/FilesController.cs b/Modules/Files/src/Files.ConsumerApi/Controllers/FilesController.cs index 2bf2bb65a8..0eaa0424d1 100644 --- a/Modules/Files/src/Files.ConsumerApi/Controllers/FilesController.cs +++ b/Modules/Files/src/Files.ConsumerApi/Controllers/FilesController.cs @@ -11,7 +11,7 @@ using Backbone.Modules.Files.Application.Files.Queries.GetFileMetadata; using Backbone.Modules.Files.Application.Files.Queries.ListFileMetadata; using Backbone.Modules.Files.ConsumerApi.DTOs; -using Backbone.Modules.Files.Domain.Entities; +using Backbone.Modules.Files.ConsumerApi.DTOs.Validators; using MediatR; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; @@ -39,6 +39,10 @@ public FilesController(IMediator mediator, IOptions options) [ProducesError(StatusCodes.Status400BadRequest)] public async Task UploadFile([FromForm] CreateFileDTO dto, CancellationToken cancellationToken) { + var validationResult = await new CreateFileDTOValidator().ValidateAsync(dto, cancellationToken); + if (!validationResult.IsValid) + throw new ValidationException(new ApplicationError(validationResult.Errors.First().ErrorCode, validationResult.Errors.First().ErrorMessage)); + var inputStream = new MemoryStream(); await dto.Content.CopyToAsync(inputStream, cancellationToken); @@ -61,7 +65,7 @@ public async Task UploadFile([FromForm] CreateFileDTO dto, Cancel [Produces(MediaTypeNames.Application.Octet)] [ProducesResponseType(typeof(HttpResponseEnvelopeResult), StatusCodes.Status200OK)] [ProducesError(StatusCodes.Status404NotFound)] - public async Task DownloadFile(FileId fileId, CancellationToken cancellationToken) + public async Task DownloadFile(string fileId, CancellationToken cancellationToken) { var response = await _mediator.Send(new GetFileContentQuery { Id = fileId }, cancellationToken); return File(response.FileContent, MediaTypeNames.Application.Octet); @@ -71,7 +75,7 @@ public async Task DownloadFile(FileId fileId, CancellationToken c [HttpGet("{fileId}/metadata")] [ProducesResponseType(typeof(HttpResponseEnvelopeResult), StatusCodes.Status200OK)] [ProducesError(StatusCodes.Status404NotFound)] - public async Task GetFileMetadata(FileId fileId, CancellationToken cancellationToken) + public async Task GetFileMetadata(string fileId, CancellationToken cancellationToken) { var metadata = await _mediator.Send(new GetFileMetadataQuery { Id = fileId }, cancellationToken); return Ok(metadata); @@ -80,7 +84,7 @@ public async Task GetFileMetadata(FileId fileId, CancellationToke [HttpGet] [ProducesResponseType(typeof(PagedHttpResponseEnvelope), StatusCodes.Status200OK)] public async Task ListFileMetadata([FromQuery] PaginationFilter paginationFilter, - [FromQuery] IEnumerable ids, CancellationToken cancellationToken) + [FromQuery] IEnumerable ids, CancellationToken cancellationToken) { paginationFilter.PageSize ??= _options.Pagination.DefaultPageSize; diff --git a/Modules/Files/src/Files.ConsumerApi/DTOs/CreateFileDTO.cs b/Modules/Files/src/Files.ConsumerApi/DTOs/CreateFileDTO.cs index 3fccc67a16..703595b1c9 100644 --- a/Modules/Files/src/Files.ConsumerApi/DTOs/CreateFileDTO.cs +++ b/Modules/Files/src/Files.ConsumerApi/DTOs/CreateFileDTO.cs @@ -1,4 +1,3 @@ -using Backbone.DevelopmentKit.Identity.ValueObjects; using Microsoft.AspNetCore.Http; namespace Backbone.Modules.Files.ConsumerApi.DTOs; @@ -6,7 +5,7 @@ namespace Backbone.Modules.Files.ConsumerApi.DTOs; public class CreateFileDTO { public required IFormFile Content { get; set; } - public required IdentityAddress Owner { get; set; } + public required string Owner { get; set; } public required string OwnerSignature { get; set; } public required string CipherHash { get; set; } diff --git a/Modules/Files/src/Files.ConsumerApi/DTOs/Validators/CreateFileDTOValidator.cs b/Modules/Files/src/Files.ConsumerApi/DTOs/Validators/CreateFileDTOValidator.cs index 7bcbdae561..42c916f9dd 100644 --- a/Modules/Files/src/Files.ConsumerApi/DTOs/Validators/CreateFileDTOValidator.cs +++ b/Modules/Files/src/Files.ConsumerApi/DTOs/Validators/CreateFileDTOValidator.cs @@ -1,4 +1,4 @@ -using Backbone.BuildingBlocks.Application.FluentValidation; +using Backbone.BuildingBlocks.Application.Extensions; using Backbone.Tooling.Extensions; using FluentValidation; diff --git a/Modules/Files/test/Files.Application.Tests/Tests/AutoMapper/AutoMapperProfileTests.cs b/Modules/Files/test/Files.Application.Tests/Tests/AutoMapper/AutoMapperProfileTests.cs deleted file mode 100644 index c74bed3997..0000000000 --- a/Modules/Files/test/Files.Application.Tests/Tests/AutoMapper/AutoMapperProfileTests.cs +++ /dev/null @@ -1,19 +0,0 @@ -using AutoMapper; -using Backbone.Modules.Files.Application.AutoMapper; -using Backbone.UnitTestTools.BaseClasses; -using Xunit; - -namespace Backbone.Modules.Files.Application.Tests.Tests.AutoMapper; - -public class AutoMapperProfileTests : AbstractTestsBase -{ - [Fact] - public void ProfileIsValid() - { - // Arrange - var configuration = new MapperConfiguration(cfg => cfg.AddProfile()); - - // Act & Assert - configuration.AssertConfigurationIsValid(); - } -} diff --git a/Modules/Files/test/Files.Application.Tests/Tests/Files/Queries/GetFileContent/ValidatorTests.cs b/Modules/Files/test/Files.Application.Tests/Tests/Files/Queries/GetFileContent/ValidatorTests.cs new file mode 100644 index 0000000000..7fa025a082 --- /dev/null +++ b/Modules/Files/test/Files.Application.Tests/Tests/Files/Queries/GetFileContent/ValidatorTests.cs @@ -0,0 +1,37 @@ +using Backbone.Modules.Files.Application.Files.Queries.GetFileContent; +using Backbone.Modules.Files.Domain.Entities; +using Backbone.UnitTestTools.BaseClasses; +using Backbone.UnitTestTools.FluentValidation; +using FluentValidation.TestHelper; +using Xunit; + +namespace Backbone.Modules.Files.Application.Tests.Tests.Files.Queries.GetFileContent; + +public class ValidatorTests : AbstractTestsBase +{ + [Fact] + public void Happy_path() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new GetFileContentQuery { Id = FileId.New() }); + + // Assert + validationResult.ShouldNotHaveAnyValidationErrors(); + } + + [Fact] + public void Fails_when_file_id_is_invalid() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new GetFileContentQuery { Id = "some-invalid-file-id" }); + + // Assert + validationResult.ShouldHaveValidationErrorForId(nameof(GetFileContentQuery.Id)); + } +} diff --git a/Modules/Files/test/Files.Application.Tests/Tests/Files/Queries/GetFileMetadata/ValidatorTests.cs b/Modules/Files/test/Files.Application.Tests/Tests/Files/Queries/GetFileMetadata/ValidatorTests.cs new file mode 100644 index 0000000000..056c3eccb7 --- /dev/null +++ b/Modules/Files/test/Files.Application.Tests/Tests/Files/Queries/GetFileMetadata/ValidatorTests.cs @@ -0,0 +1,37 @@ +using Backbone.Modules.Files.Application.Files.Queries.GetFileMetadata; +using Backbone.Modules.Files.Domain.Entities; +using Backbone.UnitTestTools.BaseClasses; +using Backbone.UnitTestTools.FluentValidation; +using FluentValidation.TestHelper; +using Xunit; + +namespace Backbone.Modules.Files.Application.Tests.Tests.Files.Queries.GetFileMetadata; + +public class ValidatorTests : AbstractTestsBase +{ + [Fact] + public void Happy_path() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new GetFileMetadataQuery { Id = FileId.New() }); + + // Assert + validationResult.ShouldNotHaveAnyValidationErrors(); + } + + [Fact] + public void Fails_when_file_id_is_invalid() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new GetFileMetadataQuery { Id = "some-invalid-file-id" }); + + // Assert + validationResult.ShouldHaveValidationErrorForId(nameof(GetFileMetadataQuery.Id)); + } +} diff --git a/Modules/Files/test/Files.Application.Tests/Tests/Files/Queries/ListFileMetadata/ValidatorTests.cs b/Modules/Files/test/Files.Application.Tests/Tests/Files/Queries/ListFileMetadata/ValidatorTests.cs new file mode 100644 index 0000000000..e7468bb3ff --- /dev/null +++ b/Modules/Files/test/Files.Application.Tests/Tests/Files/Queries/ListFileMetadata/ValidatorTests.cs @@ -0,0 +1,40 @@ +using Backbone.BuildingBlocks.Application.Pagination; +using Backbone.Modules.Files.Application.Files.Queries.ListFileMetadata; +using Backbone.Modules.Files.Domain.Entities; +using Backbone.UnitTestTools.BaseClasses; +using Backbone.UnitTestTools.FluentValidation; +using FluentValidation.TestHelper; +using Xunit; + +namespace Backbone.Modules.Files.Application.Tests.Tests.Files.Queries.ListFileMetadata; + +public class ValidatorTests : AbstractTestsBase +{ + [Fact] + public void Happy_path() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new ListFileMetadataQuery(new PaginationFilter(), [FileId.New()])); + + // Assert + validationResult.ShouldNotHaveAnyValidationErrors(); + } + + [Fact] + public void Fails_when_file_id_is_invalid() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new ListFileMetadataQuery(new PaginationFilter(), ["some-invalid-file-id"])); + + // Assert + validationResult.ShouldHaveValidationErrorForIdInCollection( + collectionWithInvalidId: nameof(ListFileMetadataQuery.Ids), + indexWithInvalidId: 0); + } +} diff --git a/Modules/Files/test/Files.Application.Tests/Tests/Identities/Commands/DeleteIdentityCommandTests/HandlerTests.cs b/Modules/Files/test/Files.Application.Tests/Tests/Identities/Commands/DeleteFilesOfIdentity/HandlerTests.cs similarity index 96% rename from Modules/Files/test/Files.Application.Tests/Tests/Identities/Commands/DeleteIdentityCommandTests/HandlerTests.cs rename to Modules/Files/test/Files.Application.Tests/Tests/Identities/Commands/DeleteFilesOfIdentity/HandlerTests.cs index 7103d1be4e..ac6245b1b1 100644 --- a/Modules/Files/test/Files.Application.Tests/Tests/Identities/Commands/DeleteIdentityCommandTests/HandlerTests.cs +++ b/Modules/Files/test/Files.Application.Tests/Tests/Identities/Commands/DeleteFilesOfIdentity/HandlerTests.cs @@ -7,7 +7,7 @@ using static Backbone.UnitTestTools.Data.TestDataGenerator; using File = Backbone.Modules.Files.Domain.Entities.File; -namespace Backbone.Modules.Files.Application.Tests.Tests.Identities.Commands.DeleteIdentityCommandTests; +namespace Backbone.Modules.Files.Application.Tests.Tests.Identities.Commands.DeleteFilesOfIdentity; public class HandlerTests : AbstractTestsBase { diff --git a/Modules/Files/test/Files.Application.Tests/Tests/Identities/Commands/DeleteFilesOfIdentity/ValidatorTests.cs b/Modules/Files/test/Files.Application.Tests/Tests/Identities/Commands/DeleteFilesOfIdentity/ValidatorTests.cs new file mode 100644 index 0000000000..2003edc1a4 --- /dev/null +++ b/Modules/Files/test/Files.Application.Tests/Tests/Identities/Commands/DeleteFilesOfIdentity/ValidatorTests.cs @@ -0,0 +1,37 @@ +using Backbone.Modules.Files.Application.Identities.Commands.DeleteFilesOfIdentity; +using Backbone.UnitTestTools.BaseClasses; +using Backbone.UnitTestTools.Data; +using Backbone.UnitTestTools.FluentValidation; +using FluentValidation.TestHelper; +using Xunit; + +namespace Backbone.Modules.Files.Application.Tests.Tests.Identities.Commands.DeleteFilesOfIdentity; + +public class ValidatorTests : AbstractTestsBase +{ + [Fact] + public void Happy_path() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new DeleteFilesOfIdentityCommand(TestDataGenerator.CreateRandomIdentityAddress())); + + // Assert + validationResult.ShouldNotHaveAnyValidationErrors(); + } + + [Fact] + public void Fails_when_identity_address_is_invalid() + { + // Arrange + var validator = new Validator(); + + // Act + var validationResult = validator.TestValidate(new DeleteFilesOfIdentityCommand("invalid-identity-address")); + + // Assert + validationResult.ShouldHaveValidationErrorForId(nameof(DeleteFilesOfIdentityCommand.IdentityAddress)); + } +} diff --git a/Modules/Messages/src/Messages.Application/AutoMapper/AutoMapperProfile.cs b/Modules/Messages/src/Messages.Application/AutoMapper/AutoMapperProfile.cs deleted file mode 100644 index af6da51f59..0000000000 --- a/Modules/Messages/src/Messages.Application/AutoMapper/AutoMapperProfile.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Reflection; -using AutoMapper; -using Backbone.BuildingBlocks.Application.AutoMapper; - -namespace Backbone.Modules.Messages.Application.AutoMapper; - -public class AutoMapperProfile : AutoMapperProfileBase -{ - public AutoMapperProfile() : base(Assembly.GetExecutingAssembly()) { } - - public static IMapper CreateMapper() - { - var profile = new AutoMapperProfile(); - var config = new MapperConfiguration(cfg => cfg.AddProfile(profile)); - var mapper = config.CreateMapper(); - return mapper; - } -} diff --git a/Modules/Messages/src/Messages.Application/Extensions/IServiceCollectionExtensions.cs b/Modules/Messages/src/Messages.Application/Extensions/IServiceCollectionExtensions.cs index c87e9b9657..466b9b22f9 100644 --- a/Modules/Messages/src/Messages.Application/Extensions/IServiceCollectionExtensions.cs +++ b/Modules/Messages/src/Messages.Application/Extensions/IServiceCollectionExtensions.cs @@ -1,7 +1,6 @@ using System.Reflection; using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.EventBus; using Backbone.BuildingBlocks.Application.MediatR; -using Backbone.Modules.Messages.Application.AutoMapper; using Backbone.Modules.Messages.Application.Messages.Commands.SendMessage; using FluentValidation; using Microsoft.Extensions.DependencyInjection; @@ -18,8 +17,7 @@ public static void AddApplication(this IServiceCollection services) .AddOpenBehavior(typeof(RequestValidationBehavior<,>)) .AddOpenBehavior(typeof(QuotaEnforcerBehavior<,>)) ); - services.AddAutoMapper(typeof(AutoMapperProfile).Assembly); - services.AddValidatorsFromAssembly(typeof(SendMessageCommandValidator).Assembly); + services.AddValidatorsFromAssembly(typeof(Validator).Assembly); services.AddEventHandlers(); } diff --git a/Modules/Messages/src/Messages.Application/Messages/Commands/AnonymizeMessagesOfIdentity/AnonymizeMessagesOfIdentityCommand.cs b/Modules/Messages/src/Messages.Application/Messages/Commands/AnonymizeMessagesOfIdentity/AnonymizeMessagesOfIdentityCommand.cs index 503803edeb..91b8a1bbf0 100644 --- a/Modules/Messages/src/Messages.Application/Messages/Commands/AnonymizeMessagesOfIdentity/AnonymizeMessagesOfIdentityCommand.cs +++ b/Modules/Messages/src/Messages.Application/Messages/Commands/AnonymizeMessagesOfIdentity/AnonymizeMessagesOfIdentityCommand.cs @@ -1,14 +1,13 @@ -using Backbone.DevelopmentKit.Identity.ValueObjects; -using MediatR; +using MediatR; namespace Backbone.Modules.Messages.Application.Messages.Commands.AnonymizeMessagesOfIdentity; public class AnonymizeMessagesOfIdentityCommand : IRequest { - public AnonymizeMessagesOfIdentityCommand(IdentityAddress identityAddress) + public AnonymizeMessagesOfIdentityCommand(string identityAddress) { IdentityAddress = identityAddress; } - public IdentityAddress IdentityAddress { get; set; } + public string IdentityAddress { get; set; } } diff --git a/Modules/Messages/src/Messages.Application/Messages/Commands/AnonymizeMessagesOfIdentity/Validator.cs b/Modules/Messages/src/Messages.Application/Messages/Commands/AnonymizeMessagesOfIdentity/Validator.cs index 410b9ed660..28176b0361 100644 --- a/Modules/Messages/src/Messages.Application/Messages/Commands/AnonymizeMessagesOfIdentity/Validator.cs +++ b/Modules/Messages/src/Messages.Application/Messages/Commands/AnonymizeMessagesOfIdentity/Validator.cs @@ -1,8 +1,13 @@ -using Backbone.DevelopmentKit.Identity.ValueObjects; +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.DevelopmentKit.Identity.ValueObjects; using FluentValidation; namespace Backbone.Modules.Messages.Application.Messages.Commands.AnonymizeMessagesOfIdentity; + public class Validator : AbstractValidator { - public Validator() => RuleFor(x => x.IdentityAddress).Must(x => IdentityAddress.IsValid(x)); + public Validator() + { + RuleFor(x => x.IdentityAddress).ValidId(); + } } diff --git a/Modules/Messages/src/Messages.Application/Messages/Commands/SendMessage/Handler.cs b/Modules/Messages/src/Messages.Application/Messages/Commands/SendMessage/Handler.cs index 197dac2496..bdd0dcb077 100644 --- a/Modules/Messages/src/Messages.Application/Messages/Commands/SendMessage/Handler.cs +++ b/Modules/Messages/src/Messages.Application/Messages/Commands/SendMessage/Handler.cs @@ -1,4 +1,3 @@ -using AutoMapper; using Backbone.BuildingBlocks.Application.Abstractions.Exceptions; using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.UserContext; using Backbone.Modules.Messages.Application.Infrastructure.Persistence.Repository; @@ -13,7 +12,6 @@ namespace Backbone.Modules.Messages.Application.Messages.Commands.SendMessage; public class Handler : IRequestHandler { private readonly ILogger _logger; - private readonly IMapper _mapper; private readonly ApplicationOptions _options; private readonly IUserContext _userContext; private readonly IMessagesRepository _messagesRepository; @@ -21,14 +19,12 @@ public class Handler : IRequestHandler public Handler( IUserContext userContext, - IMapper mapper, IOptionsSnapshot options, ILogger logger, IMessagesRepository messagesRepository, IRelationshipsRepository relationshipsRepository) { _userContext = userContext; - _mapper = mapper; _logger = logger; _options = options.Value; _messagesRepository = messagesRepository; @@ -47,8 +43,7 @@ public async Task Handle(SendMessageCommand request, Cancel recipients); await _messagesRepository.Add(message, cancellationToken); - - return _mapper.Map(message); + return new SendMessageResponse(message); } private async Task> ValidateRecipients(SendMessageCommand request, CancellationToken cancellationToken) diff --git a/Modules/Messages/src/Messages.Application/Messages/Commands/SendMessage/SendMessageCommand.cs b/Modules/Messages/src/Messages.Application/Messages/Commands/SendMessage/SendMessageCommand.cs index 108cc649b3..b16fce0ca1 100644 --- a/Modules/Messages/src/Messages.Application/Messages/Commands/SendMessage/SendMessageCommand.cs +++ b/Modules/Messages/src/Messages.Application/Messages/Commands/SendMessage/SendMessageCommand.cs @@ -1,5 +1,4 @@ using Backbone.BuildingBlocks.Application.Attributes; -using Backbone.DevelopmentKit.Identity.ValueObjects; using MediatR; namespace Backbone.Modules.Messages.Application.Messages.Commands.SendMessage; @@ -14,7 +13,7 @@ public class SendMessageCommand : IRequest public class SendMessageCommandRecipientInformation { - public required IdentityAddress Address { get; set; } + public required string Address { get; set; } public required byte[] EncryptedKey { get; set; } } diff --git a/Modules/Messages/src/Messages.Application/Messages/Commands/SendMessage/SendMessageResponse.cs b/Modules/Messages/src/Messages.Application/Messages/Commands/SendMessage/SendMessageResponse.cs index 84aee5f8b4..6a85d77ca7 100644 --- a/Modules/Messages/src/Messages.Application/Messages/Commands/SendMessage/SendMessageResponse.cs +++ b/Modules/Messages/src/Messages.Application/Messages/Commands/SendMessage/SendMessageResponse.cs @@ -1,11 +1,15 @@ -using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.Mapping; using Backbone.Modules.Messages.Domain.Entities; -using Backbone.Modules.Messages.Domain.Ids; namespace Backbone.Modules.Messages.Application.Messages.Commands.SendMessage; -public class SendMessageResponse : IMapTo +public class SendMessageResponse { - public required MessageId Id { get; set; } - public required DateTime CreatedAt { get; set; } + public SendMessageResponse(Message message) + { + Id = message.Id; + CreatedAt = message.CreatedAt; + } + + public string Id { get; set; } + public DateTime CreatedAt { get; set; } } diff --git a/Modules/Messages/src/Messages.Application/Messages/Commands/SendMessage/SendMessageCommandValidator.cs b/Modules/Messages/src/Messages.Application/Messages/Commands/SendMessage/Validator.cs similarity index 86% rename from Modules/Messages/src/Messages.Application/Messages/Commands/SendMessage/SendMessageCommandValidator.cs rename to Modules/Messages/src/Messages.Application/Messages/Commands/SendMessage/Validator.cs index 8c67912330..6cab42e1bf 100644 --- a/Modules/Messages/src/Messages.Application/Messages/Commands/SendMessage/SendMessageCommandValidator.cs +++ b/Modules/Messages/src/Messages.Application/Messages/Commands/SendMessage/Validator.cs @@ -1,14 +1,16 @@ using Backbone.BuildingBlocks.Application.Abstractions.Exceptions; +using Backbone.BuildingBlocks.Application.Extensions; using Backbone.BuildingBlocks.Application.FluentValidation; +using Backbone.DevelopmentKit.Identity.ValueObjects; using Backbone.Modules.Messages.Domain.Ids; using Backbone.Tooling.Extensions; using FluentValidation; namespace Backbone.Modules.Messages.Application.Messages.Commands.SendMessage; -public class SendMessageCommandValidator : AbstractValidator +public class Validator : AbstractValidator { - public SendMessageCommandValidator() + public Validator() { RuleFor(m => m.Recipients) .DetailedNotNull() @@ -37,7 +39,7 @@ public class SendMessageCommandRecipientInformationValidator : AbstractValidator { public SendMessageCommandRecipientInformationValidator() { - RuleFor(r => r.Address).DetailedNotNull(); + RuleFor(r => r.Address).ValidId(); RuleFor(r => r.EncryptedKey) .DetailedNotNull() diff --git a/Modules/Messages/src/Messages.Application/Messages/DTOs/MessageDTO.cs b/Modules/Messages/src/Messages.Application/Messages/DTOs/MessageDTO.cs index a639d7233f..7f792782ac 100644 --- a/Modules/Messages/src/Messages.Application/Messages/DTOs/MessageDTO.cs +++ b/Modules/Messages/src/Messages.Application/Messages/DTOs/MessageDTO.cs @@ -1,6 +1,5 @@ using Backbone.DevelopmentKit.Identity.ValueObjects; using Backbone.Modules.Messages.Domain.Entities; -using Backbone.Modules.Messages.Domain.Ids; namespace Backbone.Modules.Messages.Application.Messages.DTOs; @@ -17,10 +16,10 @@ public MessageDTO(Message message, IdentityAddress activeIdentity, string didDom Recipients = MapRecipients(message, activeIdentity, didDomainName); } - public MessageId Id { get; set; } + public string Id { get; set; } public DateTime CreatedAt { get; set; } - public IdentityAddress CreatedBy { get; set; } - public DeviceId CreatedByDevice { get; set; } + public string CreatedBy { get; set; } + public string CreatedByDevice { get; set; } public byte[] Body { get; set; } public List Attachments { get; set; } public List Recipients { get; set; } diff --git a/Modules/Messages/src/Messages.Application/Messages/DTOs/RecipientInformationDTO.cs b/Modules/Messages/src/Messages.Application/Messages/DTOs/RecipientInformationDTO.cs index a1eab79991..3b930fa53c 100644 --- a/Modules/Messages/src/Messages.Application/Messages/DTOs/RecipientInformationDTO.cs +++ b/Modules/Messages/src/Messages.Application/Messages/DTOs/RecipientInformationDTO.cs @@ -1,4 +1,3 @@ -using Backbone.DevelopmentKit.Identity.ValueObjects; using Backbone.Modules.Messages.Domain.Entities; namespace Backbone.Modules.Messages.Application.Messages.DTOs; @@ -10,11 +9,11 @@ public RecipientInformationDTO(RecipientInformation recipientInformation) Address = recipientInformation.Address; EncryptedKey = recipientInformation.EncryptedKey; ReceivedAt = recipientInformation.ReceivedAt; - ReceivedByDevice = recipientInformation.ReceivedByDevice; + ReceivedByDevice = recipientInformation.ReceivedByDevice?.Value; } - public IdentityAddress Address { get; set; } + public string Address { get; set; } public byte[] EncryptedKey { get; set; } public DateTime? ReceivedAt { get; set; } - public DeviceId? ReceivedByDevice { get; set; } + public string? ReceivedByDevice { get; set; } } diff --git a/Modules/Messages/src/Messages.Application/Messages/Queries/GetMessage/GetMessageQuery.cs b/Modules/Messages/src/Messages.Application/Messages/Queries/GetMessage/GetMessageQuery.cs index e2aef14bbf..ffd417809a 100644 --- a/Modules/Messages/src/Messages.Application/Messages/Queries/GetMessage/GetMessageQuery.cs +++ b/Modules/Messages/src/Messages.Application/Messages/Queries/GetMessage/GetMessageQuery.cs @@ -1,11 +1,10 @@ using Backbone.Modules.Messages.Application.Messages.DTOs; -using Backbone.Modules.Messages.Domain.Ids; using MediatR; namespace Backbone.Modules.Messages.Application.Messages.Queries.GetMessage; public class GetMessageQuery : IRequest { - public required MessageId Id { get; init; } + public required string Id { get; init; } public required bool NoBody { get; init; } } diff --git a/Modules/Messages/src/Messages.Application/Messages/Queries/GetMessage/Handler.cs b/Modules/Messages/src/Messages.Application/Messages/Queries/GetMessage/Handler.cs index bcbc5cd99f..ae2e04c10a 100644 --- a/Modules/Messages/src/Messages.Application/Messages/Queries/GetMessage/Handler.cs +++ b/Modules/Messages/src/Messages.Application/Messages/Queries/GetMessage/Handler.cs @@ -2,6 +2,7 @@ using Backbone.Modules.Messages.Application.Extensions; using Backbone.Modules.Messages.Application.Infrastructure.Persistence.Repository; using Backbone.Modules.Messages.Application.Messages.DTOs; +using Backbone.Modules.Messages.Domain.Ids; using MediatR; using Microsoft.Extensions.Options; @@ -22,7 +23,7 @@ public Handler(IUserContext userContext, IMessagesRepository messagesRepository, public async Task Handle(GetMessageQuery request, CancellationToken cancellationToken) { - var message = await _messagesRepository.Find(request.Id, _userContext.GetAddress(), cancellationToken, track: true); + var message = await _messagesRepository.Find(MessageId.Parse(request.Id), _userContext.GetAddress(), cancellationToken, true); var recipient = message.Recipients.FirstWithIdOrDefault(_userContext.GetAddress()); diff --git a/Modules/Messages/src/Messages.Application/Messages/Queries/GetMessage/Validator.cs b/Modules/Messages/src/Messages.Application/Messages/Queries/GetMessage/Validator.cs new file mode 100644 index 0000000000..1c8b05f4ed --- /dev/null +++ b/Modules/Messages/src/Messages.Application/Messages/Queries/GetMessage/Validator.cs @@ -0,0 +1,13 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.Modules.Messages.Domain.Ids; +using FluentValidation; + +namespace Backbone.Modules.Messages.Application.Messages.Queries.GetMessage; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleFor(x => x.Id).ValidId(); + } +} diff --git a/Modules/Messages/src/Messages.Application/Messages/Queries/ListMessages/Handler.cs b/Modules/Messages/src/Messages.Application/Messages/Queries/ListMessages/Handler.cs index 8eb6c4765a..d87cffd261 100644 --- a/Modules/Messages/src/Messages.Application/Messages/Queries/ListMessages/Handler.cs +++ b/Modules/Messages/src/Messages.Application/Messages/Queries/ListMessages/Handler.cs @@ -1,6 +1,7 @@ using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.UserContext; using Backbone.Modules.Messages.Application.Extensions; using Backbone.Modules.Messages.Application.Infrastructure.Persistence.Repository; +using Backbone.Modules.Messages.Domain.Ids; using MediatR; using Microsoft.Extensions.Options; @@ -21,7 +22,8 @@ public Handler(IUserContext userContext, IMessagesRepository messagesRepository, public async Task Handle(ListMessagesQuery request, CancellationToken cancellationToken) { - var dbPaginationResult = await _messagesRepository.FindMessagesWithIds(request.Ids, _userContext.GetAddress(), request.PaginationFilter, cancellationToken, track: true); + var dbPaginationResult = + await _messagesRepository.FindMessagesWithIds(request.Ids.Select(MessageId.Parse), _userContext.GetAddress(), request.PaginationFilter, cancellationToken, track: true); foreach (var message in dbPaginationResult.ItemsOnPage) { @@ -32,7 +34,7 @@ public async Task Handle(ListMessagesQuery request, Cancel await _messagesRepository.Update(dbPaginationResult.ItemsOnPage); - var response = new ListMessagesResponse(dbPaginationResult.ItemsOnPage, request.PaginationFilter, dbPaginationResult.TotalNumberOfItems, _userContext.GetAddress(), _options.DidDomainName); + var response = new ListMessagesResponse(dbPaginationResult, request.PaginationFilter, _userContext.GetAddress(), _options.DidDomainName); return response; } diff --git a/Modules/Messages/src/Messages.Application/Messages/Queries/ListMessages/ListMessagesQuery.cs b/Modules/Messages/src/Messages.Application/Messages/Queries/ListMessages/ListMessagesQuery.cs index 6931f4d58f..3b8f8c016f 100644 --- a/Modules/Messages/src/Messages.Application/Messages/Queries/ListMessages/ListMessagesQuery.cs +++ b/Modules/Messages/src/Messages.Application/Messages/Queries/ListMessages/ListMessagesQuery.cs @@ -1,17 +1,16 @@ using Backbone.BuildingBlocks.Application.Pagination; -using Backbone.Modules.Messages.Domain.Ids; using MediatR; namespace Backbone.Modules.Messages.Application.Messages.Queries.ListMessages; public class ListMessagesQuery : IRequest { - public ListMessagesQuery(PaginationFilter paginationFilter, IEnumerable ids) + public ListMessagesQuery(PaginationFilter paginationFilter, IEnumerable ids) { PaginationFilter = paginationFilter; Ids = ids; } public PaginationFilter PaginationFilter { get; set; } - public IEnumerable Ids { get; set; } + public IEnumerable Ids { get; set; } } diff --git a/Modules/Messages/src/Messages.Application/Messages/Queries/ListMessages/ListMessagesQueryValidator.cs b/Modules/Messages/src/Messages.Application/Messages/Queries/ListMessages/ListMessagesQueryValidator.cs deleted file mode 100644 index d042b0ee6d..0000000000 --- a/Modules/Messages/src/Messages.Application/Messages/Queries/ListMessages/ListMessagesQueryValidator.cs +++ /dev/null @@ -1,6 +0,0 @@ -using FluentValidation; - -namespace Backbone.Modules.Messages.Application.Messages.Queries.ListMessages; - -// ReSharper disable once UnusedMember.Global -public class ListMessagesQueryValidator : AbstractValidator; diff --git a/Modules/Messages/src/Messages.Application/Messages/Queries/ListMessages/ListMessagesResponse.cs b/Modules/Messages/src/Messages.Application/Messages/Queries/ListMessages/ListMessagesResponse.cs index 4921a036eb..cf49b6decc 100644 --- a/Modules/Messages/src/Messages.Application/Messages/Queries/ListMessages/ListMessagesResponse.cs +++ b/Modules/Messages/src/Messages.Application/Messages/Queries/ListMessages/ListMessagesResponse.cs @@ -1,3 +1,4 @@ +using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.Persistence.Database; using Backbone.BuildingBlocks.Application.Pagination; using Backbone.DevelopmentKit.Identity.ValueObjects; using Backbone.Modules.Messages.Application.Messages.DTOs; @@ -7,8 +8,8 @@ namespace Backbone.Modules.Messages.Application.Messages.Queries.ListMessages; public class ListMessagesResponse : PagedResponse { - public ListMessagesResponse(IEnumerable itemsOnPage, PaginationFilter previousPaginationFilter, int totalNumberOfItems, IdentityAddress activeIdentity, string didDomainName) - : base(itemsOnPage.Select(i => new MessageDTO(i, activeIdentity, didDomainName)), previousPaginationFilter, totalNumberOfItems) + public ListMessagesResponse(DbPaginationResult dbPaginationResult, PaginationFilter previousPaginationFilter, IdentityAddress activeIdentity, string didDomainName) + : base(dbPaginationResult.ItemsOnPage.Select(i => new MessageDTO(i, activeIdentity, didDomainName)), previousPaginationFilter, dbPaginationResult.TotalNumberOfItems) { } } diff --git a/Modules/Messages/src/Messages.Application/Messages/Queries/ListMessages/Validator.cs b/Modules/Messages/src/Messages.Application/Messages/Queries/ListMessages/Validator.cs new file mode 100644 index 0000000000..ebe98e2d23 --- /dev/null +++ b/Modules/Messages/src/Messages.Application/Messages/Queries/ListMessages/Validator.cs @@ -0,0 +1,14 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.Modules.Messages.Domain.Ids; +using FluentValidation; + +namespace Backbone.Modules.Messages.Application.Messages.Queries.ListMessages; + +// ReSharper disable once UnusedMember.Global +public class Validator : AbstractValidator +{ + public Validator() + { + RuleForEach(x => x.Ids).ValidId(); + } +} diff --git a/Modules/Messages/src/Messages.Application/Messages/RequestHandlerBase.cs b/Modules/Messages/src/Messages.Application/Messages/RequestHandlerBase.cs deleted file mode 100644 index 62c9c548ec..0000000000 --- a/Modules/Messages/src/Messages.Application/Messages/RequestHandlerBase.cs +++ /dev/null @@ -1,23 +0,0 @@ -using AutoMapper; -using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.EventBus; -using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.UserContext; -using Backbone.DevelopmentKit.Identity.ValueObjects; -using MediatR; - -namespace Backbone.Modules.Messages.Application.Messages; - -public abstract class RequestHandlerBase : IRequestHandler where TRequest : IRequest -{ - protected readonly IdentityAddress _activeIdentity; - protected readonly IEventBus _eventBus; - protected readonly IMapper _mapper; - - protected RequestHandlerBase(IUserContext userContext, IMapper mapper, IEventBus eventBus) - { - _mapper = mapper; - _eventBus = eventBus; - _activeIdentity = userContext.GetAddress(); - } - - public abstract Task Handle(TRequest request, CancellationToken cancellationToken); -} diff --git a/Modules/Messages/src/Messages.ConsumerApi/Controllers/MessagesController.cs b/Modules/Messages/src/Messages.ConsumerApi/Controllers/MessagesController.cs index 7402f651e9..5cf43e9811 100644 --- a/Modules/Messages/src/Messages.ConsumerApi/Controllers/MessagesController.cs +++ b/Modules/Messages/src/Messages.ConsumerApi/Controllers/MessagesController.cs @@ -10,7 +10,6 @@ using Backbone.Modules.Messages.Application.Messages.DTOs; using Backbone.Modules.Messages.Application.Messages.Queries.GetMessage; using Backbone.Modules.Messages.Application.Messages.Queries.ListMessages; -using Backbone.Modules.Messages.Domain.Ids; using MediatR; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; @@ -34,7 +33,7 @@ public MessagesController(IMediator mediator, IOptions optio [HttpGet] [ProducesResponseType(typeof(PagedHttpResponseEnvelope), StatusCodes.Status200OK)] public async Task ListMessages([FromQuery] PaginationFilter paginationFilter, - [FromQuery] IEnumerable ids, CancellationToken cancellationToken) + [FromQuery] IEnumerable ids, CancellationToken cancellationToken) { var command = new ListMessagesQuery(paginationFilter, ids); @@ -51,7 +50,7 @@ public async Task ListMessages([FromQuery] PaginationFilter pagin [HttpGet("{id}")] [ProducesResponseType(typeof(HttpResponseEnvelopeResult), StatusCodes.Status200OK)] [ProducesError(StatusCodes.Status404NotFound)] - public async Task GetMessage(MessageId id, [FromQuery] bool? noBody, CancellationToken cancellationToken) + public async Task GetMessage(string id, [FromQuery] bool? noBody, CancellationToken cancellationToken) { var response = await _mediator.Send(new GetMessageQuery { Id = id, NoBody = noBody == true }, cancellationToken); return Ok(response); @@ -62,7 +61,7 @@ public async Task GetMessage(MessageId id, [FromQuery] bool? noBo [ProducesError(StatusCodes.Status400BadRequest)] public async Task SendMessage(SendMessageCommand request, CancellationToken cancellationToken) { - var recipientAddresses = request.Recipients.Select(r => r.Address); + var recipientAddresses = request.Recipients.Select(r => r.Address).ToList(); var identitiesToBeDeleted = await _mediator.Send(new ListIdentitiesQuery(recipientAddresses, IdentityStatus.ToBeDeleted), cancellationToken); if (identitiesToBeDeleted.Any()) throw new ApplicationException(ApplicationErrors.RecipientsToBeDeleted(identitiesToBeDeleted.Select(i => i.Address))); diff --git a/Modules/Messages/test/Messages.Application.Tests/Tests/AutoMapper/AutoMapperProfileTests.cs b/Modules/Messages/test/Messages.Application.Tests/Tests/AutoMapper/AutoMapperProfileTests.cs deleted file mode 100644 index 7239c6c798..0000000000 --- a/Modules/Messages/test/Messages.Application.Tests/Tests/AutoMapper/AutoMapperProfileTests.cs +++ /dev/null @@ -1,19 +0,0 @@ -using AutoMapper; -using Backbone.Modules.Messages.Application.AutoMapper; -using Backbone.UnitTestTools.BaseClasses; -using Xunit; - -namespace Backbone.Modules.Messages.Application.Tests.Tests.AutoMapper; - -public class AutoMapperProfileTests : AbstractTestsBase -{ - [Fact] - public void ProfileIsValid() - { - // Arrange - var configuration = new MapperConfiguration(cfg => cfg.AddProfile()); - - // Act & Assert - configuration.AssertConfigurationIsValid(); - } -} diff --git a/Modules/Quotas/src/Quotas.Application/AutoMapper/AutoMapperProfile.cs b/Modules/Quotas/src/Quotas.Application/AutoMapper/AutoMapperProfile.cs deleted file mode 100644 index f3e3687faa..0000000000 --- a/Modules/Quotas/src/Quotas.Application/AutoMapper/AutoMapperProfile.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Reflection; -using AutoMapper; -using Backbone.BuildingBlocks.Application.AutoMapper; - -namespace Backbone.Modules.Quotas.Application.AutoMapper; - -public class AutoMapperProfile : AutoMapperProfileBase -{ - public AutoMapperProfile() : base(Assembly.GetExecutingAssembly()) { } - - public static IMapper CreateMapper() - { - var profile = new AutoMapperProfile(); - var config = new MapperConfiguration(cfg => cfg.AddProfile(profile)); - var mapper = config.CreateMapper(); - return mapper; - } -} diff --git a/Modules/Quotas/src/Quotas.Application/DTOs/MetricStatusDTO.cs b/Modules/Quotas/src/Quotas.Application/DTOs/MetricStatusDTO.cs deleted file mode 100644 index 54d7dd90cf..0000000000 --- a/Modules/Quotas/src/Quotas.Application/DTOs/MetricStatusDTO.cs +++ /dev/null @@ -1,2 +0,0 @@ -namespace Backbone.Modules.Quotas.Application.DTOs; -public class MetricStatusDTO; diff --git a/Modules/Quotas/src/Quotas.Application/Extensions/IServiceCollectionExtensions.cs b/Modules/Quotas/src/Quotas.Application/Extensions/IServiceCollectionExtensions.cs index a07d839e6c..96997e39f6 100644 --- a/Modules/Quotas/src/Quotas.Application/Extensions/IServiceCollectionExtensions.cs +++ b/Modules/Quotas/src/Quotas.Application/Extensions/IServiceCollectionExtensions.cs @@ -1,7 +1,6 @@ using System.Reflection; using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.EventBus; using Backbone.BuildingBlocks.Application.MediatR; -using Backbone.Modules.Quotas.Application.AutoMapper; using Backbone.Modules.Quotas.Application.Metrics; using Backbone.Modules.Quotas.Application.Tiers.Commands.CreateQuotaForTier; using Backbone.Modules.Quotas.Domain; @@ -21,7 +20,6 @@ public static void AddApplication(this IServiceCollection services) ); services.AddScoped(); - services.AddAutoMapper(typeof(AutoMapperProfile)); services.AddEventHandlers(); services.AddMetricCalculators(); } diff --git a/Modules/Quotas/src/Quotas.Application/Identities/Commands/CreateQuotaForIdentity/CreateQuotaForIdentityCommandValidator.cs b/Modules/Quotas/src/Quotas.Application/Identities/Commands/CreateQuotaForIdentity/Validator.cs similarity index 63% rename from Modules/Quotas/src/Quotas.Application/Identities/Commands/CreateQuotaForIdentity/CreateQuotaForIdentityCommandValidator.cs rename to Modules/Quotas/src/Quotas.Application/Identities/Commands/CreateQuotaForIdentity/Validator.cs index 90dc6ffb1c..22ee83ca82 100644 --- a/Modules/Quotas/src/Quotas.Application/Identities/Commands/CreateQuotaForIdentity/CreateQuotaForIdentityCommandValidator.cs +++ b/Modules/Quotas/src/Quotas.Application/Identities/Commands/CreateQuotaForIdentity/Validator.cs @@ -1,15 +1,16 @@ using Backbone.BuildingBlocks.Application.Abstractions.Exceptions; +using Backbone.BuildingBlocks.Application.Extensions; using Backbone.BuildingBlocks.Application.FluentValidation; +using Backbone.DevelopmentKit.Identity.ValueObjects; using FluentValidation; namespace Backbone.Modules.Quotas.Application.Identities.Commands.CreateQuotaForIdentity; -public class CreateQuotaForIdentityCommandValidator : AbstractValidator +public class Validator : AbstractValidator { - public CreateQuotaForIdentityCommandValidator() + public Validator() { - RuleFor(c => c.IdentityAddress) - .DetailedNotEmpty(); + RuleFor(c => c.IdentityAddress).ValidId(); RuleFor(c => c.Max) .GreaterThan(0).WithErrorCode(GenericApplicationErrors.Validation.InvalidPropertyValue().Code); RuleFor(c => c.Period) diff --git a/Modules/Quotas/src/Quotas.Application/Identities/Commands/DeleteIdentity/DeleteIdentityCommand.cs b/Modules/Quotas/src/Quotas.Application/Identities/Commands/DeleteIdentity/DeleteIdentityCommand.cs index a9cc335df8..71201170f2 100644 --- a/Modules/Quotas/src/Quotas.Application/Identities/Commands/DeleteIdentity/DeleteIdentityCommand.cs +++ b/Modules/Quotas/src/Quotas.Application/Identities/Commands/DeleteIdentity/DeleteIdentityCommand.cs @@ -1,13 +1,13 @@ -using Backbone.DevelopmentKit.Identity.ValueObjects; -using MediatR; +using MediatR; namespace Backbone.Modules.Quotas.Application.Identities.Commands.DeleteIdentity; + public class DeleteIdentityCommand : IRequest { - public DeleteIdentityCommand(IdentityAddress identityAddress) + public DeleteIdentityCommand(string identityAddress) { IdentityAddress = identityAddress; } - public IdentityAddress IdentityAddress { get; set; } + public string IdentityAddress { get; set; } } diff --git a/Modules/Quotas/src/Quotas.Application/Identities/Commands/DeleteIdentity/Validator.cs b/Modules/Quotas/src/Quotas.Application/Identities/Commands/DeleteIdentity/Validator.cs index f7a6a00f35..76c33eb37e 100644 --- a/Modules/Quotas/src/Quotas.Application/Identities/Commands/DeleteIdentity/Validator.cs +++ b/Modules/Quotas/src/Quotas.Application/Identities/Commands/DeleteIdentity/Validator.cs @@ -1,8 +1,13 @@ -using Backbone.DevelopmentKit.Identity.ValueObjects; +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.DevelopmentKit.Identity.ValueObjects; using FluentValidation; namespace Backbone.Modules.Quotas.Application.Identities.Commands.DeleteIdentity; + public class Validator : AbstractValidator { - public Validator() => RuleFor(x => x.IdentityAddress).Must(x => IdentityAddress.IsValid(x)); + public Validator() + { + RuleFor(x => x.IdentityAddress).ValidId(); + } } diff --git a/Modules/Quotas/src/Quotas.Application/Identities/Commands/DeleteQuotaForIdentity/DeleteQuotaForIdentityCommandValidator.cs b/Modules/Quotas/src/Quotas.Application/Identities/Commands/DeleteQuotaForIdentity/DeleteQuotaForIdentityCommandValidator.cs deleted file mode 100644 index d5229c0fde..0000000000 --- a/Modules/Quotas/src/Quotas.Application/Identities/Commands/DeleteQuotaForIdentity/DeleteQuotaForIdentityCommandValidator.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Backbone.BuildingBlocks.Application.FluentValidation; -using FluentValidation; - -namespace Backbone.Modules.Quotas.Application.Identities.Commands.DeleteQuotaForIdentity; - -public class DeleteQuotaForIdentityCommandValidator : AbstractValidator -{ - public DeleteQuotaForIdentityCommandValidator() - { - RuleFor(c => c.IdentityAddress).DetailedNotEmpty(); - RuleFor(c => c.IndividualQuotaId).DetailedNotEmpty(); - } -} diff --git a/Modules/Quotas/src/Quotas.Application/Identities/Commands/DeleteQuotaForIdentity/Validator.cs b/Modules/Quotas/src/Quotas.Application/Identities/Commands/DeleteQuotaForIdentity/Validator.cs new file mode 100644 index 0000000000..5f5b734d91 --- /dev/null +++ b/Modules/Quotas/src/Quotas.Application/Identities/Commands/DeleteQuotaForIdentity/Validator.cs @@ -0,0 +1,15 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.DevelopmentKit.Identity.ValueObjects; +using Backbone.Modules.Quotas.Domain.Aggregates.Identities; +using FluentValidation; + +namespace Backbone.Modules.Quotas.Application.Identities.Commands.DeleteQuotaForIdentity; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleFor(c => c.IdentityAddress).ValidId(); + RuleFor(c => c.IndividualQuotaId).ValidId(); + } +} diff --git a/Modules/Quotas/src/Quotas.Application/Identities/Queries/GetIdentity/GetIdentityQuery.cs b/Modules/Quotas/src/Quotas.Application/Identities/Queries/GetIdentity/GetIdentityQuery.cs index bb968c9a1e..704d58fbb4 100644 --- a/Modules/Quotas/src/Quotas.Application/Identities/Queries/GetIdentity/GetIdentityQuery.cs +++ b/Modules/Quotas/src/Quotas.Application/Identities/Queries/GetIdentity/GetIdentityQuery.cs @@ -1,11 +1,13 @@ using MediatR; namespace Backbone.Modules.Quotas.Application.Identities.Queries.GetIdentity; + public class GetIdentityQuery : IRequest { public GetIdentityQuery(string address) { Address = address; } + public string Address { get; set; } } diff --git a/Modules/Quotas/src/Quotas.Application/Identities/Queries/GetIdentity/GetIdentityResponse.cs b/Modules/Quotas/src/Quotas.Application/Identities/Queries/GetIdentity/GetIdentityResponse.cs index f6dcb4fa8b..6749f93c3b 100644 --- a/Modules/Quotas/src/Quotas.Application/Identities/Queries/GetIdentity/GetIdentityResponse.cs +++ b/Modules/Quotas/src/Quotas.Application/Identities/Queries/GetIdentity/GetIdentityResponse.cs @@ -5,6 +5,7 @@ using Backbone.Tooling; namespace Backbone.Modules.Quotas.Application.Identities.Queries.GetIdentity; + public class GetIdentityResponse { public required string Address { get; set; } @@ -26,7 +27,7 @@ public static async Task Create(MetricCalculatorFactory met )); } - return new GetIdentityResponse() + return new GetIdentityResponse { Address = identityAddress, Quotas = quotasList diff --git a/Modules/Quotas/src/Quotas.Application/Identities/Queries/GetIdentity/Validator.cs b/Modules/Quotas/src/Quotas.Application/Identities/Queries/GetIdentity/Validator.cs new file mode 100644 index 0000000000..8d1cba4810 --- /dev/null +++ b/Modules/Quotas/src/Quotas.Application/Identities/Queries/GetIdentity/Validator.cs @@ -0,0 +1,13 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.DevelopmentKit.Identity.ValueObjects; +using FluentValidation; + +namespace Backbone.Modules.Quotas.Application.Identities.Queries.GetIdentity; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleFor(x => x.Address).ValidId(); + } +} diff --git a/Modules/Quotas/src/Quotas.Application/Metrics/Queries/ListMetrics/Handler.cs b/Modules/Quotas/src/Quotas.Application/Metrics/Queries/ListMetrics/Handler.cs index 0c171ade54..ee44ffe99a 100644 --- a/Modules/Quotas/src/Quotas.Application/Metrics/Queries/ListMetrics/Handler.cs +++ b/Modules/Quotas/src/Quotas.Application/Metrics/Queries/ListMetrics/Handler.cs @@ -1,8 +1,8 @@ -using Backbone.Modules.Quotas.Application.DTOs; using Backbone.Modules.Quotas.Application.Infrastructure.Persistence.Repository; using MediatR; namespace Backbone.Modules.Quotas.Application.Metrics.Queries.ListMetrics; + public class Handler : IRequestHandler { private readonly IMetricsRepository _metricsRepository; @@ -15,8 +15,6 @@ public Handler(IMetricsRepository metricsRepository) public async Task Handle(ListMetricsQuery request, CancellationToken cancellationToken) { var metrics = await _metricsRepository.FindAll(cancellationToken); - var metricDtos = metrics.Select(m => new MetricDTO(m)); - - return new ListMetricsResponse(metricDtos); + return new ListMetricsResponse(metrics); } } diff --git a/Modules/Quotas/src/Quotas.Application/Metrics/Queries/ListMetrics/ListMetricsResponse.cs b/Modules/Quotas/src/Quotas.Application/Metrics/Queries/ListMetrics/ListMetricsResponse.cs index aa85fbd9f0..db769040f2 100644 --- a/Modules/Quotas/src/Quotas.Application/Metrics/Queries/ListMetrics/ListMetricsResponse.cs +++ b/Modules/Quotas/src/Quotas.Application/Metrics/Queries/ListMetrics/ListMetricsResponse.cs @@ -1,8 +1,12 @@ using Backbone.BuildingBlocks.Application.CQRS.BaseClasses; using Backbone.Modules.Quotas.Application.DTOs; +using Backbone.Modules.Quotas.Domain.Aggregates.Metrics; namespace Backbone.Modules.Quotas.Application.Metrics.Queries.ListMetrics; + public class ListMetricsResponse : CollectionResponseBase { - public ListMetricsResponse(IEnumerable items) : base(items) { } + public ListMetricsResponse(IEnumerable items) : base(items.Select(m => new MetricDTO(m))) + { + } } diff --git a/Modules/Quotas/src/Quotas.Application/Tiers/Commands/CreateQuotaForTier/CreateQuotaForTierCommandValidator.cs b/Modules/Quotas/src/Quotas.Application/Tiers/Commands/CreateQuotaForTier/Validator.cs similarity index 64% rename from Modules/Quotas/src/Quotas.Application/Tiers/Commands/CreateQuotaForTier/CreateQuotaForTierCommandValidator.cs rename to Modules/Quotas/src/Quotas.Application/Tiers/Commands/CreateQuotaForTier/Validator.cs index 37f599e6cc..321117b49f 100644 --- a/Modules/Quotas/src/Quotas.Application/Tiers/Commands/CreateQuotaForTier/CreateQuotaForTierCommandValidator.cs +++ b/Modules/Quotas/src/Quotas.Application/Tiers/Commands/CreateQuotaForTier/Validator.cs @@ -1,15 +1,16 @@ using Backbone.BuildingBlocks.Application.Abstractions.Exceptions; +using Backbone.BuildingBlocks.Application.Extensions; using Backbone.BuildingBlocks.Application.FluentValidation; +using Backbone.Modules.Quotas.Domain.Aggregates.Tiers; using FluentValidation; namespace Backbone.Modules.Quotas.Application.Tiers.Commands.CreateQuotaForTier; -public class CreateQuotaForTierCommandValidator : AbstractValidator +public class Validator : AbstractValidator { - public CreateQuotaForTierCommandValidator() + public Validator() { - RuleFor(c => c.TierId) - .DetailedNotEmpty(); + RuleFor(c => c.TierId).ValidId(); RuleFor(c => c.Max) .GreaterThan(0).WithErrorCode(GenericApplicationErrors.Validation.InvalidPropertyValue().Code); RuleFor(c => c.Period) diff --git a/Modules/Quotas/src/Quotas.Application/Tiers/Commands/DeleteTierQuotaDefinition/DeleteTierQuotaDefinitionCommandValidator.cs b/Modules/Quotas/src/Quotas.Application/Tiers/Commands/DeleteTierQuotaDefinition/DeleteTierQuotaDefinitionCommandValidator.cs deleted file mode 100644 index 9e6e977fce..0000000000 --- a/Modules/Quotas/src/Quotas.Application/Tiers/Commands/DeleteTierQuotaDefinition/DeleteTierQuotaDefinitionCommandValidator.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Backbone.BuildingBlocks.Application.FluentValidation; -using FluentValidation; - -namespace Backbone.Modules.Quotas.Application.Tiers.Commands.DeleteTierQuotaDefinition; -public class DeleteTierQuotaDefinitionCommandValidator : AbstractValidator -{ - public DeleteTierQuotaDefinitionCommandValidator() - { - RuleFor(c => c.TierId).DetailedNotEmpty(); - RuleFor(c => c.TierQuotaDefinitionId).DetailedNotEmpty(); - } -} diff --git a/Modules/Quotas/src/Quotas.Application/Tiers/Commands/DeleteTierQuotaDefinition/Validator.cs b/Modules/Quotas/src/Quotas.Application/Tiers/Commands/DeleteTierQuotaDefinition/Validator.cs new file mode 100644 index 0000000000..5e5d3a98b6 --- /dev/null +++ b/Modules/Quotas/src/Quotas.Application/Tiers/Commands/DeleteTierQuotaDefinition/Validator.cs @@ -0,0 +1,14 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.Modules.Quotas.Domain.Aggregates.Tiers; +using FluentValidation; + +namespace Backbone.Modules.Quotas.Application.Tiers.Commands.DeleteTierQuotaDefinition; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleFor(c => c.TierId).ValidId(); + RuleFor(c => c.TierQuotaDefinitionId).ValidId(); + } +} diff --git a/Modules/Quotas/src/Quotas.Application/Tiers/Queries/GetTierById/Validator.cs b/Modules/Quotas/src/Quotas.Application/Tiers/Queries/GetTierById/Validator.cs new file mode 100644 index 0000000000..634c0384e1 --- /dev/null +++ b/Modules/Quotas/src/Quotas.Application/Tiers/Queries/GetTierById/Validator.cs @@ -0,0 +1,13 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.Modules.Quotas.Domain.Aggregates.Tiers; +using FluentValidation; + +namespace Backbone.Modules.Quotas.Application.Tiers.Queries.GetTierById; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleFor(c => c.Id).ValidId(); + } +} diff --git a/Modules/Quotas/src/Quotas.Domain/Aggregates/Identities/QuotaId.cs b/Modules/Quotas/src/Quotas.Domain/Aggregates/Identities/QuotaId.cs index 8fa78ff86d..213734fdf5 100644 --- a/Modules/Quotas/src/Quotas.Domain/Aggregates/Identities/QuotaId.cs +++ b/Modules/Quotas/src/Quotas.Domain/Aggregates/Identities/QuotaId.cs @@ -18,6 +18,11 @@ private QuotaId(string value) : base(value) } + public static bool IsValid(string stringValue) + { + return UTILS.IsValid(stringValue); + } + public static QuotaId Generate() { var value = PREFIX + StringUtils.Generate(DEFAULT_VALID_CHARS, DEFAULT_MAX_LENGTH_WITHOUT_PREFIX); diff --git a/Modules/Quotas/src/Quotas.Domain/Aggregates/Tiers/TierId.cs b/Modules/Quotas/src/Quotas.Domain/Aggregates/Tiers/TierId.cs index 303f6bc25a..4149ceb511 100644 --- a/Modules/Quotas/src/Quotas.Domain/Aggregates/Tiers/TierId.cs +++ b/Modules/Quotas/src/Quotas.Domain/Aggregates/Tiers/TierId.cs @@ -1,22 +1,30 @@ using System.ComponentModel; using System.Globalization; +using Backbone.BuildingBlocks.Domain.StronglyTypedIds.Records; namespace Backbone.Modules.Quotas.Domain.Aggregates.Tiers; [Serializable] [TypeConverter(typeof(TierIdTypeConverter))] -public record TierId +public record TierId : StronglyTypedId { - public string Value { get; } + public const int MAX_LENGTH = DEFAULT_MAX_LENGTH; + private const string PREFIX = "TIR"; + + private static readonly StronglyTypedIdHelpers UTILS = new(PREFIX, DEFAULT_VALID_CHARS, MAX_LENGTH); public static implicit operator string(TierId id) { return id.Value; } - private TierId(string value) + private TierId(string value) : base(value) + { + } + + public static bool IsValid(string stringValue) { - Value = value; + return UTILS.IsValid(stringValue); } public static TierId Parse(string stringValue) diff --git a/Modules/Quotas/src/Quotas.Domain/Aggregates/Tiers/TierQuotaDefinitionId.cs b/Modules/Quotas/src/Quotas.Domain/Aggregates/Tiers/TierQuotaDefinitionId.cs index 33444c52b6..2d0ea35a26 100644 --- a/Modules/Quotas/src/Quotas.Domain/Aggregates/Tiers/TierQuotaDefinitionId.cs +++ b/Modules/Quotas/src/Quotas.Domain/Aggregates/Tiers/TierQuotaDefinitionId.cs @@ -18,6 +18,11 @@ private TierQuotaDefinitionId(string value) : base(value) } + public static bool IsValid(string stringValue) + { + return UTILS.IsValid(stringValue); + } + public static TierQuotaDefinitionId Generate() { var value = PREFIX + StringUtils.Generate(DEFAULT_VALID_CHARS, DEFAULT_MAX_LENGTH_WITHOUT_PREFIX); diff --git a/Modules/Relationships/src/Relationships.Application/AutoMapper/AutoMapperProfile.Tests.cs b/Modules/Relationships/src/Relationships.Application/AutoMapper/AutoMapperProfile.Tests.cs deleted file mode 100644 index 94e1896c7d..0000000000 --- a/Modules/Relationships/src/Relationships.Application/AutoMapper/AutoMapperProfile.Tests.cs +++ /dev/null @@ -1,18 +0,0 @@ -using AutoMapper; -using Backbone.UnitTestTools.BaseClasses; -using Xunit; - -namespace Backbone.Modules.Relationships.Application.AutoMapper; - -public class AutoMapperProfileTests : AbstractTestsBase -{ - [Fact] - public void ProfileIsValid() - { - // Arrange - var configuration = new MapperConfiguration(cfg => cfg.AddProfile()); - - // Act & Assert - configuration.AssertConfigurationIsValid(); - } -} diff --git a/Modules/Relationships/src/Relationships.Application/AutoMapper/AutoMapperProfile.cs b/Modules/Relationships/src/Relationships.Application/AutoMapper/AutoMapperProfile.cs deleted file mode 100644 index f43e069e98..0000000000 --- a/Modules/Relationships/src/Relationships.Application/AutoMapper/AutoMapperProfile.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Reflection; -using AutoMapper; -using Backbone.BuildingBlocks.Application.AutoMapper; - -namespace Backbone.Modules.Relationships.Application.AutoMapper; - -public class AutoMapperProfile : AutoMapperProfileBase -{ - public AutoMapperProfile() : base(Assembly.GetExecutingAssembly()) { } - - public static IMapper CreateMapper() - { - var profile = new AutoMapperProfile(); - var config = new MapperConfiguration(cfg => cfg.AddProfile(profile)); - var mapper = config.CreateMapper(); - return mapper; - } -} diff --git a/Modules/Relationships/src/Relationships.Application/Extensions/IServiceCollectionExtensions.cs b/Modules/Relationships/src/Relationships.Application/Extensions/IServiceCollectionExtensions.cs index fef7aff125..e693aabe90 100644 --- a/Modules/Relationships/src/Relationships.Application/Extensions/IServiceCollectionExtensions.cs +++ b/Modules/Relationships/src/Relationships.Application/Extensions/IServiceCollectionExtensions.cs @@ -1,7 +1,6 @@ using System.Reflection; using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.EventBus; using Backbone.BuildingBlocks.Application.MediatR; -using Backbone.Modules.Relationships.Application.AutoMapper; using Backbone.Modules.Relationships.Application.RelationshipTemplates.Commands.CreateRelationshipTemplate; using FluentValidation; using Microsoft.Extensions.DependencyInjection; @@ -19,8 +18,7 @@ public static void AddApplication(this IServiceCollection services) .AddOpenBehavior(typeof(QuotaEnforcerBehavior<,>)) ); - services.AddAutoMapper(typeof(AutoMapperProfile).Assembly); - services.AddValidatorsFromAssembly(typeof(CreateRelationshipTemplateCommandValidator).Assembly); + services.AddValidatorsFromAssembly(typeof(Validator).Assembly); services.AddEventHandlers(); } diff --git a/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Commands/AnonymizeRelationshipTemplateAllocationsAllocatedByIdentity/AnonymizeRelationshipTemplateAllocationsAllocatedByIdentityCommand.cs b/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Commands/AnonymizeRelationshipTemplateAllocationsAllocatedByIdentity/AnonymizeRelationshipTemplateAllocationsAllocatedByIdentityCommand.cs index 7a936e1b57..6ce0904842 100644 --- a/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Commands/AnonymizeRelationshipTemplateAllocationsAllocatedByIdentity/AnonymizeRelationshipTemplateAllocationsAllocatedByIdentityCommand.cs +++ b/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Commands/AnonymizeRelationshipTemplateAllocationsAllocatedByIdentity/AnonymizeRelationshipTemplateAllocationsAllocatedByIdentityCommand.cs @@ -1,14 +1,13 @@ -using Backbone.DevelopmentKit.Identity.ValueObjects; -using MediatR; +using MediatR; namespace Backbone.Modules.Relationships.Application.RelationshipTemplates.Commands.AnonymizeRelationshipTemplateAllocationsAllocatedByIdentity; public class AnonymizeRelationshipTemplateAllocationsAllocatedByIdentityCommand : IRequest { - public AnonymizeRelationshipTemplateAllocationsAllocatedByIdentityCommand(IdentityAddress identityAddress) + public AnonymizeRelationshipTemplateAllocationsAllocatedByIdentityCommand(string identityAddress) { IdentityAddress = identityAddress; } - public IdentityAddress IdentityAddress { get; set; } + public string IdentityAddress { get; set; } } diff --git a/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Commands/AnonymizeRelationshipTemplateAllocationsAllocatedByIdentity/Validator.cs b/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Commands/AnonymizeRelationshipTemplateAllocationsAllocatedByIdentity/Validator.cs index d0fc87c588..0461f069aa 100644 --- a/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Commands/AnonymizeRelationshipTemplateAllocationsAllocatedByIdentity/Validator.cs +++ b/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Commands/AnonymizeRelationshipTemplateAllocationsAllocatedByIdentity/Validator.cs @@ -1,9 +1,13 @@ -using Backbone.DevelopmentKit.Identity.ValueObjects; +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.DevelopmentKit.Identity.ValueObjects; using FluentValidation; namespace Backbone.Modules.Relationships.Application.RelationshipTemplates.Commands.AnonymizeRelationshipTemplateAllocationsAllocatedByIdentity; public class Validator : AbstractValidator { - public Validator() => RuleFor(x => x.IdentityAddress).Must(x => IdentityAddress.IsValid(x)); + public Validator() + { + RuleFor(x => x.IdentityAddress).ValidId(); + } } diff --git a/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Commands/CreateRelationshipTemplate/CreateRelationshipTemplateCommand.cs b/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Commands/CreateRelationshipTemplate/CreateRelationshipTemplateCommand.cs index 883788a994..597546ab82 100644 --- a/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Commands/CreateRelationshipTemplate/CreateRelationshipTemplateCommand.cs +++ b/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Commands/CreateRelationshipTemplate/CreateRelationshipTemplateCommand.cs @@ -1,12 +1,10 @@ -using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.Mapping; using Backbone.BuildingBlocks.Application.Attributes; -using Backbone.Modules.Relationships.Domain.Aggregates.RelationshipTemplates; using MediatR; namespace Backbone.Modules.Relationships.Application.RelationshipTemplates.Commands.CreateRelationshipTemplate; [ApplyQuotasForMetrics("NumberOfRelationshipTemplates")] -public class CreateRelationshipTemplateCommand : IMapTo, IRequest +public class CreateRelationshipTemplateCommand : IRequest { public DateTime? ExpiresAt { get; set; } public int? MaxNumberOfAllocations { get; set; } diff --git a/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Commands/CreateRelationshipTemplate/CreateRelationshipTemplateResponse.cs b/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Commands/CreateRelationshipTemplate/CreateRelationshipTemplateResponse.cs index 3eaee098df..24e0f51436 100644 --- a/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Commands/CreateRelationshipTemplate/CreateRelationshipTemplateResponse.cs +++ b/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Commands/CreateRelationshipTemplate/CreateRelationshipTemplateResponse.cs @@ -1,10 +1,15 @@ -using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.Mapping; using Backbone.Modules.Relationships.Domain.Aggregates.RelationshipTemplates; namespace Backbone.Modules.Relationships.Application.RelationshipTemplates.Commands.CreateRelationshipTemplate; -public class CreateRelationshipTemplateResponse : IMapTo +public class CreateRelationshipTemplateResponse { - public required RelationshipTemplateId Id { get; set; } - public required DateTime CreatedAt { get; set; } + public CreateRelationshipTemplateResponse(RelationshipTemplate relationshipTemplate) + { + Id = relationshipTemplate.Id; + CreatedAt = relationshipTemplate.CreatedAt; + } + + public string Id { get; set; } + public DateTime CreatedAt { get; set; } } diff --git a/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Commands/CreateRelationshipTemplate/Handler.cs b/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Commands/CreateRelationshipTemplate/Handler.cs index 83a116c064..2121246a89 100644 --- a/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Commands/CreateRelationshipTemplate/Handler.cs +++ b/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Commands/CreateRelationshipTemplate/Handler.cs @@ -1,4 +1,3 @@ -using AutoMapper; using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.UserContext; using Backbone.Modules.Relationships.Application.Infrastructure.Persistence.Repository; using Backbone.Modules.Relationships.Domain.Aggregates.RelationshipTemplates; @@ -9,14 +8,12 @@ namespace Backbone.Modules.Relationships.Application.RelationshipTemplates.Comma public class Handler : IRequestHandler { private readonly IRelationshipTemplatesRepository _relationshipTemplatesRepository; - private readonly IMapper _mapper; private readonly IUserContext _userContext; - public Handler(IRelationshipTemplatesRepository relationshipTemplatesRepository, IUserContext userContext, IMapper mapper) + public Handler(IRelationshipTemplatesRepository relationshipTemplatesRepository, IUserContext userContext) { _relationshipTemplatesRepository = relationshipTemplatesRepository; _userContext = userContext; - _mapper = mapper; } public async Task Handle(CreateRelationshipTemplateCommand request, CancellationToken cancellationToken) @@ -30,6 +27,6 @@ public async Task Handle(CreateRelationshipT await _relationshipTemplatesRepository.Add(template, cancellationToken); - return _mapper.Map(template); + return new CreateRelationshipTemplateResponse(template); } } diff --git a/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Commands/CreateRelationshipTemplate/CreateRelationshipTemplateCommandValidator.cs b/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Commands/CreateRelationshipTemplate/Validator.cs similarity index 83% rename from Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Commands/CreateRelationshipTemplate/CreateRelationshipTemplateCommandValidator.cs rename to Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Commands/CreateRelationshipTemplate/Validator.cs index b362d9c754..4b03fc5caf 100644 --- a/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Commands/CreateRelationshipTemplate/CreateRelationshipTemplateCommandValidator.cs +++ b/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Commands/CreateRelationshipTemplate/Validator.cs @@ -6,9 +6,9 @@ namespace Backbone.Modules.Relationships.Application.RelationshipTemplates.Commands.CreateRelationshipTemplate; -public class CreateRelationshipTemplateCommandValidator : AbstractValidator +public class Validator : AbstractValidator { - public CreateRelationshipTemplateCommandValidator() + public Validator() { RuleFor(c => c.Content).NumberOfBytes(0, 10.Mebibytes()); diff --git a/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Commands/DeleteRelationshipTemplatesOfIdentity/DeleteRelationshipTemplatesOfIdentityCommand.cs b/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Commands/DeleteRelationshipTemplatesOfIdentity/DeleteRelationshipTemplatesOfIdentityCommand.cs index 2b5de05e57..1166fa095a 100644 --- a/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Commands/DeleteRelationshipTemplatesOfIdentity/DeleteRelationshipTemplatesOfIdentityCommand.cs +++ b/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Commands/DeleteRelationshipTemplatesOfIdentity/DeleteRelationshipTemplatesOfIdentityCommand.cs @@ -1,14 +1,13 @@ -using Backbone.DevelopmentKit.Identity.ValueObjects; using MediatR; namespace Backbone.Modules.Relationships.Application.RelationshipTemplates.Commands.DeleteRelationshipTemplatesOfIdentity; public class DeleteRelationshipTemplatesOfIdentityCommand : IRequest { - public DeleteRelationshipTemplatesOfIdentityCommand(IdentityAddress identityAddress) + public DeleteRelationshipTemplatesOfIdentityCommand(string identityAddress) { IdentityAddress = identityAddress; } - public IdentityAddress IdentityAddress { get; set; } + public string IdentityAddress { get; set; } } diff --git a/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Commands/DeleteRelationshipTemplatesOfIdentity/Validator.cs b/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Commands/DeleteRelationshipTemplatesOfIdentity/Validator.cs index 42e9de7aa5..f89b7fce40 100644 --- a/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Commands/DeleteRelationshipTemplatesOfIdentity/Validator.cs +++ b/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Commands/DeleteRelationshipTemplatesOfIdentity/Validator.cs @@ -1,8 +1,13 @@ -using Backbone.DevelopmentKit.Identity.ValueObjects; +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.DevelopmentKit.Identity.ValueObjects; using FluentValidation; namespace Backbone.Modules.Relationships.Application.RelationshipTemplates.Commands.DeleteRelationshipTemplatesOfIdentity; + public class Validator : AbstractValidator { - public Validator() => RuleFor(x => x.IdentityAddress).Must(x => IdentityAddress.IsValid(x)); + public Validator() + { + RuleFor(x => x.IdentityAddress).ValidId(); + } } diff --git a/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Queries/GetRelationshipTemplate/Handler.cs b/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Queries/GetRelationshipTemplate/Handler.cs index 9f9bb869e7..454305f741 100644 --- a/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Queries/GetRelationshipTemplate/Handler.cs +++ b/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Queries/GetRelationshipTemplate/Handler.cs @@ -1,4 +1,3 @@ -using AutoMapper; using Backbone.BuildingBlocks.Application.Abstractions.Exceptions; using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.UserContext; using Backbone.Modules.Relationships.Application.Infrastructure.Persistence.Repository; @@ -10,13 +9,11 @@ namespace Backbone.Modules.Relationships.Application.RelationshipTemplates.Queri public class Handler : IRequestHandler { - private readonly IMapper _mapper; private readonly IRelationshipTemplatesRepository _relationshipTemplatesRepository; private readonly IUserContext _userContext; - public Handler(IUserContext userContext, IMapper mapper, IRelationshipTemplatesRepository relationshipTemplatesRepository) + public Handler(IUserContext userContext, IRelationshipTemplatesRepository relationshipTemplatesRepository) { - _mapper = mapper; _relationshipTemplatesRepository = relationshipTemplatesRepository; _userContext = userContext; } @@ -30,6 +27,6 @@ public async Task Handle(GetRelationshipTemplateQuery r await _relationshipTemplatesRepository.Update(template); - return _mapper.Map(template); + return new RelationshipTemplateDTO(template); } } diff --git a/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Queries/GetRelationshipTemplate/Validator.cs b/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Queries/GetRelationshipTemplate/Validator.cs new file mode 100644 index 0000000000..55115a2b92 --- /dev/null +++ b/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Queries/GetRelationshipTemplate/Validator.cs @@ -0,0 +1,13 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.Modules.Relationships.Domain.Aggregates.RelationshipTemplates; +using FluentValidation; + +namespace Backbone.Modules.Relationships.Application.RelationshipTemplates.Queries.GetRelationshipTemplate; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleFor(x => x.Id).ValidId(); + } +} diff --git a/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Queries/ListRelationshipTemplates/Handler.cs b/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Queries/ListRelationshipTemplates/Handler.cs index fcfcc43eb7..bf103bc64c 100644 --- a/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Queries/ListRelationshipTemplates/Handler.cs +++ b/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Queries/ListRelationshipTemplates/Handler.cs @@ -1,28 +1,26 @@ -using AutoMapper; using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.UserContext; using Backbone.Modules.Relationships.Application.Infrastructure.Persistence.Repository; -using Backbone.Modules.Relationships.Application.Relationships.DTOs; +using Backbone.Modules.Relationships.Domain.Aggregates.RelationshipTemplates; using MediatR; namespace Backbone.Modules.Relationships.Application.RelationshipTemplates.Queries.ListRelationshipTemplates; public class Handler : IRequestHandler { - private readonly IMapper _mapper; private readonly IRelationshipTemplatesRepository _relationshipTemplatesRepository; private readonly IUserContext _userContext; - public Handler(IUserContext userContext, IMapper mapper, IRelationshipTemplatesRepository relationshipTemplatesRepository) + public Handler(IUserContext userContext, IRelationshipTemplatesRepository relationshipTemplatesRepository) { - _mapper = mapper; _relationshipTemplatesRepository = relationshipTemplatesRepository; _userContext = userContext; } public async Task Handle(ListRelationshipTemplatesQuery request, CancellationToken cancellationToken) { - var dbPaginationResult = await _relationshipTemplatesRepository.FindTemplatesWithIds(request.Ids, _userContext.GetAddress(), request.PaginationFilter, cancellationToken, track: false); + var dbPaginationResult = await _relationshipTemplatesRepository.FindTemplatesWithIds(request.Ids.Select(RelationshipTemplateId.Parse), _userContext.GetAddress(), request.PaginationFilter, + cancellationToken, track: false); - return new ListRelationshipTemplatesResponse(_mapper.Map(dbPaginationResult.ItemsOnPage), request.PaginationFilter, dbPaginationResult.TotalNumberOfItems); + return new ListRelationshipTemplatesResponse(dbPaginationResult, request.PaginationFilter); } } diff --git a/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Queries/ListRelationshipTemplates/ListRelationshipTemplatesQuery.cs b/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Queries/ListRelationshipTemplates/ListRelationshipTemplatesQuery.cs index bcd00bbaf2..ecaa4ba976 100644 --- a/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Queries/ListRelationshipTemplates/ListRelationshipTemplatesQuery.cs +++ b/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Queries/ListRelationshipTemplates/ListRelationshipTemplatesQuery.cs @@ -1,17 +1,16 @@ using Backbone.BuildingBlocks.Application.Pagination; -using Backbone.Modules.Relationships.Domain.Aggregates.RelationshipTemplates; using MediatR; namespace Backbone.Modules.Relationships.Application.RelationshipTemplates.Queries.ListRelationshipTemplates; public class ListRelationshipTemplatesQuery : IRequest { - public ListRelationshipTemplatesQuery(PaginationFilter paginationFilter, IEnumerable? ids) + public ListRelationshipTemplatesQuery(PaginationFilter paginationFilter, IEnumerable? ids) { PaginationFilter = paginationFilter; Ids = ids == null ? [] : ids.ToList(); } public PaginationFilter PaginationFilter { get; set; } - public List Ids { get; set; } + public List Ids { get; set; } } diff --git a/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Queries/ListRelationshipTemplates/ListRelationshipTemplatesResponse.cs b/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Queries/ListRelationshipTemplates/ListRelationshipTemplatesResponse.cs index e509a8881f..c8cfd1e364 100644 --- a/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Queries/ListRelationshipTemplates/ListRelationshipTemplatesResponse.cs +++ b/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Queries/ListRelationshipTemplates/ListRelationshipTemplatesResponse.cs @@ -1,9 +1,14 @@ +using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.Persistence.Database; using Backbone.BuildingBlocks.Application.Pagination; using Backbone.Modules.Relationships.Application.Relationships.DTOs; +using Backbone.Modules.Relationships.Domain.Aggregates.RelationshipTemplates; namespace Backbone.Modules.Relationships.Application.RelationshipTemplates.Queries.ListRelationshipTemplates; public class ListRelationshipTemplatesResponse : PagedResponse { - public ListRelationshipTemplatesResponse(IEnumerable items, PaginationFilter previousPaginationFilter, int totalRecords) : base(items, previousPaginationFilter, totalRecords) { } + public ListRelationshipTemplatesResponse(DbPaginationResult dbPaginationResult, PaginationFilter previousPaginationFilter) : base( + dbPaginationResult.ItemsOnPage.Select(x => new RelationshipTemplateDTO(x)), previousPaginationFilter, dbPaginationResult.TotalNumberOfItems) + { + } } diff --git a/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Queries/ListRelationshipTemplates/ListRelationshipTemplatesValidator.Tests.cs b/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Queries/ListRelationshipTemplates/ListRelationshipTemplatesValidator.Tests.cs index fe80db5956..b8ab48d109 100644 --- a/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Queries/ListRelationshipTemplates/ListRelationshipTemplatesValidator.Tests.cs +++ b/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Queries/ListRelationshipTemplates/ListRelationshipTemplatesValidator.Tests.cs @@ -1,7 +1,7 @@ using Backbone.BuildingBlocks.Application.Pagination; using Backbone.Modules.Relationships.Domain.Aggregates.RelationshipTemplates; using Backbone.UnitTestTools.BaseClasses; -using FluentAssertions; +using Backbone.UnitTestTools.FluentValidation; using FluentValidation.TestHelper; using Xunit; @@ -12,36 +12,45 @@ public class ListRelationshipTemplatesValidatorTests : AbstractTestsBase [Fact] public void Happy_path() { - var validator = new ListRelationshipTemplatesValidator(); + // Arrange + var validator = new Validator(); + // Act var validationResult = validator.TestValidate(new ListRelationshipTemplatesQuery(new PaginationFilter(), [RelationshipTemplateId.New()])); + // Assert validationResult.ShouldNotHaveAnyValidationErrors(); } [Fact] public void Fails_when_Ids_is_null() { - var validator = new ListRelationshipTemplatesValidator(); + // Arrange + var validator = new Validator(); + // Act var validationResult = validator.TestValidate(new ListRelationshipTemplatesQuery(new PaginationFilter(), null)); - validationResult.ShouldHaveValidationErrorFor(q => q.Ids); - validationResult.Errors.Should().HaveCount(1); - validationResult.Errors.First().ErrorCode.Should().Be("error.platform.validation.invalidPropertyValue"); - validationResult.Errors.First().ErrorMessage.Should().Be("'Ids' must not be empty."); + // Assert + validationResult.ShouldHaveValidationErrorForItem( + propertyName: nameof(ListRelationshipTemplatesQuery.Ids), + expectedErrorCode: "error.platform.validation.invalidPropertyValue", + expectedErrorMessage: "'Ids' must not be empty."); } [Fact] public void Fails_when_Ids_is_empty() { - var validator = new ListRelationshipTemplatesValidator(); + // Arrange + var validator = new Validator(); - var validationResult = validator.TestValidate(new ListRelationshipTemplatesQuery(new PaginationFilter(), Array.Empty())); + // Act + var validationResult = validator.TestValidate(new ListRelationshipTemplatesQuery(new PaginationFilter(), [])); - validationResult.ShouldHaveValidationErrorFor(q => q.Ids); - validationResult.Errors.Should().HaveCount(1); - validationResult.Errors.First().ErrorCode.Should().Be("error.platform.validation.invalidPropertyValue"); - validationResult.Errors.First().ErrorMessage.Should().Be("'Ids' must not be empty."); + // Assert + validationResult.ShouldHaveValidationErrorForItem( + propertyName: nameof(ListRelationshipTemplatesQuery.Ids), + expectedErrorCode: "error.platform.validation.invalidPropertyValue", + expectedErrorMessage: "'Ids' must not be empty."); } } diff --git a/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Queries/ListRelationshipTemplates/ListRelationshipTemplatesValidator.cs b/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Queries/ListRelationshipTemplates/Validator.cs similarity index 63% rename from Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Queries/ListRelationshipTemplates/ListRelationshipTemplatesValidator.cs rename to Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Queries/ListRelationshipTemplates/Validator.cs index 6f659668ad..ab13585141 100644 --- a/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Queries/ListRelationshipTemplates/ListRelationshipTemplatesValidator.cs +++ b/Modules/Relationships/src/Relationships.Application/RelationshipTemplates/Queries/ListRelationshipTemplates/Validator.cs @@ -1,17 +1,21 @@ using Backbone.BuildingBlocks.Application.Abstractions.Exceptions; +using Backbone.BuildingBlocks.Application.Extensions; using Backbone.BuildingBlocks.Application.FluentValidation; +using Backbone.Modules.Relationships.Domain.Aggregates.RelationshipTemplates; using FluentValidation; namespace Backbone.Modules.Relationships.Application.RelationshipTemplates.Queries.ListRelationshipTemplates; // ReSharper disable once UnusedMember.Global -public class ListRelationshipTemplatesValidator : AbstractValidator +public class Validator : AbstractValidator { - public ListRelationshipTemplatesValidator() + public Validator() { RuleFor(q => q.Ids) .Cascade(CascadeMode.Stop) .DetailedNotNull() .Must(ids => ids.Count > 0).WithErrorCode(GenericApplicationErrors.Validation.InvalidPropertyValue().Code).WithMessage("'Ids' must not be empty."); + + RuleForEach(x => x.Ids).ValidId(); } } diff --git a/Modules/Relationships/src/Relationships.Application/Relationships/Commands/AcceptRelationship/Validator.cs b/Modules/Relationships/src/Relationships.Application/Relationships/Commands/AcceptRelationship/Validator.cs new file mode 100644 index 0000000000..542c249fe6 --- /dev/null +++ b/Modules/Relationships/src/Relationships.Application/Relationships/Commands/AcceptRelationship/Validator.cs @@ -0,0 +1,13 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.Modules.Relationships.Domain.Aggregates.Relationships; +using FluentValidation; + +namespace Backbone.Modules.Relationships.Application.Relationships.Commands.AcceptRelationship; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleFor(x => x.RelationshipId).ValidId(); + } +} diff --git a/Modules/Relationships/src/Relationships.Application/Relationships/Commands/AcceptRelationshipReactivation/AcceptRelationshipReactivationResponse.cs b/Modules/Relationships/src/Relationships.Application/Relationships/Commands/AcceptRelationshipReactivation/AcceptRelationshipReactivationResponse.cs index ef9f2e7b89..edb292d7ba 100644 --- a/Modules/Relationships/src/Relationships.Application/Relationships/Commands/AcceptRelationshipReactivation/AcceptRelationshipReactivationResponse.cs +++ b/Modules/Relationships/src/Relationships.Application/Relationships/Commands/AcceptRelationshipReactivation/AcceptRelationshipReactivationResponse.cs @@ -2,6 +2,7 @@ using Backbone.Modules.Relationships.Domain.Aggregates.Relationships; namespace Backbone.Modules.Relationships.Application.Relationships.Commands.AcceptRelationshipReactivation; + public class AcceptRelationshipReactivationResponse : RelationshipMetadataDTO { public AcceptRelationshipReactivationResponse(Relationship relationship) : base(relationship) diff --git a/Modules/Relationships/src/Relationships.Application/Relationships/Commands/AcceptRelationshipReactivation/Validator.cs b/Modules/Relationships/src/Relationships.Application/Relationships/Commands/AcceptRelationshipReactivation/Validator.cs new file mode 100644 index 0000000000..05ff9096a0 --- /dev/null +++ b/Modules/Relationships/src/Relationships.Application/Relationships/Commands/AcceptRelationshipReactivation/Validator.cs @@ -0,0 +1,13 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.Modules.Relationships.Domain.Aggregates.Relationships; +using FluentValidation; + +namespace Backbone.Modules.Relationships.Application.Relationships.Commands.AcceptRelationshipReactivation; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleFor(x => x.RelationshipId).ValidId(); + } +} diff --git a/Modules/Relationships/src/Relationships.Application/Relationships/Commands/CreateRelationship/CreateRelationshipRequestValidator.cs b/Modules/Relationships/src/Relationships.Application/Relationships/Commands/CreateRelationship/Validator.cs similarity index 51% rename from Modules/Relationships/src/Relationships.Application/Relationships/Commands/CreateRelationship/CreateRelationshipRequestValidator.cs rename to Modules/Relationships/src/Relationships.Application/Relationships/Commands/CreateRelationship/Validator.cs index d75b9eeed2..2f49bec75c 100644 --- a/Modules/Relationships/src/Relationships.Application/Relationships/Commands/CreateRelationship/CreateRelationshipRequestValidator.cs +++ b/Modules/Relationships/src/Relationships.Application/Relationships/Commands/CreateRelationship/Validator.cs @@ -1,15 +1,17 @@ +using Backbone.BuildingBlocks.Application.Extensions; using Backbone.BuildingBlocks.Application.FluentValidation; +using Backbone.Modules.Relationships.Domain.Aggregates.RelationshipTemplates; using Backbone.Tooling.Extensions; using FluentValidation; namespace Backbone.Modules.Relationships.Application.Relationships.Commands.CreateRelationship; // ReSharper disable once UnusedMember.Global -public class CreateRelationshipCommandValidator : AbstractValidator +public class Validator : AbstractValidator { - public CreateRelationshipCommandValidator() + public Validator() { - RuleFor(c => c.RelationshipTemplateId).DetailedNotEmpty(); + RuleFor(c => c.RelationshipTemplateId).ValidId(); RuleFor(c => c.CreationContent).NumberOfBytes(0, 10.Mebibytes()); } } diff --git a/Modules/Relationships/src/Relationships.Application/Relationships/Commands/DecomposeRelationship/Validator.cs b/Modules/Relationships/src/Relationships.Application/Relationships/Commands/DecomposeRelationship/Validator.cs new file mode 100644 index 0000000000..c5dc103636 --- /dev/null +++ b/Modules/Relationships/src/Relationships.Application/Relationships/Commands/DecomposeRelationship/Validator.cs @@ -0,0 +1,14 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.Modules.Relationships.Domain.Aggregates.Relationships; +using FluentValidation; + +namespace Backbone.Modules.Relationships.Application.Relationships.Commands.DecomposeRelationship; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleFor(x => x.RelationshipId).ValidId(); + } +} + diff --git a/Modules/Relationships/src/Relationships.Application/Relationships/Commands/DeleteRelationshipsOfIdentity/DeleteRelationshipsOfIdentityCommand.cs b/Modules/Relationships/src/Relationships.Application/Relationships/Commands/DeleteRelationshipsOfIdentity/DeleteRelationshipsOfIdentityCommand.cs index 985832b130..aa0ecb08cb 100644 --- a/Modules/Relationships/src/Relationships.Application/Relationships/Commands/DeleteRelationshipsOfIdentity/DeleteRelationshipsOfIdentityCommand.cs +++ b/Modules/Relationships/src/Relationships.Application/Relationships/Commands/DeleteRelationshipsOfIdentity/DeleteRelationshipsOfIdentityCommand.cs @@ -1,14 +1,13 @@ -using Backbone.DevelopmentKit.Identity.ValueObjects; using MediatR; namespace Backbone.Modules.Relationships.Application.Relationships.Commands.DeleteRelationshipsOfIdentity; public class DeleteRelationshipsOfIdentityCommand : IRequest { - public DeleteRelationshipsOfIdentityCommand(IdentityAddress identityAddress) + public DeleteRelationshipsOfIdentityCommand(string identityAddress) { IdentityAddress = identityAddress; } - public IdentityAddress IdentityAddress { get; set; } + public string IdentityAddress { get; set; } } diff --git a/Modules/Relationships/src/Relationships.Application/Relationships/Commands/DeleteRelationshipsOfIdentity/Validator.cs b/Modules/Relationships/src/Relationships.Application/Relationships/Commands/DeleteRelationshipsOfIdentity/Validator.cs index b94612ecce..be78352873 100644 --- a/Modules/Relationships/src/Relationships.Application/Relationships/Commands/DeleteRelationshipsOfIdentity/Validator.cs +++ b/Modules/Relationships/src/Relationships.Application/Relationships/Commands/DeleteRelationshipsOfIdentity/Validator.cs @@ -1,9 +1,13 @@ -using Backbone.DevelopmentKit.Identity.ValueObjects; +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.DevelopmentKit.Identity.ValueObjects; using FluentValidation; namespace Backbone.Modules.Relationships.Application.Relationships.Commands.DeleteRelationshipsOfIdentity; public class Validator : AbstractValidator { - public Validator() => RuleFor(x => x.IdentityAddress).Must(x => IdentityAddress.IsValid(x)); + public Validator() + { + RuleFor(x => x.IdentityAddress).ValidId(); + } } diff --git a/Modules/Relationships/src/Relationships.Application/Relationships/Commands/RejectRelationship/Validator.cs b/Modules/Relationships/src/Relationships.Application/Relationships/Commands/RejectRelationship/Validator.cs new file mode 100644 index 0000000000..3f6e917965 --- /dev/null +++ b/Modules/Relationships/src/Relationships.Application/Relationships/Commands/RejectRelationship/Validator.cs @@ -0,0 +1,13 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.Modules.Relationships.Domain.Aggregates.Relationships; +using FluentValidation; + +namespace Backbone.Modules.Relationships.Application.Relationships.Commands.RejectRelationship; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleFor(x => x.RelationshipId).ValidId(); + } +} diff --git a/Modules/Relationships/src/Relationships.Application/Relationships/Commands/RejectRelationshipReactivation/RejectRelationshipReactivationResponse.cs b/Modules/Relationships/src/Relationships.Application/Relationships/Commands/RejectRelationshipReactivation/RejectRelationshipReactivationResponse.cs index fd06240bc5..f8be111b8a 100644 --- a/Modules/Relationships/src/Relationships.Application/Relationships/Commands/RejectRelationshipReactivation/RejectRelationshipReactivationResponse.cs +++ b/Modules/Relationships/src/Relationships.Application/Relationships/Commands/RejectRelationshipReactivation/RejectRelationshipReactivationResponse.cs @@ -2,6 +2,7 @@ using Backbone.Modules.Relationships.Domain.Aggregates.Relationships; namespace Backbone.Modules.Relationships.Application.Relationships.Commands.RejectRelationshipReactivation; + public class RejectRelationshipReactivationResponse : RelationshipMetadataDTO { public RejectRelationshipReactivationResponse(Relationship relationship) : base(relationship) diff --git a/Modules/Relationships/src/Relationships.Application/Relationships/Commands/RejectRelationshipReactivation/Validator.cs b/Modules/Relationships/src/Relationships.Application/Relationships/Commands/RejectRelationshipReactivation/Validator.cs new file mode 100644 index 0000000000..3d85bfd0fa --- /dev/null +++ b/Modules/Relationships/src/Relationships.Application/Relationships/Commands/RejectRelationshipReactivation/Validator.cs @@ -0,0 +1,13 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.Modules.Relationships.Domain.Aggregates.Relationships; +using FluentValidation; + +namespace Backbone.Modules.Relationships.Application.Relationships.Commands.RejectRelationshipReactivation; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleFor(x => x.RelationshipId).ValidId(); + } +} diff --git a/Modules/Relationships/src/Relationships.Application/Relationships/Commands/RequestRelationshipReactivation/Validator.cs b/Modules/Relationships/src/Relationships.Application/Relationships/Commands/RequestRelationshipReactivation/Validator.cs new file mode 100644 index 0000000000..e1d4e53523 --- /dev/null +++ b/Modules/Relationships/src/Relationships.Application/Relationships/Commands/RequestRelationshipReactivation/Validator.cs @@ -0,0 +1,13 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.Modules.Relationships.Domain.Aggregates.Relationships; +using FluentValidation; + +namespace Backbone.Modules.Relationships.Application.Relationships.Commands.RequestRelationshipReactivation; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleFor(x => x.RelationshipId).ValidId(); + } +} diff --git a/Modules/Relationships/src/Relationships.Application/Relationships/Commands/RevokeRelationship/Validator.cs b/Modules/Relationships/src/Relationships.Application/Relationships/Commands/RevokeRelationship/Validator.cs new file mode 100644 index 0000000000..25fcb4e3f1 --- /dev/null +++ b/Modules/Relationships/src/Relationships.Application/Relationships/Commands/RevokeRelationship/Validator.cs @@ -0,0 +1,13 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.Modules.Relationships.Domain.Aggregates.Relationships; +using FluentValidation; + +namespace Backbone.Modules.Relationships.Application.Relationships.Commands.RevokeRelationship; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleFor(x => x.RelationshipId).ValidId(); + } +} diff --git a/Modules/Relationships/src/Relationships.Application/Relationships/Commands/RevokeRelationshipReactivation/RevokeRelationshipReactivationResponse.cs b/Modules/Relationships/src/Relationships.Application/Relationships/Commands/RevokeRelationshipReactivation/RevokeRelationshipReactivationResponse.cs index 50cddbf2cc..70f33d3ffa 100644 --- a/Modules/Relationships/src/Relationships.Application/Relationships/Commands/RevokeRelationshipReactivation/RevokeRelationshipReactivationResponse.cs +++ b/Modules/Relationships/src/Relationships.Application/Relationships/Commands/RevokeRelationshipReactivation/RevokeRelationshipReactivationResponse.cs @@ -2,6 +2,7 @@ using Backbone.Modules.Relationships.Domain.Aggregates.Relationships; namespace Backbone.Modules.Relationships.Application.Relationships.Commands.RevokeRelationshipReactivation; + public class RevokeRelationshipReactivationResponse : RelationshipMetadataDTO { public RevokeRelationshipReactivationResponse(Relationship relationship) : base(relationship) { } diff --git a/Modules/Relationships/src/Relationships.Application/Relationships/Commands/RevokeRelationshipReactivation/Validator.cs b/Modules/Relationships/src/Relationships.Application/Relationships/Commands/RevokeRelationshipReactivation/Validator.cs new file mode 100644 index 0000000000..7fe487e393 --- /dev/null +++ b/Modules/Relationships/src/Relationships.Application/Relationships/Commands/RevokeRelationshipReactivation/Validator.cs @@ -0,0 +1,13 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.Modules.Relationships.Domain.Aggregates.Relationships; +using FluentValidation; + +namespace Backbone.Modules.Relationships.Application.Relationships.Commands.RevokeRelationshipReactivation; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleFor(x => x.RelationshipId).ValidId(); + } +} diff --git a/Modules/Relationships/src/Relationships.Application/Relationships/Commands/TerminateRelationship/TerminateRelationshipResponse.cs b/Modules/Relationships/src/Relationships.Application/Relationships/Commands/TerminateRelationship/TerminateRelationshipResponse.cs deleted file mode 100644 index e1392b1ed9..0000000000 --- a/Modules/Relationships/src/Relationships.Application/Relationships/Commands/TerminateRelationship/TerminateRelationshipResponse.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Backbone.Modules.Relationships.Application.Relationships.DTOs; -using Backbone.Modules.Relationships.Domain.Aggregates.Relationships; - -namespace Backbone.Modules.Relationships.Application.Relationships.Commands.TerminateRelationship; - -public class TerminateRelationshipResponse : RelationshipMetadataDTO -{ - public TerminateRelationshipResponse(Relationship relationship) : base(relationship) { } -} diff --git a/Modules/Relationships/src/Relationships.Application/Relationships/Commands/TerminateRelationship/Validator.cs b/Modules/Relationships/src/Relationships.Application/Relationships/Commands/TerminateRelationship/Validator.cs new file mode 100644 index 0000000000..12cf238326 --- /dev/null +++ b/Modules/Relationships/src/Relationships.Application/Relationships/Commands/TerminateRelationship/Validator.cs @@ -0,0 +1,14 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.Modules.Relationships.Domain.Aggregates.Relationships; +using FluentValidation; + +namespace Backbone.Modules.Relationships.Application.Relationships.Commands.TerminateRelationship; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleFor(x => x.RelationshipId).ValidId(); + } +} + diff --git a/Modules/Relationships/src/Relationships.Application/Relationships/DTOs/RelationshipAuditLogEntryDTO.cs b/Modules/Relationships/src/Relationships.Application/Relationships/DTOs/RelationshipAuditLogEntryDTO.cs index 79bbcccdee..4ebf18f063 100644 --- a/Modules/Relationships/src/Relationships.Application/Relationships/DTOs/RelationshipAuditLogEntryDTO.cs +++ b/Modules/Relationships/src/Relationships.Application/Relationships/DTOs/RelationshipAuditLogEntryDTO.cs @@ -1,20 +1,9 @@ -using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.Mapping; -using Backbone.Modules.Relationships.Domain.Aggregates.Relationships; +using Backbone.Modules.Relationships.Domain.Aggregates.Relationships; namespace Backbone.Modules.Relationships.Application.Relationships.DTOs; -public class RelationshipAuditLogEntryDTO : IMapTo +public class RelationshipAuditLogEntryDTO { - // This constructor is only used by AutoMapper. - // ReSharper disable once UnusedMember.Local - private RelationshipAuditLogEntryDTO() - { - CreatedBy = null!; - CreatedByDevice = null!; - Reason = null!; - NewStatus = null!; - } - public RelationshipAuditLogEntryDTO(RelationshipAuditLogEntry entry) { CreatedAt = entry.CreatedAt; diff --git a/Modules/Relationships/src/Relationships.Application/Relationships/DTOs/RelationshipDTO.cs b/Modules/Relationships/src/Relationships.Application/Relationships/DTOs/RelationshipDTO.cs index ef2077f76c..f72c760568 100644 --- a/Modules/Relationships/src/Relationships.Application/Relationships/DTOs/RelationshipDTO.cs +++ b/Modules/Relationships/src/Relationships.Application/Relationships/DTOs/RelationshipDTO.cs @@ -1,6 +1,4 @@ -using Backbone.DevelopmentKit.Identity.ValueObjects; using Backbone.Modules.Relationships.Domain.Aggregates.Relationships; -using Backbone.Modules.Relationships.Domain.Aggregates.RelationshipTemplates; namespace Backbone.Modules.Relationships.Application.Relationships.DTOs; @@ -19,11 +17,11 @@ public RelationshipDTO(Relationship relationship) AuditLog = relationship.AuditLog.Select(a => new RelationshipAuditLogEntryDTO(a)).ToList(); } - public RelationshipId Id { get; set; } - public RelationshipTemplateId RelationshipTemplateId { get; set; } + public string Id { get; set; } + public string RelationshipTemplateId { get; set; } - public IdentityAddress From { get; set; } - public IdentityAddress To { get; set; } + public string From { get; set; } + public string To { get; set; } public byte[]? CreationContent { get; set; } public byte[]? CreationResponseContent { get; set; } diff --git a/Modules/Relationships/src/Relationships.Application/Relationships/DTOs/RelationshipMetadataDTO.cs b/Modules/Relationships/src/Relationships.Application/Relationships/DTOs/RelationshipMetadataDTO.cs index ffc1cf9acd..cdeb41ef40 100644 --- a/Modules/Relationships/src/Relationships.Application/Relationships/DTOs/RelationshipMetadataDTO.cs +++ b/Modules/Relationships/src/Relationships.Application/Relationships/DTOs/RelationshipMetadataDTO.cs @@ -1,6 +1,4 @@ -using Backbone.DevelopmentKit.Identity.ValueObjects; using Backbone.Modules.Relationships.Domain.Aggregates.Relationships; -using Backbone.Modules.Relationships.Domain.Aggregates.RelationshipTemplates; namespace Backbone.Modules.Relationships.Application.Relationships.DTOs; @@ -17,11 +15,11 @@ public RelationshipMetadataDTO(Relationship relationship) AuditLog = relationship.AuditLog.Select(a => new RelationshipAuditLogEntryDTO(a)).ToList(); } - public RelationshipId Id { get; set; } - public RelationshipTemplateId RelationshipTemplateId { get; set; } + public string Id { get; set; } + public string RelationshipTemplateId { get; set; } - public IdentityAddress From { get; set; } - public IdentityAddress To { get; set; } + public string From { get; set; } + public string To { get; set; } public DateTime CreatedAt { get; set; } diff --git a/Modules/Relationships/src/Relationships.Application/Relationships/DTOs/RelationshipTemplateDTO.cs b/Modules/Relationships/src/Relationships.Application/Relationships/DTOs/RelationshipTemplateDTO.cs index e15dee4089..6f8647a8e3 100644 --- a/Modules/Relationships/src/Relationships.Application/Relationships/DTOs/RelationshipTemplateDTO.cs +++ b/Modules/Relationships/src/Relationships.Application/Relationships/DTOs/RelationshipTemplateDTO.cs @@ -1,19 +1,27 @@ -using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.Mapping; -using Backbone.DevelopmentKit.Identity.ValueObjects; using Backbone.Modules.Relationships.Domain.Aggregates.RelationshipTemplates; namespace Backbone.Modules.Relationships.Application.Relationships.DTOs; -public class RelationshipTemplateDTO : IMapTo +public class RelationshipTemplateDTO { - public required RelationshipTemplateId Id { get; set; } + public RelationshipTemplateDTO(RelationshipTemplate relationshipTemplate) + { + Id = relationshipTemplate.Id; + CreatedBy = relationshipTemplate.CreatedBy; + CreatedByDevice = relationshipTemplate.CreatedByDevice; + MaxNumberOfAllocations = relationshipTemplate.MaxNumberOfAllocations; + ExpiresAt = relationshipTemplate.ExpiresAt; + Content = relationshipTemplate.Content; + CreatedAt = relationshipTemplate.CreatedAt; + DeletedAt = relationshipTemplate.DeletedAt; + } - public required IdentityAddress CreatedBy { get; set; } - public required DeviceId CreatedByDevice { get; set; } + public string Id { get; set; } + public string CreatedBy { get; set; } + public string CreatedByDevice { get; set; } public int? MaxNumberOfAllocations { get; set; } public DateTime? ExpiresAt { get; set; } public byte[]? Content { get; set; } - - public required DateTime CreatedAt { get; set; } + public DateTime CreatedAt { get; set; } public DateTime? DeletedAt { get; set; } } diff --git a/Modules/Relationships/src/Relationships.Application/Relationships/Queries/FindRelationshipsOfIdentity/FindRelationshipsOfIdentityQuery.cs b/Modules/Relationships/src/Relationships.Application/Relationships/Queries/FindRelationshipsOfIdentity/FindRelationshipsOfIdentityQuery.cs index 85e1a96a67..07f29ddbd7 100644 --- a/Modules/Relationships/src/Relationships.Application/Relationships/Queries/FindRelationshipsOfIdentity/FindRelationshipsOfIdentityQuery.cs +++ b/Modules/Relationships/src/Relationships.Application/Relationships/Queries/FindRelationshipsOfIdentity/FindRelationshipsOfIdentityQuery.cs @@ -1,14 +1,13 @@ -using Backbone.DevelopmentKit.Identity.ValueObjects; using MediatR; namespace Backbone.Modules.Relationships.Application.Relationships.Queries.FindRelationshipsOfIdentity; public class FindRelationshipsOfIdentityQuery : IRequest { - public FindRelationshipsOfIdentityQuery(IdentityAddress identityAddress) + public FindRelationshipsOfIdentityQuery(string identityAddress) { IdentityAddress = identityAddress; } - public IdentityAddress IdentityAddress { get; set; } + public string IdentityAddress { get; set; } } diff --git a/Modules/Relationships/src/Relationships.Application/Relationships/Queries/FindRelationshipsOfIdentity/Validator.cs b/Modules/Relationships/src/Relationships.Application/Relationships/Queries/FindRelationshipsOfIdentity/Validator.cs index 327ba1c54e..09121ff7d9 100644 --- a/Modules/Relationships/src/Relationships.Application/Relationships/Queries/FindRelationshipsOfIdentity/Validator.cs +++ b/Modules/Relationships/src/Relationships.Application/Relationships/Queries/FindRelationshipsOfIdentity/Validator.cs @@ -1,9 +1,13 @@ -using Backbone.DevelopmentKit.Identity.ValueObjects; +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.DevelopmentKit.Identity.ValueObjects; using FluentValidation; namespace Backbone.Modules.Relationships.Application.Relationships.Queries.FindRelationshipsOfIdentity; public class Validator : AbstractValidator { - public Validator() => RuleFor(x => x.IdentityAddress).Must(x => IdentityAddress.IsValid(x)); + public Validator() + { + RuleFor(x => x.IdentityAddress).ValidId(); + } } diff --git a/Modules/Relationships/src/Relationships.Application/Relationships/Queries/GetPeerOfActiveIdentityInRelationship/Validator.cs b/Modules/Relationships/src/Relationships.Application/Relationships/Queries/GetPeerOfActiveIdentityInRelationship/Validator.cs new file mode 100644 index 0000000000..2177f0c2ed --- /dev/null +++ b/Modules/Relationships/src/Relationships.Application/Relationships/Queries/GetPeerOfActiveIdentityInRelationship/Validator.cs @@ -0,0 +1,13 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.Modules.Relationships.Domain.Aggregates.Relationships; +using FluentValidation; + +namespace Backbone.Modules.Relationships.Application.Relationships.Queries.GetPeerOfActiveIdentityInRelationship; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleFor(x => x.Id).ValidId(); + } +} diff --git a/Modules/Relationships/src/Relationships.Application/Relationships/Queries/GetRelationship/GetRelationshipQuery.cs b/Modules/Relationships/src/Relationships.Application/Relationships/Queries/GetRelationship/GetRelationshipQuery.cs index bfa2043b59..8224fe9c01 100644 --- a/Modules/Relationships/src/Relationships.Application/Relationships/Queries/GetRelationship/GetRelationshipQuery.cs +++ b/Modules/Relationships/src/Relationships.Application/Relationships/Queries/GetRelationship/GetRelationshipQuery.cs @@ -1,10 +1,9 @@ using Backbone.Modules.Relationships.Application.Relationships.DTOs; -using Backbone.Modules.Relationships.Domain.Aggregates.Relationships; using MediatR; namespace Backbone.Modules.Relationships.Application.Relationships.Queries.GetRelationship; public class GetRelationshipQuery : IRequest { - public required RelationshipId Id { get; set; } + public required string Id { get; set; } } diff --git a/Modules/Relationships/src/Relationships.Application/Relationships/Queries/GetRelationship/Handler.cs b/Modules/Relationships/src/Relationships.Application/Relationships/Queries/GetRelationship/Handler.cs index 1883180c4f..87a5d944f3 100644 --- a/Modules/Relationships/src/Relationships.Application/Relationships/Queries/GetRelationship/Handler.cs +++ b/Modules/Relationships/src/Relationships.Application/Relationships/Queries/GetRelationship/Handler.cs @@ -1,27 +1,25 @@ -using AutoMapper; using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.UserContext; using Backbone.Modules.Relationships.Application.Infrastructure.Persistence.Repository; using Backbone.Modules.Relationships.Application.Relationships.DTOs; +using Backbone.Modules.Relationships.Domain.Aggregates.Relationships; using MediatR; namespace Backbone.Modules.Relationships.Application.Relationships.Queries.GetRelationship; public class Handler : IRequestHandler { - private readonly IMapper _mapper; private readonly IRelationshipsRepository _relationshipsRepository; private readonly IUserContext _userContext; - public Handler(IUserContext userContext, IMapper mapper, IRelationshipsRepository relationshipsRepository) + public Handler(IUserContext userContext, IRelationshipsRepository relationshipsRepository) { - _mapper = mapper; _relationshipsRepository = relationshipsRepository; _userContext = userContext; } public async Task Handle(GetRelationshipQuery request, CancellationToken cancellationToken) { - var relationship = await _relationshipsRepository.FindRelationship(request.Id, _userContext.GetAddress(), cancellationToken, track: false); + var relationship = await _relationshipsRepository.FindRelationship(RelationshipId.Parse(request.Id), _userContext.GetAddress(), cancellationToken, track: false); return new RelationshipDTO(relationship); } diff --git a/Modules/Relationships/src/Relationships.Application/Relationships/Queries/GetRelationship/Validator.cs b/Modules/Relationships/src/Relationships.Application/Relationships/Queries/GetRelationship/Validator.cs new file mode 100644 index 0000000000..509791937c --- /dev/null +++ b/Modules/Relationships/src/Relationships.Application/Relationships/Queries/GetRelationship/Validator.cs @@ -0,0 +1,13 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.Modules.Relationships.Domain.Aggregates.Relationships; +using FluentValidation; + +namespace Backbone.Modules.Relationships.Application.Relationships.Queries.GetRelationship; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleFor(x => x.Id).ValidId(); + } +} diff --git a/Modules/Relationships/src/Relationships.Application/Relationships/Queries/ListRelationships/Handler.cs b/Modules/Relationships/src/Relationships.Application/Relationships/Queries/ListRelationships/Handler.cs index a43b4251e4..980a39f4f4 100644 --- a/Modules/Relationships/src/Relationships.Application/Relationships/Queries/ListRelationships/Handler.cs +++ b/Modules/Relationships/src/Relationships.Application/Relationships/Queries/ListRelationships/Handler.cs @@ -1,6 +1,6 @@ using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.UserContext; using Backbone.Modules.Relationships.Application.Infrastructure.Persistence.Repository; -using Backbone.Modules.Relationships.Application.Relationships.DTOs; +using Backbone.Modules.Relationships.Domain.Aggregates.Relationships; using MediatR; namespace Backbone.Modules.Relationships.Application.Relationships.Queries.ListRelationships; @@ -18,8 +18,9 @@ public Handler(IUserContext userContext, IRelationshipsRepository relationshipsR public async Task Handle(ListRelationshipsQuery request, CancellationToken cancellationToken) { - var dbPaginationResult = await _relationshipsRepository.FindRelationshipsWithIds(request.Ids, _userContext.GetAddress(), request.PaginationFilter, cancellationToken, track: false); + var dbPaginationResult = + await _relationshipsRepository.FindRelationshipsWithIds(request.Ids.Select(RelationshipId.Parse), _userContext.GetAddress(), request.PaginationFilter, cancellationToken, track: false); - return new ListRelationshipsResponse(dbPaginationResult.ItemsOnPage.Select(r => new RelationshipDTO(r)), request.PaginationFilter, dbPaginationResult.TotalNumberOfItems); + return new ListRelationshipsResponse(dbPaginationResult, request.PaginationFilter); } } diff --git a/Modules/Relationships/src/Relationships.Application/Relationships/Queries/ListRelationships/ListRelationshipsQuery.cs b/Modules/Relationships/src/Relationships.Application/Relationships/Queries/ListRelationships/ListRelationshipsQuery.cs index 30153b363a..dc9d0c3ab4 100644 --- a/Modules/Relationships/src/Relationships.Application/Relationships/Queries/ListRelationships/ListRelationshipsQuery.cs +++ b/Modules/Relationships/src/Relationships.Application/Relationships/Queries/ListRelationships/ListRelationshipsQuery.cs @@ -1,17 +1,16 @@ using Backbone.BuildingBlocks.Application.Pagination; -using Backbone.Modules.Relationships.Domain.Aggregates.Relationships; using MediatR; namespace Backbone.Modules.Relationships.Application.Relationships.Queries.ListRelationships; public class ListRelationshipsQuery : IRequest { - public ListRelationshipsQuery(PaginationFilter paginationFilter, IEnumerable? ids) + public ListRelationshipsQuery(PaginationFilter paginationFilter, IEnumerable? ids) { PaginationFilter = paginationFilter; Ids = ids == null ? [] : ids.ToList(); } public PaginationFilter PaginationFilter { get; set; } - public List Ids { get; set; } + public List Ids { get; set; } } diff --git a/Modules/Relationships/src/Relationships.Application/Relationships/Queries/ListRelationships/ListRelationshipsResponse.cs b/Modules/Relationships/src/Relationships.Application/Relationships/Queries/ListRelationships/ListRelationshipsResponse.cs index 2fcd3fb937..0364f6b7e5 100644 --- a/Modules/Relationships/src/Relationships.Application/Relationships/Queries/ListRelationships/ListRelationshipsResponse.cs +++ b/Modules/Relationships/src/Relationships.Application/Relationships/Queries/ListRelationships/ListRelationshipsResponse.cs @@ -1,9 +1,14 @@ +using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.Persistence.Database; using Backbone.BuildingBlocks.Application.Pagination; using Backbone.Modules.Relationships.Application.Relationships.DTOs; +using Backbone.Modules.Relationships.Domain.Aggregates.Relationships; namespace Backbone.Modules.Relationships.Application.Relationships.Queries.ListRelationships; public class ListRelationshipsResponse : PagedResponse { - public ListRelationshipsResponse(IEnumerable items, PaginationFilter previousPaginationFilter, int totalRecords) : base(items, previousPaginationFilter, totalRecords) { } + public ListRelationshipsResponse(DbPaginationResult dbPaginationResult, PaginationFilter previousPaginationFilter) : base( + dbPaginationResult.ItemsOnPage.Select(r => new RelationshipDTO(r)), previousPaginationFilter, dbPaginationResult.TotalNumberOfItems) + { + } } diff --git a/Modules/Relationships/src/Relationships.Application/Relationships/Queries/ListRelationships/ListRelationshipsValidator.Tests.cs b/Modules/Relationships/src/Relationships.Application/Relationships/Queries/ListRelationships/ListRelationshipsValidator.Tests.cs index 526395f00a..ace742b4ef 100644 --- a/Modules/Relationships/src/Relationships.Application/Relationships/Queries/ListRelationships/ListRelationshipsValidator.Tests.cs +++ b/Modules/Relationships/src/Relationships.Application/Relationships/Queries/ListRelationships/ListRelationshipsValidator.Tests.cs @@ -1,7 +1,7 @@ using Backbone.BuildingBlocks.Application.Pagination; using Backbone.Modules.Relationships.Domain.Aggregates.Relationships; using Backbone.UnitTestTools.BaseClasses; -using FluentAssertions; +using Backbone.UnitTestTools.FluentValidation; using FluentValidation.TestHelper; using Xunit; @@ -12,36 +12,45 @@ public class ListRelationshipsValidatorTests : AbstractTestsBase [Fact] public void Happy_path() { - var validator = new ListRelationshipsValidator(); + // Arrange + var validator = new Validator(); - var validationResult = validator.TestValidate(new ListRelationshipsQuery(new PaginationFilter(), new[] { RelationshipId.New() })); + // Act + var validationResult = validator.TestValidate(new ListRelationshipsQuery(new PaginationFilter(), [RelationshipId.New().Value])); + // Assert validationResult.ShouldNotHaveAnyValidationErrors(); } [Fact] public void Fails_when_Ids_is_null() { - var validator = new ListRelationshipsValidator(); + // Arrange + var validator = new Validator(); + // Act var validationResult = validator.TestValidate(new ListRelationshipsQuery(new PaginationFilter(), null)); - validationResult.ShouldHaveValidationErrorFor(q => q.Ids); - validationResult.Errors.Should().HaveCount(1); - validationResult.Errors.First().ErrorCode.Should().Be("error.platform.validation.invalidPropertyValue"); - validationResult.Errors.First().ErrorMessage.Should().Be("'Ids' must not be empty."); + // Assert + validationResult.ShouldHaveValidationErrorForItem( + propertyName: nameof(ListRelationshipsQuery.Ids), + expectedErrorCode: "error.platform.validation.invalidPropertyValue", + expectedErrorMessage: "'Ids' must not be empty."); } [Fact] public void Fails_when_Ids_is_empty() { - var validator = new ListRelationshipsValidator(); + // Arrange + var validator = new Validator(); - var validationResult = validator.TestValidate(new ListRelationshipsQuery(new PaginationFilter(), Array.Empty())); + // Act + var validationResult = validator.TestValidate(new ListRelationshipsQuery(new PaginationFilter(), [])); - validationResult.ShouldHaveValidationErrorFor(q => q.Ids); - validationResult.Errors.Should().HaveCount(1); - validationResult.Errors.First().ErrorCode.Should().Be("error.platform.validation.invalidPropertyValue"); - validationResult.Errors.First().ErrorMessage.Should().Be("'Ids' must not be empty."); + // Assert + validationResult.ShouldHaveValidationErrorForItem( + propertyName: nameof(ListRelationshipsQuery.Ids), + expectedErrorCode: "error.platform.validation.invalidPropertyValue", + expectedErrorMessage: "'Ids' must not be empty."); } } diff --git a/Modules/Relationships/src/Relationships.Application/Relationships/Queries/ListRelationships/ListRelationshipsValidator.cs b/Modules/Relationships/src/Relationships.Application/Relationships/Queries/ListRelationships/Validator.cs similarity index 65% rename from Modules/Relationships/src/Relationships.Application/Relationships/Queries/ListRelationships/ListRelationshipsValidator.cs rename to Modules/Relationships/src/Relationships.Application/Relationships/Queries/ListRelationships/Validator.cs index b7097d39af..b331294c83 100644 --- a/Modules/Relationships/src/Relationships.Application/Relationships/Queries/ListRelationships/ListRelationshipsValidator.cs +++ b/Modules/Relationships/src/Relationships.Application/Relationships/Queries/ListRelationships/Validator.cs @@ -1,17 +1,21 @@ using Backbone.BuildingBlocks.Application.Abstractions.Exceptions; +using Backbone.BuildingBlocks.Application.Extensions; using Backbone.BuildingBlocks.Application.FluentValidation; +using Backbone.Modules.Relationships.Domain.Aggregates.Relationships; using FluentValidation; namespace Backbone.Modules.Relationships.Application.Relationships.Queries.ListRelationships; // ReSharper disable once UnusedMember.Global -public class ListRelationshipsValidator : AbstractValidator +public class Validator : AbstractValidator { - public ListRelationshipsValidator() + public Validator() { RuleFor(q => q.Ids) .Cascade(CascadeMode.Stop) .DetailedNotNull() .Must(ids => ids.Count > 0).WithErrorCode(GenericApplicationErrors.Validation.InvalidPropertyValue().Code).WithMessage("'Ids' must not be empty."); + + RuleForEach(x => x.Ids).ValidId(); } } diff --git a/Modules/Relationships/src/Relationships.ConsumerApi/Controllers/RelationshipTemplatesController.cs b/Modules/Relationships/src/Relationships.ConsumerApi/Controllers/RelationshipTemplatesController.cs index ff3aec6385..590713fc49 100644 --- a/Modules/Relationships/src/Relationships.ConsumerApi/Controllers/RelationshipTemplatesController.cs +++ b/Modules/Relationships/src/Relationships.ConsumerApi/Controllers/RelationshipTemplatesController.cs @@ -8,7 +8,6 @@ using Backbone.Modules.Relationships.Application.RelationshipTemplates.Commands.CreateRelationshipTemplate; using Backbone.Modules.Relationships.Application.RelationshipTemplates.Queries.GetRelationshipTemplate; using Backbone.Modules.Relationships.Application.RelationshipTemplates.Queries.ListRelationshipTemplates; -using Backbone.Modules.Relationships.Domain.Aggregates.RelationshipTemplates; using MediatR; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; @@ -32,7 +31,7 @@ public RelationshipTemplatesController(IMediator mediator, IOptions), StatusCodes.Status200OK)] [ProducesError(StatusCodes.Status404NotFound)] - public async Task GetById(RelationshipTemplateId id, CancellationToken cancellationToken) + public async Task GetById(string id, CancellationToken cancellationToken) { var template = await _mediator.Send(new GetRelationshipTemplateQuery { Id = id }, cancellationToken); return Ok(template); @@ -42,7 +41,7 @@ public async Task GetById(RelationshipTemplateId id, Cancellation [ProducesResponseType(typeof(PagedHttpResponseEnvelope), StatusCodes.Status200OK)] public async Task GetAll([FromQuery] PaginationFilter paginationFilter, - [FromQuery] IEnumerable ids, CancellationToken cancellationToken) + [FromQuery] IEnumerable ids, CancellationToken cancellationToken) { var request = new ListRelationshipTemplatesQuery(paginationFilter, ids); diff --git a/Modules/Relationships/src/Relationships.ConsumerApi/Controllers/RelationshipsController.cs b/Modules/Relationships/src/Relationships.ConsumerApi/Controllers/RelationshipsController.cs index 15fa4a31c8..e41f8d5a5b 100644 --- a/Modules/Relationships/src/Relationships.ConsumerApi/Controllers/RelationshipsController.cs +++ b/Modules/Relationships/src/Relationships.ConsumerApi/Controllers/RelationshipsController.cs @@ -23,7 +23,6 @@ using Backbone.Modules.Relationships.Application.Relationships.Queries.GetRelationship; using Backbone.Modules.Relationships.Application.Relationships.Queries.ListRelationships; using Backbone.Modules.Relationships.Application.RelationshipTemplates.Queries.GetRelationshipTemplate; -using Backbone.Modules.Relationships.Domain.Aggregates.Relationships; using MediatR; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; @@ -47,7 +46,7 @@ public RelationshipsController(IMediator mediator, IOptions [HttpGet("{id}")] [ProducesResponseType(typeof(HttpResponseEnvelopeResult), StatusCodes.Status200OK)] [ProducesError(StatusCodes.Status404NotFound)] - public async Task GetRelationship(RelationshipId id, CancellationToken cancellationToken) + public async Task GetRelationship(string id, CancellationToken cancellationToken) { var relationship = await _mediator.Send(new GetRelationshipQuery { Id = id }, cancellationToken); return Ok(relationship); @@ -56,7 +55,7 @@ public async Task GetRelationship(RelationshipId id, Cancellation [HttpGet] [ProducesResponseType(typeof(PagedHttpResponseEnvelope), StatusCodes.Status200OK)] public async Task ListRelationships([FromQuery] PaginationFilter paginationFilter, - [FromQuery] IEnumerable ids, CancellationToken cancellationToken) + [FromQuery] IEnumerable ids, CancellationToken cancellationToken) { var request = new ListRelationshipsQuery(paginationFilter, ids); diff --git a/Modules/Synchronization/src/Synchronization.Application/AutoMapper/AutoMapperProfile.cs b/Modules/Synchronization/src/Synchronization.Application/AutoMapper/AutoMapperProfile.cs deleted file mode 100644 index c08c556382..0000000000 --- a/Modules/Synchronization/src/Synchronization.Application/AutoMapper/AutoMapperProfile.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Reflection; -using AutoMapper; -using Backbone.BuildingBlocks.Application.AutoMapper; - -namespace Backbone.Modules.Synchronization.Application.AutoMapper; - -public class AutoMapperProfile : AutoMapperProfileBase -{ - public AutoMapperProfile() : base(Assembly.GetExecutingAssembly()) { } - - public static IMapper CreateMapper() - { - var profile = new AutoMapperProfile(); - var config = new MapperConfiguration(cfg => cfg.AddProfile(profile)); - var mapper = config.CreateMapper(); - return mapper; - } -} diff --git a/Modules/Synchronization/src/Synchronization.Application/Datawallets/Commands/DeleteDatawalletsOfIdentity/DeleteDatawalletsOfIdentityCommand.cs b/Modules/Synchronization/src/Synchronization.Application/Datawallets/Commands/DeleteDatawalletsOfIdentity/DeleteDatawalletsOfIdentityCommand.cs index ad5b9777c4..e7cab1b44d 100644 --- a/Modules/Synchronization/src/Synchronization.Application/Datawallets/Commands/DeleteDatawalletsOfIdentity/DeleteDatawalletsOfIdentityCommand.cs +++ b/Modules/Synchronization/src/Synchronization.Application/Datawallets/Commands/DeleteDatawalletsOfIdentity/DeleteDatawalletsOfIdentityCommand.cs @@ -1,13 +1,13 @@ -using Backbone.DevelopmentKit.Identity.ValueObjects; -using MediatR; +using MediatR; namespace Backbone.Modules.Synchronization.Application.Datawallets.Commands.DeleteDatawalletsOfIdentity; + public class DeleteDatawalletsOfIdentityCommand : IRequest { - public DeleteDatawalletsOfIdentityCommand(IdentityAddress identityAddress) + public DeleteDatawalletsOfIdentityCommand(string identityAddress) { IdentityAddress = identityAddress; } - public IdentityAddress IdentityAddress { get; set; } + public string IdentityAddress { get; set; } } diff --git a/Modules/Synchronization/src/Synchronization.Application/Datawallets/Commands/DeleteDatawalletsOfIdentity/Validator.cs b/Modules/Synchronization/src/Synchronization.Application/Datawallets/Commands/DeleteDatawalletsOfIdentity/Validator.cs index fd286f492f..963bd4a803 100644 --- a/Modules/Synchronization/src/Synchronization.Application/Datawallets/Commands/DeleteDatawalletsOfIdentity/Validator.cs +++ b/Modules/Synchronization/src/Synchronization.Application/Datawallets/Commands/DeleteDatawalletsOfIdentity/Validator.cs @@ -1,8 +1,13 @@ -using Backbone.DevelopmentKit.Identity.ValueObjects; +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.DevelopmentKit.Identity.ValueObjects; using FluentValidation; namespace Backbone.Modules.Synchronization.Application.Datawallets.Commands.DeleteDatawalletsOfIdentity; + public class Validator : AbstractValidator { - public Validator() => RuleFor(x => x.IdentityAddress).Must(x => IdentityAddress.IsValid(x)); + public Validator() + { + RuleFor(x => x.IdentityAddress).ValidId(); + } } diff --git a/Modules/Synchronization/src/Synchronization.Application/Datawallets/Commands/PushDatawalletModifications/Handler.cs b/Modules/Synchronization/src/Synchronization.Application/Datawallets/Commands/PushDatawalletModifications/Handler.cs index ff40cfae3c..30789941f0 100644 --- a/Modules/Synchronization/src/Synchronization.Application/Datawallets/Commands/PushDatawalletModifications/Handler.cs +++ b/Modules/Synchronization/src/Synchronization.Application/Datawallets/Commands/PushDatawalletModifications/Handler.cs @@ -1,4 +1,3 @@ -using AutoMapper; using Backbone.BuildingBlocks.Application.Abstractions.Exceptions; using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.UserContext; using Backbone.BuildingBlocks.Application.Extensions; @@ -17,7 +16,6 @@ public class Handler : IRequestHandler(modificationDto.Type), + MapDatawalletModificationType(modificationDto.Type), new DatawalletVersion(modificationDto.DatawalletVersion), modificationDto.Collection, modificationDto.ObjectIdentifier, @@ -105,6 +102,18 @@ private DatawalletModification CreateModification(PushDatawalletModificationItem ); } + private DatawalletModificationType MapDatawalletModificationType(DatawalletModificationDTO.DatawalletModificationType type) + { + return type switch + { + DatawalletModificationDTO.DatawalletModificationType.Create => DatawalletModificationType.Create, + DatawalletModificationDTO.DatawalletModificationType.Update => DatawalletModificationType.Update, + DatawalletModificationDTO.DatawalletModificationType.Delete => DatawalletModificationType.Delete, + DatawalletModificationDTO.DatawalletModificationType.CacheChanged => DatawalletModificationType.CacheChanged, + _ => throw new Exception($"Unsupported Datawallet Modification Type: {type}") + }; + } + private void EnsureDeviceIsUpToDate() { if (_datawallet!.LatestModification != null && _datawallet.LatestModification.Index != _request.LocalIndex) @@ -113,7 +122,7 @@ private void EnsureDeviceIsUpToDate() private void BuildResponse() { - var responseItems = _mapper.Map(_modifications); + var responseItems = _modifications.Select(m => new PushDatawalletModificationsResponseItem(m)); _response = new PushDatawalletModificationsResponse { Modifications = responseItems, NewIndex = responseItems.Max(i => i.Index) }; } diff --git a/Modules/Synchronization/src/Synchronization.Application/Datawallets/Commands/PushDatawalletModifications/PushDatawalletModificationsResponse.cs b/Modules/Synchronization/src/Synchronization.Application/Datawallets/Commands/PushDatawalletModifications/PushDatawalletModificationsResponse.cs index b7e3c03603..701383f5a7 100644 --- a/Modules/Synchronization/src/Synchronization.Application/Datawallets/Commands/PushDatawalletModifications/PushDatawalletModificationsResponse.cs +++ b/Modules/Synchronization/src/Synchronization.Application/Datawallets/Commands/PushDatawalletModifications/PushDatawalletModificationsResponse.cs @@ -1,4 +1,3 @@ -using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.Mapping; using Backbone.Modules.Synchronization.Domain.Entities; namespace Backbone.Modules.Synchronization.Application.Datawallets.Commands.PushDatawalletModifications; @@ -10,9 +9,16 @@ public class PushDatawalletModificationsResponse public required IEnumerable Modifications { get; set; } } -public class PushDatawalletModificationsResponseItem : IMapTo +public class PushDatawalletModificationsResponseItem { - public required DatawalletModificationId Id { get; set; } - public required long Index { get; set; } - public required DateTime CreatedAt { get; set; } + public PushDatawalletModificationsResponseItem(DatawalletModification datawalletModification) + { + Id = datawalletModification.Id; + Index = datawalletModification.Index; + CreatedAt = datawalletModification.CreatedAt; + } + + public string Id { get; set; } + public long Index { get; set; } + public DateTime CreatedAt { get; set; } } diff --git a/Modules/Synchronization/src/Synchronization.Application/Datawallets/Commands/PushDatawalletModifications/PushDatawalletModificationsCommandValidator.cs b/Modules/Synchronization/src/Synchronization.Application/Datawallets/Commands/PushDatawalletModifications/Validator.cs similarity index 81% rename from Modules/Synchronization/src/Synchronization.Application/Datawallets/Commands/PushDatawalletModifications/PushDatawalletModificationsCommandValidator.cs rename to Modules/Synchronization/src/Synchronization.Application/Datawallets/Commands/PushDatawalletModifications/Validator.cs index f05b172115..420242f1d7 100644 --- a/Modules/Synchronization/src/Synchronization.Application/Datawallets/Commands/PushDatawalletModifications/PushDatawalletModificationsCommandValidator.cs +++ b/Modules/Synchronization/src/Synchronization.Application/Datawallets/Commands/PushDatawalletModifications/Validator.cs @@ -6,9 +6,9 @@ namespace Backbone.Modules.Synchronization.Application.Datawallets.Commands.PushDatawalletModifications; // ReSharper disable once UnusedMember.Global -public class PushDatawalletModificationsCommandValidator : AbstractValidator +public class Validator : AbstractValidator { - public PushDatawalletModificationsCommandValidator() + public Validator() { RuleFor(r => r.Modifications).DetailedNotEmpty(); RuleForEach(r => r.Modifications).SetValidator(new PushDatawalletModificationItemValidator()); diff --git a/Modules/Synchronization/src/Synchronization.Application/Datawallets/DTOs/CreatedDatawalletModificationDTO.cs b/Modules/Synchronization/src/Synchronization.Application/Datawallets/DTOs/CreatedDatawalletModificationDTO.cs index d1bc0ef241..f0139e65f2 100644 --- a/Modules/Synchronization/src/Synchronization.Application/Datawallets/DTOs/CreatedDatawalletModificationDTO.cs +++ b/Modules/Synchronization/src/Synchronization.Application/Datawallets/DTOs/CreatedDatawalletModificationDTO.cs @@ -1,18 +1,17 @@ -using AutoMapper; -using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.Mapping; using Backbone.Modules.Synchronization.Domain.Entities; namespace Backbone.Modules.Synchronization.Application.Datawallets.DTOs; -public class CreatedDatawalletModificationDTO : IHaveCustomMapping +public class CreatedDatawalletModificationDTO { - public required string Id { get; set; } - public required long Index { get; set; } - public required DateTime CreatedAt { get; set; } - - public void CreateMappings(Profile configuration) + public CreatedDatawalletModificationDTO(DatawalletModification datawalletModification) { - configuration.CreateMap() - .ForMember(dto => dto.Id, expression => expression.MapFrom(d => d.Id.Value)); + Id = datawalletModification.Id; + Index = datawalletModification.Index; + CreatedAt = datawalletModification.CreatedAt; } + + public string Id { get; set; } + public long Index { get; set; } + public DateTime CreatedAt { get; set; } } diff --git a/Modules/Synchronization/src/Synchronization.Application/Datawallets/DTOs/DatawalletDTO.cs b/Modules/Synchronization/src/Synchronization.Application/Datawallets/DTOs/DatawalletDTO.cs index 04e8bcba10..9a4d4517f4 100644 --- a/Modules/Synchronization/src/Synchronization.Application/Datawallets/DTOs/DatawalletDTO.cs +++ b/Modules/Synchronization/src/Synchronization.Application/Datawallets/DTOs/DatawalletDTO.cs @@ -1,16 +1,13 @@ -using AutoMapper; -using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.Mapping; using Backbone.Modules.Synchronization.Domain.Entities; namespace Backbone.Modules.Synchronization.Application.Datawallets.DTOs; -public class DatawalletDTO : IHaveCustomMapping +public class DatawalletDTO { - public ushort Version { get; set; } - - public void CreateMappings(Profile configuration) + public DatawalletDTO(Datawallet datawallet) { - configuration.CreateMap() - .ForMember(dto => dto.Version, expression => expression.MapFrom(m => m.Version.Value)); + Version = datawallet.Version; } + + public ushort Version { get; set; } } diff --git a/Modules/Synchronization/src/Synchronization.Application/Datawallets/DTOs/DatawalletModificationDTO.cs b/Modules/Synchronization/src/Synchronization.Application/Datawallets/DTOs/DatawalletModificationDTO.cs index aca1cd0852..ceb80c05e1 100644 --- a/Modules/Synchronization/src/Synchronization.Application/Datawallets/DTOs/DatawalletModificationDTO.cs +++ b/Modules/Synchronization/src/Synchronization.Application/Datawallets/DTOs/DatawalletModificationDTO.cs @@ -1,12 +1,8 @@ -using AutoMapper; -using AutoMapper.Extensions.EnumMapping; -using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.Mapping; -using Backbone.DevelopmentKit.Identity.ValueObjects; using Backbone.Modules.Synchronization.Domain.Entities; namespace Backbone.Modules.Synchronization.Application.Datawallets.DTOs; -public class DatawalletModificationDTO : IHaveCustomMapping +public class DatawalletModificationDTO { public enum DatawalletModificationType { @@ -16,29 +12,40 @@ public enum DatawalletModificationType CacheChanged } - public required DatawalletModificationId Id { get; set; } - public required ushort DatawalletVersion { get; set; } - public required long Index { get; set; } - public required string ObjectIdentifier { get; set; } + public DatawalletModificationDTO(DatawalletModification datawalletModification) + { + Id = datawalletModification.Id; + DatawalletVersion = datawalletModification.DatawalletVersion; + Index = datawalletModification.Index; + ObjectIdentifier = datawalletModification.ObjectIdentifier; + PayloadCategory = datawalletModification.PayloadCategory; + CreatedAt = datawalletModification.CreatedAt; + CreatedByDevice = datawalletModification.CreatedByDevice; + Collection = datawalletModification.Collection; + Type = MapDatawalletModificationType(datawalletModification.Type); + EncryptedPayload = datawalletModification.EncryptedPayload; + } + + public string Id { get; set; } + public ushort DatawalletVersion { get; set; } + public long Index { get; set; } + public string ObjectIdentifier { get; set; } public string? PayloadCategory { get; set; } - public required DateTime CreatedAt { get; set; } - public required DeviceId CreatedByDevice { get; set; } - public required string Collection { get; set; } - public required string Type { get; set; } + public DateTime CreatedAt { get; set; } + public string CreatedByDevice { get; set; } + public string Collection { get; set; } + public DatawalletModificationType Type { get; set; } public byte[]? EncryptedPayload { get; set; } - - public void CreateMappings(Profile configuration) + private DatawalletModificationType MapDatawalletModificationType(Domain.Entities.DatawalletModificationType type) { - configuration.CreateMap(); - - configuration.CreateMap().ConvertUsing(version => version.Value); - - configuration.CreateMap().ConvertUsingEnumMapping( - config => config - .MapValue(Domain.Entities.DatawalletModificationType.CacheChanged, DatawalletModificationType.CacheChanged) - .MapValue(Domain.Entities.DatawalletModificationType.Create, DatawalletModificationType.Create) - .MapValue(Domain.Entities.DatawalletModificationType.Delete, DatawalletModificationType.Delete) - .MapValue(Domain.Entities.DatawalletModificationType.Update, DatawalletModificationType.Update)); + return type switch + { + Domain.Entities.DatawalletModificationType.Create => DatawalletModificationType.Create, + Domain.Entities.DatawalletModificationType.Update => DatawalletModificationType.Update, + Domain.Entities.DatawalletModificationType.Delete => DatawalletModificationType.Delete, + Domain.Entities.DatawalletModificationType.CacheChanged => DatawalletModificationType.CacheChanged, + _ => throw new Exception($"Unsupported Datawallet Modification Type: {type}") + }; } } diff --git a/Modules/Synchronization/src/Synchronization.Application/Datawallets/Queries/GetDatawallet/Handler.cs b/Modules/Synchronization/src/Synchronization.Application/Datawallets/Queries/GetDatawallet/Handler.cs index 64e93b014a..6422d39a1a 100644 --- a/Modules/Synchronization/src/Synchronization.Application/Datawallets/Queries/GetDatawallet/Handler.cs +++ b/Modules/Synchronization/src/Synchronization.Application/Datawallets/Queries/GetDatawallet/Handler.cs @@ -1,4 +1,3 @@ -using AutoMapper; using Backbone.BuildingBlocks.Application.Abstractions.Exceptions; using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.UserContext; using Backbone.DevelopmentKit.Identity.ValueObjects; @@ -13,18 +12,16 @@ internal class Handler : IRequestHandler { private readonly IdentityAddress _activeIdentity; private readonly ISynchronizationDbContext _dbContext; - private readonly IMapper _mapper; - public Handler(ISynchronizationDbContext dbContext, IUserContext userContext, IMapper mapper) + public Handler(ISynchronizationDbContext dbContext, IUserContext userContext) { _dbContext = dbContext; - _mapper = mapper; _activeIdentity = userContext.GetAddress(); } public async Task Handle(GetDatawalletQuery request, CancellationToken cancellationToken) { var datawallet = await _dbContext.GetDatawallet(_activeIdentity, cancellationToken) ?? throw new NotFoundException(nameof(Datawallet)); - return _mapper.Map(datawallet); + return new DatawalletDTO(datawallet); } } diff --git a/Modules/Synchronization/src/Synchronization.Application/Datawallets/Queries/GetModifications/Handler.cs b/Modules/Synchronization/src/Synchronization.Application/Datawallets/Queries/GetModifications/Handler.cs index b97d3fca2e..35c5b3b0fc 100644 --- a/Modules/Synchronization/src/Synchronization.Application/Datawallets/Queries/GetModifications/Handler.cs +++ b/Modules/Synchronization/src/Synchronization.Application/Datawallets/Queries/GetModifications/Handler.cs @@ -1,4 +1,3 @@ -using AutoMapper; using Backbone.BuildingBlocks.Application.Abstractions.Exceptions; using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.UserContext; using Backbone.DevelopmentKit.Identity.ValueObjects; @@ -13,12 +12,10 @@ public class Handler : IRequestHandler Handle(GetModificationsQuery request var dbPaginationResult = await _dbContext.GetDatawalletModifications(_activeIdentity, request.LocalIndex, request.PaginationFilter, cancellationToken); - var dtos = MapToDtos(dbPaginationResult.ItemsOnPage); - - return new GetModificationsResponse(dtos, request.PaginationFilter, dbPaginationResult.TotalNumberOfItems); - } - - private List MapToDtos(IEnumerable modifications) - { - var datawalletModifications = modifications as DatawalletModification[] ?? modifications.ToArray(); - - var mappingTasks = datawalletModifications.Select(MapToDto); - - return mappingTasks.ToList(); - } - - private DatawalletModificationDTO MapToDto(DatawalletModification modification) - { - var dto = _mapper.Map(modification); - return dto; + return new GetModificationsResponse(dbPaginationResult.ItemsOnPage.Select(modification => new DatawalletModificationDTO(modification)), request.PaginationFilter, + dbPaginationResult.TotalNumberOfItems); } } diff --git a/Modules/Synchronization/src/Synchronization.Application/Extensions/IServiceCollectionExtensions.cs b/Modules/Synchronization/src/Synchronization.Application/Extensions/IServiceCollectionExtensions.cs index b64bb98489..0bfef288dd 100644 --- a/Modules/Synchronization/src/Synchronization.Application/Extensions/IServiceCollectionExtensions.cs +++ b/Modules/Synchronization/src/Synchronization.Application/Extensions/IServiceCollectionExtensions.cs @@ -2,7 +2,6 @@ using Backbone.BuildingBlocks.Application.Abstractions.Exceptions; using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.EventBus; using Backbone.BuildingBlocks.Application.MediatR; -using Backbone.Modules.Synchronization.Application.AutoMapper; using Backbone.Modules.Synchronization.Application.Datawallets.Commands.PushDatawalletModifications; using FluentValidation; using MediatR; @@ -22,7 +21,6 @@ public static void AddApplication(this IServiceCollection services) .AddOpenBehavior(typeof(QuotaEnforcerBehavior<,>)) ); - services.AddAutoMapper(typeof(AutoMapperProfile).Assembly); services.AddValidatorsFromAssembly(typeof(PushDatawalletModificationsCommand).Assembly); services.AddEventHandlers(); } diff --git a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/DeleteExternalEventsOfIdentity/DeleteSyncRunsOfIdentityCommand.cs b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/DeleteExternalEventsOfIdentity/DeleteSyncRunsOfIdentityCommand.cs index 1e96f7ed40..b820042d35 100644 --- a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/DeleteExternalEventsOfIdentity/DeleteSyncRunsOfIdentityCommand.cs +++ b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/DeleteExternalEventsOfIdentity/DeleteSyncRunsOfIdentityCommand.cs @@ -1,14 +1,13 @@ -using Backbone.DevelopmentKit.Identity.ValueObjects; -using MediatR; +using MediatR; namespace Backbone.Modules.Synchronization.Application.SyncRuns.Commands.DeleteExternalEventsOfIdentity; public class DeleteExternalEventsOfIdentityCommand : IRequest { - public DeleteExternalEventsOfIdentityCommand(IdentityAddress identityAddress) + public DeleteExternalEventsOfIdentityCommand(string identityAddress) { IdentityAddress = identityAddress; } - public IdentityAddress IdentityAddress { get; set; } + public string IdentityAddress { get; set; } } diff --git a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/DeleteExternalEventsOfIdentity/Validator.cs b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/DeleteExternalEventsOfIdentity/Validator.cs index 42646b0455..2c480a6575 100644 --- a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/DeleteExternalEventsOfIdentity/Validator.cs +++ b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/DeleteExternalEventsOfIdentity/Validator.cs @@ -1,9 +1,13 @@ -using Backbone.DevelopmentKit.Identity.ValueObjects; +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.DevelopmentKit.Identity.ValueObjects; using FluentValidation; namespace Backbone.Modules.Synchronization.Application.SyncRuns.Commands.DeleteExternalEventsOfIdentity; public class Validator : AbstractValidator { - public Validator() => RuleFor(x => x.IdentityAddress).Must(x => IdentityAddress.IsValid(x)); + public Validator() + { + RuleFor(x => x.IdentityAddress).ValidId(); + } } diff --git a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/DeleteSyncRunsOfIdentity/DeleteSyncRunsOfIdentityCommand.cs b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/DeleteSyncRunsOfIdentity/DeleteSyncRunsOfIdentityCommand.cs index 5fe38f86a5..b7a043882c 100644 --- a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/DeleteSyncRunsOfIdentity/DeleteSyncRunsOfIdentityCommand.cs +++ b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/DeleteSyncRunsOfIdentity/DeleteSyncRunsOfIdentityCommand.cs @@ -1,14 +1,13 @@ -using Backbone.DevelopmentKit.Identity.ValueObjects; -using MediatR; +using MediatR; namespace Backbone.Modules.Synchronization.Application.SyncRuns.Commands.DeleteSyncRunsOfIdentity; public class DeleteSyncRunsOfIdentityCommand : IRequest { - public DeleteSyncRunsOfIdentityCommand(IdentityAddress identityAddress) + public DeleteSyncRunsOfIdentityCommand(string identityAddress) { IdentityAddress = identityAddress; } - public IdentityAddress IdentityAddress { get; set; } + public string IdentityAddress { get; set; } } diff --git a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/DeleteSyncRunsOfIdentity/Validator.cs b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/DeleteSyncRunsOfIdentity/Validator.cs index 1e85c8a20e..0082fbacfd 100644 --- a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/DeleteSyncRunsOfIdentity/Validator.cs +++ b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/DeleteSyncRunsOfIdentity/Validator.cs @@ -1,9 +1,13 @@ -using Backbone.DevelopmentKit.Identity.ValueObjects; +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.DevelopmentKit.Identity.ValueObjects; using FluentValidation; namespace Backbone.Modules.Synchronization.Application.SyncRuns.Commands.DeleteSyncRunsOfIdentity; public class Validator : AbstractValidator { - public Validator() => RuleFor(x => x.IdentityAddress).Must(x => IdentityAddress.IsValid(x)); + public Validator() + { + RuleFor(x => x.IdentityAddress).ValidId(); + } } diff --git a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/FinalizeSyncRun/FinalizeDatawalletVersionUpgradeSyncRunCommand.cs b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/FinalizeSyncRun/FinalizeDatawalletVersionUpgradeSyncRunCommand.cs index 1b884d8dea..51f8c2ec7b 100644 --- a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/FinalizeSyncRun/FinalizeDatawalletVersionUpgradeSyncRunCommand.cs +++ b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/FinalizeSyncRun/FinalizeDatawalletVersionUpgradeSyncRunCommand.cs @@ -1,6 +1,5 @@ using System.Text.Json.Serialization; using Backbone.Modules.Synchronization.Application.Datawallets.DTOs; -using Backbone.Modules.Synchronization.Domain.Entities.Sync; using MediatR; namespace Backbone.Modules.Synchronization.Application.SyncRuns.Commands.FinalizeSyncRun; @@ -8,14 +7,14 @@ namespace Backbone.Modules.Synchronization.Application.SyncRuns.Commands.Finaliz public class FinalizeDatawalletVersionUpgradeSyncRunCommand : IRequest { [JsonConstructor] - public FinalizeDatawalletVersionUpgradeSyncRunCommand(SyncRunId syncRunId, ushort newDatawalletVersion, List datawalletModifications) + public FinalizeDatawalletVersionUpgradeSyncRunCommand(string syncRunId, ushort newDatawalletVersion, List datawalletModifications) { SyncRunId = syncRunId; NewDatawalletVersion = newDatawalletVersion; DatawalletModifications = datawalletModifications; } - public SyncRunId SyncRunId { get; set; } + public string SyncRunId { get; set; } public ushort NewDatawalletVersion { get; set; } public List DatawalletModifications { get; set; } } diff --git a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/FinalizeSyncRun/FinalizeDatawalletVersionUpgradeSyncRunCommandValidator.cs b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/FinalizeSyncRun/FinalizeDatawalletVersionUpgradeSyncRunCommandValidator.cs index 9d55cb44ef..8a18cc625f 100644 --- a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/FinalizeSyncRun/FinalizeDatawalletVersionUpgradeSyncRunCommandValidator.cs +++ b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/FinalizeSyncRun/FinalizeDatawalletVersionUpgradeSyncRunCommandValidator.cs @@ -1,5 +1,7 @@ +using Backbone.BuildingBlocks.Application.Extensions; using Backbone.BuildingBlocks.Application.FluentValidation; using Backbone.Modules.Synchronization.Application.Datawallets.DTOs; +using Backbone.Modules.Synchronization.Domain.Entities.Sync; using FluentValidation; namespace Backbone.Modules.Synchronization.Application.SyncRuns.Commands.FinalizeSyncRun; @@ -9,6 +11,7 @@ public class FinalizeDatawalletVersionUpgradeSyncRunCommandValidator : AbstractV { public FinalizeDatawalletVersionUpgradeSyncRunCommandValidator() { + RuleFor(x => x.SyncRunId).ValidId(); RuleFor(x => x.NewDatawalletVersion).DetailedNotEmpty(); RuleForEach(x => x.DatawalletModifications).SetValidator(new PushDatawalletModificationItemValidator()); } diff --git a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/FinalizeSyncRun/FinalizeExternalEventSyncSyncRunCommand.cs b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/FinalizeSyncRun/FinalizeExternalEventSyncSyncRunCommand.cs index d50e2b730e..cb0b08d065 100644 --- a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/FinalizeSyncRun/FinalizeExternalEventSyncSyncRunCommand.cs +++ b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/FinalizeSyncRun/FinalizeExternalEventSyncSyncRunCommand.cs @@ -1,51 +1,49 @@ using System.Text.Json.Serialization; -using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.Mapping; using Backbone.Modules.Synchronization.Application.Datawallets.DTOs; -using Backbone.Modules.Synchronization.Domain.Entities.Sync; using MediatR; namespace Backbone.Modules.Synchronization.Application.SyncRuns.Commands.FinalizeSyncRun; public class FinalizeExternalEventSyncSyncRunCommand : IRequest { - public FinalizeExternalEventSyncSyncRunCommand(SyncRunId syncRunId) : this(syncRunId, [], []) + public FinalizeExternalEventSyncSyncRunCommand(string syncRunId) : this(syncRunId, [], []) { } - public FinalizeExternalEventSyncSyncRunCommand(SyncRunId syncRunId, List externalEventResults) : this(syncRunId, externalEventResults, []) + public FinalizeExternalEventSyncSyncRunCommand(string syncRunId, List externalEventResults) : this(syncRunId, externalEventResults, []) { } - public FinalizeExternalEventSyncSyncRunCommand(SyncRunId syncRunId, List datawalletModifications) : this(syncRunId, [], datawalletModifications) + public FinalizeExternalEventSyncSyncRunCommand(string syncRunId, List datawalletModifications) : this(syncRunId, [], datawalletModifications) { } [JsonConstructor] - public FinalizeExternalEventSyncSyncRunCommand(SyncRunId syncRunId, List externalEventResults, List datawalletModifications) + public FinalizeExternalEventSyncSyncRunCommand(string syncRunId, List externalEventResults, List datawalletModifications) { SyncRunId = syncRunId; ExternalEventResults = externalEventResults; DatawalletModifications = datawalletModifications; } - public SyncRunId SyncRunId { get; set; } + public string SyncRunId { get; set; } public List ExternalEventResults { get; set; } public List DatawalletModifications { get; set; } - public class ExternalEventResult : IMapTo + public class ExternalEventResult { - public ExternalEventResult(ExternalEventId externalEventId) : this(externalEventId, null) + public ExternalEventResult(string externalEventId) : this(externalEventId, null) { } [JsonConstructor] - public ExternalEventResult(ExternalEventId externalEventId, string? errorCode) + public ExternalEventResult(string externalEventId, string? errorCode) { ExternalEventId = externalEventId; ErrorCode = errorCode; } - public ExternalEventId ExternalEventId { get; set; } + public string ExternalEventId { get; set; } public string? ErrorCode { get; set; } } } diff --git a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/FinalizeSyncRun/FinalizeExternalEventSyncSyncRunCommandValidator.cs b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/FinalizeSyncRun/FinalizeExternalEventSyncSyncRunCommandValidator.cs index f9adc40831..508b890483 100644 --- a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/FinalizeSyncRun/FinalizeExternalEventSyncSyncRunCommandValidator.cs +++ b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/FinalizeSyncRun/FinalizeExternalEventSyncSyncRunCommandValidator.cs @@ -1,5 +1,6 @@ -using Backbone.BuildingBlocks.Application.FluentValidation; +using Backbone.BuildingBlocks.Application.Extensions; using Backbone.Modules.Synchronization.Application.Datawallets.DTOs; +using Backbone.Modules.Synchronization.Domain.Entities.Sync; using FluentValidation; namespace Backbone.Modules.Synchronization.Application.SyncRuns.Commands.FinalizeSyncRun; @@ -9,6 +10,7 @@ public class FinalizeExternalEventSyncSyncRunCommandValidator : AbstractValidato { public FinalizeExternalEventSyncSyncRunCommandValidator() { + RuleFor(x => x.SyncRunId).ValidId(); RuleForEach(x => x.ExternalEventResults).SetValidator(new EventResultValidator()); RuleForEach(x => x.DatawalletModifications).SetValidator(new PushDatawalletModificationItemValidator()); } @@ -17,7 +19,8 @@ public class EventResultValidator : AbstractValidator i.ExternalEventId).DetailedNotEmpty(); + RuleFor(i => i.ExternalEventId).ValidId(); + RuleFor(i => i.ErrorCode).MaximumLength(50); } } } diff --git a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/FinalizeSyncRun/Handler.cs b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/FinalizeSyncRun/Handler.cs index 035a454c9b..d45568bd32 100644 --- a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/FinalizeSyncRun/Handler.cs +++ b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/FinalizeSyncRun/Handler.cs @@ -1,6 +1,4 @@ -using AutoMapper; using Backbone.BuildingBlocks.Application.Abstractions.Exceptions; -using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.EventBus; using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.UserContext; using Backbone.DevelopmentKit.Identity.ValueObjects; using Backbone.Modules.Synchronization.Application.Datawallets.DTOs; @@ -18,23 +16,19 @@ public class Handler : IRequestHandler Handle(FinalizeDatawalletVersionUpgradeSyncRunCommand request, CancellationToken cancellationToken) { - _syncRun = await _dbContext.GetSyncRun(request.SyncRunId, _activeIdentity, cancellationToken); + _syncRun = await _dbContext.GetSyncRun(SyncRunId.Parse(request.SyncRunId), _activeIdentity, cancellationToken); if (_syncRun.Type != SyncRun.SyncRunType.DatawalletVersionUpgrade) throw new ApplicationException(ApplicationErrors.SyncRuns.UnexpectedSyncRunType(SyncRun.SyncRunType.DatawalletVersionUpgrade)); @@ -64,7 +58,7 @@ public async Task Handle(Finali var response = new FinalizeDatawalletVersionUpgradeSyncRunResponse { NewDatawalletModificationIndex = _datawallet.LatestModification?.Index, - DatawalletModifications = _mapper.Map(newModifications) + DatawalletModifications = newModifications.Select(m => new CreatedDatawalletModificationDTO(m)) }; return response; @@ -72,7 +66,7 @@ public async Task Handle(Finali public async Task Handle(FinalizeExternalEventSyncSyncRunCommand request, CancellationToken cancellationToken) { - _syncRun = await _dbContext.GetSyncRunWithExternalEvents(request.SyncRunId, _activeIdentity, cancellationToken); + _syncRun = await _dbContext.GetSyncRunWithExternalEvents(SyncRunId.Parse(request.SyncRunId), _activeIdentity, cancellationToken); if (_syncRun.Type != SyncRun.SyncRunType.ExternalEventSync) throw new ApplicationException(ApplicationErrors.SyncRuns.UnexpectedSyncRunType(SyncRun.SyncRunType.ExternalEventSync)); @@ -81,7 +75,13 @@ public async Task Handle(FinalizeExter _datawallet = await _dbContext.GetDatawalletForInsertion(_activeIdentity, cancellationToken) ?? throw new NotFoundException(nameof(Datawallet)); - var eventResults = _mapper.Map(request.ExternalEventResults); + var eventResults = request.ExternalEventResults.Select(e => + new ExternalEventResult + { + ErrorCode = e.ErrorCode ?? string.Empty, + ExternalEventId = ExternalEventId.Parse(e.ExternalEventId) + }).ToArray(); + _syncRun.FinalizeExternalEventSync(eventResults); _dbContext.Set().Update(_syncRun); @@ -93,7 +93,7 @@ public async Task Handle(FinalizeExter var response = new FinalizeExternalEventSyncSyncRunResponse { NewDatawalletModificationIndex = _datawallet.LatestModification?.Index, - DatawalletModifications = _mapper.Map(newModifications) + DatawalletModifications = newModifications.Select(x => new CreatedDatawalletModificationDTO(x)) }; return response; @@ -123,7 +123,7 @@ private List AddModificationsToDatawallet(List(modificationDto.Type), + MapDatawalletModificationType(modificationDto.Type), new Datawallet.DatawalletVersion(modificationDto.DatawalletVersion), modificationDto.Collection, modificationDto.ObjectIdentifier, @@ -137,4 +137,16 @@ private List AddModificationsToDatawallet(List DatawalletModificationType.Create, + DatawalletModificationDTO.DatawalletModificationType.Update => DatawalletModificationType.Update, + DatawalletModificationDTO.DatawalletModificationType.Delete => DatawalletModificationType.Delete, + DatawalletModificationDTO.DatawalletModificationType.CacheChanged => DatawalletModificationType.CacheChanged, + _ => throw new Exception($"Unsupported Datawallet Modification Type: {type}") + }; + } } diff --git a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/RefreshExpirationTimeOfSyncRun/Handler.cs b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/RefreshExpirationTimeOfSyncRun/Handler.cs index 983e168d5a..d92b28dacd 100644 --- a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/RefreshExpirationTimeOfSyncRun/Handler.cs +++ b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/RefreshExpirationTimeOfSyncRun/Handler.cs @@ -22,7 +22,7 @@ public Handler(ISynchronizationDbContext dbContext, IUserContext userContext) public async Task Handle(RefreshExpirationTimeOfSyncRunCommand request, CancellationToken cancellationToken) { - var syncRun = await _dbContext.GetSyncRun(request.SyncRunId, _activeIdentity, cancellationToken); + var syncRun = await _dbContext.GetSyncRun(SyncRunId.Parse(request.SyncRunId), _activeIdentity, cancellationToken); CheckPrerequisites(syncRun); diff --git a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/RefreshExpirationTimeOfSyncRun/RefreshExpirationTimeOfSyncRunCommand.cs b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/RefreshExpirationTimeOfSyncRun/RefreshExpirationTimeOfSyncRunCommand.cs index fa70fa9433..4b2906a24b 100644 --- a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/RefreshExpirationTimeOfSyncRun/RefreshExpirationTimeOfSyncRunCommand.cs +++ b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/RefreshExpirationTimeOfSyncRun/RefreshExpirationTimeOfSyncRunCommand.cs @@ -1,14 +1,13 @@ -using Backbone.Modules.Synchronization.Domain.Entities.Sync; using MediatR; namespace Backbone.Modules.Synchronization.Application.SyncRuns.Commands.RefreshExpirationTimeOfSyncRun; public class RefreshExpirationTimeOfSyncRunCommand : IRequest { - public RefreshExpirationTimeOfSyncRunCommand(SyncRunId syncRunId) + public RefreshExpirationTimeOfSyncRunCommand(string syncRunId) { SyncRunId = syncRunId; } - public SyncRunId SyncRunId { get; set; } + public string SyncRunId { get; set; } } diff --git a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/RefreshExpirationTimeOfSyncRun/Validator.cs b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/RefreshExpirationTimeOfSyncRun/Validator.cs new file mode 100644 index 0000000000..2bc60a990e --- /dev/null +++ b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/RefreshExpirationTimeOfSyncRun/Validator.cs @@ -0,0 +1,13 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.Modules.Synchronization.Domain.Entities.Sync; +using FluentValidation; + +namespace Backbone.Modules.Synchronization.Application.SyncRuns.Commands.RefreshExpirationTimeOfSyncRun; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleFor(x => x.SyncRunId).ValidId(); + } +} diff --git a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/StartSyncRun/Handler.cs b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/StartSyncRun/Handler.cs index ebf467b6ac..7bf538d0a3 100644 --- a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/StartSyncRun/Handler.cs +++ b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/StartSyncRun/Handler.cs @@ -1,4 +1,3 @@ -using AutoMapper; using Backbone.BuildingBlocks.Application.Abstractions.Exceptions; using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.UserContext; using Backbone.BuildingBlocks.Application.Extensions; @@ -21,7 +20,6 @@ public class Handler : IRequestHandler Handle(StartSyncRunCommand request, CancellationToken cancellationToken) { _request = request; @@ -125,7 +121,7 @@ private async Task CreateNewSyncRun() private async Task CreateNewSyncRun(IEnumerable events) { var newIndex = DetermineNextSyncRunIndex(); - var syncRun = new SyncRun(newIndex, _request.Duration ?? DEFAULT_DURATION, _activeIdentity, _activeDevice, events, _mapper.Map(_request.Type)); + var syncRun = new SyncRun(newIndex, _request.Duration ?? DEFAULT_DURATION, _activeIdentity, _activeDevice, events, MapSyncRunType(_request.Type)); await _dbContext.Set().AddAsync(syncRun, _cancellationToken); try @@ -143,6 +139,16 @@ private async Task CreateNewSyncRun(IEnumerable events) return syncRun; } + private SyncRun.SyncRunType MapSyncRunType(SyncRunDTO.SyncRunType type) + { + return type switch + { + SyncRunDTO.SyncRunType.DatawalletVersionUpgrade => SyncRun.SyncRunType.DatawalletVersionUpgrade, + SyncRunDTO.SyncRunType.ExternalEventSync => SyncRun.SyncRunType.ExternalEventSync, + _ => throw new Exception($"Unsupported Sync Run Type: {type}") + }; + } + private long DetermineNextSyncRunIndex() { return _previousSyncRun == null ? 0 : _previousSyncRun.Index + 1; @@ -150,13 +156,6 @@ private long DetermineNextSyncRunIndex() private StartSyncRunResponse CreateResponse(StartSyncRunStatus status, SyncRun? newSyncRun = null) { - var syncRunDTO = _mapper.Map(newSyncRun); - - var response = new StartSyncRunResponse - { - Status = status, - SyncRun = syncRunDTO - }; - return response; + return new StartSyncRunResponse(status, newSyncRun); } } diff --git a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/StartSyncRun/StartSyncRunResponse.cs b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/StartSyncRun/StartSyncRunResponse.cs index c08519b54e..466e038e0b 100644 --- a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/StartSyncRun/StartSyncRunResponse.cs +++ b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/StartSyncRun/StartSyncRunResponse.cs @@ -1,12 +1,19 @@ using System.Text.Json.Serialization; using Backbone.Modules.Synchronization.Application.SyncRuns.DTOs; +using Backbone.Modules.Synchronization.Domain.Entities.Sync; namespace Backbone.Modules.Synchronization.Application.SyncRuns.Commands.StartSyncRun; public class StartSyncRunResponse { - public required StartSyncRunStatus Status { get; set; } - public required SyncRunDTO SyncRun { get; set; } + public StartSyncRunResponse(StartSyncRunStatus status, SyncRun? newSyncRun = null) + { + Status = status; + SyncRun = newSyncRun != null ? new SyncRunDTO(newSyncRun) : null; + } + + public StartSyncRunStatus Status { get; set; } + public SyncRunDTO? SyncRun { get; set; } } [JsonConverter(typeof(JsonStringEnumConverter))] diff --git a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/StartSyncRun/StartSyncRunCommandValidator.cs b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/StartSyncRun/Validator.cs similarity index 76% rename from Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/StartSyncRun/StartSyncRunCommandValidator.cs rename to Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/StartSyncRun/Validator.cs index 377d1348cb..549627720c 100644 --- a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/StartSyncRun/StartSyncRunCommandValidator.cs +++ b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Commands/StartSyncRun/Validator.cs @@ -3,9 +3,9 @@ namespace Backbone.Modules.Synchronization.Application.SyncRuns.Commands.StartSyncRun; -internal class StartSyncRunCommandValidator : AbstractValidator +internal class Validator : AbstractValidator { - public StartSyncRunCommandValidator() + public Validator() { RuleFor(r => r.SupportedDatawalletVersion).Must(v => v > 0).WithErrorCode(GenericApplicationErrors.Validation.InvalidPropertyValue().Code) .WithMessage("'SupportedDatawalletVersion' must be greater than 0."); diff --git a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/DTOs/ExternalEventDTO.cs b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/DTOs/ExternalEventDTO.cs index d53d86d165..e1ab19e542 100644 --- a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/DTOs/ExternalEventDTO.cs +++ b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/DTOs/ExternalEventDTO.cs @@ -1,21 +1,29 @@ -using AutoMapper; -using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.Mapping; using Backbone.Modules.Synchronization.Domain.Entities.Sync; namespace Backbone.Modules.Synchronization.Application.SyncRuns.DTOs; -public class ExternalEventDTO : IHaveCustomMapping +public class ExternalEventDTO { - public required ExternalEventId Id { get; set; } - public required string Type { get; set; } - public required long Index { get; set; } - public required DateTime CreatedAt { get; set; } - public required byte SyncErrorCount { get; set; } - public required object Payload { get; set; } + public ExternalEventDTO(ExternalEvent externalEvent) + { + Id = externalEvent.Id; + Type = MapExternalEventType(externalEvent.Type); + Index = externalEvent.Index; + CreatedAt = externalEvent.CreatedAt; + SyncErrorCount = externalEvent.SyncErrorCount; + Payload = externalEvent.Payload; + } + + public string Id { get; set; } + public string Type { get; set; } + public long Index { get; set; } + public DateTime CreatedAt { get; set; } + public byte SyncErrorCount { get; set; } + public object Payload { get; set; } - public void CreateMappings(Profile configuration) + private string MapExternalEventType(ExternalEventType externalEventType) { - configuration.CreateMap().ConvertUsing((externalEventType, _) => externalEventType switch + return externalEventType switch { ExternalEventType.MessageReceived => "MessageReceived", ExternalEventType.MessageDelivered => "MessageDelivered", @@ -31,7 +39,6 @@ public void CreateMappings(Profile configuration) ExternalEventType.PeerDeleted => "PeerDeleted", _ => throw new ArgumentOutOfRangeException(nameof(externalEventType), externalEventType, null) - }); - configuration.CreateMap(); + }; } } diff --git a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/DTOs/SyncRunDTO.cs b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/DTOs/SyncRunDTO.cs index c60c2015a5..6bad9bd4ea 100644 --- a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/DTOs/SyncRunDTO.cs +++ b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/DTOs/SyncRunDTO.cs @@ -1,12 +1,8 @@ -using AutoMapper; -using AutoMapper.Extensions.EnumMapping; -using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.Mapping; -using Backbone.DevelopmentKit.Identity.ValueObjects; using Backbone.Modules.Synchronization.Domain.Entities.Sync; namespace Backbone.Modules.Synchronization.Application.SyncRuns.DTOs; -public class SyncRunDTO : IHaveCustomMapping +public class SyncRunDTO { public enum SyncRunType { @@ -14,22 +10,38 @@ public enum SyncRunType DatawalletVersionUpgrade } - public required SyncRunId Id { get; set; } - public required SyncRunType Type { get; set; } - public required DateTime ExpiresAt { get; set; } - public required long Index { get; set; } - public required DateTime CreatedAt { get; set; } - public required IdentityAddress CreatedBy { get; set; } - public required DeviceId CreatedByDevice { get; set; } - public required int EventCount { get; set; } + public SyncRunDTO() + { + } - public void CreateMappings(Profile configuration) + public SyncRunDTO(SyncRun syncRun) { - configuration.CreateMap(); + Id = syncRun.Id; + Type = MapSyncRunType(syncRun.Type); + ExpiresAt = syncRun.ExpiresAt; + Index = syncRun.Index; + CreatedAt = syncRun.CreatedAt; + CreatedBy = syncRun.CreatedBy; + CreatedByDevice = syncRun.CreatedByDevice; + EventCount = syncRun.EventCount; + } - configuration.CreateMap().ConvertUsingEnumMapping(opt => opt - .MapValue(SyncRun.SyncRunType.DatawalletVersionUpgrade, SyncRunType.DatawalletVersionUpgrade) - .MapValue(SyncRun.SyncRunType.ExternalEventSync, SyncRunType.ExternalEventSync) - ); + public string Id { get; set; } = null!; + public SyncRunType Type { get; set; } + public DateTime ExpiresAt { get; set; } + public long Index { get; set; } + public DateTime CreatedAt { get; set; } + public string CreatedBy { get; set; } = null!; + public string CreatedByDevice { get; set; } = null!; + public int EventCount { get; set; } + + private SyncRunType MapSyncRunType(SyncRun.SyncRunType type) + { + return type switch + { + SyncRun.SyncRunType.DatawalletVersionUpgrade => SyncRunType.DatawalletVersionUpgrade, + SyncRun.SyncRunType.ExternalEventSync => SyncRunType.ExternalEventSync, + _ => throw new Exception($"Unsupported Sync Run Type: {type}") + }; } } diff --git a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Queries/GetExternalEventsOfSyncRun/GetExternalEventsOfSyncRunQuery.cs b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Queries/GetExternalEventsOfSyncRun/GetExternalEventsOfSyncRunQuery.cs index 50f1ca9675..f448f3feb1 100644 --- a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Queries/GetExternalEventsOfSyncRun/GetExternalEventsOfSyncRunQuery.cs +++ b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Queries/GetExternalEventsOfSyncRun/GetExternalEventsOfSyncRunQuery.cs @@ -1,6 +1,5 @@ using System.Text.Json.Serialization; using Backbone.BuildingBlocks.Application.Pagination; -using Backbone.Modules.Synchronization.Domain.Entities.Sync; using MediatR; namespace Backbone.Modules.Synchronization.Application.SyncRuns.Queries.GetExternalEventsOfSyncRun; @@ -8,12 +7,12 @@ namespace Backbone.Modules.Synchronization.Application.SyncRuns.Queries.GetExter public class GetExternalEventsOfSyncRunQuery : IRequest { [JsonConstructor] - public GetExternalEventsOfSyncRunQuery(SyncRunId syncRunId, PaginationFilter paginationFilter) + public GetExternalEventsOfSyncRunQuery(string syncRunId, PaginationFilter paginationFilter) { PaginationFilter = paginationFilter; SyncRunId = syncRunId; } - public SyncRunId SyncRunId { get; set; } + public string SyncRunId { get; set; } public PaginationFilter PaginationFilter { get; set; } } diff --git a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Queries/GetExternalEventsOfSyncRun/Handler.cs b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Queries/GetExternalEventsOfSyncRun/Handler.cs index 5858639aad..03796c43be 100644 --- a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Queries/GetExternalEventsOfSyncRun/Handler.cs +++ b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Queries/GetExternalEventsOfSyncRun/Handler.cs @@ -1,9 +1,9 @@ -using AutoMapper; using Backbone.BuildingBlocks.Application.Abstractions.Exceptions; using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.UserContext; using Backbone.DevelopmentKit.Identity.ValueObjects; using Backbone.Modules.Synchronization.Application.Infrastructure; using Backbone.Modules.Synchronization.Application.SyncRuns.DTOs; +using Backbone.Modules.Synchronization.Domain.Entities.Sync; using MediatR; namespace Backbone.Modules.Synchronization.Application.SyncRuns.Queries.GetExternalEventsOfSyncRun; @@ -13,19 +13,17 @@ public class Handler : IRequestHandler Handle(GetExternalEventsOfSyncRunQuery request, CancellationToken cancellationToken) { - var syncRun = await _dbContext.GetSyncRunAsNoTracking(request.SyncRunId, _activeIdentity, cancellationToken); + var syncRun = await _dbContext.GetSyncRunAsNoTracking(SyncRunId.Parse(request.SyncRunId), _activeIdentity, cancellationToken); if (syncRun.IsFinalized) throw new OperationFailedException(ApplicationErrors.SyncRuns.SyncRunAlreadyFinalized()); @@ -35,8 +33,6 @@ public async Task Handle(GetExternalEventsOf var dbPaginationResult = await _dbContext.GetExternalEventsOfSyncRun(request.PaginationFilter, _activeIdentity, syncRun.Id, cancellationToken); - var dtos = _mapper.Map>(dbPaginationResult.ItemsOnPage); - - return new GetExternalEventsOfSyncRunResponse(dtos, request.PaginationFilter, dbPaginationResult.TotalNumberOfItems); + return new GetExternalEventsOfSyncRunResponse(dbPaginationResult.ItemsOnPage.Select(e => new ExternalEventDTO(e)), request.PaginationFilter, dbPaginationResult.TotalNumberOfItems); } } diff --git a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Queries/GetExternalEventsOfSyncRun/Validator.cs b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Queries/GetExternalEventsOfSyncRun/Validator.cs new file mode 100644 index 0000000000..0688d7992f --- /dev/null +++ b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Queries/GetExternalEventsOfSyncRun/Validator.cs @@ -0,0 +1,13 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.Modules.Synchronization.Domain.Entities.Sync; +using FluentValidation; + +namespace Backbone.Modules.Synchronization.Application.SyncRuns.Queries.GetExternalEventsOfSyncRun; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleFor(x => x.SyncRunId).ValidId(); + } +} diff --git a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Queries/GetSyncRunById/GetSyncRunByIdQuery.cs b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Queries/GetSyncRunById/GetSyncRunByIdQuery.cs index f8797ef681..04da7aa7d7 100644 --- a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Queries/GetSyncRunById/GetSyncRunByIdQuery.cs +++ b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Queries/GetSyncRunById/GetSyncRunByIdQuery.cs @@ -1,6 +1,5 @@ using System.Text.Json.Serialization; using Backbone.Modules.Synchronization.Application.SyncRuns.DTOs; -using Backbone.Modules.Synchronization.Domain.Entities.Sync; using MediatR; namespace Backbone.Modules.Synchronization.Application.SyncRuns.Queries.GetSyncRunById; @@ -8,10 +7,10 @@ namespace Backbone.Modules.Synchronization.Application.SyncRuns.Queries.GetSyncR public class GetSyncRunByIdQuery : IRequest { [JsonConstructor] - public GetSyncRunByIdQuery(SyncRunId syncRunId) + public GetSyncRunByIdQuery(string syncRunId) { SyncRunId = syncRunId; } - public SyncRunId SyncRunId { get; set; } + public string SyncRunId { get; set; } } diff --git a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Queries/GetSyncRunById/Handler.cs b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Queries/GetSyncRunById/Handler.cs index a4c78d1a16..880a72db7b 100644 --- a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Queries/GetSyncRunById/Handler.cs +++ b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Queries/GetSyncRunById/Handler.cs @@ -1,8 +1,8 @@ -using AutoMapper; using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.UserContext; using Backbone.DevelopmentKit.Identity.ValueObjects; using Backbone.Modules.Synchronization.Application.Infrastructure; using Backbone.Modules.Synchronization.Application.SyncRuns.DTOs; +using Backbone.Modules.Synchronization.Domain.Entities.Sync; using MediatR; namespace Backbone.Modules.Synchronization.Application.SyncRuns.Queries.GetSyncRunById; @@ -11,22 +11,17 @@ public class Handler : IRequestHandler { private readonly IdentityAddress _activeIdentity; private readonly ISynchronizationDbContext _dbContext; - private readonly IMapper _mapper; - public Handler(ISynchronizationDbContext dbContext, IUserContext userContext, IMapper mapper) + public Handler(ISynchronizationDbContext dbContext, IUserContext userContext) { _dbContext = dbContext; - _mapper = mapper; _activeIdentity = userContext.GetAddress(); userContext.GetDeviceId(); } public async Task Handle(GetSyncRunByIdQuery request, CancellationToken cancellationToken) { - var syncRun = await _dbContext.GetSyncRunAsNoTracking(request.SyncRunId, _activeIdentity, CancellationToken.None); - - var dto = _mapper.Map(syncRun); - - return dto; + var syncRun = await _dbContext.GetSyncRunAsNoTracking(SyncRunId.Parse(request.SyncRunId), _activeIdentity, CancellationToken.None); + return new SyncRunDTO(syncRun); } } diff --git a/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Queries/GetSyncRunById/Validator.cs b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Queries/GetSyncRunById/Validator.cs new file mode 100644 index 0000000000..054a864d6d --- /dev/null +++ b/Modules/Synchronization/src/Synchronization.Application/SyncRuns/Queries/GetSyncRunById/Validator.cs @@ -0,0 +1,13 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.Modules.Synchronization.Domain.Entities.Sync; +using FluentValidation; + +namespace Backbone.Modules.Synchronization.Application.SyncRuns.Queries.GetSyncRunById; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleFor(x => x.SyncRunId).ValidId(); + } +} diff --git a/Modules/Synchronization/src/Synchronization.Application/Synchronization.Application.csproj b/Modules/Synchronization/src/Synchronization.Application/Synchronization.Application.csproj index dcfcf44012..006f1ed8f5 100644 --- a/Modules/Synchronization/src/Synchronization.Application/Synchronization.Application.csproj +++ b/Modules/Synchronization/src/Synchronization.Application/Synchronization.Application.csproj @@ -5,7 +5,6 @@ - diff --git a/Modules/Synchronization/test/Synchronization.Application.Tests/Tests/AutoMapper/AutoMapperProfileTests.cs b/Modules/Synchronization/test/Synchronization.Application.Tests/Tests/AutoMapper/AutoMapperProfileTests.cs deleted file mode 100644 index 134d003568..0000000000 --- a/Modules/Synchronization/test/Synchronization.Application.Tests/Tests/AutoMapper/AutoMapperProfileTests.cs +++ /dev/null @@ -1,19 +0,0 @@ -using AutoMapper; -using Backbone.Modules.Synchronization.Application.AutoMapper; -using Backbone.UnitTestTools.BaseClasses; -using Xunit; - -namespace Backbone.Modules.Synchronization.Application.Tests.Tests.AutoMapper; - -public class AutoMapperProfileTests : AbstractTestsBase -{ - [Fact] - public void ProfileIsValid() - { - // Arrange - var configuration = new MapperConfiguration(cfg => cfg.AddProfile()); - - // Act & Assert - configuration.AssertConfigurationIsValid(); - } -} diff --git a/Modules/Synchronization/test/Synchronization.Application.Tests/Tests/Datawallet/Commands/PushDatawalletModifications/HandlerTests.cs b/Modules/Synchronization/test/Synchronization.Application.Tests/Tests/Datawallet/Commands/PushDatawalletModifications/HandlerTests.cs index 7249730c16..b08cde2812 100644 --- a/Modules/Synchronization/test/Synchronization.Application.Tests/Tests/Datawallet/Commands/PushDatawalletModifications/HandlerTests.cs +++ b/Modules/Synchronization/test/Synchronization.Application.Tests/Tests/Datawallet/Commands/PushDatawalletModifications/HandlerTests.cs @@ -3,7 +3,6 @@ using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.EventBus; using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.UserContext; using Backbone.DevelopmentKit.Identity.ValueObjects; -using Backbone.Modules.Synchronization.Application.AutoMapper; using Backbone.Modules.Synchronization.Application.Datawallets.Commands.PushDatawalletModifications; using Backbone.Modules.Synchronization.Application.Datawallets.DTOs; using Backbone.Modules.Synchronization.Infrastructure.Persistence.Database; @@ -94,8 +93,6 @@ private static Handler CreateHandler(IdentityAddress activeIdentity, DeviceId ac A.CallTo(() => userContext.GetAddress()).Returns(activeIdentity); A.CallTo(() => userContext.GetDeviceId()).Returns(activeDevice); - var mapper = AutoMapperProfile.CreateMapper(); - - return new Handler(dbContext, userContext, mapper); + return new Handler(dbContext, userContext); } } diff --git a/Modules/Synchronization/test/Synchronization.Application.Tests/Tests/Datawallet/Commands/PushDatawalletModifications/PushDatawalletModificationsCommandValidatorTests.cs b/Modules/Synchronization/test/Synchronization.Application.Tests/Tests/Datawallet/Commands/PushDatawalletModifications/PushDatawalletModificationsCommandValidatorTests.cs index 8fa241d5c9..7018c8c5c6 100644 --- a/Modules/Synchronization/test/Synchronization.Application.Tests/Tests/Datawallet/Commands/PushDatawalletModifications/PushDatawalletModificationsCommandValidatorTests.cs +++ b/Modules/Synchronization/test/Synchronization.Application.Tests/Tests/Datawallet/Commands/PushDatawalletModifications/PushDatawalletModificationsCommandValidatorTests.cs @@ -11,36 +11,40 @@ public class PushDatawalletModificationsCommandValidatorTests : AbstractTestsBas [Fact] public void Happy_path() { - var validator = new PushDatawalletModificationsCommandValidator(); + // Arrange + var validator = new Validator(); - var command = new PushDatawalletModificationsCommand( + // Act + var validationResult = validator.TestValidate(new PushDatawalletModificationsCommand( [ new PushDatawalletModificationItem { Collection = "x", DatawalletVersion = 1, EncryptedPayload = [], ObjectIdentifier = "x", PayloadCategory = "x", Type = DatawalletModificationDTO.DatawalletModificationType.Create } ], - 1); - var validationResult = validator.TestValidate(command); + 1)); + // Assert validationResult.ShouldNotHaveAnyValidationErrors(); } [Fact] public void Fails_when_not_passing_a_SupportedDatawalletVersion() { - var validator = new PushDatawalletModificationsCommandValidator(); + // Arrange + var validator = new Validator(); - var command = new PushDatawalletModificationsCommand( + // Act + var validationResult = validator.TestValidate(new PushDatawalletModificationsCommand( [ new PushDatawalletModificationItem { Collection = "x", DatawalletVersion = 1, EncryptedPayload = [], ObjectIdentifier = "x", PayloadCategory = "x", Type = DatawalletModificationDTO.DatawalletModificationType.Create } ], - 0); - var validationResult = validator.TestValidate(command); + 0)); + // Assert validationResult.ShouldHaveValidationErrorFor(x => x.SupportedDatawalletVersion); } } diff --git a/Modules/Synchronization/test/Synchronization.Application.Tests/Tests/Datawallet/Queries/GetDatawalletModifications/HandlerTests.cs b/Modules/Synchronization/test/Synchronization.Application.Tests/Tests/Datawallet/Queries/GetDatawalletModifications/HandlerTests.cs index f2e14107c0..66d060df42 100644 --- a/Modules/Synchronization/test/Synchronization.Application.Tests/Tests/Datawallet/Queries/GetDatawalletModifications/HandlerTests.cs +++ b/Modules/Synchronization/test/Synchronization.Application.Tests/Tests/Datawallet/Queries/GetDatawalletModifications/HandlerTests.cs @@ -1,7 +1,6 @@ using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.UserContext; using Backbone.BuildingBlocks.Application.Pagination; using Backbone.DevelopmentKit.Identity.ValueObjects; -using Backbone.Modules.Synchronization.Application.AutoMapper; using Backbone.Modules.Synchronization.Application.Datawallets.Queries.GetModifications; using Backbone.Modules.Synchronization.Domain.Entities; using Backbone.Modules.Synchronization.Infrastructure.Persistence.Database; @@ -362,6 +361,6 @@ private Handler CreateHandler() var userContext = A.Fake(); A.CallTo(() => userContext.GetAddress()).Returns(ACTIVE_IDENTITY); - return new Handler(_actContext, AutoMapperProfile.CreateMapper(), userContext); + return new Handler(_actContext, userContext); } } diff --git a/Modules/Synchronization/test/Synchronization.Application.Tests/Tests/SyncRuns/Commands/FinalizeSyncRun/HandlerTests.cs b/Modules/Synchronization/test/Synchronization.Application.Tests/Tests/SyncRuns/Commands/FinalizeSyncRun/HandlerTests.cs index e7b7e91217..c9d1590e56 100644 --- a/Modules/Synchronization/test/Synchronization.Application.Tests/Tests/SyncRuns/Commands/FinalizeSyncRun/HandlerTests.cs +++ b/Modules/Synchronization/test/Synchronization.Application.Tests/Tests/SyncRuns/Commands/FinalizeSyncRun/HandlerTests.cs @@ -1,8 +1,6 @@ using Backbone.BuildingBlocks.Application.Abstractions.Exceptions; -using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.EventBus; using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.UserContext; using Backbone.DevelopmentKit.Identity.ValueObjects; -using Backbone.Modules.Synchronization.Application.AutoMapper; using Backbone.Modules.Synchronization.Application.Datawallets.DTOs; using Backbone.Modules.Synchronization.Application.SyncRuns.Commands.FinalizeSyncRun; using Backbone.Modules.Synchronization.Infrastructure.Persistence.Database; @@ -254,11 +252,7 @@ private Handler CreateHandler(IdentityAddress activeIdentity, DeviceId activeDev A.CallTo(() => userContext.GetAddress()).Returns(activeIdentity); A.CallTo(() => userContext.GetDeviceId()).Returns(activeDevice); - var mapper = AutoMapperProfile.CreateMapper(); - - var eventBus = A.Fake(); - - return new Handler(_actContext, userContext, mapper, eventBus); + return new Handler(_actContext, userContext); } #endregion diff --git a/Modules/Synchronization/test/Synchronization.Application.Tests/Tests/SyncRuns/Commands/StartSyncRun/HandlerTests.cs b/Modules/Synchronization/test/Synchronization.Application.Tests/Tests/SyncRuns/Commands/StartSyncRun/HandlerTests.cs index 26c6e40eff..74f2d6c259 100644 --- a/Modules/Synchronization/test/Synchronization.Application.Tests/Tests/SyncRuns/Commands/StartSyncRun/HandlerTests.cs +++ b/Modules/Synchronization/test/Synchronization.Application.Tests/Tests/SyncRuns/Commands/StartSyncRun/HandlerTests.cs @@ -2,7 +2,6 @@ using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.EventBus; using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.UserContext; using Backbone.DevelopmentKit.Identity.ValueObjects; -using Backbone.Modules.Synchronization.Application.AutoMapper; using Backbone.Modules.Synchronization.Application.SyncRuns.Commands.StartSyncRun; using Backbone.Modules.Synchronization.Application.SyncRuns.DTOs; using Backbone.Modules.Synchronization.Domain.Entities.Sync; @@ -132,7 +131,7 @@ public async Task No_sync_items_with_max_error_count_are_added() // Assert - var itemsOfSyncRun = _assertionContext.ExternalEvents.Where(i => i.SyncRunId == response.SyncRun.Id); + var itemsOfSyncRun = _assertionContext.ExternalEvents.Where(i => i.SyncRunId! == response.SyncRun!.Id); itemsOfSyncRun.Should().Contain(i => i.Id == itemWithoutErrors.Id); itemsOfSyncRun.Should().NotContain(i => i.Id == itemWithMaxErrorCount.Id); } @@ -171,7 +170,7 @@ public async Task Only_sync_items_of_active_identity_are_added() // Assert - var itemsOfSyncRun = _assertionContext.ExternalEvents.Where(i => i.SyncRunId == response.SyncRun.Id); + var itemsOfSyncRun = _assertionContext.ExternalEvents.Where(i => i.SyncRunId! == response.SyncRun!.Id); itemsOfSyncRun.Should().Contain(i => i.Id == itemOfActiveIdentity.Id); itemsOfSyncRun.Should().NotContain(i => i.Id == itemOfOtherIdentity.Id); } @@ -191,7 +190,7 @@ public async Task Only_unsynced_sync_items_are_added() // Assert - var itemsOfSyncRun = _assertionContext.ExternalEvents.Where(i => i.SyncRunId == response.SyncRun.Id); + var itemsOfSyncRun = _assertionContext.ExternalEvents.Where(i => i.SyncRunId! == response.SyncRun!.Id); itemsOfSyncRun.Should().Contain(i => i.Id == unsyncedItem.Id); itemsOfSyncRun.Should().NotContain(i => i.Id == syncedItem.Id); } @@ -229,7 +228,7 @@ public async Task Start_a_sync_run_when_already_running_sync_run_is_expired() canceledSyncRun.FinalizedAt.Should().NotBeNull(); var externalEventOfCanceledSyncRun = _assertionContext.ExternalEvents.First(i => i.Id == externalEvent.Id); - externalEventOfCanceledSyncRun.SyncRunId.Should().Be(response.SyncRun.Id); + externalEventOfCanceledSyncRun.SyncRunId?.Value.Should().Be(response.SyncRun!.Id); externalEventOfCanceledSyncRun.SyncErrorCount.Should().Be(1); } @@ -263,9 +262,7 @@ private Handler CreateHandler(IdentityAddress activeIdentity, DeviceId createdBy A.CallTo(() => userContext.GetAddress()).Returns(activeIdentity); A.CallTo(() => userContext.GetDeviceId()).Returns(createdByDevice); - var mapper = AutoMapperProfile.CreateMapper(); - - return new Handler(dbContext ?? _actContext, userContext, mapper); + return new Handler(dbContext ?? _actContext, userContext); } #endregion diff --git a/Modules/Synchronization/test/Synchronization.Application.Tests/Tests/SyncRuns/Commands/StartSyncRun/StartSyncRunCommandValidatorTests.cs b/Modules/Synchronization/test/Synchronization.Application.Tests/Tests/SyncRuns/Commands/StartSyncRun/StartSyncRunCommandValidatorTests.cs index 096dcabada..cb17a75719 100644 --- a/Modules/Synchronization/test/Synchronization.Application.Tests/Tests/SyncRuns/Commands/StartSyncRun/StartSyncRunCommandValidatorTests.cs +++ b/Modules/Synchronization/test/Synchronization.Application.Tests/Tests/SyncRuns/Commands/StartSyncRun/StartSyncRunCommandValidatorTests.cs @@ -11,22 +11,26 @@ public class StartSyncRunCommandValidatorTests : AbstractTestsBase [Fact] public void Happy_path() { - var validator = new StartSyncRunCommandValidator(); + // Arrange + var validator = new Validator(); - var command = new StartSyncRunCommand(SyncRunDTO.SyncRunType.DatawalletVersionUpgrade, 1); - var validationResult = validator.TestValidate(command); + // Act + var validationResult = validator.TestValidate(new StartSyncRunCommand(SyncRunDTO.SyncRunType.DatawalletVersionUpgrade, 1)); + // Assert validationResult.ShouldNotHaveAnyValidationErrors(); } [Fact] public void Fails_when_not_passing_a_SupportedDatawalletVersion() { - var validator = new StartSyncRunCommandValidator(); + // Arrange + var validator = new Validator(); - var command = new StartSyncRunCommand(SyncRunDTO.SyncRunType.DatawalletVersionUpgrade, 0); - var validationResult = validator.TestValidate(command); + // Act + var validationResult = validator.TestValidate(new StartSyncRunCommand(SyncRunDTO.SyncRunType.DatawalletVersionUpgrade, 0)); + // Assert validationResult.ShouldHaveValidationErrorFor(x => x.SupportedDatawalletVersion); } } diff --git a/Modules/Tokens/src/Tokens.Application/AutoMapper/AutoMapperProfile.cs b/Modules/Tokens/src/Tokens.Application/AutoMapper/AutoMapperProfile.cs deleted file mode 100644 index baacfb4481..0000000000 --- a/Modules/Tokens/src/Tokens.Application/AutoMapper/AutoMapperProfile.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Reflection; -using AutoMapper; -using Backbone.BuildingBlocks.Application.AutoMapper; - -namespace Backbone.Modules.Tokens.Application.AutoMapper; - -public class AutoMapperProfile : AutoMapperProfileBase -{ - public AutoMapperProfile() : base(Assembly.GetExecutingAssembly()) { } - - public static IMapper CreateMapper() - { - var profile = new AutoMapperProfile(); - var config = new MapperConfiguration(cfg => cfg.AddProfile(profile)); - var mapper = config.CreateMapper(); - return mapper; - } -} diff --git a/Modules/Tokens/src/Tokens.Application/Extensions/IServiceCollectionExtensions.cs b/Modules/Tokens/src/Tokens.Application/Extensions/IServiceCollectionExtensions.cs index ff7488ec6d..397c597c22 100644 --- a/Modules/Tokens/src/Tokens.Application/Extensions/IServiceCollectionExtensions.cs +++ b/Modules/Tokens/src/Tokens.Application/Extensions/IServiceCollectionExtensions.cs @@ -1,5 +1,4 @@ using Backbone.BuildingBlocks.Application.MediatR; -using Backbone.Modules.Tokens.Application.AutoMapper; using Backbone.Modules.Tokens.Application.Tokens.Commands.CreateToken; using FluentValidation; using Microsoft.Extensions.DependencyInjection; @@ -16,7 +15,6 @@ public static void AddApplication(this IServiceCollection services) .AddOpenBehavior(typeof(RequestValidationBehavior<,>)) .AddOpenBehavior(typeof(QuotaEnforcerBehavior<,>)) ); - services.AddAutoMapper(typeof(AutoMapperProfile).Assembly); - services.AddValidatorsFromAssembly(typeof(CreateTokenCommandValidator).Assembly); + services.AddValidatorsFromAssembly(typeof(Validator).Assembly); } } diff --git a/Modules/Tokens/src/Tokens.Application/Tokens/Commands/CreateToken/CreateTokenCommand.cs b/Modules/Tokens/src/Tokens.Application/Tokens/Commands/CreateToken/CreateTokenCommand.cs index 2d5b4d0d04..06eb76e3cc 100644 --- a/Modules/Tokens/src/Tokens.Application/Tokens/Commands/CreateToken/CreateTokenCommand.cs +++ b/Modules/Tokens/src/Tokens.Application/Tokens/Commands/CreateToken/CreateTokenCommand.cs @@ -1,12 +1,10 @@ -using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.Mapping; using Backbone.BuildingBlocks.Application.Attributes; -using Backbone.Modules.Tokens.Domain.Entities; using MediatR; namespace Backbone.Modules.Tokens.Application.Tokens.Commands.CreateToken; [ApplyQuotasForMetrics("NumberOfTokens")] -public class CreateTokenCommand : IRequest, IMapTo +public class CreateTokenCommand : IRequest { public required byte[] Content { get; set; } public required DateTime ExpiresAt { get; set; } diff --git a/Modules/Tokens/src/Tokens.Application/Tokens/Commands/CreateToken/CreateTokenResponse.cs b/Modules/Tokens/src/Tokens.Application/Tokens/Commands/CreateToken/CreateTokenResponse.cs index 97e638a55a..216e6229ac 100644 --- a/Modules/Tokens/src/Tokens.Application/Tokens/Commands/CreateToken/CreateTokenResponse.cs +++ b/Modules/Tokens/src/Tokens.Application/Tokens/Commands/CreateToken/CreateTokenResponse.cs @@ -1,10 +1,15 @@ -using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.Mapping; using Backbone.Modules.Tokens.Domain.Entities; namespace Backbone.Modules.Tokens.Application.Tokens.Commands.CreateToken; -public class CreateTokenResponse : IMapTo +public class CreateTokenResponse { - public required TokenId Id { get; set; } - public required DateTime CreatedAt { get; set; } + public CreateTokenResponse(Token token) + { + Id = token.Id; + CreatedAt = token.CreatedAt; + } + + public string Id { get; set; } + public DateTime CreatedAt { get; set; } } diff --git a/Modules/Tokens/src/Tokens.Application/Tokens/Commands/CreateToken/Handler.cs b/Modules/Tokens/src/Tokens.Application/Tokens/Commands/CreateToken/Handler.cs index 0fe396604a..9ac7ece9fa 100644 --- a/Modules/Tokens/src/Tokens.Application/Tokens/Commands/CreateToken/Handler.cs +++ b/Modules/Tokens/src/Tokens.Application/Tokens/Commands/CreateToken/Handler.cs @@ -1,4 +1,3 @@ -using AutoMapper; using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.UserContext; using Backbone.Modules.Tokens.Application.Infrastructure.Persistence.Repository; using Backbone.Modules.Tokens.Domain.Entities; @@ -8,14 +7,12 @@ namespace Backbone.Modules.Tokens.Application.Tokens.Commands.CreateToken; public class Handler : IRequestHandler { - private readonly IMapper _mapper; private readonly ITokensRepository _tokensRepository; private readonly IUserContext _userContext; - public Handler(IUserContext userContext, IMapper mapper, ITokensRepository tokensRepository) + public Handler(IUserContext userContext, ITokensRepository tokensRepository) { _userContext = userContext; - _mapper = mapper; _tokensRepository = tokensRepository; } @@ -25,6 +22,6 @@ public async Task Handle(CreateTokenCommand request, Cancel await _tokensRepository.Add(newTokenEntity); - return _mapper.Map(newTokenEntity); + return new CreateTokenResponse(newTokenEntity); } } diff --git a/Modules/Tokens/src/Tokens.Application/Tokens/Commands/CreateToken/CreateTokenCommandValidator.cs b/Modules/Tokens/src/Tokens.Application/Tokens/Commands/CreateToken/Validator.cs similarity index 85% rename from Modules/Tokens/src/Tokens.Application/Tokens/Commands/CreateToken/CreateTokenCommandValidator.cs rename to Modules/Tokens/src/Tokens.Application/Tokens/Commands/CreateToken/Validator.cs index aa99772428..a48fe1cabe 100644 --- a/Modules/Tokens/src/Tokens.Application/Tokens/Commands/CreateToken/CreateTokenCommandValidator.cs +++ b/Modules/Tokens/src/Tokens.Application/Tokens/Commands/CreateToken/Validator.cs @@ -6,11 +6,11 @@ namespace Backbone.Modules.Tokens.Application.Tokens.Commands.CreateToken; -public class CreateTokenCommandValidator : AbstractValidator +public class Validator : AbstractValidator { private static readonly int MAX_CONTENT_LENGTH = 10.Mebibytes(); - public CreateTokenCommandValidator() + public Validator() { RuleFor(t => t.Content) .DetailedNotEmpty() diff --git a/Modules/Tokens/src/Tokens.Application/Tokens/Commands/DeleteTokensOfIdentity/DeleteTokensOfIdentityCommand.cs b/Modules/Tokens/src/Tokens.Application/Tokens/Commands/DeleteTokensOfIdentity/DeleteTokensOfIdentityCommand.cs index 824a2ef493..32b338cae3 100644 --- a/Modules/Tokens/src/Tokens.Application/Tokens/Commands/DeleteTokensOfIdentity/DeleteTokensOfIdentityCommand.cs +++ b/Modules/Tokens/src/Tokens.Application/Tokens/Commands/DeleteTokensOfIdentity/DeleteTokensOfIdentityCommand.cs @@ -1,13 +1,13 @@ -using Backbone.DevelopmentKit.Identity.ValueObjects; -using MediatR; +using MediatR; namespace Backbone.Modules.Tokens.Application.Tokens.Commands.DeleteTokensOfIdentity; + public class DeleteTokensOfIdentityCommand : IRequest { - public DeleteTokensOfIdentityCommand(IdentityAddress identityAddress) + public DeleteTokensOfIdentityCommand(string identityAddress) { IdentityAddress = identityAddress; } - public IdentityAddress IdentityAddress { get; set; } + public string IdentityAddress { get; set; } } diff --git a/Modules/Tokens/src/Tokens.Application/Tokens/Commands/DeleteTokensOfIdentity/Validator.cs b/Modules/Tokens/src/Tokens.Application/Tokens/Commands/DeleteTokensOfIdentity/Validator.cs index fd12040d32..617815fe1c 100644 --- a/Modules/Tokens/src/Tokens.Application/Tokens/Commands/DeleteTokensOfIdentity/Validator.cs +++ b/Modules/Tokens/src/Tokens.Application/Tokens/Commands/DeleteTokensOfIdentity/Validator.cs @@ -1,8 +1,13 @@ -using Backbone.DevelopmentKit.Identity.ValueObjects; +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.DevelopmentKit.Identity.ValueObjects; using FluentValidation; namespace Backbone.Modules.Tokens.Application.Tokens.Commands.DeleteTokensOfIdentity; + public class Validator : AbstractValidator { - public Validator() => RuleFor(x => x.IdentityAddress).Must(x => IdentityAddress.IsValid(x)); + public Validator() + { + RuleFor(x => x.IdentityAddress).ValidId(); + } } diff --git a/Modules/Tokens/src/Tokens.Application/Tokens/DTOs/TokenDTO.cs b/Modules/Tokens/src/Tokens.Application/Tokens/DTOs/TokenDTO.cs index eaf6f11b41..47556f71c2 100644 --- a/Modules/Tokens/src/Tokens.Application/Tokens/DTOs/TokenDTO.cs +++ b/Modules/Tokens/src/Tokens.Application/Tokens/DTOs/TokenDTO.cs @@ -1,18 +1,26 @@ -using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.Mapping; -using Backbone.DevelopmentKit.Identity.ValueObjects; using Backbone.Modules.Tokens.Domain.Entities; namespace Backbone.Modules.Tokens.Application.Tokens.DTOs; -public class TokenDTO : IMapTo +public class TokenDTO { - public required TokenId Id { get; set; } + public TokenDTO(Token token) + { + Id = token.Id; + CreatedBy = token.CreatedBy; + CreatedByDevice = token.CreatedByDevice; + CreatedAt = token.CreatedAt; + ExpiresAt = token.ExpiresAt; + Content = token.Content; + } - public required IdentityAddress CreatedBy { get; set; } - public required DeviceId CreatedByDevice { get; set; } + public string Id { get; set; } - public required DateTime CreatedAt { get; set; } - public required DateTime ExpiresAt { get; set; } + public string CreatedBy { get; set; } + public string CreatedByDevice { get; set; } - public required byte[] Content { get; set; } + public DateTime CreatedAt { get; set; } + public DateTime ExpiresAt { get; set; } + + public byte[] Content { get; set; } } diff --git a/Modules/Tokens/src/Tokens.Application/Tokens/Queries/GetToken/GetTokenQuery.cs b/Modules/Tokens/src/Tokens.Application/Tokens/Queries/GetToken/GetTokenQuery.cs index e499be2212..fb4ed2cb77 100644 --- a/Modules/Tokens/src/Tokens.Application/Tokens/Queries/GetToken/GetTokenQuery.cs +++ b/Modules/Tokens/src/Tokens.Application/Tokens/Queries/GetToken/GetTokenQuery.cs @@ -1,10 +1,9 @@ using Backbone.Modules.Tokens.Application.Tokens.DTOs; -using Backbone.Modules.Tokens.Domain.Entities; using MediatR; namespace Backbone.Modules.Tokens.Application.Tokens.Queries.GetToken; public class GetTokenQuery : IRequest { - public required TokenId Id { get; set; } + public required string Id { get; set; } } diff --git a/Modules/Tokens/src/Tokens.Application/Tokens/Queries/GetToken/Handler.cs b/Modules/Tokens/src/Tokens.Application/Tokens/Queries/GetToken/Handler.cs index d145dae4ff..0f3438808b 100644 --- a/Modules/Tokens/src/Tokens.Application/Tokens/Queries/GetToken/Handler.cs +++ b/Modules/Tokens/src/Tokens.Application/Tokens/Queries/GetToken/Handler.cs @@ -1,24 +1,22 @@ -using AutoMapper; using Backbone.Modules.Tokens.Application.Infrastructure.Persistence.Repository; using Backbone.Modules.Tokens.Application.Tokens.DTOs; +using Backbone.Modules.Tokens.Domain.Entities; using MediatR; namespace Backbone.Modules.Tokens.Application.Tokens.Queries.GetToken; public class Handler : IRequestHandler { - private readonly IMapper _mapper; private readonly ITokensRepository _tokensRepository; - public Handler(IMapper mapper, ITokensRepository tokensRepository) + public Handler(ITokensRepository tokensRepository) { - _mapper = mapper; _tokensRepository = tokensRepository; } public async Task Handle(GetTokenQuery request, CancellationToken cancellationToken) { - var token = await _tokensRepository.Find(request.Id); - return _mapper.Map(token); + var token = await _tokensRepository.Find(TokenId.Parse(request.Id)); + return new TokenDTO(token); } } diff --git a/Modules/Tokens/src/Tokens.Application/Tokens/Queries/GetToken/Validator.cs b/Modules/Tokens/src/Tokens.Application/Tokens/Queries/GetToken/Validator.cs new file mode 100644 index 0000000000..107c81664b --- /dev/null +++ b/Modules/Tokens/src/Tokens.Application/Tokens/Queries/GetToken/Validator.cs @@ -0,0 +1,13 @@ +using Backbone.BuildingBlocks.Application.Extensions; +using Backbone.Modules.Tokens.Domain.Entities; +using FluentValidation; + +namespace Backbone.Modules.Tokens.Application.Tokens.Queries.GetToken; + +public class Validator : AbstractValidator +{ + public Validator() + { + RuleFor(x => x.Id).ValidId(); + } +} diff --git a/Modules/Tokens/src/Tokens.Application/Tokens/Queries/ListTokens/Handler.cs b/Modules/Tokens/src/Tokens.Application/Tokens/Queries/ListTokens/Handler.cs index 72e1016cae..2d377db583 100644 --- a/Modules/Tokens/src/Tokens.Application/Tokens/Queries/ListTokens/Handler.cs +++ b/Modules/Tokens/src/Tokens.Application/Tokens/Queries/ListTokens/Handler.cs @@ -1,8 +1,7 @@ -using AutoMapper; using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.UserContext; using Backbone.DevelopmentKit.Identity.ValueObjects; using Backbone.Modules.Tokens.Application.Infrastructure.Persistence.Repository; -using Backbone.Modules.Tokens.Application.Tokens.DTOs; +using Backbone.Modules.Tokens.Domain.Entities; using MediatR; namespace Backbone.Modules.Tokens.Application.Tokens.Queries.ListTokens; @@ -10,22 +9,20 @@ namespace Backbone.Modules.Tokens.Application.Tokens.Queries.ListTokens; public class Handler : IRequestHandler { private readonly ITokensRepository _tokensRepository; - private readonly IMapper _mapper; private readonly IdentityAddress _activeIdentity; - public Handler(ITokensRepository tokensRepository, IUserContext userContext, IMapper mapper) + public Handler(ITokensRepository tokensRepository, IUserContext userContext) { _tokensRepository = tokensRepository; - _mapper = mapper; _activeIdentity = userContext.GetAddress(); } public async Task Handle(ListTokensQuery request, CancellationToken cancellationToken) { var dbPaginationResult = request.Ids.Any() - ? await _tokensRepository.FindAllWithIds(request.Ids, request.PaginationFilter, cancellationToken) + ? await _tokensRepository.FindAllWithIds(request.Ids.Select(TokenId.Parse), request.PaginationFilter, cancellationToken) : await _tokensRepository.FindAllOfOwner(_activeIdentity, request.PaginationFilter, cancellationToken); - return new ListTokensResponse(_mapper.Map>(dbPaginationResult.ItemsOnPage), request.PaginationFilter, dbPaginationResult.TotalNumberOfItems); + return new ListTokensResponse(dbPaginationResult, request.PaginationFilter); } } diff --git a/Modules/Tokens/src/Tokens.Application/Tokens/Queries/ListTokens/ListTokensQuery.cs b/Modules/Tokens/src/Tokens.Application/Tokens/Queries/ListTokens/ListTokensQuery.cs index bdd92a8071..df912053b4 100644 --- a/Modules/Tokens/src/Tokens.Application/Tokens/Queries/ListTokens/ListTokensQuery.cs +++ b/Modules/Tokens/src/Tokens.Application/Tokens/Queries/ListTokens/ListTokensQuery.cs @@ -1,17 +1,16 @@ using Backbone.BuildingBlocks.Application.Pagination; -using Backbone.Modules.Tokens.Domain.Entities; using MediatR; namespace Backbone.Modules.Tokens.Application.Tokens.Queries.ListTokens; public class ListTokensQuery : IRequest { - public ListTokensQuery(PaginationFilter paginationFilter, IEnumerable ids) + public ListTokensQuery(PaginationFilter paginationFilter, IEnumerable ids) { PaginationFilter = paginationFilter; Ids = ids; } public PaginationFilter PaginationFilter { get; set; } - public IEnumerable Ids { get; set; } + public IEnumerable Ids { get; set; } } diff --git a/Modules/Tokens/src/Tokens.Application/Tokens/Queries/ListTokens/ListTokensResponse.cs b/Modules/Tokens/src/Tokens.Application/Tokens/Queries/ListTokens/ListTokensResponse.cs index 43b5962327..6e1bdc9393 100644 --- a/Modules/Tokens/src/Tokens.Application/Tokens/Queries/ListTokens/ListTokensResponse.cs +++ b/Modules/Tokens/src/Tokens.Application/Tokens/Queries/ListTokens/ListTokensResponse.cs @@ -1,9 +1,14 @@ +using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.Persistence.Database; using Backbone.BuildingBlocks.Application.Pagination; using Backbone.Modules.Tokens.Application.Tokens.DTOs; +using Backbone.Modules.Tokens.Domain.Entities; namespace Backbone.Modules.Tokens.Application.Tokens.Queries.ListTokens; public class ListTokensResponse : PagedResponse { - public ListTokensResponse(IEnumerable items, PaginationFilter previousPaginationFilter, int totalRecords) : base(items, previousPaginationFilter, totalRecords) { } + public ListTokensResponse(DbPaginationResult dbPaginationResult, PaginationFilter previousPaginationFilter) : base(dbPaginationResult.ItemsOnPage.Select(t => new TokenDTO(t)), + previousPaginationFilter, dbPaginationResult.TotalNumberOfItems) + { + } } diff --git a/Modules/Tokens/src/Tokens.Application/Tokens/Queries/ListTokens/ListTokensQueryValidator.cs b/Modules/Tokens/src/Tokens.Application/Tokens/Queries/ListTokens/Validator.cs similarity index 73% rename from Modules/Tokens/src/Tokens.Application/Tokens/Queries/ListTokens/ListTokensQueryValidator.cs rename to Modules/Tokens/src/Tokens.Application/Tokens/Queries/ListTokens/Validator.cs index 30f9420811..eb222c7408 100644 --- a/Modules/Tokens/src/Tokens.Application/Tokens/Queries/ListTokens/ListTokensQueryValidator.cs +++ b/Modules/Tokens/src/Tokens.Application/Tokens/Queries/ListTokens/Validator.cs @@ -1,15 +1,18 @@ using Backbone.BuildingBlocks.Application.Abstractions.Exceptions; +using Backbone.BuildingBlocks.Application.Extensions; using Backbone.BuildingBlocks.Application.Pagination; +using Backbone.Modules.Tokens.Domain.Entities; using FluentValidation; namespace Backbone.Modules.Tokens.Application.Tokens.Queries.ListTokens; // ReSharper disable once UnusedMember.Global -public class ListTokensQueryValidator : AbstractValidator +public class Validator : AbstractValidator { - public ListTokensQueryValidator() + public Validator() { RuleFor(t => t.PaginationFilter).SetValidator(new PaginationFilterValidator()).When(t => t != null); + RuleForEach(x => x.Ids).ValidId(); } } diff --git a/Modules/Tokens/src/Tokens.Application/Tokens/RequestHandlerBase.cs b/Modules/Tokens/src/Tokens.Application/Tokens/RequestHandlerBase.cs deleted file mode 100644 index 94a1ec66c0..0000000000 --- a/Modules/Tokens/src/Tokens.Application/Tokens/RequestHandlerBase.cs +++ /dev/null @@ -1,20 +0,0 @@ -using AutoMapper; -using Backbone.BuildingBlocks.Application.Abstractions.Infrastructure.UserContext; -using Backbone.DevelopmentKit.Identity.ValueObjects; -using MediatR; - -namespace Backbone.Modules.Tokens.Application.Tokens; - -public abstract class RequestHandlerBase : IRequestHandler where TRequest : IRequest -{ - protected readonly IdentityAddress _activeIdentity; - protected readonly IMapper _mapper; - - protected RequestHandlerBase(IUserContext userContext, IMapper mapper) - { - _mapper = mapper; - _activeIdentity = userContext.GetAddress(); - } - - public abstract Task Handle(TRequest request, CancellationToken cancellationToken); -} diff --git a/Modules/Tokens/src/Tokens.ConsumerApi/Controllers/TokensController.cs b/Modules/Tokens/src/Tokens.ConsumerApi/Controllers/TokensController.cs index c039a705bf..88f9654b8c 100644 --- a/Modules/Tokens/src/Tokens.ConsumerApi/Controllers/TokensController.cs +++ b/Modules/Tokens/src/Tokens.ConsumerApi/Controllers/TokensController.cs @@ -8,7 +8,6 @@ using Backbone.Modules.Tokens.Application.Tokens.DTOs; using Backbone.Modules.Tokens.Application.Tokens.Queries.GetToken; using Backbone.Modules.Tokens.Application.Tokens.Queries.ListTokens; -using Backbone.Modules.Tokens.Domain.Entities; using MediatR; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; @@ -41,7 +40,7 @@ public async Task CreateToken(CreateTokenCommand request, Cancell [ProducesResponseType(typeof(HttpResponseEnvelopeResult), StatusCodes.Status200OK)] [ProducesError(StatusCodes.Status404NotFound)] [AllowAnonymous] - public async Task GetToken([FromRoute] TokenId id, CancellationToken cancellationToken) + public async Task GetToken([FromRoute] string id, CancellationToken cancellationToken) { var response = await _mediator.Send(new GetTokenQuery { Id = id }, cancellationToken); return Ok(response); @@ -50,7 +49,7 @@ public async Task GetToken([FromRoute] TokenId id, CancellationTo [HttpGet] [ProducesResponseType(typeof(PagedHttpResponseEnvelope), StatusCodes.Status200OK)] public async Task ListTokens([FromQuery] PaginationFilter paginationFilter, - [FromQuery] IEnumerable ids, CancellationToken cancellationToken) + [FromQuery] IEnumerable ids, CancellationToken cancellationToken) { paginationFilter.PageSize ??= _options.Pagination.DefaultPageSize; diff --git a/Modules/Tokens/test/Tokens.Application.Tests/Tests/AutoMapper/AutoMapperProfileTests.cs b/Modules/Tokens/test/Tokens.Application.Tests/Tests/AutoMapper/AutoMapperProfileTests.cs deleted file mode 100644 index e66c08ea23..0000000000 --- a/Modules/Tokens/test/Tokens.Application.Tests/Tests/AutoMapper/AutoMapperProfileTests.cs +++ /dev/null @@ -1,19 +0,0 @@ -using AutoMapper; -using Backbone.Modules.Tokens.Application.AutoMapper; -using Backbone.UnitTestTools.BaseClasses; -using Xunit; - -namespace Backbone.Modules.Tokens.Application.Tests.Tests.AutoMapper; - -public class AutoMapperProfileTests : AbstractTestsBase -{ - [Fact] - public void ProfileIsValid() - { - // Arrange - var configuration = new MapperConfiguration(cfg => cfg.AddProfile()); - - // Act & Assert - configuration.AssertConfigurationIsValid(); - } -}