From ac4efc2077d8b969f9efef8d2a3cfbde30c9f316 Mon Sep 17 00:00:00 2001 From: MicRyc Date: Tue, 15 Oct 2024 15:05:22 +0200 Subject: [PATCH] Add tests for setResolveResponses flag/ Fix existing ones --- .../parser/processors/OperationProcessor.java | 4 +- .../v3/parser/test/NetworkReferenceTest.java | 1 + .../v3/parser/test/OpenAPIResolverTest.java | 9 +- .../v3/parser/test/OpenAPIV3ParserTest.java | 43 +++- .../resources/resolve-responses-test.yaml | 200 ++++++++++++++++++ 5 files changed, 251 insertions(+), 6 deletions(-) create mode 100644 modules/swagger-parser-v3/src/test/resources/resolve-responses-test.yaml diff --git a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/OperationProcessor.java b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/OperationProcessor.java index 3a73be51db..351af1990b 100644 --- a/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/OperationProcessor.java +++ b/modules/swagger-parser-v3/src/main/java/io/swagger/v3/parser/processors/OperationProcessor.java @@ -70,8 +70,8 @@ public void processOperation(Operation operation) { for (String responseCode : responses.keySet()) { ApiResponse response = responses.get(responseCode); if(response != null) { - //This part allows parser to put response inline without the resolveFully option set to true - if (response.get$ref() != null && cache != null && cache.getParseOptions() != null && cache.getParseOptions().isResolveResponses()) { + //This part allows parser to put response inline within resolveResponses or ResolveFully + if (response.get$ref() != null && cache != null && cache.getParseOptions() != null && (cache.getParseOptions().isResolveResponses() || cache.getParseOptions().isResolveFully())) { responseProcessor.processResponse(response); diff --git a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/NetworkReferenceTest.java b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/NetworkReferenceTest.java index 081dc264f1..96ed91bad6 100644 --- a/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/NetworkReferenceTest.java +++ b/modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/NetworkReferenceTest.java @@ -272,6 +272,7 @@ public void testIssue411() throws Exception { OpenAPIV3Parser parser = new OpenAPIV3Parser(); ParseOptions options = new ParseOptions(); options.setResolve(true); + options.setResolveResponses(true); SwaggerParseResult result = parser.readLocation("http://remote1/resources/swagger.yaml", auths, options); OpenAPI swagger = result.getOpenAPI(); 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 5820e23775..36117dd216 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 @@ -766,8 +766,9 @@ public void testIssue1706() { ParseOptions options = new ParseOptions(); options.setResolve(true); - // Added this parseOption to make requestBody inline in the operation resolve processing flow. + // Added this parseOption to make requestBody/response inline in the operation resolve processing flow. options.setResolveRequestBody(true); + options.setResolveResponses(true); OpenAPI openAPI = new OpenAPIV3Parser().readLocation(path, null, options).getOpenAPI(); @@ -776,7 +777,7 @@ public void testIssue1706() { assertTrue(openAPI.getPaths().get("/resource").getPost().getRequestBody().getContent() != null); assertTrue(openAPI.getPaths().get("/resource").getPost().getRequestBody().getContent().get("application/json").getSchema() instanceof ObjectSchema); - // Responses are already by default made inline in case referenced. + // Responses should be inline assertTrue(openAPI.getPaths().get("/resource").getPost().getResponses().get("200").get$ref() == null); assertTrue(openAPI.getPaths().get("/resource").getPost().getResponses().get("200").getContent() != null); assertTrue(openAPI.getPaths().get("/resource").getPost().getResponses().get("200").getContent().get("application/json").getSchema() instanceof ObjectSchema); @@ -1285,6 +1286,8 @@ public void testSharedSwaggerParametersTest() { @Test(description = "resolve top-level responses") public void testSharedResponses() { final OpenAPI swagger = new OpenAPI(); + ParseOptions parseOptions = new ParseOptions(); + parseOptions.setResolveResponses(true); List parameters = new ArrayList<>(); parameters.add(0,new Parameter().$ref("username")); swagger.path("/fun", new PathItem() @@ -1294,7 +1297,7 @@ public void testSharedResponses() { swagger.components(new Components().addResponses("foo", new ApiResponse().description("ok!"))); - final OpenAPI resolved = new OpenAPIResolver(swagger, null).resolve(); + final OpenAPI resolved = new OpenAPIResolver(swagger, null, null, null, parseOptions).resolve(); ApiResponse response = resolved.getPaths().get("/fun").getGet().getResponses().get("200"); assertTrue(response.getDescription().equals("ok!")); assertTrue(response instanceof ApiResponse); 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 997f1c23bd..aa3721c193 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 @@ -170,6 +170,7 @@ public void testIssue1780() { public void testParametersAndResponsesAsNumbers() throws Exception { ParseOptions options = new ParseOptions(); options.setResolve(true); + options.setResolveResponses(true); SwaggerParseResult result = new OpenAPIV3Parser().readLocation("src/test/resources/parametersAsNumbers/swagger.yaml", null, options); Assert.assertNotNull(result); @@ -1214,6 +1215,7 @@ public void testIssue1131() { public void testIssue834() { ParseOptions options = new ParseOptions(); options.setResolve(true); + options.setResolveResponses(true); SwaggerParseResult result = new OpenAPIV3Parser().readLocation("issue-834/index.yaml", null, options); assertNotNull(result.getOpenAPI()); @@ -1247,8 +1249,8 @@ public void testIssue811_RefSchema_ToRefSchema() { public void testIssue811() { ParseOptions options = new ParseOptions(); options.setResolve(true); + options.setResolveResponses(true); final OpenAPI openAPI = new OpenAPIV3Parser().readLocation("oapi-reference-test/index.yaml", null, options).getOpenAPI(); - Assert.assertNotNull(openAPI); Assert.assertEquals(openAPI.getPaths().get("/").getGet().getResponses().get("200").getContent().get("application/json").getSchema().get$ref(),"#/components/schemas/schema-with-reference"); } @@ -1940,7 +1942,9 @@ public void testRelativePath() { OpenAPIV3Parser parser = new OpenAPIV3Parser(); ParseOptions options = new ParseOptions(); options.setResolve(true); + options.setResolveResponses(true); SwaggerParseResult readResult = parser.readLocation("src/test/resources/relative-issue/api.yaml", null, options); + Yaml.prettyPrint(readResult.getOpenAPI()); Assert.assertEquals(readResult.getOpenAPI().getPaths().get("/scans").getGet().getResponses().get("500").getContent().get("application/json").getSchema().get$ref(), "#/components/schemas/ErrorMessage"); } @@ -1949,6 +1953,7 @@ public void testRelativePath2() { OpenAPIV3Parser parser = new OpenAPIV3Parser(); ParseOptions options = new ParseOptions(); options.setResolve(true); + options.setResolveResponses(true); SwaggerParseResult readResult = parser.readLocation("src/test/resources/codegen-remote-responses/openapi.yaml", null, options); Assert.assertEquals(readResult.getOpenAPI().getPaths().get("/pet/findByTags").getGet().getResponses().get("default").getContent().get("application/json").getSchema().get$ref(), "#/components/schemas/ErrorModel"); } @@ -1957,6 +1962,7 @@ private OpenAPI doRelativeFileTest(String location) { OpenAPIV3Parser parser = new OpenAPIV3Parser(); ParseOptions options = new ParseOptions(); options.setResolve(true); + options.setResolveResponses(true); SwaggerParseResult readResult = parser.readLocation(location, null, options); if (readResult.getMessages().size() > 0) { @@ -3298,4 +3304,39 @@ public void testIssue2081() { assertEquals(openAPI.getComponents().getSchemas().get("PetCreate").getRequired().size(), 1); assertEquals(openAPI.getComponents().getSchemas().get("PetCreate").getProperties().size(), 2); } + + @Test(description = "responses should be inline") + public void testFullyResolveResponses() { + ParseOptions options = new ParseOptions(); + options.setResolve(true); + options.setResolveResponses(true); + OpenAPIV3Parser openApiParser = new OpenAPIV3Parser(); + SwaggerParseResult parseResult = openApiParser.readLocation("resolve-responses-test.yaml", null, options); + OpenAPI openAPI = parseResult.getOpenAPI(); + assertNull(openAPI.getPaths().get("/users").getGet().getResponses().get("400").get$ref()); + assertNull(openAPI.getPaths().get("/users").getPost().getResponses().get("400").get$ref()); + assertNull(openAPI.getPaths().get("/users").getPost().getResponses().get("422").get$ref()); + assertNull(openAPI.getPaths().get("/users/{userId}").getGet().getResponses().get("404").get$ref()); + assertNull(openAPI.getPaths().get("/users/{userId}").getPut().getResponses().get("400").get$ref()); + assertNull(openAPI.getPaths().get("/users/{userId}").getPut().getResponses().get("404").get$ref()); + assertNull(openAPI.getPaths().get("/users/{userId}").getDelete().getResponses().get("400").get$ref()); + assertNull(openAPI.getPaths().get("/users/{userId}").getDelete().getResponses().get("404").get$ref()); + } + + @Test(description = "responses should not be inline") + public void testResolveResponsesRef() { + ParseOptions options = new ParseOptions(); + options.setResolve(true); + OpenAPIV3Parser openApiParser = new OpenAPIV3Parser(); + SwaggerParseResult parseResult = openApiParser.readLocation("resolve-responses-test.yaml", null, options); + OpenAPI openAPI = parseResult.getOpenAPI(); + assertEquals(openAPI.getPaths().get("/users").getGet().getResponses().get("400").get$ref(), "#/components/responses/BadRequest"); + assertEquals(openAPI.getPaths().get("/users").getPost().getResponses().get("400").get$ref(), "#/components/responses/BadRequest"); + assertEquals(openAPI.getPaths().get("/users").getPost().getResponses().get("422").get$ref(), "#/components/responses/UnprocessableEntity"); + assertEquals(openAPI.getPaths().get("/users/{userId}").getGet().getResponses().get("404").get$ref(), "#/components/responses/NotFound"); + assertEquals(openAPI.getPaths().get("/users/{userId}").getPut().getResponses().get("400").get$ref(), "#/components/responses/BadRequest"); + assertEquals(openAPI.getPaths().get("/users/{userId}").getPut().getResponses().get("404").get$ref(), "#/components/responses/NotFound"); + assertEquals(openAPI.getPaths().get("/users/{userId}").getDelete().getResponses().get("400").get$ref(), "#/components/responses/BadRequest"); + assertEquals(openAPI.getPaths().get("/users/{userId}").getDelete().getResponses().get("404").get$ref(), "#/components/responses/NotFound"); + } } \ No newline at end of file diff --git a/modules/swagger-parser-v3/src/test/resources/resolve-responses-test.yaml b/modules/swagger-parser-v3/src/test/resources/resolve-responses-test.yaml new file mode 100644 index 0000000000..43642b01f1 --- /dev/null +++ b/modules/swagger-parser-v3/src/test/resources/resolve-responses-test.yaml @@ -0,0 +1,200 @@ +openapi: 3.0.1 +info: + title: Example API with Error Responses + description: An example API with 4xx responses as references. + version: "1.0.0" +servers: + - url: https://api.example.com/v1 + description: Production server + - url: https://staging-api.example.com/v1 + description: Staging server +paths: + /users: + get: + summary: Get list of users + description: Returns a list of users + responses: + '200': + description: A list of users. + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/User' + '500': + description: Server error + '400': + $ref: "#/components/responses/BadRequest" + post: + summary: Create a new user + description: Creates a new user in the system + requestBody: + $ref: "#/components/requestBodies/UserStructure" + responses: + '201': + description: User created successfully + content: + application/json: + schema: + $ref: '#/components/schemas/User' + '400': + $ref: "#/components/responses/BadRequest" + '422': + $ref: '#/components/responses/UnprocessableEntity' + /users/{userId}: + get: + summary: Get a user by ID + description: Retrieves a specific user by their ID + parameters: + - name: userId + in: path + required: true + schema: + type: string + responses: + '200': + description: User data retrieved successfully + content: + application/json: + schema: + $ref: '#/components/schemas/User' + '404': + $ref: "#/components/responses/NotFound" + '500': + description: Server error + put: + summary: Update a user by ID + description: Updates a user's data + parameters: + - name: userId + in: path + required: true + schema: + type: string + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UserInput' + responses: + '200': + description: User updated successfully + '400': + $ref: "#/components/responses/BadRequest" + '404': + $ref: "#/components/responses/NotFound" + '500': + description: Server error + delete: + summary: Delete a user by ID + description: Deletes a specific user + parameters: + - name: userId + in: path + required: true + schema: + type: string + responses: + '204': + description: User deleted successfully + '404': + $ref: "#/components/responses/NotFound" + '400': + $ref: "#/components/responses/BadRequest" + '500': + description: Server error +components: + schemas: + User: + type: object + properties: + id: + type: string + description: The user's unique ID + name: + type: string + description: The user's name + email: + type: string + description: The user's email address + age: + type: integer + description: The user's age + required: + - id + - name + - email + UserInput: + type: object + properties: + name: + type: string + description: The user's name + email: + type: string + description: The user's email address + age: + type: integer + description: The user's age + required: + - name + - email + responses: + BadRequest: + description: Bad request due to invalid input data + content: + application/json: + schema: + type: object + properties: + message: + type: string + description: Error message explaining why the request was invalid + code: + type: integer + description: Error code + NotFound: + description: The requested resource was not found + content: + application/json: + schema: + type: object + properties: + message: + type: string + description: Error message explaining why the resource was not found + code: + type: integer + description: Error code + UnprocessableEntity: + description: Request was well-formed but contains invalid data + content: + application/json: + schema: + type: object + properties: + message: + type: string + description: Explanation of why the request could not be processed + code: + type: integer + description: Error code + requestBodies: + UserStructure: + content: + application/json: + schema: + type: object + properties: + name: + type: string + maxLength: 10 + minLength: 1 + surname: + type: string + maxLength: 10 + minLength: 1 + + \ No newline at end of file