diff --git a/src/Swashbuckle.AspNetCore.SwaggerGen/SchemaGenerator/SchemaGenerator.cs b/src/Swashbuckle.AspNetCore.SwaggerGen/SchemaGenerator/SchemaGenerator.cs index 69b09d8b15..b9ecacaa7d 100644 --- a/src/Swashbuckle.AspNetCore.SwaggerGen/SchemaGenerator/SchemaGenerator.cs +++ b/src/Swashbuckle.AspNetCore.SwaggerGen/SchemaGenerator/SchemaGenerator.cs @@ -405,7 +405,8 @@ private OpenApiSchema CreateObjectSchema(DataContract dataContract, SchemaReposi } applicableDataProperties = applicableDataProperties - .Where(dataProperty => dataProperty.MemberInfo.DeclaringType == dataContract.UnderlyingType); + // if the property is declared on a type other than (the one we just added as a base or one of its parents) + .Where(dataProperty => !baseTypeDataContract.UnderlyingType.IsAssignableTo(dataProperty.MemberInfo.DeclaringType)); } if (IsBaseTypeWithKnownTypesDefined(dataContract, out var knownTypesDataContracts)) diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/Fixtures/FakeControllerWithInheritance.cs b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/Fixtures/FakeControllerWithInheritance.cs new file mode 100644 index 0000000000..353527841e --- /dev/null +++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/Fixtures/FakeControllerWithInheritance.cs @@ -0,0 +1,35 @@ +using Microsoft.AspNetCore.Mvc; + +namespace Swashbuckle.AspNetCore.SwaggerGen.Test; + +public class FakeControllerWithInheritance +{ + public void ActionWithDerivedObjectParameter([FromBody] AbcTests_C param) + { } + + public List ActionWithDerivedObjectResponse() + { + return null!; + } + + public AbcTests_B ActionWithDerivedObjectResponse_ExcludedFromInheritanceConfig() + { + return null!; + } + + // Helper test types for GenerateSchema_PreservesIntermediateBaseProperties_WhenUsingOneOfPolymorphism + public abstract class AbcTests_A + { + public string PropA { get; set; } + } + + public class AbcTests_B : AbcTests_A + { + public string PropB { get; set; } + } + + public class AbcTests_C : AbcTests_B + { + public string PropC { get; set; } + } +} diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SchemaGenerator/JsonSerializerSchemaGeneratorTests.cs b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SchemaGenerator/JsonSerializerSchemaGeneratorTests.cs index f662064bf3..321e70ee3e 100644 --- a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SchemaGenerator/JsonSerializerSchemaGeneratorTests.cs +++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/SchemaGenerator/JsonSerializerSchemaGeneratorTests.cs @@ -717,6 +717,60 @@ public void GenerateSchema_SupportsOption_UseAllOfForPolymorphism() Assert.Equal(["Property2"], subType2Schema.Properties.Keys); } + [Fact] + public void GenerateSchema_PreservesIntermediateBaseProperties_WhenUsingOneOfPolymorphism() + { + // Arrange - define a type hierarchy A <- B <- C where only A and C are selected as known subtypes + var subject = Subject(configureGenerator: c => + { + c.UseOneOfForPolymorphism = true; + c.SubTypesSelector = (type) => type == typeof(AbcTests_A) ? new[] { typeof(AbcTests_C) } : Array.Empty(); + }); + + var schemaRepository = new SchemaRepository(); + + // Act + var schema = subject.GenerateSchema(typeof(AbcTests_A), schemaRepository); + + // Assert - polymorphic schema should be present + Assert.NotNull(schema.OneOf); + + // Ensure base A schema contains PropA + Assert.True(schemaRepository.Schemas.ContainsKey(nameof(AbcTests_A))); + var aSchema = schemaRepository.Schemas[nameof(AbcTests_A)]; + Assert.True(aSchema.Properties.ContainsKey(nameof(AbcTests_A.PropA))); + + // Find the C schema in the OneOf and assert it preserves B's properties while not duplicating A's + var cRef = schema.OneOf + .OfType() + .First(r => r.Reference.Id == nameof(AbcTests_C)); + + var cSchema = schemaRepository.Schemas[nameof(AbcTests_C)]; + + // C should include PropC and properties declared on intermediate B + Assert.True(cSchema.Properties.ContainsKey(nameof(AbcTests_C.PropC))); + Assert.True(cSchema.Properties.ContainsKey(nameof(AbcTests_B.PropB))); + + // A's property should not be in C's inline properties because it's provided by the referenced base schema + Assert.False(cSchema.Properties.ContainsKey(nameof(AbcTests_A.PropA))); + } + + // Helper test types for the A/B/C regression + public abstract class AbcTests_A + { + public string PropA { get; set; } + } + + public class AbcTests_B : AbcTests_A + { + public string PropB { get; set; } + } + + public class AbcTests_C : AbcTests_B + { + public string PropC { get; set; } + } + [Fact] public void GenerateSchema_SupportsOption_UseAllOfToExtendReferenceSchemas() { diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/VerifyTests.cs b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/VerifyTests.cs index 02bc8e8ac1..f27dcbb564 100644 --- a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/VerifyTests.cs +++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/VerifyTests.cs @@ -1112,6 +1112,146 @@ public async Task ActionHavingFromFormAttributeWithSwaggerIgnore() await Verify(document); } + [Fact] + public async Task GenerateSchema_PreservesIntermediateBaseProperties_WhenUsingOneOfPolymorphism() + { + var subject = Subject( + apiDescriptions: + [ + ApiDescriptionFactory.Create( + c => nameof(c.ActionWithDerivedObjectParameter), + groupName: "v1", + httpMethod: "POST", + relativePath: "resource", + parameterDescriptions: + [ + new ApiParameterDescription + { + Name = "param1", + Source = BindingSource.Body, + Type = typeof(FakeControllerWithInheritance.AbcTests_C), // most derived type + ModelMetadata = ModelMetadataFactory.CreateForType(typeof(FakeControllerWithInheritance.AbcTests_C)), + }, + ], + supportedRequestFormats: + [ + new ApiRequestFormat { MediaType = "application/json" }, + ]), + ApiDescriptionFactory.Create( + c => nameof(c.ActionWithDerivedObjectResponse), + groupName: "v1", + httpMethod: "GET", + relativePath: "resource", + parameterDescriptions: [], + supportedResponseTypes: [ + new ApiResponseType + { + ApiResponseFormats = [new ApiResponseFormat { MediaType = "application/json" }], + StatusCode = 200, + Type = typeof(FakeControllerWithInheritance.AbcTests_A), + }, + ]), + ApiDescriptionFactory.Create( + c => nameof(c.ActionWithDerivedObjectResponse_ExcludedFromInheritanceConfig), + groupName: "v1", + httpMethod: "GET", + relativePath: "resourceB", + parameterDescriptions: [], + supportedResponseTypes: [ + new ApiResponseType + { + ApiResponseFormats = [new ApiResponseFormat { MediaType = "application/json" }], + StatusCode = 200, + Type = typeof(FakeControllerWithInheritance.AbcTests_B), + }, + ]), + ], + configureSchemaGeneratorOptions: c => + { + c.UseOneOfForPolymorphism = true; + c.SubTypesSelector = + (type) => (Type[])( + type == typeof(FakeControllerWithInheritance.AbcTests_A) + ? [typeof(FakeControllerWithInheritance.AbcTests_C)] + : [] + ); + } + ); + var document = subject.GetSwagger("v1"); + + await Verify(document); + } + + [Fact] + public async Task GenerateSchema_PreservesMultiLevelInheritance() + { + var subject = Subject( + apiDescriptions: + [ + ApiDescriptionFactory.Create( + c => nameof(c.ActionWithDerivedObjectParameter), + groupName: "v1", + httpMethod: "POST", + relativePath: "resource", + parameterDescriptions: + [ + new ApiParameterDescription + { + Name = "param1", + Source = BindingSource.Body, + Type = typeof(FakeControllerWithInheritance.AbcTests_C), // most derived type + ModelMetadata = ModelMetadataFactory.CreateForType(typeof(FakeControllerWithInheritance.AbcTests_C)), + }, + ], + supportedRequestFormats: + [ + new ApiRequestFormat { MediaType = "application/json" }, + ]), + ApiDescriptionFactory.Create( + c => nameof(c.ActionWithDerivedObjectResponse), + groupName: "v1", + httpMethod: "GET", + relativePath: "resource", + parameterDescriptions: [], + supportedResponseTypes: [ + new ApiResponseType + { + ApiResponseFormats = [new ApiResponseFormat { MediaType = "application/json" }], + StatusCode = 200, + Type = typeof(FakeControllerWithInheritance.AbcTests_A), + }, + ]), + ApiDescriptionFactory.Create( + c => nameof(c.ActionWithDerivedObjectResponse_ExcludedFromInheritanceConfig), + groupName: "v1", + httpMethod: "GET", + relativePath: "resourceB", + parameterDescriptions: [], + supportedResponseTypes: [ + new ApiResponseType + { + ApiResponseFormats = [new ApiResponseFormat { MediaType = "application/json" }], + StatusCode = 200, + Type = typeof(FakeControllerWithInheritance.AbcTests_B), + }, + ]), + ], + configureSchemaGeneratorOptions: c => + { + c.UseOneOfForPolymorphism = true; + c.SubTypesSelector = + (type) => (Type[])( + type == typeof(FakeControllerWithInheritance.AbcTests_A) ? [typeof(FakeControllerWithInheritance.AbcTests_B), typeof(FakeControllerWithInheritance.AbcTests_C)] + : type == typeof(FakeControllerWithInheritance.AbcTests_B) ? [typeof(FakeControllerWithInheritance.AbcTests_C)] + : [] + ); + } + ); + var document = subject.GetSwagger("v1"); + + await Verify(document); + } + [Fact] public async Task GetSwagger_Works_As_Expected_When_FromFormObject() { @@ -1465,12 +1605,16 @@ private static SwaggerGenerator Subject( IEnumerable apiDescriptions, SwaggerGeneratorOptions options = null, IEnumerable authenticationSchemes = null, - List schemaFilters = null) + List schemaFilters = null, + Action configureSchemaGeneratorOptions = null) { + var schemaGeneratorOptions = new SchemaGeneratorOptions() { SchemaFilters = schemaFilters ?? [] }; + configureSchemaGeneratorOptions?.Invoke(schemaGeneratorOptions); + return new SwaggerGenerator( options ?? DefaultOptions, new FakeApiDescriptionGroupCollectionProvider(apiDescriptions), - new SchemaGenerator(new SchemaGeneratorOptions() { SchemaFilters = schemaFilters ?? [] }, new JsonSerializerDataContractResolver(new JsonSerializerOptions())), + new SchemaGenerator(schemaGeneratorOptions, new JsonSerializerDataContractResolver(new JsonSerializerOptions())), new FakeAuthenticationSchemeProvider(authenticationSchemes ?? []) ); } diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/snapshots/VerifyTests.GenerateSchema_PreservesIntermediateBaseProperties_WhenUsingOneOfPolymorphism.DotNet10_0.verified.txt b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/snapshots/VerifyTests.GenerateSchema_PreservesIntermediateBaseProperties_WhenUsingOneOfPolymorphism.DotNet10_0.verified.txt new file mode 100644 index 0000000000..7ce98c5a8f --- /dev/null +++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/snapshots/VerifyTests.GenerateSchema_PreservesIntermediateBaseProperties_WhenUsingOneOfPolymorphism.DotNet10_0.verified.txt @@ -0,0 +1,125 @@ +{ + "openapi": "3.0.4", + "info": { + "title": "Test API", + "version": "V1" + }, + "paths": { + "/resource": { + "post": { + "tags": [ + "FakeWithInheritance" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AbcTests_C" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + }, + "get": { + "tags": [ + "FakeWithInheritance" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/AbcTests_C" + } + ] + } + } + } + } + } + } + } + }, + "/resourceB": { + "get": { + "tags": [ + "FakeWithInheritance" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AbcTests_B" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "AbcTests_A": { + "type": "object", + "properties": { + "PropA": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "AbcTests_B": { + "type": "object", + "properties": { + "PropA": { + "type": "string", + "nullable": true + }, + "PropB": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "AbcTests_C": { + "type": "object", + "allOf": [ + { + "$ref": "#/components/schemas/AbcTests_A" + } + ], + "properties": { + "PropB": { + "type": "string", + "nullable": true + }, + "PropC": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + } + } + }, + "tags": [ + { + "name": "FakeWithInheritance" + } + ] +} diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/snapshots/VerifyTests.GenerateSchema_PreservesIntermediateBaseProperties_WhenUsingOneOfPolymorphism.DotNet8_0.verified.txt b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/snapshots/VerifyTests.GenerateSchema_PreservesIntermediateBaseProperties_WhenUsingOneOfPolymorphism.DotNet8_0.verified.txt new file mode 100644 index 0000000000..7ce98c5a8f --- /dev/null +++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/snapshots/VerifyTests.GenerateSchema_PreservesIntermediateBaseProperties_WhenUsingOneOfPolymorphism.DotNet8_0.verified.txt @@ -0,0 +1,125 @@ +{ + "openapi": "3.0.4", + "info": { + "title": "Test API", + "version": "V1" + }, + "paths": { + "/resource": { + "post": { + "tags": [ + "FakeWithInheritance" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AbcTests_C" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + }, + "get": { + "tags": [ + "FakeWithInheritance" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/AbcTests_C" + } + ] + } + } + } + } + } + } + } + }, + "/resourceB": { + "get": { + "tags": [ + "FakeWithInheritance" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AbcTests_B" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "AbcTests_A": { + "type": "object", + "properties": { + "PropA": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "AbcTests_B": { + "type": "object", + "properties": { + "PropA": { + "type": "string", + "nullable": true + }, + "PropB": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "AbcTests_C": { + "type": "object", + "allOf": [ + { + "$ref": "#/components/schemas/AbcTests_A" + } + ], + "properties": { + "PropB": { + "type": "string", + "nullable": true + }, + "PropC": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + } + } + }, + "tags": [ + { + "name": "FakeWithInheritance" + } + ] +} diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/snapshots/VerifyTests.GenerateSchema_PreservesIntermediateBaseProperties_WhenUsingOneOfPolymorphism.DotNet9_0.verified.txt b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/snapshots/VerifyTests.GenerateSchema_PreservesIntermediateBaseProperties_WhenUsingOneOfPolymorphism.DotNet9_0.verified.txt new file mode 100644 index 0000000000..7ce98c5a8f --- /dev/null +++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/snapshots/VerifyTests.GenerateSchema_PreservesIntermediateBaseProperties_WhenUsingOneOfPolymorphism.DotNet9_0.verified.txt @@ -0,0 +1,125 @@ +{ + "openapi": "3.0.4", + "info": { + "title": "Test API", + "version": "V1" + }, + "paths": { + "/resource": { + "post": { + "tags": [ + "FakeWithInheritance" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AbcTests_C" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + }, + "get": { + "tags": [ + "FakeWithInheritance" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/AbcTests_C" + } + ] + } + } + } + } + } + } + } + }, + "/resourceB": { + "get": { + "tags": [ + "FakeWithInheritance" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AbcTests_B" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "AbcTests_A": { + "type": "object", + "properties": { + "PropA": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "AbcTests_B": { + "type": "object", + "properties": { + "PropA": { + "type": "string", + "nullable": true + }, + "PropB": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "AbcTests_C": { + "type": "object", + "allOf": [ + { + "$ref": "#/components/schemas/AbcTests_A" + } + ], + "properties": { + "PropB": { + "type": "string", + "nullable": true + }, + "PropC": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + } + } + }, + "tags": [ + { + "name": "FakeWithInheritance" + } + ] +} diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/snapshots/VerifyTests.GenerateSchema_PreservesMultiLevelInheritance.DotNet10_0.verified.txt b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/snapshots/VerifyTests.GenerateSchema_PreservesMultiLevelInheritance.DotNet10_0.verified.txt new file mode 100644 index 0000000000..4ffab987e0 --- /dev/null +++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/snapshots/VerifyTests.GenerateSchema_PreservesMultiLevelInheritance.DotNet10_0.verified.txt @@ -0,0 +1,132 @@ +{ + "openapi": "3.0.4", + "info": { + "title": "Test API", + "version": "V1" + }, + "paths": { + "/resource": { + "post": { + "tags": [ + "FakeWithInheritance" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AbcTests_C" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + }, + "get": { + "tags": [ + "FakeWithInheritance" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/AbcTests_B" + }, + { + "$ref": "#/components/schemas/AbcTests_C" + } + ] + } + } + } + } + } + } + } + }, + "/resourceB": { + "get": { + "tags": [ + "FakeWithInheritance" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "oneOf": [ + { + "$ref": "#/components/schemas/AbcTests_B" + }, + { + "$ref": "#/components/schemas/AbcTests_C" + } + ] + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "AbcTests_A": { + "type": "object", + "properties": { + "PropA": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "AbcTests_B": { + "type": "object", + "allOf": [ + { + "$ref": "#/components/schemas/AbcTests_A" + } + ], + "properties": { + "PropB": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "AbcTests_C": { + "type": "object", + "allOf": [ + { + "$ref": "#/components/schemas/AbcTests_B" + } + ], + "properties": { + "PropC": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + } + } + }, + "tags": [ + { + "name": "FakeWithInheritance" + } + ] +} diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/snapshots/VerifyTests.GenerateSchema_PreservesMultiLevelInheritance.DotNet8_0.verified.txt b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/snapshots/VerifyTests.GenerateSchema_PreservesMultiLevelInheritance.DotNet8_0.verified.txt new file mode 100644 index 0000000000..4ffab987e0 --- /dev/null +++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/snapshots/VerifyTests.GenerateSchema_PreservesMultiLevelInheritance.DotNet8_0.verified.txt @@ -0,0 +1,132 @@ +{ + "openapi": "3.0.4", + "info": { + "title": "Test API", + "version": "V1" + }, + "paths": { + "/resource": { + "post": { + "tags": [ + "FakeWithInheritance" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AbcTests_C" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + }, + "get": { + "tags": [ + "FakeWithInheritance" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/AbcTests_B" + }, + { + "$ref": "#/components/schemas/AbcTests_C" + } + ] + } + } + } + } + } + } + } + }, + "/resourceB": { + "get": { + "tags": [ + "FakeWithInheritance" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "oneOf": [ + { + "$ref": "#/components/schemas/AbcTests_B" + }, + { + "$ref": "#/components/schemas/AbcTests_C" + } + ] + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "AbcTests_A": { + "type": "object", + "properties": { + "PropA": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "AbcTests_B": { + "type": "object", + "allOf": [ + { + "$ref": "#/components/schemas/AbcTests_A" + } + ], + "properties": { + "PropB": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "AbcTests_C": { + "type": "object", + "allOf": [ + { + "$ref": "#/components/schemas/AbcTests_B" + } + ], + "properties": { + "PropC": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + } + } + }, + "tags": [ + { + "name": "FakeWithInheritance" + } + ] +} diff --git a/test/Swashbuckle.AspNetCore.SwaggerGen.Test/snapshots/VerifyTests.GenerateSchema_PreservesMultiLevelInheritance.DotNet9_0.verified.txt b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/snapshots/VerifyTests.GenerateSchema_PreservesMultiLevelInheritance.DotNet9_0.verified.txt new file mode 100644 index 0000000000..4ffab987e0 --- /dev/null +++ b/test/Swashbuckle.AspNetCore.SwaggerGen.Test/snapshots/VerifyTests.GenerateSchema_PreservesMultiLevelInheritance.DotNet9_0.verified.txt @@ -0,0 +1,132 @@ +{ + "openapi": "3.0.4", + "info": { + "title": "Test API", + "version": "V1" + }, + "paths": { + "/resource": { + "post": { + "tags": [ + "FakeWithInheritance" + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AbcTests_C" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + }, + "get": { + "tags": [ + "FakeWithInheritance" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/AbcTests_B" + }, + { + "$ref": "#/components/schemas/AbcTests_C" + } + ] + } + } + } + } + } + } + } + }, + "/resourceB": { + "get": { + "tags": [ + "FakeWithInheritance" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "oneOf": [ + { + "$ref": "#/components/schemas/AbcTests_B" + }, + { + "$ref": "#/components/schemas/AbcTests_C" + } + ] + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "AbcTests_A": { + "type": "object", + "properties": { + "PropA": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "AbcTests_B": { + "type": "object", + "allOf": [ + { + "$ref": "#/components/schemas/AbcTests_A" + } + ], + "properties": { + "PropB": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + }, + "AbcTests_C": { + "type": "object", + "allOf": [ + { + "$ref": "#/components/schemas/AbcTests_B" + } + ], + "properties": { + "PropC": { + "type": "string", + "nullable": true + } + }, + "additionalProperties": false + } + } + }, + "tags": [ + { + "name": "FakeWithInheritance" + } + ] +}