Skip to content

Commit 39f1443

Browse files
authored
Add test coverage for collections of self-referential schemas (#60402)
1 parent ec389c7 commit 39f1443

File tree

1 file changed

+52
-0
lines changed

1 file changed

+52
-0
lines changed

src/OpenApi/test/Microsoft.AspNetCore.OpenApi.Tests/Transformers/Implementations/OpenApiSchemaReferenceTransformerTests.cs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,58 @@ await VerifyOpenApiDocument(builder, document =>
628628
});
629629
}
630630

631+
[Fact]
632+
public async Task SupportsListOfNestedSchemasWithSelfReference()
633+
{
634+
// Arrange
635+
var builder = CreateBuilder();
636+
637+
builder.MapPost("/list", (List<LocationContainer> items) => { });
638+
builder.MapPost("/array", (LocationContainer[] items) => { });
639+
builder.MapPost("/dictionary", (Dictionary<string, LocationContainer> items) => { });
640+
builder.MapPost("/", (LocationContainer item) => { });
641+
642+
await VerifyOpenApiDocument(builder, document =>
643+
{
644+
var listOperation = document.Paths["/list"].Operations[OperationType.Post];
645+
var listRequestSchema = listOperation.RequestBody.Content["application/json"].Schema;
646+
647+
var arrayOperation = document.Paths["/array"].Operations[OperationType.Post];
648+
var arrayRequestSchema = arrayOperation.RequestBody.Content["application/json"].Schema;
649+
650+
var dictionaryOperation = document.Paths["/dictionary"].Operations[OperationType.Post];
651+
var dictionaryRequestSchema = dictionaryOperation.RequestBody.Content["application/json"].Schema;
652+
653+
var operation = document.Paths["/"].Operations[OperationType.Post];
654+
var requestSchema = operation.RequestBody.Content["application/json"].Schema;
655+
656+
// Assert $ref used for top-level
657+
Assert.Equal("LocationContainer", ((OpenApiSchemaReference)listRequestSchema.Items).Reference.Id);
658+
Assert.Equal("LocationContainer", ((OpenApiSchemaReference)arrayRequestSchema.Items).Reference.Id);
659+
Assert.Equal("LocationContainer", ((OpenApiSchemaReference)dictionaryRequestSchema.AdditionalProperties).Reference.Id);
660+
Assert.Equal("LocationContainer", ((OpenApiSchemaReference)requestSchema).Reference.Id);
661+
662+
// Assert that $ref is used for nested LocationDto
663+
var locationContainerSchema = requestSchema;
664+
Assert.Equal("LocationDto", ((OpenApiSchemaReference)locationContainerSchema.Properties["location"]).Reference.Id);
665+
666+
// Assert that $ref is used for nested AddressDto
667+
var locationSchema = locationContainerSchema.Properties["location"];
668+
Assert.Equal("AddressDto", ((OpenApiSchemaReference)locationSchema.Properties["address"]).Reference.Id);
669+
670+
// Assert that $ref is used for related LocationDto
671+
var addressSchema = locationSchema.Properties["address"];
672+
Assert.Equal("LocationDto", ((OpenApiSchemaReference)addressSchema.Properties["relatedLocation"]).Reference.Id);
673+
674+
// Assert that only expected schemas are generated at the top-level
675+
Assert.Equal(3, document.Components.Schemas.Count);
676+
Assert.Collection(document.Components.Schemas.Keys,
677+
key => Assert.Equal("AddressDto", key),
678+
key => Assert.Equal("LocationContainer", key),
679+
key => Assert.Equal("LocationDto", key));
680+
});
681+
}
682+
631683
private class Root
632684
{
633685
public Item Item1 { get; set; } = null!;

0 commit comments

Comments
 (0)