Skip to content

Commit

Permalink
add scenario for query after new data arrives.
Browse files Browse the repository at this point in the history
  • Loading branch information
serefarikan committed Feb 16, 2018
1 parent 1b66055 commit 5284a5c
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 14 deletions.
Expand Up @@ -35,6 +35,7 @@ public class AqlFeaturesSteps {
private static final String POPULATION_COMPOSITION_SECTION_INSTRUCTION_AQL = "population_composition_section_instruction.aql";
private static final String POPULATION_COMPOSITION_SECTION_OBSERVATION_AQL = "population_composition_section_observation.aql";
private static final String POPULATION_COMPOSITION_SECTION_ACTION_AQL = "population_composition_section_action.aql";
private static final String POPULATION_COMPOSITION_SECTION_ENTRY_AQL = "population_composition_section_entry.aql";
private final String SELECT_COMPLETE_INSTRUCTION_AQL = "select_complete_instruction.aql";
private final String ARCHETYPE_NODE_ID_AND_NAME_PATTERN = "\\[at\\d{4} *, *\\'[\\w\\s]*\\'\\]";
private final String SELECT_COMPLETE_COMPOSITION_AQL = "select_complete_composition.aql";
Expand All @@ -59,6 +60,7 @@ public class AqlFeaturesSteps {

private List<String> _code4HealthTemplateIds;
private List<Map<String, String>> _aqlResultSet;
private List<Map<String, String>> _previousAqlResultSet;
private String _instructionArchetypeNodeId;
private String _observationArchetypeNodeId;
private String _evaluationArchetypeNodeId;
Expand Down Expand Up @@ -373,4 +375,36 @@ public void theResultsShouldIncludeActionInstances() throws Throwable {
_aqlResultSet.forEach(
map -> assertArchetypeNodeIdPrefix(map, "action", ACTION_ARCHETYPE_ID_PREFIX));
}

@When("^An aql query that describes an EHR/COMPOSITION/SECTION/ENTRY structure is created$")
public void anAqlQueryThatDescribesAnEHRCOMPOSITIONSECTIONENTRYStructureIsCreated() throws Throwable {
_aqlQuery = readAqlFile(POPULATION_COMPOSITION_SECTION_ENTRY_AQL);
}

@Then("^The results should include ENTRY instances$")
public void theResultsShouldIncludeENTRYInstances() throws Throwable {
_aqlResultSet = bg.extractAqlResults(bg.getAqlResponse(_aqlQuery));
assertTrue(_aqlResultSet.size() > 0);
}

@And("^The results include ENTRY instances$")
public void theResultsIncludeENTRYInstances() throws Throwable {
theResultsShouldIncludeENTRYInstances();
}

@And("^More data is inserted$")
public void moreDataIsInserted() throws Throwable {
bg.reInsertTestCompositions();
}

@And("^The AQL query is repeated$")
public void theAQLQueryIsRepeated() throws Throwable {
_previousAqlResultSet = _aqlResultSet;
_aqlResultSet = bg.extractAqlResults(bg.getAqlResponse(_aqlQuery));
}

@Then("^A larger result set should be returned$")
public void aLargerResultSetShouldBeReturned() throws Throwable {
assertTrue(_aqlResultSet.size() > _previousAqlResultSet.size());
}
}
Expand Up @@ -7,13 +7,16 @@
import cucumber.api.java.en.When;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import java.io.ByteArrayInputStream;
import java.io.IOException;

import static com.ethercis.vehr.RestAPIBackgroundSteps.COMPOSITION_ENDPOINT;
import static com.ethercis.vehr.RestAPIBackgroundSteps.STATUS_CODE_OK;
Expand Down Expand Up @@ -87,25 +90,32 @@ private Response getComposition(String objectId, String pContentType, String pFo
}

@And("^Composition id should allow retrieval of composition in xml format$")
public void compositionIdShouldAllowRetrievalOfCompositionInXmlFormat() throws Throwable {
String objectId = _compositionUid.substring(0, _compositionUid.indexOf("::"));
public void compositionIdShouldAllowRetrievalOfCompositionInXmlFormat() throws Exception {
Document xmlComposition = getXmlCompositionFromRestApi();

Response response = getComposition(objectId, bg.CONTENT_TYPE_XML, FORMAT_XML);
XPathFactory xPathFactory = XPathFactory.newInstance();
XPath xPath = xPathFactory.newXPath();
Node rootNode = (Node) xPath.evaluate("/composition", xmlComposition.getDocumentElement(), XPathConstants.NODE);
assertNotNull(rootNode);
assertTrue(rootNode.getNodeName().equals("composition"));

}

String composition = response.body().asString();
public Document getXmlCompositionFromRestApi() throws ParserConfigurationException, SAXException, IOException {
String composition = getXmlStringFromRestAPI();
assertNotNull(composition);

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = factory.newDocumentBuilder();
Document xmlComposition =
documentBuilder
.parse(new ByteArrayInputStream(composition.getBytes()));
return documentBuilder
.parse(new ByteArrayInputStream(composition.getBytes()));
}

XPathFactory xPathFactory = XPathFactory.newInstance();
XPath xPath = xPathFactory.newXPath();
Node rootNode = (Node) xPath.evaluate("/composition", xmlComposition.getDocumentElement(), XPathConstants.NODE);
assertNotNull(rootNode);
assertTrue(rootNode.getNodeName().equals("composition"));
public String getXmlStringFromRestAPI() {
String objectId = _compositionUid.substring(0, _compositionUid.indexOf("::"));

Response response = getComposition(objectId, bg.CONTENT_TYPE_XML, FORMAT_XML);

return response.body().asString();
}
}
Expand Up @@ -18,8 +18,10 @@
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.IntStream;

import static com.jayway.restassured.RestAssured.given;
import static java.util.stream.Collectors.toList;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
Expand Down Expand Up @@ -50,6 +52,8 @@ public class RestAPIBackgroundSteps {
public static final String COMPOSITION_ENDPOINT = "/rest/v1/composition";
private Pattern uidPattern;
private Map<String, List<String>> persistedCompositions = new HashMap<>();
private List<AbstractMap.SimpleEntry<String, String>> _persistedCompositionsAsXml;
private DataTable _testCompositions;

public RestAPIBackgroundSteps(){
RestAssured.baseURI = "http://localhost";
Expand All @@ -63,6 +67,14 @@ public RestAPIBackgroundSteps(){
uidPattern = Pattern.compile("[a-z0-9-]*::[a-z0-9.]*::[0-9]*");
}

public void reInsertTestCompositions() {
try {
theFollowingCompositionsExistsUnderTheEHR(_testCompositions);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}

@Given("^The server is running$")
public void theServerIsRunning() throws Throwable {
startLauncher();
Expand Down Expand Up @@ -145,7 +157,8 @@ public void anEHRIsCreated() throws Throwable {
}

@And("^The following compositions exists under the EHR:$")
public void theFollowingCompositionsExistsUnderTheEHR(DataTable pCompositionFileNames) throws Throwable {
public void theFollowingCompositionsExistsUnderTheEHR(DataTable pCompositionFileNames) throws Exception {

List<DataTableRow> gherkinRows = pCompositionFileNames.getGherkinRows();
for (DataTableRow fnameTempId : gherkinRows) {

Expand All @@ -160,6 +173,18 @@ public void theFollowingCompositionsExistsUnderTheEHR(DataTable pCompositionFile
.computeIfAbsent(templateId, x -> new ArrayList<>())//x is ignored
.add(compositionUid);
}

_testCompositions = pCompositionFileNames;
}

private String getCompositionAsXML(String uid) {
try {
CompositionAPISteps compositionAPISteps = new CompositionAPISteps(this);
compositionAPISteps.setCompositionUid(uid);
return compositionAPISteps.getXmlStringFromRestAPI();
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}

public void postXMLComposition(boolean pPassEhrId, String pCompositionPath, CompositionFormat pFormat) {
Expand Down
Expand Up @@ -68,6 +68,7 @@ Feature: Support for openEHR Archetype Query Language
| Composition_IDCR_Vital_Signs_Encounter.v1.0.json | IDCR - Vital Signs Encounter.v1 |
| Composition_IDCR_Vital_Signs_Encounter.v1.1.json | IDCR - Vital Signs Encounter.v1 |
| Composition_IDCR_Vital_Signs_Encounter.v1.2.json | IDCR - Vital Signs Encounter.v1 |
| Composition_IDCR_Vital_Signs_Encounter.v1.3.json | IDCR - Vital Signs Encounter.v1 |
| Composition_RIPPLE_Clinical_Notes.v1.0.json | RIPPLE - Clinical Notes.v1 |
| Composition_RIPPLE_Clinical_Notes.v1.1.json | RIPPLE - Clinical Notes.v1 |
| Composition_RIPPLE_Clinical_Notes.v1.2.json | RIPPLE - Clinical Notes.v1 |
Expand Down Expand Up @@ -209,4 +210,27 @@ Feature: Support for openEHR Archetype Query Language
The SELECT clause includes the complete action instance

When A an AQL query that describes an action under a section is created
Then The results should include action instances
Then The results should include action instances

Scenario: Query without archetype id or name constraints
A composition with a section and and entry subtype under the section is queried.
The EHR is also included in the query.
The query does not use any EHR ids, archetype ids or archetype names. Therefore it is
a purely structural population query. The query returns instances of entry subtype.

When An aql query that describes an EHR/COMPOSITION/SECTION/ENTRY structure is created
Then The results should include ENTRY instances

Scenario: Query after data volume increases
A composition with a section and and entry subtype under the section is queried.
The EHR is also included in the query.
The query does not use any EHR ids, archetype ids or archetype names. Therefore it is
a purely structural population query. The query returns instances of entry subtype.
After the query returns, more data is inserted and the query is repeated. The
query returns a larger result set.

When An aql query that describes an EHR/COMPOSITION/SECTION/ENTRY structure is created
And The results include ENTRY instances
And More data is inserted
And The AQL query is repeated
Then A larger result set should be returned
@@ -0,0 +1,12 @@
{
"ctx/composer_name": "Dr Tony Shannon",
"ctx/composer_id": "G33567",
"ctx/health_care_facility|id": "999999-345",
"ctx/health_care_facility|name": "Ripple Valley Hospital NHS",
"ctx/id_namespace": "NHS-UK",
"ctx/id_scheme": "2.16.840.1.113883.2.1.4.3",
"ctx/language": "en",
"ctx/territory": "GB",
"ctx/time": "2015-08-03T00:23:02.518+02:00",
"vital_signs_observations/vital_signs/body_temperature/temperature|magnitude": 35.4
}
@@ -0,0 +1,10 @@
select
b_a as evaluation

from EHR e
contains COMPOSITION a

contains SECTION

contains EVALUATION b_a

0 comments on commit 5284a5c

Please sign in to comment.