Skip to content

Commit 777a99d

Browse files
authored
71 failed to execute goal generatetests while trying to generate contracts from an openapi yaml document (#73)
1 parent b2b785b commit 777a99d

File tree

8 files changed

+461
-158
lines changed

8 files changed

+461
-158
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>net.coru</groupId>
88
<artifactId>scc-multiapi-converter</artifactId>
9-
<version>3.0.1</version>
9+
<version>3.0.2</version>
1010
<name>SCC-MultiApi-Converter</name>
1111
<description>Generates Spring Cloud Contracts based on an OpenApi and AsyncApi document</description>
1212
<url>https://github.com/corunet/scc-multiapi-converter</url>

src/main/java/net/coru/multiapi/converter/asyncapi/AsyncApiContractConverter.java

Lines changed: 165 additions & 71 deletions
Large diffs are not rendered by default.

src/main/java/net/coru/multiapi/converter/asyncapi/AsyncApiContractConverterUtils.java

Lines changed: 126 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,19 @@
66

77
package net.coru.multiapi.converter.asyncapi;
88

9+
import java.util.ArrayList;
910
import java.util.Iterator;
1011
import java.util.List;
1112
import java.util.Map;
1213
import java.util.Objects;
1314

1415
import com.fasterxml.jackson.core.JsonProcessingException;
1516
import com.fasterxml.jackson.databind.JsonNode;
16-
import net.coru.multiapi.converter.exception.ElementNotFoundException;
1717
import net.coru.multiapi.converter.exception.MultiApiContractConverterException;
1818
import net.coru.multiapi.converter.utils.BasicTypeConstants;
19+
import net.coru.multiapi.converter.utils.RandomGenerator;
1920
import org.apache.commons.lang3.RandomStringUtils;
21+
import org.apache.commons.lang3.RandomUtils;
2022
import org.springframework.cloud.contract.spec.internal.ResponseBodyMatchers;
2123

2224
public final class AsyncApiContractConverterUtils {
@@ -27,11 +29,15 @@ public static void processEnumPropertyType(
2729
final ResponseBodyMatchers responseBodyMatchers, final JsonNode properties, final String operationType, final Map<String, Object> messageBody, final String property,
2830
final String path, final String enumType) {
2931
if (operationType.equals(BasicTypeConstants.SUBSCRIBE)) {
30-
messageBody.put(property, processEnumTypes(properties.get(property).get(BasicTypeConstants.EXAMPLE), enumType));
32+
if (properties.get(property).has(BasicTypeConstants.EXAMPLE)) {
33+
messageBody.put(property, properties.get(property).get(BasicTypeConstants.EXAMPLE).textValue());
34+
} else {
35+
messageBody.put(property, processEnumTypes(properties.get(property)));
36+
}
3137
} else {
3238
final var enumList = properties.get(property).get(BasicTypeConstants.ENUM);
3339
responseBodyMatchers.jsonPath(path, responseBodyMatchers.byRegex(getEnumRegex(enumType, properties, property)));
34-
messageBody.put(property, processEnumTypes(enumList.get(BasicTypeConstants.RANDOM.nextInt(enumList.size())), enumType));
40+
messageBody.put(property, enumList.get(BasicTypeConstants.RANDOM.nextInt(enumList.size())).textValue());
3541
}
3642
}
3743

@@ -61,59 +67,55 @@ public static void processFloatPropertyType(
6167
final ResponseBodyMatchers responseBodyMatchers, final JsonNode properties, final String operationType, final Map<String, Object> messageBody, final String property,
6268
final String path) {
6369
if (operationType.equals(BasicTypeConstants.SUBSCRIBE)) {
64-
messageBody.put(property, Float.parseFloat(properties.get(property).get(BasicTypeConstants.EXAMPLE).asText()));
70+
if (properties.get(property).has(BasicTypeConstants.EXAMPLE)) {
71+
messageBody.put(property, Float.parseFloat(properties.get(property).get(BasicTypeConstants.EXAMPLE).asText()));
72+
} else {
73+
messageBody.put(property, RandomUtils.nextFloat());
74+
}
6575
} else {
6676
responseBodyMatchers.jsonPath(path, responseBodyMatchers.byRegex(BasicTypeConstants.DECIMAL_REGEX));
67-
messageBody.put(property, Math.abs(BasicTypeConstants.RANDOM.nextFloat()));
77+
messageBody.put(property, RandomUtils.nextFloat());
6878
}
6979
}
7080

7181
public static void processNumberPropertyType(
7282
final ResponseBodyMatchers responseBodyMatchers, final JsonNode properties, final String operationType, final Map<String, Object> messageBody, final String property,
7383
final String path) {
7484
if (operationType.equals(BasicTypeConstants.SUBSCRIBE)) {
75-
messageBody.put(property, properties.get(property).get(BasicTypeConstants.EXAMPLE).asInt());
85+
if (properties.get(property).has(BasicTypeConstants.EXAMPLE)) {
86+
messageBody.put(property, properties.get(property).get(BasicTypeConstants.EXAMPLE).asInt());
87+
} else {
88+
messageBody.put(property, RandomUtils.nextInt());
89+
}
7690
} else {
7791
responseBodyMatchers.jsonPath(path, responseBodyMatchers.byRegex(BasicTypeConstants.INT_REGEX));
78-
messageBody.put(property, BasicTypeConstants.RANDOM.nextInt());
92+
messageBody.put(property, RandomUtils.nextInt());
7993
}
8094
}
8195

8296
public static void processStringPropertyType(
8397
final ResponseBodyMatchers responseBodyMatchers, final JsonNode properties, final String operationType, final Map<String, Object> messageBody, final String property,
8498
final String path) {
8599
if (operationType.equals(BasicTypeConstants.SUBSCRIBE)) {
86-
messageBody.put(property, properties.get(property).get(BasicTypeConstants.EXAMPLE).asText());
100+
if (properties.get(property).has(BasicTypeConstants.EXAMPLE)) {
101+
messageBody.put(property, properties.get(property).get(BasicTypeConstants.EXAMPLE).asText());
102+
} else {
103+
messageBody.put(property, RandomStringUtils.random(5, true, false));
104+
}
87105
} else {
88106
responseBodyMatchers.jsonPath(path, responseBodyMatchers.byRegex(BasicTypeConstants.STRING_REGEX));
89107
messageBody.put(property, RandomStringUtils.random(5, true, false));
90108
}
91109
}
92110

93-
public static Object processEnumTypes(final JsonNode value, final String type) {
94-
final Object enumValue;
95-
96-
switch (type) {
97-
case BasicTypeConstants.STRING:
98-
enumValue = value.asText();
99-
break;
100-
case BasicTypeConstants.INT_32:
101-
case BasicTypeConstants.NUMBER:
102-
enumValue = value.asInt();
103-
break;
104-
case BasicTypeConstants.INT_64:
105-
case BasicTypeConstants.FLOAT:
106-
case BasicTypeConstants.DOUBLE:
107-
enumValue = value.asDouble();
108-
break;
109-
case BasicTypeConstants.BOOLEAN:
110-
enumValue = value.asBoolean();
111-
break;
112-
default:
113-
throw new ElementNotFoundException(BasicTypeConstants.TYPE);
114-
}
111+
public static String processEnumTypes(final JsonNode value) {
112+
final List<String> enumValueList = new ArrayList<>();
115113

116-
return enumValue;
114+
final var enumValuesIT = value.get("enum").elements();
115+
while (enumValuesIT.hasNext()) {
116+
enumValueList.add(enumValuesIT.next().textValue());
117+
}
118+
return enumValueList.get(RandomUtils.nextInt(0, enumValueList.size()));
117119
}
118120

119121
public static String getEnumRegex(final String type, final JsonNode properties, final String property) {
@@ -140,11 +142,11 @@ public static void processArrayEnumType(
140142
if (operationType.equals(BasicTypeConstants.SUBSCRIBE)) {
141143
final var arrayNode = BasicTypeConstants.OBJECT_MAPPER.readTree(internalProperties.toString()).get(BasicTypeConstants.EXAMPLE);
142144
for (int i = 0; i < arrayNode.size(); i++) {
143-
arrayValues.add(AsyncApiContractConverterUtils.processEnumTypes(arrayNode.get(i), enumType));
145+
arrayValues.add(AsyncApiContractConverterUtils.processEnumTypes(arrayNode.get(i)));
144146
}
145147
} else {
146148
final var enumList = internalProperties.get(BasicTypeConstants.ENUM);
147-
arrayValues.add(AsyncApiContractConverterUtils.processEnumTypes(enumList.get(BasicTypeConstants.RANDOM.nextInt(enumList.size())), enumType));
149+
arrayValues.add(AsyncApiContractConverterUtils.processEnumTypes(enumList.get(BasicTypeConstants.RANDOM.nextInt(enumList.size()))));
148150
if (isNotRegexIncluded(responseBodyMatchers, path + "[0]")) {
149151
responseBodyMatchers.jsonPath(path + "[0]", responseBodyMatchers.byRegex(AsyncApiContractConverterUtils.getEnumRegex(enumType, internalProperties, property)));
150152
}
@@ -236,6 +238,54 @@ public static void processArrayStringType(
236238
}
237239
}
238240

241+
public static void processArrayDateType(
242+
final ResponseBodyMatchers responseBodyMatchers, final String path, final String operationType, final List<Object> arrayValues, final JsonNode internalProperties)
243+
throws JsonProcessingException {
244+
if (operationType.equals(BasicTypeConstants.SUBSCRIBE)) {
245+
final var arrayNode = BasicTypeConstants.OBJECT_MAPPER.readTree(internalProperties.toString()).get(BasicTypeConstants.EXAMPLE);
246+
for (int i = 0; i < arrayNode.size(); i++) {
247+
arrayValues.add(arrayNode.get(i).asText());
248+
}
249+
} else {
250+
arrayValues.add(RandomStringUtils.random(5, true, false));
251+
if (isNotRegexIncluded(responseBodyMatchers, path + "[0]")) {
252+
responseBodyMatchers.jsonPath(path + "[0]", responseBodyMatchers.byRegex(BasicTypeConstants.DATE_REGEX));
253+
}
254+
}
255+
}
256+
257+
public static void processArrayDateTimeType(
258+
final ResponseBodyMatchers responseBodyMatchers, final String path, final String operationType, final List<Object> arrayValues, final JsonNode internalProperties)
259+
throws JsonProcessingException {
260+
if (operationType.equals(BasicTypeConstants.SUBSCRIBE)) {
261+
final var arrayNode = BasicTypeConstants.OBJECT_MAPPER.readTree(internalProperties.toString()).get(BasicTypeConstants.EXAMPLE);
262+
for (int i = 0; i < arrayNode.size(); i++) {
263+
arrayValues.add(arrayNode.get(i).asText());
264+
}
265+
} else {
266+
arrayValues.add(RandomStringUtils.random(5, true, false));
267+
if (isNotRegexIncluded(responseBodyMatchers, path + "[0]")) {
268+
responseBodyMatchers.jsonPath(path + "[0]", responseBodyMatchers.byRegex(BasicTypeConstants.DATE_TIME_REGEX));
269+
}
270+
}
271+
}
272+
273+
public static void processArrayTimeType(
274+
final ResponseBodyMatchers responseBodyMatchers, final String path, final String operationType, final List<Object> arrayValues, final JsonNode internalProperties)
275+
throws JsonProcessingException {
276+
if (operationType.equals(BasicTypeConstants.SUBSCRIBE)) {
277+
final var arrayNode = BasicTypeConstants.OBJECT_MAPPER.readTree(internalProperties.toString()).get(BasicTypeConstants.EXAMPLE);
278+
for (int i = 0; i < arrayNode.size(); i++) {
279+
arrayValues.add(arrayNode.get(i).asText());
280+
}
281+
} else {
282+
arrayValues.add(RandomStringUtils.random(5, true, false));
283+
if (isNotRegexIncluded(responseBodyMatchers, path + "[0]")) {
284+
responseBodyMatchers.jsonPath(path + "[0]", responseBodyMatchers.byRegex(BasicTypeConstants.TIME_REGEX));
285+
}
286+
}
287+
}
288+
239289
public static boolean isNotRegexIncluded(final ResponseBodyMatchers responseBodyMatchers, final String property) {
240290
var isIncluded = false;
241291

@@ -270,15 +320,7 @@ public static String getType(final JsonNode node) {
270320
}
271321

272322
public static boolean isEnum(final JsonNode properties) {
273-
boolean isEnum = false;
274-
final Iterator<String> ite = properties.fieldNames();
275-
276-
while (ite.hasNext()) {
277-
if (ite.next().equals(BasicTypeConstants.ENUM)) {
278-
isEnum = true;
279-
}
280-
}
281-
return isEnum;
323+
return properties.has("enum");
282324
}
283325

284326
public static JsonNode subscribeOrPublishOperation(final JsonNode rootNode) {
@@ -297,4 +339,46 @@ public static void checkIfReferenceWithProperties(final JsonNode jsonNode) {
297339
throw new MultiApiContractConverterException("If reference exists no other additional properties are allowed");
298340
}
299341
}
342+
343+
public static void processDatePropertyType(final ResponseBodyMatchers responseBodyMatchers, final JsonNode properties, final String operationType,
344+
final Map<String, Object> messageBody, final String property, final String path) {
345+
if (operationType.equals(BasicTypeConstants.SUBSCRIBE)) {
346+
if (properties.get(property).has(BasicTypeConstants.EXAMPLE)) {
347+
messageBody.put(property, properties.get(property).get(BasicTypeConstants.EXAMPLE).asText());
348+
} else {
349+
messageBody.put(property, RandomGenerator.randomEnumValue(properties.get(property)));
350+
}
351+
} else {
352+
responseBodyMatchers.jsonPath(path, responseBodyMatchers.byRegex(BasicTypeConstants.DATE_REGEX));
353+
messageBody.put(property, RandomGenerator.getRandomDate());
354+
}
355+
}
356+
357+
public static void processDateTimePropertyType(final ResponseBodyMatchers responseBodyMatchers, final JsonNode properties, final String operationType,
358+
final Map<String, Object> messageBody, final String property, final String path) {
359+
if (operationType.equals(BasicTypeConstants.SUBSCRIBE)) {
360+
if (properties.get(property).has(BasicTypeConstants.EXAMPLE)) {
361+
messageBody.put(property, properties.get(property).get(BasicTypeConstants.EXAMPLE).asText());
362+
} else {
363+
messageBody.put(property, RandomGenerator.getRandomDateTime());
364+
}
365+
} else {
366+
responseBodyMatchers.jsonPath(path, responseBodyMatchers.byRegex(BasicTypeConstants.DATE_TIME_REGEX));
367+
messageBody.put(property, RandomStringUtils.random(5, true, false));
368+
}
369+
}
370+
371+
public static void processTimePropertyType(final ResponseBodyMatchers responseBodyMatchers, final JsonNode properties, final String operationType,
372+
final Map<String, Object> messageBody, final String property, final String path) {
373+
if (operationType.equals(BasicTypeConstants.SUBSCRIBE)) {
374+
if (properties.get(property).has(BasicTypeConstants.EXAMPLE)) {
375+
messageBody.put(property, properties.get(property).get(BasicTypeConstants.EXAMPLE).asText());
376+
} else {
377+
messageBody.put(property, RandomGenerator.getRandomTime());
378+
}
379+
} else {
380+
responseBodyMatchers.jsonPath(path, responseBodyMatchers.byRegex(BasicTypeConstants.TIME_REGEX));
381+
messageBody.put(property, RandomStringUtils.random(5, true, false));
382+
}
383+
}
300384
}

src/main/java/net/coru/multiapi/converter/utils/BasicTypeConstants.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ public final class BasicTypeConstants {
2626

2727
public static final String INTEGER = "integer";
2828

29+
public static final String LONG = "long";
30+
2931
public static final String INT_64 = "int64";
3032

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

6567
public static final String PAYLOAD = "payload";
6668

69+
public static final String DATE = "date";
70+
71+
public static final String DATE_TIME = "date-time";
72+
73+
public static final String TIME = "time";
74+
6775
public static final RegexProperty STRING_REGEX = RegexPatterns.alphaNumeric();
6876

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

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

83+
public static final RegexProperty DATE_REGEX = RegexPatterns.isoDate();
84+
85+
public static final RegexProperty DATE_TIME_REGEX = RegexPatterns.isoDateTime();
86+
87+
public static final RegexProperty TIME_REGEX = RegexPatterns.isoTime();
88+
89+
public static final RegexProperty DATE_TIME_OFFSET_REGEX = RegexPatterns.iso8601WithOffset();
90+
7591
public static final String DEFAULT_REGEX = ".*";
7692

7793
public static final Random RANDOM = new Random();
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package net.coru.multiapi.converter.utils;
2+
3+
import java.time.LocalDateTime;
4+
import java.time.ZoneOffset;
5+
import java.time.format.DateTimeFormatter;
6+
7+
import com.fasterxml.jackson.databind.JsonNode;
8+
import org.apache.commons.lang3.RandomUtils;
9+
10+
public final class RandomGenerator {
11+
12+
private RandomGenerator() {
13+
}
14+
15+
public static String getRandomDateTime() {
16+
return getRandomLocalDateTime().format(DateTimeFormatter.ISO_DATE_TIME);
17+
}
18+
19+
public static String getRandomDate() {
20+
return getRandomLocalDateTime().format(DateTimeFormatter.ISO_DATE);
21+
}
22+
23+
public static String getRandomTime() {
24+
return getRandomLocalDateTime().format(DateTimeFormatter.ISO_TIME);
25+
}
26+
27+
public static String getRandomDateTimeOffset() {
28+
return getRandomLocalDateTime().format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
29+
}
30+
31+
private static LocalDateTime getRandomLocalDateTime() {
32+
final long minDay = LocalDateTime.of(1900, 1, 1, 0, 0).toEpochSecond(ZoneOffset.UTC);
33+
final long maxDay = LocalDateTime.of(2100, 1, 1, 0, 0).toEpochSecond(ZoneOffset.UTC);
34+
final long randomSeconds = minDay + RandomUtils.nextLong(0, maxDay - minDay);
35+
36+
return LocalDateTime.ofEpochSecond(randomSeconds, RandomUtils.nextInt(0, 1_000_000_000 - 1), ZoneOffset.UTC);
37+
38+
}
39+
40+
public static String randomEnumValue(final JsonNode jsonNode) {
41+
final String[] enumValues = jsonNode.get("enum").asText().split(",");
42+
return enumValues[RandomUtils.nextInt(0, enumValues.length - 1)];
43+
}
44+
}

0 commit comments

Comments
 (0)