diff --git a/src/Faithlife.DataAnnotations/ValidateObjectAttribute.cs b/src/Faithlife.DataAnnotations/ValidateObjectAttribute.cs index dffc930..609368a 100644 --- a/src/Faithlife.DataAnnotations/ValidateObjectAttribute.cs +++ b/src/Faithlife.DataAnnotations/ValidateObjectAttribute.cs @@ -21,6 +21,6 @@ public sealed class ValidateObjectAttribute : ValidationAttribute var innerErrorMessage = string.Join(" ", validationResults.Select(x => x.ErrorMessage).Where(x => x is not null)); return new ValidationResult( errorMessage: $"{FormatErrorMessage(validationContext.DisplayName)}{(innerErrorMessage.Length == 0 ? "" : $" ({innerErrorMessage})")}", - memberNames: validationContext.MemberName is { } memberName ? new[] { memberName } : null); + memberNames: validationContext.MemberName is { } memberName ? [memberName] : null); } } diff --git a/tests/Faithlife.DataAnnotations.Tests/ValidateObjectAttributeTests.cs b/tests/Faithlife.DataAnnotations.Tests/ValidateObjectAttributeTests.cs new file mode 100644 index 0000000..f52fd15 --- /dev/null +++ b/tests/Faithlife.DataAnnotations.Tests/ValidateObjectAttributeTests.cs @@ -0,0 +1,36 @@ +using System.ComponentModel.DataAnnotations; +using NUnit.Framework; + +namespace Faithlife.DataAnnotations.Tests; + +public sealed class ValidateObjectAttributeTests +{ + [Test] + public void ValidateRecursive() + { + var invalid = new ValidatableDto(); + var validatable = new ValidatableDto { Required = "x", Validatable = invalid }; + + var results = ValidatorUtility.GetValidationResults(validatable); + Assert.That(results.Single().MemberNames.Single(), Is.EqualTo(nameof(ValidatableDto.Validatable))); + Assert.That(results.Single().ErrorMessage, Is.EqualTo("The field Validatable is invalid. (The Required field is required.)")); + + validatable.Validatable = new ValidatableDto { Required = "x", Validatable = invalid }; + results = ValidatorUtility.GetValidationResults(validatable); + Assert.That(results.Single().MemberNames.Single(), Is.EqualTo(nameof(ValidatableDto.Validatable))); + Assert.That(results.Single().ErrorMessage, Is.EqualTo("The field Validatable is invalid. (The field Validatable is invalid. (The Required field is required.))")); + + validatable.Validatable.Validatable = new ValidatableDto { Required = "x" }; + results = ValidatorUtility.GetValidationResults(validatable); + Assert.That(results, Is.Empty); + } + + private sealed class ValidatableDto + { + [Required] + public string? Required { get; set; } + + [ValidateObject] + public ValidatableDto? Validatable { get; set; } + } +} diff --git a/tests/Faithlife.DataAnnotations.Tests/ValidatorTests.cs b/tests/Faithlife.DataAnnotations.Tests/ValidatorTests.cs index 8eaf976..f62a8a2 100644 --- a/tests/Faithlife.DataAnnotations.Tests/ValidatorTests.cs +++ b/tests/Faithlife.DataAnnotations.Tests/ValidatorTests.cs @@ -27,50 +27,35 @@ public void ValidateRequired() var validatable = new ValidatableDto(); var results = ValidatorUtility.GetValidationResults(validatable); - Assert.That(results.Single().MemberNames.Single(), Is.EqualTo(nameof(ValidatableDto.Required))); + AssertFieldIsRequired(results.Single()); var exception = Assert.Throws(() => ValidatorUtility.Validate(validatable)); - Assert.That(exception!.ValidationResult.MemberNames.Single(), Is.EqualTo(nameof(ValidatableDto.Required))); + AssertFieldIsRequired(exception!.ValidationResult); validatable.Required = ""; results = ValidatorUtility.GetValidationResults(validatable); - Assert.That(results.Single().MemberNames.Single(), Is.EqualTo(nameof(ValidatableDto.Required))); + AssertFieldIsRequired(results.Single()); Assert.Throws(() => ValidatorUtility.Validate(validatable)); validatable.Required = " "; results = ValidatorUtility.GetValidationResults(validatable); - Assert.That(results.Single().MemberNames.Single(), Is.EqualTo(nameof(ValidatableDto.Required))); + AssertFieldIsRequired(results.Single()); Assert.Throws(() => ValidatorUtility.Validate(validatable)); validatable.Required = "x"; results = ValidatorUtility.GetValidationResults(validatable); Assert.That(results, Is.Empty); ValidatorUtility.Validate(validatable); - } - - [Test] - public void ValidateRecursive() - { - var invalid = new ValidatableDto(); - var validatable = new ValidatableDto { Required = "x", Validatable = invalid }; - - var results = ValidatorUtility.GetValidationResults(validatable); - Assert.That(results.Single().MemberNames.Single(), Is.EqualTo(nameof(ValidatableDto.Validatable))); - validatable.Validatable = new ValidatableDto { Required = "x", Validatable = invalid }; - results = ValidatorUtility.GetValidationResults(validatable); - Assert.That(results.Single().MemberNames.Single(), Is.EqualTo(nameof(ValidatableDto.Validatable))); - - validatable.Validatable.Validatable = new ValidatableDto { Required = "x" }; - results = ValidatorUtility.GetValidationResults(validatable); - Assert.That(results, Is.Empty); + void AssertFieldIsRequired(ValidationResult result) + { + Assert.That(result.MemberNames.Single(), Is.EqualTo(nameof(ValidatableDto.Required))); + Assert.That(result.ErrorMessage, Is.EqualTo("The Required field is required.")); + } } private sealed class ValidatableDto { [Required] public string? Required { get; set; } - - [ValidateObject] - public ValidatableDto? Validatable { get; set; } } }