Skip to content

Commit

Permalink
Fix behavior for array of refs (#55)
Browse files Browse the repository at this point in the history
* Fix behavior for array of refs

* Fixed array behaviour for refs with arrays of refs

* Updated Readme version

* Updated Readme

* Update Pom version

Co-authored-by: Pablo José López Rivadulla <[email protected]>
  • Loading branch information
fcampostato and Rivarsal authored Jul 18, 2022
1 parent 7bed432 commit 96c22f8
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 24 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ Currently, this plugin has some limitations that will be addressed in the future
- This plugin allows the use of AllOfs and AnyOfs in the Response section. However, OpenApi does not support AllOfs in this section and AnyOf usage might not work depending on the OpenApi version you are using.
- Some OpenApi functionalities are not implemented yet, such as creating example objects, instead you must use the example tag in every property of the object.
- Due to the OpenApi Parser code, when you use a $ref that points to an external file, there are some limitations when using $ref again in that same file.
**Async Api implementation**:
Expand All @@ -191,3 +192,4 @@ Currently, this plugin has some limitations that will be addressed in the future
- Add support for generating contracts from avro files.
- Further investigation for OpenApi/AsyncApi and Spring Cloud Contract possibilities.
- More testing and fixing possible bugs that may occur in the future.
- Get rid of the OpenApi parser in order to control our own code.
6 changes: 3 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>net.coru</groupId>
<artifactId>scc-multiapi-converter</artifactId>
<version>2.6.1</version>
<version>2.6.2</version>
<name>SCC-MultiApi-Converter</name>
<description>Generates Spring Cloud Contracts based on an OpenApi and AsyncApi document</description>
<url>https://github.com/corunet/scc-multiapi-converter</url>
Expand Down Expand Up @@ -62,7 +62,7 @@
<organization>Corunet</organization>
<organizationUrl>https://corunet.github.io/</organizationUrl>
<roles>
<role>Junior Developer</role>
<role>Developer</role>
</roles>
<timezone>Europe/Madrid</timezone>
</developer>
Expand All @@ -73,7 +73,7 @@
<organization>Corunet</organization>
<organizationUrl>https://corunet.github.io/</organizationUrl>
<roles>
<role>Junior Developer</role>
<role>Developer</role>
</roles>
<timezone>Europe/Madrid</timezone>
</developer>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,15 @@ private void processResponseContent(OpenAPI openAPI, ApiResponse apiResponse, Re
OpenApiContractConverterUtils.processBasicResponseTypeBody(response, schema);
} else {
processBodyAndMatchers(bodyMap, schema, openAPI, responseBodyMatchers);
response.setBody(new Body(bodyMap));
Schema<?> checkArraySchema = new Schema<>();
if (schema.get$ref() != null){
checkArraySchema = openAPI.getComponents().getSchemas().get(OpenApiContractConverterUtils.mapRefName(schema));
}
if ((schema.getType() != null && "array".equalsIgnoreCase(schema.getType())) || (checkArraySchema.getType() != null && "array".equalsIgnoreCase(checkArraySchema.getType()))){
response.setBody(new Body(bodyMap.values().toArray()[0]));
} else {
response.setBody(new Body(bodyMap));
}
response.setBodyMatchers(responseBodyMatchers);
}
}
Expand Down Expand Up @@ -185,15 +193,19 @@ private void processRequestContent(final OpenAPI openAPI, Operation operation, R
private void processBodyAndMatchers(final Map<String, Object> bodyMap, Schema schema, OpenAPI openAPI, BodyMatchers bodyMatchers) {

if (Objects.nonNull(schema.getType())) {
final Map<String, Schema> basicObjectProperties = schema.getProperties();
for (Entry<String, Schema> property : basicObjectProperties.entrySet()) {
if (Objects.nonNull(property.getValue().get$ref())) {
final String subRef = OpenApiContractConverterUtils.mapRefName(property.getValue());
final HashMap<String, Schema> subProperties = (HashMap<String, Schema>) openAPI.getComponents().getSchemas().get(subRef).getProperties();
bodyMap.put(property.getKey(), processComplexBodyAndMatchers(property.getKey(), subProperties, openAPI, bodyMatchers));
} else {
writeBodyMatcher(bodyMap, openAPI, bodyMatchers, property.getKey(), property.getValue(), property.getValue().getType());
if (Objects.nonNull(schema.getProperties())){
final Map<String, Schema> basicObjectProperties = schema.getProperties();
for (Entry<String, Schema> property : basicObjectProperties.entrySet()) {
if (Objects.nonNull(property.getValue().get$ref())) {
final String subRef = OpenApiContractConverterUtils.mapRefName(property.getValue());
final HashMap<String, Schema> subProperties = (HashMap<String, Schema>) openAPI.getComponents().getSchemas().get(subRef).getProperties();
bodyMap.put(property.getKey(), processComplexBodyAndMatchers(property.getKey(), subProperties, openAPI, bodyMatchers));
} else {
writeBodyMatcher(bodyMap, openAPI, bodyMatchers, property.getKey(), property.getValue(), property.getValue().getType());
}
}
} else {
writeBodyMatcher(bodyMap, openAPI, bodyMatchers, "[0]", schema, schema.getType());
}
}
if (Objects.nonNull(schema.get$ref())) {
Expand Down Expand Up @@ -230,7 +242,7 @@ private void processBodyAndMatchers(final Map<String, Object> bodyMap, Schema sc
}
} else {
Schema arraySchema = openAPI.getComponents().getSchemas().get(ref);
writeBodyMatcher(bodyMap, openAPI, bodyMatchers, ref, arraySchema, arraySchema.getType());
writeBodyMatcher(bodyMap, openAPI, bodyMatchers, "[0]", arraySchema, arraySchema.getType());
}
}
}
Expand Down Expand Up @@ -306,8 +318,14 @@ private HashMap<String, Object> processComplexBodyAndMatchers(final String objec
final String newObjectName = objectName + "." + property.getKey();
if (Objects.nonNull(property.getValue().get$ref())) {
final String ref = OpenApiContractConverterUtils.mapRefName(property.getValue());
final HashMap<String, Schema> subProperties = (HashMap<String, Schema>) openAPI.getComponents().getSchemas().get(ref).getProperties();
propertyMap.put(property.getKey(), processComplexBodyAndMatchers(newObjectName, subProperties, openAPI, bodyMatchers));
if (Objects.nonNull(openAPI.getComponents().getSchemas().get(ref).getProperties())){
final HashMap<String, Schema> subProperties = (HashMap<String, Schema>) openAPI.getComponents().getSchemas().get(ref).getProperties();
propertyMap.put(property.getKey(), processComplexBodyAndMatchers(newObjectName, subProperties, openAPI, bodyMatchers));
} else {
final var subProperties = ((ArraySchema) openAPI.getComponents().getSchemas().get(ref)).getItems();
final List<Object> propertyList = new ArrayList<>();
propertyMap.put(property.getKey(), processArray(subProperties, propertyList, newObjectName, bodyMatchers, openAPI));
}
} else {
final String type;
if (Objects.nonNull(property.getValue().getEnum())) {
Expand Down Expand Up @@ -386,7 +404,7 @@ private List<Object> processArray(final Schema<?> arraySchema, List<Object> prop
if (Objects.nonNull(arraySchema.get$ref())) {
final String ref = OpenApiContractConverterUtils.mapRefName(arraySchema);
final HashMap<String, Schema> subObject = (HashMap<String, Schema>) openAPI.getComponents().getSchemas().get(ref).getProperties();
propertyList.add(processComplexBodyAndMatchers(objectName + "[0]", subObject, openAPI, bodyMatchers));
propertyList.add(processComplexBodyAndMatchers("[0]", subObject, openAPI, bodyMatchers));
} else {
final String type = arraySchema.getType();
switch (type) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ void testArrays() {
assertThat(contract).isNotNull();
assertThat(contract.getRequest()).isNotNull();
assertThat(contract.getResponse()).isNotNull();
final Map<String, Object> bodyServerValueMap = (HashMap<String, Object>) contract.getResponse().getBody().getServerValue();
final Map<String, Object> bodyServerValueMap = ((ArrayList<HashMap<String, Object>>) contract.getResponse().getBody().getServerValue()).get(0);
assertThat(bodyServerValueMap)
.containsKey(openApiContractConverterTestFixtures.NAME)
.containsKey(openApiContractConverterTestFixtures.ADDRESS)
Expand Down Expand Up @@ -331,15 +331,15 @@ void testRefsInsideArrays() {
List<Contract> contractList = new ArrayList<>(contracts);
Contract contract = contractList.get(0);
Response response = contract.getResponse();
final Map<String, Object> bodyServerValueMap = (Map<String, Object>) response.getBody().getServerValue();
final List<Map<String, Object>> refMap = (List<Map<String, Object>>) bodyServerValueMap.get(openApiContractConverterTestFixtures.SIMILAR_GAMES);
final List<Map<String,Object>> serverValueList = (List<Map<String, Object>>) response.getBody().getServerValue();
final Map<String, Object> bodyServerValueMap = serverValueList.get(0);
assertThat(response).isNotNull();
assertThat(bodyServerValueMap)
.isNotNull()
.containsKey(openApiContractConverterTestFixtures.SIMILAR_GAMES);
assertThat(refMap.get(0))
.isNotNull()
.containsKey(openApiContractConverterTestFixtures.PRICE)
.containsKeys(openApiContractConverterTestFixtures.PRICE,
openApiContractConverterTestFixtures.AVAILABILITY,
openApiContractConverterTestFixtures.ID,
openApiContractConverterTestFixtures.NAME)
.isInstanceOf(HashMap.class);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ public class OpenApiContractConverterTestFixtures {

protected final String[] OPENAPI_TEXT_EXTERNAL_REF_KEYS = {"schemaRegistryName", "topic", "kafkaName", "schemaName", "repetitions"};

protected final String AVAILABILITY = "availability";

protected final String ID = "id";

protected final String PRICE = "price";

protected final String SIMILAR_GAMES = "SimilarGames";
Expand Down
4 changes: 3 additions & 1 deletion src/test/resources/openapi/testArrays.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ paths:
content:
application/json:
schema:
$ref: "#/components/schemas/Game"
type: array
items:
$ref: "#/components/schemas/Game"
components:
schemas:
Game:
Expand Down

0 comments on commit 96c22f8

Please sign in to comment.