Skip to content

Commit

Permalink
71 failed to execute goal generatetests while trying to generate cont…
Browse files Browse the repository at this point in the history
…racts from an openapi yaml document (#73)
  • Loading branch information
jemacineiras authored Oct 10, 2022
1 parent b2b785b commit 777a99d
Show file tree
Hide file tree
Showing 8 changed files with 461 additions and 158 deletions.
2 changes: 1 addition & 1 deletion 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>3.0.1</version>
<version>3.0.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

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,19 @@

package net.coru.multiapi.converter.asyncapi;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import net.coru.multiapi.converter.exception.ElementNotFoundException;
import net.coru.multiapi.converter.exception.MultiApiContractConverterException;
import net.coru.multiapi.converter.utils.BasicTypeConstants;
import net.coru.multiapi.converter.utils.RandomGenerator;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.RandomUtils;
import org.springframework.cloud.contract.spec.internal.ResponseBodyMatchers;

public final class AsyncApiContractConverterUtils {
Expand All @@ -27,11 +29,15 @@ public static void processEnumPropertyType(
final ResponseBodyMatchers responseBodyMatchers, final JsonNode properties, final String operationType, final Map<String, Object> messageBody, final String property,
final String path, final String enumType) {
if (operationType.equals(BasicTypeConstants.SUBSCRIBE)) {
messageBody.put(property, processEnumTypes(properties.get(property).get(BasicTypeConstants.EXAMPLE), enumType));
if (properties.get(property).has(BasicTypeConstants.EXAMPLE)) {
messageBody.put(property, properties.get(property).get(BasicTypeConstants.EXAMPLE).textValue());
} else {
messageBody.put(property, processEnumTypes(properties.get(property)));
}
} else {
final var enumList = properties.get(property).get(BasicTypeConstants.ENUM);
responseBodyMatchers.jsonPath(path, responseBodyMatchers.byRegex(getEnumRegex(enumType, properties, property)));
messageBody.put(property, processEnumTypes(enumList.get(BasicTypeConstants.RANDOM.nextInt(enumList.size())), enumType));
messageBody.put(property, enumList.get(BasicTypeConstants.RANDOM.nextInt(enumList.size())).textValue());
}
}

Expand Down Expand Up @@ -61,59 +67,55 @@ public static void processFloatPropertyType(
final ResponseBodyMatchers responseBodyMatchers, final JsonNode properties, final String operationType, final Map<String, Object> messageBody, final String property,
final String path) {
if (operationType.equals(BasicTypeConstants.SUBSCRIBE)) {
messageBody.put(property, Float.parseFloat(properties.get(property).get(BasicTypeConstants.EXAMPLE).asText()));
if (properties.get(property).has(BasicTypeConstants.EXAMPLE)) {
messageBody.put(property, Float.parseFloat(properties.get(property).get(BasicTypeConstants.EXAMPLE).asText()));
} else {
messageBody.put(property, RandomUtils.nextFloat());
}
} else {
responseBodyMatchers.jsonPath(path, responseBodyMatchers.byRegex(BasicTypeConstants.DECIMAL_REGEX));
messageBody.put(property, Math.abs(BasicTypeConstants.RANDOM.nextFloat()));
messageBody.put(property, RandomUtils.nextFloat());
}
}

public static void processNumberPropertyType(
final ResponseBodyMatchers responseBodyMatchers, final JsonNode properties, final String operationType, final Map<String, Object> messageBody, final String property,
final String path) {
if (operationType.equals(BasicTypeConstants.SUBSCRIBE)) {
messageBody.put(property, properties.get(property).get(BasicTypeConstants.EXAMPLE).asInt());
if (properties.get(property).has(BasicTypeConstants.EXAMPLE)) {
messageBody.put(property, properties.get(property).get(BasicTypeConstants.EXAMPLE).asInt());
} else {
messageBody.put(property, RandomUtils.nextInt());
}
} else {
responseBodyMatchers.jsonPath(path, responseBodyMatchers.byRegex(BasicTypeConstants.INT_REGEX));
messageBody.put(property, BasicTypeConstants.RANDOM.nextInt());
messageBody.put(property, RandomUtils.nextInt());
}
}

public static void processStringPropertyType(
final ResponseBodyMatchers responseBodyMatchers, final JsonNode properties, final String operationType, final Map<String, Object> messageBody, final String property,
final String path) {
if (operationType.equals(BasicTypeConstants.SUBSCRIBE)) {
messageBody.put(property, properties.get(property).get(BasicTypeConstants.EXAMPLE).asText());
if (properties.get(property).has(BasicTypeConstants.EXAMPLE)) {
messageBody.put(property, properties.get(property).get(BasicTypeConstants.EXAMPLE).asText());
} else {
messageBody.put(property, RandomStringUtils.random(5, true, false));
}
} else {
responseBodyMatchers.jsonPath(path, responseBodyMatchers.byRegex(BasicTypeConstants.STRING_REGEX));
messageBody.put(property, RandomStringUtils.random(5, true, false));
}
}

public static Object processEnumTypes(final JsonNode value, final String type) {
final Object enumValue;

switch (type) {
case BasicTypeConstants.STRING:
enumValue = value.asText();
break;
case BasicTypeConstants.INT_32:
case BasicTypeConstants.NUMBER:
enumValue = value.asInt();
break;
case BasicTypeConstants.INT_64:
case BasicTypeConstants.FLOAT:
case BasicTypeConstants.DOUBLE:
enumValue = value.asDouble();
break;
case BasicTypeConstants.BOOLEAN:
enumValue = value.asBoolean();
break;
default:
throw new ElementNotFoundException(BasicTypeConstants.TYPE);
}
public static String processEnumTypes(final JsonNode value) {
final List<String> enumValueList = new ArrayList<>();

return enumValue;
final var enumValuesIT = value.get("enum").elements();
while (enumValuesIT.hasNext()) {
enumValueList.add(enumValuesIT.next().textValue());
}
return enumValueList.get(RandomUtils.nextInt(0, enumValueList.size()));
}

public static String getEnumRegex(final String type, final JsonNode properties, final String property) {
Expand All @@ -140,11 +142,11 @@ public static void processArrayEnumType(
if (operationType.equals(BasicTypeConstants.SUBSCRIBE)) {
final var arrayNode = BasicTypeConstants.OBJECT_MAPPER.readTree(internalProperties.toString()).get(BasicTypeConstants.EXAMPLE);
for (int i = 0; i < arrayNode.size(); i++) {
arrayValues.add(AsyncApiContractConverterUtils.processEnumTypes(arrayNode.get(i), enumType));
arrayValues.add(AsyncApiContractConverterUtils.processEnumTypes(arrayNode.get(i)));
}
} else {
final var enumList = internalProperties.get(BasicTypeConstants.ENUM);
arrayValues.add(AsyncApiContractConverterUtils.processEnumTypes(enumList.get(BasicTypeConstants.RANDOM.nextInt(enumList.size())), enumType));
arrayValues.add(AsyncApiContractConverterUtils.processEnumTypes(enumList.get(BasicTypeConstants.RANDOM.nextInt(enumList.size()))));
if (isNotRegexIncluded(responseBodyMatchers, path + "[0]")) {
responseBodyMatchers.jsonPath(path + "[0]", responseBodyMatchers.byRegex(AsyncApiContractConverterUtils.getEnumRegex(enumType, internalProperties, property)));
}
Expand Down Expand Up @@ -236,6 +238,54 @@ public static void processArrayStringType(
}
}

public static void processArrayDateType(
final ResponseBodyMatchers responseBodyMatchers, final String path, final String operationType, final List<Object> arrayValues, final JsonNode internalProperties)
throws JsonProcessingException {
if (operationType.equals(BasicTypeConstants.SUBSCRIBE)) {
final var arrayNode = BasicTypeConstants.OBJECT_MAPPER.readTree(internalProperties.toString()).get(BasicTypeConstants.EXAMPLE);
for (int i = 0; i < arrayNode.size(); i++) {
arrayValues.add(arrayNode.get(i).asText());
}
} else {
arrayValues.add(RandomStringUtils.random(5, true, false));
if (isNotRegexIncluded(responseBodyMatchers, path + "[0]")) {
responseBodyMatchers.jsonPath(path + "[0]", responseBodyMatchers.byRegex(BasicTypeConstants.DATE_REGEX));
}
}
}

public static void processArrayDateTimeType(
final ResponseBodyMatchers responseBodyMatchers, final String path, final String operationType, final List<Object> arrayValues, final JsonNode internalProperties)
throws JsonProcessingException {
if (operationType.equals(BasicTypeConstants.SUBSCRIBE)) {
final var arrayNode = BasicTypeConstants.OBJECT_MAPPER.readTree(internalProperties.toString()).get(BasicTypeConstants.EXAMPLE);
for (int i = 0; i < arrayNode.size(); i++) {
arrayValues.add(arrayNode.get(i).asText());
}
} else {
arrayValues.add(RandomStringUtils.random(5, true, false));
if (isNotRegexIncluded(responseBodyMatchers, path + "[0]")) {
responseBodyMatchers.jsonPath(path + "[0]", responseBodyMatchers.byRegex(BasicTypeConstants.DATE_TIME_REGEX));
}
}
}

public static void processArrayTimeType(
final ResponseBodyMatchers responseBodyMatchers, final String path, final String operationType, final List<Object> arrayValues, final JsonNode internalProperties)
throws JsonProcessingException {
if (operationType.equals(BasicTypeConstants.SUBSCRIBE)) {
final var arrayNode = BasicTypeConstants.OBJECT_MAPPER.readTree(internalProperties.toString()).get(BasicTypeConstants.EXAMPLE);
for (int i = 0; i < arrayNode.size(); i++) {
arrayValues.add(arrayNode.get(i).asText());
}
} else {
arrayValues.add(RandomStringUtils.random(5, true, false));
if (isNotRegexIncluded(responseBodyMatchers, path + "[0]")) {
responseBodyMatchers.jsonPath(path + "[0]", responseBodyMatchers.byRegex(BasicTypeConstants.TIME_REGEX));
}
}
}

public static boolean isNotRegexIncluded(final ResponseBodyMatchers responseBodyMatchers, final String property) {
var isIncluded = false;

Expand Down Expand Up @@ -270,15 +320,7 @@ public static String getType(final JsonNode node) {
}

public static boolean isEnum(final JsonNode properties) {
boolean isEnum = false;
final Iterator<String> ite = properties.fieldNames();

while (ite.hasNext()) {
if (ite.next().equals(BasicTypeConstants.ENUM)) {
isEnum = true;
}
}
return isEnum;
return properties.has("enum");
}

public static JsonNode subscribeOrPublishOperation(final JsonNode rootNode) {
Expand All @@ -297,4 +339,46 @@ public static void checkIfReferenceWithProperties(final JsonNode jsonNode) {
throw new MultiApiContractConverterException("If reference exists no other additional properties are allowed");
}
}

public static void processDatePropertyType(final ResponseBodyMatchers responseBodyMatchers, final JsonNode properties, final String operationType,
final Map<String, Object> messageBody, final String property, final String path) {
if (operationType.equals(BasicTypeConstants.SUBSCRIBE)) {
if (properties.get(property).has(BasicTypeConstants.EXAMPLE)) {
messageBody.put(property, properties.get(property).get(BasicTypeConstants.EXAMPLE).asText());
} else {
messageBody.put(property, RandomGenerator.randomEnumValue(properties.get(property)));
}
} else {
responseBodyMatchers.jsonPath(path, responseBodyMatchers.byRegex(BasicTypeConstants.DATE_REGEX));
messageBody.put(property, RandomGenerator.getRandomDate());
}
}

public static void processDateTimePropertyType(final ResponseBodyMatchers responseBodyMatchers, final JsonNode properties, final String operationType,
final Map<String, Object> messageBody, final String property, final String path) {
if (operationType.equals(BasicTypeConstants.SUBSCRIBE)) {
if (properties.get(property).has(BasicTypeConstants.EXAMPLE)) {
messageBody.put(property, properties.get(property).get(BasicTypeConstants.EXAMPLE).asText());
} else {
messageBody.put(property, RandomGenerator.getRandomDateTime());
}
} else {
responseBodyMatchers.jsonPath(path, responseBodyMatchers.byRegex(BasicTypeConstants.DATE_TIME_REGEX));
messageBody.put(property, RandomStringUtils.random(5, true, false));
}
}

public static void processTimePropertyType(final ResponseBodyMatchers responseBodyMatchers, final JsonNode properties, final String operationType,
final Map<String, Object> messageBody, final String property, final String path) {
if (operationType.equals(BasicTypeConstants.SUBSCRIBE)) {
if (properties.get(property).has(BasicTypeConstants.EXAMPLE)) {
messageBody.put(property, properties.get(property).get(BasicTypeConstants.EXAMPLE).asText());
} else {
messageBody.put(property, RandomGenerator.getRandomTime());
}
} else {
responseBodyMatchers.jsonPath(path, responseBodyMatchers.byRegex(BasicTypeConstants.TIME_REGEX));
messageBody.put(property, RandomStringUtils.random(5, true, false));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ public final class BasicTypeConstants {

public static final String INTEGER = "integer";

public static final String LONG = "long";

public static final String INT_64 = "int64";

public static final String NUMBER = "number";
Expand Down Expand Up @@ -64,6 +66,12 @@ public final class BasicTypeConstants {

public static final String PAYLOAD = "payload";

public static final String DATE = "date";

public static final String DATE_TIME = "date-time";

public static final String TIME = "time";

public static final RegexProperty STRING_REGEX = RegexPatterns.alphaNumeric();

public static final RegexProperty INT_REGEX = RegexPatterns.positiveInt();
Expand All @@ -72,6 +80,14 @@ public final class BasicTypeConstants {

public static final RegexProperty BOOLEAN_REGEX = RegexPatterns.anyBoolean();

public static final RegexProperty DATE_REGEX = RegexPatterns.isoDate();

public static final RegexProperty DATE_TIME_REGEX = RegexPatterns.isoDateTime();

public static final RegexProperty TIME_REGEX = RegexPatterns.isoTime();

public static final RegexProperty DATE_TIME_OFFSET_REGEX = RegexPatterns.iso8601WithOffset();

public static final String DEFAULT_REGEX = ".*";

public static final Random RANDOM = new Random();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package net.coru.multiapi.converter.utils;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;

import com.fasterxml.jackson.databind.JsonNode;
import org.apache.commons.lang3.RandomUtils;

public final class RandomGenerator {

private RandomGenerator() {
}

public static String getRandomDateTime() {
return getRandomLocalDateTime().format(DateTimeFormatter.ISO_DATE_TIME);
}

public static String getRandomDate() {
return getRandomLocalDateTime().format(DateTimeFormatter.ISO_DATE);
}

public static String getRandomTime() {
return getRandomLocalDateTime().format(DateTimeFormatter.ISO_TIME);
}

public static String getRandomDateTimeOffset() {
return getRandomLocalDateTime().format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
}

private static LocalDateTime getRandomLocalDateTime() {
final long minDay = LocalDateTime.of(1900, 1, 1, 0, 0).toEpochSecond(ZoneOffset.UTC);
final long maxDay = LocalDateTime.of(2100, 1, 1, 0, 0).toEpochSecond(ZoneOffset.UTC);
final long randomSeconds = minDay + RandomUtils.nextLong(0, maxDay - minDay);

return LocalDateTime.ofEpochSecond(randomSeconds, RandomUtils.nextInt(0, 1_000_000_000 - 1), ZoneOffset.UTC);

}

public static String randomEnumValue(final JsonNode jsonNode) {
final String[] enumValues = jsonNode.get("enum").asText().split(",");
return enumValues[RandomUtils.nextInt(0, enumValues.length - 1)];
}
}
Loading

0 comments on commit 777a99d

Please sign in to comment.