Skip to content

Commit 2e46d78

Browse files
committed
Enhance validation endpoint tests
Added a new test method to validate the ProblemDetails service with a timestamp extension.
1 parent 5288c3a commit 2e46d78

File tree

1 file changed

+65
-3
lines changed

1 file changed

+65
-3
lines changed

src/Http/Http.Extensions/test/ValidationFilterEndpointFactoryTests.cs

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
namespace Microsoft.AspNetCore.Http.Extensions.Tests;
1616

17-
public class ValidationEndpointFilterFactoryTests
17+
public class ValidationEndpointFilterFactoryTests : LoggedTest
1818
{
1919
[Fact]
2020
public async Task GetHttpValidationProblemDetailsWhenProblemDetailsServiceNotRegistered()
@@ -26,7 +26,7 @@ public async Task GetHttpValidationProblemDetailsWhenProblemDetailsServiceNotReg
2626
var builder = new DefaultEndpointRouteBuilder(new ApplicationBuilder(serviceProvider));
2727

2828
// Act - Create one endpoint with validation
29-
builder.MapGet("test-enabled", ([Range(5, 10)] int param) => "Validation enabled here.");
29+
builder.MapGet("validation-test", ([Range(5, 10)] int param) => "Validation enabled here.");
3030

3131
// Build the endpoints
3232
var dataSource = Assert.Single(builder.DataSources);
@@ -73,7 +73,7 @@ public async Task UseProblemDetailsServiceWhenAddedInServiceCollection()
7373
var builder = new DefaultEndpointRouteBuilder(new ApplicationBuilder(serviceProvider));
7474

7575
// Act - Create one endpoint with validation
76-
builder.MapGet("test-enabled", ([Range(5, 10)] int param) => "Validation enabled here.");
76+
builder.MapGet("validation-test", ([Range(5, 10)] int param) => "Validation enabled here.");
7777

7878
// Build the endpoints
7979
var dataSource = Assert.Single(builder.DataSources);
@@ -101,6 +101,7 @@ public async Task UseProblemDetailsServiceWhenAddedInServiceCollection()
101101
ms.Seek(0, SeekOrigin.Begin);
102102
var problemDetails = await JsonSerializer.DeserializeAsync<ProblemDetails>(ms, JsonSerializerOptions.Web);
103103

104+
// Check if the response is an actual ProblemDetails object
104105
Assert.Equal("https://tools.ietf.org/html/rfc9110#section-15.5.1", problemDetails.Type);
105106
Assert.Equal("One or more validation errors occurred.", problemDetails.Title);
106107
Assert.Equal(StatusCodes.Status400BadRequest, problemDetails.Status);
@@ -111,6 +112,67 @@ public async Task UseProblemDetailsServiceWhenAddedInServiceCollection()
111112
Assert.True(errors.EnumerateObject().Count() == 1);
112113
}
113114

115+
[Fact]
116+
public async Task UseProblemDetailsServiceWithCallbackWhenAddedInServiceCollection()
117+
{
118+
var services = new ServiceCollection();
119+
services.AddValidation();
120+
121+
services.AddProblemDetails(options =>
122+
{
123+
options.CustomizeProblemDetails = context =>
124+
{
125+
context.ProblemDetails.Extensions.Add("timestamp", DateTimeOffset.Now);
126+
};
127+
});
128+
129+
var serviceProvider = services.BuildServiceProvider();
130+
131+
var builder = new DefaultEndpointRouteBuilder(new ApplicationBuilder(serviceProvider));
132+
133+
// Act - Create one endpoint with validation
134+
builder.MapGet("validation-test", ([Range(5, 10)] int param) => "Validation enabled here.");
135+
136+
// Build the endpoints
137+
var dataSource = Assert.Single(builder.DataSources);
138+
var endpoints = dataSource.Endpoints;
139+
140+
// Get filter factories from endpoint
141+
var endpoint = endpoints[0];
142+
143+
var context = new DefaultHttpContext
144+
{
145+
RequestServices = serviceProvider
146+
};
147+
148+
context.Request.Method = "GET";
149+
context.Request.QueryString = new QueryString("?param=15");
150+
using var ms = new MemoryStream();
151+
context.Response.Body = ms;
152+
153+
await endpoint.RequestDelegate(context);
154+
155+
// Assert
156+
Assert.Equal(StatusCodes.Status400BadRequest, context.Response.StatusCode);
157+
Assert.StartsWith(MediaTypeNames.Application.ProblemJson, context.Response.ContentType, StringComparison.OrdinalIgnoreCase);
158+
159+
ms.Seek(0, SeekOrigin.Begin);
160+
var problemDetails = await JsonSerializer.DeserializeAsync<ProblemDetails>(ms, JsonSerializerOptions.Web);
161+
162+
// Check if the response is an actual ProblemDetails object
163+
Assert.Equal("https://tools.ietf.org/html/rfc9110#section-15.5.1", problemDetails.Type);
164+
Assert.Equal("One or more validation errors occurred.", problemDetails.Title);
165+
Assert.Equal(StatusCodes.Status400BadRequest, problemDetails.Status);
166+
167+
// Check that ProblemDetails contains the errors object with 1 validation error
168+
Assert.True(problemDetails.Extensions.TryGetValue("errors", out var errorsObj));
169+
var errors = Assert.IsType<JsonElement>(errorsObj);
170+
Assert.True(errors.EnumerateObject().Count() == 1);
171+
172+
// Check that ProblemDetails customizations are applied in the response
173+
Assert.True(problemDetails.Extensions.ContainsKey("timestamp"));
174+
}
175+
114176
private class DefaultEndpointRouteBuilder(IApplicationBuilder applicationBuilder) : IEndpointRouteBuilder
115177
{
116178
private IApplicationBuilder ApplicationBuilder { get; } = applicationBuilder ?? throw new ArgumentNullException(nameof(applicationBuilder));

0 commit comments

Comments
 (0)