@@ -1020,13 +1020,43 @@ def test_build_schemas(mocker):
10201020 assert result .errors == [error ]
10211021
10221022
1023- def test_build_parse_error_on_reference ():
1023+ def test_build_parse_error_on_unknown_local_reference ():
10241024 from openapi_python_client .parser .openapi import build_schemas
10251025
1026- ref_schema = oai .Reference .construct ()
1026+ ref_schema = oai .Reference .construct (ref = "#/foobar" )
10271027 in_data = {"1" : ref_schema }
10281028 result = build_schemas (components = in_data )
1029- assert result .errors [0 ] == PropertyError (data = ref_schema , detail = "Reference schemas are not supported." )
1029+ assert result .errors [0 ] == PropertyError (data = ref_schema , detail = "Failed to resolve local reference schemas." )
1030+
1031+
1032+ def test_build_parse_success_on_known_local_reference (mocker ):
1033+ from openapi_python_client .parser .openapi import build_schemas
1034+
1035+ build_model_property = mocker .patch (f"{ MODULE_NAME } .build_model_property" )
1036+ schemas = mocker .MagicMock ()
1037+ build_enum_property = mocker .patch (f"{ MODULE_NAME } .build_enum_property" , return_value = (mocker .MagicMock (), schemas ))
1038+ in_data = {"1" : oai .Reference .construct (ref = "#/foobar" ), "foobar" : mocker .MagicMock (enum = ["val1" , "val2" , "val3" ])}
1039+
1040+ result = build_schemas (components = in_data )
1041+
1042+ assert len (result .errors ) == 0
1043+ assert result .enums ["1" ] == result .enums ["foobar" ]
1044+
1045+
1046+ def test_build_parse_error_on_remote_reference ():
1047+ from openapi_python_client .parser .openapi import build_schemas
1048+
1049+ ref_schemas = [
1050+ oai .Reference .construct (ref = "http://foobar/../foobar.yaml#/foobar" ),
1051+ oai .Reference .construct (ref = "https://foobar/foobar.yaml#/foobar" ),
1052+ oai .Reference .construct (ref = "../foobar.yaml#/foobar" ),
1053+ oai .Reference .construct (ref = "foobar.yaml#/foobar" ),
1054+ oai .Reference .construct (ref = "//foobar#/foobar" ),
1055+ ]
1056+ for ref_schema in ref_schemas :
1057+ in_data = {"1" : ref_schema }
1058+ result = build_schemas (components = in_data )
1059+ assert result .errors [0 ] == PropertyError (data = ref_schema , detail = "Remote reference schemas are not supported." )
10301060
10311061
10321062def test_build_enums (mocker ):
@@ -1191,3 +1221,171 @@ def test_build_enum_property_bad_default():
11911221
11921222 assert schemas == schemas
11931223 assert err == PropertyError (detail = "B is an invalid default for enum Existing" , data = data )
1224+
1225+
1226+ def test__is_local_reference ():
1227+ from openapi_python_client .parser .properties import _is_local_reference
1228+
1229+ data_set = [
1230+ ("//foobar#foobar" , False ),
1231+ ("foobar#/foobar" , False ),
1232+ ("foobar.json" , False ),
1233+ ("foobar.yaml" , False ),
1234+ ("../foo/bar.json#/foobar" , False ),
1235+ ("#/foobar" , True ),
1236+ ("#/foo/bar" , True ),
1237+ ]
1238+
1239+ for data , expected_result in data_set :
1240+ ref = oai .Reference .construct (ref = data )
1241+ assert _is_local_reference (ref ) == expected_result
1242+
1243+
1244+ def test__reference_name ():
1245+ from openapi_python_client .parser .properties import _reference_name
1246+
1247+ data_set = [
1248+ ("#/foobar" , "foobar" ),
1249+ ("#/foo/bar" , "bar" ),
1250+ ]
1251+
1252+ for data , expected_result in data_set :
1253+ ref = oai .Reference .construct (ref = data )
1254+ assert _reference_name (ref ) == expected_result
1255+
1256+
1257+ def test__reference_model_name ():
1258+ from openapi_python_client .parser .properties import _reference_model_name
1259+
1260+ data_set = [
1261+ ("#/foobar" , "Foobar" ),
1262+ ("#/foo/bar" , "Bar" ),
1263+ ]
1264+
1265+ for data , expected_result in data_set :
1266+ ref = oai .Reference .construct (ref = data )
1267+ assert _reference_model_name (ref ) == expected_result
1268+
1269+
1270+ def test__resolve_model_or_enum_reference (mocker ):
1271+ from openapi_python_client .parser .properties import _resolve_model_or_enum_reference
1272+ from openapi_python_client .parser .properties .schemas import Schemas
1273+
1274+ references_by_name = {
1275+ "FooBarReferenceLoop" : oai .Reference .construct (ref = "#/foobar" ),
1276+ "FooBarDeeperReferenceLoop" : oai .Reference .construct (ref = "#/FooBarReferenceLoop" ),
1277+ "BarFooReferenceLoop" : oai .Reference .construct (ref = "#/barfoo" ),
1278+ "BarFooDeeperReferenceLoop" : oai .Reference .construct (ref = "#/BarFooReferenceLoop" ),
1279+ "InfiniteReferenceLoop" : oai .Reference .construct (ref = "#/InfiniteReferenceLoop" ),
1280+ "UnknownReference" : oai .Reference .construct (ref = "#/unknown" ),
1281+ }
1282+ schemas = Schemas (enums = {"Foobar" : 1 }, models = {"Barfoo" : 2 })
1283+
1284+ res_1 = _resolve_model_or_enum_reference (
1285+ "FooBarReferenceLoop" , references_by_name ["FooBarReferenceLoop" ], schemas , references_by_name
1286+ )
1287+ res_2 = _resolve_model_or_enum_reference (
1288+ "FooBarDeeperReferenceLoop" , references_by_name ["FooBarDeeperReferenceLoop" ], schemas , references_by_name
1289+ )
1290+ res_3 = _resolve_model_or_enum_reference (
1291+ "BarFooReferenceLoop" , references_by_name ["BarFooReferenceLoop" ], schemas , references_by_name
1292+ )
1293+ res_4 = _resolve_model_or_enum_reference (
1294+ "BarFooDeeperReferenceLoop" , references_by_name ["BarFooDeeperReferenceLoop" ], schemas , references_by_name
1295+ )
1296+ res_5 = _resolve_model_or_enum_reference (
1297+ "InfiniteReferenceLoop" , references_by_name ["InfiniteReferenceLoop" ], schemas , references_by_name
1298+ )
1299+ res_6 = _resolve_model_or_enum_reference (
1300+ "UnknownReference" , references_by_name ["UnknownReference" ], schemas , references_by_name
1301+ )
1302+
1303+ assert res_1 == schemas .enums ["Foobar" ]
1304+ assert res_2 == schemas .enums ["Foobar" ]
1305+ assert res_3 == schemas .models ["Barfoo" ]
1306+ assert res_4 == schemas .models ["Barfoo" ]
1307+ assert res_5 == None
1308+ assert res_6 == None
1309+
1310+
1311+ def test__resolve_local_reference_schema (mocker ):
1312+ from openapi_python_client .parser .properties import _resolve_local_reference_schema
1313+ from openapi_python_client .parser .properties .enum_property import EnumProperty
1314+ from openapi_python_client .parser .properties .model_property import ModelProperty
1315+ from openapi_python_client .parser .properties .schemas import Schemas
1316+
1317+ references_by_name = {
1318+ "FooBarReferenceLoop" : oai .Reference .construct (ref = "#/foobar" ),
1319+ "FooBarDeeperReferenceLoop" : oai .Reference .construct (ref = "#/FooBarReferenceLoop" ),
1320+ "fooBarLowerCaseReferenceLoop" : oai .Reference .construct (ref = "#/foobar" ),
1321+ "fooBarLowerCaseDeeperReferenceLoop" : oai .Reference .construct (ref = "#/fooBarLowerCaseReferenceLoop" ),
1322+ "BarFooReferenceLoop" : oai .Reference .construct (ref = "#/barfoo" ),
1323+ "BarFooDeeperReferenceLoop" : oai .Reference .construct (ref = "#/BarFooReferenceLoop" ),
1324+ "InfiniteReferenceLoop" : oai .Reference .construct (ref = "#/InfiniteReferenceLoop" ),
1325+ "UnknownReference" : oai .Reference .construct (ref = "#/unknown" ),
1326+ }
1327+ schemas = Schemas (
1328+ enums = {
1329+ "Foobar" : EnumProperty (
1330+ name = "Foobar" ,
1331+ required = False ,
1332+ nullable = True ,
1333+ default = "foobar" ,
1334+ values = ["foobar" ],
1335+ value_type = "str" ,
1336+ reference = "" ,
1337+ )
1338+ },
1339+ models = {
1340+ "Barfoo" : ModelProperty (
1341+ name = "Barfoo" ,
1342+ required = False ,
1343+ nullable = True ,
1344+ default = "barfoo" ,
1345+ reference = "" ,
1346+ required_properties = [],
1347+ optional_properties = [],
1348+ description = "" ,
1349+ relative_imports = [],
1350+ additional_properties = [],
1351+ )
1352+ },
1353+ )
1354+
1355+ res_1 = _resolve_local_reference_schema (
1356+ "FooBarReferenceLoop" , references_by_name ["FooBarReferenceLoop" ], schemas , references_by_name
1357+ )
1358+ res_2 = _resolve_local_reference_schema (
1359+ "FooBarDeeperReferenceLoop" , references_by_name ["FooBarDeeperReferenceLoop" ], schemas , references_by_name
1360+ )
1361+ res_3 = _resolve_local_reference_schema (
1362+ "BarFooReferenceLoop" , references_by_name ["BarFooReferenceLoop" ], schemas , references_by_name
1363+ )
1364+ res_4 = _resolve_local_reference_schema (
1365+ "BarFooDeeperReferenceLoop" , references_by_name ["BarFooDeeperReferenceLoop" ], schemas , references_by_name
1366+ )
1367+ res_5 = _resolve_local_reference_schema (
1368+ "fooBarLowerCaseReferenceLoop" , references_by_name ["fooBarLowerCaseReferenceLoop" ], schemas , references_by_name
1369+ )
1370+ res_6 = _resolve_local_reference_schema (
1371+ "fooBarLowerCaseDeeperReferenceLoop" ,
1372+ references_by_name ["fooBarLowerCaseDeeperReferenceLoop" ],
1373+ schemas ,
1374+ references_by_name ,
1375+ )
1376+ res_7 = _resolve_local_reference_schema (
1377+ "InfiniteReferenceLoop" , references_by_name ["InfiniteReferenceLoop" ], schemas , references_by_name
1378+ )
1379+ res_8 = _resolve_local_reference_schema (
1380+ "UnknownReference" , references_by_name ["UnknownReference" ], schemas , references_by_name
1381+ )
1382+
1383+ assert res_1 == res_2 == res_3 == res_4 == res_5 == res_6 == schemas
1384+ assert schemas .enums ["FooBarReferenceLoop" ] == schemas .enums ["Foobar" ]
1385+ assert schemas .enums ["FooBarDeeperReferenceLoop" ] == schemas .enums ["Foobar" ]
1386+ assert schemas .models ["BarFooReferenceLoop" ] == schemas .models ["Barfoo" ]
1387+ assert schemas .models ["BarFooDeeperReferenceLoop" ] == schemas .models ["Barfoo" ]
1388+ assert schemas .enums ["FooBarLowerCaseReferenceLoop" ] == schemas .enums ["Foobar" ]
1389+ assert schemas .enums ["FooBarLowerCaseDeeperReferenceLoop" ] == schemas .enums ["Foobar" ]
1390+ assert isinstance (res_7 , PropertyError )
1391+ assert isinstance (res_8 , PropertyError )
0 commit comments