* Added improved fractionalsecond Commander acceptance tests, need to backfill into Web API server cert * Added Date tests * Refactored fractionalseconds tests to accept greater precision, and refactored Web API Server tests to use new payload comparison helpers. Also added more tests. * Changed private access of Timestamp compare functions to public so they could be used from other test functions * Updated if/then statetments to use switch() instead * Generated new Commander Jar
This commit is contained in:
parent
fa117b19fd
commit
a2843cad82
|
@ -44,7 +44,6 @@ dependencies {
|
||||||
compile 'com.networknt:json-schema-validator:1.0.35'
|
compile 'com.networknt:json-schema-validator:1.0.35'
|
||||||
|
|
||||||
implementation 'org.mockito:mockito-core:3.3.3'
|
implementation 'org.mockito:mockito-core:3.3.3'
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
configurations {
|
configurations {
|
||||||
|
|
Binary file not shown.
|
@ -171,7 +171,7 @@
|
||||||
<Parameter Name="ToUpperValue" Value="MAIN" />
|
<Parameter Name="ToUpperValue" Value="MAIN" />
|
||||||
|
|
||||||
<!-- Gold and Platinum: Date Fields for testing -->
|
<!-- Gold and Platinum: Date Fields for testing -->
|
||||||
<Parameter Name="DateTimeValue" Value="2018-12-31T23:55:55-09:00" />
|
<Parameter Name="DateTimeValue" Value="2018-12-31T23:55:55.3-09:00" />
|
||||||
<Parameter Name="DateValue" Value="2018-12-31" />
|
<Parameter Name="DateValue" Value="2018-12-31" />
|
||||||
<Parameter Name="YearValue" Value="2018" />
|
<Parameter Name="YearValue" Value="2018" />
|
||||||
<Parameter Name="MonthValue" Value="12" />
|
<Parameter Name="MonthValue" Value="12" />
|
||||||
|
@ -180,7 +180,7 @@
|
||||||
<Parameter Name="HourValue" Value="23" />
|
<Parameter Name="HourValue" Value="23" />
|
||||||
<Parameter Name="MinuteValue" Value="55" />
|
<Parameter Name="MinuteValue" Value="55" />
|
||||||
<Parameter Name="SecondValue" Value="55" />
|
<Parameter Name="SecondValue" Value="55" />
|
||||||
<Parameter Name="FractionalValue" Value="30" />
|
<Parameter Name="FractionalValue" Value="0.3" />
|
||||||
|
|
||||||
<!-- Platinum - GeoSpatial query values -->
|
<!-- Platinum - GeoSpatial query values -->
|
||||||
<Parameter Name="GeoSpatialDistanceValue" Value="1000" />
|
<Parameter Name="GeoSpatialDistanceValue" Value="1000" />
|
||||||
|
|
|
@ -38,6 +38,7 @@ import static org.reso.commander.certfication.containers.WebAPITestContainer.*;
|
||||||
import static org.reso.commander.common.ErrorMsg.getAssertResponseCodeErrorMessage;
|
import static org.reso.commander.common.ErrorMsg.getAssertResponseCodeErrorMessage;
|
||||||
import static org.reso.commander.common.ErrorMsg.getDefaultErrorMessage;
|
import static org.reso.commander.common.ErrorMsg.getDefaultErrorMessage;
|
||||||
import static org.reso.commander.common.TestUtils.*;
|
import static org.reso.commander.common.TestUtils.*;
|
||||||
|
import static org.reso.commander.common.TestUtils.DateParts.FRACTIONAL;
|
||||||
import static org.reso.commander.common.TestUtils.Operators.*;
|
import static org.reso.commander.common.TestUtils.Operators.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -83,10 +84,9 @@ public class WebAPIServer_1_0_2 implements En {
|
||||||
/*
|
/*
|
||||||
* Edm Metadata Validator
|
* Edm Metadata Validator
|
||||||
*/
|
*/
|
||||||
And("^the Edm metadata returned by the server are valid$", () -> {
|
And("^the Edm metadata returned by the server are valid$", () ->
|
||||||
assertTrue("Edm Metadata at the given service root is not valid! " + getTestContainer().getServiceRoot(),
|
assertTrue("Edm Metadata at the given service root is not valid! " + getTestContainer().getServiceRoot(),
|
||||||
getTestContainer().getIsValidEdm());
|
getTestContainer().getIsValidEdm()));
|
||||||
});
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XML Metadata Validator
|
* XML Metadata Validator
|
||||||
|
@ -140,7 +140,7 @@ public class WebAPIServer_1_0_2 implements En {
|
||||||
|
|
||||||
DecimalFormat df = new DecimalFormat();
|
DecimalFormat df = new DecimalFormat();
|
||||||
df.setMaximumFractionDigits(1);
|
df.setMaximumFractionDigits(1);
|
||||||
double fill = 0;
|
double fill;
|
||||||
|
|
||||||
assertNotNull("ERROR: no fields found within the given $select list. Check request Id: " + getTestContainer().getRequest().getRequestId() + " in your .resoscript file!",
|
assertNotNull("ERROR: no fields found within the given $select list. Check request Id: " + getTestContainer().getRequest().getRequestId() + " in your .resoscript file!",
|
||||||
getTestContainer().getSelectList());
|
getTestContainer().getSelectList());
|
||||||
|
@ -327,32 +327,6 @@ public class WebAPIServer_1_0_2 implements En {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
|
||||||
* Compares field data (LHS) to a given parameter value (RHS). The operator is passed as a string,
|
|
||||||
* and is used to select among the supported comparisons.
|
|
||||||
*/
|
|
||||||
And("^Integer data in \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\"$", (String parameterFieldName, String op, String parameterAssertedValue) -> {
|
|
||||||
try {
|
|
||||||
String fieldName = Settings.resolveParametersString(parameterFieldName, getTestContainer().getSettings());
|
|
||||||
int assertedValue = Integer.parseInt(Settings.resolveParametersString(parameterAssertedValue, getTestContainer().getSettings()));
|
|
||||||
|
|
||||||
LOG.info("fieldName: " + fieldName + ", op: " + op + ", assertedValue: " + assertedValue);
|
|
||||||
|
|
||||||
//subsequent value comparisons are and-ed together while iterating over the list of items, so init to true
|
|
||||||
AtomicBoolean result = new AtomicBoolean(true);
|
|
||||||
AtomicReference<Integer> fieldValue = new AtomicReference<>();
|
|
||||||
|
|
||||||
//iterate through response data and ensure that with data, the statement fieldName "op" assertValue is true
|
|
||||||
from(getTestContainer().getResponseData()).getList(JSON_VALUE_PATH, HashMap.class).forEach(item -> {
|
|
||||||
fieldValue.set(item.get(fieldName) != null ? new Integer(item.get(fieldName).toString()) : null);
|
|
||||||
result.set(result.get() && TestUtils.compare(fieldValue.get(), op, assertedValue));
|
|
||||||
});
|
|
||||||
assertTrue(result.get());
|
|
||||||
} catch (Exception ex) {
|
|
||||||
fail(getDefaultErrorMessage(ex));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* True if response has results, meaning value.length > 0
|
* True if response has results, meaning value.length > 0
|
||||||
*/
|
*/
|
||||||
|
@ -374,8 +348,7 @@ public class WebAPIServer_1_0_2 implements En {
|
||||||
String value = Settings.resolveParametersString(parameterFieldName, getTestContainer().getSettings());
|
String value = Settings.resolveParametersString(parameterFieldName, getTestContainer().getSettings());
|
||||||
boolean isPresent = from(getTestContainer().getResponseData()).get() != null;
|
boolean isPresent = from(getTestContainer().getResponseData()).get() != null;
|
||||||
assertTrue("ERROR: singleton results not found for '" + value + "'!", isPresent);
|
assertTrue("ERROR: singleton results not found for '" + value + "'!", isPresent);
|
||||||
LOG.info("Response value is: " + value);
|
LOG.info("Data are present and response value is: " + value);
|
||||||
LOG.info("Is Present: " + isPresent);
|
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
fail(getDefaultErrorMessage(ex));
|
fail(getDefaultErrorMessage(ex));
|
||||||
}
|
}
|
||||||
|
@ -395,8 +368,25 @@ public class WebAPIServer_1_0_2 implements En {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compares field data (LHS) to a given parameter value (RHS). The operator is passed as a string,
|
||||||
|
* and is used to select among the supported comparisons.
|
||||||
|
*/
|
||||||
|
And("^Integer data in \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\"$", (String parameterFieldName, String op, String parameterAssertedValue) -> {
|
||||||
|
try {
|
||||||
|
String fieldName = Settings.resolveParametersString(parameterFieldName, getTestContainer().getSettings());
|
||||||
|
int assertedValue = Integer.parseInt(Settings.resolveParametersString(parameterAssertedValue, getTestContainer().getSettings()));
|
||||||
|
|
||||||
|
LOG.info("fieldName: " + fieldName + ", op: " + op + ", assertedValue: " + assertedValue);
|
||||||
|
assertTrue(TestUtils.compareIntegerPayloadToAssertedValue(getTestContainer().getResponseData(), fieldName, op, assertedValue));
|
||||||
|
} catch (Exception ex) {
|
||||||
|
fail(getDefaultErrorMessage(ex));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* True if data in the lhs expression and rhs expressions pass the AND or OR condition given in andOrOp
|
* True if data in the lhs expression and rhs expressions pass the AND or OR condition given in andOrOp
|
||||||
|
* TODO: integrate with TestUtils compareIntegerPayloadToAssertedValue
|
||||||
*/
|
*/
|
||||||
And("^Integer data in \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\"$", (String parameterFieldName, String opLhs, String parameterAssertedLhsValue, String andOrOp, String opRhs, String parameterAssertedRhsValue) -> {
|
And("^Integer data in \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\"$", (String parameterFieldName, String opLhs, String parameterAssertedLhsValue, String andOrOp, String opRhs, String parameterAssertedRhsValue) -> {
|
||||||
try {
|
try {
|
||||||
|
@ -412,8 +402,9 @@ public class WebAPIServer_1_0_2 implements En {
|
||||||
AtomicBoolean rhsResult = new AtomicBoolean(isAndOp);
|
AtomicBoolean rhsResult = new AtomicBoolean(isAndOp);
|
||||||
AtomicBoolean itemResult = new AtomicBoolean(isAndOp);
|
AtomicBoolean itemResult = new AtomicBoolean(isAndOp);
|
||||||
|
|
||||||
AtomicReference<Integer> lhsValue = new AtomicReference<>(),
|
AtomicReference<Integer>
|
||||||
rhsValue = new AtomicReference<>();
|
lhsValue = new AtomicReference<>(),
|
||||||
|
rhsValue = new AtomicReference<>();
|
||||||
|
|
||||||
//iterate through response data and ensure that with data, the statement fieldName "op" assertValue is true
|
//iterate through response data and ensure that with data, the statement fieldName "op" assertValue is true
|
||||||
from(getTestContainer().getResponseData()).getList(JSON_VALUE_PATH, HashMap.class).forEach(item -> {
|
from(getTestContainer().getResponseData()).getList(JSON_VALUE_PATH, HashMap.class).forEach(item -> {
|
||||||
|
@ -614,44 +605,34 @@ public class WebAPIServer_1_0_2 implements En {
|
||||||
try {
|
try {
|
||||||
assertedValue.set(Integer.parseInt(Settings.resolveParametersString(parameterAssertedValue, getTestContainer().getSettings())));
|
assertedValue.set(Integer.parseInt(Settings.resolveParametersString(parameterAssertedValue, getTestContainer().getSettings())));
|
||||||
LOG.info("Asserted value is: " + assertedValue.get());
|
LOG.info("Asserted value is: " + assertedValue.get());
|
||||||
|
assertTrue(TestUtils.compareDatePayloadToAssertedDatePartValue(getTestContainer().getResponseData(), datePart.get(), fieldName, operator.get(), assertedValue.intValue()));
|
||||||
from(getTestContainer().getResponseData()).getList(JSON_VALUE_PATH, HashMap.class).forEach(item -> {
|
|
||||||
try {
|
|
||||||
fieldValue.set(TestUtils.getDatePart(datePart.get(), item.get(fieldName)));
|
|
||||||
assertTrue(TestUtils.compare(fieldValue.get(), operator.get(), assertedValue.get()));
|
|
||||||
} catch (Exception ex) {
|
|
||||||
fail(getDefaultErrorMessage(ex));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
fail(getDefaultErrorMessage(ex));
|
fail(getDefaultErrorMessage(ex));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Year comparison from Timestamp Field
|
* Date part comparison with Timestamp Field
|
||||||
* TODO: consolidate with Year comparison with Date Field
|
|
||||||
*/
|
*/
|
||||||
And("^\"([^\"]*)\" data in Timestamp Field \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\"$", (String stringDatePart, String parameterFieldName, String op, String parameterAssertedValue) -> {
|
And("^\"([^\"]*)\" data in Timestamp Field \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\"$", (String stringDatePart, String parameterFieldName, String op, String parameterAssertedValue) -> {
|
||||||
try {
|
try {
|
||||||
String fieldName = Settings.resolveParametersString(parameterFieldName, getTestContainer().getSettings());
|
String fieldName = Settings.resolveParametersString(parameterFieldName, getTestContainer().getSettings());
|
||||||
AtomicReference<Integer> fieldValue = new AtomicReference<>();
|
Double assertedValue;
|
||||||
AtomicReference<Integer> assertedValue = new AtomicReference<>();
|
String datePart = stringDatePart.toLowerCase();
|
||||||
AtomicReference<String> datePart = new AtomicReference<>(stringDatePart.toLowerCase());
|
String operator = op.toLowerCase();
|
||||||
AtomicReference<String> operator = new AtomicReference<>(op.toLowerCase());
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
assertedValue.set(Integer.parseInt(Settings.resolveParametersString(parameterAssertedValue, getTestContainer().getSettings())));
|
assertedValue = Double.parseDouble(Settings.resolveParametersString(parameterAssertedValue, getTestContainer().getSettings()));
|
||||||
LOG.info("Asserted value is: " + assertedValue.get().toString());
|
|
||||||
|
|
||||||
from(getTestContainer().getResponseData()).getList(JSON_VALUE_PATH, HashMap.class).forEach(item -> {
|
if (assertedValue % 1 == 0) LOG.info("Asserted value is: " + assertedValue.intValue());
|
||||||
try {
|
else LOG.info("Asserted value is: " + assertedValue);
|
||||||
fieldValue.set(TestUtils.getTimestampPart(datePart.get(), item.get(fieldName).toString()));
|
|
||||||
assertTrue(TestUtils.compare(fieldValue.get(), operator.get(), assertedValue.get()));
|
//TODO: re-consolidate fractional with other date part ops
|
||||||
} catch (Exception ex) {
|
if (datePart.contentEquals(FRACTIONAL)) {
|
||||||
fail(getDefaultErrorMessage(ex));
|
assertTrue(TestUtils.compareFractionalSecondsPayloadToAssertedValue(getTestContainer().getResponseData(), fieldName, operator, assertedValue));
|
||||||
}
|
} else {
|
||||||
});
|
assertTrue(TestUtils.compareTimestampPayloadToAssertedDatePartValue(getTestContainer().getResponseData(), datePart, fieldName, operator, assertedValue.intValue()));
|
||||||
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
fail(getDefaultErrorMessage(ex));
|
fail(getDefaultErrorMessage(ex));
|
||||||
}
|
}
|
||||||
|
@ -666,12 +647,8 @@ public class WebAPIServer_1_0_2 implements En {
|
||||||
And("^String data in \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\"$", (String parameterFieldName, String op, String parameterAssertedValue) -> {
|
And("^String data in \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\"$", (String parameterFieldName, String op, String parameterAssertedValue) -> {
|
||||||
try {
|
try {
|
||||||
String fieldName = Settings.resolveParametersString(parameterFieldName, getTestContainer().getSettings());
|
String fieldName = Settings.resolveParametersString(parameterFieldName, getTestContainer().getSettings());
|
||||||
AtomicReference<String> assertedValue = new AtomicReference<>(Settings.resolveParametersString(parameterAssertedValue, getTestContainer().getSettings()));
|
String assertedValue = Settings.resolveParametersString(parameterAssertedValue, getTestContainer().getSettings());
|
||||||
AtomicReference<String> operator = new AtomicReference<>(op.toLowerCase());
|
assertTrue(TestUtils.compareStringPayloadToAssertedValue(getTestContainer().getResponseData(), fieldName, op, assertedValue));
|
||||||
|
|
||||||
from(getTestContainer().getResponseData()).getList(JSON_VALUE_PATH, HashMap.class).forEach(item -> {
|
|
||||||
assertTrue(TestUtils.compare(item.get(fieldName).toString(), operator.get(), assertedValue.get()));
|
|
||||||
});
|
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
fail(getDefaultErrorMessage(ex));
|
fail(getDefaultErrorMessage(ex));
|
||||||
}
|
}
|
||||||
|
@ -708,8 +685,6 @@ public class WebAPIServer_1_0_2 implements En {
|
||||||
*/
|
*/
|
||||||
And("^resource metadata for \"([^\"]*)\" contains the fields in the given select list$", (String parameterResourceName) -> {
|
And("^resource metadata for \"([^\"]*)\" contains the fields in the given select list$", (String parameterResourceName) -> {
|
||||||
try {
|
try {
|
||||||
final String resourceName = Settings.resolveParametersString(parameterResourceName, getTestContainer().getSettings());
|
|
||||||
|
|
||||||
LOG.info("Searching metadata for fields in given select list: " + getTestContainer().getSelectList().toString());
|
LOG.info("Searching metadata for fields in given select list: " + getTestContainer().getSelectList().toString());
|
||||||
getTestContainer().getSelectList().forEach(fieldName -> {
|
getTestContainer().getSelectList().forEach(fieldName -> {
|
||||||
//need to skip the expand field when looking through the metadata
|
//need to skip the expand field when looking through the metadata
|
||||||
|
@ -838,9 +813,8 @@ public class WebAPIServer_1_0_2 implements En {
|
||||||
* Checks to see whether expanding the EndpointResource on ExpandField produces equivalent records from the corresponding
|
* Checks to see whether expanding the EndpointResource on ExpandField produces equivalent records from the corresponding
|
||||||
* resource of the expanded type
|
* resource of the expanded type
|
||||||
*/
|
*/
|
||||||
And("^the expanded data were found in the related resource$", () -> {
|
And("^the expanded data were found in the related resource$", () ->
|
||||||
LOG.info("TODO: this depends on either finding the appropriate navigation property for a given relationship, or having the Expanded resource type name.");
|
LOG.info("TODO: this depends on either finding the appropriate navigation property for a given relationship, or having the Expanded resource type name."));
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -922,9 +896,8 @@ public class WebAPIServer_1_0_2 implements En {
|
||||||
Integer fieldValue = Integer.parseInt(Settings.resolveParametersString(parameterFieldValue, getTestContainer().getSettings()));
|
Integer fieldValue = Integer.parseInt(Settings.resolveParametersString(parameterFieldValue, getTestContainer().getSettings()));
|
||||||
assertNotNull(fieldValue);
|
assertNotNull(fieldValue);
|
||||||
|
|
||||||
getTestContainer().getClientEntitySet().getEntities().forEach(entity -> {
|
getTestContainer().getClientEntitySet().getEntities().forEach(entity ->
|
||||||
assertTrue(compare((Integer) entity.getProperty(fieldName).getValue().asPrimitive().toValue(), op, fieldValue));
|
assertTrue(compare((Integer) entity.getProperty(fieldName).getValue().asPrimitive().toValue(), op, fieldValue)));
|
||||||
});
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1017,6 +990,7 @@ public class WebAPIServer_1_0_2 implements En {
|
||||||
assertNotNull("ERROR: pathToRESOScript must be present in command arguments, see README", getTestContainer().getPathToRESOScript());
|
assertNotNull("ERROR: pathToRESOScript must be present in command arguments, see README", getTestContainer().getPathToRESOScript());
|
||||||
LOG.info("Using RESOScript: " + getTestContainer().getPathToRESOScript());
|
LOG.info("Using RESOScript: " + getTestContainer().getPathToRESOScript());
|
||||||
});
|
});
|
||||||
|
|
||||||
And("^Client Settings and Parameters were read from the file$", () -> {
|
And("^Client Settings and Parameters were read from the file$", () -> {
|
||||||
if (getTestContainer().getSettings() == null) {
|
if (getTestContainer().getSettings() == null) {
|
||||||
getTestContainer().setSettings(Settings.loadFromRESOScript(new File(System.getProperty("pathToRESOScript"))));
|
getTestContainer().setSettings(Settings.loadFromRESOScript(new File(System.getProperty("pathToRESOScript"))));
|
||||||
|
@ -1025,9 +999,8 @@ public class WebAPIServer_1_0_2 implements En {
|
||||||
LOG.info("RESOScript loaded successfully!");
|
LOG.info("RESOScript loaded successfully!");
|
||||||
});
|
});
|
||||||
|
|
||||||
Given("^a test container was successfully created from the given RESOScript$", () -> {
|
Given("^a test container was successfully created from the given RESOScript$", ()
|
||||||
getTestContainer().initialize();
|
-> getTestContainer().initialize());
|
||||||
});
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ensures that the client either uses Authorization Codes or Client Credentials
|
* Ensures that the client either uses Authorization Codes or Client Credentials
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -2,26 +2,19 @@ package org.reso.commander.test.stepdefs;
|
||||||
|
|
||||||
import io.cucumber.java8.En;
|
import io.cucumber.java8.En;
|
||||||
import org.apache.http.HttpStatus;
|
import org.apache.http.HttpStatus;
|
||||||
import org.apache.logging.log4j.LogManager;
|
|
||||||
import org.apache.logging.log4j.Logger;
|
|
||||||
import org.reso.commander.certfication.containers.WebAPITestContainer;
|
import org.reso.commander.certfication.containers.WebAPITestContainer;
|
||||||
import org.reso.commander.common.TestUtils;
|
import org.reso.commander.common.TestUtils;
|
||||||
import org.reso.models.Settings;
|
import org.reso.models.Settings;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
import static io.restassured.path.json.JsonPath.from;
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
import static org.reso.commander.common.ErrorMsg.getDefaultErrorMessage;
|
import static org.reso.commander.common.ErrorMsg.getDefaultErrorMessage;
|
||||||
import static org.reso.commander.common.TestUtils.JSON_VALUE_PATH;
|
import static org.reso.commander.common.TestUtils.*;
|
||||||
import static org.reso.commander.common.TestUtils.parseTimestampFromEdmDateTimeOffsetString;
|
|
||||||
|
|
||||||
public class TestWebAPITestContainer implements En {
|
public class TestWebAPITestContainer implements En {
|
||||||
private static final Logger LOG = LogManager.getLogger(TestWebAPITestContainer.class);
|
|
||||||
AtomicReference<WebAPITestContainer> testContainer = new AtomicReference<>();
|
AtomicReference<WebAPITestContainer> testContainer = new AtomicReference<>();
|
||||||
|
|
||||||
public TestWebAPITestContainer() {
|
public TestWebAPITestContainer() {
|
||||||
|
@ -68,30 +61,24 @@ public class TestWebAPITestContainer implements En {
|
||||||
assertNotNull(getDefaultErrorMessage("BearerToken is null in the ClientSettings section!"), token);
|
assertNotNull(getDefaultErrorMessage("BearerToken is null in the ClientSettings section!"), token);
|
||||||
});
|
});
|
||||||
|
|
||||||
Then("^the Commander is created using auth token client mode$", () -> {
|
Then("^the Commander is created using auth token client mode$", () ->
|
||||||
assertTrue(getDefaultErrorMessage("expected auth token Commander client!"),
|
assertTrue(getDefaultErrorMessage("expected auth token Commander client!"), getTestContainer().getCommander().isAuthTokenClient()));
|
||||||
getTestContainer().getCommander().isAuthTokenClient());
|
|
||||||
});
|
|
||||||
|
|
||||||
And("^the auth token has a value of \"([^\"]*)\"$", (String assertedTokenValue) -> {
|
And("^the auth token has a value of \"([^\"]*)\"$", (String assertedTokenValue) ->
|
||||||
assertEquals(getDefaultErrorMessage("asserted token value is not equal to the one provided in the container!"),
|
assertEquals(getDefaultErrorMessage("asserted token value is not equal to the one provided in the container!"),
|
||||||
assertedTokenValue, getTestContainer().getAuthToken());
|
assertedTokenValue, getTestContainer().getAuthToken()));
|
||||||
});
|
|
||||||
|
|
||||||
And("^a Commander instance exists within the test container$", () -> {
|
And("^a Commander instance exists within the test container$", () ->
|
||||||
assertNotNull(getDefaultErrorMessage("Commander instance is null in the container!"),
|
assertNotNull(getDefaultErrorMessage("Commander instance is null in the container!"),
|
||||||
getTestContainer().getCommander());
|
getTestContainer().getCommander()));
|
||||||
});
|
|
||||||
|
|
||||||
But("^the Commander is not created using client credentials mode$", () -> {
|
But("^the Commander is not created using client credentials mode$", () ->
|
||||||
assertFalse(getDefaultErrorMessage("expected that the Commander was not using client credentials"),
|
assertFalse(getDefaultErrorMessage("expected that the Commander was not using client credentials"),
|
||||||
getTestContainer().getCommander().isOAuth2Client());
|
getTestContainer().getCommander().isOAuth2Client()));
|
||||||
});
|
|
||||||
|
|
||||||
And("^Settings are present in the test container$", () -> {
|
And("^Settings are present in the test container$", () ->
|
||||||
assertNotNull(getDefaultErrorMessage("settings were not found in the Web API test container!"),
|
assertNotNull(getDefaultErrorMessage("settings were not found in the Web API test container!"),
|
||||||
getTestContainer().getSettings());
|
getTestContainer().getSettings()));
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -118,15 +105,13 @@ public class TestWebAPITestContainer implements En {
|
||||||
getTestContainer().setResponseData(loadResourceAsString(resourceName));
|
getTestContainer().setResponseData(loadResourceAsString(resourceName));
|
||||||
});
|
});
|
||||||
|
|
||||||
Then("^schema validation passes for the sample DataSystem data$", () -> {
|
Then("^schema validation passes for the sample DataSystem data$", () ->
|
||||||
assertTrue(getDefaultErrorMessage("expected DataSystem to pass validation, but it failed!"),
|
assertTrue(getDefaultErrorMessage("expected DataSystem to pass validation, but it failed!"),
|
||||||
getTestContainer().validateDataSystem().getIsValidDataSystem());
|
getTestContainer().validateDataSystem().getIsValidDataSystem()));
|
||||||
});
|
|
||||||
|
|
||||||
Then("^schema validation fails for the sample DataSystem data$", () -> {
|
Then("^schema validation fails for the sample DataSystem data$", () ->
|
||||||
assertFalse(getDefaultErrorMessage("expected DataSystem to fail validation, but it passed!"),
|
assertFalse(getDefaultErrorMessage("expected DataSystem to fail validation, but it passed!"),
|
||||||
getTestContainer().validateDataSystem().getIsValidDataSystem());
|
getTestContainer().validateDataSystem().getIsValidDataSystem()));
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -134,7 +119,7 @@ public class TestWebAPITestContainer implements En {
|
||||||
*/
|
*/
|
||||||
Then("^Integer comparisons of \"([^\"]*)\" \"([^\"]*)\" (\\d+) return \"([^\"]*)\"$", (String fieldName, String op, Integer assertedValue, String expectedValue) -> {
|
Then("^Integer comparisons of \"([^\"]*)\" \"([^\"]*)\" (\\d+) return \"([^\"]*)\"$", (String fieldName, String op, Integer assertedValue, String expectedValue) -> {
|
||||||
final boolean expected = Boolean.parseBoolean(expectedValue),
|
final boolean expected = Boolean.parseBoolean(expectedValue),
|
||||||
result = testIntegerComparisons(fieldName, op, assertedValue);
|
result = compareIntegerPayloadToAssertedValue(getTestContainer().getResponseData(), fieldName, op, assertedValue);
|
||||||
if (expected) {
|
if (expected) {
|
||||||
assertTrue(result);
|
assertTrue(result);
|
||||||
} else {
|
} else {
|
||||||
|
@ -144,7 +129,7 @@ public class TestWebAPITestContainer implements En {
|
||||||
|
|
||||||
Then("^Integer comparisons of \"([^\"]*)\" \"([^\"]*)\" null return \"([^\"]*)\"$", (String fieldName, String op, String expectedValue) -> {
|
Then("^Integer comparisons of \"([^\"]*)\" \"([^\"]*)\" null return \"([^\"]*)\"$", (String fieldName, String op, String expectedValue) -> {
|
||||||
final boolean expected = Boolean.parseBoolean(expectedValue),
|
final boolean expected = Boolean.parseBoolean(expectedValue),
|
||||||
result = testIntegerComparisons(fieldName, op, null);
|
result = compareIntegerPayloadToAssertedValue(getTestContainer().getResponseData(), fieldName, op, null);
|
||||||
if (expected) {
|
if (expected) {
|
||||||
assertTrue(result);
|
assertTrue(result);
|
||||||
} else {
|
} else {
|
||||||
|
@ -158,7 +143,7 @@ public class TestWebAPITestContainer implements En {
|
||||||
*/
|
*/
|
||||||
Then("^String data in \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\" returns \"([^\"]*)\"$", (String fieldName, String op, String assertedValue, String expectedValue) -> {
|
Then("^String data in \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\" returns \"([^\"]*)\"$", (String fieldName, String op, String assertedValue, String expectedValue) -> {
|
||||||
final boolean expected = Boolean.parseBoolean(expectedValue),
|
final boolean expected = Boolean.parseBoolean(expectedValue),
|
||||||
result = testStringComparisons(fieldName, op, assertedValue);
|
result = compareStringPayloadToAssertedValue(getTestContainer().getResponseData(), fieldName, op, assertedValue);
|
||||||
if (expected) {
|
if (expected) {
|
||||||
assertTrue(result);
|
assertTrue(result);
|
||||||
} else {
|
} else {
|
||||||
|
@ -168,7 +153,7 @@ public class TestWebAPITestContainer implements En {
|
||||||
|
|
||||||
Then("^String data in \"([^\"]*)\" \"([^\"]*)\" null returns \"([^\"]*)\"$", (String fieldName, String op, String expectedValue) -> {
|
Then("^String data in \"([^\"]*)\" \"([^\"]*)\" null returns \"([^\"]*)\"$", (String fieldName, String op, String expectedValue) -> {
|
||||||
final boolean expected = Boolean.parseBoolean(expectedValue),
|
final boolean expected = Boolean.parseBoolean(expectedValue),
|
||||||
result = testStringComparisons(fieldName, op, null);
|
result = compareStringPayloadToAssertedValue(getTestContainer().getResponseData(), fieldName, op, null);
|
||||||
if (expected) {
|
if (expected) {
|
||||||
assertTrue(result);
|
assertTrue(result);
|
||||||
} else {
|
} else {
|
||||||
|
@ -176,25 +161,22 @@ public class TestWebAPITestContainer implements En {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Then("^String data in \"([^\"]*)\" \"([^\"]*)\" equals \"([^\"]*)\"$", (String fieldName, String op, String assertedValue) -> {
|
Then("^String data in \"([^\"]*)\" \"([^\"]*)\" equals \"([^\"]*)\"$", (String fieldName, String op, String assertedValue)
|
||||||
assertTrue(testStringComparisons(fieldName, op, assertedValue));
|
-> assertTrue(compareStringPayloadToAssertedValue(getTestContainer().getResponseData(), fieldName, op, assertedValue)));
|
||||||
});
|
|
||||||
|
|
||||||
Then("^String data in \"([^\"]*)\" \"([^\"]*)\" does not equal \"([^\"]*)\"$", (String fieldName, String op, String assertedValue) -> {
|
Then("^String data in \"([^\"]*)\" \"([^\"]*)\" does not equal \"([^\"]*)\"$", (String fieldName, String op, String assertedValue)
|
||||||
assertFalse(testStringComparisons(fieldName, op, assertedValue));
|
-> assertFalse(compareStringPayloadToAssertedValue(getTestContainer().getResponseData(), fieldName, op, assertedValue)));
|
||||||
});
|
|
||||||
|
|
||||||
Then("^String data in \"([^\"]*)\" \"([^\"]*)\" is null$", (String fieldName, String op) -> {
|
Then("^String data in \"([^\"]*)\" \"([^\"]*)\" is null$", (String fieldName, String op)
|
||||||
assertFalse(testStringComparisons(fieldName, op, null));
|
-> assertFalse(compareStringPayloadToAssertedValue(getTestContainer().getResponseData(), fieldName, op, null)));
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Timestamp Response Testing
|
* Timestamp Response Testing
|
||||||
*/
|
*/
|
||||||
Then("^Timestamp comparisons of \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\" return \"([^\"]*)\"$", (String fieldName, String op, String assertedValue, String expectedValue) -> {
|
Then("^comparisons of Timestamp field \"([^\"]*)\" \"([^\"]*)\" \"([^\"]*)\" return \"([^\"]*)\"$", (String fieldName, String op, String assertedValue, String expectedValue) -> {
|
||||||
final boolean expected = Boolean.parseBoolean(expectedValue),
|
final boolean expected = Boolean.parseBoolean(expectedValue),
|
||||||
result = testTimestampComparisons(fieldName, op, assertedValue);
|
result = compareTimestampPayloadToAssertedValue(getTestContainer().getResponseData(), fieldName, op, assertedValue);
|
||||||
if (expected) {
|
if (expected) {
|
||||||
assertTrue(result);
|
assertTrue(result);
|
||||||
} else {
|
} else {
|
||||||
|
@ -202,9 +184,52 @@ public class TestWebAPITestContainer implements En {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Then("^Timestamp comparisons of \"([^\"]*)\" \"([^\"]*)\" null return \"([^\"]*)\"$", (String fieldName, String op, String expectedValue) -> {
|
Then("^comparisons of Timestamp field \"([^\"]*)\" \"([^\"]*)\" null return \"([^\"]*)\"$", (String fieldName, String op, String expectedValue) -> {
|
||||||
final boolean expected = Boolean.parseBoolean(expectedValue),
|
final boolean expected = Boolean.parseBoolean(expectedValue),
|
||||||
result = testTimestampComparisons(fieldName, op, null);
|
result = compareTimestampPayloadToAssertedValue(getTestContainer().getResponseData(), fieldName, op, null);
|
||||||
|
if (expected) {
|
||||||
|
assertTrue(result);
|
||||||
|
} else {
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Then("^\"([^\"]*)\" comparisons of Timestamp field \"([^\"]*)\" \"([^\"]*)\" (\\d+) return \"([^\"]*)\"$", (String datePart, String fieldName, String op, Integer assertedValue, String expectedValue) -> {
|
||||||
|
final boolean expected = Boolean.parseBoolean(expectedValue),
|
||||||
|
result = compareTimestampPayloadToAssertedDatePartValue(getTestContainer().getResponseData(), datePart, fieldName, op, assertedValue);
|
||||||
|
if (expected) {
|
||||||
|
assertTrue(result);
|
||||||
|
} else {
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Then("^\"([^\"]*)\" comparisons of Timestamp field \"([^\"]*)\" \"([^\"]*)\" null return \"([^\"]*)\"$", (String datePart, String fieldName, String op, String expectedValue) -> {
|
||||||
|
final boolean expected = Boolean.parseBoolean(expectedValue),
|
||||||
|
result = compareTimestampPayloadToAssertedDatePartValue(getTestContainer().getResponseData(), datePart, fieldName, op,null);
|
||||||
|
if (expected) {
|
||||||
|
assertTrue(result);
|
||||||
|
} else {
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fractional Second Response Testing
|
||||||
|
*/
|
||||||
|
Then("^fractionalsecond comparisons of Timestamp field \"([^\"]*)\" \"([^\"]*)\" (\\d+\\.\\d+) return \"([^\"]*)\"$", (String fieldName, String op, Double assertedValue, String expectedValue) -> {
|
||||||
|
final boolean expected = Boolean.parseBoolean(expectedValue),
|
||||||
|
result = compareFractionalSecondsPayloadToAssertedValue(getTestContainer().getResponseData(), fieldName, op, assertedValue);
|
||||||
|
if (expected) {
|
||||||
|
assertTrue(result);
|
||||||
|
} else {
|
||||||
|
assertFalse(result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Then("^fractionalsecond comparisons of Timestamp field \"([^\"]*)\" \"([^\"]*)\" null return \"([^\"]*)\"$", (String fieldName, String op, String expectedValue) -> {
|
||||||
|
final boolean expected = Boolean.parseBoolean(expectedValue),
|
||||||
|
result = compareFractionalSecondsPayloadToAssertedValue(getTestContainer().getResponseData(), fieldName, op, null);
|
||||||
if (expected) {
|
if (expected) {
|
||||||
assertTrue(result);
|
assertTrue(result);
|
||||||
} else {
|
} else {
|
||||||
|
@ -214,11 +239,11 @@ public class TestWebAPITestContainer implements En {
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Date Part Response Testing
|
* Date Comparisons
|
||||||
*/
|
*/
|
||||||
Then("^\"([^\"]*)\" comparisons of \"([^\"]*)\" \"([^\"]*)\" (\\d+) return \"([^\"]*)\"$", (String datePart, String fieldName, String op, Integer assertedValue, String expectedValue) -> {
|
Then("^\"([^\"]*)\" comparisons of Date field \"([^\"]*)\" \"([^\"]*)\" (\\d+) return \"([^\"]*)\"$", (String datePart, String fieldName, String op, Integer assertedValue, String expectedValue) -> {
|
||||||
final boolean expected = Boolean.parseBoolean(expectedValue),
|
final boolean expected = Boolean.parseBoolean(expectedValue),
|
||||||
result = testDatePartComparisons(datePart, fieldName, op, assertedValue);
|
result = compareDatePayloadToAssertedDatePartValue(getTestContainer().getResponseData(), datePart, fieldName, op, assertedValue);
|
||||||
if (expected) {
|
if (expected) {
|
||||||
assertTrue(result);
|
assertTrue(result);
|
||||||
} else {
|
} else {
|
||||||
|
@ -226,60 +251,16 @@ public class TestWebAPITestContainer implements En {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Then("^\"([^\"]*)\" comparisons of \"([^\"]*)\" \"([^\"]*)\" null return \"([^\"]*)\"$", (String datePart, String fieldName, String op, String expectedValue) -> {
|
Then("^\"([^\"]*)\" comparisons of Date field \"([^\"]*)\" \"([^\"]*)\" null return \"([^\"]*)\"$", (String datePart, String fieldName, String op, String expectedValue) -> {
|
||||||
final boolean expected = Boolean.parseBoolean(expectedValue),
|
final boolean expected = Boolean.parseBoolean(expectedValue),
|
||||||
result = testDatePartComparisons(datePart, fieldName, op, null);
|
result = compareDatePayloadToAssertedDatePartValue(getTestContainer().getResponseData(), datePart, fieldName, op, null);
|
||||||
if (expected) {
|
if (expected) {
|
||||||
assertTrue(result);
|
assertTrue(result);
|
||||||
} else {
|
} else {
|
||||||
assertFalse(result);
|
assertFalse(result);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
boolean testStringComparisons(String fieldName, String op, String assertedValue) {
|
|
||||||
AtomicBoolean result = new AtomicBoolean(false);
|
|
||||||
//iterate over the items and count the number of fields with data to determine whether there are data present
|
|
||||||
from(getTestContainer().getResponseData()).getList(JSON_VALUE_PATH, HashMap.class).forEach(item -> {
|
|
||||||
result.compareAndSet(result.get(), TestUtils.compare((String)item.get(fieldName), op, assertedValue));
|
|
||||||
});
|
|
||||||
return result.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean testIntegerComparisons(String fieldName, String op, Integer assertedValue) {
|
|
||||||
AtomicBoolean result = new AtomicBoolean(false);
|
|
||||||
//iterate over the items and count the number of fields with data to determine whether there are data present
|
|
||||||
from(getTestContainer().getResponseData()).getList(JSON_VALUE_PATH, HashMap.class).forEach(item -> {
|
|
||||||
result.compareAndSet(result.get(), TestUtils.compare((Integer) item.get(fieldName), op, assertedValue));
|
|
||||||
});
|
|
||||||
return result.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean testTimestampComparisons(String fieldName, String op, String offsetDateTime) {
|
|
||||||
AtomicBoolean result = new AtomicBoolean(false);
|
|
||||||
//iterate over the items and count the number of fields with data to determine whether there are data present
|
|
||||||
from(getTestContainer().getResponseData()).getList(JSON_VALUE_PATH, HashMap.class).forEach(item -> {
|
|
||||||
try {
|
|
||||||
result.compareAndSet(result.get(), TestUtils.compare(
|
|
||||||
parseTimestampFromEdmDateTimeOffsetString((String)item.get(fieldName)), op,
|
|
||||||
parseTimestampFromEdmDateTimeOffsetString(offsetDateTime)));
|
|
||||||
} catch (Exception ex) {
|
|
||||||
fail(getDefaultErrorMessage(ex));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return result.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean testDatePartComparisons(String datePart, String fieldName, String op, Integer assertedValue) {
|
|
||||||
AtomicBoolean result = new AtomicBoolean(false);
|
|
||||||
|
|
||||||
from(getTestContainer().getResponseData()).getList(JSON_VALUE_PATH, HashMap.class).forEach(item -> {
|
|
||||||
try {
|
|
||||||
result.compareAndSet(result.get(), TestUtils.compare(TestUtils.getTimestampPart(datePart, item.get(fieldName)), op, assertedValue));
|
|
||||||
} catch (Exception ex) {
|
|
||||||
fail(getDefaultErrorMessage(ex));
|
|
||||||
}});
|
|
||||||
return result.get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
{
|
|
||||||
"@odata.context": "https://test.reso.org",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"ListingKeyNumeric": 1,
|
|
||||||
"BedroomsTotal": null
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
{
|
|
||||||
"@odata.context": "https://test.reso.org",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"ListingKeyNumeric": 1,
|
|
||||||
"BedroomsTotal": 5
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"@odata.context": "https://test.reso.org",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"ListingKeyNumeric": null,
|
||||||
|
"BedroomsTotal": null,
|
||||||
|
"StreetName": null,
|
||||||
|
"ModificationTimestamp": null,
|
||||||
|
"ListingContractDate": null
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"@odata.context": "https://test.reso.org",
|
||||||
|
"value": [
|
||||||
|
{
|
||||||
|
"ListingKeyNumeric": 1,
|
||||||
|
"BedroomsTotal": 5,
|
||||||
|
"StreetName": "Main",
|
||||||
|
"ModificationTimestamp": "2020-04-02T02:02:02.02Z",
|
||||||
|
"ListingContractDate": "2020-04-02"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -1,9 +0,0 @@
|
||||||
{
|
|
||||||
"@odata.context": "https://test.reso.org",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"ListingKeyNumeric": 1,
|
|
||||||
"StreetName": null
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
{
|
|
||||||
"@odata.context": "https://test.reso.org",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"ListingKeyNumeric": 1,
|
|
||||||
"StreetName": "Main"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
{
|
|
||||||
"@odata.context": "https://test.reso.org",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"ListingKeyNumeric": 1,
|
|
||||||
"ModificationTimestamp": null
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
{
|
|
||||||
"@odata.context": "https://test.reso.org",
|
|
||||||
"value": [
|
|
||||||
{
|
|
||||||
"ListingKeyNumeric": 1,
|
|
||||||
"ModificationTimestamp": "2020-04-02T02:02:02.02Z"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
Loading…
Reference in New Issue