Skip to content

Commit 2cd175e

Browse files
committed
refactor convert method and add test
1 parent 6a32a23 commit 2cd175e

3 files changed

Lines changed: 91 additions & 16 deletions

File tree

modules/swagger-parser-v2-converter/src/main/java/io/swagger/v3/parser/converter/SwaggerConverter.java

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,13 @@
5959

6060

6161
import java.math.BigDecimal;
62-
import java.util.ArrayList;
63-
import java.util.HashMap;
64-
import java.util.LinkedHashMap;
65-
import java.util.List;
66-
import java.util.Map;
67-
import java.util.Optional;
62+
import java.util.*;
6863
import java.util.stream.Collectors;
6964

7065
public class SwaggerConverter implements SwaggerParserExtension {
66+
67+
private static final Set<String> STRIPPED_EXTENSION_KEYS = Set.of("x-example", "x-examples", "x-nullable");
68+
7169
private List<String> globalConsumes = new ArrayList<>();
7270
private List<String> globalProduces = new ArrayList<>();
7371
private Components components = new Components();
@@ -654,18 +652,17 @@ public Operation convert(io.swagger.models.Operation v2Operation) {
654652
}
655653

656654
private Map<String, Object> convert(Map<String, Object> vendorExtensions) {
657-
if (vendorExtensions != null && vendorExtensions.size() > 0) {
658-
Map<String, Object> result = new LinkedHashMap<>();
659-
for (Map.Entry<String, Object> entry : vendorExtensions.entrySet()) {
660-
String key = entry.getKey();
661-
if (!key.equals("x-example") && !key.equals("x-examples") && !key.equals("x-nullable")) {
662-
result.put(key, entry.getValue());
663-
}
664-
}
665-
return result;
655+
if (vendorExtensions == null || vendorExtensions.isEmpty()) {
656+
return vendorExtensions;
666657
}
667658

668-
return vendorExtensions;
659+
Map<String, Object> result = new LinkedHashMap<>();
660+
for (Map.Entry<String, Object> entry : vendorExtensions.entrySet()) {
661+
if (!STRIPPED_EXTENSION_KEYS.contains(entry.getKey())) {
662+
result.put(entry.getKey(), entry.getValue());
663+
}
664+
}
665+
return result;
669666
}
670667

671668
private Schema convertFormDataToSchema(io.swagger.models.parameters.Parameter formParam) {

modules/swagger-parser-v2-converter/src/test/java/io/swagger/parser/test/V2ConverterTest.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ public class V2ConverterTest {
100100

101101
private static final String ISSUE_1767_YAML = "issue-1767.yaml";
102102
private static final String ISSUE_1796_YAML = "issue-1796.yaml";
103+
private static final String ISSUE_2269_YAML = "issue-2269.yaml";
103104

104105
private static final String API_BATCH_PATH = "/api/batch/";
105106
private static final String PETS_PATH = "/pets";
@@ -928,6 +929,42 @@ public void testConvertFormDataAsObjectSchema() throws Exception {
928929

929930
}
930931

932+
@Test
933+
public void testIssue2269SharedResponseNullable() {
934+
SwaggerConverter converter = new SwaggerConverter();
935+
ParseOptions parseOptions = new ParseOptions();
936+
parseOptions.setResolve(true);
937+
parseOptions.setResolveFully(true);
938+
SwaggerParseResult result = converter.readLocation(
939+
"src/test/resources/" + ISSUE_2269_YAML, null, parseOptions);
940+
assertNotNull(result);
941+
OpenAPI oas = result.getOpenAPI();
942+
assertNotNull(oas);
943+
944+
for (String endpoint : Arrays.asList("/endpoint1", "/endpoint2")) {
945+
Map<String, Schema> properties = oas.getPaths().get(endpoint).getGet()
946+
.getResponses().get("200").getContent().values().iterator().next()
947+
.getSchema().getProperties();
948+
assertNotNull(properties, endpoint + " schema properties must not be null");
949+
950+
Schema nullableField = properties.get("nullable_field");
951+
assertNotNull(nullableField, endpoint + " must have nullable_field");
952+
assertEquals(nullableField.getNullable(), Boolean.TRUE,
953+
endpoint + " nullable_field must have nullable: true");
954+
assertNotNull(nullableField.getExtensions(), endpoint + " nullable_field must retain extensions");
955+
assertEquals(nullableField.getExtensions().get("x-internal-note"), "abc",
956+
endpoint + " nullable_field must retain x-internal-note extension");
957+
958+
Schema nonNullableField = properties.get("non_nullable_field");
959+
assertNotNull(nonNullableField, endpoint + " must have non_nullable_field");
960+
assertEquals(nonNullableField.getNullable(), Boolean.FALSE,
961+
endpoint + " non_nullable_field must have nullable: false");
962+
assertNotNull(nonNullableField.getExtensions(), endpoint + " non_nullable_field must retain extensions");
963+
assertEquals(nonNullableField.getExtensions().get("x-internal-note"), "def",
964+
endpoint + " non_nullable_field must retain x-internal-note extension");
965+
}
966+
}
967+
931968
/**
932969
* A clone (almost) of {@link OpenAPIV3Parser#readContents(String, List, ParseOptions)}.
933970
*/
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
swagger: '2.0'
2+
info:
3+
version: 1.0.0
4+
title: Issue 2269 - x-nullable preservation for shared $ref responses
5+
6+
responses:
7+
SharedResponse:
8+
description: A shared response with multiple fields using x-nullable
9+
schema:
10+
type: object
11+
properties:
12+
data:
13+
type: string
14+
description: Required field
15+
nullable_field:
16+
type: integer
17+
x-nullable: true
18+
x-internal-note: abc
19+
non_nullable_field:
20+
type: integer
21+
x-nullable: false
22+
x-internal-note: def
23+
required:
24+
- data
25+
26+
paths:
27+
/endpoint1:
28+
get:
29+
operationId: endpoint1
30+
summary: First endpoint using shared response
31+
responses:
32+
'200':
33+
$ref: '#/responses/SharedResponse'
34+
35+
/endpoint2:
36+
get:
37+
operationId: endpoint2
38+
summary: Second endpoint using shared response
39+
responses:
40+
'200':
41+
$ref: '#/responses/SharedResponse'

0 commit comments

Comments
 (0)