diff --git a/client/src/test/java/org/ehrbase/client/classgenerator/examples/minimalevaluationenv1composition/MinimalEvaluationEnV1Composition.java b/client/src/test/java/org/ehrbase/client/classgenerator/examples/minimalevaluationenv1composition/MinimalEvaluationEnV1Composition.java new file mode 100644 index 000000000..e53770627 --- /dev/null +++ b/client/src/test/java/org/ehrbase/client/classgenerator/examples/minimalevaluationenv1composition/MinimalEvaluationEnV1Composition.java @@ -0,0 +1,212 @@ +package org.ehrbase.client.classgenerator.examples.minimalevaluationenv1composition; + +import com.nedap.archie.rm.archetyped.FeederAudit; +import com.nedap.archie.rm.generic.Participation; +import com.nedap.archie.rm.generic.PartyIdentified; +import com.nedap.archie.rm.generic.PartyProxy; +import java.lang.String; +import java.time.temporal.TemporalAccessor; +import java.util.List; +import javax.annotation.processing.Generated; +import org.ehrbase.client.annotations.Archetype; +import org.ehrbase.client.annotations.Entity; +import org.ehrbase.client.annotations.Id; +import org.ehrbase.client.annotations.Path; +import org.ehrbase.client.annotations.Template; +import org.ehrbase.client.classgenerator.examples.minimalevaluationenv1composition.definition.MinimalEvaluation; +import org.ehrbase.client.classgenerator.interfaces.CompositionEntity; +import org.ehrbase.client.classgenerator.shareddefinition.Category; +import org.ehrbase.client.classgenerator.shareddefinition.Language; +import org.ehrbase.client.classgenerator.shareddefinition.Setting; +import org.ehrbase.client.classgenerator.shareddefinition.Territory; +import org.ehrbase.client.openehrclient.VersionUid; + +@Entity +@Archetype("openEHR-EHR-COMPOSITION.minimal.v1") +@Generated( + value = "org.ehrbase.client.classgenerator.ClassGenerator", + date = "2021-03-22T13:27:16.902461+07:00", + comments = "https://github.com/ehrbase/openEHR_SDK Version: 1.3.0" +) +@Template("minimal_evaluation.en.v1") +public class MinimalEvaluationEnV1Composition implements CompositionEntity { + /** + * Path: Minimal/category + */ + @Path("/category|defining_code") + private Category categoryDefiningCode; + + /** + * Path: Minimal/Minimal + * Description: unknown + */ + @Path("/content[openEHR-EHR-EVALUATION.minimal.v1]") + private List minimal; + + /** + * Path: Minimal/composer + */ + @Path("/composer") + private PartyProxy composer; + + /** + * Path: Minimal/language + */ + @Path("/language") + private Language language; + + /** + * Path: Minimal/context/start_time + */ + @Path("/context/start_time|value") + private TemporalAccessor startTimeValue; + + /** + * Path: Minimal/context/participations + */ + @Path("/context/participations") + private List participations; + + /** + * Path: Minimal/context/end_time + */ + @Path("/context/end_time|value") + private TemporalAccessor endTimeValue; + + /** + * Path: Minimal/context/location + */ + @Path("/context/location") + private String location; + + /** + * Path: Minimal/context/health_care_facility + */ + @Path("/context/health_care_facility") + private PartyIdentified healthCareFacility; + + /** + * Path: Minimal/context/setting + */ + @Path("/context/setting|defining_code") + private Setting settingDefiningCode; + + /** + * Path: Minimal/feeder_audit + */ + @Path("/feeder_audit") + private FeederAudit feederAudit; + + /** + * Path: Minimal/territory + */ + @Path("/territory") + private Territory territory; + + @Id + private VersionUid versionUid; + + public void setCategoryDefiningCode(Category categoryDefiningCode) { + this.categoryDefiningCode = categoryDefiningCode; + } + + public Category getCategoryDefiningCode() { + return this.categoryDefiningCode ; + } + + public void setMinimal(List minimal) { + this.minimal = minimal; + } + + public List getMinimal() { + return this.minimal ; + } + + public void setComposer(PartyProxy composer) { + this.composer = composer; + } + + public PartyProxy getComposer() { + return this.composer ; + } + + public void setLanguage(Language language) { + this.language = language; + } + + public Language getLanguage() { + return this.language ; + } + + public void setStartTimeValue(TemporalAccessor startTimeValue) { + this.startTimeValue = startTimeValue; + } + + public TemporalAccessor getStartTimeValue() { + return this.startTimeValue ; + } + + public void setParticipations(List participations) { + this.participations = participations; + } + + public List getParticipations() { + return this.participations ; + } + + public void setEndTimeValue(TemporalAccessor endTimeValue) { + this.endTimeValue = endTimeValue; + } + + public TemporalAccessor getEndTimeValue() { + return this.endTimeValue ; + } + + public void setLocation(String location) { + this.location = location; + } + + public String getLocation() { + return this.location ; + } + + public void setHealthCareFacility(PartyIdentified healthCareFacility) { + this.healthCareFacility = healthCareFacility; + } + + public PartyIdentified getHealthCareFacility() { + return this.healthCareFacility ; + } + + public void setSettingDefiningCode(Setting settingDefiningCode) { + this.settingDefiningCode = settingDefiningCode; + } + + public Setting getSettingDefiningCode() { + return this.settingDefiningCode ; + } + + public void setFeederAudit(FeederAudit feederAudit) { + this.feederAudit = feederAudit; + } + + public FeederAudit getFeederAudit() { + return this.feederAudit ; + } + + public void setTerritory(Territory territory) { + this.territory = territory; + } + + public Territory getTerritory() { + return this.territory ; + } + + public VersionUid getVersionUid() { + return this.versionUid ; + } + + public void setVersionUid(VersionUid versionUid) { + this.versionUid = versionUid; + } +} diff --git a/client/src/test/java/org/ehrbase/client/classgenerator/examples/minimalevaluationenv1composition/MinimalEvaluationEnV1CompositionContainment.java b/client/src/test/java/org/ehrbase/client/classgenerator/examples/minimalevaluationenv1composition/MinimalEvaluationEnV1CompositionContainment.java new file mode 100644 index 000000000..efb974cf7 --- /dev/null +++ b/client/src/test/java/org/ehrbase/client/classgenerator/examples/minimalevaluationenv1composition/MinimalEvaluationEnV1CompositionContainment.java @@ -0,0 +1,54 @@ +package org.ehrbase.client.classgenerator.examples.minimalevaluationenv1composition; + +import com.nedap.archie.rm.archetyped.FeederAudit; +import com.nedap.archie.rm.generic.Participation; +import com.nedap.archie.rm.generic.PartyIdentified; +import com.nedap.archie.rm.generic.PartyProxy; +import java.lang.String; +import java.time.temporal.TemporalAccessor; +import org.ehrbase.client.aql.containment.Containment; +import org.ehrbase.client.aql.field.AqlFieldImp; +import org.ehrbase.client.aql.field.ListAqlFieldImp; +import org.ehrbase.client.aql.field.ListSelectAqlField; +import org.ehrbase.client.aql.field.SelectAqlField; +import org.ehrbase.client.classgenerator.examples.minimalevaluationenv1composition.definition.MinimalEvaluation; +import org.ehrbase.client.classgenerator.shareddefinition.Category; +import org.ehrbase.client.classgenerator.shareddefinition.Language; +import org.ehrbase.client.classgenerator.shareddefinition.Setting; +import org.ehrbase.client.classgenerator.shareddefinition.Territory; + +public class MinimalEvaluationEnV1CompositionContainment extends Containment { + public SelectAqlField MINIMAL_EVALUATION_EN_V1_COMPOSITION = new AqlFieldImp(MinimalEvaluationEnV1Composition.class, "", "MinimalEvaluationEnV1Composition", MinimalEvaluationEnV1Composition.class, this); + + public SelectAqlField CATEGORY_DEFINING_CODE = new AqlFieldImp(MinimalEvaluationEnV1Composition.class, "/category|defining_code", "categoryDefiningCode", Category.class, this); + + public ListSelectAqlField MINIMAL = new ListAqlFieldImp(MinimalEvaluationEnV1Composition.class, "/content[openEHR-EHR-EVALUATION.minimal.v1]", "minimal", MinimalEvaluation.class, this); + + public SelectAqlField COMPOSER = new AqlFieldImp(MinimalEvaluationEnV1Composition.class, "/composer", "composer", PartyProxy.class, this); + + public SelectAqlField LANGUAGE = new AqlFieldImp(MinimalEvaluationEnV1Composition.class, "/language", "language", Language.class, this); + + public SelectAqlField START_TIME_VALUE = new AqlFieldImp(MinimalEvaluationEnV1Composition.class, "/context/start_time|value", "startTimeValue", TemporalAccessor.class, this); + + public ListSelectAqlField PARTICIPATIONS = new ListAqlFieldImp(MinimalEvaluationEnV1Composition.class, "/context/participations", "participations", Participation.class, this); + + public SelectAqlField END_TIME_VALUE = new AqlFieldImp(MinimalEvaluationEnV1Composition.class, "/context/end_time|value", "endTimeValue", TemporalAccessor.class, this); + + public SelectAqlField LOCATION = new AqlFieldImp(MinimalEvaluationEnV1Composition.class, "/context/location", "location", String.class, this); + + public SelectAqlField HEALTH_CARE_FACILITY = new AqlFieldImp(MinimalEvaluationEnV1Composition.class, "/context/health_care_facility", "healthCareFacility", PartyIdentified.class, this); + + public SelectAqlField SETTING_DEFINING_CODE = new AqlFieldImp(MinimalEvaluationEnV1Composition.class, "/context/setting|defining_code", "settingDefiningCode", Setting.class, this); + + public SelectAqlField FEEDER_AUDIT = new AqlFieldImp(MinimalEvaluationEnV1Composition.class, "/feeder_audit", "feederAudit", FeederAudit.class, this); + + public SelectAqlField TERRITORY = new AqlFieldImp(MinimalEvaluationEnV1Composition.class, "/territory", "territory", Territory.class, this); + + private MinimalEvaluationEnV1CompositionContainment() { + super("openEHR-EHR-COMPOSITION.minimal.v1"); + } + + public static MinimalEvaluationEnV1CompositionContainment getInstance() { + return new MinimalEvaluationEnV1CompositionContainment(); + } +} diff --git a/client/src/test/java/org/ehrbase/client/classgenerator/examples/minimalevaluationenv1composition/definition/MinimalEvaluation.java b/client/src/test/java/org/ehrbase/client/classgenerator/examples/minimalevaluationenv1composition/definition/MinimalEvaluation.java new file mode 100644 index 000000000..ed90d4c17 --- /dev/null +++ b/client/src/test/java/org/ehrbase/client/classgenerator/examples/minimalevaluationenv1composition/definition/MinimalEvaluation.java @@ -0,0 +1,108 @@ +package org.ehrbase.client.classgenerator.examples.minimalevaluationenv1composition.definition; + +import com.nedap.archie.rm.archetyped.FeederAudit; +import com.nedap.archie.rm.generic.PartyProxy; +import java.lang.Double; +import java.lang.String; +import javax.annotation.processing.Generated; +import org.ehrbase.client.annotations.Archetype; +import org.ehrbase.client.annotations.Entity; +import org.ehrbase.client.annotations.Path; +import org.ehrbase.client.classgenerator.interfaces.EntryEntity; +import org.ehrbase.client.classgenerator.shareddefinition.Language; +import org.ehrbase.client.classgenerator.shareddefinition.NullFlavour; + +@Entity +@Archetype("openEHR-EHR-EVALUATION.minimal.v1") +@Generated( + value = "org.ehrbase.client.classgenerator.ClassGenerator", + date = "2021-03-22T13:27:16.936346+07:00", + comments = "https://github.com/ehrbase/openEHR_SDK Version: 1.3.0" +) +public class MinimalEvaluation implements EntryEntity { + /** + * Path: Minimal/Minimal/quantity + * Description: * + */ + @Path("/data[at0001]/items[at0002]/value|magnitude") + private Double quantityMagnitude; + + /** + * Path: Minimal/Minimal/quantity + * Description: * + */ + @Path("/data[at0001]/items[at0002]/value|units") + private String quantityUnits; + + /** + * Path: Minimal/Minimal/Arbol/quantity/null_flavour + */ + @Path("/data[at0001]/items[at0002]/null_flavour|defining_code") + private NullFlavour quantityNullFlavourDefiningCode; + + /** + * Path: Minimal/Minimal/subject + */ + @Path("/subject") + private PartyProxy subject; + + /** + * Path: Minimal/Minimal/language + */ + @Path("/language") + private Language language; + + /** + * Path: Minimal/Minimal/feeder_audit + */ + @Path("/feeder_audit") + private FeederAudit feederAudit; + + public void setQuantityMagnitude(Double quantityMagnitude) { + this.quantityMagnitude = quantityMagnitude; + } + + public Double getQuantityMagnitude() { + return this.quantityMagnitude ; + } + + public void setQuantityUnits(String quantityUnits) { + this.quantityUnits = quantityUnits; + } + + public String getQuantityUnits() { + return this.quantityUnits ; + } + + public void setQuantityNullFlavourDefiningCode(NullFlavour quantityNullFlavourDefiningCode) { + this.quantityNullFlavourDefiningCode = quantityNullFlavourDefiningCode; + } + + public NullFlavour getQuantityNullFlavourDefiningCode() { + return this.quantityNullFlavourDefiningCode ; + } + + public void setSubject(PartyProxy subject) { + this.subject = subject; + } + + public PartyProxy getSubject() { + return this.subject ; + } + + public void setLanguage(Language language) { + this.language = language; + } + + public Language getLanguage() { + return this.language ; + } + + public void setFeederAudit(FeederAudit feederAudit) { + this.feederAudit = feederAudit; + } + + public FeederAudit getFeederAudit() { + return this.feederAudit ; + } +} diff --git a/client/src/test/java/org/ehrbase/client/classgenerator/examples/minimalevaluationenv1composition/definition/MinimalEvaluationContainment.java b/client/src/test/java/org/ehrbase/client/classgenerator/examples/minimalevaluationenv1composition/definition/MinimalEvaluationContainment.java new file mode 100644 index 000000000..d5cee9175 --- /dev/null +++ b/client/src/test/java/org/ehrbase/client/classgenerator/examples/minimalevaluationenv1composition/definition/MinimalEvaluationContainment.java @@ -0,0 +1,35 @@ +package org.ehrbase.client.classgenerator.examples.minimalevaluationenv1composition.definition; + +import com.nedap.archie.rm.archetyped.FeederAudit; +import com.nedap.archie.rm.generic.PartyProxy; +import java.lang.Double; +import java.lang.String; +import org.ehrbase.client.aql.containment.Containment; +import org.ehrbase.client.aql.field.AqlFieldImp; +import org.ehrbase.client.aql.field.SelectAqlField; +import org.ehrbase.client.classgenerator.shareddefinition.Language; +import org.ehrbase.client.classgenerator.shareddefinition.NullFlavour; + +public class MinimalEvaluationContainment extends Containment { + public SelectAqlField MINIMAL_EVALUATION = new AqlFieldImp(MinimalEvaluation.class, "", "MinimalEvaluation", MinimalEvaluation.class, this); + + public SelectAqlField QUANTITY_MAGNITUDE = new AqlFieldImp(MinimalEvaluation.class, "/data[at0001]/items[at0002]/value|magnitude", "quantityMagnitude", Double.class, this); + + public SelectAqlField QUANTITY_UNITS = new AqlFieldImp(MinimalEvaluation.class, "/data[at0001]/items[at0002]/value|units", "quantityUnits", String.class, this); + + public SelectAqlField QUANTITY_NULL_FLAVOUR_DEFINING_CODE = new AqlFieldImp(MinimalEvaluation.class, "/data[at0001]/items[at0002]/null_flavour|defining_code", "quantityNullFlavourDefiningCode", NullFlavour.class, this); + + public SelectAqlField SUBJECT = new AqlFieldImp(MinimalEvaluation.class, "/subject", "subject", PartyProxy.class, this); + + public SelectAqlField LANGUAGE = new AqlFieldImp(MinimalEvaluation.class, "/language", "language", Language.class, this); + + public SelectAqlField FEEDER_AUDIT = new AqlFieldImp(MinimalEvaluation.class, "/feeder_audit", "feederAudit", FeederAudit.class, this); + + private MinimalEvaluationContainment() { + super("openEHR-EHR-EVALUATION.minimal.v1"); + } + + public static MinimalEvaluationContainment getInstance() { + return new MinimalEvaluationContainment(); + } +} diff --git a/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/CanonicalUtil.java b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/CanonicalUtil.java index 93e9fd083..b432f948c 100644 --- a/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/CanonicalUtil.java +++ b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/CanonicalUtil.java @@ -21,75 +21,65 @@ import com.google.gson.GsonBuilder; import com.nedap.archie.rm.RMObject; import com.nedap.archie.rm.archetyped.Locatable; -import com.nedap.archie.rm.datavalues.quantity.datetime.DvDateTime; -import com.nedap.archie.rm.datavalues.quantity.datetime.DvTime; -import com.nedap.archie.rm.generic.PartySelf; -import com.nedap.archie.rm.support.identification.TerminologyId; import com.nedap.archie.rminfo.ArchieRMInfoLookup; -import com.nedap.archie.terminology.openehr.Terminology; import org.ehrbase.serialisation.dbencoding.wrappers.json.I_DvTypeAdapter; import org.ehrbase.serialisation.jsonencoding.CanonicalJson; import org.ehrbase.validation.constraints.util.SnakeToCamel; import java.lang.reflect.Method; -import java.net.URI; -import java.time.Duration; -import java.time.OffsetDateTime; -import java.time.temporal.Temporal; import java.util.Arrays; import java.util.List; import java.util.Map; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.InstanceOfAssertFactories.OFFSET_TIME; public abstract class CanonicalUtil { - public static String toJson(Object anRmObjectAsString){ + public static String toJson(Object anRmObjectAsString) { GsonBuilder builder = new GsonBuilder(); Gson gson = builder.setPrettyPrinting().create(); return gson.toJson(anRmObjectAsString); } - public static Map toMap(RMObject anRmObject){ + public static Map toMap(RMObject anRmObject) { GsonBuilder builder = new GsonBuilder(); Gson gson = builder.create(); String asString = new CanonicalJson().marshal(anRmObject); return gson.fromJson(asString, Map.class); } - public static String toRmJson(RMObject anRmObject){ + public static String toRmJson(RMObject anRmObject) { return new CanonicalJson().marshal(anRmObject); } - public static RMObject toRmObject(Map anRmObjectAsMap, Class rmClass){ + public static RMObject toRmObject(Map anRmObjectAsMap, Class rmClass) { return new CanonicalJson().unmarshal(toJson(anRmObjectAsMap), rmClass); } - public static Object valueObject(Object anObject){ + public static Object valueObject(Object anObject) { Object retObject = anObject; - if (anObject instanceof Map){ + if (anObject instanceof Map) { //perform the conversion using the type if any - if (((Map)anObject).containsKey(I_DvTypeAdapter.AT_TYPE)){ + if (((Map) anObject).containsKey(I_DvTypeAdapter.AT_TYPE)) { //get the actual type from Archie lookup - Class objectRmClass = ArchieRMInfoLookup.getInstance().getClass((String) ((Map)anObject).get(I_DvTypeAdapter.AT_TYPE)); + Class objectRmClass = ArchieRMInfoLookup.getInstance().getClass((String) ((Map) anObject).get(I_DvTypeAdapter.AT_TYPE)); if (objectRmClass != null) - retObject = toRmObject(((Map)anObject),objectRmClass); + retObject = toRmObject(((Map) anObject), objectRmClass); } } - retObject = handleSpecialClass(retObject); + retObject = new SpecialCase().transform(retObject); return retObject; } - public static RMObject toRmObject(String anRmObjectAsString, Class rmClass){ + public static RMObject toRmObject(String anRmObjectAsString, Class rmClass) { return new CanonicalJson().unmarshal(anRmObjectAsString, rmClass); } - public static Object compareArbitraryRmClass(Map anRmObjectAsMap, Class rmClass, RMObject compareExpectedObject){ + public static Object compareArbitraryRmClass(Map anRmObjectAsMap, Class rmClass, RMObject compareExpectedObject) { RMObject actualRmObject = toRmObject(anRmObjectAsMap, rmClass); assertThat(actualRmObject).isEqualTo(compareExpectedObject); return null; @@ -98,6 +88,7 @@ public static Object compareArbitraryRmClass(Map anRmObjectAsMap /** * resolves an attribute of a RMObject * NB. borrowed from CAttribute.java in validation + * * @param obj * @param attributePath * @return @@ -111,18 +102,17 @@ private static Object getAttributeValue(Object obj, String attributePath) { Method getter; String getterName; - if (attributePath.startsWith("is_")){ + if (attributePath.startsWith("is_")) { //conventionally, a getter for a boolean uses 'is' as a prefix getterName = "is" + new SnakeToCamel(attributePath.substring(3)).convert(); - } - else + } else getterName = "get" + new SnakeToCamel(attributePath).convert(); try { getter = rmClass.getMethod(getterName); value = getter.invoke(obj, null); } catch (Exception e) { - throw new IllegalStateException("unresolved attribute:"+attributePath+" for class:"+rmClass); + throw new IllegalStateException("unresolved attribute:" + attributePath + " for class:" + rmClass); } return value; @@ -132,12 +122,13 @@ private static Object getAttributeValue(Object obj, String attributePath) { * Retrieve the value of an attribute identified by a path. * NB. This is not supposed to replace Locatable.itemsAtPath(), but instead it should be used * to resolve values in non locatable RMObject + * * @param root * @param attributePath * @return * @see com.nedap.archie.rm.archetyped.Locatable */ - private static Object getAttributePathValue(Object root, String attributePath){ + private static Object getAttributePathValue(Object root, String attributePath) { Object rmObject = root; if (rmObject instanceof Locatable) { @@ -147,12 +138,10 @@ private static Object getAttributePathValue(Object root, String attributePath){ rmObject = items.get(0); else rmObject = null; + } catch (Exception e) { + throw new IllegalArgumentException("Invalid path:" + attributePath); } - catch (Exception e){ - throw new IllegalArgumentException("Invalid path:"+attributePath); - } - } - else { + } else { if (!attributePath.contains("/")) rmObject = getAttributeValue(root, attributePath); else { @@ -173,46 +162,17 @@ private static Object getAttributePathValue(Object root, String attributePath){ return rmObject; } - public static Object attributeValueAt(Object root, String path){ + public static Object attributeValueAt(Object root, String path) { Object evaluated = getAttributePathValue(root, path); - return handleSpecialClass(evaluated); + return new SpecialCase().transform(evaluated); } - public static Object locatableValueItem(RMObject rmObject, int iteration, List pathItems){ + public static Object locatableValueItem(RMObject rmObject, int iteration, List pathItems) { String actualItemPath; if (pathItems.isEmpty()) actualItemPath = "/"; else actualItemPath = String.join("/", pathItems); - return ((Locatable)rmObject).itemsAtPath(actualItemPath).get(0); - } - - private static Object handleSpecialClass(Object object){ - Object retObject = object; - - if (object instanceof PartySelf && (((PartySelf)object).getExternalRef() == null || ((PartySelf)object).getExternalRef().getId() == null) ) - retObject = "PARTY_SELF"; - else if (object instanceof RMObject) { - retObject = toMap((RMObject) object); - if (object instanceof TerminologyId) { - //add the type as it is sometime implicit with archie but required for comparison - ((Map) retObject).put(I_DvTypeAdapter.AT_TYPE, "TERMINOLOGY_ID"); - } - } - else if (object instanceof Temporal || object instanceof Duration || object instanceof URI) { - retObject = object.toString(); - if (object instanceof Temporal){ - //align the millisec delimiter - if (retObject instanceof String && ((String) retObject).contains(".")) - retObject = ((String)retObject).replace(".", ","); - } - } - else if (object instanceof Integer) - //this is a hack as a Long is transformed as Integer in the HTTP response? - retObject = Integer.toUnsignedLong((Integer)object); - else if (object instanceof String && ((String)object).matches("^\\d{4}-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\d(\\.\\d+)?(([+-]\\d\\d:\\d\\d)|Z)?$")) - retObject = ((String)retObject).replace(".", ","); - - return retObject; + return ((Locatable) rmObject).itemsAtPath(actualItemPath).get(0); } } diff --git a/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/SpecialCase.java b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/SpecialCase.java new file mode 100644 index 000000000..250c96536 --- /dev/null +++ b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/SpecialCase.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2020 Christian Chevalley (Hannover Medical School) and Vitasystems GmbH + * + * This file is part of project EHRbase + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and limitations under the License. + */ + +package org.ehrbase.client.openehrclient.defaultrestclient.systematic; + +import com.nedap.archie.rm.RMObject; +import com.nedap.archie.rm.generic.PartySelf; +import com.nedap.archie.rm.support.identification.TerminologyId; +import org.ehrbase.serialisation.dbencoding.wrappers.json.I_DvTypeAdapter; + +import java.net.URI; +import java.time.Duration; +import java.time.temporal.Temporal; +import java.util.Map; + +import static org.ehrbase.client.openehrclient.defaultrestclient.systematic.CanonicalUtil.toMap; + +public class SpecialCase { + + public Object transform(Object object){ + Object retObject = object; + + if (object instanceof PartySelf && (((PartySelf)object).getExternalRef() == null || ((PartySelf)object).getExternalRef().getId() == null) ) + retObject = "PARTY_SELF"; + else if (object instanceof RMObject) { + retObject = toMap((RMObject) object); + if (object instanceof TerminologyId) { + //add the type as it is sometime implicit with archie but required for comparison + ((Map) retObject).put(I_DvTypeAdapter.AT_TYPE, "TERMINOLOGY_ID"); + } + } + else if (object instanceof Temporal || object instanceof Duration || object instanceof URI) { + retObject = object.toString(); + if (object instanceof Temporal){ + //align the millisec delimiter + if (retObject instanceof String && ((String) retObject).contains(".")) + retObject = ((String)retObject).replace(".", ","); + } + } + else if (object instanceof Integer) + //this is a hack as a Long is transformed as Integer in the HTTP response? + retObject = Integer.toUnsignedLong((Integer)object); + else if (object instanceof String && + ((String)object).matches("^\\d{4}-\\d\\d-\\d\\dT\\d\\d:\\d\\d:\\d\\d(\\.\\d+)?(([+-]\\d\\d:\\d\\d)|Z)?$")) + retObject = ((String)retObject).replace(".", ","); + + return retObject; + } +} diff --git a/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/ArbitraryQueryDateTimeIT.java b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/ArbitraryQueryDateTimeIT.java new file mode 100644 index 000000000..5eb852704 --- /dev/null +++ b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/ArbitraryQueryDateTimeIT.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2020 Christian Chevalley (Hannover Medical School) and Vitasystems GmbH + * + * This file is part of project EHRbase + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and limitations under the License. + */ + +package org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery; + +import org.ehrbase.client.Integration; +import org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery.queries.arbitrary.ArbitraryQuery; +import org.ehrbase.test_data.composition.CompositionTestDataCanonicalJson; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import java.io.IOException; + +import static org.assertj.core.api.Assertions.assertThat; + +@Category(Integration.class) +public class ArbitraryQueryDateTimeIT extends CanonicalCompoAllTypeQueryIT { + + protected ArbitraryQuery arbitraryQuery; + + @Before + public void setUp() throws IOException { + super.setUp(CompositionTestDataCanonicalJson.DATE_TIME_TESTS); + arbitraryQuery = new ArbitraryQuery(ehrUUID, openEhrClient); + } + + @Test + public void testArbitrary1() throws IOException { + String csvTestSet = dirPath+"/arbitrary/date_time_where_tests.csv"; + + assertThat(arbitraryQuery.testItemPaths(dirPath+"/arbitrary", csvTestSet)).isTrue(); + } + +} diff --git a/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/ArbitraryQueryIT.java b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/ArbitraryQueryIT.java new file mode 100644 index 000000000..a0d57c840 --- /dev/null +++ b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/ArbitraryQueryIT.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2020 Christian Chevalley (Hannover Medical School) and Vitasystems GmbH + * + * This file is part of project EHRbase + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and limitations under the License. + */ + +package org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery; + +import com.nedap.archie.rm.RMObject; +import org.ehrbase.client.Integration; +import org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery.queries.arbitrary.ArbitraryQuery; +import org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery.queries.auto.AutoWhereQuery; +import org.ehrbase.test_data.composition.CompositionTestDataCanonicalJson; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import java.io.IOException; + +import static org.assertj.core.api.Assertions.assertThat; + +@Category(Integration.class) +public class ArbitraryQueryIT extends CanonicalCompoAllTypeQueryIT { + + protected ArbitraryQuery arbitraryQuery; + + @Before + public void setUp() throws IOException { + super.setUp(CompositionTestDataCanonicalJson.ALL_TYPES_SYSTEMATIC_TESTS); + arbitraryQuery = new ArbitraryQuery(ehrUUID, openEhrClient); + } + + @Test + public void testArbitraryBoolean() throws IOException { + String csvTestSet = dirPath+"/arbitrary/arbitrary_boolean_where_tests.csv"; + + assertThat(arbitraryQuery.testItemPaths(dirPath+"/arbitrary", csvTestSet)).isTrue(); + } + + @Test + public void testArbitraryString() throws IOException { + String csvTestSet = dirPath+"/arbitrary/arbitrary_tests.csv"; + + assertThat(arbitraryQuery.testItemPaths(dirPath+"/arbitrary", csvTestSet)).isTrue(); + } + +} diff --git a/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/AutoWhereIT.java b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/AutoWhereIT.java new file mode 100644 index 000000000..0ddf774d9 --- /dev/null +++ b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/AutoWhereIT.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2020 Christian Chevalley (Hannover Medical School) and Vitasystems GmbH + * + * This file is part of project EHRbase + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and limitations under the License. + */ + +package org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery; + +import com.nedap.archie.rm.RMObject; +import org.ehrbase.client.Integration; +import org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery.queries.auto.AutoWhereQuery; +import org.ehrbase.test_data.composition.CompositionTestDataCanonicalJson; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import java.io.IOException; + +import static org.assertj.core.api.Assertions.assertThat; + +@Category(Integration.class) +public class AutoWhereIT extends CanonicalCompoAllTypeQueryIT { + protected AutoWhereQuery autoWhereQuery; + + @Before + public void setUp() throws IOException { + super.setUp(CompositionTestDataCanonicalJson.ALL_TYPES_SYSTEMATIC_TESTS); + autoWhereQuery = new AutoWhereQuery(ehrUUID, compositionUUID, openEhrClient); + } + + @Test + public void testActionAutoWhere() throws IOException { + + String rootPath = "a"; + RMObject referenceNode = (RMObject) aComposition + .itemsAtPath("/content[openEHR-EHR-SECTION.test_all_types.v1]/items[at0001]/items[at0002]/items[openEHR-EHR-ACTION.test_all_types.v1]").get(0); + String contains = "composition c[openEHR-EHR-COMPOSITION.test_all_types.v1]" + + " contains section s[openEHR-EHR-SECTION.test_all_types.v1]" + + " contains action a[openEHR-EHR-ACTION.test_all_types.v1]"; + String csvTestSet = dirPath+"/testActionWhere.csv"; + + assertThat(autoWhereQuery.testItemPaths(csvTestSet, rootPath, contains, referenceNode)).isTrue(); + } + + @Test + public void testCompositionAutoWhere() throws IOException { + String rootPath = "c"; + RMObject referenceNode = aComposition; + String contains = "composition c[openEHR-EHR-COMPOSITION.test_all_types.v1]"; + String csvTestSet = dirPath+"/testCompositionWhere.csv"; + + assertThat(autoWhereQuery.testItemPaths(csvTestSet, rootPath, contains, referenceNode)).isTrue(); + } + + @Test + public void testObservationAutoWhere() throws IOException { + String rootPath = "o"; + RMObject referenceNode = (RMObject) aComposition.itemsAtPath("/content[openEHR-EHR-OBSERVATION.test_all_types.v1]").get(0); + String contains = "composition c[openEHR-EHR-COMPOSITION.test_all_types.v1]" + + " contains observation o[openEHR-EHR-OBSERVATION.test_all_types.v1]"; + String csvTestSet = dirPath+"/testObservationWhere.csv"; + + assertThat(autoWhereQuery.testItemPaths(csvTestSet, rootPath, contains, referenceNode)).isTrue(); + } + + @Test + public void testContextAutoWhere() throws IOException { + + String rootPath = "c/context"; + RMObject referenceNode = aComposition.getContext(); + String contains = "composition c[openEHR-EHR-COMPOSITION.test_all_types.v1]"; + String csvTestSet = dirPath+"/testContextAttributesWhere.csv"; + + assertThat(autoWhereQuery.testItemPaths(csvTestSet, rootPath, contains, referenceNode)).isTrue(); + } + + @Test + public void testEvaluationAutoWhere() throws IOException { + + String rootPath = "eval"; + RMObject referenceNode = (RMObject) aComposition.itemsAtPath("/content[openEHR-EHR-EVALUATION.test_all_types.v1]").get(0); + String contains = "composition c[openEHR-EHR-COMPOSITION.test_all_types.v1]" + + " contains evaluation eval[openEHR-EHR-EVALUATION.test_all_types.v1]"; + String csvTestSet = dirPath+"/testEvaluationWhere.csv"; + + assertThat(autoWhereQuery.testItemPaths(csvTestSet, rootPath, contains, referenceNode)).isTrue(); + } + + @Test + public void testInstructionAutoWhere() throws IOException { + + String rootPath = "i"; + RMObject referenceNode = (RMObject) aComposition + .itemsAtPath("/content[openEHR-EHR-SECTION.test_all_types.v1]/items[at0001]/items[at0002]/items[openEHR-EHR-INSTRUCTION.test_all_types.v1]").get(0); + String contains = "composition c[openEHR-EHR-COMPOSITION.test_all_types.v1]" + + " contains section s[openEHR-EHR-SECTION.test_all_types.v1]" + + " contains instruction i[openEHR-EHR-INSTRUCTION.test_all_types.v1]"; + String csvTestSet = dirPath+"/testInstructionWhere.csv"; + + assertThat(autoWhereQuery.testItemPaths(csvTestSet, rootPath, contains, referenceNode)).isTrue(); + } + + @Test + public void testSectionAutoWhere() throws IOException { + + String rootPath = "s"; + RMObject referenceNode = (RMObject) aComposition.itemsAtPath("/content[openEHR-EHR-SECTION.test_all_types.v1]").get(0); + String contains = "composition c[openEHR-EHR-COMPOSITION.test_all_types.v1]" + + " contains section s[openEHR-EHR-SECTION.test_all_types.v1]"; + String csvTestSet = dirPath+"/testSectionWhere.csv"; + + assertThat(autoWhereQuery.testItemPaths(csvTestSet, rootPath, contains, referenceNode)).isTrue(); + } + +} diff --git a/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/CanonicalCompoAllTypeQueryIT.java b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/CanonicalCompoAllTypeQueryIT.java index 07f70e5af..cbe9236d5 100644 --- a/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/CanonicalCompoAllTypeQueryIT.java +++ b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/CanonicalCompoAllTypeQueryIT.java @@ -17,54 +17,36 @@ package org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery; -import com.nedap.archie.rm.RMObject; import com.nedap.archie.rm.composition.Composition; import com.nedap.archie.rm.datavalues.quantity.datetime.DvDateTime; import org.apache.commons.io.IOUtils; -import org.ehrbase.client.Integration; -import org.ehrbase.client.aql.parameter.ParameterValue; -import org.ehrbase.client.aql.query.Query; -import org.ehrbase.client.aql.record.Record1; import org.ehrbase.client.classgenerator.examples.testalltypesenv1composition.TestAllTypesEnV1Composition; -import org.ehrbase.client.exception.WrongStatusCodeException; import org.ehrbase.client.flattener.Flattener; import org.ehrbase.client.openehrclient.CompositionEndpoint; import org.ehrbase.client.openehrclient.OpenEhrClient; import org.ehrbase.client.openehrclient.defaultrestclient.DefaultRestClientTestHelper; import org.ehrbase.client.openehrclient.defaultrestclient.systematic.CanonicalUtil; import org.ehrbase.client.templateprovider.TestDataTemplateProvider; -import org.ehrbase.response.openehr.QueryResponseData; import org.ehrbase.serialisation.jsonencoding.CanonicalJson; import org.ehrbase.test_data.composition.CompositionTestDataCanonicalJson; -import org.junit.*; -import org.junit.experimental.categories.Category; -import org.junit.jupiter.params.shadow.com.univocity.parsers.csv.CsvParser; -import org.junit.jupiter.params.shadow.com.univocity.parsers.csv.CsvParserSettings; +import org.junit.After; +import org.junit.BeforeClass; -import java.io.BufferedReader; -import java.io.FileReader; import java.io.IOException; import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; import java.time.OffsetDateTime; -import java.util.List; -import java.util.Map; import java.util.UUID; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; +public abstract class CanonicalCompoAllTypeQueryIT extends CanonicalUtil { + protected static OpenEhrClient openEhrClient; + protected static final String dirPath = "src/test/resources/testsets"; + protected CompositionEndpoint compositionEndpoint; + protected Composition aComposition; -@Category(Integration.class) -//@Ignore -public class CanonicalCompoAllTypeQueryIT extends CanonicalUtil { - private static OpenEhrClient openEhrClient; - private static final String dirPath = "src/test/resources/testsets"; - private CompositionEndpoint compositionEndpoint; - private Composition allTypesComposition; + protected UUID ehrUUID; + protected UUID compositionUUID; - private UUID ehrUUID; - private UUID compositionUUID; - private DvDateTime actualDvDateTime; @BeforeClass @@ -72,23 +54,24 @@ public static void before() throws URISyntaxException { openEhrClient = DefaultRestClientTestHelper.setupDefaultRestClient(); } - @Before - public void setUp() throws IOException { + public void setUp(CompositionTestDataCanonicalJson testComposition) throws IOException { //manual test use // ehrUUID = UUID.fromString("ecc0de4d-eb29-40c2-ad7a-e2ab8d66a9f8"); // compositionUUID = UUID.fromString("a9c22c37-8002-4486-932a-f3e1729efe57"); actualDvDateTime = new DvDateTime(OffsetDateTime.now()); - allTypesComposition = new CanonicalJson().unmarshal(IOUtils.toString(CompositionTestDataCanonicalJson.ALL_TYPES_SYSTEMATIC_TESTS.getStream(), StandardCharsets.UTF_8), Composition.class); -// normal test run + // normal test run ehrUUID = openEhrClient.ehrEndpoint().createEhr(); compositionEndpoint = openEhrClient.compositionEndpoint(ehrUUID); - Flattener flattener = new Flattener(new TestDataTemplateProvider()); - TestAllTypesEnV1Composition testAllTypesEnV1Composition = flattener.flatten(allTypesComposition, TestAllTypesEnV1Composition.class); -// create the composition - TestAllTypesEnV1Composition comp = compositionEndpoint.mergeCompositionEntity(testAllTypesEnV1Composition); - compositionUUID = comp.getVersionUid().getUuid(); + if (testComposition != null) { + aComposition = new CanonicalJson().unmarshal(IOUtils.toString(testComposition.getStream(), StandardCharsets.UTF_8), Composition.class); + Flattener flattener = new Flattener(new TestDataTemplateProvider()); + TestAllTypesEnV1Composition testAllTypesEnV1Composition = flattener.flatten(aComposition, TestAllTypesEnV1Composition.class); +// create the composition + TestAllTypesEnV1Composition comp = compositionEndpoint.mergeCompositionEntity(testAllTypesEnV1Composition); + compositionUUID = comp.getVersionUid().getUuid(); + } } @After @@ -97,176 +80,4 @@ public void tearDown(){ openEhrClient.adminEhrEndpoint().delete(ehrUUID); } - @Test - public void testCompositionAttributeQuery() throws IOException { - String rootPath = "c"; - RMObject referenceNode = allTypesComposition; - - //reads in the test set - BufferedReader inputCSVSetReader = new BufferedReader(new FileReader("src/test/resources/testsets/testCompositionAttributeQuery.csv")); - - String csvParams; - CsvParser csvParser = new CsvParser(new CsvParserSettings()); - - while ((csvParams = inputCSVSetReader.readLine()) != null) { - String[] params = csvParser.parseLine(csvParams); - String attributePath = params[0]; - if (params.length == 1) { //conventionally, if params[1] exists, this means skip the test - QueryResponseData result = performQuery(rootPath, attributePath, "composition c[openEHR-EHR-COMPOSITION.test_all_types.v1]"); - - List objectList = result.getRows().get(0); - - - //special case, c/uid is actually completed after db insertion, hence cannot be compared with the initial - //null value - if (attributePath.contains("uid")) { - assertThat(objectList.get(0)).isNotNull(); - } else - assertThat(valueObject(objectList.get(0))) - .as(rootPath + "/" + attributePath) - .isEqualTo(attributeValueAt(referenceNode, attributePath)); - } - } - } - - @Test - public void testContextAttributesDrillDown() throws IOException { - - String rootPath = "c/context"; - RMObject referenceNode = allTypesComposition.getContext(); - String contains = "composition c[openEHR-EHR-COMPOSITION.test_all_types.v1]"; - String csvTestSet = dirPath+"/testContextAttributesDrillDown.csv"; - - assertThat(testItemPaths(csvTestSet, rootPath, contains, referenceNode)).isTrue(); - } - - @Test - public void testObservationDrillDown() throws IOException { - - String rootPath = "o"; - RMObject referenceNode = (RMObject) allTypesComposition.itemsAtPath("/content[openEHR-EHR-OBSERVATION.test_all_types.v1]").get(0); - String contains = "composition c[openEHR-EHR-COMPOSITION.test_all_types.v1]" + - " contains observation o[openEHR-EHR-OBSERVATION.test_all_types.v1]"; - String csvTestSet = dirPath+"/testObservationDrillDown.csv"; - - assertThat(testItemPaths(csvTestSet, rootPath, contains, referenceNode)).isTrue(); - } - - @Test - public void testEvaluationDrillDown() throws IOException { - - String rootPath = "eval"; - RMObject referenceNode = (RMObject) allTypesComposition.itemsAtPath("/content[openEHR-EHR-EVALUATION.test_all_types.v1]").get(0); - String contains = "composition c[openEHR-EHR-COMPOSITION.test_all_types.v1]" + - " contains evaluation eval[openEHR-EHR-EVALUATION.test_all_types.v1]"; - String csvTestSet = dirPath+"/testEvaluationDrillDown.csv"; - - assertThat(testItemPaths(csvTestSet, rootPath, contains, referenceNode)).isTrue(); - } - - @Test - public void testSectionDrillDown() throws IOException { - - String rootPath = "s"; - RMObject referenceNode = (RMObject) allTypesComposition.itemsAtPath("/content[openEHR-EHR-SECTION.test_all_types.v1]").get(0); - String contains = "composition c[openEHR-EHR-COMPOSITION.test_all_types.v1]" + - " contains section s[openEHR-EHR-SECTION.test_all_types.v1]"; - String csvTestSet = dirPath+"/testSectionDrillDown.csv"; - - assertThat(testItemPaths(csvTestSet, rootPath, contains, referenceNode)).isTrue(); - } - - @Test - public void testInstructionDrillDown() throws IOException { - - String rootPath = "i"; - RMObject referenceNode = (RMObject) allTypesComposition - .itemsAtPath("/content[openEHR-EHR-SECTION.test_all_types.v1]/items[at0001]/items[at0002]/items[openEHR-EHR-INSTRUCTION.test_all_types.v1]").get(0); - String contains = "composition c[openEHR-EHR-COMPOSITION.test_all_types.v1]" + - " contains section s[openEHR-EHR-SECTION.test_all_types.v1]" + - " contains instruction i[openEHR-EHR-INSTRUCTION.test_all_types.v1]"; - String csvTestSet = dirPath+"/testInstructionDrillDown.csv"; - - assertThat(testItemPaths(csvTestSet, rootPath, contains, referenceNode)).isTrue(); - } - - @Test - public void testActionDrillDown() throws IOException { - - String rootPath = "a"; - RMObject referenceNode = (RMObject) allTypesComposition - .itemsAtPath("/content[openEHR-EHR-SECTION.test_all_types.v1]/items[at0001]/items[at0002]/items[openEHR-EHR-ACTION.test_all_types.v1]").get(0); - String contains = "composition c[openEHR-EHR-COMPOSITION.test_all_types.v1]" + - " contains section s[openEHR-EHR-SECTION.test_all_types.v1]" + - " contains action a[openEHR-EHR-ACTION.test_all_types.v1]"; - String csvTestSet = dirPath+"/testActionDrillDown.csv"; - - assertThat(testItemPaths(csvTestSet, rootPath, contains, referenceNode)).isTrue(); - } - - @Test - public void testAdminEntryDrillDown() throws IOException { - - String rootPath = "a"; - RMObject referenceNode = (RMObject) allTypesComposition - .itemsAtPath("/content[openEHR-EHR-SECTION.test_all_types.v1]/items[at0001]/items[openEHR-EHR-ADMIN_ENTRY.test_all_types.v1]").get(0); - String contains = "composition c[openEHR-EHR-COMPOSITION.test_all_types.v1]" + - " contains section s[openEHR-EHR-SECTION.test_all_types.v1]" + - " contains ADMIN_ENTRY a[openEHR-EHR-ADMIN_ENTRY.test_all_types.v1]"; - String csvTestSet = dirPath+"/testAdminEntryDrillDown.csv"; - - assertThat(testItemPaths(csvTestSet, rootPath, contains, referenceNode)).isTrue(); - } - - private String buildAqlCompositionQuery(String rootPath, String attributePath, String containment){ - String aqlSelect = rootPath+"/"+attributePath; - StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.append("select "); - stringBuilder.append(aqlSelect); - stringBuilder.append(" from EHR e[ehr_id/value = $ehr_id]"); - stringBuilder.append(" contains "); - stringBuilder.append(containment); - stringBuilder.append(" WHERE c/uid/value = $comp_uuid"); - - return stringBuilder.toString(); - } - - private QueryResponseData performQuery(String rootPath, String attributePath, String containment){ - Query> query = Query.buildNativeQuery( - buildAqlCompositionQuery(rootPath, attributePath, containment) - , Map.class - ); - try { - return openEhrClient.aqlEndpoint().executeRaw(query, - new ParameterValue("ehr_id", ehrUUID), - new ParameterValue("comp_uuid", compositionUUID)); - } - catch (WrongStatusCodeException e){ - fail("path:"+rootPath+"/"+attributePath+", error"+e.getMessage()); - } - return null; - } - - private boolean testItemPaths(String csvTestSet, String rootPath, String contains, RMObject referenceNode) throws IOException { - BufferedReader inputCSVSetReader = new BufferedReader(new FileReader(csvTestSet)); - - String csvParams = null; - CsvParser csvParser = new CsvParser(new CsvParserSettings()); - - while ((csvParams = inputCSVSetReader.readLine()) != null) { - String[] params = csvParser.parseLine(csvParams); - String attributePath = params[0]; - if (params.length == 1 || (params.length > 1 && params[1] == null)) { //conventionally, if params[1] exists, this means skip the test - QueryResponseData result = performQuery(rootPath, attributePath, contains); - - List objectList = result.getRows().get(0); - - assertThat(valueObject(objectList.get(0))) - .as(rootPath + "/" + attributePath) - .isEqualTo(attributeValueAt(referenceNode, attributePath)); - } - } - - return true; - } } diff --git a/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/NumericTestsIT.java b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/NumericTestsIT.java new file mode 100644 index 000000000..322efb19d --- /dev/null +++ b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/NumericTestsIT.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2020 Christian Chevalley (Hannover Medical School) and Vitasystems GmbH + * + * This file is part of project EHRbase + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and limitations under the License. + */ + +package org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery; + +import com.nedap.archie.rm.composition.Composition; +import com.nedap.archie.rm.datastructures.Element; +import com.nedap.archie.rm.datavalues.DvText; +import com.nedap.archie.rm.datavalues.quantity.DvQuantity; +import org.apache.commons.io.IOUtils; +import org.ehrbase.client.Integration; +import org.ehrbase.client.classgenerator.examples.minimalevaluationenv1composition.MinimalEvaluationEnV1Composition; +import org.ehrbase.client.flattener.Flattener; +import org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery.queries.arbitrary.NumericQuery; +import org.ehrbase.client.templateprovider.TestDataTemplateProvider; +import org.ehrbase.serialisation.jsonencoding.CanonicalJson; +import org.ehrbase.test_data.composition.CompositionTestDataCanonicalJson; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +import static org.assertj.core.api.Assertions.assertThat; + +@Category(Integration.class) +public class NumericTestsIT extends CanonicalCompoAllTypeQueryIT { + + protected NumericQuery numericQuery; + + @Before + public void setUp() throws IOException { + super.setUp(null); + + //build a number of compositions with different DvQuantity values and different names + + aComposition = new CanonicalJson().unmarshal(IOUtils.toString(CompositionTestDataCanonicalJson.MINIMAL_EVAL.getStream(), StandardCharsets.UTF_8), Composition.class); + + for (int i=0; i< 10; i++){ + Element element = (Element) aComposition.itemsAtPath("/content[openEHR-EHR-EVALUATION.minimal.v1]/data[at0001]/items[at0002]").get(0); + element.setValue(new DvQuantity("kg", Double.valueOf(""+(i+1)), 0L)); + element.setName(new DvText("value-"+i+1)); + Flattener flattener = new Flattener(new TestDataTemplateProvider()); + MinimalEvaluationEnV1Composition minimalEvaluationEnV1Composition = flattener.flatten(aComposition, MinimalEvaluationEnV1Composition.class); +// create the composition + MinimalEvaluationEnV1Composition comp = compositionEndpoint.mergeCompositionEntity(minimalEvaluationEnV1Composition); + } + + numericQuery = new NumericQuery(ehrUUID, openEhrClient); + } + + @Test + public void testNumeric1() throws IOException { + String csvTestSet = dirPath+"/arbitrary/numeric_tests.csv"; + + assertThat(numericQuery.testItemPaths(dirPath+"/arbitrary", csvTestSet)).isTrue(); + } + +} diff --git a/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/SelectRMIT.java b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/SelectRMIT.java new file mode 100644 index 000000000..349a6f5ca --- /dev/null +++ b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/SelectRMIT.java @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2020 Christian Chevalley (Hannover Medical School) and Vitasystems GmbH + * + * This file is part of project EHRbase + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and limitations under the License. + */ + +package org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery; + +import com.nedap.archie.rm.RMObject; +import org.ehrbase.client.Integration; +import org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery.queries.simple.SimpleSelectQuery; +import org.ehrbase.response.openehr.QueryResponseData; +import org.ehrbase.test_data.composition.CompositionTestDataCanonicalJson; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.jupiter.params.shadow.com.univocity.parsers.csv.CsvParser; +import org.junit.jupiter.params.shadow.com.univocity.parsers.csv.CsvParserSettings; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThat; + +@Category(Integration.class) +public class SelectRMIT extends CanonicalCompoAllTypeQueryIT { + + protected SimpleSelectQuery simpleSelectQueryEngine; + + @Before + public void setUp() throws IOException { + super.setUp(CompositionTestDataCanonicalJson.ALL_TYPES_SYSTEMATIC_TESTS); + simpleSelectQueryEngine = new SimpleSelectQuery(ehrUUID, compositionUUID, openEhrClient); + } + + @Test + public void testCompositionAttributeQuery() throws IOException { + String rootPath = "c"; + RMObject referenceNode = aComposition; + + //reads in the test set + BufferedReader inputCSVSetReader = new BufferedReader(new FileReader("src/test/resources/testsets/testCompositionAttributeQuery.csv")); + + String csvParams; + CsvParser csvParser = new CsvParser(new CsvParserSettings()); + + while ((csvParams = inputCSVSetReader.readLine()) != null) { + String[] params = csvParser.parseLine(csvParams); + String attributePath = params[0]; + if (params.length == 1) { //conventionally, if params[1] exists, this means skip the test + QueryResponseData result = simpleSelectQueryEngine.performQuery(rootPath, attributePath, "composition c[openEHR-EHR-COMPOSITION.test_all_types.v1]"); + + List objectList = result.getRows().get(0); + + + //special case, c/uid is actually completed after db insertion, hence cannot be compared with the initial + //null value + if (attributePath.contains("uid")) { + assertThat(objectList.get(0)).isNotNull(); + } else + assertThat(valueObject(objectList.get(0))) + .as(rootPath + "/" + attributePath) + .isEqualTo(attributeValueAt(referenceNode, attributePath)); + } + } + } + + @Test + public void testContextAttributesDrillDown() throws IOException { + + String rootPath = "c/context"; + RMObject referenceNode = aComposition.getContext(); + String contains = "composition c[openEHR-EHR-COMPOSITION.test_all_types.v1]"; + String csvTestSet = dirPath+"/testContextAttributesDrillDown.csv"; + + assertThat(simpleSelectQueryEngine.testItemPaths(csvTestSet, rootPath, contains, referenceNode)).isTrue(); + } + + @Test + public void testObservationDrillDown() throws IOException { + + String rootPath = "o"; + RMObject referenceNode = (RMObject) aComposition.itemsAtPath("/content[openEHR-EHR-OBSERVATION.test_all_types.v1]").get(0); + String contains = "composition c[openEHR-EHR-COMPOSITION.test_all_types.v1]" + + " contains observation o[openEHR-EHR-OBSERVATION.test_all_types.v1]"; + String csvTestSet = dirPath+"/testObservationDrillDown.csv"; + + assertThat(simpleSelectQueryEngine.testItemPaths(csvTestSet, rootPath, contains, referenceNode)).isTrue(); + } + + @Test + public void testEvaluationDrillDown() throws IOException { + + String rootPath = "eval"; + RMObject referenceNode = (RMObject) aComposition.itemsAtPath("/content[openEHR-EHR-EVALUATION.test_all_types.v1]").get(0); + String contains = "composition c[openEHR-EHR-COMPOSITION.test_all_types.v1]" + + " contains evaluation eval[openEHR-EHR-EVALUATION.test_all_types.v1]"; + String csvTestSet = dirPath+"/testEvaluationDrillDown.csv"; + + assertThat(simpleSelectQueryEngine.testItemPaths(csvTestSet, rootPath, contains, referenceNode)).isTrue(); + } + + @Test + public void testSectionDrillDown() throws IOException { + + String rootPath = "s"; + RMObject referenceNode = (RMObject) aComposition.itemsAtPath("/content[openEHR-EHR-SECTION.test_all_types.v1]").get(0); + String contains = "composition c[openEHR-EHR-COMPOSITION.test_all_types.v1]" + + " contains section s[openEHR-EHR-SECTION.test_all_types.v1]"; + String csvTestSet = dirPath+"/testSectionDrillDown.csv"; + + assertThat(simpleSelectQueryEngine.testItemPaths(csvTestSet, rootPath, contains, referenceNode)).isTrue(); + } + + @Test + public void testInstructionDrillDown() throws IOException { + + String rootPath = "i"; + RMObject referenceNode = (RMObject) aComposition + .itemsAtPath("/content[openEHR-EHR-SECTION.test_all_types.v1]/items[at0001]/items[at0002]/items[openEHR-EHR-INSTRUCTION.test_all_types.v1]").get(0); + String contains = "composition c[openEHR-EHR-COMPOSITION.test_all_types.v1]" + + " contains section s[openEHR-EHR-SECTION.test_all_types.v1]" + + " contains instruction i[openEHR-EHR-INSTRUCTION.test_all_types.v1]"; + String csvTestSet = dirPath+"/testInstructionDrillDown.csv"; + + assertThat(simpleSelectQueryEngine.testItemPaths(csvTestSet, rootPath, contains, referenceNode)).isTrue(); + } + + @Test + public void testActionDrillDown() throws IOException { + + String rootPath = "a"; + RMObject referenceNode = (RMObject) aComposition + .itemsAtPath("/content[openEHR-EHR-SECTION.test_all_types.v1]/items[at0001]/items[at0002]/items[openEHR-EHR-ACTION.test_all_types.v1]").get(0); + String contains = "composition c[openEHR-EHR-COMPOSITION.test_all_types.v1]" + + " contains section s[openEHR-EHR-SECTION.test_all_types.v1]" + + " contains action a[openEHR-EHR-ACTION.test_all_types.v1]"; + String csvTestSet = dirPath+"/testActionDrillDown.csv"; + + assertThat(simpleSelectQueryEngine.testItemPaths(csvTestSet, rootPath, contains, referenceNode)).isTrue(); + } + + @Test + public void testAdminEntryDrillDown() throws IOException { + + String rootPath = "a"; + RMObject referenceNode = (RMObject) aComposition + .itemsAtPath("/content[openEHR-EHR-SECTION.test_all_types.v1]/items[at0001]/items[openEHR-EHR-ADMIN_ENTRY.test_all_types.v1]").get(0); + String contains = "composition c[openEHR-EHR-COMPOSITION.test_all_types.v1]" + + " contains section s[openEHR-EHR-SECTION.test_all_types.v1]" + + " contains ADMIN_ENTRY a[openEHR-EHR-ADMIN_ENTRY.test_all_types.v1]"; + String csvTestSet = dirPath+"/testAdminEntryDrillDown.csv"; + + assertThat(simpleSelectQueryEngine.testItemPaths(csvTestSet, rootPath, contains, referenceNode)).isTrue(); + } + +} diff --git a/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/AqlExpressionBuilder.java b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/AqlExpressionBuilder.java new file mode 100644 index 000000000..4461072d9 --- /dev/null +++ b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/AqlExpressionBuilder.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2020 Christian Chevalley (Hannover Medical School) and Vitasystems GmbH + * + * This file is part of project EHRbase + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and limitations under the License. + */ + +package org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery.queries; + +public class AqlExpressionBuilder { + private final String rootPath; + private final String attributePath; + private String containment; + + public AqlExpressionBuilder(String rootPath, String attributePath) { + this.rootPath = rootPath; + this.attributePath = attributePath; + } + + public AqlExpressionBuilder(String rootPath, String attributePath, String containment) { + this.rootPath = rootPath; + this.attributePath = attributePath; + this.containment = containment; + } + + public String composition(){ + String aqlSelect = rootPath+"/"+attributePath; + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("select "); + stringBuilder.append(aqlSelect); + stringBuilder.append(" from EHR e[ehr_id/value = $ehr_id]"); + stringBuilder.append(" contains "); + stringBuilder.append(containment); + stringBuilder.append(" WHERE c/uid/value = $comp_uuid"); + + return stringBuilder.toString(); + } + + public String composition(String whereCondition){ + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append(composition()); + stringBuilder.append(" AND "+whereCondition); + return stringBuilder.toString(); + } + + public String ehrStatus(){ + String aqlSelect = rootPath+"/"+attributePath; + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("select "); + stringBuilder.append(aqlSelect); + stringBuilder.append(" from EHR e[ehr_id/value = $ehr_id]"); + + return stringBuilder.toString(); + } + + public String ehrStatus(String whereCondition){ + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append(ehrStatus()); + stringBuilder.append(" WHERE "+whereCondition); + return stringBuilder.toString(); + } +} diff --git a/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/ParserSettings.java b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/ParserSettings.java new file mode 100644 index 000000000..7329865dd --- /dev/null +++ b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/ParserSettings.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2020 Christian Chevalley (Hannover Medical School) and Vitasystems GmbH + * + * This file is part of project EHRbase + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and limitations under the License. + */ + +package org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery.queries; + +import org.junit.jupiter.params.shadow.com.univocity.parsers.common.RowProcessorErrorHandler; +import org.junit.jupiter.params.shadow.com.univocity.parsers.common.processor.BeanListProcessor; +import org.junit.jupiter.params.shadow.com.univocity.parsers.csv.CsvParserSettings; + +import java.util.Arrays; + +public abstract class ParserSettings { + + protected CsvParserSettings settings = new CsvParserSettings(); + + public CsvParserSettings settings(){ + settings.getFormat().setComment('#'); + settings.getFormat().setDelimiter(','); + settings.setHeaderExtractionEnabled(false); + //skip empty lines + settings.setSkipEmptyLines(true); + settings.setProcessorErrorHandler((RowProcessorErrorHandler) (error, inputRow, context) -> { + throw new IllegalStateException("Error processing row: " + Arrays.toString(inputRow) + + " Error details: column '" + error.getColumnName() + + "' (index " + error.getColumnIndex() + ") has value '" + inputRow[error.getColumnIndex()] + "'"); + }); + return settings; + } +} diff --git a/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/TestQueryEngine.java b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/TestQueryEngine.java new file mode 100644 index 000000000..6b01d4c02 --- /dev/null +++ b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/TestQueryEngine.java @@ -0,0 +1,322 @@ +/* + * Copyright (c) 2020 Christian Chevalley (Hannover Medical School) and Vitasystems GmbH + * + * This file is part of project EHRbase + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and limitations under the License. + */ + +package org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery.queries; + +import com.nedap.archie.rm.RMObject; +import org.ehrbase.client.aql.parameter.ParameterValue; +import org.ehrbase.client.aql.query.Query; +import org.ehrbase.client.aql.record.Record1; +import org.ehrbase.client.exception.WrongStatusCodeException; +import org.ehrbase.client.openehrclient.OpenEhrClient; +import org.ehrbase.client.openehrclient.defaultrestclient.systematic.CanonicalUtil; +import org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery.queries.arbitrary.ArbitraryExpression; +import org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery.queries.arbitrary.ArbitraryExpressionSettings; +import org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery.queries.arbitrary.NumericExpression; +import org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery.queries.arbitrary.NumericExpressionSettings; +import org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery.queries.auto.AutoWhereCondition; +import org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery.queries.simple.PathExpression; +import org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery.queries.simple.SimplePathExpressionSettings; +import org.ehrbase.response.openehr.QueryResponseData; +import org.junit.jupiter.params.shadow.com.univocity.parsers.csv.CsvParser; + +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.lang.reflect.Method; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; + +public abstract class TestQueryEngine extends CanonicalUtil { + + private static final String FAIL_EXPECTED = "*FAIL*"; + + private final UUID ehrUUID; + private UUID compositionUUID; + private final OpenEhrClient openEhrClient; + + public TestQueryEngine(UUID ehrUUID, UUID compositionUUID, OpenEhrClient openEhrClient) { + this.ehrUUID = ehrUUID; + this.compositionUUID = compositionUUID; + this.openEhrClient = openEhrClient; + } + + public TestQueryEngine(UUID ehrUUID, OpenEhrClient openEhrClient) { + this.ehrUUID = ehrUUID; + this.openEhrClient = openEhrClient; + } + + + public boolean testItemPaths(String csvTestSet, String rootPath, String contains, RMObject referenceNode) throws IOException { + return false; + } + + + protected void checkSimpleQuery(String csvPath, String rootPath, String contains, RMObject referenceNode) throws FileNotFoundException { + SimplePathExpressionSettings simplePathExpressionSettings = new SimplePathExpressionSettings(); + CsvParser csvParser = new CsvParser(simplePathExpressionSettings.settings()); + csvParser.parse(new FileReader(csvPath)); + List attributeDefinitions = simplePathExpressionSettings.getPathExpressionRow().getBeans(); + + for (PathExpression pathExpression: attributeDefinitions) { + if (pathExpression.getComment() == null) { + String attributePath = pathExpression.getPath(); + QueryResponseData result = performQuery(rootPath, attributePath, contains); + try { + List objectList = result.getRows().get(0); + + assertThat(valueObject(objectList.get(0))) + .as(rootPath + "/" + attributePath) + .isEqualTo(attributeValueAt(referenceNode, attributePath)); + } catch (Exception e) { + fail(e.getMessage()); + } + } + } + } + + protected void checkAutoWhereQuery(String csvPath, String rootPath, String contains, RMObject referenceNode) throws FileNotFoundException { + SimplePathExpressionSettings simplePathExpressionSettings = new SimplePathExpressionSettings(); + CsvParser csvParser = new CsvParser(simplePathExpressionSettings.settings()); + csvParser.parse(new FileReader(csvPath)); + List attributeDefinitions = simplePathExpressionSettings.getPathExpressionRow().getBeans(); + + for (PathExpression pathExpression: attributeDefinitions) { + if (pathExpression.getComment() == null) { //conventionally, if params[1] exists, this means skip the test + String attributePath = pathExpression.getPath(); + + QueryResponseData result = performQueryWithWhere(rootPath, attributePath, contains, new AutoWhereCondition(rootPath, attributePath, referenceNode).condition()); + + if (result.getRows().isEmpty()) + fail(rootPath + "/" + attributePath + ": no result"); + + List objectList = result.getRows().get(0); + + assertThat(valueObject(objectList.get(0))) + .as(rootPath + "/" + attributePath) + .isEqualTo(attributeValueAt(referenceNode, attributePath)); + } + } + } + + protected void checkAutoEhrStatusWhereQuery(String csvPath, String rootPath, RMObject referenceNode) throws FileNotFoundException { + SimplePathExpressionSettings simplePathExpressionSettings = new SimplePathExpressionSettings(); + CsvParser csvParser = new CsvParser(simplePathExpressionSettings.settings()); + csvParser.parse(new FileReader(csvPath)); + List attributeDefinitions = simplePathExpressionSettings.getPathExpressionRow().getBeans(); + + for (PathExpression pathExpression: attributeDefinitions) { + if (pathExpression.getComment() == null) { + String attributePath = pathExpression.getPath(); + + QueryResponseData result = performEhrStatusQueryWithAutoWhere(rootPath, attributePath, referenceNode); + + if (result.getRows().isEmpty()) + fail(rootPath + "/" + attributePath + ": no result"); + + List objectList = result.getRows().get(0); + + assertThat(valueObject(objectList.get(0))) + .as(rootPath + "/" + attributePath) + .isEqualTo(attributeValueAt(referenceNode, attributePath)); + } + } + } + + + protected void checkArbitraryQuery(String dirPath, String csvPath) throws IOException { + + ArbitraryExpressionSettings arbitraryExpressionSettings = new ArbitraryExpressionSettings(); + CsvParser csvParser = new CsvParser(arbitraryExpressionSettings.settings()); + csvParser.parse(new FileReader(csvPath)); + List attributeDefinitions = arbitraryExpressionSettings.getArbitraryExpressionRow().getBeans(); + + for (ArbitraryExpression arbitraryExpression: attributeDefinitions) { + if (arbitraryExpression.getOptionalComment() == null) { + + String aql = arbitraryExpression.getRightSideExpression(); + + if (arbitraryExpression.getLeftSideExpressionPath() != null){ + String leftSide = Files.readString(Paths.get(dirPath+"/"+arbitraryExpression.getLeftSideExpressionPath())); + aql = leftSide+" WHERE "+ aql; + } + + boolean shouldFail = false; + + if (arbitraryExpression.getExpectedResult() != null) + shouldFail = arbitraryExpression.getExpectedResult().equals(FAIL_EXPECTED) ? true : false; + + QueryResponseData result = performAqlQuery(aql, shouldFail); + + if (shouldFail) + continue; + + if (result.getRows().isEmpty()) { + if (arbitraryExpression.getExpectedResult() == null) + continue; + else + fail(arbitraryExpression.getRightSideExpression() + ": no result"); + } + + //TODO: iterate on result + List objectList = result.getRows().get(0); + + assertThat(valueObject(objectList.get(0))) + .as(arbitraryExpression.getRightSideExpression()) + .isEqualTo(arbitraryExpression.getExpectedResult()); + } + } + + } + + protected void checkNumericQuery(String dirPath, String csvPath) throws IOException { + + NumericExpressionSettings numericLongExpressionSettings = new NumericExpressionSettings(); + CsvParser csvParser = new CsvParser(numericLongExpressionSettings.settings()); + csvParser.parse(new FileReader(csvPath)); + List attributeDefinitions = numericLongExpressionSettings.getNumericExpressionRow().getBeans(); + + for (NumericExpression numericExpression : attributeDefinitions) { + if (numericExpression.getOptionalComment() == null) { + + String leftSide = ""; + if (numericExpression.getLeftSideExpression() != null) + leftSide = Files.readString(Paths.get(dirPath+"/"+ numericExpression.getLeftSideExpression())); + + String aql; + if (!leftSide.isEmpty()) + aql = leftSide+" WHERE "+ numericExpression.getRightSideExpression(); + else + aql = numericExpression.getRightSideExpression(); + + boolean shouldFail = false; + + if (numericExpression.getExpectedResult() != null) + shouldFail = numericExpression.getExpectedResult().equals(-1L) ? true : false; + + QueryResponseData result = performAqlQuery(aql, shouldFail); + + if (shouldFail) + continue; + + if (result.getRows().isEmpty()) { + if (numericExpression.getExpectedResult() == null) + continue; + else + fail(numericExpression.getRightSideExpression() + ": no result"); + } + + Object expectedResult = numericExpression.getExpectedResult(); + try { + if (numericExpression.getJavaType() != null) { + Class clazz = Class.forName(numericExpression.getJavaType()); + Method valueOf = clazz.getMethod("valueOf", String.class); + expectedResult = valueOf.invoke(null, numericExpression.getExpectedResult()); + } + } + catch (Exception e){ + throw new IllegalArgumentException("Invalid data type:"+numericExpression.getJavaType()); + } + + //TODO: iterate on result + List objectList = result.getRows().get(0); + + assertThat(valueObject(objectList.get(0))) + .as(numericExpression.getRightSideExpression()) + .isEqualTo(expectedResult); + } + } + + } + + public QueryResponseData performQuery(String rootPath, String attributePath, String containment){ + Query> query = Query.buildNativeQuery( + new AqlExpressionBuilder(rootPath, attributePath, containment).composition() + , Map.class + ); + + return execute(query, rootPath, attributePath); + } + + private QueryResponseData performQueryWithWhere(String rootPath, String attributePath, String containment, String whereCondition){ + Query> query = Query.buildNativeQuery( + new AqlExpressionBuilder(rootPath, attributePath, containment).composition(whereCondition) + , Map.class + ); + + return execute(query, rootPath, attributePath); + } + + + + private QueryResponseData performAqlQuery(String aql, boolean shoudFail){ + Query> query = Query.buildNativeQuery( + aql + , Map.class + ); + return execute(query, aql, shoudFail); + } + + private QueryResponseData performEhrStatusQueryWithAutoWhere(String rootPath, String attributePath, RMObject referenceNode){ + + String whereCondition = new AutoWhereCondition(rootPath, attributePath, referenceNode).condition(); + + Query> query = Query.buildNativeQuery( + new AqlExpressionBuilder(rootPath, attributePath).ehrStatus(whereCondition) + , Map.class + ); + + try { + return openEhrClient.aqlEndpoint().executeRaw(query, + new ParameterValue("ehr_id", ehrUUID)); + } + catch (WrongStatusCodeException e){ + fail("path:"+rootPath+"/"+attributePath+", error"+e.getMessage()); + } + return null; + } + + protected QueryResponseData execute(Query> query, String rootPath, String attributePath){ + try { + return openEhrClient.aqlEndpoint().executeRaw(query, + new ParameterValue("ehr_id", ehrUUID), + new ParameterValue("comp_uuid", compositionUUID)); + } + catch (WrongStatusCodeException e){ + fail("path:"+rootPath+"/"+attributePath+", error"+e.getMessage()); + } + return null; + } + + protected QueryResponseData execute(Query> query, String aql, boolean shouldFail){ + try { + return openEhrClient.aqlEndpoint().executeRaw(query, new ParameterValue("ehr_id", ehrUUID)); + } + catch (WrongStatusCodeException e){ + if (!shouldFail) + fail("Query is not successful, path:"+aql+", error"+e.getMessage()); + } + return null; + } + +} diff --git a/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/arbitrary/ArbitraryExpression.java b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/arbitrary/ArbitraryExpression.java new file mode 100644 index 000000000..5be01657b --- /dev/null +++ b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/arbitrary/ArbitraryExpression.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2020 Christian Chevalley (Hannover Medical School) and Vitasystems GmbH + * + * This file is part of project EHRbase + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and limitations under the License. + */ + +package org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery.queries.arbitrary; + +import org.junit.jupiter.params.shadow.com.univocity.parsers.annotations.Parsed; + +public class ArbitraryExpression { + + //accept substitution f.e. $ehr_id or $composition_id + @Parsed(index = 0) + private String leftSideExpressionPath; + + @Parsed(index = 1) + private String rightSideExpression; + + //accept substitution f.e. $ehr_id or $composition_id + @Parsed(index = 2) + private String expectedResult; + + @Parsed(index = 3) + private String optionalComment; + + public String getLeftSideExpressionPath() { + return leftSideExpressionPath; + } + + public String getRightSideExpression() { + return rightSideExpression; + } + + public String getExpectedResult() { + return expectedResult; + } + + public String getOptionalComment() { + return optionalComment; + } +} diff --git a/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/arbitrary/ArbitraryExpressionSettings.java b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/arbitrary/ArbitraryExpressionSettings.java new file mode 100644 index 000000000..f30efa99f --- /dev/null +++ b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/arbitrary/ArbitraryExpressionSettings.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2020 Christian Chevalley (Hannover Medical School) and Vitasystems GmbH + * + * This file is part of project EHRbase + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and limitations under the License. + */ + +package org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery.queries.arbitrary; + +import org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery.queries.ParserSettings; +import org.junit.jupiter.params.shadow.com.univocity.parsers.common.processor.BeanListProcessor; +import org.junit.jupiter.params.shadow.com.univocity.parsers.csv.CsvParserSettings; + +public class ArbitraryExpressionSettings extends ParserSettings { + + private final BeanListProcessor arbitraryExpressionRow = new BeanListProcessor<>(ArbitraryExpression.class); + + public CsvParserSettings settings(){ + super.settings(); + settings.setProcessor(arbitraryExpressionRow); + return settings; + } + + public BeanListProcessor getArbitraryExpressionRow() { + return arbitraryExpressionRow; + } +} diff --git a/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/arbitrary/ArbitraryQuery.java b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/arbitrary/ArbitraryQuery.java new file mode 100644 index 000000000..43f174049 --- /dev/null +++ b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/arbitrary/ArbitraryQuery.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2020 Christian Chevalley (Hannover Medical School) and Vitasystems GmbH + * + * This file is part of project EHRbase + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and limitations under the License. + */ + +package org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery.queries.arbitrary; + +import org.ehrbase.client.openehrclient.OpenEhrClient; +import org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery.queries.TestQueryEngine; + +import java.io.IOException; +import java.util.UUID; + +public class ArbitraryQuery extends TestQueryEngine { + + public ArbitraryQuery(UUID ehrUUID, OpenEhrClient openEhrClient) { + super(ehrUUID, openEhrClient); + } + + public boolean testItemPaths(String dirPath, String csvTestSet) throws IOException { + checkArbitraryQuery(dirPath, csvTestSet); + return true; + } + +} diff --git a/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/arbitrary/NumericExpression.java b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/arbitrary/NumericExpression.java new file mode 100644 index 000000000..78c4a0b57 --- /dev/null +++ b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/arbitrary/NumericExpression.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2020 Christian Chevalley (Hannover Medical School) and Vitasystems GmbH + * + * This file is part of project EHRbase + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and limitations under the License. + */ + +package org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery.queries.arbitrary; + +import org.junit.jupiter.params.shadow.com.univocity.parsers.annotations.Parsed; + +public class NumericExpression { + + //accept substitution f.e. $ehr_id or $composition_id + @Parsed(index = 0) + private String leftSideExpression; + + @Parsed(index = 1) + private String rightSideExpression; + + //accept substitution f.e. $ehr_id or $composition_id + @Parsed(index = 2) + private String expectedResult; + + @Parsed(index = 3) + private String javaType; + + @Parsed(index = 4) + private String optionalComment; + + public String getLeftSideExpression() { + return leftSideExpression; + } + + public String getRightSideExpression() { + return rightSideExpression; + } + + public String getExpectedResult() { + return expectedResult; + } + + public String getJavaType() { + return javaType; + } + public String getOptionalComment() { + return optionalComment; + } +} diff --git a/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/arbitrary/NumericExpressionSettings.java b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/arbitrary/NumericExpressionSettings.java new file mode 100644 index 000000000..7a8cea72b --- /dev/null +++ b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/arbitrary/NumericExpressionSettings.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2020 Christian Chevalley (Hannover Medical School) and Vitasystems GmbH + * + * This file is part of project EHRbase + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and limitations under the License. + */ + +package org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery.queries.arbitrary; + +import org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery.queries.ParserSettings; +import org.junit.jupiter.params.shadow.com.univocity.parsers.common.processor.BeanListProcessor; +import org.junit.jupiter.params.shadow.com.univocity.parsers.csv.CsvParserSettings; + +public class NumericExpressionSettings extends ParserSettings { + + private final BeanListProcessor numericExpressionRow = new BeanListProcessor<>(NumericExpression.class); + + public CsvParserSettings settings(){ + super.settings(); + settings.setProcessor(numericExpressionRow); + return settings; + } + + public BeanListProcessor getNumericExpressionRow() { + return numericExpressionRow; + } +} diff --git a/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/arbitrary/NumericQuery.java b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/arbitrary/NumericQuery.java new file mode 100644 index 000000000..2852e2e0f --- /dev/null +++ b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/arbitrary/NumericQuery.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2020 Christian Chevalley (Hannover Medical School) and Vitasystems GmbH + * + * This file is part of project EHRbase + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and limitations under the License. + */ + +package org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery.queries.arbitrary; + +import org.ehrbase.client.openehrclient.OpenEhrClient; +import org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery.queries.TestQueryEngine; + +import java.io.IOException; +import java.util.UUID; + +public class NumericQuery extends TestQueryEngine { + + public NumericQuery(UUID ehrUUID, OpenEhrClient openEhrClient) { + super(ehrUUID, openEhrClient); + } + + public boolean testItemPaths(String dirPath, String csvTestSet) throws IOException { + checkNumericQuery(dirPath, csvTestSet); + return true; + } + +} diff --git a/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/auto/AutoEhrStatusWhereQuery.java b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/auto/AutoEhrStatusWhereQuery.java new file mode 100644 index 000000000..d7a478a97 --- /dev/null +++ b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/auto/AutoEhrStatusWhereQuery.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2020 Christian Chevalley (Hannover Medical School) and Vitasystems GmbH + * + * This file is part of project EHRbase + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and limitations under the License. + */ + +package org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery.queries.auto; + +import com.nedap.archie.rm.RMObject; +import org.ehrbase.client.openehrclient.OpenEhrClient; +import org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery.queries.TestQueryEngine; + +import java.io.IOException; +import java.util.UUID; + +public class AutoEhrStatusWhereQuery extends TestQueryEngine { + + public AutoEhrStatusWhereQuery(UUID ehrUUID, OpenEhrClient openEhrClient) { + super(ehrUUID, openEhrClient); + } + + public boolean testItemPaths(String csvTestSet, String rootPath, RMObject referenceNode) throws IOException { + checkAutoEhrStatusWhereQuery(csvTestSet, rootPath, referenceNode); + return true; + } + +} diff --git a/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/auto/AutoWhereCondition.java b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/auto/AutoWhereCondition.java new file mode 100644 index 000000000..148abd193 --- /dev/null +++ b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/auto/AutoWhereCondition.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2020 Christian Chevalley (Hannover Medical School) and Vitasystems GmbH + * + * This file is part of project EHRbase + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and limitations under the License. + */ + +package org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery.queries.auto; + +import com.nedap.archie.rm.RMObject; +import org.ehrbase.client.openehrclient.defaultrestclient.systematic.SpecialCase; + +import static org.ehrbase.client.openehrclient.defaultrestclient.systematic.CanonicalUtil.attributeValueAt; + +public class AutoWhereCondition { + + private final String rootPath; + private final String attributePath; + private final RMObject referenceNode; + + public AutoWhereCondition(String rootPath, String attributePath, RMObject referenceNode) { + this.rootPath = rootPath; + this.attributePath = attributePath; + this.referenceNode = referenceNode; + } + + public String condition(){ + + Object reference = attributeValueAt(referenceNode, attributePath); + + StringBuilder autoWhereCondition = new StringBuilder(); + autoWhereCondition.append(rootPath+"/"+attributePath); + autoWhereCondition.append(" = "); + Object filterObject = new SpecialCase().transform(reference); + autoWhereCondition.append(filterObject instanceof String ? "'"+filterObject+"'" : filterObject); + + return autoWhereCondition.toString(); + } +} diff --git a/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/auto/AutoWhereQuery.java b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/auto/AutoWhereQuery.java new file mode 100644 index 000000000..24d9ae7d5 --- /dev/null +++ b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/auto/AutoWhereQuery.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2020 Christian Chevalley (Hannover Medical School) and Vitasystems GmbH + * + * This file is part of project EHRbase + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and limitations under the License. + */ + +package org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery.queries.auto; + +import com.nedap.archie.rm.RMObject; +import org.ehrbase.client.openehrclient.OpenEhrClient; +import org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery.queries.TestQueryEngine; + +import java.io.IOException; +import java.util.UUID; + +public class AutoWhereQuery extends TestQueryEngine { + + public AutoWhereQuery(UUID ehrUUID, UUID compositionUUID, OpenEhrClient openEhrClient) { + super(ehrUUID, compositionUUID, openEhrClient); + } + + public boolean testItemPaths(String csvTestSet, String rootPath, String contains, RMObject referenceNode) throws IOException { + checkAutoWhereQuery(csvTestSet, rootPath, contains, referenceNode); + return true; + } + +} diff --git a/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/simple/PathExpression.java b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/simple/PathExpression.java new file mode 100644 index 000000000..73ebffd97 --- /dev/null +++ b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/simple/PathExpression.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2020 Christian Chevalley (Hannover Medical School) and Vitasystems GmbH + * + * This file is part of project EHRbase + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and limitations under the License. + */ + +package org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery.queries.simple; + +import org.junit.jupiter.params.shadow.com.univocity.parsers.annotations.Parsed; + +public class PathExpression { + + @Parsed(index = 0) + private String path; + + @Parsed(index = 1) + private String comment; + + public String getPath() { + return path; + } + + public String getComment() { + return comment; + } +} diff --git a/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/simple/SimplePathExpressionSettings.java b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/simple/SimplePathExpressionSettings.java new file mode 100644 index 000000000..e9fb06c36 --- /dev/null +++ b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/simple/SimplePathExpressionSettings.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2020 Christian Chevalley (Hannover Medical School) and Vitasystems GmbH + * + * This file is part of project EHRbase + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and limitations under the License. + */ + +package org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery.queries.simple; + +import org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery.queries.ParserSettings; +import org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery.queries.simple.PathExpression; +import org.junit.jupiter.params.shadow.com.univocity.parsers.common.processor.BeanListProcessor; +import org.junit.jupiter.params.shadow.com.univocity.parsers.csv.CsvParserSettings; + +public class SimplePathExpressionSettings extends ParserSettings { + + private BeanListProcessor pathExpressionRow = new BeanListProcessor<>(PathExpression.class); + + public CsvParserSettings settings(){ + super.settings(); + settings.setProcessor(pathExpressionRow); + return settings; + } + + public BeanListProcessor getPathExpressionRow() { + return pathExpressionRow; + } +} diff --git a/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/simple/SimpleSelectQuery.java b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/simple/SimpleSelectQuery.java new file mode 100644 index 000000000..ffad59ff4 --- /dev/null +++ b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/compositionquery/queries/simple/SimpleSelectQuery.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2020 Christian Chevalley (Hannover Medical School) and Vitasystems GmbH + * + * This file is part of project EHRbase + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and limitations under the License. + */ + +package org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery.queries.simple; + +import com.nedap.archie.rm.RMObject; +import org.ehrbase.client.openehrclient.OpenEhrClient; +import org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery.queries.TestQueryEngine; + +import java.io.IOException; +import java.util.UUID; + +public class SimpleSelectQuery extends TestQueryEngine { + + public SimpleSelectQuery(UUID ehrUUID, UUID compositionUUID, OpenEhrClient openEhrClient) { + super(ehrUUID, compositionUUID, openEhrClient); + } + + public boolean testItemPaths(String csvTestSet, String rootPath, String contains, RMObject referenceNode) throws IOException { + checkSimpleQuery(csvTestSet, rootPath, contains, referenceNode); + return true; + } + +} diff --git a/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/ehrquery/CanonicalEhrQuery3IT.java b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/ehrquery/CanonicalEhrQuery3IT.java index f589c902e..f617ff0e0 100644 --- a/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/ehrquery/CanonicalEhrQuery3IT.java +++ b/client/src/test/java/org/ehrbase/client/openehrclient/defaultrestclient/systematic/ehrquery/CanonicalEhrQuery3IT.java @@ -26,7 +26,8 @@ import org.ehrbase.client.aql.record.Record1; import org.ehrbase.client.openehrclient.OpenEhrClient; import org.ehrbase.client.openehrclient.defaultrestclient.DefaultRestClientTestHelper; -import org.ehrbase.client.openehrclient.defaultrestclient.systematic.CanonicalUtil; +import org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery.CanonicalCompoAllTypeQueryIT; +import org.ehrbase.client.openehrclient.defaultrestclient.systematic.compositionquery.queries.auto.AutoEhrStatusWhereQuery; import org.ehrbase.response.openehr.QueryResponseData; import org.ehrbase.serialisation.jsonencoding.CanonicalJson; import org.ehrbase.test_data.ehr.EhrTestDataCanonicalJson; @@ -44,7 +45,7 @@ @Category(Integration.class) //@Ignore -public class CanonicalEhrQuery3IT extends CanonicalUtil { +public class CanonicalEhrQuery3IT extends CanonicalCompoAllTypeQueryIT { private static OpenEhrClient openEhrClient; private UUID ehrUUID; @@ -132,4 +133,15 @@ public void testEhrAttributesDrillDown(){ } } + @Test + public void testEhrAutoWhere() throws IOException { + EhrStatus referenceEhrStatus = new CanonicalJson().unmarshal(IOUtils.toString(EhrTestDataCanonicalJson.EHR_STATUS_SUBJECT_EXTERNAL_REF_OTHER_DETAILS.getStream(), StandardCharsets.UTF_8), EhrStatus.class); + + String rootPath = "e/ehr_status"; + RMObject referenceNode = referenceEhrStatus; + String csvTestSet = dirPath+"/testEhrStatusWhere.csv"; + + assertThat(new AutoEhrStatusWhereQuery(ehrUUID, openEhrClient).testItemPaths(csvTestSet, rootPath, referenceNode)).isTrue(); + } + } diff --git a/client/src/test/resources/testsets/arbitrary/all_types_action_select.txt b/client/src/test/resources/testsets/arbitrary/all_types_action_select.txt new file mode 100644 index 000000000..f3ca5b8a7 --- /dev/null +++ b/client/src/test/resources/testsets/arbitrary/all_types_action_select.txt @@ -0,0 +1,5 @@ +select + c/name/value + from EHR e + contains COMPOSITION c + contains ACTION d[openEHR-EHR-ACTION.test_all_types.v1] \ No newline at end of file diff --git a/client/src/test/resources/testsets/arbitrary/arbitrary_boolean_where_tests.csv b/client/src/test/resources/testsets/arbitrary/arbitrary_boolean_where_tests.csv new file mode 100644 index 000000000..3fa6a99a8 --- /dev/null +++ b/client/src/test/resources/testsets/arbitrary/arbitrary_boolean_where_tests.csv @@ -0,0 +1,24 @@ +all_types_action_select.txt, d/description[at0001]/items[openEHR-EHR-CLUSTER.test_all_types.v1]/items[at0001]/items[at0002]/items[at0003]/value/value = 'hello',*FAIL* +all_types_action_select.txt, NOT (d/description[at0001]/items[openEHR-EHR-CLUSTER.test_all_types.v1]/items[at0001]/items[at0002]/items[at0003]/value/value = false),Test all types +all_types_action_select.txt, d/description[at0001]/items[openEHR-EHR-CLUSTER.test_all_types.v1]/items[at0001]/items[at0002]/items[at0003]/value/value != false,Test all types +all_types_action_select.txt, d/description[at0001]/items[openEHR-EHR-CLUSTER.test_all_types.v1]/items[at0001]/items[at0002]/items[at0003]/value/value = true,Test all types +all_types_action_select.txt, d/description[at0001]/items[openEHR-EHR-CLUSTER.test_all_types.v1]/items[at0001]/items[at0002]/items[at0003]/value/value = true AND d/description[at0001]/items[openEHR-EHR-CLUSTER.test_all_types.v1]/items[at0001]/items[at0002]/items[at0003]/value/value != false,Test all types +all_types_action_select.txt, d/description[at0001]/items[openEHR-EHR-CLUSTER.test_all_types.v1]/items[at0001]/items[at0002]/items[at0003]/value/value = true OR d/description[at0001]/items[openEHR-EHR-CLUSTER.test_all_types.v1]/items[at0001]/items[at0002]/items[at0003]/value/value = false,Test all types +all_types_action_select.txt, d/description[at0001]/items[openEHR-EHR-CLUSTER.test_all_types.v1]/items[at0001]/items[at0002]/items[at0003]/value/value IN (true),Test all types +all_types_action_select.txt, true = SOME(d/description[at0001]/items[openEHR-EHR-CLUSTER.test_all_types.v1]/items[at0001]/items[at0002]/items[at0003]/value/value),Test all types +all_types_action_select.txt, true = ANY(d/description[at0001]/items[openEHR-EHR-CLUSTER.test_all_types.v1]/items[at0001]/items[at0002]/items[at0003]/value/value),Test all types +all_types_action_select.txt, true = ANY(d/description[at0001]/items[openEHR-EHR-CLUSTER.test_all_types.v1]/items[at0001]/items[at0002]/items[at0003]/value/value),Test all types +all_types_action_select.txt, true = ALL(d/description[at0001]/items[openEHR-EHR-CLUSTER.test_all_types.v1]/items[at0001]/items[at0002]/items[at0003]/value/value),Test all types +all_types_action_select.txt, false = ALL(d/description[at0001]/items[openEHR-EHR-CLUSTER.test_all_types.v1]/items[at0001]/items[at0002]/items[at0003]/value/value) +all_types_action_select.txt, d/description[at0001]/items[openEHR-EHR-CLUSTER.test_all_types.v1]/items[at0001]/items[at0002]/items[at0003]/value/value IS TRUE,Test all types +all_types_action_select.txt, d/description[at0001]/items[openEHR-EHR-CLUSTER.test_all_types.v1]/items[at0001]/items[at0002]/items[at0003]/value/value IS NOT FALSE,Test all types +all_types_action_select.txt, d/description[at0001]/items[openEHR-EHR-CLUSTER.test_all_types.v1]/items[at0001]/items[at0002]/items[at0003]/value/value IS FALSE +all_types_action_select.txt, d/description[at0001]/items[openEHR-EHR-CLUSTER.test_all_types.v1]/items[at0001]/items[at0002]/items[at0003]/value/value IS NULL +all_types_action_select.txt, d/description[at0001]/items[openEHR-EHR-CLUSTER.test_all_types.v1]/items[at0001]/items[at0002]/items[at0003]/value/value IS NOT NULL,Test all types +all_types_action_select.txt, d/description[at0001]/items[openEHR-EHR-CLUSTER.test_all_types.v1]/items[at0001]/items[at0002]/items[at0003]/value/value IS DISTINCT FROM FALSE,Test all types +all_types_action_select.txt, d/description[at0001]/items[openEHR-EHR-CLUSTER.test_all_types.v1]/items[at0001]/items[at0002]/items[at0003]/value/value IS DISTINCT FROM TRUE +all_types_action_select.txt, d/description[at0001]/items[openEHR-EHR-CLUSTER.test_all_types.v1]/items[at0001]/items[at0002]/items[at0003]/value/value IS NOT DISTINCT FROM TRUE,Test all types +all_types_action_select.txt, d/description[at0001]/items[openEHR-EHR-CLUSTER.test_all_types.v1]/items[at0001]/items[at0002]/items[at0003]/value/value BETWEEN TRUE AND TRUE,Test all types +all_types_action_select.txt, d/description[at0001]/items[openEHR-EHR-CLUSTER.test_all_types.v1]/items[at0001]/items[at0002]/items[at0003]/value/value NOT BETWEEN FALSE AND FALSE,Test all types +all_types_action_select.txt, d/description[at0001]/items[openEHR-EHR-CLUSTER.test_all_types.v1]/items[at0001]/items[at0002]/items[at0003]/value/value IS NOT UNKNOWN,Test all types + diff --git a/client/src/test/resources/testsets/arbitrary/arbitrary_tests.csv b/client/src/test/resources/testsets/arbitrary/arbitrary_tests.csv new file mode 100644 index 000000000..b49500126 --- /dev/null +++ b/client/src/test/resources/testsets/arbitrary/arbitrary_tests.csv @@ -0,0 +1,72 @@ +# check partial string comparison + +#functions +# TODO: implement function support in WHERE +string_tests_select.txt, "SUBSTR(o/data[at0001]/events[at0002]/data[at0003]/items[at0004]/value/value,1,3)='the'","the quick brown fox jumps over the lazy dog",$FAIL$ + +# supported functions in SELECT +# substring +,"select SUBSTR(o/data[at0001]/events[at0002]/data[at0003]/items[at0004]/value/value,1,3) from EHR e contains COMPOSITION c contains OBSERVATION o[openEHR-EHR-OBSERVATION.test_all_types.v1] ",the +# split string on delimiter and returns the nth element +,"select SPLIT_PART(o/data[at0001]/events[at0002]/data[at0003]/items[at0004]/value/value,' ',3) from EHR e contains COMPOSITION c contains OBSERVATION o[openEHR-EHR-OBSERVATION.test_all_types.v1] ",brown +# trim leading and trailing char (here space) +,"select BTRIM(o/data[at0001]/events[at0002]/data[at0003]/items[at0004]/value/value,' ') from EHR e contains COMPOSITION c contains OBSERVATION o[openEHR-EHR-OBSERVATION.test_all_types.v1] ","the quick brown fox jumps over the lazy dog" +# concatenate strings +,"select CONCAT(o/data[at0001]/events[at0002]/data[at0003]/items[at0004]/value/value,'1234') from EHR e contains COMPOSITION c contains OBSERVATION o[openEHR-EHR-OBSERVATION.test_all_types.v1] ","the quick brown fox jumps over the lazy dog1234" +# CONCAT_WS function is used to concatenate strings with a separator +,"select CONCAT_WS(',',o/data[at0001]/events[at0002]/data[at0003]/items[at0004]/value/value,'1234') from EHR e contains COMPOSITION c contains OBSERVATION o[openEHR-EHR-OBSERVATION.test_all_types.v1] ","the quick brown fox jumps over the lazy dog,1234" +# encoding -- FAILS +#,"select ENCODE(o/data[at0001]/events[at0002]/data[at0003]/items[at0004]/value/value,'base64') from EHR e contains COMPOSITION c contains OBSERVATION o[openEHR-EHR-OBSERVATION.test_all_types.v1] ",$FAIL$ +# formatting +,"select FORMAT("EHRbase is %s",'great!') from EHR e contains COMPOSITION c contains OBSERVATION o[openEHR-EHR-OBSERVATION.test_all_types.v1] ","EHRbase is great!" +# Initial cap +,"select INITCAP(o/data[at0001]/events[at0002]/data[at0003]/items[at0004]/value/value) from EHR e contains COMPOSITION c contains OBSERVATION o[openEHR-EHR-OBSERVATION.test_all_types.v1] ","The Quick Brown Fox Jumps Over The Lazy Dog" +# left substr +,"select LEFT(o/data[at0001]/events[at0002]/data[at0003]/items[at0004]/value/value,4) from EHR e contains COMPOSITION c contains OBSERVATION o[openEHR-EHR-OBSERVATION.test_all_types.v1] ","the " +# right substr +,"select RIGHT(o/data[at0001]/events[at0002]/data[at0003]/items[at0004]/value/value,4) from EHR e contains COMPOSITION c contains OBSERVATION o[openEHR-EHR-OBSERVATION.test_all_types.v1] "," dog" +# left pad +,"select LPAD('EHRbase',11, '!') from EHR e ","!!!!EHRbase" +# right pad +,"select RPAD('EHRbase',11, '!') from EHR e ","EHRbase!!!!" +# trim functions +,"select LTRIM('EHRbase','E') from EHR e ","HRbase" +,"select RTRIM('EHRbase','e') from EHR e ","EHRbas" +,"select BTRIM(' EHRbase ',' ') from EHR e ","EHRbase" +# regexp +# FAILS as fct returns an array! +#,"select REGEXP_MATCH(o/data[at0001]/events[at0002]/data[at0003]/items[at0004]/value/value,'quick|fox') from EHR e contains COMPOSITION c contains OBSERVATION o[openEHR-EHR-OBSERVATION.test_all_types.v1] "," dog" +# repeat string +,"select REPEAT('EHRbase ',2) from EHR e ","EHRbase EHRbase " +# replace +,"select REPEAT('EHRbase ',2) from EHR e ","EHRbase EHRbase " +# reverse +,"select REVERSE('EHRbase') from EHR e ","esabRHE" +# translate +# Seems reverse back is not reliable! Do not use! +#,"select TRANSLATE(o/data[at0001]/events[at0002]/ata[at0003]/items[at0004]/value/value,'abcdefghijklmnopqrstuvwxyz','0123456789acwrvyuiopkjhbq0123456789acwrvyuiopkjhbq') from EHR e contains COMPOSITION c contains OBSERVATION o[openEHR-EHR-OBSERVATION.test_all_types.v1] ","p74 uk82a 1ivhr 5vb 9kwyo vj4i p74 c00q 3v6" +#,"select TRANSLATE('p74 uk82a 1ivhr 5vb 9kwyo vj4i p74 c00q 3v6','0123456789acwrvyuiopkjhbq0123456789acwrvyuiopkjhbq', 'abcdefghijklmnopqrstuvwxyz') from EHR e","s74 gg82j 1fhfj 5hj 9gfdj hd4f s74 g0gh 3h6" + + +#nested function calls +# REQUIRES EXTENSIVE TESTING! +,"select LEFT(REPEAT('EHRbase ',2),3) from EHR e ","EHR" +# playing with CAST +,"select CAST('2019-12-23 14:39:53.662522-05' AS 'DATE') as cast1 from EHR e","2019-12-23" +,"select CAST('2019-12-23 14:39:53.662522-05' AS 'TIME') as cast1 from EHR e","14:39:53" +# Constants +#,select TRUE from EHR e,TRUE +#,select FALSE from EHR e,FALSE + + + +# SIMILAR uses a regexp (see https://www.postgresql.org/docs/13/functions-matching.html#FUNCTIONS-SIMILARTO-REGEXP) +string_tests_select.txt, "o/data[at0001]/events[at0002]/data[at0003]/items[at0004]/value/value SIMILAR TO '([a-z]| )*'","the quick brown fox jumps over the lazy dog" + +# standard like/ilike matching +string_tests_select.txt, "o/data[at0001]/events[at0002]/data[at0003]/items[at0004]/value/value LIKE 'the%'","the quick brown fox jumps over the lazy dog" +string_tests_select.txt, "o/data[at0001]/events[at0002]/data[at0003]/items[at0004]/value/value LIKE '__________brown____________________________'","the quick brown fox jumps over the lazy dog" +string_tests_select.txt, "o/data[at0001]/events[at0002]/data[at0003]/items[at0004]/value/value ILIKE '%FOX%'","the quick brown fox jumps over the lazy dog" + + + diff --git a/client/src/test/resources/testsets/arbitrary/date_time_tests_select.txt b/client/src/test/resources/testsets/arbitrary/date_time_tests_select.txt new file mode 100644 index 000000000..f8c5a768d --- /dev/null +++ b/client/src/test/resources/testsets/arbitrary/date_time_tests_select.txt @@ -0,0 +1,5 @@ +select + c/name/value + from EHR e + contains COMPOSITION c + contains OBSERVATION o[openEHR-EHR-OBSERVATION.test_all_types.v1] \ No newline at end of file diff --git a/client/src/test/resources/testsets/arbitrary/date_time_where_tests.csv b/client/src/test/resources/testsets/arbitrary/date_time_where_tests.csv new file mode 100644 index 000000000..d7a90b4ba --- /dev/null +++ b/client/src/test/resources/testsets/arbitrary/date_time_where_tests.csv @@ -0,0 +1,20 @@ +# the path is quoted as it contains a comma (csv delimiter) +date_time_tests_select.txt, "o/data[at0001]/events[at0002]/data[at0003]/items[at0011]/value/value = '2019-01-28T21:22:49,427+07:00'",Test all types + +# test comparison with partial date/time +date_time_tests_select.txt, o/data[at0001]/events[at0002]/data[at0003]/items[at0011]/value/value > '2021' AND o/data[at0001]/events[at0002]/data[at0003]/items[at0011]/value/value < '2022', +date_time_tests_select.txt, o/data[at0001]/events[at0002]/data[at0003]/items[at0011]/value/value > '2019' AND o/data[at0001]/events[at0002]/data[at0003]/items[at0011]/value/value < '2020',Test all types +date_time_tests_select.txt, o/data[at0001]/events[at0002]/data[at0003]/items[at0011]/value/value > '2019-01' AND o/data[at0001]/events[at0002]/data[at0003]/items[at0011]/value/value < '2019-12',Test all types +date_time_tests_select.txt, o/data[at0001]/events[at0002]/data[at0003]/items[at0011]/value/value > '2019-01-01' AND o/data[at0001]/events[at0002]/data[at0003]/items[at0011]/value/value < '2019-01-31',Test all types +date_time_tests_select.txt, o/data[at0001]/events[at0002]/data[at0003]/items[at0011]/value/value > '2019-01-28T01' AND o/data[at0001]/events[at0002]/data[at0003]/items[at0011]/value/value < '2019-01-28T24',Test all types +date_time_tests_select.txt, o/data[at0001]/events[at0002]/data[at0003]/items[at0011]/value/value > '2019-01-28T21:00' AND o/data[at0001]/events[at0002]/data[at0003]/items[at0011]/value/value < '2019-01-28T21:59',Test all types +date_time_tests_select.txt, o/data[at0001]/events[at0002]/data[at0003]/items[at0011]/value/value > '2019-01-28T21:22:00' AND o/data[at0001]/events[at0002]/data[at0003]/items[at0011]/value/value < '2019-01-28T21:22:59',Test all types + +# TODO: add date time casting and function to allow partial date/time equality when millisecs is part of the date/time expression +# at the moment, this test returns an empty set +date_time_tests_select.txt, o/data[at0001]/events[at0002]/data[at0003]/items[at0011]/value/value = '2019-01-28T21:22:49', + +#interval +date_time_tests_select.txt, o/data[at0001]/events[at0002]/data[at0003]/items[at0011]/value/value >= '2019-01-28T21:22:00' AND o/data[at0001]/events[at0002]/data[at0003]/items[at0011]/value/value <= '2019-01-28T21:22:59',Test all types +date_time_tests_select.txt, o/data[at0001]/events[at0002]/data[at0003]/items[at0011]/value/value BETWEEN '2019-01-28T21:22:00' AND '2019-01-28T21:22:59',Test all types + diff --git a/client/src/test/resources/testsets/arbitrary/numeric_count_select.txt b/client/src/test/resources/testsets/arbitrary/numeric_count_select.txt new file mode 100644 index 000000000..6132caa57 --- /dev/null +++ b/client/src/test/resources/testsets/arbitrary/numeric_count_select.txt @@ -0,0 +1,5 @@ +select + count(eval/data[at0001]/items[at0002]/value/magnitude) + from EHR e + contains COMPOSITION c + contains EVALUATION eval[openEHR-EHR-EVALUATION.minimal.v1] \ No newline at end of file diff --git a/client/src/test/resources/testsets/arbitrary/numeric_tests.csv b/client/src/test/resources/testsets/arbitrary/numeric_tests.csv new file mode 100644 index 000000000..6688b7146 --- /dev/null +++ b/client/src/test/resources/testsets/arbitrary/numeric_tests.csv @@ -0,0 +1,41 @@ +# test set consists on 10 evaluations with data value with value {1...10} +# the data value DvQuantity path is eval/data[at0001]/items[at0002]/value/magnitude +# NOTES: +# 1. at the moment (25.3.21) no arithmetic operators are supported +# 2. this also applies to all statistical functions as subselect is not yet implemented +# 3. REAL type is now supported +numeric_count_select.txt,eval/data[at0001]/items[at0002]/value/magnitude > 2.34567890,8,java.lang.Long +numeric_count_select.txt,eval/data[at0001]/items[at0002]/value/magnitude > -1,10,java.lang.Long +numeric_count_select.txt,eval/data[at0001]/items[at0002]/value/magnitude > -1.0,10,java.lang.Long +numeric_count_select.txt,eval/data[at0001]/items[at0002]/value/magnitude IS NOT NULL,10,java.lang.Long +numeric_count_select.txt,eval/data[at0001]/items[at0002]/value/magnitude IS NULL,0,java.lang.Long +numeric_count_select.txt,NOT EXISTS eval/data[at0001]/items[at0002]/value/magnitude,0,java.lang.Long +numeric_count_select.txt,EXISTS eval/data[at0001]/items[at0002]/value/magnitude,10,java.lang.Long +numeric_count_select.txt,eval/data[at0001]/items[at0002]/value/magnitude BETWEEN 4 AND 7,4,java.lang.Long +numeric_count_select.txt,"eval/data[at0001]/items[at0002]/value/magnitude MATCHES {1,2,3,4}",4,java.lang.Long +numeric_count_select.txt,"1 MATCHES {eval/data[at0001]/items[at0002]/value/magnitude}",1,java.lang.Long +numeric_count_select.txt,"eval/data[at0001]/items[at0002]/value/magnitude IN (1,2,3,4)",4,java.lang.Long +numeric_count_select.txt,"1 = ANY(eval/data[at0001]/items[at0002]/value/magnitude)",1,java.lang.Long +numeric_count_select.txt,"1 < ANY(eval/data[at0001]/items[at0002]/value/magnitude)",9,java.lang.Long +numeric_count_select.txt,"1 = SOME(eval/data[at0001]/items[at0002]/value/magnitude)",1,java.lang.Long +numeric_count_select.txt,"1 < SOME(eval/data[at0001]/items[at0002]/value/magnitude)",9,java.lang.Long +numeric_count_select.txt,"1 = ALL(eval/data[at0001]/items[at0002]/value/magnitude)",1,java.lang.Long +numeric_count_select.txt,"1 < ALL(eval/data[at0001]/items[at0002]/value/magnitude)",9,java.lang.Long +numeric_count_select.txt,"eval/data[at0001]/items[at0002]/value/magnitude IS NOT NULL",10,java.lang.Long +numeric_count_select.txt,"eval/data[at0001]/items[at0002]/value/magnitude IS DISTINCT FROM 2",9,java.lang.Long +numeric_val_select.txt,"eval/data[at0001]/items[at0002]/value/magnitude = 2",2,java.lang.Double +numeric_val_select.txt,"eval/data[at0001]/items[at0002]/value/magnitude >= 2 LIMIT 1 ORDER BY eval/data[at0001]/items[at0002]/value/magnitude ASC",2,java.lang.Double +numeric_val_select.txt,"eval/data[at0001]/items[at0002]/value/magnitude >= 2 LIMIT 1 ORDER BY eval/data[at0001]/items[at0002]/value/magnitude ASCENDING",2,java.lang.Double +numeric_val_select.txt,"eval/data[at0001]/items[at0002]/value/magnitude >= 2 LIMIT 1 OFFSET 3 ORDER BY eval/data[at0001]/items[at0002]/value/magnitude ASC",5,java.lang.Double +numeric_val_select.txt,"eval/data[at0001]/items[at0002]/value/magnitude >= 2 LIMIT 1 ORDER BY eval/data[at0001]/items[at0002]/value/magnitude DESC",10,java.lang.Double +numeric_val_select.txt,"eval/data[at0001]/items[at0002]/value/magnitude >= 2 LIMIT 1 ORDER BY eval/data[at0001]/items[at0002]/value/magnitude DESCENDING",10,java.lang.Double +numeric_val_select.txt,"eval/data[at0001]/items[at0002]/value/magnitude >= 2 LIMIT 1 OFFSET 3 ORDER BY eval/data[at0001]/items[at0002]/value/magnitude DESC",7,java.lang.Double +# functions (nb. SUM is now supported) +,select sum(eval/data[at0001]/items[at0002]/value/magnitude) from EHR e contains COMPOSITION c contains EVALUATION eval[openEHR-EHR-EVALUATION.minimal.v1],55,java.lang.Double +,select avg(eval/data[at0001]/items[at0002]/value/magnitude) from EHR e contains COMPOSITION c contains EVALUATION eval[openEHR-EHR-EVALUATION.minimal.v1],5.5,java.lang.Double +,select min(eval/data[at0001]/items[at0002]/value/magnitude) from EHR e contains COMPOSITION c contains EVALUATION eval[openEHR-EHR-EVALUATION.minimal.v1],1,java.lang.Double +,select max(eval/data[at0001]/items[at0002]/value/magnitude) from EHR e contains COMPOSITION c contains EVALUATION eval[openEHR-EHR-EVALUATION.minimal.v1],10,java.lang.Double +# REAL is now supported +numeric_count_select.txt,"eval/data[at0001]/items[at0002]/value/magnitude < 2e+3",10,java.lang.Long +numeric_count_select.txt,"eval/data[at0001]/items[at0002]/value/magnitude < 2e3",10,java.lang.Long +numeric_count_select.txt,"eval/data[at0001]/items[at0002]/value/magnitude < 2e-3",0,java.lang.Long diff --git a/client/src/test/resources/testsets/arbitrary/numeric_tests.test.csv b/client/src/test/resources/testsets/arbitrary/numeric_tests.test.csv new file mode 100644 index 000000000..059f437a9 --- /dev/null +++ b/client/src/test/resources/testsets/arbitrary/numeric_tests.test.csv @@ -0,0 +1,2 @@ +#numeric_count_select.txt,"eval/data[at0001]/items[at0002]/value/magnitude IN (1,2,3,4)",4,java.lang.Long +numeric_count_select.txt,"1 MATCHES {eval/data[at0001]/items[at0002]/value/magnitude,eval/data[at0001]/items[at0002]/value/magnitude}",1,java.lang.Long \ No newline at end of file diff --git a/client/src/test/resources/testsets/arbitrary/numeric_val_select.txt b/client/src/test/resources/testsets/arbitrary/numeric_val_select.txt new file mode 100644 index 000000000..630c3ce98 --- /dev/null +++ b/client/src/test/resources/testsets/arbitrary/numeric_val_select.txt @@ -0,0 +1,5 @@ +select + eval/data[at0001]/items[at0002]/value/magnitude + from EHR e + contains COMPOSITION c + contains EVALUATION eval[openEHR-EHR-EVALUATION.minimal.v1] \ No newline at end of file diff --git a/client/src/test/resources/testsets/arbitrary/string_tests_select.txt b/client/src/test/resources/testsets/arbitrary/string_tests_select.txt new file mode 100644 index 000000000..08b758d9f --- /dev/null +++ b/client/src/test/resources/testsets/arbitrary/string_tests_select.txt @@ -0,0 +1,5 @@ +select + o/data[at0001]/events[at0002]/data[at0003]/items[at0004]/value/value + from EHR e + contains COMPOSITION c + contains OBSERVATION o[openEHR-EHR-OBSERVATION.test_all_types.v1] \ No newline at end of file diff --git a/client/src/test/resources/testsets/testActionWhere.csv b/client/src/test/resources/testsets/testActionWhere.csv new file mode 100644 index 000000000..519e34188 --- /dev/null +++ b/client/src/test/resources/testsets/testActionWhere.csv @@ -0,0 +1,10 @@ +name/value, +archetype_node_id, +language/code_string, +language/terminology_id/value, +subject,//ignore +time/value, +ism_transition/current_state/value, +ism_transition/current_state/defining_code/code_string, +ism_transition/current_state/defining_code/terminology_id/value, +description[at0001]/items[openEHR-EHR-CLUSTER.test_all_types.v1]/items[at0001]/items[at0002]/items[at0003]/value/value, \ No newline at end of file diff --git a/client/src/test/resources/testsets/testCompositionWhere.csv b/client/src/test/resources/testsets/testCompositionWhere.csv new file mode 100644 index 000000000..2eaec4301 --- /dev/null +++ b/client/src/test/resources/testsets/testCompositionWhere.csv @@ -0,0 +1,17 @@ +name/value +archetype_details/archetype_id/value +archetype_details/template_id/value +archetype_details/rm_version,//TODO: https://github.com/ehrbase/ehrbase/tree/feature/463_rm_version_persistence +archetype_node_id +uid/value,//this cannot be determined by autowhere (as it requires the localhost and the version id) +language/code_string +language/terminology_id/value +territory/code_string +territory/terminology_id/value +category/value +category/defining_code/code_string +category/defining_code/terminology_id/value +composer/name +composer/external_ref/type +composer/external_ref/namespace +composer/external_ref/id/value \ No newline at end of file diff --git a/client/src/test/resources/testsets/testContextAttributesWhere.csv b/client/src/test/resources/testsets/testContextAttributesWhere.csv new file mode 100644 index 000000000..fcea8dad1 --- /dev/null +++ b/client/src/test/resources/testsets/testContextAttributesWhere.csv @@ -0,0 +1,4 @@ +start_time/value,//ignore due to delimiter in SQL timestamp. +setting/value +setting/defining_code/code_string +setting/defining_code/terminology_id/value, \ No newline at end of file diff --git a/client/src/test/resources/testsets/testEhrStatusWhere.csv b/client/src/test/resources/testsets/testEhrStatusWhere.csv new file mode 100644 index 000000000..b38953d90 --- /dev/null +++ b/client/src/test/resources/testsets/testEhrStatusWhere.csv @@ -0,0 +1,14 @@ + archetype_node_id,//not supported in where + subject/external_ref/id/value, + subject/external_ref/id/scheme, + subject/external_ref/namespace, + subject/external_ref/type, + other_details/name/value, + other_details/items[at0001]/archetype_node_id,// + other_details/items[at0001]/name/value, + other_details/items[at0001]/value/id, + other_details/items[at0001]/value/type, + other_details/items[at0001]/value/issuer, + other_details/items[at0001]/value/assigner, + is_queryable, + is_modifiable \ No newline at end of file diff --git a/client/src/test/resources/testsets/testEvaluationWhere.csv b/client/src/test/resources/testsets/testEvaluationWhere.csv new file mode 100644 index 000000000..9e867bdf2 --- /dev/null +++ b/client/src/test/resources/testsets/testEvaluationWhere.csv @@ -0,0 +1,42 @@ +name/value, +archetype_node_id,// +language/code_string, +language/terminology_id/value, +subject,// +data[at0001]/name/value, +data[at0001]/archetype_node_id,// +data[at0001]/items[at0002]/name/value,// +data[at0001]/items[at0002]/archetype_node_id,// +data[at0001]/items[at0003]/name/value, +data[at0001]/items[at0003]/archetype_node_id,// +data[at0001]/items[at0003]/value/lower/magnitude, +data[at0001]/items[at0003]/value/upper/magnitude, +data[at0001]/items[at0003]/value/lower_unbounded, +data[at0001]/items[at0003]/value/upper_unbounded, +data[at0001]/items[at0004]/name/value, +data[at0001]/items[at0004]/archetype_node_id,// +data[at0001]/items[at0004]/value/lower/magnitude, +data[at0001]/items[at0004]/value/lower/units, +data[at0001]/items[at0004]/value/upper/magnitude, +data[at0001]/items[at0004]/value/upper/units, +data[at0001]/items[at0004]/value/lower_unbounded, +data[at0001]/items[at0004]/value/upper_unbounded, +data[at0001]/items[at0005]/name/value, +data[at0001]/items[at0005]/archetype_node_id,// +data[at0001]/items[at0005]/value/lower/value, +data[at0001]/items[at0005]/value/upper/value, +data[at0001]/items[at0005]/value/lower_unbounded, +data[at0001]/items[at0005]/value/upper_unbounded, +data[at0001]/items[at0009]/name/value, +data[at0001]/items[at0009]/archetype_node_id,// +data[at0001]/items[at0009]/value/magnitude, +data[at0001]/items[at0009]/value/units, +data[at0001]/items[at0006]/name/value, +data[at0001]/items[at0006]/archetype_node_id,// +data[at0001]/items[at0006]/items[at0007]/name/value, +data[at0001]/items[at0006]/items[at0007]/archetype_node_id,// +data[at0001]/items[at0006]/items[at0007]/items[at0008]/name/value, +data[at0001]/items[at0006]/items[at0007]/items[at0008]/archetype_node_id,// +data[at0001]/items[at0006]/items[at0007]/items[at0008]/items[at0010]/name/value, +data[at0001]/items[at0006]/items[at0007]/items[at0008]/items[at0010]/archetype_node_id,// +data[at0001]/items[at0006]/items[at0007]/items[at0008]/items[at0010]/value/value \ No newline at end of file diff --git a/client/src/test/resources/testsets/testInstructionWhere.csv b/client/src/test/resources/testsets/testInstructionWhere.csv new file mode 100644 index 000000000..deaa70b03 --- /dev/null +++ b/client/src/test/resources/testsets/testInstructionWhere.csv @@ -0,0 +1,16 @@ +name/value +archetype_node_id,// +language/code_string +language/terminology_id/value +activities[at0001]/name/value +activities[at0001]/archetype_node_id,// +activities[at0001]/action_archetype_id, //missing from flattener open CR! +activities[at0001]/timing/value +activities[at0001]/timing/formalism +activities[at0001]/description[at0002]/archetype_node_id,// +activities[at0001]/description[at0002]/items[at0003]/name/value +activities[at0001]/description[at0002]/items[at0003]/archetype_node_id,// +activities[at0001]/description[at0002]/items[at0003]/value/value, +activities[at0001]/description[at0002]/items[at0004]/name/value +activities[at0001]/description[at0002]/items[at0004]/archetype_node_id,// +activities[at0001]/description[at0002]/items[at0004]/value/value diff --git a/client/src/test/resources/testsets/testObservationWhere.csv b/client/src/test/resources/testsets/testObservationWhere.csv new file mode 100644 index 000000000..f5ed5b51e --- /dev/null +++ b/client/src/test/resources/testsets/testObservationWhere.csv @@ -0,0 +1,19 @@ +name/value +archetype_node_id +language/code_string +language/terminology_id/value +data[at0001]/name/value +data[at0001]/archetype_node_id,//WRONG encoding of where clause for archetype_node_id +data[at0001]/origin/value +data[at0001]/events[at0002]/name/value +data[at0001]/events[at0002]/archetype_node_id,//WRONG encoding of where clause for archetype_node_id +data[at0001]/events[at0002]/time/value +data[at0001]/events[at0002]/data[at0003]/name/value +data[at0001]/events[at0002]/data[at0003]/archetype_node_id,//WRONG encoding of where clause for archetype_node_id +data[at0001]/events[at0002]/data[at0003]/items[at0004]/name/value +data[at0001]/events[at0002]/data[at0003]/items[at0004]/value/value +data[at0001]/events[at0002]/data[at0003]/items[at0005]/name/value +data[at0001]/events[at0002]/data[at0003]/items[at0005]/value/value +data[at0001]/events[at0002]/data[at0003]/items[at0005]/value/defining_code/code_string +data[at0001]/events[at0002]/data[at0003]/items[at0005]/value/defining_code/terminology_id/value +data[at0001]/events[at0002]/data[at0003]/items[at0007]/name/value \ No newline at end of file diff --git a/client/src/test/resources/testsets/testSectionWhere.csv b/client/src/test/resources/testsets/testSectionWhere.csv new file mode 100644 index 000000000..0d0347e4a --- /dev/null +++ b/client/src/test/resources/testsets/testSectionWhere.csv @@ -0,0 +1,6 @@ +name/value, +archetype_node_id,//TBC +items[at0001]/name/value, +items[at0001]/archetype_node_id,// +items[at0001]/items[at0002]/name/value, +items[at0001]/items[at0002]/archetype_node_id,// \ No newline at end of file diff --git a/test-data/src/main/java/org/ehrbase/test_data/operationaltemplate/OperationalTemplateTestData.java b/test-data/src/main/java/org/ehrbase/test_data/operationaltemplate/OperationalTemplateTestData.java index 706205258..2e03d692f 100644 --- a/test-data/src/main/java/org/ehrbase/test_data/operationaltemplate/OperationalTemplateTestData.java +++ b/test-data/src/main/java/org/ehrbase/test_data/operationaltemplate/OperationalTemplateTestData.java @@ -75,11 +75,13 @@ public enum OperationalTemplateTestData { LANGUAGE_TEST("example with multiple languages", "language_test.opt", "language_test"), SINGLE_EVENT("example with a single valued EVENT", "single_event.opt", "Körpergröße"), ADDICTION("example ", "additciton_alcohol.opt", "AddictionAlcoholTemplate"), + MINIMAL_EVALUATION("minimal evaluation", "minimal_evaluation.opt", "minimal_evaluation.en.v1"), DETERIORIATION_ASSESSMENT( "Deterioriation assessment ", "EREACT - Deterioriation assessment.v0.opt", "EREACT - Deterioriation assessment.v0"); + private final String filename; private final String templateId; private final String description; diff --git a/test-data/src/main/resources/composition/canonical_json/all_types_systematic_tests.json b/test-data/src/main/resources/composition/canonical_json/all_types_systematic_tests.json index 18da12f56..78932e5f3 100644 --- a/test-data/src/main/resources/composition/canonical_json/all_types_systematic_tests.json +++ b/test-data/src/main/resources/composition/canonical_json/all_types_systematic_tests.json @@ -144,7 +144,7 @@ "archetype_node_id": "at0004", "value": { "_type": "DV_TEXT", - "value": "At,ffwkm.xsuDu,LNtqXEQJzxNMXTjyKVzQojaNTidAxLLZRbWWoGnfOIMUM.XxakRgJxExjtjBPirOxu,nUnPdIegLQbhNDKNRqGbFuvXrXYuNPXwnELoIsYMKgFEWHnR.XSBuESAamCrjJMssGgI.QOOyzatFlaXbiVaUBxzSdkOscZza,IumnYWoxwekcSAYSJiILhmKEOUWdoElCavaQPNNpGcxHEGASUMSAkFuu jZdWcysffi.QLeVONn" + "value": "the quick brown fox jumps over the lazy dog" } }, { diff --git a/test-data/src/main/resources/composition/canonical_json/datetime_tests.json b/test-data/src/main/resources/composition/canonical_json/datetime_tests.json index 4c7482ada..483d3456a 100644 --- a/test-data/src/main/resources/composition/canonical_json/datetime_tests.json +++ b/test-data/src/main/resources/composition/canonical_json/datetime_tests.json @@ -17,10 +17,6 @@ "rm_version": "1.0.2" }, "archetype_node_id": "openEHR-EHR-COMPOSITION.test_all_types.v1", - "uid": { - "_type": "OBJECT_VERSION_ID", - "value": "__THIS_SHOULD_BE_MODIFIED_BY_THE_TEST_::piri.ehrscape.com::1" - }, "language": { "_type": "CODE_PHRASE", "terminology_id": { diff --git a/test-data/src/main/resources/composition/canonical_json/minimal_evaluation.json b/test-data/src/main/resources/composition/canonical_json/minimal_evaluation.json index f5d2405f0..4c1f7bef8 100644 --- a/test-data/src/main/resources/composition/canonical_json/minimal_evaluation.json +++ b/test-data/src/main/resources/composition/canonical_json/minimal_evaluation.json @@ -17,10 +17,6 @@ "rm_version": "1.0.2" }, "archetype_node_id": "openEHR-EHR-COMPOSITION.minimal.v1", - "uid": { - "_type": "OBJECT_VERSION_ID", - "value": "__THIS_SHOULD_BE_MODIFIED_BY_THE_TEST_::piri.ehrscape.com::1" - }, "language": { "_type": "CODE_PHRASE", "terminology_id": { diff --git a/test-data/src/main/resources/operationaltemplate/minimal_evaluation.opt b/test-data/src/main/resources/operationaltemplate/minimal_evaluation.opt new file mode 100644 index 000000000..b7a47593e --- /dev/null +++ b/test-data/src/main/resources/operationaltemplate/minimal_evaluation.opt @@ -0,0 +1,254 @@ + + + \ No newline at end of file