
core.apiCore.helpers.DataHelper Maven / Gradle / Ivy
package core.apiCore.helpers;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Value;
import org.json.JSONArray;
import com.opencsv.CSVReader;
import core.apiCore.TestDataProvider;
import core.apiCore.interfaces.ExternalInterface;
import core.helpers.Helper;
import core.support.configReader.Config;
import core.support.logger.TestLog;
import core.support.objects.KeyValue;
import core.support.objects.ServiceObject;
import core.support.objects.TestObject;
import io.netty.util.internal.StringUtil;
public class DataHelper {
public static final String VERIFY_JSON_PART_INDICATOR = "_VERIFY.JSON.PART_";
public static final String VERIFY_JSON_PART_INDICATOR_UNDERSCORE = "_VERIFY_JSON_PART_";
public static final String VERIFY_RESPONSE_BODY_INDICATOR = "_VERIFY_RESPONSE_BODY_";
public static final String VERIFY_RESPONSE_NO_EMPTY = "_NOT_EMPTY_";
public static final String VERIFY_HEADER_PART_INDICATOR = "_VERIFY_HEADER_PART_";
public static final String VERIFY_TOPIC_PART_INDICATOR = "_VERIFY_TOPIC_PART_";
public static final String EXPECTED_MESSAGE_COUNT = "EXPECTED_MESSAGE_COUNT";
public static final String IS_IGNORE_XML_NAMESPACE = "service.xml.ignore.namespace";
public static final String TEST_DATA_TEMPLATE_DATA_PATH = "api.templateDataFile";
public static final String VALIDATION_OR_CONDITION_ECODE = "\\|\\|";
public static final String VALIDATION_OR_CONDITION = "||";
public static final String VALIDATION_AND_CONDITION = "&&";
public static final String REQUEST_BODY_UPDATE_INDICATOR = "_UPDATE_REQUEST_";
public enum JSON_COMMAND {
hasItems, notHaveItems, notEqualTo, equalTo, notContain, contains, containsInAnyOrder, integerGreaterThan,
integerLessThan, integerEqual, integerNotEqual, nodeSizeGreaterThan, nodeSizeExact, sequence, jsonbody,
isNotEmpty, isEmpty, nodeSizeLessThan, isBetweenDate, allValuesEqualTo, countGreaterThan, countLessThan, countExact, command, notContains, contain, isDateAfter, isDateBefore, isDateEqual, isDateNotEqual
}
public static String replaceParameters(String source) {
return replaceParameters(source, "<@(.+?)>", "<@", ">");
}
/**
* replaces placeholder values with values from config properties replaces only
* string values
*
* @param source
* @return
*/
public static String replaceParameters(String source, String tagPattern, String openingTag, String closingTag) {
if (source.isEmpty())
return source;
List parameters = Helper.getValuesFromPattern(source,tagPattern);
Object value = null;
int length = 0;
String newTime = StringUtils.EMPTY;
for (String parameter : parameters) {
if (parameter.contains("_TIME_MS_")) {
newTime = Helper.date.getTime(parameter, Config.getValue(TestObject.START_TIME_STRING));
Instant time = getTimeInstance(newTime);
value = getTimeSubstring(parameter, String.valueOf(time.toEpochMilli()));
}else if (parameter.contains("_TIME_S_")) {
newTime = Helper.date.getTime(parameter, Config.getValue(TestObject.START_TIME_STRING));
Instant time = getTimeInstance(newTime);
value = getTimeSubstring(parameter, String.valueOf(time.getEpochSecond()));
} else if (parameter.contains("_TIME_STRING_")) {
newTime = Helper.date.getTime(parameter, Config.getValue(TestObject.START_TIME_STRING));
value = getTimeSubstring(parameter, Helper.date.getTime(newTime, "yyyyMMddHHmmssSSS", null));
} else if (parameter.contains("_TIME_ISO_")) {
newTime = Helper.date.getTime(parameter, Config.getValue(TestObject.START_TIME_STRING));
value = getTimeSubstring(parameter, newTime);
} else if (parameter.contains("_TIME")) {
newTime = Helper.date.getTime(parameter, Config.getValue(TestObject.START_TIME_STRING));
value = getTimeSubstring(parameter, newTime);
} else if (parameter.contains("_RANDUUID")) {
value = Helper.generateUUID();
} else if (parameter.contains("_UUID_STATIC")) {
value = Config.getValue(TestObject.UUID_STATIC_STRING);
} else if (parameter.contains("_RAND")) {
length = Helper.getIntFromString(parameter);
value = Config.getValue(TestObject.RANDOM_STRING).substring(0, length);
} else if (parameter.contains("_INCREMENT_FROM_")) {
value = getIncrementalValue(parameter);
} else if (parameter.contains("_XML")) {
// syntax:e.g. <@_XML:ID:1> will be replaced by 2
String[] valueArray = parameter.split(":");
int index = 0;
String tag = valueArray[1];
if (valueArray.length == 3) // if has index value
index = Integer.valueOf(parameter.split(":")[2]);
value = XmlHelper.getXmlTagValue(source, tag, index + 1);
} else {
value = Config.getObjectValue(parameter.replace("@", ""));
}
if (isObjectEmpty(value))
TestLog.logWarning("parameter value not found: " + parameter);
else {
source = source.replace(openingTag + parameter + closingTag, Matcher.quoteReplacement(value.toString()));
}
}
return source;
}
public static boolean isObjectEmpty(Object value) {
if (value == null || StringUtils.isBlank(value.toString()) || value.equals("null"))
return true;
return false;
}
/**
* incremental keyword value setter starting value + current run count by
* default: starting value = 1 eg. <@_INCREMENT_FROM_3> current test count is
* appended to test case id. eg. validateId_run_1
*
* @param parameter
*/
public static int getIncrementalValue(String parameter) {
int startingValue = Helper.getIntFromString(parameter);
int testCurrentRunCount = 1;
String testId = TestObject.getTestInfo().serviceObject.getTestCaseID();
if (testId.matches(".*" + CsvReader.SERVICE_RUN_PREFIX + "(\\d)?$")) {
testId = testId.substring(testId.lastIndexOf(CsvReader.SERVICE_RUN_PREFIX) + 1);
testCurrentRunCount = Helper.getIntFromString(testId);
}
int incrementalValue = startingValue + testCurrentRunCount - 1;
return incrementalValue;
}
/**
* get substring of time based on time string length format _TIME_STRING_17-72h.
* 17 is the length
*
* @param parameter
* @param maxLength
* @param finalTime
* @return
*/
public static String getTimeSubstring(String parameter, String finalTime) {
// values after the last "_", then after the last :
String[] values = parameter.split(";");
String modifier = values[0].split("[+-]")[0];
int length = Helper.getFirstNumber(modifier);
int maxLength = finalTime.length();
if (length > maxLength || length == -1 || length == 0)
length = maxLength;
return finalTime.substring(0, length);
}
public static Instant getTimeInstance(String timeString) {
LocalDateTime localDateTime = Helper.date.getLocalDateTime(timeString);
Instant timeInstant = localDateTime.toInstant(ZoneOffset.UTC);
return timeInstant;
}
/**
* gets the map of the validation requirements split by ";"
*
* @param expected
* @return
*/
public static List getValidationMap(String expected) {
return getValidationMap(expected, ";");
}
/**
* gets the map of the validation requirements split by ";"
*
* @param expected
* @return
*/
public static List getValidationMap(String expected, String separator) {
// get hashmap of json path And verification
List keywords = new ArrayList();
// remove json indicator _VERIFY.JSON.PART_
expected = JsonHelper.removeResponseIndicator(expected);
String[] keyVals = expected.split(separator);
for (String keyVal : keyVals) {
String key = "";
String position = "";
String value = "";
// if empty, skip
if (keyVal.isEmpty())
continue;
List parts = splitToKeyPositionValue(keyVal, ":", 3);
if (parts.size() == 1) {
key = Helper.stringRemoveLines(parts.get(0));
}
if (parts.size() == 2) { // without position
key = Helper.stringRemoveLines(parts.get(0));
position = StringUtil.EMPTY_STRING;
value = Helper.stringRemoveLines(parts.get(1));
} else if (parts.size() == 3) { // with position
key = Helper.stringRemoveLines(parts.get(0));
position = Helper.stringRemoveLines(parts.get(1));
value = Helper.stringRemoveLines(parts.get(2));
}
// if there is a value
if (!key.isEmpty()) {
KeyValue keyword = new KeyValue(key, position, value);
keywords.add(keyword);
}
}
return keywords;
}
public static String getTemplateFileLocation(String file) {
String templatePath = Config.getValue(TestDataProvider.TEST_DATA_TEMPLATE_PATH).trim();
String templateTestPath = Helper.getFullPath(templatePath);
return templateTestPath + file;
}
public static Path getTemplateFilePath(String file) {
String templatePath = Config.getValue(TestDataProvider.TEST_DATA_TEMPLATE_PATH).trim();
String templateTestPath = Helper.getFullPath(templatePath);
String fullLocation = templateTestPath + file;
return new File(fullLocation).toPath();
}
public static File getFile(String filename) {
String templatePath = Config.getValue(TestDataProvider.TEST_DATA_TEMPLATE_PATH).trim();
String templateTestPath = Helper.getFullPath(templatePath);
File file = new File(templateTestPath + filename);
return file;
}
/**
* returns service object template file as string Template file name is from
* Template column in csv
*
* @param apiObject
* @return
* @throws IOException
*/
public static String getServiceObjectTemplateString(ServiceObject serviceObject) {
Path templatePath = DataHelper.getTemplateFilePath(serviceObject.getTemplateFile());
return DataHelper.convertFileToString(templatePath);
}
/**
* validates response against expected values
*
* @param command
* @param responseString
* @param expectedString
* @return
*/
public static String validateCommand(String command, String responseString, String expectedString) {
String error = validateExpectedCommand(command, responseString, expectedString, StringUtils.EMPTY);
if (error.isEmpty())
TestLog.ConsoleLog(
"validation passed for command: " + responseString + " " + command + " " + expectedString);
else
TestLog.ConsoleLog("validation failed for command: " + command + " with error: " + error);
return error;
}
/**
* validates response against expected values
* if skipValidation = false -> response variable contains error
* @param command
* @param responseString
* @param expectedString
* @param position
* @return
*/
public static String validateCommand(String command, String responseString, String expectedString,
String position, boolean skipValidation) {
String response = validateExpectedCommand(command, responseString, expectedString, position);
if(skipValidation)
return response;
if (response.isEmpty())
TestLog.ConsoleLog("validation passed for command: response " + command + " " + expectedString);
else
TestLog.ConsoleLog("validation failed for command: " + command + " with error: " + response);
return response;
}
/**
* validates response against expected values
*
* @param command
* @param responseString
* @param expectedString
* @param position
*/
public static String validateExpectedCommand(String command, String responseString, String expectedString,
String position) {
// remove surrounding quotes
expectedString = Helper.removeSurroundingQuotes(expectedString);
command = Helper.removeSurroundingQuotes(command);
responseString = Helper.removeSurroundingQuotes(responseString);
List expectedArray = getResponseArray(expectedString);
List actualArray = getResponseArray(responseString);
String actualString = "";
int positionInt = 0;
// if position has value, Then get response at position
if (!position.isEmpty() && Helper.getIntFromString(position) > 0) {
positionInt = Helper.getIntFromString(position);
boolean inBounds = (positionInt > 0) && (positionInt <= actualArray.size());
if (!inBounds) {
Helper.assertFalse("items returned are less than specified. returned: " + actualArray.size()
+ " specified: " + positionInt);
}
actualString = actualArray.get(positionInt - 1);
}
if (getCommandFromExpectedString(command).isEmpty()) {
Helper.assertFalse(
"Command not set. Options: " + Arrays.asList(JSON_COMMAND.values()) + ". See examples for usage.");
}
JSON_COMMAND jsonCommand = JSON_COMMAND.valueOf(command);
switch (jsonCommand) {
//Jsonpath:command(External.testMethod, value)
// Jsonpath:command(Command.hasMethod, value1, value2)
case command:
if(expectedArray.size() < 1)
Helper.assertFalse("invalid command format. must be: Jsonpath:command(class.methodname, value) eg. Jsonpath:command(Command.hasMethod, value");
String method = expectedArray.get(0);
expectedArray.remove(0);
expectedArray = removeEmptyElements(expectedArray);
String values = StringUtils.EMPTY;
values = "values:" + Arrays.toString(expectedArray.toArray());
ServiceObject serviceObject = new ServiceObject()
.withMethod("METHOD:" + method)
.withRequestBody("response:"+ responseString +";" + values);
return ExternalInterface.ExternalInterfaceRunner(serviceObject).toString();
case notEqualTo:
boolean val = false;
if (!position.isEmpty() && positionInt > 0) { // if position is provided
TestLog.logPass("verifying: " + actualString + " not equals " + expectedString);
val = !actualString.equals(expectedString);
if (!val)
return actualString + " does equal " + expectedString;
} else if (!position.isEmpty() && positionInt == 0) {
TestLog.logPass("verifying: " + responseString + " not equals " + expectedString);
val = !responseString.equals(expectedString);
if (!val)
return responseString + " does equal " + expectedString;
} else {
TestLog.logPass("verifying: " + Arrays.toString(actualArray.toArray()) + " not equals "
+ Arrays.toString(expectedArray.toArray()));
val = !actualArray.equals(expectedArray);
if (!val)
return Arrays.toString(actualArray.toArray()) + " does equal "
+ Arrays.toString(expectedArray.toArray());
}
break;
case equalTo:
if (!position.isEmpty() && positionInt > 0) { // if position is provided
TestLog.logPass("verifying: " + actualString + " equals " + expectedString);
val = actualString.equals(expectedString);
if (!val)
return actualString + " does not equal " + expectedString;
} else if (!position.isEmpty() && positionInt == 0) {
TestLog.logPass("verifying: " + responseString + " equals " + expectedString);
val = responseString.equals(expectedString);
if (!val)
return responseString + " does not equal " + expectedString;
} else {
TestLog.logPass("verifying: " + Arrays.toString(actualArray.toArray()) + " equals "
+ Arrays.toString(expectedArray.toArray()));
val = actualArray.equals(expectedArray);
if (!val)
return Arrays.toString(actualArray.toArray()) + " does not equal "
+ Arrays.toString(expectedArray.toArray());
}
break;
case allValuesEqualTo:
val = actualArray.get(0).equals(expectedString) && actualArray.stream().distinct().limit(2).count() == 1;
if (!val)
return Arrays.toString(actualArray.toArray()) + " are not all equal to: "+ expectedString;
break;
case notHaveItems:
case notContains:
case notContain:
// if response is single item, it is same as command with position 1 and treated as string
actualArray = DataHelper.removeEmptyElements(actualArray);
if (actualArray.size() == 1) {
position = "1";
}
if (!position.isEmpty() && positionInt > 0) { // if position is provided
TestLog.logPass("verifying: " + actualString + " does not contain " + expectedString);
Set missing = isListContain(actualString, expectedArray);
if (missing.isEmpty())
return actualString + " does contain " + missing.toString();
} else {
TestLog.logPass("verifying: " + Arrays.toString(actualArray.toArray()) + " does not contain "
+ Arrays.toString(expectedArray.toArray()));
Set missing = isListContain(responseString, expectedArray);
if (missing.isEmpty())
return Arrays.toString(actualArray.toArray()) + " does contain "
+ expectedArray.removeAll(new ArrayList(missing));
}
break;
case hasItems:
case contains:
case contain:
// if response is single item, it is same as command with position 1 and treated as string
actualArray = DataHelper.removeEmptyElements(actualArray);
if (actualArray.size() == 1) {
position = "1";
}
if (!position.isEmpty() && positionInt > 0) { // if position is provided
TestLog.logPass("verifying: " + actualString + " contains " + expectedString);
Set missing = isListContain(actualString, expectedArray);
if (!missing.isEmpty())
return actualString + " does not contain " + missing.toString();
} else {
TestLog.logPass("verifying: " + Arrays.toString(actualArray.toArray()) + " contains "
+ Arrays.toString(expectedArray.toArray()));
Set missing = isListContain(responseString, expectedArray);
if (!missing.isEmpty())
return Arrays.toString(actualArray.toArray()) + " does not contain "
+ missing.toString();
}
break;
case containsInAnyOrder:
TestLog.logPass("verifying: " + Arrays.toString(actualArray.toArray()) + " contains any order "
+ Arrays.toString(expectedArray.toArray()));
Set missing = isListContain(responseString, expectedArray);
if (!missing.isEmpty())
return Arrays.toString(actualArray.toArray()) + " does not contain "
+ missing.toString();
break;
case integerGreaterThan:
TestLog.logPass("verifying: " + responseString + " is greater than " + expectedString);
val = compareNumbers(responseString, expectedString, "greaterThan");
if (!val)
return "actual: " + responseString + " is not greater than expected: " + expectedString;
break;
case integerLessThan:
TestLog.logPass("verifying: " + responseString + " is less than " + expectedString);
val = compareNumbers(responseString, expectedString, "lessThan");
if (!val)
return "actual: " + responseString + " is not less than expected: " + expectedString;
break;
case integerEqual:
TestLog.logPass("verifying: " + responseString + " is equal to " + expectedString);
val = compareNumbers(responseString, expectedString, "equalTo");
if (!val)
return "actual: " + responseString + " is not equal to expected: " + expectedString;
break;
case integerNotEqual:
val = !compareNumbers(responseString, expectedString, "equalTo");
if (!val)
return "actual: " + responseString + " is not equal to expected: " + expectedString;
break;
case countGreaterThan:
case nodeSizeGreaterThan:
int intValue = Integer.valueOf(expectedString);
int actualLength = getResponseArrayLength(actualArray, responseString);
TestLog.logPass("verifying node with size " + actualLength + " greater than " + intValue);
if (!(actualLength > intValue))
return "response node size is: " + actualLength + " expected it to be greater than: " + intValue;
break;
case countLessThan:
case nodeSizeLessThan:
intValue = Integer.valueOf(expectedString);
actualLength = getResponseArrayLength(actualArray, responseString);
TestLog.logPass("verifying node with size " + actualLength + " less than " + intValue);
if (!(actualLength < intValue))
return "response node size is: " + actualLength + " expected it to be less than: " + intValue;
break;
case countExact:
case nodeSizeExact:
intValue = Integer.valueOf(expectedString);
actualLength = getResponseArrayLength(actualArray, responseString);
TestLog.logPass("verifying node with size " + actualLength + " equals " + intValue);
if (actualLength != intValue)
return "response node size is: " + actualLength + " expected: " + intValue;
break;
case sequence:
TestLog.logPass("verifying: " + Arrays.toString(actualArray.toArray()) + " with sequence "
+ Arrays.toString(expectedArray.toArray()));
val = actualArray.equals(expectedArray);
if (!val)
return Arrays.toString(actualArray.toArray()) + " does not equal "
+ Arrays.toString(expectedArray.toArray());
break;
case jsonbody:
TestLog.logPass("verifying response: \n" + ServiceObject.normalizeLog(responseString)
+ "\n against expected: \n" + ServiceObject.normalizeLog(expectedString));
String error = JsonHelper.validateByJsonBody(expectedString, responseString, true);
if (!error.isEmpty())
return error;
break;
case isNotEmpty:
TestLog.logPass("verifying response for path is not empty");
if (isEmpty(responseString))
return "value is empty";
break;
case isEmpty:
TestLog.logPass("verifying response for path is empty ");
if (!isEmpty(responseString))
return "value is not empty";
break;
case isBetweenDate:
if (!position.isEmpty() && positionInt > 0) { // if position is provided
TestLog.logPass("verifying date: " + actualString + " is in between dates: " + expectedString);
String[] expectedDates = expectedString.split(",");
if(expectedDates.length != 2) Helper.assertFalse("require 2 dates to validate inbewteen date");
val = Helper.date.isBetweenDates(actualString, expectedDates[0], expectedDates[1]);
if (!val)
return actualString + " is not in between dates: " + expectedString;
} else if (!position.isEmpty() && positionInt == 0) {
TestLog.logPass("verifying date: " + responseString + " is in between dates: " + expectedString);
String[] expectedDates = expectedString.split(",");
if(expectedDates.length != 2) Helper.assertFalse("require 2 dates to validate inbewteen date");
val = Helper.date.isBetweenDates(responseString, expectedDates[0], expectedDates[1]);
if (!val)
return responseString + " is not in between dates: " + expectedString;
} else {
TestLog.logPass("verifying dates: " + Arrays.toString(actualArray.toArray()) + " is in between dates: "
+ Arrays.toString(expectedArray.toArray()));
String[] expectedDates = expectedString.split(",");
if(expectedDates.length != 2) Helper.assertFalse("require 2 dates to validate inbewteen date");
val = Helper.date.isBetweenDates(actualArray, expectedDates[0], expectedDates[1]);
if (!val)
return Arrays.toString(actualArray.toArray()) + " is not in between dates: "
+ Arrays.toString(expectedArray.toArray());
}
break;
case isDateEqual:
if (!position.isEmpty() && positionInt > 0) { // if position is provided
TestLog.logPass("verifying date: " + actualString + " is equal date: " + expectedString);
val = Helper.date.isDateEqual(actualString, expectedString);
if (!val)
return actualString + " is equal date: " + expectedString;
} else if (!position.isEmpty() && positionInt == 0) {
TestLog.logPass("verifying date: " + responseString + " is equal date: " + expectedString);
val = Helper.date.isDateEqual(responseString, expectedString);
if (!val)
return responseString + " is not equal date: " + expectedString;
} else {
TestLog.logPass("verifying date: " + Arrays.toString(actualArray.toArray()) + " is equal date: "
+ Arrays.toString(expectedArray.toArray()));
val = Helper.date.isDateEqual(actualArray, expectedString);
if (!val)
return Arrays.toString(actualArray.toArray()) + " is equal date: "
+ Arrays.toString(expectedArray.toArray());
}
break;
case isDateNotEqual:
if (!position.isEmpty() && positionInt > 0) { // if position is provided
TestLog.logPass("verifying date: " + actualString + " is not equal date: " + expectedString);
val = Helper.date.isDateNotEqual(actualString, expectedString);
if (!val)
return actualString + " is not equal date: " + expectedString;
} else if (!position.isEmpty() && positionInt == 0) {
TestLog.logPass("verifying date: " + responseString + " is not equal date: " + expectedString);
val = Helper.date.isDateNotEqual(responseString, expectedString);
if (!val)
return responseString + " is not equal date: " + expectedString;
} else {
TestLog.logPass("verifying date: " + Arrays.toString(actualArray.toArray()) + " is not equal date: "
+ Arrays.toString(expectedArray.toArray()));
val = Helper.date.isDateNotEqual(actualArray, expectedString);
if (!val)
return Arrays.toString(actualArray.toArray()) + " is not equal date: "
+ Arrays.toString(expectedArray.toArray());
}
break;
case isDateAfter:
if (!position.isEmpty() && positionInt > 0) { // if position is provided
TestLog.logPass("verifying date: " + actualString + " is after date: " + expectedString);
val = Helper.date.isDateAfter(actualString, expectedString);
if (!val)
return actualString + " is after date: " + expectedString;
} else if (!position.isEmpty() && positionInt == 0) {
TestLog.logPass("verifying date: " + responseString + " is after date: " + expectedString);
val = Helper.date.isDateAfter(responseString, expectedString);
if (!val)
return responseString + " is not after date: " + expectedString;
} else {
TestLog.logPass("verifying date: " + Arrays.toString(actualArray.toArray()) + " is after date: "
+ Arrays.toString(expectedArray.toArray()));
val = Helper.date.isDateAfter(actualArray, expectedString);
if (!val)
return Arrays.toString(actualArray.toArray()) + " is after date: "
+ Arrays.toString(expectedArray.toArray());
}
break;
case isDateBefore:
if (!position.isEmpty() && positionInt > 0) { // if position is provided
TestLog.logPass("verifying date: " + actualString + " is before date: " + expectedString);
val = Helper.date.isDateBefore(actualString, expectedString);
if (!val)
return actualString + " is before date: " + expectedString;
} else if (!position.isEmpty() && positionInt == 0) {
TestLog.logPass("verifying date: " + responseString + " is before date: " + expectedString);
val = Helper.date.isDateBefore(responseString, expectedString);
if (!val)
return responseString + " is not before date: " + expectedString;
} else {
TestLog.logPass("verifying date: " + Arrays.toString(actualArray.toArray()) + " is before date: "
+ Arrays.toString(expectedArray.toArray()));
val = Helper.date.isDateBefore(actualArray, expectedString);
if (!val)
return Arrays.toString(actualArray.toArray()) + " is before date: "
+ Arrays.toString(expectedArray.toArray());
}
break;
default:
Helper.assertFalse(
"Command not set. Options: " + Arrays.asList(JSON_COMMAND.values()) + ". See examples for usage.");
break;
}
return StringUtil.EMPTY_STRING;
}
/**
* converts string separated by "," to array[] trims each value and removes
* quotes or array brackets
*
* @param array
* @return
*/
public static List getResponseArray(String array) {
List list = new ArrayList();
if(array == null)
return list;
String[] responses = array.split(",");
for (String response : responses) {
response = response.trim().replace("\"", "");
response = response.replace("[", "").replace("]", "");
list.add(response);
}
return list;
}
public static int getResponseArrayLength(List actualArray, String responseString) {
int responseLength = -1;
actualArray = removeEmptyElements(actualArray);
JSONArray jsonArray = JsonHelper.getJsonArray(responseString);
if (jsonArray != null)
responseLength = jsonArray.length();
else
responseLength = actualArray.size();
return responseLength;
}
public static boolean isGreaterThan(String value1, String value2) {
if (Helper.isNumeric(value1) && Helper.isNumeric(value2)) {
if (Integer.valueOf(value1) > Integer.valueOf(value2))
return true;
}
return false;
}
public static boolean isLessThan(String value1, String value2) {
if (Helper.isNumeric(value1) && Helper.isNumeric(value2)) {
if (Integer.valueOf(value1) < Integer.valueOf(value2))
return true;
}
return false;
}
/**
* compare string integer values based on comparator value
*
* @param value1
* @param value2
* @param comparator
* @return
*/
public static boolean compareNumbers(String value1, String value2, String comparator) {
if (!Helper.isStringContainNumber(value1) || !Helper.isStringContainNumber(value2))
return false;
double val1Double = Helper.getDoubleFromString(value1);
double val2Double = Helper.getDoubleFromString(value2);
return compareNumbers(val1Double, val2Double, comparator);
}
/**
* compare integer values
*
* @param value1
* @param value2
* @param comparator
* @return
*/
public static boolean compareNumbers(double value1, double value2, String comparator) {
switch (comparator) {
case "greaterThan":
if (value1 > value2)
return true;
break;
case "lessThan":
if (value1 < value2)
return true;
break;
case "equalTo":
if (value1 == value2)
return true;
break;
}
return false;
}
/**
* converts list to string separated by ","
*
* @param values
* @return
*/
public static String listToString(List values) {
return StringUtils.join(values, ",");
}
/**
* convert object to string object can be array
*
* @param values
* @return
*/
public static String objectToString(Object values) {
String stringVal = values.toString();
stringVal = stringVal.replaceAll("[\\[\\](){}]", "");
stringVal = stringVal.replace("\"", "");
// replace \/ with /. limitation in json parsing
stringVal = stringVal.replace("\\/", "/");
return stringVal;
}
/**
* split based on key position value
*
* @param keyvalue
* @param regex
* @param limit
* @return
*/
public static List splitToKeyPositionValue(String keyvalue, String regex, int limit) {
List result = new ArrayList();
// if no key value pair
if (!keyvalue.contains(":")) {
result.add(keyvalue);
return result;
}
// if json validation command, return format path:position:command or
// path:command
String commandValue = getCommandFromExpectedString(keyvalue);
if (!commandValue.isEmpty()) {
return getJsonKeyValue(keyvalue, commandValue);
}
String position = StringUtils.EMPTY;
// position has format :position:
boolean hasPosition = Pattern.compile(":\\d{1}:").matcher(keyvalue).find();
// split based on position, and add to result list
if (hasPosition) {
String[] resultArray = keyvalue.split(":\\d{1}:");
Pattern pattern = Pattern.compile(":\\d{1}:");
Matcher matcher = pattern.matcher(keyvalue);
if (matcher.find())
position = matcher.group(0);
result.add(resultArray[0]);
result.add(Helper.date.removeFirstAndLastChars(position, ":"));
if(resultArray.length == 2)
result.add(resultArray[1]);
else
result.add(StringUtils.EMPTY);
} else { // split left to right
String[] resultArray = keyvalue.split(":", 2);
result.add(resultArray[0]);
if(resultArray.length == 2)
result.add(resultArray[1]);
else
result.add(StringUtils.EMPTY);
}
return result;
}
public static List splitRight(String value, String regex, int limit) {
String string = value;
List result = new ArrayList();
String[] temp = new String[0];
for (int i = 1; i < limit; i++) {
if (string.matches(".*" + regex + ".*")) {
temp = string.split(modifyRegex(regex));
Helper.assertTrue("value not set for: " + string, temp.length > 1);
result.add(temp[1]);
string = temp[0];
}
}
if (temp.length > 0) {
result.add(temp[0]);
}
// handle single value
if (value.split(":").length == 1)
result.add(string);
Collections.reverse(result);
return result;
}
/**
* get the json response validation command from string eg.
* soi:EquipmentID:1:notEqualTo(2019110423T11:00:00.000Z) -> command: notEqual
* eg. value:isEmpty -> command: isEmpty
*
* @param value
* @return
*/
private static String getCommandFromExpectedString(String value) {
String commandValue = StringUtils.EMPTY;
for (JSON_COMMAND command : JSON_COMMAND.values()) {
List parameters = Helper.getValuesFromPattern(value, command + "\\(([^)]+)\\)");
if (!parameters.isEmpty()) { // command(value)
commandValue = command + "(" + parameters.get(0) + ")";
if (value.endsWith(commandValue))
return commandValue;
} else if (value.endsWith(command.name())) // isEmpty, isNotEmpty
return command.name();
}
return StringUtils.EMPTY;
}
/**
* get json key value eg. store.book[?(@.price < 10)]:jsonbody(["key":"value"])
* becomes arraylist of size 2. eg. store.book[?(@.price <
* 10)]:1:jsonbody(["key":"value"]) becomes arraylist of size 3.
*
* @param value
* @return
*/
private static List getJsonKeyValue(String value, String commandValue) {
List result = new ArrayList();
// remove commandValue
value = value.replace(commandValue, "");
// remove last colon. eg. soi:EquipmentID:1: becomes: soi:EquipmentID:1
String keyPosition = value.trim().replaceAll(":$", "");
List keyPositionList = splitRight(keyPosition, ":", 2);
// if key value has position. eg: store.book[?(@.price < 10)]:1
if (keyPositionList.size() == 2 && Helper.isStringContainOnlyNumber(keyPositionList.get(1))) {
result.add(keyPositionList.get(0));
result.add(keyPositionList.get(1));
} else {
result.add(keyPosition);
}
// add command + value. eg. equal(value) or isEmpty
result.add(commandValue);
return result;
}
private static String modifyRegex(String regex) {
return regex + "(?!.*" + regex + ".*$)";
}
public static boolean isEmpty(String value) {
if (StringUtils.isBlank(value))
return true;
if (value.equals("null"))
return true;
return false;
}
/**
* get request body from template file: json, xml, other json template: - if
* request body is set, replace value in template with format: - request body:
* json path:position:value or json path:vlaue - eg.
* "features.feature.name:1:value_<@_TIME_19>" xml template: - if request body
* is set, replace value in template with format: - request body:
* tag:position:value or tag:value - eg. "soi:EquipmentID:1:equip_<@_TIME_17>"
* other file type: - return as string if no template set: - return request body
*
* @param serviceObject
* @return
*/
@SuppressWarnings("deprecation")
public static String getRequestBodyIncludingTemplate(ServiceObject serviceObject) {
String requestbody = StringUtils.EMPTY;
// load data file to config
loadDataFile(serviceObject);
String[] criterion = serviceObject.getRequestBody().split(VALIDATION_AND_CONDITION);
// if request only contains request update keyword, set request first index to empty
if(criterion.length == 1 && criterion[0].startsWith(REQUEST_BODY_UPDATE_INDICATOR)) {
criterion = ArrayUtils.add(criterion, 0, "");
}
for(String criteria : criterion) {
criteria = Helper.stringRemoveLines(criteria);
if(!criteria.startsWith(REQUEST_BODY_UPDATE_INDICATOR)) {
serviceObject.withRequestBody(criteria);
// if json template file
if (JsonHelper.isJsonFile(serviceObject.getTemplateFile())) {
requestbody = JsonHelper.getRequestBodyFromJsonTemplate(serviceObject);
// if xml template file
} else if (XmlHelper.isXmlFile(serviceObject.getTemplateFile())) {
requestbody = XmlHelper.getRequestBodyFromXmlTemplate(serviceObject);
// if other type of file
} else if (!serviceObject.getTemplateFile().isEmpty()) {
Path templatePath = DataHelper.getTemplateFilePath(serviceObject.getTemplateFile());
requestbody = convertFileToString(templatePath);
// if no template, return request body
} else if (requestbody.isEmpty())
requestbody = serviceObject.getRequestBody();
// replace request body parameters
requestbody = replaceParameters(requestbody);
}else {
// remove update indicator _UPDATE_REQUEST_
criteria = JsonHelper.removeResponseIndicator(criteria);
if(JsonHelper.isJSONValid(requestbody, false))
requestbody = JsonHelper.updateJsonFromRequestBody(criteria, requestbody);
else if(XmlHelper.isValidXmlString(requestbody))
requestbody = XmlHelper.replaceRequestTagValues(criteria, requestbody);
// replace request body parameters
requestbody = replaceParameters(requestbody);
}
}
return requestbody;
}
/**
* loads template data info based on value set on request body format:
* DataFile:file:dataId
*
* @param serviceObject
*/
public static void loadDataFile(ServiceObject serviceObject) {
if (serviceObject.getRequestBody().isEmpty())
return;
final String DataFile = "DataFile";
// get key value mapping of header parameters
List keywords = DataHelper.getValidationMap(serviceObject.getRequestBody());
// iterate through key value pairs for headers, separated by ";"
for (KeyValue keyword : keywords) {
// if additional options
switch (keyword.key) {
case DataFile:
// remove DataFile value from request body
String updateRequest = serviceObject.getRequestBody().replace(keyword.value.toString(), "")
.replace(keyword.value.toString() + ";", "").replace(DataFile + ":", "");
String[] dataInfo = keyword.value.toString().split(":");
if (dataInfo.length != 2)
Helper.assertFalse("format must be file:dataId. actual value: " + keyword.value.toString());
String dataFilename = dataInfo[0];
String expectedDataId = dataInfo[1];
// get data file in csv format
String templateDataFilePath = Helper.getFullPath(Config.getValue(TEST_DATA_TEMPLATE_DATA_PATH));
File dataFile = new File(templateDataFilePath + dataFilename + ".csv");
try {
CSVReader reader = CsvReader.readCsvFile(dataFile);
// read header separately
String[] header = reader.readNext();
int dataId = CsvReader.getColumnIndexByName("dataId", header);
// add semicolon to separate from the rest of the data
if (header.length > 1 && !updateRequest.isEmpty())
updateRequest = updateRequest + ";";
// if dataId matches expected dataId, add all row data
String[] line;
while ((line = reader.readNext()) != null) {
if (!expectedDataId.equals(line[dataId]))
continue;
for (int i = 1; i < header.length; i++) {
updateRequest = updateRequest + header[i] + ":" + line[i] + ";";
}
}
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
serviceObject.withRequestBody(updateRequest);
break;
default:
break;
}
}
}
/**
* stores value in config format: value:<$key> separated by colon ';'
*
* @param source
*/
public static void saveDataToConfig(String source) {
if (source.isEmpty())
return;
// replace parameters for the source
source = DataHelper.replaceParameters(source);
List keywords = DataHelper.getValidationMap(source);
for (KeyValue keyword : keywords) {
// return if value is wrong format
if (!keyword.value.toString().startsWith("<") || !keyword.value.toString().contains("$")
|| !keyword.value.toString().endsWith(">"))
return;
String value = (String) keyword.value;
value = value.replace("$", "").replace("<", "").replace(">", "").trim();
// gets json value. if list, returns string separated by comma
String key = keyword.key;
Config.putValue(value, key);
}
}
/**
* get file content as text replaces parameters using syntax <@variable> from
* value in config
*
* @param templatePath
* @return
*/
public static String convertFileToString(Path templatePath) {
String content = Helper.readFileContent(templatePath.toString());
// replace content parameters
return replaceParameters(content);
}
/**
* remove section from expected response separated by && the section will start
* with the identifier. eg. _VERIFY_RESPONSE_BODY_
*
* @param section
* @param expectedResponse
* @return
*/
public static String removeSectionFromExpectedResponse(String section, String expectedResponse) {
String[] criteria = expectedResponse.split("&&");
List newResponse = new ArrayList();
for (String criterion : criteria) {
criterion = Helper.removeSurroundingQuotes(criterion);
if (!criterion.trim().startsWith(section)) {
newResponse.add(criterion);
}
}
return String.join("&&", newResponse);
}
/**
* get section from expected response separated by && the section will start
* with the identifier. eg. _VERIFY_RESPONSE_BODY_
*
* @param section
* @param expectedResponse
* @return
*/
public static String getSectionFromExpectedResponse(String section, String expectedResponse) {
String[] criteria = expectedResponse.split("&&");
List newResponse = new ArrayList();
for (String criterion : criteria) {
criterion = Helper.removeSurroundingQuotes(criterion);
if (criterion.trim().startsWith(section)) {
newResponse.add(criterion);
}
}
return String.join("&&", newResponse);
}
/**
* validates expected values (xml, json, text, or jsonpath keywords
*
* @param responseValues
* @param expectedResponse
* @return
*/
public static List validateExpectedValues(List responseValues, String expectedResponse) {
List errorMessages = new ArrayList();
if (expectedResponse.trim().isEmpty())
return errorMessages;
// return error message if response is empty
errorMessages = validateEmptyResponse(responseValues, expectedResponse);
if (!errorMessages.isEmpty())
return errorMessages;
// validate response body against expected json string
expectedResponse = DataHelper.replaceParameters(expectedResponse);
// separate the expected response by &&
String[] criteria = getCriteria(expectedResponse);
// get response body as string
logJsonResponse(responseValues);
String booleanLogicPattern = StringUtils.EMPTY;
for (String criterion : criteria) {
criterion = criterion.trim();
booleanLogicPattern += getValidationPattern(criterion);
// remove logic values if criteria starts with "(", &&, "||" or end with ")"
criterion = removeLogicIdentifiers(criterion);
Helper.assertTrue("expected response is not valid xml or json, or section identifier, are you missing the section identifier? eg. _VERIFY_JSON_PART_: " + criterion,
isValidExpectation(criterion));
//convert xml string to json for validation
criterion = convertXmlResponseToJson(criterion);
List errors = validateExpectedResponse(criterion, responseValues);
errors = removeEmptyElements(errors);
// set boolean logic response for the logic pattern. eg "Value && Value" becomes "true && false"
if(errors.isEmpty())
booleanLogicPattern = booleanLogicPattern.replace("value", "true");
else
booleanLogicPattern = booleanLogicPattern.replace("value", "false");
errorMessages.addAll(errors);
}
boolean isPass = evaluateLogic(booleanLogicPattern);
// if logic passes, remove all errors strings
if(isPass)
errorMessages = new ArrayList();
// remove all empty response strings
errorMessages = removeEmptyElements(errorMessages);
return errorMessages;
}
/**
* split expected validation based on && or ||
* we ignore json path && or ||
* @param expectedResponse
* @return
*/
private static String[] getCriteria(String expectedResponse) {
// separate the expected response by && or ||
String[] criteria = expectedResponse.split("(?="+ VALIDATION_AND_CONDITION +")|(?="+ VALIDATION_OR_CONDITION_ECODE +")");
List updatedCriteria = new ArrayList();
String criteriaVal = StringUtils.EMPTY;
for(int i = 0 ; i responseValues) {
List updatedList = new ArrayList();
for (String response : responseValues) {
updatedList.add(response.replace(System.lineSeparator(), ""));
}
String responseString = String.join(System.lineSeparator(), updatedList);
TestLog.logPass("response to be validated: " + ServiceObject.normalizeLog(responseString));
}
/**
* validates if empty response is expected and received
*
* @param responseValues
* @param expected
* @return
*/
public static List validateEmptyResponse(List responseValues, String expected) {
List errorMessage = new ArrayList();
boolean isEmptyExpected = isEmptyResponseExpected(expected);
for (String resonse : responseValues) {
if (resonse.isEmpty() && !isEmptyExpected) {
errorMessage.add("response value is empty");
return errorMessage;
}
}
return errorMessage;
}
/**
* returns true if empty response is expected. denoted by isEmpty
*
* @param expected
* @return
*/
public static boolean isEmptyResponseExpected(String expected) {
expected = JsonHelper.removeResponseIndicator(expected);
if (expected.equals(JSON_COMMAND.isEmpty.name()))
return true;
return false;
}
/**
* validates expected requirement against response strings
*
* @param criterion
* @param responseString
* @return
*/
public static List validateExpectedResponse(String criterion, List responseString) {
List errorMessages = new ArrayList();
for (int i = 0; i < responseString.size(); i++) {
errorMessages = new ArrayList();
// if response is xml, convert to json for validation
if (XmlHelper.isValidXmlString(responseString.get(i))) {
boolean isIgnoreNamespace = Config.getBooleanValue(IS_IGNORE_XML_NAMESPACE);
// if ignore name space, criteria and response are stripped of namespace
if(isIgnoreNamespace) {
String xmlIgnoreNameSpace = XmlHelper.removeXmlNameSpace(responseString.get(i));
responseString.set(i, JsonHelper.XMLToJson(xmlIgnoreNameSpace));
}else
responseString.set(i, JsonHelper.XMLToJson(responseString.get(i)));
}
errorMessages.add(JsonHelper.validateByJsonBody(criterion, responseString.get(i)));
errorMessages.addAll(JsonHelper.validateByKeywords(criterion, responseString.get(i)));
errorMessages.add(JsonHelper.validateResponseBody(criterion, responseString.get(i)));
// if no errors, then validation passed, no need to validate against other
// responses
errorMessages = removeEmptyElements(errorMessages);
if (errorMessages.isEmpty())
break;
if (i > 0 && i == responseString.size() && !errorMessages.isEmpty()) {
errorMessages = new ArrayList();
errorMessages.add("expected requirement: " + criterion + " not met by the responses: "
+ String.join(System.lineSeparator(), responseString));
}
}
return errorMessages;
}
/**
* validates if expected value is valid: json, xml or starts with valid
* indicator
*
* @param expectedValue
* @return
*/
public static boolean isValidExpectation(String expectedValue) {
if (JsonHelper.isJSONValid(expectedValue, false)) {
return true;
}
if (XmlHelper.isValidXmlString(expectedValue))
return true;
expectedValue = Helper.stringNormalize(expectedValue);
if (expectedValue.startsWith(DataHelper.VERIFY_JSON_PART_INDICATOR)
|| expectedValue.startsWith(DataHelper.VERIFY_JSON_PART_INDICATOR_UNDERSCORE)
|| expectedValue.startsWith(VERIFY_RESPONSE_NO_EMPTY)
|| expectedValue.startsWith(DataHelper.VERIFY_RESPONSE_BODY_INDICATOR)
|| expectedValue.startsWith(DataHelper.VERIFY_HEADER_PART_INDICATOR)
|| expectedValue.startsWith(DataHelper.EXPECTED_MESSAGE_COUNT)
|| expectedValue.startsWith(DataHelper.VERIFY_TOPIC_PART_INDICATOR)) {
return true;
}
return false;
}
/**
* removes empty elements from list
*
* @param list
* @return
*/
public static List removeEmptyElements(List list) {
Iterator i = list.iterator();
while (i.hasNext()) {
String s = i.next();
if (s == null || s.trim().isEmpty()) {
i.remove();
}
}
return list;
}
public static String[] removeEmptyElements(String[] array) {
List list = new ArrayList();
for (String text : array) {
if (text != null && !text.trim().isEmpty()) {
list.add(text.trim());
}
}
array = list.toArray(new String[0]);
return array;
}
/**
* verifies actual string contains list of expected values
* @param actual
* @param expectedValues
* @return
*/
public static Set isListContain(String actual, List expectedValues) {
actual = actual.trim().replace("\"", "");
Set missing = new HashSet();
for(String expected : expectedValues) {
if(!actual.contains(expected)) {
missing.add(expected);
continue;
}
}
return missing;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy