diff --git a/CHANGELOG.md b/CHANGELOG.md index 9cf5170..2c57ceb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,7 +46,7 @@ This project uses famous football stadiums (A-Z) that hosted FIFA World Cup matc ### Changed -- Field validation failures now return `422 Unprocessable Entity` (RFC 4918) instead of `400 Bad Request`; `400 Bad Request` is now reserved for malformed requests (unparseable JSON, wrong `Content-Type`, route/body mismatch) per RFC 9457 +- Field validation failures now return `422 Unprocessable Entity` (RFC 4918) instead of `400 Bad Request`; `400 Bad Request` is now reserved for malformed requests (unparseable JSON, route/body mismatch); unsupported media types return `415 Unsupported Media Type` (RFC 9110 ยง15.5.16) via the `[Consumes]` attribute. Error responses follow the Problem Details format (RFC 9457). ### Fixed diff --git a/test/Dotnet.Samples.AspNetCore.WebApi.Tests/Integration/PlayerWebApplicationTests.cs b/test/Dotnet.Samples.AspNetCore.WebApi.Tests/Integration/PlayerWebApplicationTests.cs index 7acce55..f809764 100644 --- a/test/Dotnet.Samples.AspNetCore.WebApi.Tests/Integration/PlayerWebApplicationTests.cs +++ b/test/Dotnet.Samples.AspNetCore.WebApi.Tests/Integration/PlayerWebApplicationTests.cs @@ -199,10 +199,10 @@ public async Task Post_Players_Nonexistent_Returns201Created() // Note: the controller's 409 Conflict branch (squad number already exists) is // unreachable via the HTTP pipeline. The "Create" validation rule set includes - // BeUniqueSquadNumber, which returns a 400 validation error before the - // controller's own duplicate check ever runs. The 409 path is covered by the - // unit test Post_Players_Existing_Returns409Conflict, where validation is mocked - // to pass so the controller logic can be exercised in isolation. + // BeUniqueSquadNumber, which returns a 422 validation error (Unprocessable Entity) + // before the controller's own duplicate check ever runs. The 409 path is covered + // by the unit test Post_Players_Existing_Returns409Conflict, where validation is + // mocked to pass so the controller logic can be exercised in isolation. [Fact] [Trait("Category", "Integration")] diff --git a/test/Dotnet.Samples.AspNetCore.WebApi.Tests/Unit/PlayerControllerTests.cs b/test/Dotnet.Samples.AspNetCore.WebApi.Tests/Unit/PlayerControllerTests.cs index c6b1e18..f0a138c 100644 --- a/test/Dotnet.Samples.AspNetCore.WebApi.Tests/Unit/PlayerControllerTests.cs +++ b/test/Dotnet.Samples.AspNetCore.WebApi.Tests/Unit/PlayerControllerTests.cs @@ -65,6 +65,16 @@ public async Task Post_Players_ValidationError_Returns422UnprocessableEntity() ); var httpResult = result.Should().BeOfType().Subject; httpResult.StatusCode.Should().Be(StatusCodes.Status422UnprocessableEntity); + var problemDetails = httpResult + .ProblemDetails.Should() + .BeOfType() + .Subject; + problemDetails.Status.Should().Be(StatusCodes.Status422UnprocessableEntity); + problemDetails + .Errors.Should() + .ContainKey("SquadNumber") + .WhoseValue.Should() + .Contain("SquadNumber must be greater than 0."); } [Fact] @@ -341,6 +351,16 @@ public async Task Put_PlayerBySquadNumber_ValidationError_Returns422Unprocessabl ); var httpResult = result.Should().BeOfType().Subject; httpResult.StatusCode.Should().Be(StatusCodes.Status422UnprocessableEntity); + var problemDetails = httpResult + .ProblemDetails.Should() + .BeOfType() + .Subject; + problemDetails.Status.Should().Be(StatusCodes.Status422UnprocessableEntity); + problemDetails + .Errors.Should() + .ContainKey("SquadNumber") + .WhoseValue.Should() + .Contain("SquadNumber must be greater than 0."); } [Fact]