Skip to content

Commit c0c434b

Browse files
committed
test: enhance OAS 3.1 tests
1 parent 280e6c4 commit c0c434b

20 files changed

+2069
-11
lines changed

NOTICE

+12-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,15 @@
11
Swagger Parser - ${pom.name}
22
Copyright (c) 2015. SmartBear Software Inc.
33
Swagger Parser - ${pom.name} is licensed under Apache 2.0 license.
4-
Copy of the Apache 2.0 license can be found in `LICENSE` file.
4+
Copy of the Apache 2.0 license can be found in `LICENSE` file.
5+
6+
ApiDOM
7+
Copyright 2020 SmartBear Software Inc.
8+
ApiDOM is licensed under Apache 2.0 license.
9+
Directory modules/swagger-parser-v3/src/test/resources/3.1.0/dereference/fixtures was originally created under Apache 2.0 license in https://github.com/swagger-api/apidom repository.
10+
Directory modules/swagger-parser-v3/src/test/resources/3.1.0/resolve/fixtures was originally created under Apache 2.0 license in https://github.com/swagger-api/apidom repository.
11+
These directories have been copied into this project and modified. All modifications are licensed under Apache 2.0 License.
12+
Copy of the Apache 2.0 license can be found in `LICENSES/Apache-2.0.txt` file.
13+
14+
15+

README.md

+7
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
**NOTE:** If you're looking for `swagger-parser` 1.X and OpenAPI 2.0, please refer to [v1 branch](https://github.com/swagger-api/swagger-parser/tree/v1)
44

5+
**NOTE:** Since version 2.1.0 Swagger Parser supports OpenAPI 3.1; see [this page](https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---OpenAPI-3.1) for details
6+
57
![Build Master - Java 8, 11, and 14](https://github.com/swagger-api/swagger-parser/workflows/Build%20Test%20Deploy%20master/badge.svg?branch=master)
68

79
# Table of contents
@@ -18,6 +20,7 @@
1820
- [Flatten](#3-flatten)
1921
- [ResolveCombinators](#4-resolvecombinators)
2022
- [Extensions](#extensions)
23+
- [OpenAPI 3.1 Support](#openapi-31-support)
2124
- [License](#license)
2225

2326
## Overview
@@ -657,6 +660,10 @@ This project has a core artifact--`swagger-parser`, which uses Java Service Prov
657660

658661
To build your own extension, you simply need to create a `src/main/resources/META-INF/services/io.swagger.v3.parser.core.extensions.SwaggerParserExtension` file with the full classname of your implementation. Your class must also implement the `io.swagger.v3.parser.core.extensions.SwaggerParserExtension` interface. Then, including your library with the `swagger-parser` module will cause it to be triggered automatically.
659662

663+
### OpenAPI 3.1 support
664+
665+
Since version 2.1.0 Swagger Parser supports OpenAPI 3.1; see [this page](https://github.com/swagger-api/swagger-core/wiki/Swagger-2.X---OpenAPI-3.1) for details
666+
660667
## Security contact
661668

662669
Please disclose any security-related issues or vulnerabilities by emailing [[email protected]](mailto:[email protected]), instead of using the public issue tracker.

modules/swagger-parser-v3/src/test/java/io/swagger/v3/parser/test/OpenAPIResolverTest.java

+178-9
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@
4040
import io.swagger.v3.parser.core.models.SwaggerParseResult;
4141
import io.swagger.v3.parser.processors.ComponentsProcessor;
4242
import io.swagger.v3.parser.processors.PathsProcessor;
43+
import io.swagger.v3.parser.reference.DereferencerContext;
44+
import io.swagger.v3.parser.reference.DereferencersFactory;
45+
import io.swagger.v3.parser.reference.OpenAPIDereferencer;
4346
import io.swagger.v3.parser.util.OpenAPIDeserializer;
4447
import io.swagger.v3.parser.util.ResolverFully;
4548
import mockit.Injectable;
@@ -207,6 +210,172 @@ private void tearDownWireMockServer() {
207210
this.wireMockServer.stop();
208211
}
209212

213+
@Test
214+
public void componentsResolver31() throws Exception {
215+
final ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
216+
217+
String pathFile = FileUtils.readFileToString(new File("src/test/resources/oas31.yaml.template"));
218+
pathFile = pathFile.replace("${dynamicPort}", String.valueOf(this.serverPort));
219+
220+
final JsonNode rootNode = mapper.readTree(pathFile.getBytes());
221+
final OpenAPIDeserializer deserializer = new OpenAPIDeserializer();
222+
final SwaggerParseResult result = deserializer.deserialize(rootNode);
223+
224+
Assert.assertNotNull(result);
225+
final OpenAPI openAPI = result.getOpenAPI();
226+
Assert.assertNotNull(openAPI);
227+
DereferencerContext dereferencerContext = new DereferencerContext(
228+
result,
229+
new ArrayList<>(),
230+
null,
231+
new ParseOptions(),
232+
null,
233+
null,
234+
true
235+
);
236+
List<OpenAPIDereferencer> dereferencers = DereferencersFactory.getInstance().getDereferencers();
237+
if (dereferencers.iterator().hasNext()) {
238+
OpenAPIDereferencer dereferencer = dereferencers.iterator().next();
239+
dereferencer.dereference(dereferencerContext, dereferencers.iterator());
240+
}
241+
assertEquals(dereferencerContext.getOpenApi(), openAPI);
242+
243+
Map<String, Schema> schemas = openAPI.getComponents().getSchemas();
244+
245+
//internal url schema
246+
Schema pet = schemas.get("Pet");
247+
Schema category = (Schema) pet.getProperties().get("category");
248+
assertEquals(category.get$ref(),"#/components/schemas/Category");
249+
250+
//remote url schema
251+
Schema user = (Schema) pet.getProperties().get("user");
252+
// TODO uncomment when bundling of extenrnal refs gets implemented
253+
// assertEquals(user.get$ref(),"#/components/schemas/User");
254+
255+
256+
//ArraySchema items
257+
Schema tagsProperty = (Schema) pet.getProperties().get("tags");
258+
// TODO uncomment when bundling of extenrnal refs gets implemented
259+
/* assertEquals(tagsProperty.getItems().get$ref(), "#/components/schemas/ExampleSchema" );
260+
assertEquals(tagsProperty.getType(),"array");
261+
Assert.assertNotNull(openAPI.getComponents().getSchemas().get("ExampleSchema"));*/
262+
263+
//Schema not
264+
assertEquals(schemas.get("OrderRef").getNot().get$ref(), "#/components/schemas/Category");
265+
266+
//Schema additionalProperties
267+
assertTrue(schemas.get("OrderRef").getAdditionalProperties() instanceof Schema);
268+
Schema additionalProperties = (Schema) schemas.get("OrderRef").getAdditionalProperties();
269+
// TODO uncomment when bundling of extenrnal refs gets implemented
270+
// assertEquals(additionalProperties.get$ref(), "#/components/schemas/User");
271+
272+
//AllOfSchema
273+
Schema extended = schemas.get("ExtendedErrorModel");
274+
Schema root = (Schema) ((Schema)extended.getAllOf().get(0)).getProperties().get("rootCause");
275+
assertEquals(root.get$ref(), "#/components/schemas/Category");
276+
277+
278+
Map<String, ApiResponse> responses = openAPI.getComponents().getResponses();
279+
280+
//internal response headers
281+
ApiResponse illegalInput = responses.get("IllegalInput");
282+
assertEquals(illegalInput.getHeaders().get("X-Ref-Limit-Limit").get$ref(),"#/components/headers/X-Rate-Limit-Reset");
283+
284+
//internal response links
285+
assertEquals(illegalInput.getLinks().get("address").get$ref(),"#/components/links/unsubscribe");
286+
287+
//internal url response schema
288+
MediaType generalError = responses.get("GeneralError").getContent().get("application/json");
289+
assertEquals(generalError.getSchema().get$ref(),"#/components/schemas/ExtendedErrorModel");
290+
291+
292+
Map<String, RequestBody> requestBodies = openAPI.getComponents().getRequestBodies();
293+
294+
//internal url requestBody schema
295+
RequestBody requestBody1 = requestBodies.get("requestBody1");
296+
MediaType xmlMedia = requestBody1.getContent().get("application/json");
297+
assertEquals(xmlMedia.getSchema().get$ref(),"#/components/schemas/Pet");
298+
299+
//internal url requestBody ArraySchema
300+
RequestBody requestBody2 = requestBodies.get("requestBody2");
301+
MediaType jsonMedia = requestBody2.getContent().get("application/json");
302+
Schema items = jsonMedia.getSchema();
303+
// TODO uncomment when bundling of extenrnal refs gets implemented
304+
// assertEquals(items.getItems().get$ref(),"#/components/schemas/User");
305+
306+
//internal request body
307+
assertEquals("#/components/requestBodies/requestBody2",requestBodies.get("requestBody3").get$ref());
308+
309+
//remote request body url
310+
// TODO uncomment when bundling of extenrnal refs gets implemented
311+
// assertEquals(requestBodies.get("reference").get$ref(),"#/components/requestBodies/remote_requestBody");
312+
313+
Map<String, Parameter> parameters = openAPI.getComponents().getParameters();
314+
315+
//remote url parameter
316+
// TODO uncomment when bundling of extenrnal refs gets implemented
317+
// assertEquals(parameters.get("remoteParameter").get$ref(),"#/components/parameters/parameter");
318+
319+
320+
//internal Schema Parameter
321+
assertEquals(parameters.get("newParam").getSchema().get$ref(),"#/components/schemas/Tag");
322+
323+
324+
//parameter content schema
325+
326+
assertEquals(parameters.get("contentParameter").getContent().get("application/json").getSchema().get$ref(),"#/components/schemas/ExtendedErrorModel");
327+
328+
//internal Schema header
329+
Map<String, Header> headers = openAPI.getComponents().getHeaders();
330+
//header remote schema ref
331+
// TODO uncomment when bundling of extenrnal refs gets implemented
332+
// assertEquals(headers.get("X-Rate-Limit-Remaining").getSchema().get$ref(),"#/components/schemas/User");
333+
334+
//header examples
335+
assertEquals(headers.get("X-Rate-Limit-Reset").getExamples().get("headerExample").get$ref(), "#/components/examples/dog" );
336+
//remote header ref
337+
// TODO uncomment when bundling of extenrnal refs gets implemented
338+
// assertEquals(headers.get("X-Ref-Limit-Limit").get$ref(),"#/components/headers/X-Rate-Limit-Reset" );
339+
340+
341+
//header content
342+
assertEquals(headers.get("X-Rate-Limit-Reset").getContent().get("application/json").getSchema().get$ref(),"#/components/schemas/ExtendedErrorModel");
343+
344+
Map<String, Example> examples = openAPI.getComponents().getExamples();
345+
346+
//internal url example
347+
Example frogExample = examples.get("frog");
348+
assertEquals(frogExample.get$ref(),"#/components/examples/cat");
349+
350+
//remote example url
351+
// TODO uncomment when bundling of extenrnal refs gets implemented
352+
// assertEquals(examples.get("referenceCat").get$ref(),"#/components/examples/example");
353+
354+
355+
SecurityScheme remoteScheme = openAPI.getComponents().getSecuritySchemes().get("remote_reference");
356+
// TODO uncomment when bundling of extenrnal refs gets implemented
357+
// assertEquals(remoteScheme.getType(), SecurityScheme.Type.OAUTH2);
358+
359+
360+
Map<String, Link> links = openAPI.getComponents().getLinks();
361+
//internal link
362+
assertEquals(openAPI.getComponents().getLinks().get("referenced").get$ref(),"#/components/links/unsubscribe");
363+
//remote ref link
364+
// TODO uncomment when bundling of extenrnal refs gets implemented
365+
// assertEquals(openAPI.getComponents().getLinks().get("subscribe").get$ref(),"#/components/links/link");
366+
367+
368+
Map<String, Callback> callbacks = openAPI.getComponents().getCallbacks();
369+
// internal callback reference
370+
assertEquals(callbacks.get("referenced").get$ref(),"#/components/callbacks/failed");
371+
//callback pathItem -> operation ->requestBody
372+
assertEquals(callbacks.get("heartbeat").get("$request.query.heartbeat-url").getPost().getRequestBody().get$ref(),"#/components/requestBodies/requestBody3");
373+
//remote callback ref
374+
// TODO uncomment when bundling of extenrnal refs gets implemented
375+
// assertEquals(callbacks.get("remoteCallback").get$ref(),"#/components/callbacks/callback");
376+
377+
}
378+
210379
@Test
211380
public void componentsResolver() throws Exception {
212381
final ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
@@ -236,7 +405,7 @@ public void componentsResolver() throws Exception {
236405

237406

238407
//ArraySchema items
239-
ArraySchema tagsProperty = (ArraySchema) pet.getProperties().get("tags");
408+
Schema tagsProperty = (ArraySchema) pet.getProperties().get("tags");
240409
assertEquals(tagsProperty.getItems().get$ref(), "#/components/schemas/ExampleSchema" );
241410
assertEquals(tagsProperty.getType(),"array");
242411
Assert.assertNotNull(openAPI.getComponents().getSchemas().get("ExampleSchema"));
@@ -250,8 +419,8 @@ public void componentsResolver() throws Exception {
250419
assertEquals(additionalProperties.get$ref(), "#/components/schemas/User");
251420

252421
//AllOfSchema
253-
ComposedSchema extended = (ComposedSchema) schemas.get("ExtendedErrorModel");
254-
Schema root = (Schema) extended.getAllOf().get(0).getProperties().get("rootCause");
422+
Schema extended = (ComposedSchema) schemas.get("ExtendedErrorModel");
423+
Schema root = (Schema)((Schema) extended.getAllOf().get(0)).getProperties().get("rootCause");
255424
assertEquals(root.get$ref(), "#/components/schemas/Category");
256425

257426

@@ -595,7 +764,7 @@ public void testIssue1170(@Injectable final List<AuthorizationValue> auths) {
595764
assertTrue(colouringPropertySchema == colouringsSchema);
596765

597766
}
598-
767+
599768
@Test
600769
public void testIssue1706() {
601770
String path = "/issue-1706/SimpleRequestResponseRef.json";
@@ -606,19 +775,19 @@ public void testIssue1706() {
606775
options.setResolveRequestBody(true);
607776

608777
OpenAPI openAPI = new OpenAPIV3Parser().readLocation(path, null, options).getOpenAPI();
609-
778+
610779
// RequestBody should be inline
611780
assertTrue(openAPI.getPaths().get("/resource").getPost().getRequestBody().get$ref() == null);
612781
assertTrue(openAPI.getPaths().get("/resource").getPost().getRequestBody().getContent() != null);
613782
assertTrue(openAPI.getPaths().get("/resource").getPost().getRequestBody().getContent().get("application/json").getSchema() instanceof ObjectSchema);
614-
783+
615784
// Responses are already by default made inline in case referenced.
616785
assertTrue(openAPI.getPaths().get("/resource").getPost().getResponses().get("200").get$ref() == null);
617786
assertTrue(openAPI.getPaths().get("/resource").getPost().getResponses().get("200").getContent() != null);
618-
assertTrue(openAPI.getPaths().get("/resource").getPost().getResponses().get("200").getContent().get("application/json").getSchema() instanceof ObjectSchema);
787+
assertTrue(openAPI.getPaths().get("/resource").getPost().getResponses().get("200").getContent().get("application/json").getSchema() instanceof ObjectSchema);
619788
}
620-
621-
789+
790+
622791

623792
@Test
624793
public void selfReferenceTest(@Injectable final List<AuthorizationValue> auths) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package io.swagger.v3.parser.test;
2+
3+
import io.swagger.v3.core.util.Yaml31;
4+
import io.swagger.v3.parser.OpenAPIV3Parser;
5+
import io.swagger.v3.parser.core.models.ParseOptions;
6+
import io.swagger.v3.parser.core.models.SwaggerParseResult;
7+
import org.apache.commons.io.FileUtils;
8+
import org.testng.annotations.Test;
9+
10+
import java.io.File;
11+
12+
public class OpenAPIV31ParserFSFullTest {
13+
14+
@Test
15+
public void testFull() throws Exception {
16+
ParseOptions p = new ParseOptions();
17+
p.setResolve(true);
18+
String uri = "3.1.0/dereference/fullFS/root.json";
19+
SwaggerParseResult swaggerParseResult = new OpenAPIV3Parser().readLocation(uri, null, p);
20+
org.testng.Assert.assertEquals(Yaml31.pretty(swaggerParseResult.getOpenAPI()), FileUtils.readFileToString(new File("src/test/resources/3.1.0/dereference/fullFS/dereferenced.yaml")));
21+
}
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
openapi: 3.1.0
2+
servers:
3+
- url: /
4+
paths:
5+
/path1:
6+
summary: path item summary
7+
description: /path3 ex2
8+
get: {}
9+
/relativeref:
10+
get:
11+
description: RelativeRef domain
12+
operationId: RelativeRef PathItem
13+
responses:
14+
"200":
15+
description: OK
16+
/internalref:
17+
$ref: '#/components/pathItems/InternalRef'
18+
/internalreftoexternal:
19+
$ref: '#/components/pathItems/InternalRefToExternal'
20+
/internal:
21+
get:
22+
description: Internal PathItem
23+
operationId: Internal PathItem
24+
responses:
25+
"200":
26+
description: OK
27+
components:
28+
schemas:
29+
Indirection:
30+
type: object
31+
description: VALUE ex3schema
32+
properties:
33+
prop1:
34+
type: string
35+
IndirectionSiblings:
36+
type: object
37+
description: IndirectionSiblings root
38+
properties:
39+
prop1:
40+
type: string
41+
parameters:
42+
userId:
43+
description: userId root
44+
$ref: '#/components/parameters/indirection1'
45+
indirection1:
46+
$ref: '#/components/parameters/userIdRef'
47+
indirection2:
48+
description: indirection2 root
49+
$ref: '#/components/parameters/userIdRef'
50+
userIdRef:
51+
name: userId
52+
in: query
53+
description: userIdRef root
54+
required: true
55+
style: form
56+
explode: true
57+
externalRef:
58+
name: externalParameter
59+
in: query
60+
description: externalRef root
61+
required: true
62+
style: form
63+
explode: true
64+
externalRefIndirectPointer:
65+
description: externalRefIndirectPointer root
66+
$ref: '#/components/parameters/externalRefIndirect3'
67+
externalRefIndirect3:
68+
name: externalParameter3
69+
in: query
70+
description: externalRefIndirect3 root
71+
required: true
72+
style: form
73+
explode: true
74+
links:
75+
link1:
76+
operationRef: ./ex.json#/operation
77+
pathItems:
78+
InternalRefToExternal:
79+
get:
80+
description: DomainInternalRefToExternal domain
81+
operationId: DomainInternalRefToExternal PathItem
82+
responses:
83+
"200":
84+
description: OK
85+
InternalRef:
86+
get:
87+
description: InternalRef root
88+
operationId: InternalRef PathItem
89+
responses:
90+
"200":
91+
description: OK

0 commit comments

Comments
 (0)