@@ -1004,6 +1004,124 @@ await VerifyOpenApiDocument(builder, document =>
1004
1004
} ) ;
1005
1005
}
1006
1006
1007
+ // Test for: https://github.com/dotnet/aspnetcore/issues/63503
1008
+ [ Fact ]
1009
+ public async Task HandlesCircularReferencesRegardlessOfPropertyOrder_SelfFirst ( )
1010
+ {
1011
+ var builder = CreateBuilder ( ) ;
1012
+ builder . MapPost ( "/" , ( DirectCircularModelSelfFirst dto ) => { } ) ;
1013
+
1014
+ // Assert
1015
+ await VerifyOpenApiDocument ( builder , document =>
1016
+ {
1017
+ Assert . NotNull ( document . Components ? . Schemas ) ;
1018
+ var schema = document . Components . Schemas [ "DirectCircularModelSelfFirst" ] ;
1019
+ Assert . Equal ( JsonSchemaType . Object , schema . Type ) ;
1020
+ Assert . NotNull ( schema . Properties ) ;
1021
+ Assert . Collection ( schema . Properties ,
1022
+ property =>
1023
+ {
1024
+ Assert . Equal ( "self" , property . Key ) ;
1025
+ var reference = Assert . IsType < OpenApiSchemaReference > ( property . Value ) ;
1026
+ Assert . Equal ( "#/components/schemas/DirectCircularModelSelfFirst" , reference . Reference . ReferenceV3 ) ;
1027
+ } ,
1028
+ property =>
1029
+ {
1030
+ Assert . Equal ( "referenced" , property . Key ) ;
1031
+ var reference = Assert . IsType < OpenApiSchemaReference > ( property . Value ) ;
1032
+ } ) ;
1033
+
1034
+ // Verify that it does not result in an empty schema for a referenced schema
1035
+ var referencedSchema = document . Components . Schemas [ "ReferencedModel" ] ;
1036
+ Assert . NotNull ( referencedSchema . Properties ) ;
1037
+ Assert . NotEmpty ( referencedSchema . Properties ) ;
1038
+ var idProperty = Assert . Single ( referencedSchema . Properties ) ;
1039
+ Assert . Equal ( "id" , idProperty . Key ) ;
1040
+ var idPropertySchema = Assert . IsType < OpenApiSchema > ( idProperty . Value ) ;
1041
+ Assert . Equal ( JsonSchemaType . Integer , idPropertySchema . Type ) ;
1042
+ } ) ;
1043
+ }
1044
+
1045
+ // Test for: https://github.com/dotnet/aspnetcore/issues/63503
1046
+ [ Fact ]
1047
+ public async Task HandlesCircularReferencesRegardlessOfPropertyOrder_SelfLast ( )
1048
+ {
1049
+ var builder = CreateBuilder ( ) ;
1050
+ builder . MapPost ( "/" , ( DirectCircularModelSelfLast dto ) => { } ) ;
1051
+
1052
+ await VerifyOpenApiDocument ( builder , document =>
1053
+ {
1054
+ Assert . NotNull ( document . Components ? . Schemas ) ;
1055
+ var schema = document . Components . Schemas [ "DirectCircularModelSelfLast" ] ;
1056
+ Assert . Equal ( JsonSchemaType . Object , schema . Type ) ;
1057
+ Assert . NotNull ( schema . Properties ) ;
1058
+ Assert . Collection ( schema . Properties ,
1059
+ property =>
1060
+ {
1061
+ Assert . Equal ( "referenced" , property . Key ) ;
1062
+ var reference = Assert . IsType < OpenApiSchemaReference > ( property . Value ) ;
1063
+ } ,
1064
+ property =>
1065
+ {
1066
+ Assert . Equal ( "self" , property . Key ) ;
1067
+ var reference = Assert . IsType < OpenApiSchemaReference > ( property . Value ) ;
1068
+ Assert . Equal ( "#/components/schemas/DirectCircularModelSelfLast" , reference . Reference . ReferenceV3 ) ;
1069
+ } ) ;
1070
+
1071
+ // Verify that it does not result in an empty schema for a referenced schema
1072
+ var referencedSchema = document . Components . Schemas [ "ReferencedModel" ] ;
1073
+ Assert . NotNull ( referencedSchema . Properties ) ;
1074
+ Assert . NotEmpty ( referencedSchema . Properties ) ;
1075
+ var idProperty = Assert . Single ( referencedSchema . Properties ) ;
1076
+ Assert . Equal ( "id" , idProperty . Key ) ;
1077
+ var idPropertySchema = Assert . IsType < OpenApiSchema > ( idProperty . Value ) ;
1078
+ Assert . Equal ( JsonSchemaType . Integer , idPropertySchema . Type ) ;
1079
+ } ) ;
1080
+ }
1081
+
1082
+ // Test for: https://github.com/dotnet/aspnetcore/issues/63503
1083
+ [ Fact ]
1084
+ public async Task HandlesCircularReferencesRegardlessOfPropertyOrder_MultipleSelf ( )
1085
+ {
1086
+ var builder = CreateBuilder ( ) ;
1087
+ builder . MapPost ( "/" , ( DirectCircularModelMultiple dto ) => { } ) ;
1088
+
1089
+ await VerifyOpenApiDocument ( builder , document =>
1090
+ {
1091
+ Assert . NotNull ( document . Components ? . Schemas ) ;
1092
+ var schema = document . Components . Schemas [ "DirectCircularModelMultiple" ] ;
1093
+ Assert . Equal ( JsonSchemaType . Object , schema . Type ) ;
1094
+ Assert . NotNull ( schema . Properties ) ;
1095
+ Assert . Collection ( schema . Properties ,
1096
+ property =>
1097
+ {
1098
+ Assert . Equal ( "selfFirst" , property . Key ) ;
1099
+ var reference = Assert . IsType < OpenApiSchemaReference > ( property . Value ) ;
1100
+ Assert . Equal ( "#/components/schemas/DirectCircularModelMultiple" , reference . Reference . ReferenceV3 ) ;
1101
+ } ,
1102
+ property =>
1103
+ {
1104
+ Assert . Equal ( "referenced" , property . Key ) ;
1105
+ var reference = Assert . IsType < OpenApiSchemaReference > ( property . Value ) ;
1106
+ } ,
1107
+ property =>
1108
+ {
1109
+ Assert . Equal ( "selfLast" , property . Key ) ;
1110
+ var reference = Assert . IsType < OpenApiSchemaReference > ( property . Value ) ;
1111
+ Assert . Equal ( "#/components/schemas/DirectCircularModelMultiple" , reference . Reference . ReferenceV3 ) ;
1112
+ } ) ;
1113
+
1114
+ // Verify that it does not result in an empty schema for a referenced schema
1115
+ var referencedSchema = document . Components . Schemas [ "ReferencedModel" ] ;
1116
+ Assert . NotNull ( referencedSchema . Properties ) ;
1117
+ Assert . NotEmpty ( referencedSchema . Properties ) ;
1118
+ var idProperty = Assert . Single ( referencedSchema . Properties ) ;
1119
+ Assert . Equal ( "id" , idProperty . Key ) ;
1120
+ var idPropertySchema = Assert . IsType < OpenApiSchema > ( idProperty . Value ) ;
1121
+ Assert . Equal ( JsonSchemaType . Integer , idPropertySchema . Type ) ;
1122
+ } ) ;
1123
+ }
1124
+
1007
1125
// Test models for issue 61194
1008
1126
private class Config
1009
1127
{
@@ -1060,5 +1178,30 @@ public sealed class RefUser
1060
1178
public string Name { get ; set ; } = "" ;
1061
1179
public string Email { get ; set ; } = "" ;
1062
1180
}
1181
+
1182
+ // Test models for issue 63503
1183
+ private class DirectCircularModelSelfFirst
1184
+ {
1185
+ public DirectCircularModelSelfFirst Self { get ; set ; } = null ! ;
1186
+ public ReferencedModel Referenced { get ; set ; } = null ! ;
1187
+ }
1188
+
1189
+ private class DirectCircularModelSelfLast
1190
+ {
1191
+ public ReferencedModel Referenced { get ; set ; } = null ! ;
1192
+ public DirectCircularModelSelfLast Self { get ; set ; } = null ! ;
1193
+ }
1194
+
1195
+ private class DirectCircularModelMultiple
1196
+ {
1197
+ public DirectCircularModelMultiple SelfFirst { get ; set ; } = null ! ;
1198
+ public ReferencedModel Referenced { get ; set ; } = null ! ;
1199
+ public DirectCircularModelMultiple SelfLast { get ; set ; } = null ! ;
1200
+ }
1201
+
1202
+ private class ReferencedModel
1203
+ {
1204
+ public int Id { get ; set ; }
1205
+ }
1063
1206
}
1064
1207
#nullable restore
0 commit comments