diff --git a/src/main/java/com/endava/cats/args/FilesArguments.java b/src/main/java/com/endava/cats/args/FilesArguments.java index 3cdf13ee7..0fcc4c423 100644 --- a/src/main/java/com/endava/cats/args/FilesArguments.java +++ b/src/main/java/com/endava/cats/args/FilesArguments.java @@ -22,15 +22,14 @@ import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.stream.Collectors; @Singleton public class FilesArguments { private static final String ALL = "all"; private final PrettyLogger log = PrettyLoggerFactory.getLogger(this.getClass()); - private Map> headers; - private Map> queryParams; - private Map> refData; + private Map> headers; + private Map> queryParams; + private Map> refData; private Map> customFuzzerDetails = new HashMap<>(); private Map> securityFuzzerDetails = new HashMap<>(); @@ -49,7 +48,7 @@ public class FilesArguments { description = "Specifies the headers that will be passed along with the request. When supplied it will be applied to ALL paths. For per-path control use the `--headers` arg that requires a file.") @Setter @Getter - Map headersMap; + Map headersMap; @CommandLine.Option(names = {"--queryParams"}, description = "Specifies additional query parameters that will be passed along with request. This can be used to pass non-documented query params") @@ -137,7 +136,7 @@ public void loadHeaders() throws IOException { /*Merge headers from file with the ones supplied using the -H argument*/ if (headersMap != null) { headers.merge(ALL, headersMap, (stringStringMap, stringStringMap2) -> { - Map mergedMap = new HashMap<>(stringStringMap); + Map mergedMap = new HashMap<>(stringStringMap); mergedMap.putAll(stringStringMap2); return mergedMap; }); @@ -178,7 +177,7 @@ public String replacePathWithUrlParams(String startingUrl) { * * @return a Map representation of the --headers file with paths being the Map keys */ - public Map getHeaders(String path) { + public Map getHeaders(String path) { return getPathAndAll(headers, path); } @@ -190,7 +189,7 @@ public Map getHeaders(String path) { * @param currentPath the current API path * @return a Map with the supplied --refData */ - public Map getRefData(String currentPath) { + public Map getRefData(String currentPath) { return getPathAndAll(refData, currentPath); } @@ -201,7 +200,7 @@ public Map getRefData(String currentPath) { * @param path the given path * @return a key-value map with all additional query params */ - public Map getAdditionalQueryParamsForPath(String path) { + public Map getAdditionalQueryParamsForPath(String path) { return getPathAndAll(queryParams, path); } @@ -224,20 +223,19 @@ public Map> getSecurityFuzzerDetails() { } - static Map getPathAndAll(Map> collection, String path) { + static Map getPathAndAll(Map> collection, String path) { return collection.entrySet().stream() .filter(entry -> entry.getKey().equalsIgnoreCase(path) || entry.getKey().equalsIgnoreCase(ALL)) .map(Map.Entry::getValue).collect(HashMap::new, Map::putAll, Map::putAll); } - - private Map> loadFileAsMapOfMapsOfStrings(File file, String fileType) throws IOException { - Map> fromFile = new HashMap<>(); + private Map> loadFileAsMapOfMapsOfStrings(File file, String fileType) throws IOException { + Map> fromFile = new HashMap<>(); if (file == null) { log.debug("No {} file provided!", fileType); } else { log.config("{} file supplied {}", fileType, file.getAbsolutePath()); - fromFile = this.loadYamlFileToMap(file.getAbsolutePath()); + fromFile = this.parseYaml(file.getAbsolutePath()); log.debug("{} file loaded successfully: {}", fileType, fromFile); } return fromFile; @@ -257,14 +255,4 @@ public Map> parseYaml(String yaml) throws IOExceptio } return result; } - - public Map> loadYamlFileToMap(String filePath) throws IOException { - Map> result = new HashMap<>(); - Map> headersAsObject = this.parseYaml(filePath); - for (Map.Entry> entry : headersAsObject.entrySet()) { - result.put(entry.getKey(), entry.getValue().entrySet() - .stream().collect(Collectors.toMap(Map.Entry::getKey, en -> String.valueOf(en.getValue())))); - } - return result; - } } diff --git a/src/main/java/com/endava/cats/command/CatsCommand.java b/src/main/java/com/endava/cats/command/CatsCommand.java index 97893a283..01eb1f23a 100644 --- a/src/main/java/com/endava/cats/command/CatsCommand.java +++ b/src/main/java/com/endava/cats/command/CatsCommand.java @@ -60,7 +60,7 @@ defaultValueProvider = CommandLine.PropertiesDefaultProvider.class, exitCodeOnInvalidInput = 191, exitCodeOnExecutionException = 192, - resourceBundle = "version", +// resourceBundle = "version", subcommands = { AutoComplete.GenerateCompletion.class, CommandLine.HelpCommand.class, diff --git a/src/main/java/com/endava/cats/command/RunCommand.java b/src/main/java/com/endava/cats/command/RunCommand.java index c05ae7022..fe35eca37 100644 --- a/src/main/java/com/endava/cats/command/RunCommand.java +++ b/src/main/java/com/endava/cats/command/RunCommand.java @@ -65,7 +65,7 @@ public class RunCommand implements Runnable, CommandLine.IExitCodeGenerator { @CommandLine.Option(names = {"-H"}, description = "Specifies the headers that will be passed along with the request. When supplied it will be applied to ALL paths. For per-path control use the `--headers` arg that requires a file.") - Map headersMap; + Map headersMap; @CommandLine.Option(names = {"--createRefData"}, description = "This is only applicable when enabling the @|bold FunctionalFuzzer |@. It will instruct the @|bold FunctionalFuzzer|@ to create a @|bold,underline --refData|@ file " + diff --git a/src/main/java/com/endava/cats/fuzzer/executor/FieldsIteratorExecutor.java b/src/main/java/com/endava/cats/fuzzer/executor/FieldsIteratorExecutor.java index 11633b682..bd5c68afa 100644 --- a/src/main/java/com/endava/cats/fuzzer/executor/FieldsIteratorExecutor.java +++ b/src/main/java/com/endava/cats/fuzzer/executor/FieldsIteratorExecutor.java @@ -62,7 +62,7 @@ public void execute(FieldsIteratorExecutorContext context) { Set allFields = context.getFuzzingData().getAllFieldsByHttpMethod(); context.getLogger().debug("All fields: {}", allFields); List fieldsToBeRemoved = filesArguments.getRefData(context.getFuzzingData().getPath()).entrySet() - .stream().filter(entry -> entry.getValue().equalsIgnoreCase(CATS_REMOVE_FIELD)).map(Map.Entry::getKey).toList(); + .stream().filter(entry -> String.valueOf(entry.getValue()).equalsIgnoreCase(CATS_REMOVE_FIELD)).map(Map.Entry::getKey).toList(); context.getLogger().config("The following fields marked as [{}] in refData will not be fuzzed: {}", CATS_REMOVE_FIELD, fieldsToBeRemoved); fieldsToBeRemoved.forEach(allFields::remove); diff --git a/src/main/java/com/endava/cats/fuzzer/fields/InvalidReferencesFieldsFuzzer.java b/src/main/java/com/endava/cats/fuzzer/fields/InvalidReferencesFieldsFuzzer.java index 46da603e1..b6b88cc95 100644 --- a/src/main/java/com/endava/cats/fuzzer/fields/InvalidReferencesFieldsFuzzer.java +++ b/src/main/java/com/endava/cats/fuzzer/fields/InvalidReferencesFieldsFuzzer.java @@ -11,6 +11,7 @@ import com.endava.cats.generator.simple.UnicodeGenerator; import com.endava.cats.report.TestCaseListener; import com.endava.cats.util.ConsoleUtils; +import com.endava.cats.util.WordUtils; import io.github.ludovicianul.prettylogger.PrettyLogger; import io.github.ludovicianul.prettylogger.PrettyLoggerFactory; @@ -80,6 +81,7 @@ private List replacePathVariables(String path) { for (String variable : variables) { String variableName = variable.substring(1, variable.length() - 1); String value = Optional.ofNullable(filesArguments.getRefData(path).get(variableName)) + .map(WordUtils::nullOrValueOf) .orElse(filesArguments.getUrlParamsList() .stream() .filter(param -> param.startsWith(variableName + ":")) diff --git a/src/main/java/com/endava/cats/fuzzer/fields/base/BaseFieldsFuzzer.java b/src/main/java/com/endava/cats/fuzzer/fields/base/BaseFieldsFuzzer.java index 157e676ac..8a810f163 100644 --- a/src/main/java/com/endava/cats/fuzzer/fields/base/BaseFieldsFuzzer.java +++ b/src/main/java/com/endava/cats/fuzzer/fields/base/BaseFieldsFuzzer.java @@ -51,7 +51,7 @@ public void fuzz(FuzzingData data) { logger.debug("All fields {}", allFields); List fieldsToBeRemoved = filesArguments.getRefData(data.getPath()).entrySet() - .stream().filter(entry -> entry.getValue().equalsIgnoreCase(CATS_REMOVE_FIELD)).map(Map.Entry::getKey).toList(); + .stream().filter(entry -> String.valueOf(entry.getValue()).equalsIgnoreCase(CATS_REMOVE_FIELD)).map(Map.Entry::getKey).toList(); logger.config("The following fields marked as [{}] in refData will not be fuzzed: {}", CATS_REMOVE_FIELD, fieldsToBeRemoved); fieldsToBeRemoved.forEach(allFields::remove); diff --git a/src/main/java/com/endava/cats/fuzzer/special/CustomFuzzerUtil.java b/src/main/java/com/endava/cats/fuzzer/special/CustomFuzzerUtil.java index a72f8b4cb..3d5ef865d 100644 --- a/src/main/java/com/endava/cats/fuzzer/special/CustomFuzzerUtil.java +++ b/src/main/java/com/endava/cats/fuzzer/special/CustomFuzzerUtil.java @@ -15,6 +15,7 @@ import com.endava.cats.strategy.FuzzingStrategy; import com.endava.cats.util.CatsDSLWords; import com.endava.cats.util.CatsUtil; +import com.endava.cats.util.WordUtils; import io.github.ludovicianul.prettylogger.PrettyLogger; import io.github.ludovicianul.prettylogger.PrettyLoggerFactory; import jakarta.enterprise.context.ApplicationScoped; @@ -54,13 +55,13 @@ public CustomFuzzerUtil(ServiceCaller sc, CatsUtil cu, TestCaseListener tcl) { } - public void process(FuzzingData data, String testName, Map currentPathValues) { + public void process(FuzzingData data, String testName, Map currentPathValues) { int howManyTests = this.getNumberOfIterationsBasedOnHeaders(data, currentPathValues); boolean isHeadersFuzzing = currentPathValues.get(CATS_HEADERS) != null; CatsHeader[] arrayOfHeaders = data.getHeaders().toArray(new CatsHeader[0]); for (int i = 0; i < howManyTests; i++) { - String expectedResponseCode = currentPathValues.get(EXPECTED_RESPONSE_CODE); + String expectedResponseCode = String.valueOf(currentPathValues.get(EXPECTED_RESPONSE_CODE)); this.startCustomTest(testName, currentPathValues, expectedResponseCode); String payloadWithCustomValuesReplaced = this.getJsonWithCustomValuesFromFile(data, currentPathValues); @@ -74,7 +75,7 @@ public void process(FuzzingData data, String testName, Map curre this.setOutputVariables(currentPathValues, response, payloadWithCustomValuesReplaced); - String verify = currentPathValues.get(VERIFY); + String verify = WordUtils.nullOrValueOf(currentPathValues.get(VERIFY)); if (verify != null) { this.checkVerifiesAndReport(data, payloadWithCustomValuesReplaced, response, verify, expectedResponseCode); @@ -84,18 +85,18 @@ public void process(FuzzingData data, String testName, Map curre } } - private Set getHeaders(CatsHeader[] existingHeaders, Map currentPathValues, boolean isHeadersFuzzing, int i) { + private Set getHeaders(CatsHeader[] existingHeaders, Map currentPathValues, boolean isHeadersFuzzing, int i) { Set headers = new java.util.HashSet<>(Set.of(existingHeaders)); if (!headers.isEmpty() && isHeadersFuzzing) { CatsHeader headerToReplace = existingHeaders[i]; - String toReplaceWith = currentPathValues.get(headerToReplace.getName()); - headerToReplace.withValue(toReplaceWith); + Object toReplaceWith = currentPathValues.get(headerToReplace.getName()); + headerToReplace.withValue(WordUtils.nullOrValueOf(toReplaceWith)); headers.add(headerToReplace); } return headers; } - private int getNumberOfIterationsBasedOnHeaders(FuzzingData data, Map currentPathValues) { + private int getNumberOfIterationsBasedOnHeaders(FuzzingData data, Map currentPathValues) { boolean isHeadersFuzzing = currentPathValues.get(CATS_HEADERS) != null; if (isHeadersFuzzing) { log.note("Fuzzing headers! Total number of headers: {}", data.getHeaders().size()); @@ -105,13 +106,13 @@ private int getNumberOfIterationsBasedOnHeaders(FuzzingData data, Map currentPathValues, CatsResponse response, String request) { - String output = currentPathValues.get(OUTPUT); + private void setOutputVariables(Map currentPathValues, CatsResponse response, String request) { + Object output = currentPathValues.get(OUTPUT); /* add all variables first; resolve any variables requiring request access, resolve response variables and merge all in the end.*/ /* we merge request variables at the end, because otherwise the resolved values will try to be searched in response and result in NOT_SET*/ if (output != null) { - Map variablesFromYaml = this.parseYmlEntryIntoMap(output); + Map variablesFromYaml = this.parseYmlEntryIntoMap(String.valueOf(output)); this.variables.putAll(variablesFromYaml); Map requestVariables = matchVariablesFromRequest(request); this.variables.putAll(matchVariablesWithTheResponse(response, variablesFromYaml, Map.Entry::getValue)); @@ -211,8 +212,8 @@ private Map matchVariablesWithTheResponse(CatsResponse response, } - public String getTestScenario(String testName, Map currentPathValues) { - String description = currentPathValues.get(DESCRIPTION); + public String getTestScenario(String testName, Map currentPathValues) { + String description = WordUtils.nullOrValueOf(currentPathValues.get(DESCRIPTION)); if (StringUtils.isNotBlank(description)) { return description; } @@ -221,16 +222,16 @@ public String getTestScenario(String testName, Map currentPathVa } - public void startCustomTest(String testName, Map currentPathValues, String expectedResponseCode) { + public void startCustomTest(String testName, Map currentPathValues, String expectedResponseCode) { String testScenario = this.getTestScenario(testName, currentPathValues); testCaseListener.addScenario(log, "Scenario: {}", testScenario); testCaseListener.addExpectedResult(log, "Should return [{}]", expectedResponseCode); } - public String getJsonWithCustomValuesFromFile(FuzzingData data, Map currentPathValues) { + public String getJsonWithCustomValuesFromFile(FuzzingData data, Map currentPathValues) { String payload = data.getPayload(); - for (Map.Entry entry : currentPathValues.entrySet()) { + for (Map.Entry entry : currentPathValues.entrySet()) { if (this.isCatsRemove(entry)) { payload = JsonUtils.deleteNode(payload, entry.getKey()); } else if (this.isNotAReservedWord(entry.getKey())) { @@ -243,8 +244,8 @@ public String getJsonWithCustomValuesFromFile(FuzzingData data, Map keyValue) { - return ServiceCaller.CATS_REMOVE_FIELD.equalsIgnoreCase(keyValue.getValue()); + public boolean isCatsRemove(Map.Entry keyValue) { + return ServiceCaller.CATS_REMOVE_FIELD.equalsIgnoreCase(String.valueOf(keyValue.getValue())); } public void executeTestCases(FuzzingData data, String key, Object value, CustomFuzzerBase fuzzer) { @@ -253,8 +254,8 @@ public void executeTestCases(FuzzingData data, String key, Object value, CustomF if (this.entryIsValid((Map) value) && isValidOneOf) { this.pathsWithInputVariables.put(data.getPath(), (Map) value); - List> individualTestCases = this.createIndividualRequest((Map) value); - for (Map testCase : individualTestCases) { + List> individualTestCases = this.createIndividualRequest((Map) value); + for (Map testCase : individualTestCases) { testCaseListener.createAndExecuteTest(log, fuzzer, () -> this.process(data, key, testCase)); } } else if (!isValidOneOf) { @@ -296,31 +297,31 @@ private boolean entryIsValid(Map currentPathValues) { * @param testCase object from the custom fuzzer file * @return individual requests */ - public List> createIndividualRequest(Map testCase) { + public List> createIndividualRequest(Map testCase) { Optional> listOfValuesOptional = testCase.entrySet().stream().filter(entry -> entry.getValue() instanceof List).findFirst(); - List> allValues = new ArrayList<>(); + List> allValues = new ArrayList<>(); if (listOfValuesOptional.isPresent()) { Map.Entry listOfValues = listOfValuesOptional.get(); for (Object value : (List) listOfValues.getValue()) { testCase.put(listOfValues.getKey(), value); allValues.add(testCase.entrySet() - .stream().collect(Collectors.toMap(Map.Entry::getKey, en -> String.valueOf(en.getValue())))); + .stream().collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))); } return List.copyOf(allValues); } return Collections.singletonList(testCase.entrySet() - .stream().collect(Collectors.toMap(Map.Entry::getKey, en -> String.valueOf(en.getValue())))); + .stream().collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))); } - public String replacePathVariablesWithCustomValues(FuzzingData data, Map currentPathValues) { + public String replacePathVariablesWithCustomValues(FuzzingData data, Map currentPathValues) { String newPath = data.getPath(); if (HttpMethod.requiresBody(data.getMethod())) { - for (Map.Entry entry : currentPathValues.entrySet()) { - String valueToReplaceWith = entry.getValue(); - if (this.isVariable(entry.getValue())) { - valueToReplaceWith = variables.getOrDefault(this.getVariableName(entry.getValue()), NOT_SET); + for (Map.Entry entry : currentPathValues.entrySet()) { + String valueToReplaceWith = String.valueOf(entry.getValue()); + if (this.isVariable(valueToReplaceWith)) { + valueToReplaceWith = variables.getOrDefault(this.getVariableName(valueToReplaceWith), NOT_SET); } newPath = newPath.replace("{" + entry.getKey() + "}", valueToReplaceWith); } @@ -332,12 +333,15 @@ private boolean isNotAReservedWord(String key) { return !RESERVED_WORDS.contains(key); } - private String replaceElementWithCustomValue(Map.Entry keyValue, String payload) { + private String replaceElementWithCustomValue(Map.Entry keyValue, String payload) { Map contextForParser = new HashMap<>(); contextForParser.put(Parser.REQUEST, payload); contextForParser.putAll(variables); - String toReplace = CatsDSLParser.parseAndGetResult(this.getPropertyValueToReplaceInBody(keyValue), contextForParser); + Object toReplace = this.getPropertyValueToReplaceInBody(keyValue); + if (toReplace instanceof String str) { + toReplace = CatsDSLParser.parseAndGetResult(str, contextForParser); + } try { FuzzingStrategy fuzzingStrategy = FuzzingStrategy.replace().withData(toReplace); return catsUtil.replaceField(payload, keyValue.getKey(), fuzzingStrategy).json(); @@ -348,11 +352,11 @@ private String replaceElementWithCustomValue(Map.Entry keyValue, } } - public String getPropertyValueToReplaceInBody(Map.Entry keyValue) { - String propertyValue = keyValue.getValue(); + public Object getPropertyValueToReplaceInBody(Map.Entry keyValue) { + Object propertyValue = keyValue.getValue(); - if (this.isVariable(propertyValue)) { - String variableValue = variables.get(this.getVariableName(propertyValue)); + if (this.isVariable(String.valueOf(propertyValue))) { + String variableValue = variables.get(this.getVariableName(String.valueOf(propertyValue))); if (variableValue == null) { log.error("Supplied variable was not found [{}]", propertyValue); diff --git a/src/main/java/com/endava/cats/fuzzer/special/FunctionalFuzzer.java b/src/main/java/com/endava/cats/fuzzer/special/FunctionalFuzzer.java index 9b688261b..92618464c 100644 --- a/src/main/java/com/endava/cats/fuzzer/special/FunctionalFuzzer.java +++ b/src/main/java/com/endava/cats/fuzzer/special/FunctionalFuzzer.java @@ -2,17 +2,17 @@ import com.endava.cats.annotations.SpecialFuzzer; import com.endava.cats.args.FilesArguments; -import com.endava.cats.util.CatsDSLWords; import com.endava.cats.fuzzer.fields.base.CustomFuzzerBase; import com.endava.cats.model.CustomFuzzerExecution; import com.endava.cats.model.FuzzingData; +import com.endava.cats.util.CatsDSLWords; import com.endava.cats.util.CatsUtil; import com.endava.cats.util.ConsoleUtils; import io.github.ludovicianul.prettylogger.PrettyLogger; import io.github.ludovicianul.prettylogger.PrettyLoggerFactory; +import jakarta.inject.Singleton; import org.slf4j.MDC; -import jakarta.inject.Singleton; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; diff --git a/src/main/java/com/endava/cats/io/ServiceCaller.java b/src/main/java/com/endava/cats/io/ServiceCaller.java index be3b10a83..0dc14d6a0 100755 --- a/src/main/java/com/endava/cats/io/ServiceCaller.java +++ b/src/main/java/com/endava/cats/io/ServiceCaller.java @@ -232,8 +232,8 @@ public CatsResponse call(ServiceData data) { String addAdditionalQueryParams(String startingUrl, String currentPath) { HttpUrl.Builder httpUrl = HttpUrl.get(startingUrl).newBuilder(); - for (Map.Entry queryParamEntry : filesArguments.getAdditionalQueryParamsForPath(currentPath).entrySet()) { - httpUrl.addQueryParameter(queryParamEntry.getKey(), queryParamEntry.getValue()); + for (Map.Entry queryParamEntry : filesArguments.getAdditionalQueryParamsForPath(currentPath).entrySet()) { + httpUrl.addQueryParameter(queryParamEntry.getKey(), String.valueOf(queryParamEntry.getValue())); } return httpUrl.build().toString(); @@ -506,12 +506,12 @@ private void recordRequestAndResponse(CatsRequest catsRequest, CatsResponse cats } private void addSuppliedHeaders(ServiceData data, List> headers) { - Map userSuppliedHeaders = filesArguments.getHeaders(data.getRelativePath()); + Map userSuppliedHeaders = filesArguments.getHeaders(data.getRelativePath()); logger.debug("Path {} (including ALL headers) has the following headers: {}", data.getRelativePath(), userSuppliedHeaders); Map suppliedHeaders = userSuppliedHeaders.entrySet().stream() .collect(Collectors.toMap(Map.Entry::getKey, - entry -> CatsDSLParser.parseAndGetResult(entry.getValue(), authArguments.getAuthScriptAsMap()))); + entry -> CatsDSLParser.parseAndGetResult(String.valueOf(entry.getValue()), authArguments.getAuthScriptAsMap()))); for (Map.Entry suppliedHeader : suppliedHeaders.entrySet()) { if (data.isAddUserHeaders()) { @@ -557,11 +557,11 @@ private void replaceHeaderIfNotFuzzed(List> headers } private String replacePathWithRefData(ServiceData data, String currentUrl) { - Map currentPathRefData = filesArguments.getRefData(data.getRelativePath()); + Map currentPathRefData = filesArguments.getRefData(data.getRelativePath()); logger.debug("Path reference data replacement: path {} has the following reference data: {}", data.getRelativePath(), currentPathRefData); - for (Map.Entry entry : currentPathRefData.entrySet()) { - currentUrl = currentUrl.replace("{" + entry.getKey() + "}", entry.getValue()); + for (Map.Entry entry : currentPathRefData.entrySet()) { + currentUrl = currentUrl.replace("{" + entry.getKey() + "}", String.valueOf(entry.getValue())); data.getPathParams().add(entry.getKey()); } @@ -580,10 +580,10 @@ String replacePayloadWithRefData(ServiceData data) { logger.note("Bypassing reference data replacement for path {}!", data.getRelativePath()); return data.getPayload(); } else { - Map refDataForCurrentPath = filesArguments.getRefData(data.getRelativePath()); + Map refDataForCurrentPath = filesArguments.getRefData(data.getRelativePath()); logger.debug("Payload reference data replacement: path {} has the following reference data: {}", data.getRelativePath(), refDataForCurrentPath); - Map refDataWithoutAdditionalProperties = refDataForCurrentPath.entrySet().stream() + Map refDataWithoutAdditionalProperties = refDataForCurrentPath.entrySet().stream() .filter(stringStringEntry -> !stringStringEntry.getKey().equalsIgnoreCase(ADDITIONAL_PROPERTIES)) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); String payload = data.getPayload(); @@ -591,11 +591,13 @@ String replacePayloadWithRefData(ServiceData data) { /*this will override refData for DELETE requests in order to provide valid entities that will get deleted*/ refDataWithoutAdditionalProperties.putAll(this.getPathParamFromCorrespondingPostIfDelete(data)); - for (Map.Entry entry : refDataWithoutAdditionalProperties.entrySet()) { - String refDataValue = CatsDSLParser.parseAndGetResult(entry.getValue(), Map.of(Parser.REQUEST, data.getPayload())); - + for (Map.Entry entry : refDataWithoutAdditionalProperties.entrySet()) { + Object refDataValue = entry.getValue(); + if (refDataValue instanceof String str) { + refDataValue = CatsDSLParser.parseAndGetResult(str, Map.of(Parser.REQUEST, data.getPayload())); + } try { - if (CATS_REMOVE_FIELD.equalsIgnoreCase(refDataValue)) { + if (CATS_REMOVE_FIELD.equalsIgnoreCase(String.valueOf(refDataValue))) { payload = JsonUtils.deleteNode(payload, entry.getKey()); } else { diff --git a/src/main/java/com/endava/cats/util/CatsUtil.java b/src/main/java/com/endava/cats/util/CatsUtil.java index 32e48b96e..20c0a21a1 100644 --- a/src/main/java/com/endava/cats/util/CatsUtil.java +++ b/src/main/java/com/endava/cats/util/CatsUtil.java @@ -133,9 +133,9 @@ private String nullOrValueOf(Object object) { * @param payload the existing payload * @return a payload with additionalProperties added */ - public String setAdditionalPropertiesToPayload(Map currentPathValues, String payload) { - String additionalProperties = currentPathValues.get(ADDITIONAL_PROPERTIES); - if (!"null".equalsIgnoreCase(additionalProperties) && additionalProperties != null && StringUtils.isNotBlank(payload)) { + public String setAdditionalPropertiesToPayload(Map currentPathValues, String payload) { + String additionalProperties = WordUtils.nullOrValueOf(currentPathValues.get(ADDITIONAL_PROPERTIES)); + if (additionalProperties != null && StringUtils.isNotBlank(payload)) { DocumentContext jsonDoc = JsonPath.parse(payload); String mapValues = additionalProperties; String prefix = "$"; diff --git a/src/main/java/com/endava/cats/util/WordUtils.java b/src/main/java/com/endava/cats/util/WordUtils.java index 8b7034b74..56318cebd 100644 --- a/src/main/java/com/endava/cats/util/WordUtils.java +++ b/src/main/java/com/endava/cats/util/WordUtils.java @@ -15,6 +15,7 @@ public abstract class WordUtils { private WordUtils() { //ntd } + /** * Starts from a list of words and creates all possible combinations matching all cases and delimiters. * @@ -51,4 +52,8 @@ public static String[] capitalizeFirstLetter(String[] words) { return result; } + + public static String nullOrValueOf(Object obj) { + return obj == null ? null : String.valueOf(obj); + } } \ No newline at end of file diff --git a/src/test/java/com/endava/cats/args/FilesArgumentsTest.java b/src/test/java/com/endava/cats/args/FilesArgumentsTest.java index 03dee228f..9289762f2 100644 --- a/src/test/java/com/endava/cats/args/FilesArgumentsTest.java +++ b/src/test/java/com/endava/cats/args/FilesArgumentsTest.java @@ -69,7 +69,7 @@ void shouldMergeHeaders() throws Exception { ReflectionTestUtils.setField(filesArguments, "headersFile", new File("src/test/resources/headers.yml")); ReflectionTestUtils.setField(filesArguments, "headersMap", Map.of("auth", "secret")); filesArguments.loadHeaders(); - Map headers = filesArguments.getHeaders("all"); + Map headers = filesArguments.getHeaders("all"); org.assertj.core.api.Assertions.assertThat(headers).hasSize(3).containsOnlyKeys("auth", "catsFuzzedHeader", "header"); } diff --git a/src/test/java/com/endava/cats/command/ReplayCommandTest.java b/src/test/java/com/endava/cats/command/ReplayCommandTest.java index 90ca10e13..4de09d68e 100644 --- a/src/test/java/com/endava/cats/command/ReplayCommandTest.java +++ b/src/test/java/com/endava/cats/command/ReplayCommandTest.java @@ -5,8 +5,8 @@ import com.endava.cats.model.CatsResponse; import com.endava.cats.report.TestCaseExporter; import com.endava.cats.report.TestCaseListener; +import io.quarkus.test.InjectMock; import io.quarkus.test.junit.QuarkusTest; -import io.quarkus.test.junit.mockito.InjectMock; import io.quarkus.test.junit.mockito.InjectSpy; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/src/test/java/com/endava/cats/fuzzer/fields/AbugidasInStringFieldsSanitizeValidateFuzzerTest.java b/src/test/java/com/endava/cats/fuzzer/fields/AbugidasInStringFieldsSanitizeValidateFuzzerTest.java index f1c6c6cde..e5c074bc3 100644 --- a/src/test/java/com/endava/cats/fuzzer/fields/AbugidasInStringFieldsSanitizeValidateFuzzerTest.java +++ b/src/test/java/com/endava/cats/fuzzer/fields/AbugidasInStringFieldsSanitizeValidateFuzzerTest.java @@ -89,14 +89,14 @@ void shouldFuzzIfNotDiscriminatorField() { @Test void shouldNotFuzzIfRefDataField() { - Map refData = Map.of("field", "test"); + Map refData = Map.of("field", "test"); Mockito.when(filesArguments.getRefData("/test")).thenReturn(refData); Assertions.assertThat(abugidasCharsInStringFieldsSanitizeValidateFuzzer.isFuzzerWillingToFuzz(mockFuzzingData(), "field")).isFalse(); } @Test void shouldNotFuzzWhenEnum() { - Map refData = Map.of("field", "test"); + Map refData = Map.of("field", "test"); Mockito.when(filesArguments.getRefData("/test")).thenReturn(refData); Assertions.assertThat(abugidasCharsInStringFieldsSanitizeValidateFuzzer.isFuzzerWillingToFuzz(mockFuzzingData(), "pet#age")).isFalse(); } diff --git a/src/test/java/com/endava/cats/fuzzer/http/BypassAuthenticationFuzzerTest.java b/src/test/java/com/endava/cats/fuzzer/http/BypassAuthenticationFuzzerTest.java index 6f4b545b3..425cb9545 100644 --- a/src/test/java/com/endava/cats/fuzzer/http/BypassAuthenticationFuzzerTest.java +++ b/src/test/java/com/endava/cats/fuzzer/http/BypassAuthenticationFuzzerTest.java @@ -118,8 +118,8 @@ void shouldProperlyIdentifyAuthHeadersFromHeadersFile() throws Exception { Assertions.assertThat(authHeaders).containsExactlyInAnyOrder("api-key", "authorization", "jwt"); } - private Map createCustomFuzzerFile() { - Map tests = new HashMap<>(); + private Map createCustomFuzzerFile() { + Map tests = new HashMap<>(); tests.put("jwt", "v1"); tests.put("authorization", "200"); tests.put("cats", "mumu"); diff --git a/src/test/java/com/endava/cats/util/CatsUtilTest.java b/src/test/java/com/endava/cats/util/CatsUtilTest.java index 827fa2654..0dc999c60 100644 --- a/src/test/java/com/endava/cats/util/CatsUtilTest.java +++ b/src/test/java/com/endava/cats/util/CatsUtilTest.java @@ -49,7 +49,7 @@ void shouldAddTopElement() { CatsUtil catsUtil = new CatsUtil(); String payload = "{\"field\":\"value\", \"anotherField\":{\"subfield\": \"otherValue\"}}"; - Map currentPathValues = Collections.singletonMap("additionalProperties", "{topElement=metadata, mapValues={test1=value1,test2=value2}}"); + Map currentPathValues = Collections.singletonMap("additionalProperties", "{topElement=metadata, mapValues={test1=value1,test2=value2}}"); String updatedPayload = catsUtil.setAdditionalPropertiesToPayload(currentPathValues, payload); Assertions.assertThat(updatedPayload).contains("metadata").contains("test1"); } @@ -59,7 +59,7 @@ void shouldNotAddTopElement() { CatsUtil catsUtil = new CatsUtil(); String payload = "{\"field\":\"value\", \"anotherField\":{\"subfield\": \"otherValue\"}}"; - Map currentPathValues = Collections.singletonMap("additionalProperties", "{mapValues={test1=value1,test2=value2}}"); + Map currentPathValues = Collections.singletonMap("additionalProperties", "{mapValues={test1=value1,test2=value2}}"); String updatedPayload = catsUtil.setAdditionalPropertiesToPayload(currentPathValues, payload); Assertions.assertThat(updatedPayload).doesNotContain("metadata").contains("test1"); }