Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions src/Http/Http.Extensions/src/DefaultProblemDetailsWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,17 @@ public ValueTask WriteAsync(ProblemDetailsContext context)
ProblemDetailsDefaults.Apply(context.ProblemDetails, httpContext.Response.StatusCode);

var traceId = Activity.Current?.Id ?? httpContext.TraceIdentifier;
context.ProblemDetails.Extensions["traceId"] = traceId;

var traceIdKeyName = _serializerOptions.PropertyNamingPolicy?.ConvertName("traceId") ?? "traceId";
context.ProblemDetails.Extensions[traceIdKeyName] = traceId;

_options.CustomizeProblemDetails?.Invoke(context);

var problemDetailsType = context.ProblemDetails.GetType();

return new ValueTask(httpContext.Response.WriteAsJsonAsync(
context.ProblemDetails,
_serializerOptions.GetTypeInfo(problemDetailsType),
contentType: "application/problem+json"));
context.ProblemDetails,
_serializerOptions.GetTypeInfo(problemDetailsType),
contentType: "application/problem+json"));
}
}
151 changes: 148 additions & 3 deletions src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,7 @@
Assert.Equal("traceId", extension.Key);
Assert.Equal(expectedTraceId, extension.Value.ToString());
});

}

[Fact]
Expand All @@ -503,6 +504,10 @@
var options = new JsonOptions();
options.SerializerOptions.TypeInfoResolver = JsonTypeInfoResolver.Combine(CustomProblemDetailsContext.Default, ProblemDetailsJsonContext.Default);

var mockNamingPolicy = new Mock<JsonNamingPolicy>();

Check failure on line 507 in src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs

View check run for this annotation

Azure Pipelines / aspnetcore-quarantined-pr (Tests: Ubuntu x64)

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs#L507

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs(507,36): error CS0246: (NETCORE_ENGINEERING_TELEMETRY=Build) The type or namespace name 'Mock<>' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 507 in src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs

View check run for this annotation

Azure Pipelines / aspnetcore-quarantined-pr (Tests: macOS)

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs#L507

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs(507,36): error CS0246: (NETCORE_ENGINEERING_TELEMETRY=Build) The type or namespace name 'Mock<>' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 507 in src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Test: Ubuntu x64)

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs#L507

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs(507,36): error CS0246: (NETCORE_ENGINEERING_TELEMETRY=Build) The type or namespace name 'Mock<>' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 507 in src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Test: macOS)

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs#L507

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs(507,36): error CS0246: (NETCORE_ENGINEERING_TELEMETRY=Build) The type or namespace name 'Mock<>' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 507 in src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs

View check run for this annotation

Azure Pipelines / aspnetcore-quarantined-pr

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs#L507

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs(507,36): error CS0246: (NETCORE_ENGINEERING_TELEMETRY=Build) The type or namespace name 'Mock<>' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 507 in src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs#L507

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs(507,36): error CS0246: (NETCORE_ENGINEERING_TELEMETRY=Build) The type or namespace name 'Mock<>' could not be found (are you missing a using directive or an assembly reference?)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of modifying the existing tests, can we add a new one?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @captainsafia, My local is somehow not working properly and studio is not giving errors. I may need to reinstall devbox.

Since I am traveling somewhere for few days, I would really appreciate if you can help adding dependencies as they are only missing. That can complete the PR and issue. Please let me know. :)

mockNamingPolicy.Setup(policy => policy.ConvertName("traceId")).Returns("custom_traceId");
options.SerializerOptions.PropertyNamingPolicy = mockNamingPolicy.Object;

var writer = GetWriter(jsonOptions: options);
var stream = new MemoryStream();
var context = CreateContext(stream);
Expand All @@ -517,10 +522,10 @@
ProblemDetails = expectedProblem
};

//Act
// Act
await writer.WriteAsync(problemDetailsContext);

//Assert
// Assert
stream.Position = 0;

var problemDetails = await JsonSerializer.DeserializeAsync<ProblemDetails>(stream, options.SerializerOptions);
Expand All @@ -537,7 +542,7 @@
},
(extension) =>
{
Assert.Equal("traceId", extension.Key);
Assert.Equal("custom_traceId", extension.Key); // Updated to reflect the custom naming policy
Assert.Equal(expectedTraceId, extension.Value.ToString());
});
}
Expand Down Expand Up @@ -670,6 +675,146 @@
Assert.False(result);
}

[Fact]
public async Task WriteAsync_Respects_CustomNamingPolicy_ForTraceId()
{
// Arrange
var writer = GetWriter();
var stream = new MemoryStream();
var context = CreateContext(stream);
var expectedTraceId = Activity.Current?.Id ?? context.TraceIdentifier;

var mockNamingPolicy = new Mock<JsonNamingPolicy>();

Check failure on line 687 in src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs

View check run for this annotation

Azure Pipelines / aspnetcore-quarantined-pr (Tests: Ubuntu x64)

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs#L687

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs(687,36): error CS0246: (NETCORE_ENGINEERING_TELEMETRY=Build) The type or namespace name 'Mock<>' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 687 in src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs

View check run for this annotation

Azure Pipelines / aspnetcore-quarantined-pr (Tests: macOS)

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs#L687

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs(687,36): error CS0246: (NETCORE_ENGINEERING_TELEMETRY=Build) The type or namespace name 'Mock<>' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 687 in src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Test: Ubuntu x64)

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs#L687

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs(687,36): error CS0246: (NETCORE_ENGINEERING_TELEMETRY=Build) The type or namespace name 'Mock<>' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 687 in src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Test: macOS)

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs#L687

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs(687,36): error CS0246: (NETCORE_ENGINEERING_TELEMETRY=Build) The type or namespace name 'Mock<>' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 687 in src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs

View check run for this annotation

Azure Pipelines / aspnetcore-quarantined-pr

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs#L687

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs(687,36): error CS0246: (NETCORE_ENGINEERING_TELEMETRY=Build) The type or namespace name 'Mock<>' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 687 in src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs#L687

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs(687,36): error CS0246: (NETCORE_ENGINEERING_TELEMETRY=Build) The type or namespace name 'Mock<>' could not be found (are you missing a using directive or an assembly reference?)
mockNamingPolicy.Setup(policy => policy.ConvertName("traceId")).Returns("custom_traceId");

var serializerOptions = new JsonSerializerOptions { PropertyNamingPolicy = mockNamingPolicy.Object };
SetSerializerOptions(writer, serializerOptions);

Check failure on line 691 in src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs

View check run for this annotation

Azure Pipelines / aspnetcore-quarantined-pr (Tests: Ubuntu x64)

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs#L691

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs(691,9): error CS0103: (NETCORE_ENGINEERING_TELEMETRY=Build) The name 'SetSerializerOptions' does not exist in the current context

Check failure on line 691 in src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs

View check run for this annotation

Azure Pipelines / aspnetcore-quarantined-pr (Tests: macOS)

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs#L691

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs(691,9): error CS0103: (NETCORE_ENGINEERING_TELEMETRY=Build) The name 'SetSerializerOptions' does not exist in the current context

Check failure on line 691 in src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Test: Ubuntu x64)

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs#L691

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs(691,9): error CS0103: (NETCORE_ENGINEERING_TELEMETRY=Build) The name 'SetSerializerOptions' does not exist in the current context

Check failure on line 691 in src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Test: macOS)

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs#L691

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs(691,9): error CS0103: (NETCORE_ENGINEERING_TELEMETRY=Build) The name 'SetSerializerOptions' does not exist in the current context

Check failure on line 691 in src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs

View check run for this annotation

Azure Pipelines / aspnetcore-quarantined-pr

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs#L691

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs(691,9): error CS0103: (NETCORE_ENGINEERING_TELEMETRY=Build) The name 'SetSerializerOptions' does not exist in the current context

Check failure on line 691 in src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs#L691

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs(691,9): error CS0103: (NETCORE_ENGINEERING_TELEMETRY=Build) The name 'SetSerializerOptions' does not exist in the current context

var expectedProblem = new ProblemDetails()
{
Status = StatusCodes.Status500InternalServerError
};

var problemDetailsContext = new ProblemDetailsContext()
{
HttpContext = context,
ProblemDetails = expectedProblem
};

// Act
await writer.WriteAsync(problemDetailsContext);

// Assert
stream.Position = 0;
var problemDetails = await JsonSerializer.DeserializeAsync<ProblemDetails>(stream, serializerOptions);
Assert.NotNull(problemDetails);
Assert.Equal(expectedTraceId, problemDetails.Extensions["custom_traceId"].ToString());
Assert.DoesNotContain("traceId", problemDetails.Extensions.Keys);
}

[Fact]
public async Task WriteAsync_FallsBack_WhenNamingPolicyReturnsNull()
{
// Arrange
var writer = GetWriter();
var stream = new MemoryStream();
var context = CreateContext(stream);
var expectedTraceId = Activity.Current?.Id ?? context.TraceIdentifier;

var mockNamingPolicy = new Mock<JsonNamingPolicy>();

Check failure on line 724 in src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs

View check run for this annotation

Azure Pipelines / aspnetcore-quarantined-pr (Tests: Ubuntu x64)

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs#L724

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs(724,36): error CS0246: (NETCORE_ENGINEERING_TELEMETRY=Build) The type or namespace name 'Mock<>' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 724 in src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs

View check run for this annotation

Azure Pipelines / aspnetcore-quarantined-pr (Tests: macOS)

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs#L724

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs(724,36): error CS0246: (NETCORE_ENGINEERING_TELEMETRY=Build) The type or namespace name 'Mock<>' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 724 in src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Test: Ubuntu x64)

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs#L724

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs(724,36): error CS0246: (NETCORE_ENGINEERING_TELEMETRY=Build) The type or namespace name 'Mock<>' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 724 in src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Test: macOS)

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs#L724

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs(724,36): error CS0246: (NETCORE_ENGINEERING_TELEMETRY=Build) The type or namespace name 'Mock<>' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 724 in src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs

View check run for this annotation

Azure Pipelines / aspnetcore-quarantined-pr

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs#L724

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs(724,36): error CS0246: (NETCORE_ENGINEERING_TELEMETRY=Build) The type or namespace name 'Mock<>' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 724 in src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs#L724

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs(724,36): error CS0246: (NETCORE_ENGINEERING_TELEMETRY=Build) The type or namespace name 'Mock<>' could not be found (are you missing a using directive or an assembly reference?)
mockNamingPolicy.Setup(policy => policy.ConvertName("traceId")).Returns((string)null);

var serializerOptions = new JsonSerializerOptions { PropertyNamingPolicy = mockNamingPolicy.Object };
SetSerializerOptions(writer, serializerOptions);

Check failure on line 728 in src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs

View check run for this annotation

Azure Pipelines / aspnetcore-quarantined-pr (Tests: macOS)

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs#L728

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs(728,9): error CS0103: (NETCORE_ENGINEERING_TELEMETRY=Build) The name 'SetSerializerOptions' does not exist in the current context

Check failure on line 728 in src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Test: Ubuntu x64)

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs#L728

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs(728,9): error CS0103: (NETCORE_ENGINEERING_TELEMETRY=Build) The name 'SetSerializerOptions' does not exist in the current context

Check failure on line 728 in src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs

View check run for this annotation

Azure Pipelines / aspnetcore-ci (Build Test: macOS)

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs#L728

src/Http/Http.Extensions/test/ProblemDetailsDefaultWriterTest.cs(728,9): error CS0103: (NETCORE_ENGINEERING_TELEMETRY=Build) The name 'SetSerializerOptions' does not exist in the current context

var expectedProblem = new ProblemDetails()
{
Status = StatusCodes.Status500InternalServerError
};

var problemDetailsContext = new ProblemDetailsContext()
{
HttpContext = context,
ProblemDetails = expectedProblem
};

// Act
await writer.WriteAsync(problemDetailsContext);

// Assert
stream.Position = 0;
var problemDetails = await JsonSerializer.DeserializeAsync<ProblemDetails>(stream, serializerOptions);
Assert.NotNull(problemDetails);
Assert.Equal(expectedTraceId, problemDetails.Extensions["traceId"].ToString());
}

[Fact]
public async Task WriteAsync_Respects_CustomNamingPolicy_ForValidationProblemDetails()
{
// Arrange
var writer = GetWriter();
var stream = new MemoryStream();
var context = CreateContext(stream);
var expectedTraceId = Activity.Current?.Id ?? context.TraceIdentifier;

var mockNamingPolicy = new Mock<JsonNamingPolicy>();
mockNamingPolicy.Setup(policy => policy.ConvertName("traceId")).Returns("custom_traceId");

var serializerOptions = new JsonSerializerOptions { PropertyNamingPolicy = mockNamingPolicy.Object };
SetSerializerOptions(writer, serializerOptions);

var expectedProblem = new ValidationProblemDetails()
{
Errors = new Dictionary<string, string[]> { { "sample", new[] { "error-message" } } }
};

var problemDetailsContext = new ProblemDetailsContext()
{
HttpContext = context,
ProblemDetails = expectedProblem
};

// Act
await writer.WriteAsync(problemDetailsContext);

// Assert
stream.Position = 0;
var problemDetails = await JsonSerializer.DeserializeAsync<ValidationProblemDetails>(stream, serializerOptions);
Assert.NotNull(problemDetails);
Assert.Equal(expectedTraceId, problemDetails.Extensions["custom_traceId"].ToString());
Assert.DoesNotContain("traceId", problemDetails.Extensions.Keys);
}

[Fact]
public async Task WriteAsync_Uses_DefaultTraceIdKey_WhenNoNamingPolicy()
{
// Arrange
var writer = GetWriter();
var stream = new MemoryStream();
var context = CreateContext(stream);
var expectedTraceId = Activity.Current?.Id ?? context.TraceIdentifier;

var expectedProblem = new ProblemDetails()
{
Status = StatusCodes.Status500InternalServerError
};

var problemDetailsContext = new ProblemDetailsContext()
{
HttpContext = context,
ProblemDetails = expectedProblem
};

// Act
await writer.WriteAsync(problemDetailsContext);

// Assert
stream.Position = 0;
var problemDetails = await JsonSerializer.DeserializeAsync<ProblemDetails>(stream, SerializerOptions);
Assert.NotNull(problemDetails);
Assert.Equal(expectedTraceId, problemDetails.Extensions["traceId"].ToString());
}

private static HttpContext CreateContext(
Stream body,
int statusCode = StatusCodes.Status400BadRequest,
Expand Down
Loading