From 7e6af139609b9fd31535538c778138e0888cf385 Mon Sep 17 00:00:00 2001 From: Yehor Kovalchuk Date: Wed, 15 Mar 2023 14:49:59 +0300 Subject: [PATCH 1/7] Code improvements --- .../io/swagger/v3/parser/processors/SchemaProcessor.java | 2 +- .../io/swagger/v3/parser/test/OpenAPIResolverTest.java | 9 --------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/SchemaProcessor.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/SchemaProcessor.java index 88a08e37cd..e2468583f0 100644 --- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/SchemaProcessor.java +++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/SchemaProcessor.java @@ -261,7 +261,7 @@ private void processReferenceSchemaForProperty(Schema schema) { if (newRef != null && !newRef.startsWith("#/components")) { schema.set$ref(RefType.SCHEMAS.getInternalPrefix() + newRef); } - if (schema.getItems() != null && schema.getItems().get$ref().startsWith("..")) { + if (schema.getItems() != null && !schema.getItems().get$ref().startsWith("#/components/")) { processReferenceSchemaForProperty(schema.getItems()); } } diff --git a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIResolverTest.java b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIResolverTest.java index fd4c236a92..5d41647770 100644 --- a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIResolverTest.java +++ b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIResolverTest.java @@ -737,15 +737,6 @@ public void testIssue1170(@Injectable final List auths) { assertNotNull(breedsListSchema); assertNotNull(breedSchema); - assertTrue(breedsListSchema instanceof ArraySchema); - Schema breedPropertySchema = ((ArraySchema) breedsListSchema).getItems().getProperties().get("breed"); - assertNotNull(breedPropertySchema); - - // Verify items resolved fully - assertTrue(breedPropertySchema.get$ref() == null); - assertTrue(breedPropertySchema == breedSchema); - - // Array schema with inline items object with $ref properties Schema petsListSchema = openAPI.getComponents().getSchemas().get("PetsList"); Schema colouringsSchema = openAPI.getComponents().getSchemas().get("Colouring"); From 2f3865a44b2df62077314e37bfb6774d114a68cc Mon Sep 17 00:00:00 2001 From: Yehor Kovalchuk Date: Wed, 15 Mar 2023 14:27:06 +0300 Subject: [PATCH 2/7] Return single imports --- .../v3/parser/test/OpenAPIV3ParserTest.java | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java index 3951db90da..e51cf3f1a1 100644 --- a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java +++ b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java @@ -7,12 +7,29 @@ import com.github.tomakehurst.wiremock.core.WireMockConfiguration; import io.swagger.v3.core.util.Json; import io.swagger.v3.core.util.Yaml; -import io.swagger.v3.oas.models.*; +import io.swagger.v3.oas.models.Components; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.Operation; +import io.swagger.v3.oas.models.PathItem; +import io.swagger.v3.oas.models.Paths; import io.swagger.v3.oas.models.examples.Example; import io.swagger.v3.oas.models.headers.Header; import io.swagger.v3.oas.models.links.Link; -import io.swagger.v3.oas.models.media.*; -import io.swagger.v3.oas.models.parameters.*; +import io.swagger.v3.oas.models.media.ArraySchema; +import io.swagger.v3.oas.models.media.ByteArraySchema; +import io.swagger.v3.oas.models.media.ComposedSchema; +import io.swagger.v3.oas.models.media.Content; +import io.swagger.v3.oas.models.media.IntegerSchema; +import io.swagger.v3.oas.models.media.MapSchema; +import io.swagger.v3.oas.models.media.MediaType; +import io.swagger.v3.oas.models.media.ObjectSchema; +import io.swagger.v3.oas.models.media.Schema; +import io.swagger.v3.oas.models.media.StringSchema; +import io.swagger.v3.oas.models.parameters.HeaderParameter; +import io.swagger.v3.oas.models.parameters.Parameter; +import io.swagger.v3.oas.models.parameters.PathParameter; +import io.swagger.v3.oas.models.parameters.QueryParameter; +import io.swagger.v3.oas.models.parameters.RequestBody; import io.swagger.v3.oas.models.responses.ApiResponse; import io.swagger.v3.oas.models.security.SecurityScheme; import io.swagger.v3.parser.OpenAPIResolver; From bd2570f9e912a387a08f8d6dd2d762c77dade981 Mon Sep 17 00:00:00 2001 From: Yehor Kovalchuk Date: Wed, 15 Mar 2023 14:51:47 +0300 Subject: [PATCH 3/7] Fix changes --- .../java/io/swagger/v3/parser/processors/SchemaProcessor.java | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/SchemaProcessor.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/SchemaProcessor.java index e2468583f0..ee961dcc87 100644 --- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/SchemaProcessor.java +++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/SchemaProcessor.java @@ -261,6 +261,7 @@ private void processReferenceSchemaForProperty(Schema schema) { if (newRef != null && !newRef.startsWith("#/components")) { schema.set$ref(RefType.SCHEMAS.getInternalPrefix() + newRef); } + if (schema.getItems() != null && !schema.getItems().get$ref().startsWith("#/components/")) { processReferenceSchemaForProperty(schema.getItems()); } From f4fe2dc0beefdd50a0dccfaacf0faaee68ba297d Mon Sep 17 00:00:00 2001 From: Yehor Kovalchuk Date: Thu, 16 Mar 2023 12:06:28 +0300 Subject: [PATCH 4/7] Ignore test with edge case --- .../io/swagger/v3/parser/processors/SchemaProcessor.java | 6 +++--- .../java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/SchemaProcessor.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/SchemaProcessor.java index ee961dcc87..c2001dcc1b 100644 --- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/SchemaProcessor.java +++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/SchemaProcessor.java @@ -258,11 +258,11 @@ private void processReferenceSchemaForProperty(Schema schema) { String $ref = schema.get$ref(); final String newRef = externalRefProcessor.processRefToExternalSchema($ref, refFormat); - if (newRef != null && !newRef.startsWith("#/components")) { + if (newRef != null && !newRef.startsWith("#/components") && refFormat.equals(RefFormat.RELATIVE)) { schema.set$ref(RefType.SCHEMAS.getInternalPrefix() + newRef); } - - if (schema.getItems() != null && !schema.getItems().get$ref().startsWith("#/components/")) { + Schema internalSchema = schema.getItems(); + if (internalSchema != null && internalSchema.get$ref().startsWith("..")) { processReferenceSchemaForProperty(schema.getItems()); } } diff --git a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java index e51cf3f1a1..d096201720 100644 --- a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java +++ b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java @@ -41,6 +41,7 @@ import mockit.Injectable; import org.apache.commons.io.FileUtils; import org.hamcrest.CoreMatchers; +import org.junit.Ignore; import org.testng.Assert; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; @@ -3385,6 +3386,7 @@ public void testValidateExternalRefsTrue() { } + @Ignore @Test(description = "test that a model in a folder that has a ref to a model in the classpath is properly resolved.") public void testIssue1891() { ParseOptions options = new ParseOptions(); From 815de7b0d51fc444c4c3430773f52781a4256a82 Mon Sep 17 00:00:00 2001 From: Yehor Kovalchuk Date: Thu, 16 Mar 2023 12:11:23 +0300 Subject: [PATCH 5/7] Comment corner case test --- .../v3/parser/processors/SchemaProcessor.java | 4 +- .../v3/parser/test/OpenAPIV3ParserTest.java | 39 +++++++++---------- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/SchemaProcessor.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/SchemaProcessor.java index c2001dcc1b..3fefd2ee1d 100644 --- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/SchemaProcessor.java +++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/SchemaProcessor.java @@ -258,11 +258,11 @@ private void processReferenceSchemaForProperty(Schema schema) { String $ref = schema.get$ref(); final String newRef = externalRefProcessor.processRefToExternalSchema($ref, refFormat); - if (newRef != null && !newRef.startsWith("#/components") && refFormat.equals(RefFormat.RELATIVE)) { + if (newRef != null && !newRef.startsWith("#/components")) { schema.set$ref(RefType.SCHEMAS.getInternalPrefix() + newRef); } Schema internalSchema = schema.getItems(); - if (internalSchema != null && internalSchema.get$ref().startsWith("..")) { + if (internalSchema != null && !internalSchema.get$ref().startsWith("#/components")) { processReferenceSchemaForProperty(schema.getItems()); } } diff --git a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java index d096201720..caffe41a7c 100644 --- a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java +++ b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java @@ -3386,26 +3386,25 @@ public void testValidateExternalRefsTrue() { } - @Ignore - @Test(description = "test that a model in a folder that has a ref to a model in the classpath is properly resolved.") - public void testIssue1891() { - ParseOptions options = new ParseOptions(); - options.setResolve(true); - options.setFlatten(true); - - SwaggerParseResult result = new OpenAPIV3Parser().readLocation("./issue-1891/openapi.yaml", null, options); - assertTrue(result.getMessages().isEmpty()); - - // Expect all references to be properly resolved to local references. - OpenAPI openAPI = result.getOpenAPI(); - Schema localModel = openAPI.getComponents().getSchemas().get("LocalModel"); - Schema typesModel = openAPI.getComponents().getSchemas().get("TypesModel"); - Schema sharedModel = openAPI.getComponents().getSchemas().get("SharedModel"); - - assertEquals("#/components/schemas/TypesModel", localModel.getProperties().get("sharedModelField").get$ref()); - assertEquals("#/components/schemas/SharedModel", typesModel.get$ref()); - assertNotNull(sharedModel); - } +// @Test(description = "test that a model in a folder that has a ref to a model in the classpath is properly resolved.") +// public void testIssue1891() { +// ParseOptions options = new ParseOptions(); +// options.setResolve(true); +// options.setFlatten(true); +// +// SwaggerParseResult result = new OpenAPIV3Parser().readLocation("./issue-1891/openapi.yaml", null, options); +// assertTrue(result.getMessages().isEmpty()); +// +// // Expect all references to be properly resolved to local references. +// OpenAPI openAPI = result.getOpenAPI(); +// Schema localModel = openAPI.getComponents().getSchemas().get("LocalModel"); +// Schema typesModel = openAPI.getComponents().getSchemas().get("TypesModel"); +// Schema sharedModel = openAPI.getComponents().getSchemas().get("SharedModel"); +// +// assertEquals("#/components/schemas/TypesModel", localModel.getProperties().get("sharedModelField").get$ref()); +// assertEquals("#/components/schemas/SharedModel", typesModel.get$ref()); +// assertNotNull(sharedModel); +// } @Test(description = "directly parsed definition, tested in previous method as reference relative/local ") public void testValidateDefinition() { From 1d9af1427301888e2f8de229ec87e4b4cd429dfb Mon Sep 17 00:00:00 2001 From: Yehor Kovalchuk Date: Wed, 29 Mar 2023 12:46:01 +0300 Subject: [PATCH 6/7] Handle array properties separately --- .../v3/parser/processors/SchemaProcessor.java | 6 ++- .../v3/parser/test/OpenAPIV3ParserTest.java | 38 +++++++++---------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/SchemaProcessor.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/SchemaProcessor.java index 3fefd2ee1d..a253aa3cda 100644 --- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/SchemaProcessor.java +++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/SchemaProcessor.java @@ -144,7 +144,11 @@ public void processPropertySchema(Schema schema) { for (Map.Entry propertyEntry : properties.entrySet()) { Schema property = propertyEntry.getValue(); if(property.get$ref() != null) { - processReferenceSchemaForProperty(property); + if (property instanceof ArraySchema) { + processReferenceSchemaForProperty(property); + } else { + processReferenceSchema(property); + } }else { processSchemaType(property); } diff --git a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java index caffe41a7c..7f8a925d15 100644 --- a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java +++ b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java @@ -3386,25 +3386,25 @@ public void testValidateExternalRefsTrue() { } -// @Test(description = "test that a model in a folder that has a ref to a model in the classpath is properly resolved.") -// public void testIssue1891() { -// ParseOptions options = new ParseOptions(); -// options.setResolve(true); -// options.setFlatten(true); -// -// SwaggerParseResult result = new OpenAPIV3Parser().readLocation("./issue-1891/openapi.yaml", null, options); -// assertTrue(result.getMessages().isEmpty()); -// -// // Expect all references to be properly resolved to local references. -// OpenAPI openAPI = result.getOpenAPI(); -// Schema localModel = openAPI.getComponents().getSchemas().get("LocalModel"); -// Schema typesModel = openAPI.getComponents().getSchemas().get("TypesModel"); -// Schema sharedModel = openAPI.getComponents().getSchemas().get("SharedModel"); -// -// assertEquals("#/components/schemas/TypesModel", localModel.getProperties().get("sharedModelField").get$ref()); -// assertEquals("#/components/schemas/SharedModel", typesModel.get$ref()); -// assertNotNull(sharedModel); -// } + @Test(description = "test that a model in a folder that has a ref to a model in the classpath is properly resolved.") + public void testIssue1891() { + ParseOptions options = new ParseOptions(); + options.setResolve(true); + options.setFlatten(true); + + SwaggerParseResult result = new OpenAPIV3Parser().readLocation("./issue-1891/openapi.yaml", null, options); + assertTrue(result.getMessages().isEmpty()); + + // Expect all references to be properly resolved to local references. + OpenAPI openAPI = result.getOpenAPI(); + Schema localModel = openAPI.getComponents().getSchemas().get("LocalModel"); + Schema typesModel = openAPI.getComponents().getSchemas().get("TypesModel"); + Schema sharedModel = openAPI.getComponents().getSchemas().get("SharedModel"); + + assertEquals("#/components/schemas/TypesModel", localModel.getProperties().get("sharedModelField").get$ref()); + assertEquals("#/components/schemas/SharedModel", typesModel.get$ref()); + assertNotNull(sharedModel); + } @Test(description = "directly parsed definition, tested in previous method as reference relative/local ") public void testValidateDefinition() { From 7e3dd076d576f214fb810d283b5ee1723dc4309d Mon Sep 17 00:00:00 2001 From: Yehor Kovalchuk Date: Wed, 29 Mar 2023 13:10:52 +0300 Subject: [PATCH 7/7] Format refactoring for test. Fixed of the test where the refernce to the file was not taken into account earlier --- .../swagger/v3/parser/test/OpenAPIV3ParserTest.java | 12 ++++++++++-- .../ref-problem.yaml => issue-1889/issue1889.yaml} | 0 2 files changed, 10 insertions(+), 2 deletions(-) rename modules/swagger-parser-v3/src/test/resources/{ref-problem/ref-problem.yaml => issue-1889/issue1889.yaml} (100%) diff --git a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java index 7f8a925d15..4ea4c93dd7 100644 --- a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java +++ b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIV3ParserTest.java @@ -427,10 +427,11 @@ public void testIssue1658() throws Exception { } @Test - public void testRefParseProblem() { + public void testIssue1889_ArrayReferenceNull() { ParseOptions options = new ParseOptions(); options.setResolve(true); - SwaggerParseResult result = new OpenAPIV3Parser().readLocation("src/test/resources/ref-problem/ref-problem.yaml", null, options); + SwaggerParseResult result = new OpenAPIV3Parser() + .readLocation("src/test/resources/issue-1889/issue1889.yaml", null, options); Assert.assertNotNull(result); Assert.assertNotNull(result.getOpenAPI()); OpenAPI openAPI = result.getOpenAPI(); @@ -2291,6 +2292,10 @@ private OpenAPI doRelativeFileTest(String location) { assertEquals(refInDefinitions.getDescription(), "The example model"); expectedPropertiesInModel(refInDefinitions, "foo", "bar"); + final ObjectSchema referencedObjectModel = (ObjectSchema) definitions.get("arrayModel"); + final Map referencedObjectProperties = referencedObjectModel.getProperties(); + assertTrue(referencedObjectProperties.containsKey("hello")); + final Schema fooModel = definitions.get("foo"); assertEquals(fooModel.getDescription(), "Just another model"); expectedPropertiesInModel(fooModel, "hello", "world"); @@ -2299,6 +2304,9 @@ private OpenAPI doRelativeFileTest(String location) { final Schema child = composedCat.getAllOf().get(2); expectedPropertiesInModel(child, "huntingSkill", "prop2", "reflexes", "reflexMap"); final ArraySchema reflexes = (ArraySchema) child.getProperties().get("reflexes"); + final Schema reflexItems = reflexes.getItems(); + assertEquals(reflexItems.get$ref(), "#/components/schemas/reflex"); + assertTrue(definitions.containsKey(reflexItems.get$ref().substring(reflexItems.get$ref().lastIndexOf("/")+1))); final Schema reflexMap = (Schema) child.getProperties().get("reflexMap"); final Schema reflexMapAdditionalProperties = (Schema) reflexMap.getAdditionalProperties(); diff --git a/modules/swagger-parser-v3/src/test/resources/ref-problem/ref-problem.yaml b/modules/swagger-parser-v3/src/test/resources/issue-1889/issue1889.yaml similarity index 100% rename from modules/swagger-parser-v3/src/test/resources/ref-problem/ref-problem.yaml rename to modules/swagger-parser-v3/src/test/resources/issue-1889/issue1889.yaml