Skip to content

Commit

Permalink
fix: Add null checks, set lists to empty if null (#434)
Browse files Browse the repository at this point in the history
  • Loading branch information
oskogstad authored Feb 13, 2024
1 parent 4ae007d commit f264aec
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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<T> EmptyIfNull<T>(this IEnumerable<T>? enumerable) => enumerable ?? Enumerable.Empty<T>();
}
Original file line number Diff line number Diff line change
@@ -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;

Expand All @@ -14,6 +15,11 @@ public static IRuleBuilderOptions<T, IEnumerable<TProperty>> UniqueBy<T, TProper
{
return ruleBuilder.Must((parent, enumerable, ctx) =>
{
if (enumerable is null)
{
return true;
}
comparer ??= EqualityComparer<TKey>.Default;
var duplicateKeys = enumerable
.Select(keySelector)
Expand All @@ -34,7 +40,7 @@ public static IRuleBuilderOptions<T, TDependent> IsIn<T, TDependent, TPrincipal,
Func<TPrincipal, TKey> principalKeySelector,
IEqualityComparer<TKey>? comparer = null)
{
return ruleBuilder.Must((parrent, dependent, ctx) =>
return ruleBuilder.Must((parent, dependent, ctx) =>
{
comparer ??= EqualityComparer<TKey>.Default;
var dependentKey = dependentKeySelector(dependent);
Expand All @@ -45,7 +51,8 @@ public static IRuleBuilderOptions<T, TDependent> IsIn<T, TDependent, TPrincipal,
.AppendArgument("DependentKey", dependentKey)
.AppendArgument("PrincipalName", name);
return dependentKey is null ||
func(parrent)
func(parent)
.EmptyIfNull()
.Any(principal => comparer
.Equals(principalKeySelector(principal), dependentKey));
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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));
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -56,32 +57,31 @@ 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)
.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.")
.UniqueBy(x => x.Id)
Expand Down

0 comments on commit f264aec

Please sign in to comment.