Added support for Asc, Desc timestamp comparison operators

This commit is contained in:
Joshua Darnell 2020-03-02 00:11:06 -08:00
parent f02b95f4fb
commit d412f0bdd4
6 changed files with 109 additions and 36 deletions

View File

@ -17,6 +17,3 @@ COPY --from=builder /home/gradle/project/build/libs/web-api-commander.jar ./
ENTRYPOINT ["java","-jar","/web-api-commander.jar"]
CMD ["--help"]

View File

@ -4,9 +4,6 @@ plugins {
// Apply the application plugin to add support for building an application
id 'application'
id "com.github.spacialcircumstances.gradle-cucumber-reporting" version "0.1.19"
}
// Define the main class for the application
@ -92,11 +89,4 @@ task testWebApiServer_1_0_2() {
systemProperties = System.getProperties()
}
}
cucumberReports {
outputDir = file('build/reports')
buildId = '0'
reports = files('path/to/web-api-server-1.0.2.json')
expandAllSteps = true
}
}

Binary file not shown.

View File

@ -25,7 +25,7 @@
Name CDATA #REQUIRED
Value CDATA #REQUIRED>
<!ELEMENT Requests (Request)*>
<!ELEMENT Request (#PCDATA)*>
<!ELEMENT Request (#PCDATA)>
<!ATTLIST Request
Capability CDATA #REQUIRED
MetallicLevel CDATA #REQUIRED
@ -456,41 +456,41 @@
<Request
TestDescription="Query Support: $orderby asc filtered"
RequirementId="REQ-WA103-QO28"
RequirementId="REQ-WA103-QO28.1"
MetallicLevel="Bronze"
Capability="Sortability ($orderby)"
WebAPIReference="2.4.4"
OutputFile="REQ-WA103-QO28_OrderByAscFiltered.json"
OutputFile="REQ-WA103-QO28.1.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_SortCount*&amp;$select=*Parameter_FilterIntegerField*,*Parameter_TimestampField*&amp;$orderby=*Parameter_TimestampField* asc&amp;$filter=*Parameter_FilterIntegerField* ne null and *Parameter_FilterIntegerField* gt *Parameter_FilterIntegerValueLow**Parameter_RequiredParameters*"
/>
<Request
TestDescription="Query Support: $orderby asc no filter"
RequirementId="REQ-WA103-QO28"
RequirementId="REQ-WA103-QO28.2"
MetallicLevel="Bronze"
Capability="Sortability ($orderby)"
WebAPIReference="2.4.4"
OutputFile="REQ-WA103-QO28_OrderByAscNoFilter.json"
OutputFile="REQ-WA103-QO28.2.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_SortCount*&amp;$select=*Parameter_FilterIntegerField*,*Parameter_TimestampField*&amp;$orderby=*Parameter_TimestampField* asc"
/>
<Request
TestDescription="Query Support: $orderby desc filtered"
RequirementId="REQ-WA103-QO28"
RequirementId="REQ-WA103-QO28.3"
MetallicLevel="Bronze"
Capability="Sortability ($orderby)"
WebAPIReference="2.4.4"
OutputFile="REQ-WA103-QO28_OrderByDescFiltered.json"
OutputFile="REQ-WA103-QO28.3.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_SortCount*&amp;$select=*Parameter_FilterIntegerField*,*Parameter_TimestampField*&amp;$orderby=*Parameter_TimestampField* desc&amp;$filter=*Parameter_FilterIntegerField* ne null and *Parameter_FilterIntegerField* gt *Parameter_FilterIntegerValueLow**Parameter_RequiredParameters*"
/>
<Request
TestDescription="Query Support: $orderby desc no filter"
RequirementId="REQ-WA103-QO28"
RequirementId="REQ-WA103-QO28.4"
MetallicLevel="Bronze"
Capability="Sortability ($orderby)"
WebAPIReference="2.4.4"
OutputFile="REQ-WA103-QO28_OrderByDescNoFilter.json"
OutputFile="REQ-WA103-QO28.4.json"
Url="*ClientSettings_WebAPIURI*/*Parameter_EndpointResource*?$top=*Parameter_SortCount*&amp;$select=*Parameter_FilterIntegerField*,*Parameter_TimestampField*&amp;$orderby=*Parameter_TimestampField* desc"
/>

View File

@ -1,6 +1,5 @@
Feature: Web API Server 1.0.2 Certification
All Scenarios Passing means that the Web API server is fully-compliant with the RESO specification.
It's not expected that a server will pass all scenarios.
All Scenarios passing means the given Web API server is fully-compliant with the RESO Platinum Web API 1.0.2 Server specification.
Background:
Given a RESOScript file was provided
@ -58,7 +57,7 @@ Feature: Web API Server 1.0.2 Certification
And the response has results
And data in the "Parameter_KeyOrKeyNumeric" fields are different in the second request than in the first
@REQ-WA103-QO1.1 @REQ-WA103-QO1.select @core @2.4.4 @core-endorsement @OData-4.0
@REQ-WA103-QO1.1 @core @2.4.4 @core-endorsement @OData-4.0
Scenario: Query Support: $select case-sensitivity for OData 4.0
When a GET request is made to the resolved Url in "REQ-WA103-QO1.1"
Then the server responds with a status code of 400 if the server headers report OData version "4.0"
@ -182,7 +181,7 @@ Feature: Web API Server 1.0.2 Certification
And the response has results
And DateTimeOffset data in "Parameter_TimestampField" "le" now()
@REQ-WA103-QM7 @bronze @2.4.9 @queryability-endorsement
@REQ-WA103-QM7 @bronze @2.4.9 @filterability-endorsement
Scenario: Support Single Value Lookups
When a GET request is made to the resolved Url in "REQ-WA103-QM7"
Then the server responds with a status code of 200
@ -190,10 +189,59 @@ Feature: Web API Server 1.0.2 Certification
And the response has results
And Single Valued Enumeration Data in "Parameter_SingleValueLookupField" has "Parameter_SingleLookupValue"
@REQ-WA103-QM8 @bronze @2.4.10 @queryability-endorsement
@REQ-WA103-QM8 @bronze @2.4.10 @filterability-endorsement
Scenario: Support Multi Value Lookups
When a GET request is made to the resolved Url in "REQ-WA103-QM8"
Then the server responds with a status code of 200
And the response is valid JSON
And the response has results
And Multiple Valued Enumeration Data in "Parameter_MultipleValueLookupField" has "Parameter_MultipleLookupValue1"
@REQ-WA103-QM8.2 @bronze @2.4.10 @filterability-endorsement
Scenario: Support Multi Value Lookups multiple values
When a GET request is made to the resolved Url in "REQ-WA103-QM8.2"
Then the server responds with a status code of 200
And the response is valid JSON
And the response has results
And Multiple Valued Enumeration Data in "Parameter_MultipleValueLookupField" has "Parameter_MultipleLookupValue1"
And Multiple Valued Enumeration Data in "Parameter_MultipleValueLookupField" has "Parameter_MultipleLookupValue2"
@REQ-WA103-QO8 @bronze @2.4.4 @filterability-endorsement
Scenario: Query Support: $filter - Comparison: has
When a GET request is made to the resolved Url in "REQ-WA103-QO8"
Then the server responds with a status code of 200
And the response is valid JSON
And the response has results
And Single Valued Enumeration Data in "Parameter_FilterHasField" has "Parameter_FilterHasValue"
@REQ-WA103-QO28.1 @bronze @2.4.4 @sortability-endorsement
Scenario: Query Support: $orderby asc filtered
When a GET request is made to the resolved Url in "REQ-WA103-QO28.1"
Then the server responds with a status code of 200
And the response is valid JSON
And the response has results
And DateTimeOffset data in "Parameter_TimestampField" is sorted in "asc" order
@REQ-WA103-QO28.2 @bronze @2.4.4 @sortability-endorsement
Scenario: Query Support: $orderby asc no filter
When a GET request is made to the resolved Url in "REQ-WA103-QO28.2"
Then the server responds with a status code of 200
And the response is valid JSON
And the response has results
And DateTimeOffset data in "Parameter_TimestampField" is sorted in "asc" order
@REQ-WA103-QO28.3 @bronze @2.4.4 @sortability-endorsement
Scenario: Query Support: $orderby desc filtered
When a GET request is made to the resolved Url in "REQ-WA103-QO28.3"
Then the server responds with a status code of 200
And the response is valid JSON
And the response has results
And DateTimeOffset data in "Parameter_TimestampField" is sorted in "desc" order
@REQ-WA103-QO28.4 @bronze @2.4.4 @sortability-endorsement
Scenario: Query Support: $orderby desc no filter
When a GET request is made to the resolved Url in "REQ-WA103-QO28.4"
Then the server responds with a status code of 200
And the response is valid JSON
And the response has results
And DateTimeOffset data in "Parameter_TimestampField" is sorted in "desc" order

View File

@ -330,7 +330,6 @@ public class WebAPIServer_1_0_2 implements En {
* validate JSON wrapper
*/
And("^the response is valid JSON$", () -> {
oDataRawResponse.get().getRawResponse().toString();
assertTrue(Utils.isValidJson(responseData.get()));
LOG.info("Response is valid JSON!");
@ -403,7 +402,7 @@ public class WebAPIServer_1_0_2 implements En {
*/
And("^the response has singleton results in \"([^\"]*)\"", (String parameterFieldName) -> {
String value = Settings.resolveParametersString(parameterFieldName, settings);
boolean isPresent = from(responseData.get()).get() != null && value != null;
boolean isPresent = from(responseData.get()).get() != null;
LOG.info("Response value is: " + value);
LOG.info("IsPresent: " + isPresent);
assertTrue(isPresent);
@ -536,6 +535,10 @@ public class WebAPIServer_1_0_2 implements En {
});
});
/*
* Multi-valued enumerations testing.
* TODO: turn array into JSON array and parse values from there
*/
And("^Multiple Valued Enumeration Data in \"([^\"]*)\" has \"([^\"]*)\"$", (String parameterFieldName, String parameterAssertedValue) -> {
String fieldName = Settings.resolveParametersString(parameterFieldName, settings);
AtomicReference<String> fieldValue = new AtomicReference<>();
@ -551,9 +554,43 @@ public class WebAPIServer_1_0_2 implements En {
result.set(fieldValue.get().contains(assertedValue.get()));
LOG.info("Assert True: " + fieldValue.get() + " has " + assertedValue.get() + " ==> " + result.get());
assertTrue(result.get());
});
});
/*
* Date comparison ordering (asc, desc).
*/
And("^DateTimeOffset data in \"([^\"]*)\" is sorted in \"([^\"]*)\" order$", (String parameterFieldName, String parameterOrderByDirection) -> {
String fieldName = Settings.resolveParametersString(parameterFieldName, settings);
final String ASC = "asc", DESC = "desc";
AtomicReference<String> orderBy = new AtomicReference<>(parameterOrderByDirection.toLowerCase());
assertTrue(orderBy.get().equals(ASC) || orderBy.get().equals(DESC));
//used to store the last value for comparisons
AtomicReference<Timestamp> initialValue = new AtomicReference<>();
AtomicReference<Timestamp> currentValue = new AtomicReference<>();
AtomicInteger count = new AtomicInteger(0);
from(responseData.get()).getList(JSON_VALUE_PATH, HashMap.class).forEach(item -> {
try {
if (count.get() == 0) {
initialValue.set(Utils.parseTimestampFromEdmDateTimeOffsetString(item.get(fieldName).toString()));
} else {
currentValue.set(Utils.parseTimestampFromEdmDateTimeOffsetString(item.get(fieldName).toString()));
if (orderBy.get().equals(ASC)) {
assertTrue(Utils.compare(initialValue.get(), Operators.LESS_THAN_OR_EQUAL, currentValue.get()));
} else if (orderBy.get().equals(DESC)){
assertTrue(Utils.compare(initialValue.get(), Operators.GREATER_THAN_OR_EQUAL, currentValue.get()));
}
initialValue.set(currentValue.get());
}
count.getAndIncrement();
} catch (EdmPrimitiveTypeException ptex) {
LOG.error("ERROR: exception thrown parsing Timestamp from given string." + ptex);
fail();
}
});
});
}
@ -767,7 +804,7 @@ public class WebAPIServer_1_0_2 implements En {
* Parses the given edmDateTimeOffsetString into a Java Instant (the type expected by the Olingo type converter).
* @param edmDateTimeOffsetString string representation of an Edm DateTimeOffset to parse.
* @return the corresponding Instant value.
* @throws EdmPrimitiveTypeException
* @throws EdmPrimitiveTypeException thrown if given value cannot be parsed.
*/
private static Timestamp parseTimestampFromEdmDateTimeOffsetString(String edmDateTimeOffsetString) throws EdmPrimitiveTypeException {
return EdmDateTimeOffset.getInstance().valueOfString(edmDateTimeOffsetString, true, null, null, null, null, Timestamp.class);
@ -777,7 +814,7 @@ public class WebAPIServer_1_0_2 implements En {
* Parses the given edmDateString into a Java Timestamp.
* @param edmDateString the date string to convert.
* @return the corresponding Timestamp value.
* @throws EdmPrimitiveTypeException
* @throws EdmPrimitiveTypeException thrown if given value cannot be parsed.
*/
private static Timestamp parseTimestampFromEdmDateString(String edmDateString) throws EdmPrimitiveTypeException {
return EdmDate.getInstance().valueOfString(edmDateString, true, null, null, null, null, Timestamp.class);
@ -787,7 +824,7 @@ public class WebAPIServer_1_0_2 implements En {
* Parses the given edmDateString into a Java Time.
* @param edmTimeOfDayOffsetString the date string to convert.
* @return the corresponding Time value.
* @throws EdmPrimitiveTypeException
* @throws EdmPrimitiveTypeException thrown if given value cannot be parsed.
*/
private static Time parseTimeOfDayFromEdmTimeOfDayString(String edmTimeOfDayOffsetString) throws EdmPrimitiveTypeException {
return EdmTimeOfDay.getInstance().valueOfString(edmTimeOfDayOffsetString, true, null, null, null, null, Time.class);
@ -797,7 +834,7 @@ public class WebAPIServer_1_0_2 implements En {
* Parses the given DateTimeOffsetString into a Java Time.
* @param edmDateTimeOffsetString the DateTimeOffsetString to parse.
* @return the corresponding Time value.
* @throws EdmPrimitiveTypeException
* @throws EdmPrimitiveTypeException thrown if given value cannot be parsed.
*/
private static Time parseTimeOfDayFromEdmDateTimeOffsetString(String edmDateTimeOffsetString) throws EdmPrimitiveTypeException {
return EdmDateTimeOffset.getInstance().valueOfString(edmDateTimeOffsetString, true, null, null, null, null, Time.class);
@ -807,7 +844,7 @@ public class WebAPIServer_1_0_2 implements En {
* Parses the given edmDateString into a Java Date
* @param edmDateString the date string to convert.
* @return the corresponding Date value.
* @throws EdmPrimitiveTypeException
* @throws EdmPrimitiveTypeException thrown if given value cannot be parsed.
*/
private static Date parseDateFromEdmDateString(String edmDateString) throws EdmPrimitiveTypeException {
return EdmDate.getInstance().valueOfString(edmDateString, true, null, null, null, null, Date.class);
@ -817,6 +854,7 @@ public class WebAPIServer_1_0_2 implements En {
* Parses the given edmDateTimeOffsetString into a Java Date
* @param edmDateTimeOffsetString string representation of an Edm DateTimeOffset to parse.
* @return the corresponding Date value.
* @throws EdmPrimitiveTypeException thrown if given value cannot be parsed.
*/
private static Date parseDateFromEdmDateTimeOffsetString(String edmDateTimeOffsetString) throws EdmPrimitiveTypeException {
return EdmDateTimeOffset.getInstance().valueOfString(edmDateTimeOffsetString, true, null, null, null, null, Date.class);