openEHR logo

openEHR Platform Conformance Test Schedule

Issuer: openEHR Specification Program

Release: CNF latest

Status: DEVELOPMENT

Revision: [latest_issue]

Date: [latest_issue_date]

Keywords: conformance, test

openEHR components
© 2017 - 2022 The openEHR Foundation

The openEHR Foundation is an independent, non-profit foundation, facilitating the sharing of health records by consumers and clinicians via open specifications, clinical models and open platform implementations.

Licence

image Creative Commons Attribution-NoDerivs 3.0 Unported. https://creativecommons.org/licenses/by-nd/3.0/

Support

Issues: Problem Reports
Web: specifications.openEHR.org

Amendment Record

Issue Details Raiser Completed

CNF Release 1.0.?

0.8.5

Improve identifiers, structure

T Beale

08 Jan 2022

0.8.0

Rewrite main schedule based on EhrBase (Github commit 674e8b2)

P Pazos;
W Wagner;
T Beale

23 Nov 2021

0.7.1

Updates and new diagrams for SUT section; Adjust some test sets.

T Beale

17 Mar 2017

0.7.0

Major rework based on openEHR Patform SM.

openEHR SEC

18 Oct 2017

0.6.2

Updates to REST API at 25 Aug 2017. Added glossary. Improved SUT diagram.

T Beale,
S Iancu

26 Aug 2017

0.6.1

Major rework from SEC call 9 Aug 2017.

C Chevalley,
H Frankel,
S Iancu,
B Lah,
B Naess,
T Beale

11 Aug 2017

0.5.0

SPECCNF-1: Initial Writing.

B Naess,
I McNicoll,
P Pazos,
T Beale

01 Jun 2017

Acknowledgements

This specification was developed and is maintained by the openEHR Specifications Editorial Committee (SEC).

Principal Authors

Trademarks

  • 'openEHR' is a trademark of the openEHR Foundation

1. Preface

1.1. Purpose

This document specifies the openEHR Platform Conformance test schedule, which may be used to determine the conformance of openEHR platform products to openEHR plaform-related specifications. The audience of this document includes:

  • Software development organisations developing healthcare information systems;

  • Customer (i.e. procuring) organisations.

Useful references for reading this document include:

1.3. Status

This specification is in the DEVELOPMENT state. The development version of this document can be found at https://specifications.openehr.org/releases/CNF/latest/platform_test_schedule.html.

Known omissions or questions are indicated in the text with a 'to be determined' paragraph, as follows:

TBD: (example To Be Determined paragraph)

1.4. Feedback

Feedback may be provided on the openEHR Conformance forum.

Issues may be raised on the specifications Problem Report tracker.

To see changes made due to previously reported issues, see the CNF component Change Request tracker.

2. Glossary of Terms and Acronyms

The following terms and acronyms are used in this document.

Term Meaning

AOM

Archetype Object Model (model of constraints).

API

Application Programmer Interface.

CDS

Clinical Decision Support.

REST

Representational state transfer, a type of web service. REST-compliant Web services allow requesting systems to access and manipulate
textual representations of Web resources using a uniform and predefined set of stateless operations.

RM

openEHR Reference Model

SUT

System under test.

3. Overview

3.1. Scope

As described in the openEHR Conformance Guide, the following aspects of a System Under Test (SUT) are tested to determine conformance to published specifications:

Test aspect How assessed Methodology

Functional conformance

Conformance of the implemented APIs to the published APIs, in a concrete API technology

Regression of test client running API call-in test cases against reference results

Content conformance

Conformance of platform’s content validation of data against semantic models (archetypes etc)

Regression of test client committing variable data sets against reference validity

Critical attributes

Conformance of specific platform non-functional properties to specification

Various

The main part of this specification is divided into sections according to the three test aspects shown above. Specific methods related to each aspect are described in the sub-sections below.

This specification does not cover claims to non-functional characteristics such as capacity, performance, availability, or consistency of systems. It is however recommended that supply agreements for operational solutions include criteria for these factors, as relevant to the situation.

It may be possible to develop a band-based rating sytem for capacity. Performance, availability, consistency and related characteristics may be assessed using a framework that takes account of the CAP and / or PACELC theorems.

Specific applications are also outside the scope of this specification, however, it is assumed that in order for solutions to be testable, a minimal generic viewing tool is provided to enable viewing of data and other testable events.

3.2. Functional conformance

Functional conformance is assessed by running tests on the SUT API, and determining deviations from known reference responses. As described in Section 4.2 of the openEHR Conformance Guide, the test cases defined here are based on the openEHR Platform Abstract Service Model API calls, which are termed 'conformance points'. A conformance point is understood as a testable capability of a system that relates to a business function. For example, conformance points for an EHR service include create_EHR, update_EHR, and so on. For any given conformance point, there may be multiple tests, each of which is individually identified.

Each test case is documented in the following form.

3.2.1. TC <Identifier, e.g. TC EHR_COMPOSITION.has_composition_bad_composition>

Description

<test case description>

Pre-conditions

<conditions required of the SUT prior to test case execution>

Post-conditions

<conditions true of the SUT subsequent to test case execution>

Flow

<steps required to execute the test>

In most automated test frameworks, pre-conditions, setup, actions, post-conditions, and cleanup steps can be directly implemented.

Note
The supported RM version(s) by the server under test should be stated beforehand, because this will determine some variations on the data sets used for testing. The minimum required version is 1.0.2.

3.3. Content conformance

TBD

3.4. Critical attributes

TBD

4. Functional Conformance: Definitions Component

4.1. Normative Reference

Items under this validation suite conceptually use these abstract interfaces defined in the Abstract Definition Service Model:

  • I_DEFINITION_ADL14

  • I_DEFINITION_ADL2

These are concretely realised in implementation technology specfic APIs, such as the Definitions REST API.

The artefacts that flow through these interfaces are defined by the following specifications:

4.2. Test Environment

The server under test should support:

  1. OPTs 1.4 or 2, but OPT 1.4 if more frequent since modeling tools supporting this were around for a long time. Could also support ADL, 1.4 or 2;

  2. validation of OPTs and archetypes uploaded to it, or even provide a service to do so before uploading (useful while developing);

  3. different versions of the same OPTs and archetypes.

The following should be taken into account when testing any given product:

  1. The server under test should support the full cycle of OPT management, including: validation, loading, versioning, retrieving, delete or deactivation (data for this OPT is loaded but no new data should be accepted for it). For the delete, the internal behavior should be defined: 1. if data was committed referencing an OPT, can it be physically deleted? or should be logically deleted? 2. if there is no data, can the OPT be deleted physically? Logical delete might work as the deactivation mentioned above.

  2. The test cases are the same for OPT 1.4/2, but tests should be written separately and different datasets should be created for 1.4 and 2.

  3. Different implementations might use specific formats for the template IDs, when testing each server, the template IDs should be adapted to prevent failures for wrong format on the template ID. This is due to openEHR not yet defining a format for the template IDs in the specifications.

4.3. OPT 1.4/2 Test cases

4.3.1. Conformance Point: I_DEFINITION_ADL14.validate_opt()

Platform service ref: I_DEFINITION_ADL14.validate_opt()

4.3.1.1. Test Data Sets
  • minimal valid OPT (each containing each entry type);

  • maximal valid OPT (all types in the RM);

  • invalid OPT (empty file);

  • invalid OPT (empty template_id);

  • invalid OPT (removed mandatory elements);

  • invalid OPT (added multiple elements that had an upper bound of 1)

4.3.1.2. TC I_DEFINITION_ADL14.validate_opt-valid_opt

Description

validate valid OPTs

Pre-conditions

The server should be empty (no EHRs, no commits, no OPTs).

Post-conditions

None (validation should not change the state of the system).

Flow

  1. For each valid OPT in the data set, invoke the OPT validation service

  2. The result should be positive and the server should return should be related to “OPT is valid”.

Note
some servers might not have a way to just validate the OPT, and validation might be part of the OPT upload functionality. In that case, the validation should upload and validate the OPT, and in the cases of valid OPTs, the OPT should be deleted afterwards, so the system state doesn’t change. For invalid OPTs, the upload should fail.
4.3.1.3. TC I_DEFINITION_ADL14.validate_opt-invalid_opt

Description

validate valid OPTs

Pre-conditions

The server should be empty (no EHRs, no commits, no OPTs).

Post-conditions

None (validation should not change the state of the system).

Flow

  1. For each invalid OPT in the data set, invoke the OPT validation service

  2. The result should be negative related to the “OPT is invalid”, would be useful if the server also returns where the problems are in the OPT

Implementation note: when a step says “for each X, invoke service Y”, means that the test should run completely for each X, that is, the pre-conditions and post-conditions apply to the run for X. So if we have:

Test set: a, b, c

Test case:

  • ensure pre-conditions

  • verify post-conditions

  • flow

    1. for each X in data set, run service Y

    2. verify result

The run should be:

  • ensure pre-conditions

  • invoke Y(a)

  • verify result

  • verify post-conditions

  • ensure pre-conditions

  • invoke Y(b)

  • verify result

  • verify post-conditions

  • ensure pre-conditions

  • invoke Y(c)

  • verify result

  • verify post-conditions

4.3.2. Conformance Point: I_DEFINITION_ADL14.upload_opt()

Platform service ref: I_DEFINITION_ADL14.upload_opt()

4.3.2.1. Data set
  • minimal valid OPT (each with one type of entry, cover all entries)

  • minimal valid OPT, two versions

  • maximal valid OPT (all types in the RM)

  • invalid OPT (empty file)

  • invalid OPT (empty template_id)

  • invalid OPT (removed mandatory elements)

  • invalid OPT (added multiple elements that had an upper bound of 1)

4.3.2.2. TC I_DEFINITION_ADL14.upload_opt-valid_opt

Description

upload valid OPTs

Pre-conditions

No OPTs should be loaded on the system.

Post-conditions

A new OPT with the given template_id is loaded into the server.

NOTE: the server should be able to retrieve the template by `template_id` or retrieve if an OPT exists or not by `template_id`.

Flow

  1. For each valid OPT in the data set, invoke the OPT upload service

  2. The result should be positive, the server accepted the OPT and it is stored as it was uploaded

4.3.2.3. TC I_DEFINITION_ADL14.upload_opt-invalid_opt

Description

upload invalid OPTs

Pre-conditions

No OPTs should be loaded on the system.

Post-conditions

No OPTs should be loaded on the system.

Flow

  1. For each invalid OPT in the data set, invoke the OPT upload service

  2. The result should be negative, the server rejected the OPT because it was invalid, and would be useful if the result contains where the errors are in the uploaded OPT.

4.3.2.4. TC I_DEFINITION_ADL14.upload_opt-valid_opt_twice_conflict
Note
since there is no formal versioning mechanism for templates 1.4 (OPT 2 might use the archetype id format for the template id that also includes a version number, but this is not widely used), the OPT upload service needs to handle a version parameter, for instance this is the solution on the openEHR REST API. If the version information is not available when uploading OPTs, then uploading an OPT with the same template_id twice will make the second upload fail (conflict).

An alternative solution for the version parameter is to add the version number to the other_details of the OPT, or directly into the template_id.

Description

Upload valid OPT twice with conflict

Pre-conditions

No OPTs should be loaded on the system.

Post-conditions

A new OPT with the given template_id is loaded into the server, and there will be only one OPT loaded.

Note
the server should be able to retrieve the template by template_id, or retrieve if an OPT exists or not by template_id.

Flow

  1. For each valid OPT in the data set, invoke the OPT upload service

  2. The result should be positive (the server accepted the OPT)

  3. Invoke the upload service with the same OPT as in 1.

  4. The result should be negative (the server rejected the OPT)

4.3.2.5. TC I_DEFINITION_ADL14.upload_opt-valid_opt_twice_no_conflict
Note
considering the note on the previous flow, for this flow the version parameter is provided, and both service invocations contain a different version value.

Description

upload valid OPT twice with conflict

Pre-conditions

No OPTs should be loaded on the system.

Post-conditions

Two new OPTs with the given template_id and different versions are loaded into the server.

Note
the server should be able to retrieve the templates by template_id and version, or retrieve if an OPT exists or not by template_id and version. Given only the template_id, the server will return just the latest version.

Flow

  1. For each valid OPT in the data set, invoke the OPT upload service, including the version parameter = 1

  2. The result should be positive (the server accepted the OPT)

  3. Invoke the upload service with the same OPT as in 1., including the version parameter = 2

  4. The result should be positive (the server accepted the OPT)

4.3.3. Conformance Point: I_DEFINITION_ADL14.get_opt()

Platform service ref: I_DEFINITION_ADL14.get_opt()

Note
the flows of this test case will include flows from the Upload OPT test case, in order to have something to retrieve.
4.3.3.1. Data sets
  • minimal valid OPT (covering all entry types)

  • minimal valid OPT, two versions

  • maximal valid OPT (all types in the RM)

4.3.3.2. TC I_DEFINITION_ADL14.get_opt-get_single

Description

retrieve a single OPT

Pre-conditions

All valid OPTs should be loaded into the system, only the single versioned ones.

Post-conditions

None (retrieve should not change the state of the system).

Flow

  1. Invoke the retrieve OPT service with existing template_ids

  2. For each template_id, the correct OPT will be returned

Note
to check point 2, the retrieved OPT should be exactly the same as the uploaded one.
4.3.3.3. TC I_DEFINITION_ADL14.get_opt-retrieve_fail

Description

empty server OPT retrieve fail test

Pre-conditions

No OPTs should be loaded on the system.

Post-conditions

None

Flow

  1. Invoke the retrieve OPT service with a random template_id

  2. The service should return an error related to the non existence of the requested OPT

4.3.3.4. TC I_DEFINITION_ADL14.get_opt-retrieve_latest_version

Description

retrieve last version of versioned OPT

Pre-conditions

OPTs with more than one version should be loaded.

Post-conditions

None

Flow

  1. Invoke the retrieve OPT service with existing template_ids

  2. For each template_id, the correct OPT will be returned, and will be the last version

Note
to be sure the last version was returned, a small modification to the OPT could be done.
4.3.3.5. TC I_DEFINITION_ADL14.get_opt-retrieve_specific_version

Description

retrieve a specific version (not last) of versioned OPT

Pre-conditions

OPTs with more than one version should be loaded.

Post-conditions

None

Flow

  1. Invoke the retrieve OPT service with existing template_ids and a version parameter value that is not the last

  2. For each template_id, the correct OPT will be returned, and will be the requested version

Note
to be sure the last version was returned, a small modification to the OPT could be done.

4.3.4. Conformance Point: I_DEFINITION_ADL14.get_opts()

Platform service ref: I_DEFINITION_ADL14.get_opts()

4.3.4.1. Data sets
  • minimal valid OPT (covering each type of entry);

  • minimal valid OPT, two versions;

  • maximal valid OPT (all types in the RM).

4.3.4.2. TC I_DEFINITION_ADL14.get_opts-retrieve_all

Description

retrieve all loaded OPTs

Pre-conditions

All valid OPTs should be loaded.

Post-conditions

None

Flow

  1. Invoke the retrieve OPTs service

  2. All the loaded OPTs should be returned, if there are versions of any OPTs, only the last version is retrieved

4.3.4.3. TC I_DEFINITION_ADL14.get_opts-retrieve_all_no_opts

Description

retrieve all loaded OPTs when none is loaded

Pre-conditions

No OPTs should be loaded on the system.

Post-conditions

None

Flow

  1. Invoke the retrieve OPTs service

  2. The service should return an empty set and should not fail.

4.3.5. Conformance Point: I_DEFINITION_ADL14.delete_opt()

Platform service ref: I_DEFINITION_ADL14.delete_opt()

Note
the OPT delete can only happen if there is no associated data with the OPT, or if there exists a newer revision (minor version of the same OPT) in the server under test. For all these tests, there is not data committed to the server, so the delete can happen.

Implementation recommendations: the delete could be logical, so the OPT exists in the server but is not available, and there could be a service to retrieve deleted OPTs. Those can be undeleted or physically deleted (this can’t be undone), and only users with admin permissions should be able to physically delete OPTs.

4.3.5.1. Data sets
  • minimal valid OPT

  • minimal valid OPT, two versions

  • maximal valid OPT (all types in the RM)

4.3.5.2. TC I_DEFINITION_ADL14.delete_opt-delete_existing

Description

delete existing OPTs

Pre-conditions

All valid OPTs should be loaded into the system.

Post-conditions

None

Flow

  1. For each existing template_id, invoke the delete OPT service

  2. Verify the OPT is not longer available via the retrieve OPTs service

Note
for step 1, exclude versioned OPT, the result should be the same: the OPT is not available.
4.3.5.3. TC I_DEFINITION_ADL14.delete_opt-delete_latest_version

Description

delete last version of a versioned OPT

Pre-conditions

No OPTs should be loaded on the system.

Post-conditions

None

Flow

  1. Include flow: upload valid OPTs

  2. Invoke the delete OPT service for all existing template_ids

  3. Include flow: retrieve all loaded OPTs when none is loaded

NOTE: * for step 1, include only versioned OPT. * for versioned OPTs, when no version parameter is present when invoking the delete OPT service, all the versions of the OPT will be deleted.

4.3.5.4. TC I_DEFINITION_ADL14.delete_opt-delete_specific_version

Description

delete specific version of a versioned OPT

Pre-conditions

No OPTs should be loaded on the system.

Post-conditions

None

Flow

  1. Include flow: upload valid OPTs

  2. Invoke the delete OPT service for an existing template_id and version of the OPT, version should not be the last

  3. Include flow: retrieve all loaded OPTs

  4. The OPT set retrieved on step 3 should contain the deleted OPT, since the latest version was not deleted

  5. Include flow: delete existing OPTs

Note
for step 1, include only versioned OPT.
4.3.5.5. TC I_DEFINITION_ADL14.delete_opt-delete_non_existing

Description

delete a non existing OPT

Pre-conditions

No OPTs should be loaded on the system.

Post-conditions

None

Flow

  1. Include flow: upload valid OPTs

  2. Invoke the delete OPT service with a non existing template_id

  3. The server will return an error related to the OPT not existing in the server

  4. Include flow: delete existing OPTs

5. Functional Conformance: EHR Component

5.1. Normative Reference

Items in this validation suite conceptually use the following abstract interfaces from the Abstract Platform Service Model, EHR component.

  • I_EHR_SERVICE

  • I_EHR

  • I_EHR_STATUS

These are concretely realised in implementation technology specfic APIs, such as the EHR REST API.

The data that flow through these interfaces are defined by the following information model specifications:

5.2. Test Environment

The server under test should support:

  1. at least the OPT 1.4 format, and optionally OPT 2.

  2. at least the XML representation of COMPOSITIONs for committing data, which may be validated by the openEHR XSDs.

5.3. Test Data Sets

These are the data set classes:

  1. VALID:

    1. not providing an EHR_STATUS (empty input, the server creates the default structures and data)

    2. providing a valid EHR_STATUS

  2. INVALID:

    1. providing invalid EHR_STATUS

Valid data sets when the EHR_STATUS is provided and internal strucrures are valid (data set class 1.a):

No. is_queryable is_modifiable subject other_details ehr_id

1

true

true

provided

not provided

not provided

2

true

false

provided

not provided

not provided

3

false

true

provided

not provided

not provided

4

false

false

provided

not provided

not provided

5

true

true

provided

provided

not provided

6

true

false

provided

provided

not provided

7

false

true

provided

provided

not provided

8

false

false

provided

provided

not provided

9

true

true

provided

not provided

provided

10

true

false

provided

not provided

provided

11

false

true

provided

not provided

provided

12

false

false

provided

not provided

provided

13

true

true

provided

provided

provided

14

true

false

provided

provided

provided

15

false

true

provided

provided

provided

16

false

false

provided

provided

provided

Any other data set is invalid, for instance providing EHR_STATUS with:

  1. missing is_queryable, is_modifiable

  2. empty is_queryable, `_is_modifiable

  3. missing or empty subject_id

  4. invalid subject_id

  5. invalid other_details

Notes:

  1. When the ehr_id is not present, it is expected that it is assigned by the server.

  2. The server should set the EHR.system_id value to a known value (defined by the server’s configuration).

  3. The default values that should be assigned by the server for is_modifiable and is_queryable are 'true', and for the subject it defaults to an instance of PARTY_SELF.

  4. There are no cases to check if the provided ehr_id`is valid, since in the openEHR Platform Service Model the parameters are typed to `UUID, any other format will be an invalid call.

  5. The validity of an EHR_STATUS can be checked in its JSON form by validating against the JSON schemas.

5.4. Test Cases

5.4.1. Conformance point: I_EHR_SERVICE.has_ehr()

Platform service ref: I_EHR_SERVICE.has_ehr()

5.4.1.1. TC I_EHR_SERVICE.has_ehr-existing_ehr_id

Description

Check has EHR with existing EHR

Pre-conditions

An EHR should exist in the system with a known ehr_id

Post-conditions

None

Flow

  1. Invoke has EHR service with the known ehr_id

  2. The result should be positive, e.g. "the EHR with <ehr_id> exists"

Test runners

5.4.1.2. TC I_EHR_SERVICE.has_ehr-existing_subject_id

Description

Check has EHR with existing EHR by subject_id

Pre-conditions

An EHR should exist in the system with a known subject_id.

Post-conditions

None

Flow

  1. Invoke has EHR service with the known subject_id

  2. The result should be positive, e.g. "the EHR with <subject_id> exists"

Test runners

Note
subject_id refers to the PARTY_REF class instance containing the identifier of a patient represented by PARTY_SELF in the openEHR Reference Model.
5.4.1.3. TC I_EHR_SERVICE.has_ehr-non_existing_ehr_id

Description

Check has EHR with non existing EHR

Pre-conditions

The server should be empty (no EHRs, no commits, no OPTs).

Post-conditions

None

Flow

  1. Invoke has EHR service with a random ehr_id.

  2. The result should be negative, e.g. "the EHR with <ehr_id> does not exist"

Test runners

5.4.1.4. TC I_EHR_SERVICE.has_ehr-non_existing_subject_id

Description

Check has EHR with non existing EHR by subject_id

Pre-conditions

The server should be empty (no EHRs, no commits, no OPTs).

Post-conditions

None

Flow

  1. Invoke has EHR service with a random subject_id

  2. The result should be negative, e.g. "the EHR for <subject_id> does not exist"

Test runners

5.4.2. Conformance point: I_EHR_SERVICE.create_ehr()

Platform service ref: I_EHR_SERVICE.create_ehr()

5.4.2.1. TC I_EHR_SERVICE.create_ehr-main

Description

Create new EHR

Pre-conditions

The server should be empty (no EHRs, no commits, no OPTs).

Post-conditions

A new EHR will exist in the system and be consistent with the data sets used.

Flow

  1. Invoke the create EHR service

    1. for each item in the VALID data set classes

    2. when the ehr_id is provided, should be unique for each invocation of the service

  2. The server should answer with a positive response associated to the successful EHR creation

Test runners

5.4.2.2. TC I_EHR_SERVICE.create_ehr-same_ehr_twice

Description

Attempt to create same EHR twice

Pre-conditions

The server should be empty (no EHRs, no commits, no OPTs).

Post-conditions

A new EHR will exist in the system, the first one created, and be consistent with the data sets used.

Flow

  1. Invoke the create EHR service

    1. for each VALID data set not providing ehr_id

    2. for each VALID data set providing ehr_id

  2. The server should answer with a positive response associated to the successful EHR creation

  3. Invoke the create EHR service

    1. with the same ehr_id of the EHR created in 1.1. (should be read from the response)

    2. with the same ehr_id of the EHR created in 1.2. (should be read from the test data sets)

  4. The server should answer with a negative response, related to the existence of an EHR with the provided ehr_id, because ehr_id values should be unique

Test runners

5.4.2.3. TC I_EHR_SERVICE.create_ehr-two_ehrs_same_patient

Description

Create two EHRs for the same patient

Pre-conditions

The server should be empty (no EHRs, no commits, no OPTs).

Post-conditions

A new EHR will exist in the system.

Flow

  1. Invoke the create EHR service

    1. for each VALID data set with a provided subject and not providing ehr_id

  2. The server should answer with a positive response associated to the successful EHR creation

  3. Invoke the create EHR service

    1. with the same data set used in 1.1

  4. The server should answer with a negative response, related with the EHR already existing for the provided subject

Test runners

5.4.3. Conformance point: I_EHR_SERVICE.get_ehr()

Platform service ref: I_EHR_SERVICE.get_ehr()

5.4.3.1. TC I_EHR_SERVICE.get_ehr-existing_ehr_by_ehr_id

Description

Get existing EHR

Pre-conditions

An EHR should exist in the system with a known ehr_id.

Post-conditions

None.

Flow

  1. Invoke get EHR service with the known ehr_id

  2. The result should be positive and retrieve the EHR

Test runners

5.4.3.2. TC I_EHR_SERVICE.get_ehr-existing_ehr_by_subject_id

Description

Get existing EHR by subject_id

Pre-conditions

An EHR should exist in the system with a known subject_id.

Post-conditions

None.

Flow

  1. Invoke get EHR service with the known subject_id

  2. The result should be positive and retrieve the EHR

Test runners

5.4.3.3. TC I_EHR_SERVICE.get_ehr-get_ehr_by_invalid_ehr_id

Description

Get non existing EHR

Pre-conditions

The server should be empty (no EHRs, no commits, no OPTs).

Post-conditions

None.

Flow

  1. Invoke get EHR service by a random ehr_id

  2. The result should be negative, e.g. "EHR with <ehr_id> does not exist"

Test runners

5.4.3.4. TC I_EHR_SERVICE.get_ehr-get_ehr_by_invalid_subject_id

Description

Get non existing EHR by subject_id

Pre-conditions

The server should be empty (no EHRs, no commits, no OPTs).

Post-conditions

None.

Flow

  1. Invoke get EHR service by a random subject_id

  2. The result should be negative, e.g. "EHR for <subject_id> does not exist"

Test runners

5.5. EHR_STATUS Test Cases

5.5.1. Conformance Point: I_EHR_STATUS.get_ehr_status()

Platform service ref: I_EHR_STATUS.get_ehr_status()

5.5.1.1. TC I_EHR_STATUS.get_ehr_status-get_by_ehr_id

Description

Get status of an existing EHR

Pre-conditions

An EHR with known ehr_id should exist.

Post-conditions

None.

Flow

  1. Invoke the get EHR_STATUS service by the existing ehr_id

  2. The result should be positive and retrieve a correspondent EHR_STATUS.

    1. The EHR_STATUS internal information should match the rules in which the EHR was created (see test flow Create EHR)

    2. Those rules should be verified: a. has or not a subject_id, b. has correct value for is_modifiable, c. has correct value for is_queryable.

Test runners

5.5.1.2. TC I_EHR_STATUS.get_ehr_status-bad_ehr

Description

Get status of a non-existing EHR

Pre-conditions

The server should be empty (no EHRs, no commits, no OPTs).

Post-conditions

None.

Flow

  1. Invoke the get EHR_STATUS service by a random ehr_id

  2. The result should be negative and the result should include an error e.g. "EHR with <ehr_id> doesn’t exist".

Test runners

5.5.2. Conformance Point: I_EHR_STATUS.set_ehr_queryable()

Platform service ref: I_EHR_STATUS.set_ehr_queryable()

5.5.2.1. TC I_EHR_STATUS.set_ehr_queryable-existing_ehr

Description

Set EHR queryable of an existing EHR

Pre-conditions

An EHR with known ehr_id should exist.

Post-conditions

EHR_STATUS.is_queryable, for the EHR with known ehr_id, should be true.

Flow

  1. For the existing EHR, invoke the set EHR queryable service

  2. The result should be positive and the corresponding EHR_STATUS.is_queryable should be true

Test runners

5.5.2.2. TC I_EHR_STATUS.set_ehr_queryable-bad_ehr

Description

Set EHR queryable of non existing EHR

Pre-conditions

The server should be empty (no EHRs, no commits, no OPTs).

Post-conditions

None

Flow

  1. Invoke the set EHR queryable service by a random ehr_id

  2. The result should be negative and the result should include an error e.g. "EHR with <ehr_id> doesn’t exist".

Test runners

5.5.3. Conformance Point: I_EHR_STATUS.set_ehr_modifiable()

Platform service ref: I_EHR_STATUS.set_ehr_modifiable()

5.5.3.1. TC I_EHR_STATUS.set_ehr_modifiable-existing_ehr

Description

Set EHR modifiable of an existing EHR

Pre-conditions

An EHR with known ehr_id should exist.

Post-conditions

EHR_STATUS.is_modifiable, for the EHR with known ehr_id, should be true.

Flow

  1. For the existing EHR, invoke the set EHR modifiable service

  2. The result should be positive and the corresponding EHR_STATUS.is_modifiable should be true

Test runners

5.5.3.2. TC I_EHR_STATUS.set_ehr_modifiable-bad_ehr

Description

Set EHR modifiable of non-existing EHR

Pre-conditions

The server should be empty (no EHRs, no commits, no OPTs).

Post-conditions

None

Flow

  1. Invoke the set EHR modifiable service by a random ehr_id

  2. The result should be negative and the result should include an error e.g. "EHR with <ehr_id> doesn’t exist".

Test runners

5.5.4. Conformance Point: I_EHR_STATUS.clear_ehr_queryable()

Platform service ref: I_EHR_STATUS.clear_ehr_queryable()

5.5.4.1. TC I_EHR_STATUS.clear_ehr_queryable-existing_ehr

Description

Clear EHR queryable of an existing EHR

Pre-conditions

An EHR with known ehr_id should exist.

Post-conditions

EHR_STATUS.is_queryable, for the EHR with known ehr_id, should be false.

Flow

  1. For the existing EHR, invoke the clear EHR queryable service

  2. The result should be positive and the corresponding EHR_STATUS.is_queryable should be false

Test runners

5.5.4.2. TC I_EHR_STATUS.clear_ehr_queryable-bad_ehr

Description

Clear EHR queryable of non-existing EHR

Pre-conditions

The server should be empty (no EHRs, no commits, no OPTs).

Post-conditions

None

Flow

  1. Invoke the clear EHR queryable service by a random ehr_id

  2. The result should be negative and the result should include an error e.g. "EHR with <ehr_id> doesn’t exist".

Test runners

5.5.5. Conformance Point: I_EHR_STATUS.clear_ehr_modifiable()

Platform service ref: I_EHR_STATUS.clear_ehr_modifiable()

5.5.5.1. TC I_EHR_STATUS.clear_ehr_modifiable-existing_ehr

Description

Clear EHR modifiable of an existing EHR

Pre-conditions

An EHR with known ehr_id should exist.

Post-conditions

EHR_STATUS.is_modifiable, for the EHR with known ehr_id, should be false

Flow

  1. For the existing EHR, invoke the clear EHR modifiable service

  2. The result should be positive and the corresponding EHR_STATUS.is_modifiable should be false

Test runners

5.5.5.2. TC I_EHR_STATUS.clear_ehr_modifiable-bad_ehr

Description

Clear EHR modifiable of non existing EHR

Pre-conditions

The server should be empty (no EHRs, no commits, no OPTs).

Post-conditions

None

Flow

  1. Invoke the clear EHR modifiable service by a random ehr_id

  2. The result should be negative and the result should include an error e.g. "EHR with <ehr_id> doesn’t exist".

Test runners

6. Functional Conformance: EHR / COMPOSITION Component

6.1. Normative Reference

Items in this validation suite conceptually use the following abstract interfaces from the Abstract Platform Service Model, EHR/COMPOSITION component.

  • I_EHR_COMPOSITION

These are concretely realised in implementation technology specfic APIs, such as the EHR REST API.

The data that flow through these interfaces are defined by the following information model specifications:

6.2. Dependencies

This test suite depends on other test suites:

6.3. Test Environment

  1. The server under test should support at least OPTs, 1.4 or 2, but OPT 1.4 if more frequent since modeling tools supporting this were around for a long time. Could also support ADL, 1.4 or 2.

  2. The server should support at least one of the XML or JSON representations of COMPOSITIONs for committing data, and integrate the corresponding schemas (XML or JSON) to validate data syntactically (before validating against an OPT).

6.4. Test Cases

6.4.1. Conformance point: I_EHR_COMPOSITION.has_composition()

Platform service ref: I_EHR_COMPOSITION.has_composition()

6.4.1.1. TC I_EHR_COMPOSITION.has_composition

Description

Has existing COMPOSITION

Pre-conditions

  1. An EHR with known ehr_id exists

  2. The EHR has a CONTRIBUTION

  3. The CONTRIBUTION contains a VERSION with known uid.

Post-conditions

None

Flow

  1. Invoke the has COMPOSITION service for the ehr_id and VERSION.uid

  2. The result must be TRUE

6.4.1.2. TC I_EHR_COMPOSITION.has_composition-bad_composition

Description

Has COMPOSITION, COMPOSITION doesn’t exist

Pre-conditions

  1. An EHR with known ehr_id exists

  2. The EHR has no CONTRIBUTIONs

Post-conditions

None

Flow

  1. Invoke the has COMPOSITION service for ehr_id, and a random VERSION.uid

  2. The result must be FALSE

6.4.1.3. TC I_EHR_COMPOSITION.has_composition-bad_ehr

Description

Has COMPOSITION on non-existent EHR

Pre-conditions

  1. There are no EHRs on the server

Post-conditions

None

Flow

  1. Invoke the has COMPOSITION service with a random ehr_id

  2. The service should return an error related to the non existence of the EHR

6.4.2. Get COMPOSITION latest

Implementation consideration:

When a COMPOSITION is retrieved from a service, it will comply with a specific format. There could be a variant for each test to retrieve the COMPOSITION in any of the supported openEHR formats, and the syntactic validation of those retrieved formats should be done by using the corresponding schemas (XML, JSON, etc). That would be the minimal validation for conformance testing. Though it would be ideal to have semantic validation of the retrieved COMPOSITIONs to ensure conformance, which is achieved by validating against the corresponding OPT in the testing layer.

6.4.2.1. TC I_EHR_COMPOSITION.get_composition_latest

Description

Get existing COMPOSITION latest

Pre-conditions

  1. An EHR with known ehr_id exists

  2. The EHR has a VERSIONED_COMPOSITION with known uid

  3. The VERSIONED_COMPOSITION has two VERSIONs

Post-conditions

None

Flow

  1. Invoke the get COMPOSITION latest service for the ehr_id and VERSIONED_COMPOSITION uid

  2. The result must return the COMPOSITION contents, and should be the latest version

  3. The retrieved format should contain all the exact same data as the format used when committing the COMPOSITION (content check)

6.4.2.2. TC I_EHR_COMPOSITION.get_composition_latest-bad_composition

Description

Get COMPOSITION latest, COMPOSITION doesn’t exist

Pre-conditions

  1. An EHR with known ehr_id exists and has no CONTRIBUTIONs

Post-conditions

None

Flow

  1. Invoke the get COMPOSITION latest service for ehr_uid, and a random VERSIONED_COMPOSITION uid

  2. The result must be empty, with an error “the COMPOSITION uid doesn’t exist in the EHR ehr_uid”

6.4.2.3. TC I_EHR_COMPOSITION.get_composition_latest-bad_ehr

Description

Get COMPOSITION latest on non-existent EHR

Pre-conditions

  1. There are no EHRs on the server

Post-conditions

None

Flow

  1. Invoke the get COMPOSITION latest service with a random ehr_id, and a random VERSIONED_COMPOSITION uid

  2. The service should return an error related to the non existence of the EHR

6.4.3. Get COMPOSITION at time

6.4.3.1. TC I_EHR_COMPOSITION.get_composition_at_time

Description

Get existing COMPOSITION at time

Pre-conditions

  1. An EHR with known ehr_id exists

  2. The EHR has one or more VERSIONED_COMPOSITIONs with known uids

Post-conditions

None

Flow

  1. Invoke the get COMPOSITION at time service for the ehr_id, VERSIONED_COMPOSITION.uid and current time

  2. The result must return the COMPOSITION contents of the existing COMPOSITION at given time

  3. The retrieved format should contain all the exact same data as the format used when committing the COMPOSITION (content check)

Note
When requesting a COMPOSITION at time using the current time, the last version of the matching composition, if it exists, should be retrieved.
6.4.3.2. TC I_EHR_COMPOSITION.get_composition_at_time-no_time_arg

Description

Get existing COMPOSITION at time, without a given time

Pre-conditions

  1. An EHR with known ehr_id exists

  2. The EHR has one or more VERSIONED_COMPOSITIONs with known uids

Post-conditions

None

Flow

  1. Invoke the get COMPOSITION at time service for the ehr_id, VERSIONED_COMPOSITION uid and no time

  2. The result must return the COMPOSITION contents of the existing COMPOSITION, and should be the latest VERSION of the COMPOSITION

  3. The retrieved format should contain all the exact same data as the format used when committing the COMPOSITION (content check)

Note
Test this using COMPOSITIONs with one version and multiple versions, to be sure the retrieved one is the latest;
The previous tests for “get COMPOSITION latest” could be used to compare results.
6.4.3.3. TC I_EHR_COMPOSITION.get_composition_at_time-bad_composition

Description

Get COMPOSITION at time, COMPOSITION doesn’t exist

Pre-conditions

  1. An EHR with known ehr_id exists and has no CONTRIBUTIONs

Post-conditions

None

Flow

  1. Invoke the get COMPOSITION at time service for ehr_uid, and a random VERSIONED_COMPOSITION.uid and current time

  2. The result must be empty, with an error related to “the COMPOSITION uid doesn’t exist in the EHR ehr_uid”

6.4.3.4. TC I_EHR_COMPOSITION.get_composition_at_time-bad_ehr

Description

Get COMPOSITION at time on non-existent EHR

Pre-conditions

  1. There are no EHRs on the server

Post-conditions

None

Flow

  1. Invoke the get COMPOSITION at time service with a random ehr_id, random VERSIONED_OBJECT.uid and current time

  2. The service should return an error indicating non-existence of the EHR

6.4.3.5. TC I_EHR_COMPOSITION.get_composition_at_times

Description

Get existing COMPOSITION at time, cover different times

Pre-conditions

  1. An EHR with known ehr_id exists

  2. The EHR should have one VERSIONED_COMPOSITION with a know uid

  3. The VERSIONED_COMPOSITION should have two VERSIONs (the EHR has two CONTRIBUTIONs for the same COMPOSITION)

  4. CONTRIBUTIONs were done at times t0 and t1 with t0 < t1

Post-conditions

None

Flow

  1. Invoke the get COMPOSITION at time service for the ehr_id, VERSIONED_COMPOSITION uid and a time < t0

  2. The result must be negative and return an error related to the COMPOSITION not existing at that time

  3. Invoke the get COMPOSITION at time service for the ehr_id, VERSIONED_COMPOSITION uid and a time > t0 and < t1

  4. The result must return the COMPOSITION contents of the COMPOSITION committed in t0

  5. The retrieved format should contain all the exact same data as the format used when committing the COMPOSITION (content check)

  6. Invoke the get COMPOSITION at time service for the ehr_id, VERSIONED_COMPOSITION uid and a time > t1

  7. The result must return the COMPOSITION contents of the COMPOSITION committed in t1

  8. The retrieved format should contain all the exact same data as the format used when committing the COMPOSITION (content check)

6.4.4. Get COMPOSITION at version

6.4.4.1. TC I_EHR_COMPOSITION.get_composition_version

Description

Get existing COMPOSITION at version

Pre-conditions

  1. An EHR with known ehr_id exists

  2. The EHR has one VERSION with known version id

Post-conditions

None

Flow

  1. Invoke the get COMPOSITION at version service for the ehr_id, VERSION version id

  2. The result must return the COMPOSITION contents of the existing VERSION

  3. The retrieved format should contain all the exact same data as the format used when committing the COMPOSITION (content check)

6.4.4.2. TC I_EHR_COMPOSITION.get_composition_version-bad_version

Description

Get COMPOSITION at version, VERSION doesn’t exist

Pre-conditions

  1. An EHR with known ehr_id exists and doesn’t have any commits

Post-conditions

None

Flow

  1. Invoke the get COMPOSITION at version service for the ehr_id, and a random version id

  2. The result must be negative and return an error related to the non-existent COMPOSITION with the version id

6.4.4.3. TC I_EHR_COMPOSITION.get_composition_version-bad_ehr

Description

Get COMPOSITION at version, EHR doesn’t exist

Pre-conditions

  1. The system doesn’t have any EHRs

Post-conditions

None

Flow

  1. Invoke the get COMPOSITION at version service a random ehr_id and random version id

  2. The result must be negative and return an error related to the non-existent EHR.

6.4.4.4. TC I_EHR_COMPOSITION.get_composition_versions

Description

Get COMPOSITION at version, cover different versions

Pre-conditions

  1. An EHR with known ehr_id exists

  2. The EHR should have one VERSIONED_COMPOSITION with a known uid

  3. The VERSIONED_COMPOSITION should have two VERSIONs (the EHR has two CONTRIBUTIONs for the same COMPOSITION)

  4. Both VERSIONs have ids: v1 and v2

Post-conditions

None

Flow

  1. Invoke the get COMPOSITION at version service, for the ehr_id and VERSION version id v1

  2. The result must be positive and retrieve the COMPOSITION, that should match the COMPOSITION created with version id v1. (content check).

  3. Invoke the get COMPOSITION at version service, for the ehr_id and VERSION version id v2

  4. The result must be positive and retrieve the COMPOSITION, that should match the COMPOSITION created with version id v2 (content check).

6.4.5. Get VERSIONED COMPOSITION

6.4.5.1. TC I_EHR_COMPOSITION.get_versioned_composition

Description

Get existing VERSIONED_COMPOSITION

Pre-conditions

  1. An EHR with known ehr_id exists

  2. The EHR has one VERSIONED_COMPOSITION with known uid

Post-conditions

None

Flow

  1. Invoke the get VERSIONED_COMPOSITION service for the ehr_id and VERSIONED_COMPOSITION uid

  2. The result must return a valid VERSIONED_COMPOSITION object, referencing the VERSION it contains

Notes:

  1. To consider different cases, try with VERSIONED_COMPOSITION that contain just one VERSION or many VERSIONs

  2. For that, the valid test cases for Create COMPOSITION could be used to comply with the preconditions of this test flow

6.4.5.2. TC I_EHR_COMPOSITION.get_versioned_composition-non_existent

Description

Get non-existent VERSIONED_COMPOSITION

Pre-conditions

  1. An EHR with known ehr_id exists

  2. The EHR doesn’t have any commits

Post-conditions

None

Flow

  1. Invoke the get VERSIONED_COMPOSITION service for the ehr_id and a random VERSIONED_COMPOSITION uid

  2. The result must be negative and return an error related to the non-existence of the VERSIONED_COMPOSITION

6.4.5.3. TC I_EHR_COMPOSITION.get_versioned_composition-bad_ehr

Description

Get VERSIONED_COMPOSITION, EHR doesn’t exist

Pre-conditions

  1. The system doesn’t have any EHRs

Post-conditions

None

Flow

  1. Invoke the get VERSIONED_COMPOSITION service for a random ehr_id and a random VERSIONED_COMPOSITION uid

  2. The result must be negative and return an error related to the non-existence of the EHR

6.4.6. Create COMPOSITION

6.4.6.1. TC I_EHR_COMPOSITION.create_composition-event

Description

Create new event COMPOSITION

Pre-conditions

  1. The OPT, associated with the event COMPOSITION that will be created, should exist on the server

  2. An EHR with known ehr_id should exist

  3. The EHR should have no commits

Post-conditions

A new event COMPOSITION exists in the EHR.

Flow

  1. Invoke the create COMPOSITION service with a valid event COMPOSITION, compliant with the existing OPT, and with the known ehr_id

  2. The result should be positive, return information about the new COMPOSITION added to the EHR, and the version number should be 1

6.4.6.2. TC I_EHR_COMPOSITION.create_composition-persistent

Description

Create new persistent COMPOSITION

Pre-conditions

  1. The OPT, associated with the persistent COMPOSITION that will be created, should exist on the server

  2. An EHR with known ehr_id should exist

  3. The EHR should have no commits

Post-conditions

A new persistent COMPOSITION exists in the EHR.

Flow

  1. Invoke the create COMPOSITION service with a valid persistent COMPOSITION, compliant with the existing OPT, and the known ehr_id

  2. The result should be positive, and return information about the new COMPOSITION added to the EHR, and the version number should be 1

6.4.6.3. TC I_EHR_COMPOSITION.create_composition-same_opt_twice

Description

Create persistent COMPOSITION for the same OPT twice

Pre-conditions

  1. The OPT, associated with the persistent COMPOSITION that will be created, should exist on the server

  2. An EHR with known ehr_id should exist

  3. The EHR should have no commits

Post-conditions

A new persistent COMPOSITION exists in the EHR.

Flow

  1. Invoke the create COMPOSITION service with a valid persistent COMPOSITION, compliant with the existing OPT, and with the known ehr_id

  2. The result should be positive, and return information about the new COMPOSITION added to the EHR, and the version number should be 1

  3. Invoke the create COMPOSITION service with a valid persistent COMPOSITION and the same ehr_id as in 1., the COMPOSITION should comply with the same persistent OPT as the COMPOSITION in 1

  4. The result should be negative, returning an error related to trying to create a persistent COMPOSITION for the same persistent OPT that already has a first version

Notes:

  1. Current criteria is: only one ‘create’ operation is allowed for persistent COMPOSITIONs, the next operations over an existing persistent COMPOSITION should be ‘modifications’.

  2. This is under debate in the openEHR SEC since some implementations permit 'persistent' COMPOSIITONS to have more than one instance in the same EHR and some others not. This is due to the lack of information in the openEHR specifications. There is also a discussion to define other types of categories for COMPOSITIONs to allow different behaviors.

6.4.6.4. TC I_EHR_COMPOSITION.create_composition-invalid_event

Description

Create new invalid event COMPOSITION

Pre-conditions

  1. The OPT, associated with the event COMPOSITION that will be created, should exist on the server

  2. An EHR with known ehr_id should exist

  3. The EHR should have no commits

Post-conditions

None

Flow

  1. Invoke the create COMPOSITION service with an invalid event COMPOSITION and the known ehr_id

  2. The result should be negative, and return information about the errors in the provided COMPOSITION

6.4.6.5. TC I_EHR_COMPOSITION.create_composition-invalid_persistent

Description

Create new invalid persistent COMPOSITION

Pre-conditions

  1. The OPT, associated with the persistent COMPOSITION that will be created, should exist on the server

  2. An EHR with known ehr_id should exist

  3. The EHR should have no commits

Post-conditions

None

Flow

  1. Invoke the create COMPOSITION service with an invalid persistent COMPOSITION and the known ehr_id

  2. The result should be negative, and return information about the errors in the provided COMPOSITION

6.4.6.6. TC I_EHR_COMPOSITION.create_composition-event_bad_opt

Description

Create new event COMPOSITION, referenced OPT doesn’t exist

Pre-conditions

  1. The OPT, referenced by the COMPOSITION to commit, doesn’t exist on the server

  2. An EHR with known ehr_id should exist

  3. The EHR should have no commits

Post-conditions

None

Flow

  1. Invoke the create COMPOSITION service with a valid event COMPOSITION and the known ehr_id

    1. The COMPOSITION should reference an OPT that doesn’t exist on the server

  2. The result should be negative, and return information about the non-existent OPT

6.4.6.7. TC I_EHR_COMPOSITION.create_composition-event_bad_ehr

Description

Create new event COMPOSITION, EHR doesn’t exist

Pre-conditions

  1. The OPT, referenced by the COMPOSITION to commit, exists on the server

  2. The server doesn’t have any EHRs

Post-conditions

None

Flow

  1. Invoke the create COMPOSITION service with a valid event COMPOSITION and a random ehr_id

  2. The result should be negative, and return information about the non-existent EHR

6.4.7. Update COMPOSITION

The update COMPOSITION service needs the VERSION.preceding_version_uid attribute to be set, so the server knows which existing VERSION of the COMPOSITION will be associated with the newly committed COMPOSITION. The Service Model spec is not clear about where that attribute is defined. By taking into account the Reference Model, the COMPOSITION doesn’t contain that value but the VERSION does. For the COMPOSITION update service the preceding_version_uid should be a parameter or the definition in the SM should mention this.

6.4.7.1. TC I_EHR_COMPOSITION.update_composition-event

Description

Update an existing event COMPOSITION

Pre-conditions

  1. The OPT referenced by the COMPOSITIONs to commit exists on the server

  2. An EHR with known ehr_id should exist

  3. The EHR should have no commits

Post-conditions

  1. A new VERSIONED_OBJECT exists on the server

  2. The VERSIONED_OBJECT has two VERSIONs of COMPOSITION

  3. One VERSION.commit_audit.change_type is CREATE, the other one is MODIFY

Flow

  1. Invoke the create COMPOSITION service with a valid event COMPOSITION and the existing ehr_id

    1. The COMPOSITION reference the existing OPT

  2. The result should be positive and a new COMPOSITION should exist in the EHR

  3. Invoke the update COMPOSITION service with a valid event COMPOSITION to the existing ehr_id and preceding_version_uid should be the version uid from the COMPOSITION created in 1

    1. This COMPOSITION has the same OPT as the COMPOSITION created in 1

  4. The result should be positive and a new version of the existing COMPOSITION should exist in the EHR

6.4.7.2. TC I_EHR_COMPOSITION.update_composition-persistent

Description

Update an existing persistent COMPOSITION

Pre-conditions

  1. The OPT referenced by the COMPOSITIONs to commit exists on the server

  2. An EHR with known ehr_id should exist

  3. The EHR should have no commits

Post-conditions

  1. The server should contain one VERSIONED_OBJECT

  2. The VERSIONED_OBJECT should have two VERSIONs of COMPOSITION

  3. The COMPOSITIONs should comply with the existing OPT

Flow

  1. Invoke the create COMPOSITION service with a valid persistent COMPOSITION and the existing ehr_id

    1. The OPT referenced by this COMPOSITION exists on the server

  2. The result should be positive and a new COMPOSITION should exist in the EHR

  3. Invoke the update COMPOSITION service with a valid persistent COMPOSITION, to the existing ehr_id

    1. that has the same template as the COMPOSITION created in 1.,

    2. preceding_version_uid should be the VERSION.uid from the COMPOSITION created in 1

  4. The result should be positive and a new version of the existing COMPOSITION should exist in the EHR

6.4.7.3. TC I_EHR_COMPOSITION.update_composition-non_existent

Description

Update a non-existing COMPOSITION

Pre-conditions

  1. The OPT referenced by the COMPOSITIONs to commit exists on the server

  2. An EHR with known ehr_id should exist

  3. The EHR should have no commits

Post-conditions

None

Flow

  1. Invoke the update COMPOSITION service with a valid event COMPOSITION, the existing ehr_id and preceding_version_uid should be a random value

    1. The COMPOSITION should comply with the existing OPT

  2. The result should be negative and return an error related to the non-existence of the preceding_version_id

6.4.7.4. TC I_EHR_COMPOSITION.update_composition-wrong_template

Description

Update an existing COMPOSITION, referencing a different template

Pre-conditions

  1. The OPTs, referenced by the COMPOSITIONs to commit, exist on the server

  2. An EHR with known ehr_id should exist

  3. The EHR should have no commits

Post-conditions

  1. The server has a new VERSIONED_OBJECT

  2. The VERSIONED_OBJECT has one version of a COMPOSITION

Flow

  1. Invoke the create COMPOSITION service with a valid event COMPOSITION and the existing ehr_id

    1. The OPT referenced by this COMPOSITION exists on the server

  2. The result should be positive and a new COMPOSITION should exist in the EHR

  3. Invoke the update COMPOSITION service with a valid event COMPOSITION, to the existing ehr_id and preceding_version_uid should be the version uid from the COMPOSITION created in 1

    1. The COMPOSITION references a different template than the one referenced by the COMPOSITION created in 1.

    2. The OPT referenced by this COMPOSITION exists on the server

  4. The result should be negative and return an error related to the template_id mismatch

6.4.8. Delete COMPOSITION

6.4.8.1. TC I_EHR_COMPOSITION.delete_composition-event

Description

Delete event COMPOSITION

Pre-conditions

  1. The OPT referenced by the COMPOSITIONs to commit exists on the server

  2. An EHR with known ehr_id should exist

  3. The EHR should have no commits

Post-conditions

  1. The server has one VERSIONED_OBJECT

  2. The VERSIONED_OBJECT contains two versions of COMPOSITION

  3. The second VERSION.lifecycle_state value is the code `openehr::523

deleted

`

Flow

  1. Invoke the create COMPOSITION service with a valid event COMPOSITION and the existing ehr_id

    1. The COMPOSITION complies with the existing OPT

  2. The result should be positive and a new COMPOSITION should exist in the EHR

  3. Invoke the delete COMPOSITION service with the existing ehr_id and preceding_version_uid should be the version id of the COMPOSITION created in 1

  4. The result should be positive, and the COMPOSITION should be deleted

Note
The common implementation of the delete operation is two create a new VERSION of the COMPOSITION that has VERSION.commit_audit.change_type = openehr::523|deleted|, and VERSION.lifecycle_state = openehr::523|deleted|. So the delete operation is not a physical delete but a logical delete. Some implementations might add the option of a physical deleted. This test case considers the postcondition to be a logical delete, which behaves like an update operation in which a new VERSION of an existing COMPOSITION is created.
6.4.8.2. TC I_EHR_COMPOSITION.delete_composition-persistent

Description

Delete persistent COMPOSITION

Pre-conditions

  1. The OPT referenced by the COMPOSITIONs to commit exists on the server

  2. An EHR with known ehr_id should exist

  3. The EHR should have no commits

Post-conditions

  1. The server has one VERSIONED_OBJECT

  2. The VERSIONED_OBJECT contains two versions of COMPOSITION

  3. The second VERSION.lifecycle_state value is the code `openehr::523

deleted

`

Flow

  1. Invoke the create COMPOSITION service with a valid persistent COMPOSITION and the existing ehr_id

    1. The COMPOSITION complies with the existing OPT

  2. The result should be positive and a new COMPOSITION should exist in the EHR

  3. Invoke the delete COMPOSITION service with the existing ehr_id and preceding_version_uid should be the version id of the COMPOSITION created in 1

  4. The result should be positive, and the COMPOSITION should be deleted

6.4.8.3. TC I_EHR_COMPOSITION.delete_composition-non_existent

Description

Delete persistent COMPOSITION

Pre-conditions

  1. The OPT referenced by the COMPOSITIONs to commit exists on the server

  2. An EHR with known ehr_id should exist

  3. The EHR should have no commits

Post-conditions

None

Flow

  1. Invoke the delete COMPOSITION service with the existing ehr_id and a random preceding_version_uid

  2. The result should be negative and return an error related to the non-existent COMPOSITION

7. Functional Conformance: EHR / CONTRIBUTION Component

7.1. Normative Reference

Items under this validation suite conceptually use these abstract interfaces from the Abstract Platform Service Model, EHR/EHR_CONTRIBUTION component.

7.2. Dependencies

This test suite depends on other test suites:

7.3. Test Environment

  1. The server under test should support at least OPTs, 1.4 or 2, but OPT 1.4 if more frequent since modeling tools supporting this were around for a long time. Could also support ADL, 1.4 or 2.

  2. The server should support at least one of the XML or JSON representations of CONTRIBUTIONs for committing data, and integrate the corresponding schemas (XML or JSON) to validate data syntactically (before validating against an OPT).

7.4. Test Data Sets

7.4.1. General CONTRIBUTION Commit Data Sets

  1. CONTRIBUTIONs with single valid VERSION<COMPOSITION> (minimal, one for each entry type)

  2. CONTRIBUTIONs with multiple valid VERSION<COMPOSITION> (reuse the minimal ^)

  3. CONTRIBUTION with single valid VERSION<COMPOSITION> with maximal data sets

  4. Empty CONTRIBUTION (no VERSIONs)

  5. CONTRIBUTIONs with invalid VERSION<COMPOSITION>

    1. Invalid data

    2. Wrong change_type

    3. Wrong lifecycle

  6. CONTRIBUTIONs with multiple VERSION<COMPOSITION>, with mixed valid and invalid ones

Note
these cases do not consider which RM type is contained in the VERSIONs, it could be COMPOSITION, FOLDER, EHR_STATUS, etc.

7.4.2. COMPOSITION CONTRIBUTION Commit Data Sets

Since there are many combinations of data that could be used for testing the Commit CONTRIBUTION service, we decided to create three main kinds of CONTRIBUTIONs that should be tested:

  1. Valid

    1. minimal COMPOSITIONs with one type of ENTRY (one ENTRY each, all ENTRYs covered)

    2. maximal COMPOSITION (all data types, all ENTRY types, and SECTIONs)

    3. a persistent COMPOSITION (e.g. problem list, medication list, immunization list, …)

    4. time series COMPOSITION (observation with many events, e.g. CPR compressions intervals)

    5. COMPOSITION with alternative types (e.g. lab result DV_COUNT, DV_QUANTITY and DV_CODED_TEXT)

    6. COMPOSITION with DV_CODED_TEXT instance on nodes declared as DV_TEXT in the OPT

    7. COMPOSITION with empty ELEMENT.value and not empty ELEMENT.null_flavour

  2. Invalid

    1. Invalid COMPOSITIONs (e.g. mandatory items not present, wrong types, extra items not declared in OPT, invalid values)

    2. Referenced OPT not loaded (this has to do more with the state of the system than to invalid data)

  3. Change type combinations (these are the minimal required, all supported change types can be found in the openEHR Terminology)

    1. VERSION.commit_audit.change_type = creation

    2. VERSION.commit_audit.change_type = modification

    3. VERSION.commit_audit.change_type = delete

Note
there could be many combinations of flows to use the different Change Types mentioned above. The minimal required by this specification it that the server is capable of this flow: 1. creation 2. modification (one or many times) 3. deleted
7.4.2.1. Data Set Considerations

change_type

Each VERSION in a CONTRIBUTION has an AUDIT_DETAILS which contains a change_type attribute. The value on that attribute determines the internal behavior for processing each VERSION, and each VERSION in the same CONTRIBUTION could have a different change_type. The most used change types are:

  1. creation: the VERSION represents the first version of a COMPOSITION.

  2. amendment: the VERSION represents a new version of an existing COMPOSITION, with the purpose of adding data.

  3. modification: the VERSION represents a new version of an existing COMPOSITION, with the purpose of changing data, maybe to fix an error.

  4. deleted:the VERSION represents a new version of an existing COMPOSITION, with the purpose of deleting it.

Internally, amendment and modification might be processed in the exact same way, because the difference is semantic not functional.

lifecycle_state

Each VERSION in a CONTRIBUTION contains an lifecycle_state attribute, which value gives semantics about the contents of the VERSION. The values could be:

  1. incomplete: the COMPOSITION was committed incomplete and should be completed (reviewed, validated, amended) later.

  2. complete: the COMPOSITION was complete at the moment it was committed.

  3. deleted: the COMPOSITION was committed for deletion.

These codes are defined in the openEHR Terminology.

lifecycle state machine

7.4.2.2. Combinations of data sets

These combinations can be tested by doing a single commit. The same combinations with flows of multiple commits could lead to different results.

One commit (no previous commits were done), single version cases:

Note
All change types but creation should fail on the first commit, since other change types need a previous commit. Last one could fail because the first commit can’t be change_type = deleted or because the lifecycle_state = |complete| can’t be with change_type = deleted.
change_type lifecycle_state* composition category composition validity** expected

creation

complete

event

valid

accepted

amendment

complete

event

valid

rejected

modification

complete

event

valid

rejected

deleted

complete

event

valid

rejected

creation

complete

persistent

valid

accepted

amendment

complete

persistent

valid

rejected

modification

complete

persistent

valid

rejected

deleted

complete

persistent

valid

rejected

creation

deleted

event

valid

rejected

amendment

deleted

event

valid

rejected

modification

deleted

event

valid

rejected

deleted

deleted

event

valid

rejected

Note
the incomplete cases should be equal to the complete, because the flag is just adding semantics about the content, not setting how the content should be processed.
Note
the invalid cases will make the accepted cases on the previous table to be rejected because the content in the COMPOSITION is not valid.

One commit (no previous commits were done), multiple versions cases:

Note
the tables below represent one VERSION in the committed CONTRIBUTION.
  1. Creating two valid, complete event COMPOSITIONs in one commit should be accepted.

change_type+ lifecycle_state++ composition category composition validity

creation

complete

event

valid

creation

complete

event

valid

This CONTRIBUTION should be accepted.

  1. Creating two valid, complete persistent COMPOSITIONs in one commit should be accepted.

Note
depending on the server implementation, some servers might not accept the second COMPOSITION if both COMPOSITIONs reference the same persistent OPT. So this test case considers both COMPOSITIONs reference different persistent OPTs.
change_type+ lifecycle_state++ composition category composition validity

creation

complete

persistent

valid

creation

complete

persistent

valid

This CONTRIBUTION should be accepted.

  1. Creating two valid, complete and mixed category COMPOSITIONs in one commit should be accepted.

change_type+ lifecycle_state++ composition category composition validity

creation

complete

event

valid

creation

complete

persistent

valid

This CONTRIBUTION should be accepted.

  1. If any COMPOSITION is invalid in a CONTRIBUTION, the whole commit should fail. It doesn’t matter if it is complete or incomplete, event or persistent (just showing some of the combinations below).

change_type+ lifecycle_state++ composition category composition validity

creation

complete

event

valid

creation

complete

event

invalid

change_type+ lifecycle_state++ composition category composition validity

creation

complete

persistent

valid

creation

complete

persistent

invalid

change_type+ lifecycle_state++ composition category composition validity

creation

complete

event

valid

creation

complete

persistent

invalid

change_type+ lifecycle_state++ composition category composition validity

creation

complete

event

invalid

creation

complete

persistent

valid

These CONTRIBUTIONs should be REJECTED.

Note
(+) for other change types than creation, the first commit will be rejected, so not included in the table those cases but should be tested.
Note
(++) the incomplete cases should be equal to the complete, because the flag is just adding semantics about the content, not setting how the content should be processed.

7.4.3. EHR_STATUS CONTRIBUTION Commit Data Sets

7.4.3.1. Combinations for data sets

The following accepted and rejected apply under any of these scenarios:

  1. The server has an EHR with the default EHR_STATUS (the EHR was created without providing an EHR_STATUS).

  2. The server has an EHR created by providing an EHR_STATUS.

  3. The server has an EHR with modifications already done to its EHR_STATUS (consecutive modifications).

Reject Cases:

  1. CONTRIBUTIONs with VERSION, where VERSION.commit_audit.change_type IN [creation, deleted] should be rejected, because the default EHR_STATUS was already created in the EHR, and the EHR_STATUS can’t be deleted once created.

  2. CONTRIBUTIONs with VERSION, where VERSION.lifecycle_state = incomplete should be rejected, because the incomplete state doesn’t apply to EHR_STATUS. Though there is an open issue related to this: https://specifications.openehr.org/jira/browse/SPECPR-368

  3. Any other case with an invalid EHR_STATUS in VERSION should also be rejected.

Accepted Cases:

  1. CONTRIBUTIONs with VERSION where VERSION.commit_audit.change_type IN [modification, amendment] and valid EHR_STATUS, should be accepted. This inscludes the following combinations for EHR_STATUS:

is_modifiable is_queryable subject.external_ref

true

true

HIER_OBJECT_ID

true

true

GENERIC_ID

true

true

NULL

true

false

HIER_OBJECT_ID

true

false

GENERIC_ID

true

false

NULL

false

true

HIER_OBJECT_ID

false

true

GENERIC_ID

false

true

NULL

false

true

HIER_OBJECT_ID

false

true

GENERIC_ID

false

true

NULL

false

false

HIER_OBJECT_ID

false

false

GENERIC_ID

false

false

NULL

Note
Since EHR_STATUS is LOCATABLE, is should have an archetype_id assigned. It is recommended to test the combination described above, combined with different values for EHR_STATUS.archetype_id.

7.4.4. FOLDER CONTRIBUTION Commit Data Sets

All the datasets are specified at the EHR.directory level, since that is the current level of operation of the openEHR REST API for FOLDERs to create, update or delete.

7.4.4.1. Data Set Combinations

Valid payload should include these cases:

  1. minimal directory

  2. directory with items

  3. directry with subfolders

  4. directory with items and subfolders

  5. directory with items and subfolders with items

Sample structure of FOLDERs with items:

Folders with items

Table of data combinations:

change_type lifecycle_state payload expected

creation

complete / incomplete

valid

accepted

amendment / modification

complete / incomplete

valid

accepted

deleted

deleted

valid

accepted

Any invalid payload should be rejected.

7.5. Test Cases

7.5.1. Conformance point: I_EHR_CONTRIBUTION.commit_contribution()

7.5.1.1. TC I_EHR_CONTRIBUTION.commit_contribution-valid_composition

Description

Successfully commit CONTRIBUTION of COMPOSITION

Pre-conditions

  1. An EHR with known ehr_id exists

  2. OPTs for each valid cases are loaded on the server

Post-conditions

  1. The EHR with ehr_id should have a new CONTRIBUTION

  2. The ID(s) of the created VERSION(s) are correct

    1. the version ID matches the change_type executed (creation = 1, modification/amendment = 2, 3, …)

    2. ID(s) can be used to retrieve a VERSION<COMPOSITION>)

Flow

  1. Invoke commit CONTRIBUTION service with the existing ehr_id and valid data sets

    1. The COMPOSITIONs reference existing OPTs on the server

  2. The result should be positive and retrieve the id of the CONTRIBUTION just created

7.5.1.2. TC I_EHR_CONTRIBUTION.commit_contribution-invalid_composition

Description

Commit CONTRIBUTION with invalid COMPOSITION

Pre-conditions

  1. An EHR with known ehr_id exists

  2. OPTs for each valid cases are loaded on the server

Post-conditions

None

Flow

  1. Invoke commit CONTRIBUTION service with an existing ehr_id and the invalid VERSION<COMPOSITION>

    1. The COMPOSITIONs reference existing OPTs on the server

  2. The result should be negative and provide info about the errors with the data committed

7.5.1.3. TC I_EHR_CONTRIBUTION.commit_contribution-empty

Description

Commit CONTRIBUTION with no content.

Pre-conditions

  1. An EHR with known ehr_id exists

Post-conditions

None

Flow

  1. Invoke commit CONTRIBUTION service with an existing ehr_id and no data in the CONTRIBUTION

  2. The result should be negative and retrieve an error indicating the empty list of VERSION<COMPOSITION> in the CONTRIBUTION

7.5.1.4. TC I_EHR_CONTRIBUTION.commit_contribution-valid_invalid_compositions

Description

Commit CONTRIBUTION with mixed valid and invalid COMPOSITIONs.

Pre-conditions

  1. An EHR with known ehr_id exists

  2. OPTs for each valid cases are loaded on the server

Post-conditions

None

Flow

  1. Invoke commit CONTRIBUTION service with an existing ehr_id and multiple VERSION<COMPOSITION>

    1. Some VERSIONs are valid, some aree invalid

    2. The COMPOSITIONs reference existing OPTs on the server

  2. The result should be negative and retrieve an error related invalid VERSION<COMPOSITION>

Note
the whole commit should behave like a transaction and fail, no CONTRIBUTIONs or VERSIONs should be created on the server.
7.5.1.5. TC I_EHR_CONTRIBUTION.commit_contribution-event_composition

Description

Commit CONTRIBUTION with event COMPOSITION.

Pre-conditions

  1. An EHR with known ehr_id exists

  2. OPTs for each valid cases are loaded on the server

Post-conditions

  1. There should be two VERSIONs of the same COMPOSITION in the EHR with ehr_id

Flow

  1. Invoke commit CONTRIBUTION service with an existing ehr_id and a valid VERSION<COMPOSITION>

    1. The COMPOSITION has category = event

    2. The COMPOSITION reference existing an OPT on the server

  2. The result should be positive, returning the created CONTRIBUTION with the ID of the created VERSION<COMPOSITION>

  3. Invoke commit CONTRIBUTION service with an existing ehr_id and a valid VERSION<COMPOSITION>

    1. The COMPOSITION should have the same template_id as the one used in 1.

    2. The VERSION change_type = modification and preceding_version_uid = version id returned in 2.

  4. The result should be positive and the returned version id should reflect it’s a new version of an existing COMPOSITION created in 1. (has the same OBJECT_VERSION_ID with version number = 2)

7.5.1.6. TC I_EHR_CONTRIBUTION.commit_contribution-persistent_composition

Description

Commit CONTRIBUTION with persistent COMPOSITIONs.

Pre-conditions

  1. An EHR with known ehr_id exists

  2. OPTs for each valid case are loaded on the server

Post-conditions

  1. There should be two VERSIONs of the same COMPOSITION in the EHR with ehr_id

Flow

  1. Invoke commit CONTRIBUTION service with an existing ehr_id and a valid VERSION<COMPOSITION>

    1. The COMPOSITION.category = persistent

    2. The COMPOSITION references an existing OPT on the server

  2. The result should be positive, returning the version id for the created VERSION

  3. Invoke commit CONTRIBUTION service with an existing ehr_id and a valid VERSION<COMPOSITION>

    1. The COMPOSITION should have the same template_id as the one used in 1.

    2. The VERSION.change_type = modification

    3. The VERSION.preceding_version_uid = version id returned in 2.,

  4. The result should be positive and the returned version id should reflect it is a new version of an existing COMPOSITION created in 1. (has the same OBJECT_VERSION_ID with version number = 2)

7.5.1.7. TC I_EHR_CONTRIBUTION.commit_contribution-delete_composition

Description

Commit CONTRIBUTION deleting a COMPOSITION.

Pre-conditions

  1. An EHR with known ehr_id exists

  2. OPTs for each valid case are loaded on the server

Post-conditions

  1. Two VERSIONs of the same COMPOSITION should exist in the EHR with ehr_id

  2. The VERSIONED_OBJECT should be logically deleted NOTE: the effect of a VERSIONED_OBJECT being deleted might vary in different implementations. This needs further specification at the openEHR Service Model

Flow

  1. Invoke commit CONTRIBUTION service with an existing ehr_id and a valid VERSION<COMPOSITION>

    1. The COMPOSITION references an existing OPT on the server

  2. The result should be positive, returning the version id for the created VERSION

  3. Invoke commit CONTRIBUTION service with an existing ehr_id and a valid VERSION<COMPOSITION>

    1. The COMPOSITION should reference the same template_id as the one used in 1.

    2. The VERSION.change_type = deleted

    3. The VERSION.preceding_version_uid = version id returned in 2.

  4. The result should be positive and the returned version id should reflect it is a new version of an existing COMPOSITION created in 1. (has the same OBJECT_VERSION_ID with version number = 2, which should be deleted)

7.5.1.8. TC I_EHR_CONTRIBUTION.commit_contribution-two_commits_second_invalid

Description

Commit two CONTRIBUTIONa on same COMPOSITION with second containing invalid content.

Pre-conditions

  1. An EHR with known ehr_id exists

  2. OPTs for each valid case are loaded on the server

Post-conditions

  1. There will be just one VERSION in the EHR with ehr_id

Flow

  1. Invoke commit CONTRIBUTION service with an existing ehr_id and a valid VERSION<COMPOSITION>

    1. The COMPOSITION references an existing OPT on the server

  2. The result should be positive, returning the version id for the created VERSION

  3. Invoke commit CONTRIBUTION service with an existing ehr_id and a valid VERSION<COMPOSITION>

    1. The COMPOSITION references the same template_id as the one used in 1.

    2. The VERSION has change_type = modification

    3. The VERSION has preceding_version_uid = version id returned in 2.

    4. The COMPOSITION is one of the invalid data sets

  4. The result should be negative, and retrieve some info about the errors found on the data committed

7.5.1.9. TC I_EHR_CONTRIBUTION.commit_contribution-two_commits_second_creation

Description

Commit two CONTRIBUTIONa on same COMPOSITION with second having change_type = creation

Pre-conditions

  1. An EHR with known ehr_id exists

  2. OPTs for each valid case are loaded on the server

Post-conditions

  1. There will be just one VERSION in the EHR with ehr_id

Flow

  1. Invoke commit CONTRIBUTION service with an existing ehr_id and a valid VERSION<COMPOSITION>

    1. The COMPOSITION references an existing OPT on the server

  2. The result should be positive, returning the version id for the created VERSION

  3. Invoke commit CONTRIBUTION service with an existing ehr_id and a valid VERSION<COMPOSITION>

    1. The COMPOSITION references the same template_id as the one used in 1.

    2. The VERSION.change_type = creation

    3. The VERSION.preceding_version_uid = version id returned in 2.

  4. The result should be negative, and retrieve some info about the wrong change type (see notes)

Note
Validity criterion: only one 'create' operation is allowed for persistent COMPOSITIONs, the next operations over an existing persistent COMPOSITION should be modification.
7.5.1.10. TC I_EHR_CONTRIBUTION.commit_contribution-non_exiting_opt

Description

Commit CONTRIBUTION with COMPOSITION referencing a non existing OPT

Pre-conditions

  1. An EHR with known ehr_id exists

  2. There are no OPTs loaded on the server

Post-conditions

None

Flow

  1. Invoke commit CONTRIBUTION service with an existing ehr_id and a valid VERSION<COMPOSITION>

    1. The COMPOSITION references a random OPT template_id

  2. The result should be negative and retrieve an error indicating the missing OPT

7.5.1.11. TC I_EHR_CONTRIBUTION.commit_contribution-minimal_ehr_status

Description

Commit CONTRIBUTION containing minimal EHR_STATUS

Pre-conditions

  1. An EHR with known ehr_id exists

  2. The EHR contains a default EHR_STATUS

Post-conditions

  1. The EHR should have a new CONTRIBUTION

  2. The EHR should have a new VERSION for the EHR_STATUS

Flow

  1. Invoke commit CONTRIBUTION service with an existing ehr_id and the valid data sets (see section B.3.)

    1. For EHR_STATUS CONTRIBUTIONs, the change_type is always modification or amendment

  2. The result should be positive and retrieve the id of the CONTRIBUTION just created

  3. Verify expected CONTRIBUTION uids and CONTRIBUTION count for the EHR with ehr_id

7.5.1.12. TC I_EHR_CONTRIBUTION.commit_contribution-full_ehr_status
Note
this case is the same as previous but the precondition 2. is different.

Description

Commit CONTRIBUTION containing full EHR_STATUS

Pre-conditions

  1. An EHR with known ehr_id exists

  2. The EHR contains a full EHR_STATUS (all the optional information is set, i.e. subject.external_ref etc)

Post-conditions

  1. The EHR should have a new CONTRIBUTION

  2. The EHR should have a new VERSION for the EHR_STATUS

Flow

  1. Invoke commit CONTRIBUTION service with an existing ehr_id and the valid data sets (see above)

    1. Use change_type = modification or amendment

  2. The result should be positive and retrieve the id of the CONTRIBUTION just created

  3. Verify expected CONTRIBUTION uids and CONTRIBUTION count for the EHR with ehr_id

7.5.1.13. TC I_EHR_CONTRIBUTION.commit_contribution-ehr_status_invalid_change_type

Description

Commit CONTRIBUTION containing EHR_STATUS with invalid change type

Pre-conditions

  1. An EHR with known ehr_id exists

  2. The EHR has the default EHR_STATUS

Post-conditions

None

Flow

  1. Invoke commit CONTRIBUTION service with an existing ehr_id and the valid data sets (see above)

    1. Use change_type = create and delete

  2. The result should be negative and retrieve an error indicating the EHR_STATUS already existing for the EHR

7.5.1.14. TC I_EHR_CONTRIBUTION.commit_contribution-invalid_ehr_status

Description

Commit CONTRIBUTION containing invalid EHR_STATUS

Pre-conditions

  1. An EHR with known ehr_id exists

  2. The EHR has the default EHR_STATUS

Post-conditions

None

Flow

  1. Invoke commit CONTRIBUTION service with an existing ehr_id and the invalid data sets (see above)

    1. Use change_type = modification

  2. The result should be negative and retrieve an error indicating the invalid EHR_STATUS

7.5.1.15. TC I_EHR_CONTRIBUTION.commit_contribution-valid_directory

Description

Commit CONTRIBUTION containing valid FOLDER

Pre-conditions

  1. An EHR with known ehr_id exists

  2. The EHR doesn’t have a directory (root FOLDER)

Post-conditions

  1. The EHR with ehr_id should have a new CONTRIBUTION and a directory

Flow

  1. Invoke commit CONTRIBUTION service with an existing ehr_id and the valid data sets (see above) and change_type = creation

  2. The result should be positive and retrieve the id of the CONTRIBUTION just created

7.5.1.16. TC I_EHR_CONTRIBUTION.commit_contribution-fail_create_existing_directory

Description

Commit CONTRIBUTION attempting to create an EHR directory that already exists

Pre-conditions

  1. An EHR with known ehr_id exists

  2. The EHR has a directory (root FOLDER)

Post-conditions

None

Flow

  1. Invoke commit CONTRIBUTION service with an existing ehr_id and the valid data sets (see above) and change_type = creation

  2. The result should be negative, and retrieve an error indicating the wrong change_type because the root FOLDER already exists

7.5.1.17. TC I_EHR_CONTRIBUTION.commit_contribution-fail_modify_non_existing_directory

Description

Commit CONTRIBUTION attempting to modify an EHR directory that doesn’t exist

Pre-conditions

  1. An EHR with known ehr_id exists

  2. The EHR has no directory (root FOLDER)

Post-conditions

None

Flow

  1. Invoke commit CONTRIBUTION service with an existing ehr_id and the valid data sets

    1. Use change_type = modification

    2. Use a random preceding_version_uid

  2. The result should be negative since, and retrieve an error indicating the wrong change_type, because it’s trying to modify something that doesn’t exist

7.5.1.18. TC I_EHR_CONTRIBUTION.commit_contribution-update_existing_directory

Description

Commit CONTRIBUTION updating an EHR directory

Pre-conditions

  1. An EHR with known ehr_id exists

  2. The EHR has a directory (root FOLDER)

Post-conditions

  1. The EHR should have a new CONTRIBUTION and a new VERSION for the root FOLDER

Flow

  1. Invoke commit CONTRIBUTION service with an existing ehr_id and the valid data sets with change_type = modification or amendment

  2. The result should be positive and retrieve the id of the CONTRIBUTION just created

7.5.2. Conformance point: I_EHR_CONTRIBUTION.list_contributions()

Note
CONTRIBUTIONs can contain COMPOSITION, EHR_STATUS or FOLDER, or any mix of those. Each flow below applies to a specific type, except when 'ANY' is mentioned, in which case the flow applies to any of those three types.
7.5.2.1. TC I_EHR_CONTRIBUTION.list_contributions-post_commit

Description

List CONTRIBUTIONs following successful commit

Pre-conditions

  1. An EHR with known ehr_id exists

  2. The EHR as a CONTRIBUTION with known uid

  3. The CONTRIBUTION contains a VERSION<COMPOSITION>

Post-conditions

  1. The EHR should have a new CONTRIBUTION and a new VERSION for the root FOLDER

Flow

  1. Invoke list CONTRIBUTIONs service with the existing ehr_id

  2. The result should be positive and retrieve a list of CONTRIBUTIONs with one item

  3. The CONTRIBUTION should contain a VERSION<COMPOSITION>

7.5.2.2. TC I_EHR_CONTRIBUTION.list_contributions-empty

Description

List CONTRIBUTIONs of existing EHR with no CONTRIBUTIONS

Pre-conditions

  1. An EHR with known ehr_id should exist

  2. The EHR has no CONTRIBUTIONs

Post-conditions

None

Flow

  1. Invoke get CONTRIBUTIONs service by the existing ehr_id

  2. The result should be positive and retrieve an empty list

7.5.2.3. TC I_EHR_CONTRIBUTION.list_contributions-non_existing_ehr

Description

List CONTRIBUTIONs of non-existing EHR (ANY)

Pre-conditions

  1. There are no EHRs on the server

Post-conditions

None

Flow

  1. Invoke list CONTRIBUTIONs service with a random ehr_id

  2. The result should be negative and retrieve an error indicating "EHR with `ehr_id doesn’t exist"`

7.5.2.4. TC I_EHR_CONTRIBUTION.list_contributions-ehr_containing_ehr_status

Description

List CONTRIBUTIONs post commit of CONTRIBUTION containing EHR_STATUS

Pre-conditions

  1. An EHR with known ehr_id exists

  2. The EHR has a CONTRIBUTION with known uid

  3. The CONTRIBUTION contains a VERSION<EHR_STATUS>

Post-conditions

None

Flow

  1. Invoke list CONTRIBUTIONs service by the existing ehr_id

  2. The result should be positive and retrieve a list of CONTRIBUTIONs with one item

  3. The CONTRIBUTION should contain an EHR_STATUS

7.5.2.5. TC I_EHR_CONTRIBUTION.list_contributions-ehr_containing_directory

Description

List CONTRIBUTIONs post commit of CONTRIBUTION containing a directory

Pre-conditions

  1. An EHR with known ehr_id exists

  2. The EHR has a CONTRIBUTION with known uid

  3. The CONTRIBUTION contains a VERSION<FOLDER>

Post-conditions

None

Flow

  1. Invoke get CONTRIBUTIONs service by the existing ehr_id

  2. The result should be positive and retrieve a list of CONTRIBUTIONs with one item

  3. The CONTRIBUTION should contain a FOLDER

7.5.3. Conformance point: I_EHR_CONTRIBUTION.has_contribution()

7.5.3.1. TC I_EHR_CONTRIBUTION.has_contribution-existing

Description

Test presence of CONTRIBUTIONs post commit of CONTRIBUTION

Pre-conditions

  1. An EHR should exist in the system with a known ehr_id

  2. The EHR has a CONTRIBUTION with known uid

Post-conditions

None

Flow

  1. Invoke has CONTRIBUTION service with the known ehr_id and CONTRIBUTION uid

  2. The result should be true

7.5.3.2. TC I_EHR_CONTRIBUTION.has_contribution-empty_ehr

Description

Test presence of CONTRIBUTIONs on empty EHR

Pre-conditions

  1. An EHR should exists in the system with a known ehr_id

  2. The EHR doesn’t have any CONTRIBUTIONs

Post-conditions

None

Flow

  1. Invoke has CONTRIBUTION service with the known ehr_id and a random CONTRIBUTION uid

  2. The result should be false

7.5.3.3. TC I_EHR_CONTRIBUTION.has_contribution-bad_ehr

Description

Test presence of CONTRIBUTIONs on non-existent EHR

Pre-conditions

  1. There are no EHRs on the server

Post-conditions

None

Flow

  1. Invoke has CONTRIBUTION service with a random ehr_id and a random CONTRIBUTION uid

  2. The result should be negative, and retrieve an error indicating "the EHR with ehr_id doesn’t exist"

7.5.3.4. TC I_EHR_CONTRIBUTION.has_contribution-bad_contribution

Description

Test presence of CONTRIBUTION that doesn’t exist

Pre-conditions

  1. An EHR should exist on the server with a known ehr_id

  2. The EHR has CONTRIBUTIONs

Post-conditions

None

Flow

  1. Invoke has CONTRIBUTION service with the known ehr_id and a random, not existing CONTRIBUTION uid

  2. The result should be false

7.5.4. Conformance point: I_EHR_CONTRIBUTION.get_contribution()

7.5.4.1. TC I_EHR_CONTRIBUTION.get_contribution-existing

Description

Test get CONTRIBUTION from EHR with existing CONTRIBUTION

Pre-conditions

  1. An EHR should exist in the system with a known ehr_id

  2. The EHR has a CONTRIBUTION with known uid

Post-conditions

None

Flow

  1. Invoke has CONTRIBUTION service with the known ehr_id and CONTRIBUTION uid

  2. The result should be the existing CONTRIBUTION

7.5.4.2. TC I_EHR_CONTRIBUTION.get_contribution-empty_ehr

Description

Test get CONTRIBUTION from empty EHR

Pre-conditions

  1. An EHR should exists in the system with a known ehr_id

  2. The EHR doesn’t have any CONTRIBUTIONs

Post-conditions

None

Flow

  1. Invoke has CONTRIBUTION service with the known ehr_id and a random CONTRIBUTION uid

  2. The result should be negative and retrieve an error indicating the non-existing CONTRIBUTION

7.5.4.3. TC I_EHR_CONTRIBUTION.get_contribution-bad_ehr

Description

Test get CONTRIBUTION from non-existing EHR

Pre-conditions

  1. There are no EHRs on the server

Post-conditions

None

Flow

  1. Invoke has CONTRIBUTION service with a random ehr_id and a random CONTRIBUTION uid

  2. The result should be negative, and retrieve an error indicating "the EHR with ehd_id doesn’t exist"

7.5.4.4. TC I_EHR_CONTRIBUTION.get_contribution-bad_contribution

Description

Test get CONTRIBUTION from EHR with non-existing CONTRIBUTION

Pre-conditions

  1. An EHR should exist on the server with a known ehr_id

  2. The EHR has CONTRIBUTIONs

Post-conditions

None

Flow

  1. Invoke has CONTRIBUTION service with the known ehr_id and a random, non-existing CONTRIBUTION uid

  2. The result should be negative and retrieve an error indicating the non-existing CONTRIBUTION

8. Functional Conformance: EHR / DIRECTORY Component

8.1. Normative Reference

Items in this validation suite conceptually use the following abstract interfaces from the Abstract Platform Service Model, EHR/DIRECTORY component.

  • I_EHR_DIRECTORY

These are concretely realised in implementation technology specfic APIs, such as the EHR REST API.

The data that flow through these interfaces are defined by the following information model specifications:

8.2. Dependencies

This test suite depends on other test suites:

8.3. Test Environment

TBD

8.4. Test Data Sets

For the creation and modification of the EHR.directory structure it is important to explore the hierarchical nature of the FOLDER structures and consider the edge cases for EHR.directory.

8.4.1. Tests of EHR.directory

  1. FOLDER

  2. FOLDER with items

  3. FOLDER with subfolders

  4. FOLDER with subfolders and items on all the folders

  5. FOLDER with n levels of subfolders and items (to detect any implementation limitations)

8.4.2. Tests of Reference FOLDER structure

Note
the following image is provided for reference. The items in the FOLDER are references to VERSIONED_OBJECTs that may contain COMPOSITION, EHR_STATUS and FOLDER. This documentation focuses on testing COMPOSITION as content in the FOLDERs. Related discussion: here.
high level ehr structure
Figure 1. Folder structures in the EHR

8.5. Test Cases

8.5.1. Conformance point: I_EHR_DIRECTORY.has_directory()

Platform service ref: I_EHR_DIRECTORY.has_directory()

8.5.1.1. TC I_EHR_DIRECTORY.has_directory-empty_ehr

Description

Test has_directory on empty EHR

Pre-conditions

  1. An EHR with known ehr_id exists

  2. The EHR doesn’t have a directory

Post-conditions

None

Flow

  1. Invoke the has_directory service for the ehr_id

  2. The result must be false

8.5.1.2. TC I_EHR_DIRECTORY.has_directory-ehr_with_directory

Description

Test has_directory on EHR containing a directory

Pre-conditions

  1. An EHR with known ehr_id exists

  2. The EHR has a directory

Post-conditions

None

Flow

  1. Invoke the has_directory service for the ehr_id

  2. The result must be true

8.5.1.3. TC I_EHR_DIRECTORY.has_directory-bad_ehr

Description

Test has_directory on non-existent EHR

Pre-conditions

  1. There are no EHRs on the server

Post-conditions

None

Flow

  1. Invoke the has_directory service for a random non-existent ehr_id

  2. An error should be returned, indicating that the EHR that doesn’t exist

8.5.2. Conformance point: I_EHR_DIRECTORY.has_path()

Platform service ref: I_EHR_DIRECTORY.has_path()

8.5.2.1. TC I_EHR_DIRECTORY.has_path-empty_ehr

Description

Test has_path on empty EHR

Pre-conditions

  1. An EHR with known ehr_id exists

  2. The EHR doesn’t have a directory

Post-conditions

None

Flow

  1. Invoke the has path service for the ehr_id with a random FOLDER path

  2. The result must be false

8.5.2.2. TC I_EHR_DIRECTORY.has_path-ehr_root_directory

Description

Test has_path on EHR with just root directory

Pre-conditions

  1. An EHR with known ehr_id exists

  2. The EHR and has an empty directory (no subfolders or items)

Post-conditions

None

Flow

  1. Invoke the has path service for the ehr_id and an existing path $path from the data set

  2. The result must be $result from the data set

Data set

$path $result

'/'

true

random()

false

Note
'/' represents the string slash, which is the default name for the root FOLDER at EHR.directory, random() represents any randomly generated path that doesn’t exist.
8.5.2.3. TC I_EHR_DIRECTORY.has_path-folder_structure

Description

Test has_path on EHR with folder structure

Pre-conditions

  1. An EHR with known ehr_id exists

  2. The EHR has a directory with an internal structure (described below)

Post-conditions

None

Flow

  1. Invoke the has path service for the ehr_id and the path $path from the data set

  2. The result must be $result from the data set

Data set

Assuming the following structure in EHR.directory:

/
    +--- emergency
    |        |
    |        +--- episode-x
    |        |      |
    |        |      +--- summary-composition-x
    |        |
    |        +--- episode-y
    |               |
    |               +--- summary-composition-y
    |
    +--- hospitalization
             |
             +--- summary-composition-z
Note
these are the names of the FOLDERs and COMPOSITIONs in EHR.directory.
$path $result

'/'

true

'/emergency'

true

'/emergency/episode-x'

true

'/emergency/episode-x/summary-composition-x'

true

'/emergency/episode-y'

true

'/emergency/episode-y/summary-composition-y'

true

'/hospitalization'

true

'/hospitalization/summary-composition-z'

true

'/' + random()

false

'/emergency/' + random()

false

'/emergency/episode-x/' + random()

false

random()

false

Note
the table mixes cases that exist with cases of paths which part exists and parts doesn’t exist. The final one is a random path.
8.5.2.4. TC I_EHR_DIRECTORY.has_path-bad_ehr

Description

Test has_path on non-existent EHR

Pre-conditions

  1. The server is empty

Post-conditions

None

Flow

  1. Invoke the has path service for a random ehr_id and path

  2. The service should return an error, indicating that the EHR doesn’t exist

8.5.3. Conformance point: I_EHR_DIRECTORY.create_directory()

Platform service ref: I_EHR_DIRECTORY.create_directory()

8.5.3.1. TC I_EHR_DIRECTORY.create_directory-empty_ehr

Description

Test create_directory on empty EHR

Pre-conditions

  1. An EHR with ehr_id exists

  2. The EHR doesn’t have a directory

Post-conditions

  1. The EHR ehr_id should have a directory

Flow

  1. Invoke the create directory service with the existing ehr_id and a valid FOLDER structure

    1. Use any of the data sets described on the previous tests and the reference directory structure

  2. The service should return a positive result indicating the directory created for the EHR

8.5.3.2. TC I_EHR_DIRECTORY.create_directory-ehr_with_directory

Description

Test create_directory on EHR with directory

Pre-conditions

  1. An EHR with ehr_id exists

  2. The EHR has a directory

Post-conditions

None

Flow

  1. Invoke the create directory service with the existing ehr_id and a valid FOLDER structure

    1. Use any of the data sets described on the previous tests and the reference directory structure

  2. The service should return an error, indicating that the EHR directory already exists

8.5.3.3. TC I_EHR_DIRECTORY.create_directory-bad_ehr

Description

Test create_directory on non-existent EHR

Pre-conditions

  1. The server should be empty

Post-conditions

None

Flow

  1. Invoke the create directory service for a random ehr_id

  2. The service should return an error, indicating that the EHR that doesn’t exist

8.5.4. Conformance point: I_EHR_DIRECTORY.get_directory()

Platform service ref: I_EHR_DIRECTORY.get_directory()

8.5.4.1. TC I_EHR_DIRECTORY.get_directory-empty_ehr

Description

Test get_directory on empty EHR

Pre-conditions

  1. An EHR with ehr_id exists

  2. The EHR doesn’t have a directory

Post-conditions

None

Flow

  1. Invoke the get directory service for the ehr_id

  2. The service should return an empty structure

Note
in a REST API implementation, the result could be an error status instead of an empty structure.
8.5.4.2. TC I_EHR_DIRECTORY.get_directory-ehr_root_directory

Description

Test get_directory on EHR with a root directory

Pre-conditions

  1. An EHR with ehr_id exists

  2. The EHR has a single empty FOLDER in its directory

Post-conditions

None

Flow

  1. Invoke the get directory service for the ehr_id

  2. The service should return the structure of the EHR.directory: an empty FOLDER

8.5.4.3. TC I_EHR_DIRECTORY.get_directory-directory_with_structure

Description

Test get_directory on EHR with a directory containing sub-structure

Pre-conditions

  1. An EHR with ehr_id exists

  2. The EHR has a directory with a sub-structure (use the data sets from the previous tests and the reference directory structure)

Post-conditions

None

Flow

  1. Invoke the get directory service for the ehr_id

  2. The service should return the full structure of the EHR directory

8.5.4.4. TC I_EHR_DIRECTORY.get_directory-bad_ehr

Description

Test get_directory on non-existent EHR

Pre-conditions

  1. The server is empty

Post-conditions

None

Flow

  1. Invoke the get directory service for a random ehr_id

  2. The service should return an error related with the non-existent EHR

8.5.5. Conformance point: I_EHR_DIRECTORY.get_directory_at_time()

8.5.5.1. TC I_EHR_DIRECTORY.get_directory_at_time-empty_ehr

Description

Test get_directory_at_time on empty EHR

Pre-conditions

  1. An EHR with ehr_id exists

  2. The EHR doesn’t have a directory

Post-conditions

None

Flow

  1. Invoke the get directory at time service for the ehr_id and current time

  2. The service should return an empty structure

Note
considering a REST API implementation, the result could be an error status instead of an empty structure.
8.5.5.2. TC I_EHR_DIRECTORY.get_directory_at_time-empty_ehr_empty_time

Description

Test get_directory_at_time on empty EHR with empty time

Pre-conditions

  1. An EHR with ehr_id exists

  2. The EHR doesn’t have a directory

Post-conditions

None

Flow

  1. Invoke the get directory at time service for the ehr_id and empty time

  2. The service should return an empty structure

Note
considering a REST API implementation, the result could be an error status instead of an empty structure.
8.5.5.3. TC I_EHR_DIRECTORY.get_directory_at_time-ehr_with_directory

Description

Test get_directory_at_time on empty EHR with directory

Pre-conditions

  1. An EHR with ehr_id exists

  2. The EHR has a directory with one version (use any of the valid datasets from the previous tests)

Post-conditions

None

Flow

  1. Invoke the get directory at time service for the ehr_id and current time

  2. The service should return the current directory

8.5.5.4. TC I_EHR_DIRECTORY.get_directory_at_time-ehr_with_directory_empty_time

Description

Test get_directory_at_time on EHR with directory with empty time

Pre-conditions

  1. An EHR with ehr_id exists

  2. The EHR has a directory with one version (use any of the valid datasets from the previous tests)

Post-conditions

None

Flow

  1. Invoke the get directory at time service for the ehr_id and empty time

  2. The service should return the current directory

8.5.5.5. TC I_EHR_DIRECTORY.get_directory_at_time-ehr_with_directory_versions

Description

Test get_directory_at_time on EHR with directory containing multiple versions

Pre-conditions

  1. An EHR with ehr_id exists

  2. The EHR has a directory with two versions (use any of the valid datasets from the previous tests, add small changes to differentiate the versions)

Post-conditions

None

Flow

  1. Invoke the get directory at time service for the ehr_id and a time before EHR.time_created

  2. The service should return an empty structure

  3. Invoke the get directory at time service for the ehr_id and a time after the first EHR.directory version was created and before the second EHR.directory version was created

  4. The service should return the first version of EHR.drectory

  5. Invoke the get directory at time service for the ehr_id and current time

  6. The service should return the second version of EHR.directory

8.5.5.6. TC I_EHR_DIRECTORY.get_directory_at_time-ehr_with_directory_versions_empty_time

Description

Test get_directory_at_time on EHR with directory containing multiple versions with empty time

Pre-conditions

  1. An EHR with ehr_id exists

  2. The EHR has a directory with two versions (use any of the valid datasets from the previous tests, add small changes to differentiate the versions)

Post-conditions

None

Flow

  1. Invoke the get directory at time service for the ehr_id and empty time

  2. The service should return the current latest directory

8.5.5.7. TC I_EHR_DIRECTORY.get_directory_at_time-bad_ehr

Description

Test get_directory_at_time on non-existent EHR

Pre-conditions

  1. The server is empty

Post-conditions

None

Flow

  1. Invoke the get directory at time service for a random ehr_id and current time

  2. The service should return an error indicating non-existent EHR

8.5.5.8. TC I_EHR_DIRECTORY.get_directory_at_time-multiple_versions_first

Description

Test get_directory_at_time on EHR with directory with multiple versions first version

Pre-conditions

  1. An EHR with ehr_id and has directory with two versions

Post-conditions

None

Flow

  1. Invoke the get directory at time service for the ehr_id and a time AFTER the first version of the directory was created, but BEFORE the second version was created (update)

  2. The service should return the first version of the directory

8.5.6. Conformance point: I_EHR_DIRECTORY.update_directory()

Platform service ref: I_EHR_DIRECTORY.update_directory()

8.5.6.1. TC I_EHR_DIRECTORY.update_directory-ehr_with_directory

Description

Test update_directory on EHR with directory

Pre-conditions

  1. An EHR with ehr_id exists on the server

  2. The EHR has a directory

Post-conditions

  1. The EHR with ehr_id has an updated directory structure

Flow

  1. Invoke the update directory service for the ehr_id

    1. Use any of the valid paylaods described on the previous tests

  2. The service should return a positive result related with the updated directory

8.5.6.2. TC I_EHR_DIRECTORY.update_directory-empty_ehr

Description

Test update_directory on empty EHR

Pre-conditions

  1. An EHR with ehr_id exists on the server

  2. The EHR doesn’t have a directory

Post-conditions

None

Flow

  1. Invoke the update directory service for the ehr_id

    1. Use any of the valid paylaods described on the previous tests

  2. The service should return an error indicating that the non existent directory to update

8.5.6.3. TC I_EHR_DIRECTORY.update_directory-bad_ehr

Description

Test update_directory on non-existent EHR

Pre-conditions

  1. The server is empty

Post-conditions

None

Flow

  1. Invoke the update directory service for random ehr_id

    1. Any valid payload will suffice

  2. The service should return an error indicating that the non existent ehr_id

8.5.7. Conformance point: I_EHR_DIRECTORY.delete_directory()

Platform service ref: I_EHR_DIRECTORY.delete_directory()

8.5.7.1. TC I_EHR_DIRECTORY.delete_directory-empty_ehr

Description

Test delete_directory on empty EHR

Pre-conditions

  1. An EHR with ehr_id exists on the server

  2. The EHR doesn’t have a directory

Post-conditions

None

Flow

  1. Invoke the delete directory service for the ehr_id

  2. The service should return an error indicating the non existent directory

8.5.7.2. TC I_EHR_DIRECTORY.delete_directory-ehr_with_directory

Description

Test delete_directory on EHR with directory

Pre-conditions

  1. An EHR with ehr_id exists on the server

  2. The EHR has a directory

Post-conditions

  1. The EHR ehr_id doesn’t have directory

Note
the directory exists as a new deleted version (that is VERSION.lifecycle_state=deleted).

Flow

  1. Invoke the delete directory service for the ehr_id

  2. The service should return a positive result related with the deleted directory

8.5.7.3. TC I_EHR_DIRECTORY.delete_directory-bad_ehr

Description

Test delete_directory on non-existent EHR

Pre-conditions

  1. The server is empty

Post-conditions

None

Flow

  1. Invoke the get directory service for a random ehr_id

  2. The service should return an error indicating that the non existent EHR

8.5.8. Conformance point: I_EHR_DIRECTORY.has_directory_version()

8.5.8.1. TC I_EHR_DIRECTORY.has_directory_version-empty_ehr

Description

Test has_directory_version on empty EHR

Pre-conditions

  1. An EHR with known ehr_id exists on the server

  2. The EHR doesn’t have a directory

Post-conditions

None

Flow

  1. Invoke the has directory service for the ehr_id and a random version uid

  2. The service should return false

8.5.8.2. TC I_EHR_DIRECTORY.has_directory_version-directory_with_two_versions

Description

Test has_directory_version on EHR that has two versions of directory

Pre-conditions

  1. An EHR with known ehr_id exists on the server

  2. The EHR has two directory versions

Post-conditions

None

Flow

  1. Invoke the has directory service for the ehr_id and the version_uid of the first version of directory

  2. The service should return true

  3. Invoke the has directory service for the ehr_id and the version_uid of the second version of directory

  4. The service should return true

8.5.8.3. TC I_EHR_DIRECTORY.has_directory_version-bad_ehr

Description

Test has_directory_version on non-existent EHR

Pre-conditions

  1. The server doesn’t have EHRs

Post-conditions

None

Flow

  1. Invoke the has directory service for a random ehr_id and version uid

  2. The service should return an error related with the non-existence of the EHR

8.5.9. Conformance point: I_EHR_DIRECTORY.get_directory_at_version()

8.5.9.1. TC I_EHR_DIRECTORY.get_directory_at_version-empty_ehr

Description

Test get_directory_at_version on empty EHR

Pre-conditions

  1. An EHR with known ehr_id exists on the server

  2. The EHR doesn’t have a directory

Post-conditions

None

Flow

  1. Invoke the get directory at version service for the ehr_id and a random version uid

  2. The service should return an error indicating that the non-existence of the EHR directory version

8.5.9.2. TC I_EHR_DIRECTORY.get_directory_at_version-directory_with_two_versions

Description

Test get_directory_at_version on EHR that has two versions of directory

Pre-conditions

  1. An EHR with known ehr_id exists on the server

  2. The EHR has two versions of directory

Post-conditions

None

Flow

  1. Invoke the get directory at version service for the ehr_id and the version_uid of the first version of directory

  2. The service should return the first version of the directory

  3. Invoke the get directory at version service for the ehr_id and the version_uid of the second version of directory

  4. The service should return the second version of the directory

8.5.9.3. TC I_EHR_DIRECTORY.get_directory_at_version-bad_ehr

Description

Test get_directory_at_version on non-existent EHR

Pre-conditions

  1. The server doesn’t have EHRs

Post-conditions

None

Flow

  1. Invoke the get directory at version service for a random ehr_id and version uid

  2. The service should return an error related with the non existence of the EHR

8.5.10. Conformance point: I_EHR_DIRECTORY.get_versioned_directory()

8.5.10.1. TC I_EHR_DIRECTORY.get_versioned_directory-empty_ehr

Description

Test get_versioned_directory on non-existent EHR

Pre-conditions

  1. An EHR with known ehr_id exists on the server

Post-conditions

None

Flow

  1. Invoke the get versioned directory service for the ehr_id

  2. The service should return an error because the versioned directory doesn’t exist

Note
depending on the implementation, a valid result could also be returning an empty result instead of an error.
8.5.10.2. TC I_EHR_DIRECTORY.get_versioned_directory-directory_with_two_versions

Description

Test get_versioned_directory on EHR that has two versions of directory

Pre-conditions

  1. An EHR with known ehr_id exists on the server

  2. The EHR has two versions of directory

Post-conditions

None

Flow

  1. Invoke the get versioned directory service for the ehr_id

  2. The service should return the versioned folder and should reference the two exsinting versions

8.5.10.3. TC I_EHR_DIRECTORY.get_versioned_directory-bad_ehr

Description

Test get_versioned_directory on non-existent EHR

Pre-conditions

  1. The server doesn’t have any EHRs

Post-conditions

None

Flow

  1. Invoke the get directory service for a random ehr_id

  2. The service should return an error related with the non existence of the EHR

9. Functional Conformance: Demographic Component

9.1. Normative Reference

Items in this validation suite conceptually use the following abstract interfaces from the Abstract Platform Service Model, DEMOGRAPHIC component.

  • I_DEMOGRAPHIC_SERVICE

These are concretely realised in implementation technology specfic APIs, such as the EHR REST API.

The data that flow through these interfaces are defined by the following information model specifications:

9.2. Dependencies

This test suite depends on other test suites:

9.3. Test Environment

TBD

9.4. Test Data Sets

TBD

9.5. Test Cases

9.5.1. Conformance point: I_DEMOGRAPHIC_SERVICE.create_party()

Platform service ref: I_DEMOGRAPHIC_SERVICE.create_party()

9.5.1.1. TC aaaa

TBD

9.5.1.2. TC bbbb

TBD

9.5.2. Conformance point: I_DEMOGRAPHIC_SERVICE.get_party()

Platform service ref: I_DEMOGRAPHIC_SERVICE.get_party()

9.5.2.1. TC aaaa

TBD

9.5.2.2. TC bbbb

TBD

9.5.3. Conformance point: I_DEMOGRAPHIC_SERVICE.get_party_at_time()

9.5.3.1. TC aaaa

TBD

9.5.3.2. TC bbbb

TBD

9.5.4. Conformance point: I_DEMOGRAPHIC_SERVICE.update_party()

Platform service ref: I_DEMOGRAPHIC_SERVICE.update_party()

9.5.4.1. TC aaaa

TBD

9.5.4.2. TC bbbb

TBD

9.5.5. Conformance point: I_DEMOGRAPHIC_SERVICE.delete_party()

Platform service ref: I_DEMOGRAPHIC_SERVICE.delete_party()

9.5.5.1. TC aaaa

TBD

9.5.5.2. TC bbbb

TBD

9.5.6. Conformance point: I_DEMOGRAPHIC_SERVICE.get_party_at_version()

9.5.6.1. TC aaaa

TBD

9.5.6.2. TC bbbb

TBD

9.5.7. Conformance point: I_DEMOGRAPHIC_SERVICE.create_party_relationship()

9.5.7.1. TC aaaa

TBD

9.5.7.2. TC bbbb

TBD

9.5.8. Conformance point: I_DEMOGRAPHIC_SERVICE.get_party_relationship()

9.5.8.1. TC aaaa

TBD

9.5.8.2. TC bbbb

TBD

9.5.9. Conformance point: I_DEMOGRAPHIC_SERVICE.get_party_relationship_at_time()

9.5.9.1. TC aaaa

TBD

9.5.9.2. TC bbbb

TBD

9.5.10. Conformance point: I_DEMOGRAPHIC_SERVICE.update_party_relationship()

9.5.10.1. TC aaaa

TBD

9.5.10.2. TC bbbb

TBD

9.5.11. Conformance point: I_DEMOGRAPHIC_SERVICE.delete_party_relationship()

9.5.11.1. TC aaaa

TBD

9.5.11.2. TC bbbb

TBD

9.5.12. Conformance point: I_DEMOGRAPHIC_SERVICE.get_party_relationship_at_version()

9.5.12.1. TC aaaa

TBD

9.5.12.2. TC bbbb

TBD

10. Functional Conformance: Querying Component

10.1. Normative Reference

Items in this validation suite conceptually use the following abstract interfaces from the Abstract Platform Service Model, QUERY component.

  • I_QUERY_SERVICE

These are concretely realised in implementation technology specfic APIs, such as the QUERY REST API.

The data that flow through these interfaces are defined by the following information model specifications:

10.2. Dependencies

This test suite depends on other test suites:

10.3. Test Environment

TBD

10.4. Test Data Sets

TBD

10.5. Test Cases

10.5.1. Conformance point: I_QUERY_SERVICE.execute_stored_query()

10.5.1.1. TC aaaa

TBD

10.5.1.2. TC bbbb

TBD

10.5.2. Conformance point: I_QUERY_SERVICE.execute_ad_hoc_query()

10.5.2.1. TC aaaa

TBD

10.5.2.2. TC bbbb

TBD

10.5.3. Conformance point: I_QUERY_SERVICE.execute_stored_query()

10.5.3.1. TC aaaa

TBD

10.5.3.2. TC bbbb

TBD

10.5.4. Conformance point: I_QUERY_SERVICE.execute_stored_query()

10.5.4.1. TC aaaa

TBD

10.5.4.2. TC bbbb

TBD

11. Functional Conformance: Admin Component

11.1. Normative Reference

Items in this validation suite conceptually use the following abstract interfaces from the Abstract Platform Service Model, ADMIN component.

  • I_ADMIN_SERVICE

  • I_ADMIN_DUMP_LOAD

  • I_ADMIN_ARCHIVE

These are concretely realised in implementation technology specfic APIs, such as the {openehr_admin_rest_api}[ADMIN REST API^].

The data that flow through these interfaces are defined by the following information model specifications:

11.2. Dependencies

TBD

11.3. Test Environment

TBD

11.4. Test Data Sets

TBD

11.5. Test Cases

11.5.1. Conformance point: I_ADMIN_SERVICE.list_contributions()

Platform service ref: I_ADMIN_SERVICE.list_contributions()

11.5.1.1. TC aaaa

TBD

11.5.1.2. TC bbbb

TBD

11.5.2. Conformance point: I_ADMIN_SERVICE.contribution_count()

Platform service ref: I_ADMIN_SERVICE.contribution_count()

11.5.2.1. TC aaaa

TBD

11.5.2.2. TC bbbb

TBD

11.5.3. Conformance point: I_ADMIN_SERVICE.versioned_composition_count()

11.5.3.1. TC aaaa

TBD

11.5.3.2. TC bbbb

TBD

11.5.4. Conformance point: I_ADMIN_SERVICE.composition_version_count()

11.5.4.1. TC aaaa

TBD

11.5.4.2. TC bbbb

TBD

11.5.5. Conformance point: I_ADMIN_SERVICE.physical_ehr_delete()

11.5.5.1. TC aaaa

TBD

11.5.5.2. TC bbbb

TBD

11.5.6. Conformance point: I_ADMIN_SERVICE.physical_party_delete()

11.5.6.1. TC aaaa

TBD

11.5.6.2. TC bbbb

TBD

11.5.7. Conformance point: I_ADMIN_DUMP_LOAD.export_ehrs()

Platform service ref: I_ADMIN_DUMP_LOAD.export_ehrs()

11.5.7.1. TC aaaa

TBD

11.5.7.2. TC bbbb

TBD

11.5.8. Conformance point: I_ADMIN_ARCHIVE.archive_ehrs()

Platform service ref: I_ADMIN_ARCHIVE.archive_ehrs()

11.5.8.1. TC aaaa

TBD

11.5.8.2. TC bbbb

TBD

11.5.9. Conformance point: I_ADMIN_ARCHIVE.archive_parties()

Platform service ref: I_ADMIN_ARCHIVE.archive_parties()

11.5.9.1. TC aaaa

TBD

11.5.9.2. TC bbbb

TBD

12. Functional Conformance: Messaging Component

12.1. Normative Reference

Items in this validation suite conceptually use the following abstract interfaces from the Abstract Platform Service Model, MESSAGE component.

  • I_EHR_EXTRACT

  • I_TDD

These are concretely realised in implementation technology specfic APIs, such as the {openehr_message_rest_api}[MESSAGE REST API^].

The data that flow through these interfaces are defined by the following information model specifications:

12.2. Dependencies

TBD

12.3. Test Environment

TBD

12.4. Test Data Sets

TBD

12.5. Test Cases

12.5.1. Conformance point: I_EHR_EXTRACT.export_ehr()

Platform service ref: I_EHR_EXTRACT.export_ehr()

12.5.1.1. TC aaaa

TBD

12.5.1.2. TC bbbb

TBD

12.5.2. Conformance point: I_EHR_EXTRACT.export_ehr_extract()

Platform service ref: I_EHR_EXTRACT.export_ehr_extract()

12.5.2.1. TC aaaa

TBD

12.5.2.2. TC bbbb

TBD

12.5.3. Conformance point: I_EHR_EXTRACT.export_ehr()

Platform service ref: I_EHR_EXTRACT.export_ehr()

12.5.3.1. TC aaaa

TBD

12.5.3.2. TC bbbb

TBD

12.5.4. Conformance point: I_EHR_EXTRACT.export_ehrs()

Platform service ref: I_EHR_EXTRACT.export_ehrs()

12.5.4.1. TC aaaa

TBD

12.5.4.2. TC bbbb

TBD

12.5.5. Conformance point: I_EHR_EXTRACT.export_ehr_extracts()

Platform service ref: I_EHR_EXTRACT.export_ehr_extracts()

12.5.5.1. TC aaaa

TBD

12.5.5.2. TC bbbb

TBD

12.5.6. Conformance point: I_TDD.import_tdd()

Platform service ref: I_TDD.import_tdd()

12.5.6.1. TC aaaa

TBD

12.5.6.2. TC bbbb

TBD

12.5.7. Conformance point: I_TDD.import_tdds()

Platform service ref: I_TDD.import_tdds()

12.5.7.1. TC aaaa

TBD

12.5.7.2. TC bbbb

TBD

13. Content Conformance

13.1. Overview

The test cases defined here are for creating archetypes expressing specific constraints over data defined by the openEHR RM. Different data instances should be generated in order to test the constraints. It’s recommended to have at least one success case, one failure case and all border cases covered. That is, for each archetype constraint specified, at least three data instances should be created.

Since there are many combinations of constraints possible in archetypes and templates, we separate them into different classes and focus on each constraint set class independently from the other sets. The sets are defined by:

  1. A top-level LOCATABLE class: COMPOSITION, EHR_STATUS, FOLDER, PARTY.

  2. Constraint sets on top-level attributes for each class.

  3. Internal LOCATABLE class: SECTION, ENTRY, HISTORY, ITEM_STRUCTURE, ITEM, DATA_VALUE.

  4. Constraint sets on internal structures and attributes (at any level in the RM hierarchy in the internal LOCATABLE class).

In this section, the following terms are used:

  • Archetypable class: any class that extends LOCATABLE.

  • Archetypable field: generic fields on archetypable classes that can be constrained in archetypes.

For testing a 'multiple attribute' cardinality, we use this set of cardinality intervals:

  • 0..*

  • 1..*

  • 3..*

  • 0..1

  • 1..1

  • 3..5

13.1.1. Implementation notes

The constraint combinations described in the cases below could be implemented in different archetypes, or in a generic archetype then defining the specific constraints at the template level. Which option to use might depend on the modeling tools used to create archetypes and templates.

We suggest to automate the archetype/template test cases generation instead of creating each constraint combination manualy.

When there is no constraint defined for an attribute, it means anything is allowed on that attribute. It is recommended to include data not defined by the archetype, but valid in the RM, when generating the data instances.

13.2. Top-level LOCATABLE class: COMPOSITION

These cases are defined to verify the constraints defined over archetypable attributes of the top-level class COMPOSITION specified in the openEHR RM, COMPOSITION package.

The constraints combinations described below could be tested in two ways:

  1. Isolation: by not constraining the COMPOSITION.content at all, or adding an open/‘any allowed’ constraint \{*} at the COMPOSITION.content in the archetype/template. This means anything, even nothing, is accepted at the COMPOSITION.content at runtime.

  2. Combination: with constraints set for COMPOSITION.content, for any CONTENT_ITEM (SECTION or ENTRY). Below there is a specification of the constraint combinations for each class accepted at COMPOSITION.content

Note
we suggest to test with both strategies.

13.2.1. TC CONT-COMP-content_card_any-context_any

Description: COMPOSITION content cardinality 0..*, no constraint over context

COMPOSITION data sets:

  1. COMPOSITION with no entries (border case, success)

  2. COMPOSITION with one entry (success)

  3. COMPOSITION with 3 entries (success)

Combine those cases with:

  1. COMPOSITION with no context

  2. COMPOSITION with context but no other_context

  3. COMPOSITION with context and other_context

All the context structures should be valid.

content context expected constraints violated

no entries

no context

accepted

one entry

no context

accepted

three entries

no context

accepted

no entries

context without other_context

accepted

one entry

context without other_context

accepted

three entries

context without other_context

accepted

no entries

context with other_context

accepted

one entry

context with other_context

accepted

three entries

context with other_context

accepted

13.2.2. TC CONT-COMP-content_card_1plus-context_any

Description: COMPOSITION content cardinality 1..*, no constraint over context

COMPOSITION data sets:

  1. COMPOSITION with no entries (border case, fail)

  2. COMPOSITION with one entry (border case, success)

  3. COMPOSITION with 3 entries (success)

Combine those cases with:

  1. COMPOSITION with no context

  2. COMPOSITION with context but no other_context

  3. COMPOSITION with context and other_context

All the context structures should be valid.

content context expected constraints violated

no entries

no context

rejected

COMPOSITION.content: cardinality.lower

one entry

no context

accepted

three entries

no context

accepted

no entries

context without other_context

rejected

COMPOSITION.content: cardinality.lower

one entry

context without other_context

accepted

three entries

context without other_context

accepted

no entries

context with other_context

rejected

COMPOSITION.content: cardinality.lower

one entry

context with other_context

accepted

three entries

context with other_context

accepted

13.2.3. TC CONT-COMP-content_card_3plus-context_any

Description: COMPOSITION content cardinality 3..*, no constraint over context

COMPOSITION data sets:

  1. COMPOSITION with no entries (border case, fail)

  2. COMPOSITION with one entry (fail)

  3. COMPOSITION with 3 entries (border case, success)

Combine those cases with:

  1. COMPOSITION with no context

  2. COMPOSITION with context but no other_context

  3. COMPOSITION with context and other_context

All the context structures should be valid.

content context expected constraints violated

no entries

no context

rejected

COMPOSITION.content: cardinality.lower

one entry

no context

rejected

COMPOSITION.content: cardinality.lower

three entries

no context

accepted

no entries

context without other_context

rejected

COMPOSITION.content: cardinality.lower

one entry

context without other_context

rejected

COMPOSITION.content: cardinality.lower

three entries

context without other_context

accepted

no entries

context with other_context

rejected

COMPOSITION.content: cardinality.lower

one entry

context with other_context

rejected

COMPOSITION.content: cardinality.lower

three entries

context with other_context

accepted

13.2.4. TC CONT-COMP-content_card_opt-context_any

Description: COMPOSITION content cardinality 0..1, no constraint over context

COMPOSITION data sets:

  1. COMPOSITION with no entries (border case, success)

  2. COMPOSITION with one entry (border case, success)

  3. COMPOSITION with 3 entries (fail)

Combine those cases with:

  1. COMPOSITION with no context

  2. COMPOSITION with context but no other_context

  3. COMPOSITION with context and other_context

All the context structures should be valid.

content context expected constraints violated

no entries

no context

accepted

one entry

no context

accepted

three entries

no context

rejected

COMPOSITION.content: cardinality.upper

no entries

context without other_context

accepted

one entry

context without other_context

accepted

three entries

context without other_context

rejected

COMPOSITION.content: cardinality.upper

no entries

context with other_context

accepted

one entry

context with other_context

accepted

three entries

context with other_context

rejected

COMPOSITION.content: cardinality.upper

13.2.5. TC CONT-COMP-content_card_mand-context_any

Description: COMPOSITION content cardinality 1..1, no constraint over context

COMPOSITION data sets:

  1. COMPOSITION with no entries (border case, fail)

  2. COMPOSITION with one entry (border case, success)

  3. COMPOSITION with 3 entries (fail)

Combine those cases with:

  1. COMPOSITION with no context

  2. COMPOSITION with context but no other_context

  3. COMPOSITION with context and other_context

All the context structures should be valid.

content context expected constraints violated

no entries

no context

rejected

COMPOSITION.content: cardinality.lower

one entry

no context

accepted

three entries

no context

rejected

COMPOSITION.content: cardinality.upper

no entries

context without other_context

rejected

COMPOSITION.content: cardinality.lower

one entry

context without other_context

accepted

three entries

context without other_context

rejected

COMPOSITION.content: cardinality.upper

no entries

context with other_context

rejected

COMPOSITION.content: cardinality.lower

one entry

context with other_context

accepted

three entries

context with other_context

rejected

COMPOSITION.content: cardinality.upper

13.2.6. TC CONT-COMP-content_card_3to5-context_any

Description: COMPOSITION content cardinality 3..5, no constraint over context

COMPOSITION data sets:

  1. COMPOSITION with no entries (fail)

  2. COMPOSITION with one entry (fail)

  3. COMPOSITION with 3 entries (border case, success)

Combine those cases with:

  1. COMPOSITION with no context

  2. COMPOSITION with context but no other_context

  3. COMPOSITION with context and other_context

All the context structures should be valid.

content context expected constraints violated

no entries

no context

rejected

COMPOSITION.content: cardinality.lower

one entry

no context

rejected

COMPOSITION.content: cardinality.lower

three entries

no context

accepted

no entries

context without other_context

rejected

COMPOSITION.content: cardinality.lower

one entry

context without other_context

rejected

COMPOSITION.content: cardinality.lower

three entries

context without other_context

accepted

no entries

context with other_context

rejected

COMPOSITION.content: cardinality.lower

one entry

context with other_context

rejected

COMPOSITION.content: cardinality.lower

three entries

context with other_context

accepted

13.2.7. TC CONT-COMP-content_card_any-context_mand

Description: COMPOSITION content cardinality 0..*, context occurrences 1..1

COMPOSITION data sets:

  1. COMPOSITION with no entries (border case, success)

  2. COMPOSITION with one entry (success)

  3. COMPOSITION with 3 entries (success)

Combine those cases with:

  1. COMPOSITION with no context

  2. COMPOSITION with context but no other_context

  3. COMPOSITION with context and other_context

All the context structures should be valid.

content context expected constraints violated

no entries

no context

rejected

COMPOSITION.context occurrences.lower

one entry

no context

rejected

COMPOSITION.context occurrences.lower

three entries

no context

rejected

COMPOSITION.context occurrences.lower

no entries

context without other_context

accepted

one entry

context without other_context

accepted

three entries

context without other_context

accepted

no entries

context with other_context

accepted

one entry

context with other_context

accepted

three entries

context with other_context

accepted

13.2.8. TC CONT-COMP-content_card_1plus-context_mand

Description: COMPOSITION content cardinality 1..*, context occurrences 1..1

COMPOSITION data sets:

  1. COMPOSITION with no entries (border case, fail)

  2. COMPOSITION with one entry (border case, success)

  3. COMPOSITION with 3 entries (success)

Combine those cases with:

  1. COMPOSITION with no context

  2. COMPOSITION with context but no other_context

  3. COMPOSITION with context and other_context

All the context structures should be valid.

content context expected constraints violated

no entries

no context

rejected

COMPOSITION.content: cardinality.lower, COMPOSITION.context occurrences.lower

one entry

no context

rejected

COMPOSITION.context occurrences.lower

three entries

no context

rejected

COMPOSITION.context occurrences.lower

no entries

context without other_context

rejected

COMPOSITION.content: cardinality.lower

one entry

context without other_context

accepted

three entries

context without other_context

accepted

no entries

context with other_context

rejected

COMPOSITION.content: cardinality.lower

one entry

context with other_context

accepted

three entries

context with other_context

accepted

13.2.9. TC CONT-COMP-content_card_3plus-context_mand

Description: COMPOSITION content cardinality 3..*, context occurrences 1..1

COMPOSITION data sets:

  1. COMPOSITION with no entries (border case, fail)

  2. COMPOSITION with one entry (fail)

  3. COMPOSITION with 3 entries (border case, success)

Combine those cases with:

  1. COMPOSITION with no context

  2. COMPOSITION with context but no other_context

  3. COMPOSITION with context and other_context

All the context structures should be valid.

content context expected constraints violated

no entries

no context

rejected

COMPOSITION.content: cardinality.lower, COMPOSITION.context occurrences.lower

one entry

no context

rejected

COMPOSITION.content: cardinality.lower, COMPOSITION.context occurrences.lower

three entries

no context

rejected

COMPOSITION.context occurrences.lower

no entries

context without other_context

rejected

COMPOSITION.content: cardinality.lower

one entry

context without other_context

rejected

COMPOSITION.content: cardinality.lower

three entries

context without other_context

accepted

no entries

context with other_context

rejected

COMPOSITION.content: cardinality.lower

one entry

context with other_context

rejected

COMPOSITION.content: cardinality.lower

three entries

context with other_context

accepted

13.2.10. TC CONT-COMP-content_card_opt-context_mand

Description: COMPOSITION content cardinality 0..1, context occurrences 1..1

COMPOSITION data sets:

  1. COMPOSITION with no entries (border case, success)

  2. COMPOSITION with one entry (border case, success)

  3. COMPOSITION with 3 entries (fail)

Combine those cases with:

  1. COMPOSITION with no context

  2. COMPOSITION with context but no other_context

  3. COMPOSITION with context and other_context

All the context structures should be valid.

content context expected constraints violated

no entries

no context

rejected

COMPOSITION.context occurrences.lower

one entry

no context

rejected

COMPOSITION.context occurrences.lower

three entries

no context

rejected

COMPOSITION.content: cardinality.upper, COMPOSITION.context occurrences.lower

no entries

context without other_context

accepted

one entry

context without other_context

accepted

three entries

context without other_context

rejected

COMPOSITION.content: cardinality.upper

no entries

context with other_context

accepted

one entry

context with other_context

accepted

three entries

context with other_context

rejected

COMPOSITION.content: cardinality.upper

13.2.11. TC CONT-COMP-content_card_mand-context_mand

Description: COMPOSITION content cardinality 1..1, context occurrences 1..1

COMPOSITION data sets:

  1. COMPOSITION with no entries (border case, fail)

  2. COMPOSITION with one entry (border case, success)

  3. COMPOSITION with 3 entries (fail)

Combine those cases with:

  1. COMPOSITION with no context

  2. COMPOSITION with context but no other_context

  3. COMPOSITION with context and other_context

All the context structures should be valid.

content context expected constraints violated

no entries

no context

rejected

COMPOSITION.content: cardinality.lower, COMPOSITION.context occurrences.lower

one entry

no context

rejected

COMPOSITION.context occurrences.lower

three entries

no context

rejected

COMPOSITION.content: cardinality.upper, COMPOSITION.context occurrences.lower

no entries

context without other_context

rejected

COMPOSITION.content: cardinality.lower

one entry

context without other_context

accepted

three entries

context without other_context

rejected

COMPOSITION.content: cardinality.upper

no entries

context with other_context

rejected

COMPOSITION.content: cardinality.lower

one entry

context with other_context

accepted

three entries

context with other_context

rejected

COMPOSITION.content: cardinality.upper

13.2.12. TC CONT-COMP-content_card_3to5-context_mand

Description: COMPOSITION content cardinality 3..5, context occurrences 1..1

COMPOSITION data sets:

  1. COMPOSITION with no entries (fail)

  2. COMPOSITION with one entry (fail)

  3. COMPOSITION with 3 entries (border case, success)

Combine those cases with:

  1. COMPOSITION with no context

  2. COMPOSITION with context but no other_context

  3. COMPOSITION with context and other_context

All the context structures should be valid.

content context expected constraints violated

no entries

no context

rejected

COMPOSITION.content: cardinality.lower, COMPOSITION.context occurrences.lower

one entry

no context

rejected

COMPOSITION.content: cardinality.lower, COMPOSITION.context occurrences.lower

three entries

no context

rejected

COMPOSITION.context occurrences.lower

no entries

context without other_context

rejected

COMPOSITION.content: cardinality.lower

one entry

context without other_context

rejected

COMPOSITION.content: cardinality.lower

three entries

context without other_context

accepted

no entries

context with other_context

rejected

COMPOSITION.content: cardinality.lower

one entry

context with other_context

rejected

COMPOSITION.content: cardinality.lower

three entries

context with other_context

accepted

13.3. Internal LOCATABLE class: OBSERVATION

In this section there are specifications of constraint combinations for OBSERVATION.

Each data set in this section could be combined with the test data sets for COMPOSITION.content defined in section 2.

OBSERVATION data sets:

  1. OBSERVATION with no state and no protocol

  2. OBSERVATION with no state and protocol

  3. OBSERVATION with state and no protocol

  4. OBSERVATION with state and protocol

Note
since data is mandatory by the RM we can’t have a case for an AOM constraint with no OBSERVATION data. Though any OBSERVATION committed to the SUT without data will return a validation error comming from the RM/Schema, and this should be tested.

The constraints combinations described below could be tested in two ways:

  1. Isolation: by not constraining OBSERVATION.data, OBSERVATION.state and OBSERVATION.protocol, or using the open/'any allowed' constraint \{*} for those attributes.

  2. Combination: with constraints defined at the HISTORY level (for data and state) and ITEM_STRUCTURE (for protocol).

Note
we suggest to test with both strategies.

13.3.1. TC CONT-OBS-state_ex_opt-protocol_ex_opt

Description: OBSERVATION state existence = 0..1, protocol existence = 0..1

data state protocol expected constraints violated

absent

absent

absent

rejected

OBSERVATION.data existence.lower (RM/schema constraint)

absent

absent

present

rejected

OBSERVATION.data existence.lower (RM/schema constraint)

absent

present

absent

rejected

OBSERVATION.data existence.lower (RM/schema constraint)

absent

present

present

rejected

OBSERVATION.data existence.lower (RM/schema constraint)

present

absent

absent

accepted

present

absent

present

accepted

present

present

absent

accepted

present

present

present

accepted

13.3.2. TC CONT-OBS-state_ex_opt-protocol_ex_mand

Description: OBSERVATION state existence = 0..1, protocol existence = 1..1

data state protocol expected constraints violated

absent

absent

absent

rejected

OBSERVATION.data existence.lower (RM/schema constraint), OBSERVATION.protocol existence.lower

absent

absent

present

rejected

OBSERVATION.data existence.lower (RM/schema constraint)

absent

present

absent

rejected

OBSERVATION.data existence.lower (RM/schema constraint), OBSERVATION.protocol existence.lower

absent

present

present

rejected

OBSERVATION.data existence.lower (RM/schema constraint)

present

absent

absent

rejected

OBSERVATION.protocol existence.lower

present

absent

present

accepted

present

present

absent

rejected

OBSERVATION.protocol existence.lower

present

present

present

accepted

13.3.3. TC CONT-OBS-state_ex_mand-protocol_ex_opt

Description: OBSERVATION state existence = 1..1, protocol existence = 0..1

data state protocol expected constraints violated

absent

absent

absent

rejected

OBSERVATION.data existence.lower (RM/schema constraint), OBSERVATION.state existence.lower

absent

absent

present

rejected

OBSERVATION.data existence.lower (RM/schema constraint), OBSERVATION.state existence.lower

absent

present

absent

rejected

OBSERVATION.data existence.lower (RM/schema constraint)

absent

present

present

rejected

OBSERVATION.data existence.lower (RM/schema constraint)

present

absent

absent

rejected

OBSERVATION.state existence.lower

present

absent

present

rejected

OBSERVATION.state existence.lower

present

present

absent

accepted

present

present

present

accepted

13.3.4. TC CONT-OBS-state_ex_mand-protocol_ex_mand

Description: OBSERVATION state existence = 1..1, protocol existence = 1..1

data state protocol expected constraints violated

absent

absent

absent

rejected

OBSERVATION.data existence.lower (RM/schema constraint), OBSERVATION.protocol existence.lower, OBSERVATION.state existence.lower

absent

absent

present

rejected

OBSERVATION.data existence.lower (RM/schema constraint), OBSERVATION.state existence.lower

absent

present

absent

rejected

OBSERVATION.data existence.lower (RM/schema constraint), OBSERVATION.protocol existence.lower

absent

present

present

rejected

OBSERVATION.data existence.lower (RM/schema constraint)

present

absent

absent

rejected

OBSERVATION.protocol existence.lower, OBSERVATION.state existence.lower

present

absent

present

rejected

OBSERVATION.state existence.lower

present

present

absent

rejected

OBSERVATION.protocol existence.lower

present

present

present

accepted

13.4. Internal LOCATABLE class: HISTORY

In this section there are specifications of constraint combinations for HISTORY, specified in the openEHR Data Structures IM.

Each data set in this section could be combined with the test data sets for HISTORY defined in section 3.

HISTORY data sets:

  1. HISTORY with no events and no summary

  2. HISTORY with events and no summary

  3. HISTORY with no events and summary

  4. HISTORY with events and summary

The constraints combinations described below could be tested in two ways:

  1. Isolation: by not constraining HISTORY.events and HISTORY.summary, or using the open/'any allowed' constraint \{*} for those attributes.

  2. Combination: with constraints defined at the EVENT level (for events) and ITEM_STRUCTURE (for summary).

Note
we suggest to test with both strategies.

13.4.1. TC CONT-HIST-events_card_any-summary_ex_opt

Description: HISTORY events cardinality 0..*, summary existence 0..1

events summary expected constraints violated

no events

absent

accepted

one event

absent

accepted

three events

absent

accepted

no event

present

accepted

one event

present

accepted

three events

present

accepted

13.4.2. TC CONT-HIST-events_card_1plus-summary_ex_opt

Description: HISTORY events cardinality 1..*, summary existence 0..1

events summary expected constraints violated

no events

absent

rejected

HISTORY.events cardinality.lower

one event

absent

accepted

three events

absent

accepted

no event

present

rejected

HISTORY.events cardinality.lower

one event

present

accepted

three events

present

accepted

13.4.3. TC CONT-HIST-events_card_3plus-summary_ex_opt

Description: HISTORY events cardinality 3..*, summary existence 0..1

events summary expected constraints violated

no events

absent

rejected

HISTORY.events cardinality.lower

one event

absent

rejected

HISTORY.events cardinality.lower

three events

absent

accepted

no event

present

rejected

HISTORY.events cardinality.lower

one event

present

rejected

HISTORY.events cardinality.lower

three events

present

accepted

13.4.4. TC CONT-HIST-events_card_opt-summary_ex_opt

Description: HISTORY events cardinality 0..1, summary existence 0..1

events summary expected constraints violated

no events

absent

accepted

one event

absent

accepted

three events

absent

rejected

HISTORY.events cardinality.upper

no event

present

accepted

one event

present

accepted

three events

present

rejected

HISTORY.events cardinality.upper

13.4.5. TC CONT-HIST-events_card_mand-summary_ex_opt

Description: HISTORY events cardinality 1..1, summary existence 0..1

events summary expected constraints violated

no events

absent

rejected

HISTORY.events cardinality.lower

one event

absent

accepted

three events

absent

rejected

HISTORY.events cardinality.upper

no event

present

rejected

HISTORY.events cardinality.lower

one event

present

accepted

three events

present

rejected

HISTORY.events cardinality.upper

13.4.6. TC CONT-HIST-events_card_3to5-summary_ex_opt

Description: HISTORY events cardinality 3..5, summary existence 0..1

events summary expected constraints violated

no events

absent

rejected

HISTORY.events cardinality.lower

one event

absent

rejected

HISTORY.events cardinality.lower

three events

absent

accepted

no event

present

rejected

HISTORY.events cardinality.lower

one event

present

rejected

HISTORY.events cardinality.lower

three events

present

accepted

13.4.7. TC CONT-HIST-events_card_any-summary_ex_mand

Description: HISTORY events cardinality 0..*, summary existence 1..1

events summary expected constraints violated

no events

absent

rejected

HISTORY.summary existence.lower

one event

absent

rejected

HISTORY.summary existence.lower

three events

absent

rejected

HISTORY.summary existence.lower

no event

present

accepted

one event

present

accepted

three events

present

accepted

13.4.8. TC CONT-HIST-events_card_1plus-summary_ex_mand

Description: HISTORY events cardinality 1..*, summary existence 1..1

events summary expected constraints violated

no events

absent

rejected

HISTORY.events cardinality.lower, HISTORY.summary existence.lower

one event

absent

rejected

HISTORY.summary existence.lower

three events

absent

rejected

HISTORY.summary existence.lower

no event

present

rejected

HISTORY.events cardinality.lower

one event

present

accepted

three events

present

accepted

13.4.9. TC CONT-HIST-events_card_3plus-summary_ex_mand

Description: HISTORY events cardinality 3..*, summary existence 1..1

events summary expected constraints violated

no events

absent

rejected

HISTORY.events cardinality.lower, HISTORY.summary existence.lower

one event

absent

rejected

HISTORY.events cardinality.lower, HISTORY.summary existence.lower

three events

absent

rejected

HISTORY.summary existence.lower

no event

present

rejected

HISTORY.events cardinality.lower

one event

present

rejected

HISTORY.events cardinality.lower

three events

present

accepted

13.4.10. TC CONT-HIST-events_card_opt-summary_ex_mand

Description: HISTORY events cardinality 0..1, summary existence 1..1

events summary expected constraints violated

no events

absent

rejected

HISTORY.summary existence.lower

one event

absent

rejected

HISTORY.summary existence.lower

three events

absent

rejected

HISTORY.events cardinality.upper, HISTORY.summary existence.lower

no event

present

accepted

one event

present

accepted

three events

present

rejected

HISTORY.events cardinality.upper

13.4.11. TC CONT-HIST-events_card_mand-summary_ex_mand

Description: HISTORY events cardinality 1..1, summary existence 1..1

events summary expected constraints violated

no events

absent

rejected

HISTORY.events cardinality.lower, HISTORY.summary existence.lower

one event

absent

rejected

HISTORY.summary existence.lower

three events

absent

rejected

HISTORY.events cardinality.upper, HISTORY.summary existence.lower

no event

present

rejected

HISTORY.events cardinality.lower

one event

present

accepted

three events

present

rejected

HISTORY.events cardinality.upper

13.4.12. TC CONT-HIST-events_card_3to5-summary_ex_mand

Description: HISTORY events cardinality 3..5, summary existence 1..1

events summary expected constraints violated

no events

absent

rejected

HISTORY.events cardinality.lower, HISTORY.summary existence.lower

one event

absent

rejected

HISTORY.events cardinality.lower, HISTORY.summary existence.lower

three events

absent

rejected

HISTORY.summary existence.lower

no event

present

rejected

HISTORY.events cardinality.lower

one event

present

rejected

HISTORY.events cardinality.lower

three events

present

accepted

13.5. EVENT data sets and test cases

EVENT data sets:

  1. EVENT with no state

  2. EVENT with state

Note
since data is mandatory by the RM we can’t have a case for an AOM constraint with “no EVENT.data”. Though any EVENT committed to the SUT without data will return a validation error comming from the RM/Schema, and this should be tested.

EVENT type combinations:

  1. EVENT is POINT_EVENT

  2. EVENT is INTERVAL_EVENT

Note
testing both EVENT subclasses shouldn’t affect the result of testing combinations with the rest of the constraints defined for EVENT or on container classes. It will affect only the type checking test if the wrong type of EVENT is provided. So instead of combining the expected results with the rest of the constraints, we will define separate test cases.

The constraints combinations described below could be tested in two ways:

  1. Isolation: by not constraining EVENT.data and EVENT.state, or using the open/‘any allowed’ constraint \{*} for those attributes.

  2. Combination: with constraints defined at the ITEM_STRUCTURE level (for data and state).

Note
we suggest to test with both strategies.

13.5.1. TC CONT-EVENT-state_ex_opt

Description: EVENT state existence 0..1

data state expected constraints violated

absent

absent

rejected

EVENT.data existence.lower (RM/schema constraint)

absent

present

rejected

EVENT.data existence.lower (RM/schema constraint)

present

absent

accepted

present

present

accepted

13.5.2. TC CONT-EVENT-state_ex_mand

Description: EVENT state existence 1..1

data state expected constraints violated

absent

absent

rejected

EVENT.data existence.lower (RM/schema constraint), EVENT.state existence.lower

absent

present

rejected

EVENT.data existence.lower (RM/schema constraint)

present

absent

rejected

EVENT.state existence.lower

present

present

accepted

13.5.3. TC CONT-EVENT-type_any

Description: EVENT is any EVENT subtype

In the AOM/TOM the constraint for the EVENT type is using the abstract class EVENT, so it allows any EVENT subclass at this position at runtime.

event expected constraints violated

POINT_EVENT

accepted

INTERVAL_EVENT

accepted

13.5.4. TC CONT-EVENT-type_point_event

Description: EVENT is POINT_EVENT

event expected constraints violated

POINT_EVENT

accepted

INTERVAL_EVENT

rejected

Class not allowed

13.5.5. TC CONT-EVENT-type_interval_event

Description: EVENT is INTERVAL_EVENT

event expected constraints violated

POINT_EVENT

rejected

Class not allowed

INTERVAL_EVENT

accepted

13.6. ITEM_STRUCTURE data sets and test cases

ITEM_STRUCTURE type combinations:

  1. ITEM_STRUCTURE is ITEM_TREE

  2. ITEM_STRUCTURE is ITEM_LIST

  3. ITEM_STRUCTURE is ITEM_TABLE

  4. ITEM_STRUCTURE is ITEM_SINGLE

Note
testing with any of the ITEM_STRUCTURE subclasses shouldn’t affect the result of testing combinations with the rest of the constraints defined on container classes. It will affect only the type checking test if the wrong type of ITEM_STRUCTURE is provided. So instead of combining the expected results with the rest of the constraints, we will define separate test cases.

13.6.1. TC CONT-ITEM_STR-type_any

Description: ITEM_STRUCTURE is any ITEM_STRUCTURE subtype

In the AOM/TOM the constraint for the ITEM_STRUCTURE type is using the abstract class ITEM_STRUCTURE, so it allows any ITEM_STRUCTURE subclass at this position at runtime.

event expected constraints violated

ITEM_TREE

accepted

ITEM_LIST

accepted

ITEM_TABLE

accepted

ITEM_SINGLE

accepted

13.6.2. TC CONT-ITEM_STR-type_item_tree

Description: ITEM_STRUCTURE is ITEM_TREE

event expected constraints violated

ITEM_TREE

accepted

ITEM_LIST

rejected

Class not allowed

ITEM_TABLE

rejected

Class not allowed

ITEM_SINGLE

rejected

Class not allowed

13.6.3. TC CONT-ITEM_STR-type_item_list

Description: ITEM_STRUCTURE is ITEM_LIST

event expected constraints violated

ITEM_TREE

rejected

Class not allowed

ITEM_LIST

accepted

ITEM_TABLE

rejected

Class not allowed

ITEM_SINGLE

rejected

Class not allowed

13.6.4. TC CONT-ITEM_STR-type_item_table

Description: ITEM_STRUCTURE is ITEM_TABLE

event expected constraints violated

ITEM_TREE

rejected

Class not allowed

ITEM_LIST

rejected

Class not allowed

ITEM_TABLE

accepted

ITEM_SINGLE

rejected

Class not allowed

13.6.5. TC CONT-ITEM_STR-type_item_single

Description: ITEM_STRUCTURE is ITEM_SINGLE

event expected constraints violated

ITEM_TREE

rejected

Class not allowed

ITEM_LIST

rejected

Class not allowed

ITEM_TABLE

rejected

Class not allowed

ITEM_SINGLE

accepted

14. Non-Functional Conformance - Privacy

14.1. Normative Reference

Items in this validation suite rely on the following specifications.

14.2. Dependencies

TBD

14.3. Test Environment

TBD

14.4. Test Data Sets

TBD

14.5. Test Cases

14.5.1. Conformance point: I_EHR_COMPOSITION.create_composition()

14.5.1.1. TC aaaa

TBD

14.5.1.2. TC bbbb

TBD