updated generic.resoscript, and also addded versioning. Added first test

This commit is contained in:
Joshua Darnell 2020-03-09 18:10:59 -07:00
parent 16c34664d0
commit 467c06ea6a
7 changed files with 343 additions and 127 deletions

View File

@ -454,10 +454,10 @@ A sample of the runtime terminal output follows:
```gherkin
> Task :testWebApiServer_1_0_2_Platinum
@REQ-WA103-END3 @core @2.4.1 @core-endorsement @metadata
@REQ-WA103-END3 @core @x.y.z @core-endorsement @metadata
Scenario: Request and Validate Server Metadata
Using RESOScript: /path/to/your.resoscript
Using RESOScript: /path/to/your.resocript
Given a RESOScript file was provided
RESOScript loaded successfully!
@ -467,23 +467,26 @@ A sample of the runtime terminal output follows:
Service root is: https://api.server.com
And an OData client was successfully created from the given RESOScript
Fetching Edm with OData Client from: https://api.server.com/$metadata
Found Default Entity Container: 'Default'
When a default entity container exists for the service root in "ClientSettings_WebAPIURI"
Request URI: https://api.server.com/$metadata?$format=application/xml
Request succeeded...185032 bytes received.
When a GET request is made to the resolved Url in "REQ-WA103-END3"
Asserted Response Code: 200, Server Response Code: 200
Then the server responds with a status code of 200
Edm Metadata is valid!
And the Edm metadata returned by the server are valid
Fetching XMLMetadata with OData Client from: https://api.server.com/$metadata
XML Metadata retrieved from: https://api.server.com
And XML Metadata are requested from the service root in "ClientSettings_WebAPIURI"
Response is valid XML!
And the response is valid XML
XML Metadata is valid!
And the XML metadata returned by the server are valid
Fetching Edm with OData Client from: https://api.server.com/$metadata
Found Default Entity Container: 'Default'
And a default entity container exists for the service root in "ClientSettings_WebAPIURI"
Edm Metadata is valid!
And the Edm metadata returned by the server are valid
Found EntityContainer for the given resource: 'Property'
And the metadata contains the "Parameter_EndpointResource" resource
@ -500,9 +503,8 @@ A sample of the runtime terminal output follows:
1 Scenarios (1 passed)
10 Steps (10 passed)
0m3.071s
11 Steps (11 passed)
0m3.342s
```
This shows configuration parameters, requests, and responses in a lightweight-manner.

Binary file not shown.

View File

@ -11,11 +11,17 @@
Contact josh@reso.org with further questions.
-->
<!DOCTYPE OutputScript [
<!ELEMENT OutputScript (ClientSettings|Parameters|Requests)*>
<!ELEMENT ClientSettings (WebAPIURI|AuthenticationType|BearerToken|ClientScope|Version|Preauthenticate)*>
<!ELEMENT OutputScript (RESOScriptVersion|ClientSettings|Parameters|Requests)*>
<!ELEMENT RESOScriptVersion (#PCDATA)>
<!ELEMENT ClientSettings
(RESOScriptVersion|WebAPIURI|AuthenticationType|
BearerToken|ClientIdentification|ClientSecret|TokenURI|ClientScope|Version|Preauthenticate)*>
<!ELEMENT WebAPIURI (#PCDATA)>
<!ELEMENT AuthenticationType (#PCDATA)>
<!ELEMENT BearerToken (#PCDATA)>
<!ELEMENT ClientIdentification (#PCDATA)>
<!ELEMENT ClientSecret (#PCDATA)>
<!ELEMENT TokenURI (#PCDATA)>
<!ELEMENT ClientScope (#PCDATA)>
<!ELEMENT Version (#PCDATA)>
<!ELEMENT Preauthenticate (#PCDATA)>
@ -36,60 +42,142 @@
WebAPIReference CDATA #REQUIRED>
]>
<!--
############################################################
TODO: this document will be updated with language
matching the OAuth 2.0 Specification and ClientSettings
will be removed.
See:
https://tools.ietf.org/html/rfc8252
Watch for subsequent changes to this file.
ClientSettings will be converted to Parameters forthwith.
############################################################-->
<OutputScript>
<!-- TODO: deprecate ClientSettings and move them to Parameters -->
<!--
############################################################
Metadata
############################################################-->
<!-- The current version of this RESOScript -->
<RESOScriptVersion>1.0.4</RESOScriptVersion>
<!--
############################################################
Client Settings
TODO: deprecate ClientSettings and move them to Parameters
############################################################-->
<ClientSettings>
<!-- URLS -->
<WebAPIURI><!--REQUIRED: URI of your Web API Service Root goes here --></WebAPIURI>
<!-- Credentials -->
<AuthenticationType>Authorization Code</AuthenticationType>
<BearerToken><!-- REQUIRED: Your BearerToken goes here --></BearerToken>
<ClientScope>all</ClientScope>
<Version>Web API/1.0</Version>
<Preauthenticate>FALSE</Preauthenticate>
<!-- AuthenticationType
This is the OAuth2 grant_type.
Use "authorization_code" for BearerToken and "client_credentials" for Client Credentials.
See:
* https://www.oauth.com/oauth2-servers/access-tokens/authorization-code-request/
* https://www.oauth.com/oauth2-servers/access-tokens/client-credentials/
-->
<AuthenticationType>authorization_code</AuthenticationType>
<!-- Grant Type: authorization_code-->
<BearerToken><!-- REQUIRED: Your BearerToken goes here if using Access Tokens --></BearerToken>
<!-- Grant Type: client_credentials -->
<ClientIdentification><!-- REQUIRED: Your client_id value if using Client Credentials--></ClientIdentification>
<ClientSecret><!-- REQUIRED: Your client_secret value if using Client Credentials--></ClientSecret>
<TokenURI><!-- REQUIRED: Your token endpoint URI--></TokenURI>
<ClientScope>
<!--OPTIONAL - your client scope. See: https://www.oauth.com/oauth2-servers/access-tokens/client-credentials/ -->
</ClientScope>
</ClientSettings>
<!--
############################################################
Parameters Section - add your testing variables here
############################################################-->
<Parameters>
<!--
############################################################
Service Configuration
############################################################-->
<!-- REQUIRED: The DataSystems endpoint being tested
<!-- REQUIRED: Core - The DataSystems endpoint being tested
NOTE: the FULL DataSystems URL is required as it might not be relative to the Service Root.
This will likely change in future revisions. -->
<Parameter Name="EndpointDataSystem" Value="REQUIRED: YOUR DATA SYSTEMS ENDPOINT GOES HERE" />
<!-- REQUIRED: The name of the resource being tested -->
<!-- REQUIRED: Core - The name of the resource being tested -->
<Parameter Name="EndpointResource" Value="REQUIRED: YOUR RESOURCE GOES HERE, FOR EXAMPLE 'Property'" />
<!-- HTTP Code Testing -->
<!--
############################################################
Required Fields and Values
############################################################-->
<!-- REQUIRED: 200 Response OK -->
<Parameter Name="200_OK" Value="*Parameter_EndpointResource*" />
<!-- Note: some of the required values already have sample values provided. See later sections for their values.-->
<!-- REQUIRED: 400 Bad Request - Requires Full URL & Separate Login Credentials -->
<Parameter Name="400BadRequest" Value="*Parameter_EndpointResource*?$filter=BadField eq 'SoBad'" />
<!-- REQUIRED: 403 Forbidden -->
<Parameter Name="403Forbidden" Value="Teams" />
<!-- REQUIRED: 404 Not Found -->
<Parameter Name="404NotFound" Value="ResourceNotFound" />
<!-- REQUIRED: 501 Not Implemented -->
<Parameter Name="501NotImplemented" Value="*Parameter_EndpointResource*?$search=red OR blue" />
<!-- REQUIRED: Substitute key name from your Resource here, either Key or KeyNumeric -->
<!-- REQUIRED: Core - Substitute key name from your Resource here, either Key or KeyNumeric -->
<Parameter Name="KeyOrKeyNumericField" Value="ListingKey" />
<!-- REQUIRED: Provide a value for the KeyOrKeyNumeric from your server -->
<!-- REQUIRED: Core - Provide a value for the KeyOrKeyNumeric from your server -->
<Parameter Name="KeyOrKeyNumericValue" Value="REQUIRED: YOUR KeyOrKeyNumericValue GOES HERE" />
<!-- For Top, Skip, and Sort Testing -->
<Parameter Name="TopCount" Value="5" />
<Parameter Name="SortCount" Value="20" />
<!-- Integer Field for eq, ne, gt, ge, lt, le testing -->
<!-- Type="Edm.Int16" or Type="Edm.Int32" or Type="Edm.Int64" for non-lookup fields -->
<!-- REQUIRED: Core - Integer Field. Should be one of: Type="Edm.Int16", Type="Edm.Int32", or Type="Edm.Int64" -->
<Parameter Name="FilterIntegerField" Value="BedroomsTotal" />
<!-- REQUIRED: Core - Enumerated Field for Single-Value Testing -->
<Parameter Name="SingleValueLookupField" Value="PropertyType" />
<Parameter Name="SingleLookupValue" Value="Residential" />
<Parameter Name="SingleValueLookupNamespace" Value="PropertyEnums.PropertyType" />
<!-- REQUIRED: Core - Enumerated Field for Multi-value testing -->
<Parameter Name="MultipleValueLookupField" Value="Appliances" />
<Parameter Name="MultipleValueLookupNamespace" Value="PropertyEnums.Appliances" />
<Parameter Name="MultipleLookupValue1" Value="Refrigerator" />
<Parameter Name="MultipleLookupValue2" Value="Stacked" />
<!-- REQUIRED: Bronze - Date Field for comparisons. Should be Type="Edm.Date" -->
<Parameter Name="DateField" Value="ListingContractDate" />
<Parameter Name="TimestampField" Value="ModificationTimestamp" />
<!-- REQUIRED: Platinum - String Field for comparisons. Should be Type="Edm.String" -->
<Parameter Name="StringField" Value="StreetName" />
<!-- REQUIRED: Platinum - Expand Testing -->
<Parameter Name="ExpandField" Value="ListAgent" />
<!-- REQUIRED: Platinum - GeoSpatial Testing -->
<Parameter Name="GeoSpatialLatitudeField" Value="Latitude" />
<Parameter Name="GeoSpatialLongitudeField" Value="Longitude" />
<Parameter Name="GeoSpatialField" Value="Coordinates" />
<Parameter Name="GeoSpatialValue" Value="REQUIRED: YOUR COORDINATES GO HERE in 'Longitude Latitude' format" /> <!-- "Longitude Latitude" -->
<!-- REQUIRED: New Fields for WS103 Testing -->
<Parameter Name="ValueField" Value="AboveGradeFinishedArea" />
<Parameter Name="CastField" Value="AboveGradeFinishedArea" />
<Parameter Name="CastFieldValue" Value="YOUR CastFieldValue GOES HERE, FOR EXAMPLE 1200" />
<Parameter Name="ConcatFieldOne" Value="StreetName" />
<Parameter Name="ConcatFieldOneValue" Value="REQUIRED: Your OneValue GOES HERE>" />
<Parameter Name="ConcatFieldTwo" Value="City" />
<Parameter Name="ConcatFieldTwoValue" Value="YOUR TwoValue GOES HERE" />
<Parameter Name="ConcatFieldBothValue" Value="Your 'OneValue: TwoValue' GOES HERE" /> <!-- format 'OneValue: TwoValue' -->
<!--
############################################################
Sample Field Values
############################################################-->
<!-- FilterIntegerField Sample Values-->
<Parameter Name="FilterIntegerValueLow" Value="9" />
<Parameter Name="FilterIntegerValueHigh" Value="15" />
<Parameter Name="FilterIntegerNotFound" Value="-1" />
@ -99,71 +187,71 @@
<Parameter Name="FilterNotValue" Value="-1" />
<!-- Enumerated Field for "has" testing -->
<Parameter Name="FilterHasField" Value="PropertyType" />
<Parameter Name="FilterHasValue" Value="Residential" />
<Parameter Name="FilterHasLookupNamespace" Value="PropertyEnums.PropertyType" />
<Parameter Name="FilterHasField" Value="*Parameter_SingleValueLookupField*" />
<Parameter Name="FilterHasValue" Value="*Parameter_SingleValueLookupValue*" />
<Parameter Name="FilterHasLookupNamespace" Value="*Parameter_SingleValueLookupNamespace*" />
<Parameter Name="FilterHasLookupValue" Value="*Parameter_FilterHasLookupNamespace*'*Parameter_FilterHasValue*'" />
<!-- Enumerated Field for SingleValue/Multi-value testing -->
<Parameter Name="SingleValueLookupField" Value="PropertyType" />
<Parameter Name="SingleLookupValue" Value="Residential" />
<Parameter Name="SingleValueLookupNamespace" Value="PropertyEnums.PropertyType" />
<Parameter Name="MultipleValueLookupField" Value="Appliances" />
<Parameter Name="MultipleValueLookupNamespace" Value="PropertyEnums.Appliances" />
<Parameter Name="MultipleLookupValue1" Value="Refrigerator" />
<Parameter Name="MultipleLookupValue2" Value="Stacked" />
<!-- For Expand Testing -->
<Parameter Name="ExpandField" Value="ListAgent" />
<!-- For Geo-spatial Testing -->
<Parameter Name="GeoSpatialLatitudeField" Value="Latitude" />
<Parameter Name="GeoSpatialLongitudeField" Value="Longitude" />
<Parameter Name="GeoSpatialField" Value="Coordinates" />
<Parameter Name="GeoSpatialValue" Value="REQUIRED: YOUR COORDINATES GO HERE in 'Longitude Latitude' format" /> <!-- "Longitude Latitude" -->
<Parameter Name="GeoSpatialDistanceValue" Value="100" />
<!--String Fields for testing -->
<!-- Type="Edm.String" -->
<Parameter Name="ContainsField" Value="StreetName" />
<!-- Platinum - String Fields for testing -->
<Parameter Name="ContainsField" Value="*Parameter_StringField*" />
<Parameter Name="ContainsValue" Value="M" />
<Parameter Name="EndsWithField" Value="StreetName" />
<Parameter Name="EndsWithField" Value="*Parameter_StringField*" />
<Parameter Name="EndsWithValue" Value="Rd" />
<Parameter Name="StartsWithField" Value="StreetName" />
<Parameter Name="StartsWithField" Value="*Parameter_StringField*" />
<Parameter Name="StartsWithValue" Value="M" />
<Parameter Name="ToLowerField" Value="StreetName" />
<Parameter Name="ToLowerField" Value="*Parameter_StringField*" />
<Parameter Name="ToLowerValue" Value="main" />
<Parameter Name="ToUpperField" Value="StreetName" />
<Parameter Name="ToUpperField" Value="*Parameter_StringField*" />
<Parameter Name="ToUpperValue" Value="MAIN" />
<!-- REQUIRED: Date Fields for testing -->
<Parameter Name="DateField" Value="ListingContractDate" />
<!-- Gold and Platinum: Date Fields for testing -->
<Parameter Name="DateTimeValue" Value="2018-12-31T23:55:55-09:00" />
<Parameter Name="DateValue" Value="2018-12-31" />
<Parameter Name="YearValue" Value="2018" />
<Parameter Name="MonthValue" Value="12" />
<Parameter Name="DayValue" Value="31" />
<Parameter Name="TimestampField" Value="ModificationTimestamp" />
<Parameter Name="TimeValue" Value="23:55:55" />
<Parameter Name="HourValue" Value="23" />
<Parameter Name="MinuteValue" Value="55" />
<Parameter Name="SecondValue" Value="55" />
<Parameter Name="FractionalValue" Value="30" />
<!-- REQUIRED: New Fields for WS103 Testing -->
<Parameter Name="ValueField" Value="AboveGradeFinishedArea" />
<Parameter Name="CastField" Value="AboveGradeFinishedArea" />
<Parameter Name="CastFieldType" Value="Edm.String" />
<Parameter Name="CastFieldValue" Value="YOUR CastFieldValue GOES HERE, FOR EXAMPLE 1200" />
<Parameter Name="ConcatFieldOne" Value="StreetName" />
<Parameter Name="ConcatFieldOneValue" Value="YOUR OneValue GOES HERE>" />
<Parameter Name="ConcatFieldTwo" Value="City" />
<Parameter Name="ConcatFieldTwoValue" Value="YOUR TwoValue GOES HERE" />
<Parameter Name="ConcatFieldBothValue" Value="Your 'OneValue: TwoValue' GOES HERE" /> <!-- format 'OneValue: TwoValue' -->
<!-- Platinum - GeoSpatial query values -->
<Parameter Name="GeoSpatialDistanceValue" Value="100" />
<!-- Computed OData $select list - do not change -->
<!--
############################################################
HTTP Code Testing
############################################################-->
<!-- 200 Response OK: This should always work! No need to change it -->
<Parameter Name="200_OK" Value="*Parameter_EndpointResource*" />
<!-- REQUIRED: 400 Bad Request - Adjust to something that produces a 400 response if this doesn't work -->
<Parameter Name="400BadRequest" Value="*Parameter_EndpointResource*?$filter=BadField eq 'SoBad'" />
<!-- REQUIRED: 403 Forbidden - Set this to a restricted resource for the given credentials -->
<Parameter Name="403Forbidden" Value="Teams" />
<!-- REQUIRED: 404 Not Found - You shouldn't need to change this -->
<Parameter Name="404NotFound" Value="ResourceNotFound" />
<!-- REQUIRED: 501 Not Implemented - Set this to an OData query that hasn't been implemented on your server -->
<Parameter Name="501NotImplemented" Value="*Parameter_EndpointResource*?$search=red OR blue" />
<!--
############################################################
Constants and Computed Values - Do Not Change
############################################################-->
<!-- For Top, Skip, and Sort Testing -->
<Parameter Name="TopCount" Value="5" />
<Parameter Name="SortCount" Value="20" />
<!-- New Values for WS103 Testing -->
<Parameter Name="CastFieldType" Value="Edm.String" />
<!-- Computed OData $select list -->
<Parameter Name="SelectList"
Value="*Parameter_KeyOrKeyNumericField*,*Parameter_FilterIntegerField*,*Parameter_ContainsField*,*Parameter_FilterHasField*,*Parameter_DateField*" />
@ -172,19 +260,21 @@
<Parameter Name="MultipleValueLookupValue1" Value="*Parameter_MultipleValueLookupNamespace*'*Parameter_MultipleLookupValue1*'"/>
<Parameter Name="MultipleValueLookupValue2" Value="*Parameter_MultipleValueLookupNamespace*'*Parameter_MultipleLookupValue2*'" />
<Parameter Name="OptionalMetadataFormatParameter" Value="?$format=application/xml" />
<!--
############################################################
Optional Parameters. You should not need these
############################################################-->
<!-- OPTIONAL: System Specific Additional Required Parameters for Queries. Leave Blank if none. -->
<Parameter Name="RequiredParameters" Value="" />
<Parameter Name="RequiredParametersFilter" Value="" />
<!-- Note: you may need to use Value="?$format=application/xml" on your server -->
<Parameter Name="OptionalMetadataFormatParameter" Value="" />
</Parameters>
<Requests>
<!-- NOTE: the query in this test is no longer being used for automated testing,
was originally: Url="*ClientSettings_WebAPIURI*/$metadata*Parameter_OptionalMetadataFormatParameter*"-->
<Request
TestDescription="Metadata Endpoint"
RequirementId="REQ-WA103-END3"
@ -192,7 +282,7 @@
Capability="Core"
WebAPIReference=""
OutputFile="REQ-WA103-END3.metadata.xml"
Url=""
Url="*ClientSettings_WebAPIURI*/$metadata*Parameter_OptionalMetadataFormatParameter*"
/>
<Request

View File

@ -8,11 +8,12 @@ Feature: Web API Server 1.0.2 Certification
@REQ-WA103-END3 @core @x.y.z @core-endorsement @metadata
Scenario: Request and Validate Server Metadata
When a default entity container exists for the service root in "ClientSettings_WebAPIURI"
When a GET request is made to the resolved Url in "REQ-WA103-END3"
Then the server responds with a status code of 200
And the Edm metadata returned by the server are valid
And XML Metadata are requested from the service root in "ClientSettings_WebAPIURI"
And the response is valid XML
And the XML metadata returned by the server are valid
And a default entity container exists for the service root in "ClientSettings_WebAPIURI"
And the Edm metadata returned by the server are valid
And the metadata contains the "Parameter_EndpointResource" resource
And resource metadata for "Parameter_EndpointResource" contains the fields in "Parameter_SelectList"
@ -368,4 +369,14 @@ Feature: Web API Server 1.0.2 Certification
And the response is valid JSON
And the response has results
And String data in "Parameter_ToUpperField" "toupper" "Parameter_ToUpperValue"
@REQ-WA103-QO29 @platinum @2.4.4 @expandability-endorsement
Scenario: Query Support: $expand
When a GET request is made to the resolved Url in "REQ-WA103-QO29"
Then the server responds with a status code of 200
And the response is valid JSON
And the response has results
And data are present in fields contained within "Parameter_SelectList"
And data are present within "Parameter_ExpandField"
And an OData NavigationProperty exists for the given "Parameter_EndpointResource"
And the expanded data were found in the related resource

View File

@ -4,26 +4,27 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.POJONode;
import io.cucumber.java8.En;
import io.restassured.response.Response;
import io.restassured.response.ValidatableResponse;
import io.restassured.specification.RequestSpecification;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.olingo.client.api.communication.ODataClientErrorException;
import org.apache.olingo.client.api.communication.request.retrieve.ODataRawRequest;
import org.apache.olingo.client.api.communication.response.ODataRawResponse;
import org.apache.olingo.client.api.communication.response.ODataRetrieveResponse;
import org.apache.olingo.client.api.domain.ClientEntitySet;
import org.apache.olingo.client.api.edm.xml.XMLMetadata;
import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainer;
import org.apache.olingo.commons.api.edm.provider.CsdlNavigationProperty;
import org.apache.olingo.commons.api.edm.provider.CsdlProperty;
import org.apache.olingo.commons.api.format.ContentType;
import org.reso.commander.Commander;
import org.reso.commander.TestUtils;
import org.reso.models.ClientSettings;
import org.reso.models.Request;
import org.reso.models.Settings;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.net.URI;
import java.sql.Time;
@ -44,21 +45,45 @@ import static org.reso.commander.TestUtils.Operators.*;
public class WebAPIServer_1_0_2 implements En {
private static final Logger LOG = LogManager.getLogger(WebAPIServer_1_0_2.class);
private static Settings settings;
//container to hold retrieved metadata for later comparisons
private static AtomicReference<XMLMetadata> xmlMetadata = new AtomicReference<>();
private static AtomicReference<Edm> edm = new AtomicReference<>();
private Response response;
private ValidatableResponse json;
private RequestSpecification request;
private String serviceRoot, bearerToken, clientId, clientSecret, authorizationUri, tokenUri, redirectUri, scope;
private String pathToRESOScript;
/**
* Accessors used for running one-off tests that have dependent metadata tests
* @param commander the commander instance to make the request with.
* @return the XMLMetadata for the given request.
*/
private static XMLMetadata getXMLMetadata(Commander commander) {
if (xmlMetadata.get() == null) {
xmlMetadata.set(commander.getXMLMetadata());
}
return xmlMetadata.get();
}
/**
* Accessors used for running one-off tests that have dependent metadata tests
* @param commander the commander instance to make the request with.
* @return the Edm for the given request.
*/
private static Edm getEdmMetadata(Commander commander) {
if (edm.get() == null) {
edm.set(commander.getEdm());
}
return edm.get();
}
public WebAPIServer_1_0_2() {
//TODO: split into separate test files and parallelize to remove the need for Atomic "globals"
AtomicReference<Commander> commander = new AtomicReference<>();
AtomicReference<ODataRawResponse> oDataRawResponse = new AtomicReference<>();
AtomicReference<Request> request = new AtomicReference<>();
AtomicReference<URI> requestUri = new AtomicReference<>();
AtomicReference<Integer> responseCode = new AtomicReference<>();
AtomicReference<String> responseData = new AtomicReference<>();
AtomicReference<String> initialResponseData = new AtomicReference<>(); //used if two result sets need to be compared
@ -98,10 +123,10 @@ public class WebAPIServer_1_0_2 implements En {
* Executes HTTP GET request and sets the expected local variables.
* Handles exceptions and sets response codes.
*/
Function<URI, Void> executeGetRequest = (URI requestUri) -> {
LOG.info("Request URI: " + requestUri);
Function<URI, Void> executeGetRequest = (URI uri) -> {
LOG.info("Request URI: " + uri);
try {
rawRequest.set(commander.get().getClient().getRetrieveRequestFactory().getRawRequest(requestUri));
rawRequest.set(commander.get().getClient().getRetrieveRequestFactory().getRawRequest(uri));
oDataRawResponse.set(rawRequest.get().execute());
responseData.set(TestUtils.convertInputStreamToString(oDataRawResponse.get().getRawResponse()));
serverODataHeaderVersion.set(oDataRawResponse.get().getHeader(HEADER_ODATA_VERSION).toString());
@ -204,9 +229,12 @@ public class WebAPIServer_1_0_2 implements En {
* XMLMetadata Validator
*/
And("^the XML metadata returned by the server are valid$", () -> {
assertNotNull("ERROR: No XML Metadata Exists!", xmlMetadata.get());
assertNotNull("ERROR: No Response Data exists to convert to XML Metadata!", responseData.get());
try {
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(responseData.get().getBytes());
xmlMetadata.set(commander.get().getClient().getDeserializer(ContentType.APPLICATION_XML).toMetadata(byteArrayInputStream));
boolean isValid = commander.get().validateMetadata(xmlMetadata.get());
LOG.info("XML Metadata is " + (isValid ? "valid" : "invalid") + "!");
assertTrue(isValid);
@ -316,9 +344,9 @@ public class WebAPIServer_1_0_2 implements En {
initialResponseData.set(responseData.get());
//TODO: convert to OData filter factory
URI requestUri = Commander.prepareURI(Settings.resolveParameters(settings.getRequests().get(requirementId), settings).getUrl() + "&$skip=" + skipCount);
requestUri.set(Commander.prepareURI(Settings.resolveParameters(settings.getRequests().get(requirementId), settings).getUrl() + "&$skip=" + skipCount));
executeGetRequest.apply(requestUri);
executeGetRequest.apply(requestUri.get());
} catch (Exception ex) {
fail(ex.getMessage());
}
@ -353,8 +381,8 @@ public class WebAPIServer_1_0_2 implements En {
//reset local state each time a get request is run
resetRequestState.run();
URI requestUri = Commander.prepareURI(Settings.resolveParameters(settings.getRequests().get(requirementId), settings).getUrl());
executeGetRequest.apply(requestUri);
requestUri.set(Commander.prepareURI(Settings.resolveParameters(settings.getRequests().get(requirementId), settings).getUrl()));
executeGetRequest.apply(requestUri.get());
} catch (Exception ex) {
LOG.debug("Exception was thrown in " + this.getClass() + ": " + ex.toString());
}
@ -861,5 +889,61 @@ public class WebAPIServer_1_0_2 implements En {
fail(ex.getMessage());
}
});
/*
* Tests whether a navigation property can be found in the given resource name.
*/
And("^an OData NavigationProperty exists for the given \"([^\"]*)\"$", (String parameterEndpointResource) -> {
String resourceName = Settings.resolveParametersString(parameterEndpointResource, settings);
List<CsdlNavigationProperty> navigationProperties
= TestUtils.findNavigationPropertiesForEntityTypeName(getEdmMetadata(commander.get()), getXMLMetadata(commander.get()), resourceName);
assertTrue("ERROR: no navigation properties found for the given '" + resourceName + "' resource!",
navigationProperties.size() > 0);
LOG.info("Found the following Navigation Properties:");
navigationProperties.forEach(csdlNavigationProperty -> {
LOG.info("\tName: " + csdlNavigationProperty.getName());
LOG.info("\tType: " + csdlNavigationProperty.getType());
});
});
/*
* Checks to see whether the expanded field has data
*/
And("^data are present within \"([^\"]*)\"$", (String parameterExpandField) -> {
String expandField = Settings.resolveParametersString(parameterExpandField, settings);
assertFalse("ERROR: no expand field found for " + parameterExpandField, expandField.isEmpty());
ClientEntitySet results = commander.get().getClient().getRetrieveRequestFactory().getEntitySetRequest(requestUri.get()).execute().getBody();
LOG.info("Results count is: " + results.getEntities().size());
AtomicInteger counter = new AtomicInteger();
results.getEntities().forEach(clientEntity -> {
LOG.info("\nItem #" + counter.getAndIncrement());
clientEntity.getProperties().forEach(clientProperty -> {
LOG.info("\tField Name: " + clientProperty.getName());
LOG.info("\tField Value: " + clientProperty.getValue().toString());
LOG.info("\tType Name: " + clientProperty.getValue().getTypeName());
LOG.info("\n");
assertNotNull("ERROR: '" + parameterExpandField + "' not found in results!", clientProperty.getName());
assertNotNull("ERROR: data type could not be found for " + clientProperty.getName(), clientProperty.getValue().getTypeName());
});
});
});
/*
* Checks to see whether expanding the EndpointResource on ExpandField produces equivalent records from the corresponding
* resource of the expanded type
*/
And("^the expanded data were found in the related resource$", () -> {
//TODO: this depends on either finding the appropriate navigation property for a given relationship, or having the Expanded resource name
});
}
}

View File

@ -188,7 +188,7 @@ public class Commander {
*/
public Edm getEdm() {
if (edm == null) {
getODataRetrieveEdmResponse().getBody();
edm = getODataRetrieveEdmResponse().getBody();
}
return edm;
}
@ -199,9 +199,12 @@ public class Commander {
* @return XMLMetadata representation of the server metadata.
*/
public XMLMetadata getXMLMetadata() {
EdmMetadataRequest metadataRequest = client.getRetrieveRequestFactory().getMetadataRequest(serviceRoot);
LOG.info("Fetching XMLMetadata with OData Client from: " + metadataRequest.getURI().toString());
return metadataRequest.getXMLMetadata();
if (xmlMetadata == null) {
EdmMetadataRequest metadataRequest = client.getRetrieveRequestFactory().getMetadataRequest(serviceRoot);
LOG.info("Fetching XMLMetadata with OData Client from: " + metadataRequest.getURI().toString());
xmlMetadata = metadataRequest.getXMLMetadata();
}
return xmlMetadata;
}
/**
@ -434,6 +437,10 @@ public class Commander {
return getEntitySet(requestUri, limit, integerVoidFunction);
}
public ClientEntitySet getEntitySet(String requestUri) {
return getEntitySet(requestUri, 1);
}
/**
* Fairly primitive, for now, version of a fetch function.
* TODO: add a function that can write a page at a time.
@ -458,14 +465,12 @@ public class Commander {
if (requestUri != null && requestUri.length() > 0 && preparedUri != null) {
uriBuilder = new URIBuilder(preparedUri);
if (uriBuilder != null) {
if (skip != null && skip > 0) uriBuilder.addParameter("$skip", skip.toString());
if (skip != null && skip > 0) uriBuilder.addParameter("$skip", skip.toString());
URI uri = uriBuilder.build();
LOG.debug("URI created: " + uri.toString());
URI uri = uriBuilder.build();
LOG.debug("URI created: " + uri.toString());
return uri;
}
return uri;
}
} catch (Exception ex) {
LOG.error("ERROR: " + ex.toString());
@ -495,7 +500,7 @@ public class Commander {
} catch (Exception ex) {
//NOTE: sometimes a bad skip link in the payload can cause exceptions...the Olingo library validates the responses.
LOG.error("ERROR: getEntitySet could not continue. " + ex.getCause());
LOG.error("ERROR: getEntitySet could not continue. " + ex.toString());
System.exit(NOT_OK);
} finally {
//trim results size to requested limit

View File

@ -9,6 +9,7 @@ import org.apache.olingo.client.api.edm.xml.XMLMetadata;
import org.apache.olingo.commons.api.edm.Edm;
import org.apache.olingo.commons.api.edm.EdmPrimitiveTypeException;
import org.apache.olingo.commons.api.edm.provider.CsdlEntityContainer;
import org.apache.olingo.commons.api.edm.provider.CsdlNavigationProperty;
import org.apache.olingo.commons.api.edm.provider.CsdlProperty;
import org.apache.olingo.commons.api.edm.provider.CsdlSchema;
import org.apache.olingo.commons.core.edm.primitivetype.EdmDate;
@ -80,6 +81,29 @@ public final class TestUtils {
return schemaForType.getEntityType(entityTypeName).getProperties();
}
/**
* Gets a list of CsdlProperty items for the given entityTypeName.
*
* @param xmlMetadata the metadata to search.
* @param entityTypeName the name of the entityType to search for. MUST be in the default EntityContainer.
* @return a list of CsdlProperty items for the given entityTypeName
* @throws Exception is thrown if the given metadata doesn't contain the given type name.
*/
public static List<CsdlNavigationProperty> findNavigationPropertiesForEntityTypeName(Edm edm, XMLMetadata xmlMetadata, String entityTypeName) {
assertNotNull("ERROR: Edm Cannot be Null!", edm);
assertNotNull("ERROR: XMLMetadata Cannot be Null!", xmlMetadata);
assertNotNull("ERROR: entityTypeName cannot be null!", entityTypeName);
CsdlEntityContainer entityContainer = findDefaultEntityContainer(edm, xmlMetadata);
assertNotNull("ERROR: could not find a default entity container for the given server!", entityContainer);
CsdlSchema schemaForType = xmlMetadata.getSchema(entityContainer.getEntitySet(entityTypeName).getTypeFQN().getNamespace());
assertNotNull("ERROR: could not find type corresponding to given type name: " + entityTypeName, schemaForType);
return schemaForType.getEntityType(entityTypeName).getNavigationProperties();
}
/**
* Returns true if each item in the list is true
*