Skip to content

Commit 60254f2

Browse files
Refactor tests
- Rename classes from #3692 for clarity. - Some style refactoring.
1 parent 025ae09 commit 60254f2

10 files changed

+137
-138
lines changed

src/Swashbuckle.AspNetCore.SwaggerGen/SchemaGenerator/SchemaGenerator.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -404,9 +404,10 @@ private OpenApiSchema CreateObjectSchema(DataContract dataContract, SchemaReposi
404404
schema.AllOf.Add(baseTypeSchema);
405405
}
406406

407-
applicableDataProperties = applicableDataProperties
408-
// if the property is declared on a type other than (the one we just added as a base or one of its parents)
409-
.Where(dataProperty => !baseTypeDataContract.UnderlyingType.IsAssignableTo(dataProperty.MemberInfo.DeclaringType));
407+
// If the property is declared on a type other than the one we just added as a base (or one of its parents)
408+
// See https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/3201.
409+
applicableDataProperties = applicableDataProperties.Where(
410+
(dataProperty) => !baseTypeDataContract.UnderlyingType.IsAssignableTo(dataProperty.MemberInfo.DeclaringType));
410411
}
411412

412413
if (IsBaseTypeWithKnownTypesDefined(dataContract, out var knownTypesDataContracts))

test/Swashbuckle.AspNetCore.SwaggerGen.Test/Fixtures/FakeControllerWithInheritance.cs

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,34 +2,37 @@
22

33
namespace Swashbuckle.AspNetCore.SwaggerGen.Test;
44

5-
public class FakeControllerWithInheritance
5+
#pragma warning disable CA1822
6+
7+
public class FakeControllerWithInheritance : Controller
68
{
7-
public void ActionWithDerivedObjectParameter([FromBody] AbcTests_C param)
8-
{ }
9+
public void ActionWithDerivedObjectParameter([FromBody] MostDerivedClass param)
10+
{
11+
System.Diagnostics.Debug.Assert(param is not null);
12+
}
913

10-
public List<AbcTests_A> ActionWithDerivedObjectResponse()
14+
public List<BaseClass> ActionWithDerivedObjectResponse()
1115
{
1216
return null!;
1317
}
1418

15-
public AbcTests_B ActionWithDerivedObjectResponse_ExcludedFromInheritanceConfig()
19+
public DerivedClass ActionWithDerivedObjectResponse_ExcludedFromInheritanceConfig()
1620
{
1721
return null!;
1822
}
1923

20-
// Helper test types for GenerateSchema_PreservesIntermediateBaseProperties_WhenUsingOneOfPolymorphism
21-
public abstract class AbcTests_A
24+
public abstract class BaseClass
2225
{
23-
public string PropA { get; set; }
26+
public string BaseProperty { get; set; }
2427
}
2528

26-
public class AbcTests_B : AbcTests_A
29+
public class DerivedClass : BaseClass
2730
{
28-
public string PropB { get; set; }
31+
public string DerivedProperty { get; set; }
2932
}
3033

31-
public class AbcTests_C : AbcTests_B
34+
public class MostDerivedClass : DerivedClass
3235
{
33-
public string PropC { get; set; }
36+
public string MoreDerivedProperty { get; set; }
3437
}
3538
}

test/Swashbuckle.AspNetCore.SwaggerGen.Test/SchemaGenerator/JsonSerializerSchemaGeneratorTests.cs

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -721,54 +721,53 @@ public void GenerateSchema_SupportsOption_UseAllOfForPolymorphism()
721721
public void GenerateSchema_PreservesIntermediateBaseProperties_WhenUsingOneOfPolymorphism()
722722
{
723723
// Arrange - define a type hierarchy A <- B <- C where only A and C are selected as known subtypes
724-
var subject = Subject(configureGenerator: c =>
724+
var subject = Subject(configureGenerator: (c) =>
725725
{
726726
c.UseOneOfForPolymorphism = true;
727-
c.SubTypesSelector = (type) => type == typeof(AbcTests_A) ? new[] { typeof(AbcTests_C) } : Array.Empty<Type>();
727+
c.SubTypesSelector = (type) => type == typeof(ModelOfA) ? [typeof(ModelOfC)] : [];
728728
});
729729

730730
var schemaRepository = new SchemaRepository();
731731

732732
// Act
733-
var schema = subject.GenerateSchema(typeof(AbcTests_A), schemaRepository);
733+
var schema = subject.GenerateSchema(typeof(ModelOfA), schemaRepository);
734734

735735
// Assert - polymorphic schema should be present
736736
Assert.NotNull(schema.OneOf);
737737

738738
// Ensure base A schema contains PropA
739-
Assert.True(schemaRepository.Schemas.ContainsKey(nameof(AbcTests_A)));
740-
var aSchema = schemaRepository.Schemas[nameof(AbcTests_A)];
741-
Assert.True(aSchema.Properties.ContainsKey(nameof(AbcTests_A.PropA)));
739+
Assert.True(schemaRepository.Schemas.ContainsKey(nameof(ModelOfA)));
740+
var aSchema = schemaRepository.Schemas[nameof(ModelOfA)];
741+
Assert.True(aSchema.Properties.ContainsKey(nameof(ModelOfA.PropertyOfA)));
742742

743743
// Find the C schema in the OneOf and assert it preserves B's properties while not duplicating A's
744744
var cRef = schema.OneOf
745745
.OfType<OpenApiSchemaReference>()
746-
.First(r => r.Reference.Id == nameof(AbcTests_C));
746+
.First(r => r.Reference.Id == nameof(ModelOfC));
747747

748-
var cSchema = schemaRepository.Schemas[nameof(AbcTests_C)];
748+
var cSchema = schemaRepository.Schemas[nameof(ModelOfC)];
749749

750750
// C should include PropC and properties declared on intermediate B
751-
Assert.True(cSchema.Properties.ContainsKey(nameof(AbcTests_C.PropC)));
752-
Assert.True(cSchema.Properties.ContainsKey(nameof(AbcTests_B.PropB)));
751+
Assert.True(cSchema.Properties.ContainsKey(nameof(ModelOfC.PropertyOfC)));
752+
Assert.True(cSchema.Properties.ContainsKey(nameof(ModelOfB.PropertyOfB)));
753753

754754
// A's property should not be in C's inline properties because it's provided by the referenced base schema
755-
Assert.False(cSchema.Properties.ContainsKey(nameof(AbcTests_A.PropA)));
755+
Assert.False(cSchema.Properties.ContainsKey(nameof(ModelOfA.PropertyOfA)));
756756
}
757757

758-
// Helper test types for the A/B/C regression
759-
public abstract class AbcTests_A
758+
public abstract class ModelOfA
760759
{
761-
public string PropA { get; set; }
760+
public string PropertyOfA { get; set; }
762761
}
763762

764-
public class AbcTests_B : AbcTests_A
763+
public class ModelOfB : ModelOfA
765764
{
766-
public string PropB { get; set; }
765+
public string PropertyOfB { get; set; }
767766
}
768767

769-
public class AbcTests_C : AbcTests_B
768+
public class ModelOfC : ModelOfB
770769
{
771-
public string PropC { get; set; }
770+
public string PropertyOfC { get; set; }
772771
}
773772

774773
[Fact]

test/Swashbuckle.AspNetCore.SwaggerGen.Test/VerifyTests.cs

Lines changed: 26 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1129,26 +1129,24 @@ public async Task GenerateSchema_PreservesIntermediateBaseProperties_WhenUsingOn
11291129
{
11301130
Name = "param1",
11311131
Source = BindingSource.Body,
1132-
Type = typeof(FakeControllerWithInheritance.AbcTests_C), // most derived type
1133-
ModelMetadata = ModelMetadataFactory.CreateForType(typeof(FakeControllerWithInheritance.AbcTests_C)),
1132+
Type = typeof(FakeControllerWithInheritance.MostDerivedClass),
1133+
ModelMetadata = ModelMetadataFactory.CreateForType(typeof(FakeControllerWithInheritance.MostDerivedClass)),
11341134
},
11351135
],
1136-
supportedRequestFormats:
1137-
[
1138-
new ApiRequestFormat { MediaType = "application/json" },
1139-
]),
1136+
supportedRequestFormats: [new ApiRequestFormat { MediaType = "application/json" }]),
11401137
ApiDescriptionFactory.Create<FakeControllerWithInheritance>(
11411138
c => nameof(c.ActionWithDerivedObjectResponse),
11421139
groupName: "v1",
11431140
httpMethod: "GET",
11441141
relativePath: "resource",
11451142
parameterDescriptions: [],
1146-
supportedResponseTypes: [
1143+
supportedResponseTypes:
1144+
[
11471145
new ApiResponseType
11481146
{
11491147
ApiResponseFormats = [new ApiResponseFormat { MediaType = "application/json" }],
11501148
StatusCode = 200,
1151-
Type = typeof(FakeControllerWithInheritance.AbcTests_A),
1149+
Type = typeof(FakeControllerWithInheritance.BaseClass),
11521150
},
11531151
]),
11541152
ApiDescriptionFactory.Create<FakeControllerWithInheritance>(
@@ -1157,24 +1155,24 @@ public async Task GenerateSchema_PreservesIntermediateBaseProperties_WhenUsingOn
11571155
httpMethod: "GET",
11581156
relativePath: "resourceB",
11591157
parameterDescriptions: [],
1160-
supportedResponseTypes: [
1158+
supportedResponseTypes:
1159+
[
11611160
new ApiResponseType
11621161
{
11631162
ApiResponseFormats = [new ApiResponseFormat { MediaType = "application/json" }],
11641163
StatusCode = 200,
1165-
Type = typeof(FakeControllerWithInheritance.AbcTests_B),
1164+
Type = typeof(FakeControllerWithInheritance.DerivedClass),
11661165
},
11671166
]),
11681167
],
11691168
configureSchemaGeneratorOptions: c =>
11701169
{
11711170
c.UseOneOfForPolymorphism = true;
11721171
c.SubTypesSelector =
1173-
(type) => (Type[])(
1174-
type == typeof(FakeControllerWithInheritance.AbcTests_A)
1175-
? [typeof(FakeControllerWithInheritance.AbcTests_C)]
1176-
: []
1177-
);
1172+
(type) =>
1173+
type == typeof(FakeControllerWithInheritance.BaseClass)
1174+
? [typeof(FakeControllerWithInheritance.MostDerivedClass)]
1175+
: [];
11781176
}
11791177
);
11801178
var document = subject.GetSwagger("v1");
@@ -1199,26 +1197,24 @@ public async Task GenerateSchema_PreservesMultiLevelInheritance()
11991197
{
12001198
Name = "param1",
12011199
Source = BindingSource.Body,
1202-
Type = typeof(FakeControllerWithInheritance.AbcTests_C), // most derived type
1203-
ModelMetadata = ModelMetadataFactory.CreateForType(typeof(FakeControllerWithInheritance.AbcTests_C)),
1200+
Type = typeof(FakeControllerWithInheritance.MostDerivedClass),
1201+
ModelMetadata = ModelMetadataFactory.CreateForType(typeof(FakeControllerWithInheritance.MostDerivedClass)),
12041202
},
12051203
],
1206-
supportedRequestFormats:
1207-
[
1208-
new ApiRequestFormat { MediaType = "application/json" },
1209-
]),
1204+
supportedRequestFormats: [new ApiRequestFormat { MediaType = "application/json" }]),
12101205
ApiDescriptionFactory.Create<FakeControllerWithInheritance>(
12111206
c => nameof(c.ActionWithDerivedObjectResponse),
12121207
groupName: "v1",
12131208
httpMethod: "GET",
12141209
relativePath: "resource",
12151210
parameterDescriptions: [],
1216-
supportedResponseTypes: [
1211+
supportedResponseTypes:
1212+
[
12171213
new ApiResponseType
12181214
{
12191215
ApiResponseFormats = [new ApiResponseFormat { MediaType = "application/json" }],
12201216
StatusCode = 200,
1221-
Type = typeof(FakeControllerWithInheritance.AbcTests_A),
1217+
Type = typeof(FakeControllerWithInheritance.BaseClass),
12221218
},
12231219
]),
12241220
ApiDescriptionFactory.Create<FakeControllerWithInheritance>(
@@ -1227,24 +1223,24 @@ public async Task GenerateSchema_PreservesMultiLevelInheritance()
12271223
httpMethod: "GET",
12281224
relativePath: "resourceB",
12291225
parameterDescriptions: [],
1230-
supportedResponseTypes: [
1226+
supportedResponseTypes:
1227+
[
12311228
new ApiResponseType
12321229
{
12331230
ApiResponseFormats = [new ApiResponseFormat { MediaType = "application/json" }],
12341231
StatusCode = 200,
1235-
Type = typeof(FakeControllerWithInheritance.AbcTests_B),
1232+
Type = typeof(FakeControllerWithInheritance.DerivedClass),
12361233
},
12371234
]),
12381235
],
12391236
configureSchemaGeneratorOptions: c =>
12401237
{
12411238
c.UseOneOfForPolymorphism = true;
12421239
c.SubTypesSelector =
1243-
(type) => (Type[])(
1244-
type == typeof(FakeControllerWithInheritance.AbcTests_A) ? [typeof(FakeControllerWithInheritance.AbcTests_B), typeof(FakeControllerWithInheritance.AbcTests_C)]
1245-
: type == typeof(FakeControllerWithInheritance.AbcTests_B) ? [typeof(FakeControllerWithInheritance.AbcTests_C)]
1246-
: []
1247-
);
1240+
(type) =>
1241+
type == typeof(FakeControllerWithInheritance.BaseClass) ? [typeof(FakeControllerWithInheritance.DerivedClass), typeof(FakeControllerWithInheritance.MostDerivedClass)]
1242+
: type == typeof(FakeControllerWithInheritance.DerivedClass) ? [typeof(FakeControllerWithInheritance.MostDerivedClass)]
1243+
: [];
12481244
}
12491245
);
12501246
var document = subject.GetSwagger("v1");

test/Swashbuckle.AspNetCore.SwaggerGen.Test/snapshots/VerifyTests.GenerateSchema_PreservesIntermediateBaseProperties_WhenUsingOneOfPolymorphism.DotNet10_0.verified.txt

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"content": {
1515
"application/json": {
1616
"schema": {
17-
"$ref": "#/components/schemas/AbcTests_C"
17+
"$ref": "#/components/schemas/MostDerivedClass"
1818
}
1919
}
2020
}
@@ -39,7 +39,7 @@
3939
"items": {
4040
"oneOf": [
4141
{
42-
"$ref": "#/components/schemas/AbcTests_C"
42+
"$ref": "#/components/schemas/MostDerivedClass"
4343
}
4444
]
4545
}
@@ -61,7 +61,7 @@
6161
"content": {
6262
"application/json": {
6363
"schema": {
64-
"$ref": "#/components/schemas/AbcTests_B"
64+
"$ref": "#/components/schemas/DerivedClass"
6565
}
6666
}
6767
}
@@ -72,43 +72,43 @@
7272
},
7373
"components": {
7474
"schemas": {
75-
"AbcTests_A": {
75+
"BaseClass": {
7676
"type": "object",
7777
"properties": {
78-
"PropA": {
78+
"BaseProperty": {
7979
"type": "string",
8080
"nullable": true
8181
}
8282
},
8383
"additionalProperties": false
8484
},
85-
"AbcTests_B": {
85+
"DerivedClass": {
8686
"type": "object",
8787
"properties": {
88-
"PropA": {
88+
"BaseProperty": {
8989
"type": "string",
9090
"nullable": true
9191
},
92-
"PropB": {
92+
"DerivedProperty": {
9393
"type": "string",
9494
"nullable": true
9595
}
9696
},
9797
"additionalProperties": false
9898
},
99-
"AbcTests_C": {
99+
"MostDerivedClass": {
100100
"type": "object",
101101
"allOf": [
102102
{
103-
"$ref": "#/components/schemas/AbcTests_A"
103+
"$ref": "#/components/schemas/BaseClass"
104104
}
105105
],
106106
"properties": {
107-
"PropB": {
107+
"DerivedProperty": {
108108
"type": "string",
109109
"nullable": true
110110
},
111-
"PropC": {
111+
"MoreDerivedProperty": {
112112
"type": "string",
113113
"nullable": true
114114
}

0 commit comments

Comments
 (0)