diff --git a/src/Digdir.Domain.Dialogporten.Application/Common/Extensions/Enumerables/General.cs b/src/Digdir.Domain.Dialogporten.Application/Common/Extensions/Enumerables/General.cs index 7b272afe7..23c5ca821 100644 --- a/src/Digdir.Domain.Dialogporten.Application/Common/Extensions/Enumerables/General.cs +++ b/src/Digdir.Domain.Dialogporten.Application/Common/Extensions/Enumerables/General.cs @@ -6,4 +6,6 @@ namespace Digdir.Domain.Dialogporten.Application.Common.Extensions.Enumerables; internal static class General { internal static bool IsNullOrEmpty([NotNullWhen(false)] this ICollection? values) => values is null || values.Count == 0; + + internal static IEnumerable EmptyIfNull(this IEnumerable? enumerable) => enumerable ?? Enumerable.Empty(); } diff --git a/src/Digdir.Domain.Dialogporten.Application/Common/Extensions/FluentValidation/FluentValidation_Enumerable_Extensions.cs b/src/Digdir.Domain.Dialogporten.Application/Common/Extensions/FluentValidation/FluentValidation_Enumerable_Extensions.cs index f459459f8..0d41e7e56 100644 --- a/src/Digdir.Domain.Dialogporten.Application/Common/Extensions/FluentValidation/FluentValidation_Enumerable_Extensions.cs +++ b/src/Digdir.Domain.Dialogporten.Application/Common/Extensions/FluentValidation/FluentValidation_Enumerable_Extensions.cs @@ -1,6 +1,7 @@ using FluentValidation; using FluentValidation.Internal; using System.Linq.Expressions; +using Digdir.Domain.Dialogporten.Application.Common.Extensions.Enumerables; namespace Digdir.Domain.Dialogporten.Application.Common.Extensions.FluentValidation; @@ -14,6 +15,11 @@ public static IRuleBuilderOptions> UniqueBy { + if (enumerable is null) + { + return true; + } + comparer ??= EqualityComparer.Default; var duplicateKeys = enumerable .Select(keySelector) @@ -34,7 +40,7 @@ public static IRuleBuilderOptions IsIn principalKeySelector, IEqualityComparer? comparer = null) { - return ruleBuilder.Must((parrent, dependent, ctx) => + return ruleBuilder.Must((parent, dependent, ctx) => { comparer ??= EqualityComparer.Default; var dependentKey = dependentKeySelector(dependent); @@ -45,7 +51,8 @@ public static IRuleBuilderOptions IsIn comparer .Equals(principalKeySelector(principal), dependentKey)); }) diff --git a/src/Digdir.Domain.Dialogporten.Application/Externals/IDialogDbContext.cs b/src/Digdir.Domain.Dialogporten.Application/Externals/IDialogDbContext.cs index 7a7af6066..fd6cbb3eb 100644 --- a/src/Digdir.Domain.Dialogporten.Application/Externals/IDialogDbContext.cs +++ b/src/Digdir.Domain.Dialogporten.Application/Externals/IDialogDbContext.cs @@ -4,7 +4,6 @@ using Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Elements; using Digdir.Domain.Dialogporten.Domain.Outboxes; using Digdir.Library.Entity.Abstractions.Features.Identifiable; -using Digdir.Library.Entity.Abstractions.Features.Versionable; using Microsoft.EntityFrameworkCore; using System.Linq.Expressions; diff --git a/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Create/CreateDialogCommandValidator.cs b/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Create/CreateDialogCommandValidator.cs index aa866fbea..a43f41f44 100644 --- a/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Create/CreateDialogCommandValidator.cs +++ b/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Create/CreateDialogCommandValidator.cs @@ -1,4 +1,5 @@ -using Digdir.Domain.Dialogporten.Application.Common.Extensions.FluentValidation; +using Digdir.Domain.Dialogporten.Application.Common.Extensions.Enumerables; +using Digdir.Domain.Dialogporten.Application.Common.Extensions.FluentValidation; using Digdir.Domain.Dialogporten.Application.Features.V1.Common.Localizations; using Digdir.Domain.Dialogporten.Domain.Common; using Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Actions; @@ -63,33 +64,31 @@ public CreateDialogCommandValidator( .IsInEnum(); RuleFor(x => x.Content) - .NotNull() - .DependentRules(() => - { - RuleFor(x => x.Content) - .UniqueBy(x => x.Type) - .Must(content => DialogContentType.RequiredTypes - .All(requiredContent => content - .Select(x => x.Type) - .Contains(requiredContent))) - .WithMessage("Dialog must contain the following content: " + - $"[{string.Join(", ", DialogContentType.RequiredTypes)}].") - .ForEach(x => x.SetValidator(contentValidator)); - }); + .UniqueBy(x => x.Type) + .Must(content => DialogContentType.RequiredTypes + .All(requiredContent => content + .EmptyIfNull() + .Select(x => x.Type) + .Contains(requiredContent))) + .WithMessage("Dialog must contain the following content: " + + $"[{string.Join(", ", DialogContentType.RequiredTypes)}].") + .ForEach(x => x.SetValidator(contentValidator)); - RuleForEach(x => x.SearchTags) - .SetValidator(searchTagValidator); RuleFor(x => x.SearchTags) - .UniqueBy(x => x.Value, StringComparer.InvariantCultureIgnoreCase); + .UniqueBy(x => x.Value, StringComparer.InvariantCultureIgnoreCase) + .ForEach(x => x.SetValidator(searchTagValidator)); RuleFor(x => x.GuiActions) .Must(x => x + .EmptyIfNull() .Count(x => x.Priority == DialogGuiActionPriority.Values.Primary) <= 1) .WithMessage("Only one primary GUI action is allowed.") .Must(x => x + .EmptyIfNull() .Count(x => x.Priority == DialogGuiActionPriority.Values.Secondary) <= 1) .WithMessage("Only one secondary GUI action is allowed.") .Must(x => x + .EmptyIfNull() .Count(x => x.Priority == DialogGuiActionPriority.Values.Tertiary) <= 5) .WithMessage("Only five tertiary GUI actions are allowed.") .ForEach(x => x.SetValidator(guiActionValidator)); diff --git a/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Update/UpdateDialogCommandValidator.cs b/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Update/UpdateDialogCommandValidator.cs index 2510b8533..28bf72f82 100644 --- a/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Update/UpdateDialogCommandValidator.cs +++ b/src/Digdir.Domain.Dialogporten.Application/Features/V1/ServiceOwner/Dialogs/Commands/Update/UpdateDialogCommandValidator.cs @@ -1,4 +1,5 @@ -using Digdir.Domain.Dialogporten.Application.Common.Extensions.FluentValidation; +using Digdir.Domain.Dialogporten.Application.Common.Extensions.Enumerables; +using Digdir.Domain.Dialogporten.Application.Common.Extensions.FluentValidation; using Digdir.Domain.Dialogporten.Application.Features.V1.Common.Localizations; using Digdir.Domain.Dialogporten.Domain.Common; using Digdir.Domain.Dialogporten.Domain.Dialogs.Entities.Actions; @@ -56,19 +57,15 @@ public UpdateDialogDtoValidator( .IsInEnum(); RuleFor(x => x.Content) - .NotNull() - .DependentRules(() => - { - RuleFor(x => x.Content) - .UniqueBy(x => x.Type) - .Must(content => DialogContentType.RequiredTypes - .All(requiredContent => content - .Select(x => x.Type) - .Contains(requiredContent))) - .WithMessage("Dialog must contain the following content: " + - $"[{string.Join(", ", DialogContentType.RequiredTypes)}].") - .ForEach(x => x.SetValidator(contentValidator)); - }); + .UniqueBy(x => x.Type) + .Must(content => DialogContentType.RequiredTypes + .All(requiredContent => content + .EmptyIfNull() + .Select(x => x.Type) + .Contains(requiredContent))) + .WithMessage("Dialog must contain the following content: " + + $"[{string.Join(", ", DialogContentType.RequiredTypes)}].") + .ForEach(x => x.SetValidator(contentValidator)); RuleFor(x => x.SearchTags) .UniqueBy(x => x.Value, StringComparer.InvariantCultureIgnoreCase) @@ -76,12 +73,15 @@ public UpdateDialogDtoValidator( RuleFor(x => x.GuiActions) .Must(x => x + .EmptyIfNull() .Count(x => x.Priority == DialogGuiActionPriority.Values.Primary) <= 1) .WithMessage("Only one primary GUI action is allowed.") .Must(x => x + .EmptyIfNull() .Count(x => x.Priority == DialogGuiActionPriority.Values.Secondary) <= 1) .WithMessage("Only one secondary GUI action is allowed.") .Must(x => x + .EmptyIfNull() .Count(x => x.Priority == DialogGuiActionPriority.Values.Tertiary) <= 5) .WithMessage("Only five tertiary GUI actions are allowed.") .UniqueBy(x => x.Id)