Skip to content

Commit ac2acad

Browse files
committed
Tests
1 parent 605307a commit ac2acad

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

src/Http/Http.Abstractions/test/Validation/ValidatableTypeInfoTests.cs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ public class ValidatableTypeInfoTests
1515
public async Task Validate_ValidatesComplexType_WithNestedProperties()
1616
{
1717
// Arrange
18+
List<ValidationErrorContext> validationErrors = [];
19+
1820
var personType = new TestValidatableTypeInfo(
1921
typeof(Person),
2022
[
@@ -52,6 +54,8 @@ [new RequiredAttribute()])
5254
ValidationContext = new ValidationContext(personWithMissingRequiredFields)
5355
};
5456

57+
context.OnValidationError += validationErrors.Add;
58+
5559
// Act
5660
await personType.ValidateAsync(personWithMissingRequiredFields, context, default);
5761

@@ -78,12 +82,43 @@ [new RequiredAttribute()])
7882
Assert.Equal("Address.City", kvp.Key);
7983
Assert.Equal("The City field is required.", kvp.Value.First());
8084
});
85+
86+
Assert.Collection(validationErrors,
87+
context =>
88+
{
89+
Assert.Equal("Name", context.Name);
90+
Assert.Equal("Name", context.Path);
91+
Assert.Equal("The Name field is required.", context.Errors.Single());
92+
Assert.Same(context.Container, personWithMissingRequiredFields);
93+
},
94+
context =>
95+
{
96+
Assert.Equal("Age", context.Name);
97+
Assert.Equal("Age", context.Path);
98+
Assert.Equal("The field Age must be between 0 and 120.", context.Errors.Single());
99+
Assert.Same(context.Container, personWithMissingRequiredFields);
100+
},
101+
context =>
102+
{
103+
Assert.Equal("Street", context.Name);
104+
Assert.Equal("Address.Street", context.Path);
105+
Assert.Equal("The Street field is required.", context.Errors.Single());
106+
Assert.Same(context.Container, personWithMissingRequiredFields.Address);
107+
},
108+
context =>
109+
{
110+
Assert.Equal("City", context.Name);
111+
Assert.Equal("Address.City", context.Path);
112+
Assert.Equal("The City field is required.", context.Errors.Single());
113+
Assert.Same(context.Container, personWithMissingRequiredFields.Address);
114+
});
81115
}
82116

83117
[Fact]
84118
public async Task Validate_HandlesIValidatableObject_Implementation()
85119
{
86120
// Arrange
121+
var validationErrors = new List<ValidationErrorContext>();
87122
var employeeType = new TestValidatableTypeInfo(
88123
typeof(Employee),
89124
[
@@ -110,6 +145,8 @@ [new RequiredAttribute()]),
110145
ValidationContext = new ValidationContext(employee)
111146
};
112147

148+
context.OnValidationError += validationErrors.Add;
149+
113150
// Act
114151
await employeeType.ValidateAsync(employee, context, default);
115152

@@ -118,6 +155,12 @@ [new RequiredAttribute()]),
118155
var error = Assert.Single(context.ValidationErrors);
119156
Assert.Equal("Salary", error.Key);
120157
Assert.Equal("Salary must be a positive value.", error.Value.First());
158+
159+
var errorContext = Assert.Single(validationErrors);
160+
Assert.Equal("Salary", errorContext.Name);
161+
Assert.Equal("Salary", errorContext.Path);
162+
Assert.Equal("Salary must be a positive value.", errorContext.Errors.Single());
163+
Assert.Same(errorContext.Container, employee);
121164
}
122165

123166
[Fact]

src/Validation/src/ValidationErrorContext.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
using System.Diagnostics;
5+
46
namespace Microsoft.Extensions.Validation;
57

68
/// <summary>
79
/// Represents the context of a validation error.
810
/// </summary>
11+
[DebuggerDisplay($"{{{nameof(GetDebuggerDisplay)}(),nq}}")]
912
public readonly struct ValidationErrorContext
1013
{
1114
/// <summary>
@@ -27,4 +30,9 @@ public readonly struct ValidationErrorContext
2730
/// Gets a reference to the container object of the validated property.
2831
/// </summary>
2932
public required object? Container { get; init; }
33+
34+
private string GetDebuggerDisplay()
35+
{
36+
return $"{Path}: {string.Join(",", Errors)}";
37+
}
3038
}

0 commit comments

Comments
 (0)