Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

introduce JsonPathJacksonProvider #649

Merged
merged 3 commits into from
Mar 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,6 @@
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
</dependency>
<dependency>
<groupId>net.minidev</groupId>
<artifactId>json-smart</artifactId>
</dependency>

<dependency>
<groupId>com.google.classpath-explorer</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package org.jsmart.zerocode.core.di.provider;

import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.Option;
import com.jayway.jsonpath.spi.json.JacksonJsonProvider;
import com.jayway.jsonpath.spi.json.JsonProvider;
import com.jayway.jsonpath.spi.mapper.JacksonMappingProvider;
import com.jayway.jsonpath.spi.mapper.MappingProvider;
import jakarta.inject.Provider;
import java.util.EnumSet;
import java.util.Set;

public class JsonPathJacksonProvider implements Provider<Configuration.Defaults> {
@Override
public Configuration.Defaults get() {
return new Configuration.Defaults() {

private final JsonProvider jsonProvider = new JacksonJsonProvider();
private final MappingProvider mappingProvider = new JacksonMappingProvider();

@Override
public JsonProvider jsonProvider() {
return jsonProvider;
}

@Override
public MappingProvider mappingProvider() {
return mappingProvider;
}

@Override
public Set<Option> options() {
return EnumSet.noneOf(Option.class);
}
};
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@

package org.jsmart.zerocode.core.engine.assertion.array;

import net.minidev.json.JSONArray;
import org.jsmart.zerocode.core.engine.assertion.FieldAssertionMatcher;
import org.jsmart.zerocode.core.engine.assertion.JsonAsserter;

import java.util.List;

import static org.jsmart.zerocode.core.engine.assertion.FieldAssertionMatcher.aMatchingMessage;
import static org.jsmart.zerocode.core.engine.assertion.FieldAssertionMatcher.aNotMatchingMessage;

Expand All @@ -27,21 +28,14 @@ public Object getExpected() {

@Override
public FieldAssertionMatcher actualEqualsToExpected(Object result) {
if(result instanceof JSONArray){

final JSONArray actualArrayValue = (JSONArray) result;

if(actualArrayValue.isEmpty()){
if (result instanceof List<?>) {
List<?> list = (List<?>) result;

if (list.isEmpty()) {
return aMatchingMessage();
}

return aNotMatchingMessage(path, "[]", result);

} else {

return aNotMatchingMessage(path, "[]", result);

}
return aNotMatchingMessage(path, "[]", result);
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@

package org.jsmart.zerocode.core.engine.assertion.array;

import net.minidev.json.JSONArray;
import org.jsmart.zerocode.core.engine.assertion.FieldAssertionMatcher;
import org.jsmart.zerocode.core.engine.assertion.JsonAsserter;

import java.util.List;

import static org.jsmart.zerocode.core.engine.assertion.FieldAssertionMatcher.aMatchingMessage;
import static org.jsmart.zerocode.core.engine.assertion.FieldAssertionMatcher.aNotMatchingMessage;
import static org.jsmart.zerocode.core.engine.tokens.ZeroCodeAssertionTokens.ASSERT_VALUE_EQUAL_TO_NUMBER;
Expand Down Expand Up @@ -41,25 +42,24 @@ public Object getExpected() {

@Override
public FieldAssertionMatcher actualEqualsToExpected(Object result) {
if (result instanceof JSONArray) {

final JSONArray actualArrayValue = (JSONArray) result;
if (result instanceof List<?>) {
List<?> list = (List<?>) result;

if (this.expectedSize == -1 && this.expectedSizeExpression != null) {

return processRelationalExpression(actualArrayValue);
return processRelationalExpression(list);

}

if (actualArrayValue.size() == this.expectedSize) {
if (list.size() == this.expectedSize) {

return aMatchingMessage();
}

return aNotMatchingMessage(
path,
String.format("Array of size %d", expectedSize),
actualArrayValue.size());
list.size());

} else {

Expand All @@ -68,33 +68,33 @@ public FieldAssertionMatcher actualEqualsToExpected(Object result) {
}
}

public FieldAssertionMatcher processRelationalExpression(JSONArray actualArrayValue) {
public FieldAssertionMatcher processRelationalExpression(List<?> list) {
if (expectedSizeExpression.startsWith(ASSERT_VALUE_GREATER_THAN)) {
String greaterThan = this.expectedSizeExpression.substring(ASSERT_VALUE_GREATER_THAN.length());
if (actualArrayValue.size() > Integer.parseInt(greaterThan)) {
if (list.size() > Integer.parseInt(greaterThan)) {
return aMatchingMessage();
}
} else if (expectedSizeExpression.startsWith(ASSERT_VALUE_LESSER_THAN)) {
String lesserThan = this.expectedSizeExpression.substring(ASSERT_VALUE_LESSER_THAN.length());
if (actualArrayValue.size() < Integer.parseInt(lesserThan)) {
if (list.size() < Integer.parseInt(lesserThan)) {
return aMatchingMessage();
}
} else if (expectedSizeExpression.startsWith(ASSERT_VALUE_EQUAL_TO_NUMBER)) {
String equalTo = this.expectedSizeExpression.substring(ASSERT_VALUE_EQUAL_TO_NUMBER.length());
if (actualArrayValue.size() == Integer.parseInt(equalTo)) {
if (list.size() == Integer.parseInt(equalTo)) {
return aMatchingMessage();
}
} else if (expectedSizeExpression.startsWith(ASSERT_VALUE_NOT_EQUAL_TO_NUMBER)) {
String notEqualTo = this.expectedSizeExpression.substring(ASSERT_VALUE_NOT_EQUAL_TO_NUMBER.length());
if (actualArrayValue.size() != Integer.parseInt(notEqualTo)) {
if (list.size() != Integer.parseInt(notEqualTo)) {
return aMatchingMessage();
}
}

return aNotMatchingMessage(
path,
String.format("Array of size %s", expectedSizeExpression),
actualArrayValue.size());
list.size());
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import com.google.inject.Inject;
import com.google.inject.name.Named;
import com.jayway.jsonpath.JsonPath;
import net.minidev.json.JSONArray;
import org.apache.commons.text.StringSubstitutor;
import org.jsmart.zerocode.core.domain.Step;
import org.jsmart.zerocode.core.engine.assertion.FieldAssertionMatcher;
Expand Down Expand Up @@ -442,7 +441,7 @@ private LocalDateTime parseLocalDateTime(String value) {
}

boolean isPathValueJson(Object jsonPathValue) {
return jsonPathValue instanceof LinkedHashMap || jsonPathValue instanceof JSONArray;
return jsonPathValue instanceof LinkedHashMap || jsonPathValue instanceof List<?>;
}

void resolveLeafOnlyNodeValue(String scenarioState, Map<String, String> paramMap, String thisPath) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.inject.Inject;
import com.jayway.jsonpath.JsonPath;
import net.minidev.json.JSONArray;
import net.minidev.json.JSONObject;
import org.jsmart.zerocode.core.domain.Step;
import org.jsmart.zerocode.core.engine.preprocessor.ZeroCodeAssertionsProcessor;
import org.slf4j.Logger;
Expand Down Expand Up @@ -52,43 +50,37 @@ public String sortArrayAndReplaceInResponse(Step thisStep, String results, Strin
//
String transformedPath = zeroCodeAssertionsProcessor.resolveStringJson(path,
resolvedScenarioState);
Object result = getArrayToSort(transformedPath, results);

List<?> listToSort = JsonPath.parse(results).read(transformedPath, List.class);
// sorting passed array
List<Map<?, ?>> sortedList = sortList(listToSort, key, order);
return replaceArrayWithSorted(results, transformedPath, sortedList);

if (result instanceof JSONArray) {
JSONArray arrayToSort = (JSONArray) result;

// sorting passed array
JSONArray sortedArray = sortArray(arrayToSort, key, order);
return replaceArrayWithSorted(results, transformedPath, sortedArray);
} else {
throw new RuntimeException("Can't sort not an array");
}
}

private JSONArray sortArray(JSONArray arrayToSort, String key, String order) {
JSONArray sortedJsonArray = new JSONArray();

List<Map<String, ?>> jsonValues = new ArrayList<>();
private List<Map<?, ?>> sortList(List<?> arrayToSort, String key, String order) {
List<Map<?, ?>> jsonValues = new ArrayList<>();
for (Object o : arrayToSort) {
jsonValues.add((Map<String, ?>) o);
if (o instanceof Map<?, ?>) {
Map<?, ?> map = (Map<?, ?>) o;
jsonValues.add(map);
} else {
LOGGER.error("list item is no map and ignored during sort: {}", o);
}
}

jsonValues.sort((a, b) -> {
Comparable valA;
Comparable valB;

try {
valA = (Comparable) a.get(key);
valB = (Comparable) b.get(key);
} catch (Exception e) {
LOGGER.error("Objects can't be compared" + e);
Comparable valA = (Comparable<?>) a.get(key);
Comparable valB = (Comparable<?>) b.get(key);
return order.equalsIgnoreCase(SortOrder.NATURAL.getValue()) ? valA.compareTo(valB)
: -valA.compareTo(valB);
} catch (ClassCastException e) {
LOGGER.error("Objects can't be compared", e);
throw new RuntimeException("Objects can't be compared", e.getCause());
}
return order.equalsIgnoreCase(SortOrder.NATURAL.getValue()) ? valA.compareTo(valB)
: -valA.compareTo(valB);
});
sortedJsonArray.addAll(jsonValues);
return sortedJsonArray;
return jsonValues;
}

private Map<String, String> convertToMap(String value) {
Expand All @@ -101,11 +93,7 @@ private Map<String, String> convertToMap(String value) {
}
}

public Object getArrayToSort(String path, String results) {
return JsonPath.read(results, path);
}

public String replaceArrayWithSorted(String results, String path, Object sortedArray) {
private String replaceArrayWithSorted(String results, String path, Object sortedArray) {
return JsonPath.parse(results).set(path, sortedArray).jsonString();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
package org.jsmart.zerocode.core.engine.validators;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.inject.Inject;
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.JsonPath;
import java.util.ArrayList;
import java.util.List;
import org.jsmart.zerocode.core.di.provider.JsonPathJacksonProvider;
import org.jsmart.zerocode.core.di.provider.ObjectMapperProvider;
import org.jsmart.zerocode.core.domain.Step;
import org.jsmart.zerocode.core.domain.Validator;
import org.jsmart.zerocode.core.engine.assertion.FieldAssertionMatcher;
import org.jsmart.zerocode.core.engine.assertion.JsonAsserter;
import org.jsmart.zerocode.core.engine.preprocessor.ZeroCodeAssertionsProcessor;
import org.slf4j.Logger;

import java.util.ArrayList;
import java.util.List;

import static org.jsmart.zerocode.core.utils.HelperJsonUtils.strictComparePayload;
import static org.slf4j.LoggerFactory.getLogger;

Expand All @@ -20,9 +26,13 @@ public class ZeroCodeValidatorImpl implements ZeroCodeValidator {

private final ZeroCodeAssertionsProcessor zeroCodeAssertionsProcessor;

private final ObjectMapper mapper;

@Inject
public ZeroCodeValidatorImpl(ZeroCodeAssertionsProcessor zeroCodeAssertionsProcessor) {
this.zeroCodeAssertionsProcessor = zeroCodeAssertionsProcessor;
this.mapper = new ObjectMapperProvider().get();
Configuration.setDefaults(new JsonPathJacksonProvider().get());
}

@Override
Expand All @@ -40,10 +50,16 @@ public List<FieldAssertionMatcher> validateFlat(Step thisStep, String actualResu
JsonNode expectedValue = validator.getValue();

Object actualValue = JsonPath.read(actualResult, transformed);
String actualString;
try {
actualString = this.mapper.writeValueAsString(actualValue);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}

List<JsonAsserter> asserters = zeroCodeAssertionsProcessor.createJsonAsserters(expectedValue.toString());

failureResults.addAll(zeroCodeAssertionsProcessor.assertAllAndReturnFailed(asserters, actualValue.toString()));
failureResults.addAll(zeroCodeAssertionsProcessor.assertAllAndReturnFailed(asserters, actualString));
}

return failureResults;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
package org.jsmart.zerocode.core.kafka.helper;

import static org.jsmart.zerocode.core.kafka.KafkaConstants.RAW;
import static org.jsmart.zerocode.core.kafka.common.CommonConfigs.BOOTSTRAP_SERVERS;
import static org.jsmart.zerocode.core.kafka.common.KafkaCommonUtils.resolveValuePlaceHolders;
import static org.jsmart.zerocode.core.kafka.error.KafkaMessageConstants.NO_RECORD_FOUND_TO_SEND;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Properties;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.io.Resources;
import com.google.gson.Gson;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.Message;
import com.google.protobuf.Message.Builder;
import com.google.protobuf.util.JsonFormat;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.PathNotFoundException;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;
Expand All @@ -22,15 +19,17 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.io.Resources;
import com.google.gson.Gson;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.Message;
import com.google.protobuf.Message.Builder;
import com.google.protobuf.util.JsonFormat;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.PathNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Properties;

import static org.jsmart.zerocode.core.kafka.KafkaConstants.RAW;
import static org.jsmart.zerocode.core.kafka.common.CommonConfigs.BOOTSTRAP_SERVERS;
import static org.jsmart.zerocode.core.kafka.common.KafkaCommonUtils.resolveValuePlaceHolders;
import static org.jsmart.zerocode.core.kafka.error.KafkaMessageConstants.NO_RECORD_FOUND_TO_SEND;

public class KafkaProducerHelper {
private static final Logger LOGGER = LoggerFactory.getLogger(KafkaProducerHelper.class);
Expand Down
Loading
Loading