openEHR Platform Conformance Test Schedule
| Issuer: openEHR Specification Program | |
|---|---|
| Release: CNF development | Status: DEVELOPMENT | 
| Revision: [latest_issue] | Date: [latest_issue_date] | 
| Keywords: conformance, test | |
| © 2017 - 2024 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 | 
 | 
| Support | Issues: Problem Reports | 
Acknowledgements
This specification was developed and is maintained by the openEHR Specifications Editorial Committee (SEC).
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. 
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/development/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 | 
| 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 | 
|---|---|---|
| API 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 | 
| Data Validation conformance | Conformance of platform’s validation of data against semantic models (archetypes etc) | Regression of test client committing variable data sets against reference validity | 
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.
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. API Conformance Test Design
API conformance is assessed by running tests on the SUT API, and determining deviations from expected results. 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 operations. Each such operation is a testable capability of a system that relates to a business function. For example, SM operations for an EHR service include create_EHR, update_EHR, and so on. For any such operation, there may be multiple test cases, each of which is individually identified. For each test case, there may be multiple data sets. A 'test' is therefore the execution of a particular test case with a particular data set.
Each test case is documented in the form shown in the following sub-section.
3.2.1. Test Case <SERVICE_COMPONENT>.<operation>-<test-specific id>
| 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 SUT should be stated in the Conformance Statement, because this will determine some variations on the data sets used for testing. The minimum required version is RM 1.0.2. | 
3.3. Data Validation Conformance Test Design
Data validation conformance is defined in terms of test cases with multiple data sets. These test cases are documented in the same basic way as described above, along with multiple data sets, typically shown in tabulated form. They are described in Section 14.
4. Test Suite: DEFINITION Service / I_DEFINITION_ADL2 and I_DEFINITION_ADL14 Interfaces
4.1. Normative Reference
Items under this validation suite conceptually use these abstract interfaces defined in the openEHR Platform Service Model:
These are concretely realised in implementation technology specfic APIs, such as the Definitions REST API.
This test suite uses artefacts defined by the following specifications:
TODO: add ref to dependency diagram in SM/Platform service model.
4.2. Test Environment
The server under test should support:
- 
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; 
- 
validation of OPTs and archetypes uploaded to it, or even provide a service to do so before uploading (useful while developing); 
- 
different versions of the same OPTs and archetypes. 
The following should be taken into account when testing any given product:
- 
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. 
- 
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. 
- 
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. Service Model operation: I_DEFINITION_ADL14.validate_opt()
Service Model reference: 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. Test Case 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 | 
 | 
| Test runners | 
| 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. Test Case I_DEFINITION_ADL14.validate_opt-invalid_opt
| Description | Validate invalid 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 | 
 | 
| Test runners | 
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 - 
for each X in data set, run service Y 
- 
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. Service Model operation: I_DEFINITION_ADL14.upload_opt()
Service Model reference: 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. Test Case 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  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 | 
 | 
| Test runners | 
4.3.2.3. Test Case 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 | 
 | 
| Test runners | 
4.3.2.4. Test Case 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_idtwice 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.
See: SPECBASE-30 and SPECITS-42.
| 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  
 | ||
| Flow | 
 | ||
| Test runners | 
4.3.2.5. Test Case 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  
 | ||
| Flow | 
 | ||
| Test runners | 
4.3.3. Service Model operation: I_DEFINITION_ADL14.get_opt()
Service Model reference: 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. Test Case I_DEFINITION_ADL14.get_opt-retrieve_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 | 
 | 
| Test runners | 
4.3.3.3. Test Case 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 | 
 | 
| Test runners | 
4.3.3.4. Test Case 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 | 
 | 
| Test runners | 
4.3.3.5. Test Case 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 | 
 | 
| Test runners | 
4.3.4. Service Model operation: I_DEFINITION_ADL14.get_opts()
Service Model reference: 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. Test Case I_DEFINITION_ADL14.get_opts-retrieve_all
| Description | retrieve all loaded OPTs | 
|---|---|
| Pre-conditions | All valid OPTs should be loaded. | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
4.3.4.3. Test Case 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 | 
 | 
| Test runners | 
4.3.5. Service Model operation: I_DEFINITION_ADL14.delete_opt()
Service Model reference: 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. Test Case 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 | 
 | 
| Test runners | 
4.3.5.3. Test Case 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 | 
 | 
| Test runners | 
4.3.5.4. Test Case 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 | 
 | 
| Test runners | 
4.3.5.5. Test Case 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 | 
 | 
| Test runners | 
5. Test Suite: DEFINITION Service / I_DEFINITION_QUERY Interface
5.1. Normative Reference
Items under this validation suite conceptually use these abstract interfaces defined in the Platform Service Model:
- 
I_DEFINITION_QUERY 
These are concretely realised in implementation technology specfic APIs, such as the Definitions REST API.
This test suite uses artefacts defined by the following specifications:
5.4. Test cases
5.4.1. Service Model operation: I_DEFINITION_QUERY.has_query()
Service Model reference: I_DEFINITION_QUERY.has_query()
5.4.2. Service Model operation: I_DEFINITION_QUERY.valid_query()
Service Model reference: I_DEFINITION_QUERY.valid_query()
5.4.2.1. Test Case I_DEFINITION_QUERY.valid_query-valid
| Description | xx | 
|---|---|
| Pre-conditions | xx | 
| Post-conditions | xx | 
| Flow | xx | 
| Test runners | 
5.4.2.2. Test Case I_DEFINITION_QUERY.valid_query-invalid
| Description | xx | 
|---|---|
| Pre-conditions | xx | 
| Post-conditions | xx | 
| Flow | xx | 
| Test runners | 
5.4.3. Service Model operation: I_DEFINITION_QUERY.list_queries()
Service Model reference: I_DEFINITION_QUERY.list_queries()
5.4.3.1. Test Case I_DEFINITION_QUERY.list_queries-empty
| Description | xx | 
|---|---|
| Pre-conditions | xx | 
| Post-conditions | xx | 
| Flow | xx | 
| Test runners | 
5.4.3.2. Test Case I_DEFINITION_QUERY.list_queries-non_empty
| Description | xx | 
|---|---|
| Pre-conditions | xx | 
| Post-conditions | xx | 
| Flow | xx | 
| Test runners | 
6. Test Suite: EHR_SERVICE
6.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.
This test suite uses artefacts defined by the following information model specifications:
6.2. Test Environment
The server under test should support:
- 
at least the OPT 1.4 format, and optionally OPT 2. 
- 
at least the XML representation of COMPOSITIONs for committing data, which may be validated by the openEHR XSDs. 
6.3. Test Data Sets
These are the data set classes:
- 
VALID: - 
not providing an EHR_STATUS(empty input, the server creates the default structures and data)
- 
providing a valid EHR_STATUS
 
- 
- 
INVALID: - 
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:
- 
missing is_queryable,is_modifiable
- 
empty is_queryable, `_is_modifiable
- 
missing or empty subject_id
- 
invalid subject_id
- 
invalid other_details
Notes:
- 
When the ehr_idis not present, it is expected that it is assigned by the server.
- 
The server should set the EHR.system_idvalue to a known value (defined by the server’s configuration).
- 
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.
- 
There are no cases to check if the provided ehr_idis valid, since in the openEHR Platform Service Model the parameters are typed toUUID, any other format will be an invalid call.
- 
The validity of an EHR_STATUScan be checked in its JSON form by validating against the JSON schemas.
6.4. Test Cases
6.4.1. Service Model operation: I_EHR_SERVICE.has_ehr()
Service Model reference: I_EHR_SERVICE.has_ehr()
6.4.1.1. Test Case 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  | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
6.4.1.2. Test Case I_EHR_SERVICE.has_ehr-existing_subject_id
| Description | Check has EHR with existing EHR by  | 
|---|---|
| Pre-conditions | An EHR should exist in the system with a known subject_id. | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
| Note | subject_idrefers to thePARTY_REFclass instance containing the identifier of a patient represented byPARTY_SELFin the openEHR Reference Model. | 
6.4.1.3. Test Case 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 | 
 | 
| Test runners | 
6.4.1.4. Test Case I_EHR_SERVICE.has_ehr-non_existing_subject_id
| Description | Check has EHR with non existing EHR by  | 
|---|---|
| Pre-conditions | The server should be empty (no EHRs, no commits, no OPTs). | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
6.4.2. Service Model operation: I_EHR_SERVICE.create_ehr()
Service Model reference: I_EHR_SERVICE.create_ehr()
6.4.2.1. Test Case 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 | 
 | 
| Test runners | 
6.4.2.2. Test Case 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 | 
 | 
| Test runners | 
6.4.2.3. Test Case 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 | 
 | 
| Test runners | 
6.4.3. Service Model operation: I_EHR_SERVICE.get_ehr()
Service Model reference: I_EHR_SERVICE.get_ehr()
6.4.3.1. Test Case 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  | 
| Post-conditions | None. | 
| Flow | 
 | 
| Test runners | 
6.4.3.2. Test Case I_EHR_SERVICE.get_ehr-existing_ehr_by_subject_id
| Description | Get existing EHR by  | 
|---|---|
| Pre-conditions | An EHR should exist in the system with a known  | 
| Post-conditions | None. | 
| Flow | 
 | 
| Test runners | 
6.4.3.3. Test Case 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 | 
 | 
| Test runners | 
6.4.3.4. Test Case I_EHR_SERVICE.get_ehr-get_ehr_by_invalid_subject_id
| Description | Get non existing EHR by  | 
|---|---|
| Pre-conditions | The server should be empty (no EHRs, no commits, no OPTs). | 
| Post-conditions | None. | 
| Flow | 
 | 
| Test runners | 
6.5. EHR_STATUS Test Cases
6.5.1. Service Model operation: I_EHR_STATUS.get_ehr_status()
Service Model reference: I_EHR_STATUS.get_ehr_status()
6.5.1.1. Test Case I_EHR_STATUS.get_ehr_status-get_by_ehr_id
| Description | Get status of an existing EHR | 
|---|---|
| Pre-conditions | An EHR with known  | 
| Post-conditions | None. | 
| Flow | 
 | 
| Test runners | 
6.5.1.2. Test Case 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 | 
 | 
| Test runners | 
6.5.2. Service Model operation: I_EHR_STATUS.set_ehr_queryable()
Service Model reference: I_EHR_STATUS.set_ehr_queryable()
6.5.2.1. Test Case I_EHR_STATUS.set_ehr_queryable-existing_ehr
| Description | Set EHR queryable of an existing EHR | 
|---|---|
| Pre-conditions | An EHR with known  | 
| Post-conditions | 
 | 
| Flow | 
 | 
| Test runners | 
6.5.2.2. Test Case 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 | 
 | 
| Test runners | 
6.5.3. Service Model operation: I_EHR_STATUS.set_ehr_modifiable()
Service Model reference: I_EHR_STATUS.set_ehr_modifiable()
6.5.3.1. Test Case I_EHR_STATUS.set_ehr_modifiable-existing_ehr
| Description | Set EHR modifiable of an existing EHR | 
|---|---|
| Pre-conditions | An EHR with known  | 
| Post-conditions | 
 | 
| Flow | 
 | 
| Test runners | 
6.5.3.2. Test Case 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 | 
 | 
| Test runners | 
6.5.4. Service Model operation: I_EHR_STATUS.clear_ehr_queryable()
Service Model reference: I_EHR_STATUS.clear_ehr_queryable()
6.5.4.1. Test Case I_EHR_STATUS.clear_ehr_queryable-existing_ehr
| Description | Clear EHR queryable of an existing EHR | 
|---|---|
| Pre-conditions | An EHR with known  | 
| Post-conditions | 
 | 
| Flow | 
 | 
| Test runners | 
6.5.4.2. Test Case 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 | 
 | 
| Test runners | 
6.5.5. Service Model operation: I_EHR_STATUS.clear_ehr_modifiable()
Service Model reference: I_EHR_STATUS.clear_ehr_modifiable()
6.5.5.1. Test Case I_EHR_STATUS.clear_ehr_modifiable-existing_ehr
| Description | Clear EHR modifiable of an existing EHR | 
|---|---|
| Pre-conditions | An EHR with known  | 
| Post-conditions | 
 | 
| Flow | 
 | 
| Test runners | 
6.5.5.2. Test Case 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 | 
 | 
| Test runners | 
7. Test Suite: EHR_SERVICE / I_COMPOSITION Interface
7.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.
This test suite uses artefacts defined by the following information model specifications:
7.2. Dependencies
This test suite depends on other test suites:
- 
Functional Conformance: Definitions Component, providing OPTs; 
- 
Functional Conformance: EHR Component, providing EHRs. 
7.3. Test Environment
- 
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. 
- 
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). 
7.4. Test Cases
7.4.1. Service Model operation: I_EHR_COMPOSITION.has_composition()
Service Model reference: I_EHR_COMPOSITION.has_composition()
7.4.1.1. Test Case I_EHR_COMPOSITION.has_composition
| Description | Has existing  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
7.4.1.2. Test Case I_EHR_COMPOSITION.has_composition-bad_composition
| Description | Has  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
7.4.1.3. Test Case I_EHR_COMPOSITION.has_composition-bad_ehr
| Description | Has  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
7.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.
Service Model reference: I_EHR_COMPOSITION.get_composition_latest()
7.4.2.1. Test Case I_EHR_COMPOSITION.get_composition_latest
| Description | Get existing  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
7.4.2.2. Test Case I_EHR_COMPOSITION.get_composition_latest-bad_composition
| Description | Get  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
7.4.2.3. Test Case I_EHR_COMPOSITION.get_composition_latest-bad_ehr
| Description | Get  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
7.4.3. Get COMPOSITION at time
Service Model reference: I_EHR_COMPOSITION.get_composition_at_time()
7.4.3.1. Test Case I_EHR_COMPOSITION.get_composition_at_time
| Description | Get existing  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
7.4.3.2. Test Case I_EHR_COMPOSITION.get_composition_at_time-no_time_arg
| Description | Get existing  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
7.4.3.3. Test Case I_EHR_COMPOSITION.get_composition_at_time-bad_composition
| Description | Get  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
7.4.3.4. Test Case I_EHR_COMPOSITION.get_composition_at_time-bad_ehr
| Description | Get  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
7.4.3.5. Test Case I_EHR_COMPOSITION.get_composition_at_times
| Description | Get existing  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
7.4.4. Get COMPOSITION at version
Service Model reference: I_EHR_COMPOSITION.get_composition_version()
7.4.4.1. Test Case I_EHR_COMPOSITION.get_composition_version
| Description | Get existing  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
7.4.4.2. Test Case I_EHR_COMPOSITION.get_composition_version-bad_version
| Description | Get  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
7.4.4.3. Test Case I_EHR_COMPOSITION.get_composition_version-bad_ehr
| Description | Get  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
7.4.4.4. Test Case I_EHR_COMPOSITION.get_composition_versions
| Description | Get  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
7.4.5. Get VERSIONED COMPOSITION
Service Model reference: I_EHR_COMPOSITION.get_versioned_composition()
7.4.5.1. Test Case I_EHR_COMPOSITION.get_versioned_composition
| Description | Get existing  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
| Note | To consider different cases, try with VERSIONED_COMPOSITIONthat contain just oneVERSIONor manyVERSIONs | 
| Note | For that, the valid test cases for Create COMPOSITIONcould be used to comply with the preconditions of this test flow | 
7.4.5.2. Test Case I_EHR_COMPOSITION.get_versioned_composition-non_existent
| Description | Get non-existent  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
7.4.5.3. Test Case I_EHR_COMPOSITION.get_versioned_composition-bad_ehr
| Description | Get  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
7.4.6. Create COMPOSITION
Service Model reference: I_EHR_COMPOSITION.create_composition()
7.4.6.1. Test Case I_EHR_COMPOSITION.create_composition-event
| Description | Create new event  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | A new event  | 
| Flow | 
 | 
| Test runners | 
7.4.6.2. Test Case I_EHR_COMPOSITION.create_composition-persistent
| Description | Create new persistent  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | A new persistent  | 
| Flow | 
 | 
| Test runners | 
7.4.6.3. Test Case I_EHR_COMPOSITION.create_composition-same_opt_twice
| Description | Create persistent  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | A new persistent  | 
| Flow | 
 | 
| Test runners | 
Notes:
- 
Current criteria is: only one ‘create’ operation is allowed for persistent COMPOSITIONs, the next operations over an existing persistentCOMPOSITIONshould be ‘modifications’.
- 
This is under debate in the openEHR SEC since some implementations permit 'persistent' COMPOSIITONSto 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 forCOMPOSITIONsto allow different behaviors.
7.4.6.4. Test Case I_EHR_COMPOSITION.create_composition-invalid_event
| Description | Create new invalid event  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
7.4.6.5. Test Case I_EHR_COMPOSITION.create_composition-invalid_persistent
| Description | Create new invalid persistent  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
7.4.6.6. Test Case I_EHR_COMPOSITION.create_composition-event_bad_opt
| Description | Create new event  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
7.4.6.7. Test Case I_EHR_COMPOSITION.create_composition-event_bad_ehr
| Description | Create new event  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
7.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.
Service Model reference: I_EHR_COMPOSITION.update_composition()
7.4.7.1. Test Case I_EHR_COMPOSITION.update_composition-event
| Description | Update an existing event  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | 
 | 
| Flow | 
 | 
| Test runners | 
7.4.7.2. Test Case I_EHR_COMPOSITION.update_composition-persistent
| Description | Update an existing persistent  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | 
 | 
| Flow | 
 | 
| Test runners | 
7.4.7.3. Test Case I_EHR_COMPOSITION.update_composition-non_existent
| Description | Update a non-existing  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
7.4.7.4. Test Case I_EHR_COMPOSITION.update_composition-wrong_template
| Description | Update an existing  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | 
 | 
| Flow | 
 | 
| Test runners | 
7.4.8. Delete COMPOSITION
Service Model reference: I_EHR_COMPOSITION.delete_composition()
7.4.8.1. Test Case I_EHR_COMPOSITION.delete_composition-event
| Description | Delete event  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | 
 | 
| deleted | ` | 
| Flow | 
 | 
| Test runners | 
| Note | The common implementation of the deleteoperation is two create a newVERSIONof theCOMPOSITIONthat hasVERSION.commit_audit.change_type = openehr::523|deleted|, andVERSION.lifecycle_state = openehr::523|deleted|. So thedeleteoperation is not a physical delete but a logical delete. Some implementations might add the option of a physical deleted. This test case considers thepostconditionto be a logical delete, which behaves like anupdateoperation in which a newVERSIONof an existingCOMPOSITIONis created. | 
7.4.8.2. Test Case I_EHR_COMPOSITION.delete_composition-persistent
| Description | Delete persistent  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | 
 | 
| deleted | ` | 
| Flow | 
 | 
| Test runners | 
7.4.8.3. Test Case I_EHR_COMPOSITION.delete_composition-non_existent
| Description | Delete persistent  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
8. Test Suite: EHR_SERVICE / I_CONTRIBUTION Interface
8.1. Normative Reference
Items under this validation suite conceptually use these abstract interfaces from the Abstract Platform Service Model, EHR/EHR_CONTRIBUTION component.
8.2. Dependencies
This test suite depends on other test suites:
- 
Functional Conformance: Definitions Component, providing OPTs; 
- 
Functional Conformance: EHR Component, providing EHRs. 
8.3. Test Environment
- 
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. 
- 
The server should support at least one of the XML or JSON representations of CONTRIBUTIONsfor committing data, and integrate the corresponding schemas (XML or JSON) to validate data syntactically (before validating against an OPT).
8.4. Test Data Sets
8.4.1. General CONTRIBUTION Commit Data Sets
- 
CONTRIBUTIONswith single validVERSION<COMPOSITION>(minimal, one for each entry type)
- 
CONTRIBUTIONswith multiple validVERSION<COMPOSITION>(reuse the minimal ^)
- 
CONTRIBUTIONwith single validVERSION<COMPOSITION>with maximal data sets
- 
Empty CONTRIBUTION(noVERSIONs)
- 
CONTRIBUTIONswith invalidVERSION<COMPOSITION>- 
Invalid data 
- 
Wrong change_type
- 
Wrong lifecycle
 
- 
- 
CONTRIBUTIONswith multipleVERSION<COMPOSITION>, with mixed valid and invalid ones
| Note | these cases do not consider which RM type is contained in the VERSIONs, it could beCOMPOSITION,FOLDER,EHR_STATUS, etc. | 
8.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:
- 
Valid - 
minimal COMPOSITIONswith one type of ENTRY (oneENTRYeach, allENTRYscovered)
- 
maximal COMPOSITION(all data types, allENTRYtypes, andSECTIONs)
- 
a persistent COMPOSITION(e.g. problem list, medication list, immunization list, …)
- 
time series COMPOSITION(observation with many events, e.g. CPR compressions intervals)
- 
COMPOSITIONwith alternative types (e.g. lab resultDV_COUNT,DV_QUANTITYandDV_CODED_TEXT)
- 
COMPOSITIONwithDV_CODED_TEXTinstance on nodes declared asDV_TEXTin the OPT
- 
COMPOSITIONwith emptyELEMENT.valueand not emptyELEMENT.null_flavour
 
- 
- 
Invalid - 
Invalid COMPOSITIONs(e.g. mandatory items not present, wrong types, extra items not declared in OPT, invalid values)
- 
Referenced OPT not loaded (this has to do more with the state of the system than to invalid data) 
 
- 
- 
Change type combinations (these are the minimal required, all supported change types can be found in the openEHR Terminology) - 
VERSION.commit_audit.change_type = creation
- 
VERSION.commit_audit.change_type = modification
- 
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 | 
8.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:
- 
creation: the VERSIONrepresents the first version of aCOMPOSITION.
- 
amendment: the VERSIONrepresents a new version of an existingCOMPOSITION, with the purpose of adding data.
- 
modification: the VERSIONrepresents a new version of an existingCOMPOSITION, with the purpose of changing data, maybe to fix an error.
- 
deleted:the VERSIONrepresents a new version of an existingCOMPOSITION, 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:
- 
incomplete: the COMPOSITIONwas committed incomplete and should be completed (reviewed, validated, amended) later.
- 
complete: the COMPOSITIONwas complete at the moment it was committed.
- 
deleted: the COMPOSITIONwas committed for deletion.
These codes are defined in the openEHR Terminology.
lifecycle state machine
8.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 = deletedor because thelifecycle_state = |complete|can’t be withchange_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 COMPOSITIONis not
valid. | 
One commit (no previous commits were done), multiple versions cases:
| Note | the tables below represent one VERSIONin the committedCONTRIBUTION. | 
- 
Creating two valid, complete event COMPOSITIONsin one commit should be accepted.change_type+ lifecycle_state++ composition category composition validity creation complete event valid creation complete event valid This CONTRIBUTIONshould be accepted.
- 
Creating two valid, complete persistent COMPOSITIONsin one commit should be accepted.Notedepending on the server implementation, some servers might not accept the second COMPOSITIONif bothCOMPOSITIONsreference the same persistent OPT. So this test case considers bothCOMPOSITIONsreference different persistent OPTs.change_type+ lifecycle_state++ composition category composition validity creation complete persistent valid creation complete persistent valid This CONTRIBUTIONshould be accepted.
- 
Creating two valid, complete and mixed category COMPOSITIONsin one commit should be accepted.change_type+ lifecycle_state++ composition category composition validity creation complete event valid creation complete persistent valid This CONTRIBUTIONshould be accepted.
- 
If any COMPOSITIONis invalid in aCONTRIBUTION, 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 CONTRIBUTIONsshould 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. | 
8.4.3. EHR_STATUS CONTRIBUTION Commit Data Sets
8.4.3.1. Combinations for data sets
The following accepted and rejected apply under any of these scenarios:
- 
The server has an EHR with the default EHR_STATUS(the EHR was created without providing anEHR_STATUS).
- 
The server has an EHR created by providing an EHR_STATUS.
- 
The server has an EHR with modifications already done to its EHR_STATUS(consecutive modifications).
Reject Cases:
- 
CONTRIBUTIONswithVERSION, whereVERSION.commit_audit.change_typeIN [creation,deleted] should be rejected, because the defaultEHR_STATUSwas already created in the EHR, and theEHR_STATUScan’t be deleted once created.
- 
CONTRIBUTIONswithVERSION, whereVERSION.lifecycle_state=incompleteshould be rejected, because theincompletestate doesn’t apply toEHR_STATUS. Though there is an open issue related to this: https://specifications.openehr.org/jira/browse/SPECPR-368
- 
Any other case with an invalidEHR_STATUSinVERSIONshould also be rejected.
Accepted Cases:
- 
CONTRIBUTIONswithVERSIONwhereVERSION.commit_audit.change_typeIN [modification,amendment] andvalidEHR_STATUS, should be accepted. This inscludes the following combinations forEHR_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_STATUSisLOCATABLE, is should have anarchetype_idassigned. It is recommended to test the combination described above, combined with different values forEHR_STATUS.archetype_id. | 
8.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.
8.4.4.1. Data Set Combinations
Valid payload should include these cases:
- 
minimal directory 
- 
directory with items 
- 
directry with subfolders 
- 
directory with items and subfolders 
- 
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.
8.5. Test Cases
8.5.1. Service Model operation: I_EHR_CONTRIBUTION.commit_contribution()
Service Model reference: I_EHR_CONTRIBUTION.commit_contribution()
8.5.1.1. Test Case I_EHR_CONTRIBUTION.commit_contribution-valid_composition
| Description | Successfully commit  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | 
 | 
| Flow | 
 | 
| Test runners | 
8.5.1.2. Test Case I_EHR_CONTRIBUTION.commit_contribution-invalid_composition
| Description | Commit  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
8.5.1.3. Test Case I_EHR_CONTRIBUTION.commit_contribution-empty
| Description | Commit  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
8.5.1.4. Test Case I_EHR_CONTRIBUTION.commit_contribution-valid_invalid_compositions
| Description | Commit  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
| Note | the whole commit should behave like a transaction and fail, no CONTRIBUTIONsorVERSIONsshould be created on the server. | 
8.5.1.5. Test Case I_EHR_CONTRIBUTION.commit_contribution-event_composition
| Description | Commit  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | 
 | 
| Flow | 
 | 
| Test runners | 
8.5.1.6. Test Case I_EHR_CONTRIBUTION.commit_contribution-persistent_composition
| Description | Commit  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | 
 | 
| Flow | 
 | 
| Test runners | 
8.5.1.7. Test Case I_EHR_CONTRIBUTION.commit_contribution-delete
| Description | Commit  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | 
 | 
| Flow | 
 | 
| Test runners | 
8.5.1.8. Test Case I_EHR_CONTRIBUTION.commit_contribution-two_commits_second_invalid
| Description | Commit two  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | 
 | 
| Flow | 
 | 
| Test runners | 
8.5.1.9. Test Case I_EHR_CONTRIBUTION.commit_contribution-two_commits_second_creation
| Description | Commit two  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | 
 | 
| Flow | 
 | 
| Test runners | 
| Note | Validity criterion: only one 'create' operation is allowed for persistent COMPOSITIONs, the next operations over an existing persistentCOMPOSITIONshould be modification. | 
8.5.1.10. Test Case I_EHR_CONTRIBUTION.commit_contribution-non_exiting_opt
| Description | Commit  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
8.5.1.11. Test Case I_EHR_CONTRIBUTION.commit_contribution-minimal_ehr_status
| Description | Commit  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | 
 | 
| Flow | 
 | 
| Test runners | 
8.5.1.12. Test Case I_EHR_CONTRIBUTION.commit_contribution-full_ehr_status
| Note | this case is the same as previous but the precondition 2. is different. | 
| Description | Commit  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | 
 | 
| Flow | 
 | 
| Test runners | 
8.5.1.13. Test Case I_EHR_CONTRIBUTION.commit_contribution-ehr_status_invalid_change_type
| Description | Commit  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
8.5.1.14. Test Case I_EHR_CONTRIBUTION.commit_contribution-invalid_ehr_status
| Description | Commit  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
8.5.1.15. Test Case I_EHR_CONTRIBUTION.commit_contribution-valid_directory
| Description | Commit  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | 
 | 
| Flow | 
 | 
| Test runners | 
8.5.1.16. Test Case I_EHR_CONTRIBUTION.commit_contribution-fail_create_existing_directory
| Description | Commit  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
8.5.1.17. Test Case I_EHR_CONTRIBUTION.commit_contribution-fail_modify_non_existing_directory
| Description | Commit  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
8.5.1.18. Test Case I_EHR_CONTRIBUTION.commit_contribution-update_existing_directory
| Description | Commit  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | 
 | 
| Flow | 
 | 
| Test runners | 
8.5.2. Service Model operation: I_EHR_CONTRIBUTION.list_contributions()
Service Model reference: I_EHR_CONTRIBUTION.list_contributions()
| Note | CONTRIBUTIONscan containCOMPOSITION,EHR_STATUSorFOLDER, 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. | 
8.5.2.1. Test Case I_EHR_CONTRIBUTION.list_contributions-post_commit
| Description | List  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | 
 | 
| Flow | 
 | 
| Test runners | 
8.5.2.2. Test Case I_EHR_CONTRIBUTION.list_contributions-empty
| Description | List  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
8.5.2.3. Test Case I_EHR_CONTRIBUTION.list_contributions-non_existing_ehr
| Description | List  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
8.5.2.4. Test Case I_EHR_CONTRIBUTION.list_contributions-ehr_containing_ehr_status
| Description | List  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
8.5.2.5. Test Case I_EHR_CONTRIBUTION.list_contributions-ehr_containing_directory
| Description | List  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
8.5.3. Service Model operation: I_EHR_CONTRIBUTION.has_contribution()
Service Model reference: I_EHR_CONTRIBUTION.has_contribution()
8.5.3.1. Test Case I_EHR_CONTRIBUTION.has_contribution-existing
| Description | Test presence of  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
8.5.3.2. Test Case I_EHR_CONTRIBUTION.has_contribution-empty_ehr
| Description | Test presence of  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
8.5.3.3. Test Case I_EHR_CONTRIBUTION.has_contribution-bad_ehr
| Description | Test presence of  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
8.5.3.4. Test Case I_EHR_CONTRIBUTION.has_contribution-bad_contribution
| Description | Test presence of  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
8.5.4. Service Model operation: I_EHR_CONTRIBUTION.get_contribution()
Service Model reference: I_EHR_CONTRIBUTION.get_contribution()
8.5.4.1. Test Case I_EHR_CONTRIBUTION.get_contribution-existing
| Description | Test get  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
8.5.4.2. Test Case I_EHR_CONTRIBUTION.get_contribution-empty_ehr
| Description | Test get  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
8.5.4.3. Test Case I_EHR_CONTRIBUTION.get_contribution-bad_ehr
| Description | Test get  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
8.5.4.4. Test Case I_EHR_CONTRIBUTION.get_contribution-bad_contribution
| Description | Test get  | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
9. Test Suite: EHR_SERVICE / I_DIRECTORY Interface
9.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.
This test suite uses artefacts defined by the following information model specifications:
9.2. Dependencies
This test suite depends on other test suites:
- 
Functional Conformance: Definitions Component, providing OPTs; 
- 
Functional Conformance: EHR Component, providing EHRs. 
9.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.
9.4.1. Tests of EHR.directory
- 
FOLDER 
- 
FOLDER with items 
- 
FOLDER with subfolders 
- 
FOLDER with subfolders and items on all the folders 
- 
FOLDER with n levels of subfolders and items (to detect any implementation limitations) 
9.4.2. Tests of Reference FOLDER structure
| Note | the following image is provided for reference. The items in the FOLDERare references toVERSIONED_OBJECTsthat may containCOMPOSITION,EHR_STATUSandFOLDER. This documentation focuses on testingCOMPOSITIONas content in theFOLDERs. Discourse discussion. | 
9.5. Test Cases
9.5.1. Service Model operation: I_EHR_DIRECTORY.has_directory()
Service Model reference: I_EHR_DIRECTORY.has_directory()
9.5.1.1. Test Case I_EHR_DIRECTORY.has_directory-empty_ehr
| Description | Test has_directory on empty EHR | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
9.5.1.2. Test Case I_EHR_DIRECTORY.has_directory-ehr_with_directory
| Description | Test has_directory on EHR containing a directory | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
9.5.1.3. Test Case I_EHR_DIRECTORY.has_directory-bad_ehr
| Description | Test has_directory on non-existent EHR | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
9.5.2. Service Model operation: I_EHR_DIRECTORY.has_path()
Service Model reference: I_EHR_DIRECTORY.has_path()
9.5.2.1. Test Case I_EHR_DIRECTORY.has_path-empty_ehr
| Description | Test has_path on empty EHR | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
9.5.2.2. Test Case I_EHR_DIRECTORY.has_path-ehr_root_directory
| Description | Test has_path on EHR with just root directory | ||||||||
|---|---|---|---|---|---|---|---|---|---|
| Pre-conditions | 
 | ||||||||
| Post-conditions | None | ||||||||
| Flow | 
 | ||||||||
| Data set | 
 
 | ||||||||
| Test runners | 
9.5.2.3. Test Case I_EHR_DIRECTORY.has_path-folder_structure
| Description | Test has_path on EHR with folder structure | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Pre-conditions | 
 | ||||||||||||||||||||||||||||||
| Post-conditions | None | ||||||||||||||||||||||||||||||
| Flow | 
 | ||||||||||||||||||||||||||||||
| Data set | Assuming the following structure in  /
    +--- emergency
    |        |
    |        +--- episode-x
    |        |      |
    |        |      +--- summary-composition-x
    |        |
    |        +--- episode-y
    |               |
    |               +--- summary-composition-y
    |
    +--- hospitalization
             |
             +--- summary-composition-z
 
 
 | ||||||||||||||||||||||||||||||
| Test runners | 
9.5.2.4. Test Case I_EHR_DIRECTORY.has_path-bad_ehr
| Description | Test has_path on non-existent EHR | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
9.5.3. Service Model operation: I_EHR_DIRECTORY.create_directory()
Service Model reference: I_EHR_DIRECTORY.create_directory()
9.5.3.1. Test Case I_EHR_DIRECTORY.create_directory-empty_ehr
| Description | Test create_directory on empty EHR | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | 
 | 
| Flow | 
 | 
| Test runners | 
9.5.3.2. Test Case I_EHR_DIRECTORY.create_directory-ehr_with_directory
| Description | Test create_directory on EHR with directory | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
9.5.3.3. Test Case I_EHR_DIRECTORY.create_directory-bad_ehr
| Description | Test create_directory on non-existent EHR | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
9.5.4. Service Model operation: I_EHR_DIRECTORY.get_directory()
Service Model reference: I_EHR_DIRECTORY.get_directory()
9.5.4.1. Test Case I_EHR_DIRECTORY.get_directory-empty_ehr
| Description | Test get_directory on empty EHR | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
9.5.4.2. Test Case I_EHR_DIRECTORY.get_directory-ehr_root_directory
| Description | Test get_directory on EHR with a root directory | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
9.5.4.3. Test Case I_EHR_DIRECTORY.get_directory-directory_with_structure
| Description | Test get_directory on EHR with a directory containing sub-structure | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
9.5.4.4. Test Case I_EHR_DIRECTORY.get_directory-bad_ehr
| Description | Test get_directory on non-existent EHR | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
9.5.5. Service Model operation: I_EHR_DIRECTORY.get_directory_at_time()
Service Model reference: I_EHR_DIRECTORY.get_directory_at_time()
9.5.5.1. Test Case I_EHR_DIRECTORY.get_directory_at_time-empty_ehr
| Description | Test get_directory_at_time on empty EHR | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
9.5.5.2. Test Case 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 | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
9.5.5.3. Test Case I_EHR_DIRECTORY.get_directory_at_time-ehr_with_directory
| Description | Test get_directory_at_time on empty EHR with directory | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
9.5.5.4. Test Case 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 | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
9.5.5.5. Test Case 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 | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
9.5.5.6. Test Case 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 | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
9.5.5.7. Test Case I_EHR_DIRECTORY.get_directory_at_time-bad_ehr
| Description | Test get_directory_at_time on non-existent EHR | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
9.5.5.8. Test Case 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 | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
9.5.6. Service Model operation: I_EHR_DIRECTORY.update_directory()
Service Model reference: I_EHR_DIRECTORY.update_directory()
9.5.6.1. Test Case I_EHR_DIRECTORY.update_directory-ehr_with_directory
| Description | Test update_directory on EHR with directory | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | 
 | 
| Flow | 
 | 
| Test runners | 
9.5.6.2. Test Case I_EHR_DIRECTORY.update_directory-empty_ehr
| Description | Test update_directory on empty EHR | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
9.5.6.3. Test Case I_EHR_DIRECTORY.update_directory-bad_ehr
| Description | Test update_directory on non-existent EHR | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
9.5.7. Service Model operation: I_EHR_DIRECTORY.delete_directory()
Service Model reference: I_EHR_DIRECTORY.delete_directory()
9.5.7.1. Test Case I_EHR_DIRECTORY.delete_directory-empty_ehr
| Description | Test delete_directory on empty EHR | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
9.5.7.2. Test Case I_EHR_DIRECTORY.delete_directory-ehr_with_directory
| Description | Test delete_directory on EHR with directory | ||
|---|---|---|---|
| Pre-conditions | 
 | ||
| Post-conditions | 
 
 | ||
| Flow | 
 | ||
| Test runners | 
9.5.7.3. Test Case I_EHR_DIRECTORY.delete_directory-bad_ehr
| Description | Test delete_directory on non-existent EHR | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
9.5.8. Service Model operation: I_EHR_DIRECTORY.has_directory_version()
Service Model reference: I_EHR_DIRECTORY.has_directory_version()
9.5.8.1. Test Case I_EHR_DIRECTORY.has_directory_version-empty_ehr
| Description | Test has_directory_version on empty EHR | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
9.5.8.2. Test Case 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 | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
9.5.8.3. Test Case I_EHR_DIRECTORY.has_directory_version-bad_ehr
| Description | Test has_directory_version on non-existent EHR | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
9.5.9. Service Model operation: I_EHR_DIRECTORY.get_directory_at_version()
Service Model reference: I_EHR_DIRECTORY.get_directory_at_version()
9.5.9.1. Test Case I_EHR_DIRECTORY.get_directory_at_version-empty_ehr
| Description | Test get_directory_at_version on empty EHR | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
9.5.9.2. Test Case 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 | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
9.5.9.3. Test Case I_EHR_DIRECTORY.get_directory_at_version-bad_ehr
| Description | Test get_directory_at_version on non-existent EHR | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
9.5.10. Service Model operation: I_EHR_DIRECTORY.get_versioned_directory()
Service Model reference: I_EHR_DIRECTORY.get_versioned_directory()
9.5.10.1. Test Case I_EHR_DIRECTORY.get_versioned_directory-empty_ehr
| Description | Test get_versioned_directory on non-existent EHR | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
9.5.10.2. Test Case 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 | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
9.5.10.3. Test Case I_EHR_DIRECTORY.get_versioned_directory-bad_ehr
| Description | Test get_versioned_directory on non-existent EHR | 
|---|---|
| Pre-conditions | 
 | 
| Post-conditions | None | 
| Flow | 
 | 
| Test runners | 
10. Test Suite: DEMOGRAPHIC_SERVICE
10.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.
This test suite uses artefacts defined by the following information model specifications:
- 
Service Interfaces: 
- 
Information Models: 
10.2. Dependencies
This test suite depends on other test suites:
- 
Functional Conformance: Definitions Component, providing OPTs. 
10.5. Test Cases
10.5.1. Service Model operation: I_DEMOGRAPHIC_SERVICE.create_party()
Service Model reference: I_DEMOGRAPHIC_SERVICE.create_party()
10.5.2. Service Model operation: I_DEMOGRAPHIC_SERVICE.get_party()
Service Model reference: I_DEMOGRAPHIC_SERVICE.get_party()
10.5.3. Service Model operation: I_DEMOGRAPHIC_SERVICE.get_party_at_time()
Service Model reference: I_DEMOGRAPHIC_SERVICE.get_party_at_time()
10.5.4. Service Model operation: I_DEMOGRAPHIC_SERVICE.update_party()
Service Model reference: I_DEMOGRAPHIC_SERVICE.update_party()
10.5.5. Service Model operation: I_DEMOGRAPHIC_SERVICE.delete_party()
Service Model reference: I_DEMOGRAPHIC_SERVICE.delete_party()
10.5.6. Service Model operation: I_DEMOGRAPHIC_SERVICE.get_party_at_version()
Service Model reference: I_DEMOGRAPHIC_SERVICE.get_party_at_version()
10.5.7. Service Model operation: I_DEMOGRAPHIC_SERVICE.create_party_relationship()
Service Model reference: I_DEMOGRAPHIC_SERVICE.create_party_relationship()
10.5.8. Service Model operation: I_DEMOGRAPHIC_SERVICE.get_party_relationship()
Service Model reference: I_DEMOGRAPHIC_SERVICE.get_party_relationship()
10.5.9. Service Model operation: I_DEMOGRAPHIC_SERVICE.get_party_relationship_at_time()
Service Model reference: I_DEMOGRAPHIC_SERVICE.get_party_relationship_at_time()
10.5.10. Service Model operation: I_DEMOGRAPHIC_SERVICE.update_party_relationship()
Service Model reference: I_DEMOGRAPHIC_SERVICE.update_party_relationship()
10.5.11. Service Model operation: I_DEMOGRAPHIC_SERVICE.delete_party_relationship()
Service Model reference: I_DEMOGRAPHIC_SERVICE.delete_party_relationship()
10.5.12. Service Model operation: I_DEMOGRAPHIC_SERVICE.get_party_relationship_at_version()
Service Model reference: I_DEMOGRAPHIC_SERVICE.get_party_relationship_at_version()
11. Test Suite: QUERY_SERVICE
11.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.
This test suite uses artefacts defined by the following information model specifications:
- 
Service Interfaces: 
- 
Language Specifications: 
11.2. Dependencies
This test suite depends on other test suites:
- 
Functional Conformance: Definitions Component, providing OPTs. 
11.5. Test Cases
11.5.1. Service Model operation: I_QUERY_SERVICE.execute_stored_query()
Service Model reference: I_QUERY_SERVICE.execute_stored_query()
11.5.1.1. Test Case I_QUERY_SERVICE.smoke_test
| Description | xx | 
|---|---|
| Pre-conditions | xx | 
| Post-conditions | xx | 
| Flow | xx | 
| Test runners | 
11.5.2. Service Model operation: I_QUERY_SERVICE.execute_ad_hoc_query()
Service Model reference: I_QUERY_SERVICE.execute_ad_hoc_query()
11.5.2.1. Test Case I_QUERY_SERVICE.execute_ad_hoc_query-empty_db
| Description | xx | 
|---|---|
| Pre-conditions | xx | 
| Post-conditions | xx | 
| Flow | xx | 
| Test runners | 
12. Test Suite: ADMIN_SERVICE
12.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^].
This test suite uses artefacts defined by the following information model specifications:
- 
Service Interfaces: 
12.5. Test Cases
12.5.1. Service Model operation: I_ADMIN_SERVICE.list_contributions()
Service Model reference: I_ADMIN_SERVICE.list_contributions()
12.5.2. Service Model operation: I_ADMIN_SERVICE.contribution_count()
Service Model reference: I_ADMIN_SERVICE.contribution_count()
12.5.3. Service Model operation: I_ADMIN_SERVICE.versioned_composition_count()
Service Model reference: I_ADMIN_SERVICE.versioned_composition_count()
12.5.4. Service Model operation: I_ADMIN_SERVICE.composition_version_count()
Service Model reference: I_ADMIN_SERVICE.composition_version_count()
12.5.5. Service Model operation: I_ADMIN_SERVICE.physical_ehr_delete()
Service Model reference: I_ADMIN_SERVICE.physical_ehr_delete()
12.5.6. Service Model operation: I_ADMIN_SERVICE.physical_party_delete()
Service Model reference: I_ADMIN_SERVICE.physical_party_delete()
12.5.7. Service Model operation: I_ADMIN_DUMP_LOAD.export_ehrs()
Service Model reference: I_ADMIN_DUMP_LOAD.export_ehrs()
12.5.8. Service Model operation: I_ADMIN_ARCHIVE.archive_ehrs()
Service Model reference: I_ADMIN_ARCHIVE.archive_ehrs()
12.5.9. Service Model operation: I_ADMIN_ARCHIVE.archive_parties()
Service Model reference: I_ADMIN_ARCHIVE.archive_parties()
13. Test Suite: MESSAGE_SERVICE
13.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^].
This test suite uses artefacts defined by the following information model specifications:
- 
Service Interfaces: 
- 
Information Models: 
13.5. Test Cases
13.5.1. Service Model operation: I_EHR_EXTRACT.export_ehr()
Service Model reference: I_EHR_EXTRACT.export_ehr()
13.5.2. Service Model operation: I_EHR_EXTRACT.export_ehr_extract()
Service Model reference: I_EHR_EXTRACT.export_ehr_extract()
13.5.3. Service Model operation: I_EHR_EXTRACT.export_ehr()
Service Model reference: I_EHR_EXTRACT.export_ehr()
13.5.4. Service Model operation: I_EHR_EXTRACT.export_ehrs()
Service Model reference: I_EHR_EXTRACT.export_ehrs()
13.5.5. Service Model operation: I_EHR_EXTRACT.export_ehr_extracts()
Service Model reference: I_EHR_EXTRACT.export_ehr_extracts()
13.5.6. Service Model operation: I_TDD.import_tdd()
Service Model reference: I_TDD.import_tdd()
13.5.7. Service Model operation: I_TDD.import_tdds()
Service Model reference: I_TDD.import_tdds()
14. Data Validation Conformance
14.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:
- 
A top-level LOCATABLE class: COMPOSITION, EHR_STATUS, FOLDER, PARTY. 
- 
Constraint sets on top-level attributes for each class. 
- 
Internal LOCATABLE class: SECTION, ENTRY, HISTORY, ITEM_STRUCTURE, ITEM, DATA_VALUE. 
- 
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 
14.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.
14.2. COMPOSITION Test Cases
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:
- 
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. 
- 
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. | 
14.2.1. Test Case CONT-COMP-content_card_any-context_any
Description: COMPOSITION content cardinality 0..*, no constraint over context
COMPOSITION data sets:
- 
COMPOSITION with no entries (border case, success) 
- 
COMPOSITION with one entry (success) 
- 
COMPOSITION with 3 entries (success) 
Combine those cases with:
- 
COMPOSITION with no context 
- 
COMPOSITION with context but no other_context 
- 
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 | 
14.2.2. Test Case CONT-COMP-content_card_1plus-context_any
Description: COMPOSITION content cardinality 1..*, no constraint over context
COMPOSITION data sets:
- 
COMPOSITION with no entries (border case, fail) 
- 
COMPOSITION with one entry (border case, success) 
- 
COMPOSITION with 3 entries (success) 
Combine those cases with:
- 
COMPOSITION with no context 
- 
COMPOSITION with context but no other_context 
- 
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 | 
14.2.3. Test Case CONT-COMP-content_card_3plus-context_any
Description: COMPOSITION content cardinality 3..*, no constraint over context
COMPOSITION data sets:
- 
COMPOSITION with no entries (border case, fail) 
- 
COMPOSITION with one entry (fail) 
- 
COMPOSITION with 3 entries (border case, success) 
Combine those cases with:
- 
COMPOSITION with no context 
- 
COMPOSITION with context but no other_context 
- 
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 | 
14.2.4. Test Case CONT-COMP-content_card_opt-context_any
Description: COMPOSITION content cardinality 0..1, no constraint over context
COMPOSITION data sets:
- 
COMPOSITION with no entries (border case, success) 
- 
COMPOSITION with one entry (border case, success) 
- 
COMPOSITION with 3 entries (fail) 
Combine those cases with:
- 
COMPOSITION with no context 
- 
COMPOSITION with context but no other_context 
- 
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 | 
14.2.5. Test Case CONT-COMP-content_card_mand-context_any
Description: COMPOSITION content cardinality 1..1, no constraint over context
COMPOSITION data sets:
- 
COMPOSITION with no entries (border case, fail) 
- 
COMPOSITION with one entry (border case, success) 
- 
COMPOSITION with 3 entries (fail) 
Combine those cases with:
- 
COMPOSITION with no context 
- 
COMPOSITION with context but no other_context 
- 
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 | 
14.2.6. Test Case CONT-COMP-content_card_3to5-context_any
Description: COMPOSITION content cardinality 3..5, no constraint over context
COMPOSITION data sets:
- 
COMPOSITION with no entries (fail) 
- 
COMPOSITION with one entry (fail) 
- 
COMPOSITION with 3 entries (border case, success) 
Combine those cases with:
- 
COMPOSITION with no context 
- 
COMPOSITION with context but no other_context 
- 
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 | 
14.2.7. Test Case CONT-COMP-content_card_any-context_mand
Description: COMPOSITION content cardinality 0..*, context occurrences 1..1
COMPOSITION data sets:
- 
COMPOSITION with no entries (border case, success) 
- 
COMPOSITION with one entry (success) 
- 
COMPOSITION with 3 entries (success) 
Combine those cases with:
- 
COMPOSITION with no context 
- 
COMPOSITION with context but no other_context 
- 
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 | 
14.2.8. Test Case CONT-COMP-content_card_1plus-context_mand
Description: COMPOSITION content cardinality 1..*, context occurrences 1..1
COMPOSITION data sets:
- 
COMPOSITION with no entries (border case, fail) 
- 
COMPOSITION with one entry (border case, success) 
- 
COMPOSITION with 3 entries (success) 
Combine those cases with:
- 
COMPOSITION with no context 
- 
COMPOSITION with context but no other_context 
- 
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 | 
14.2.9. Test Case CONT-COMP-content_card_3plus-context_mand
Description: COMPOSITION content cardinality 3..*, context occurrences 1..1
COMPOSITION data sets:
- 
COMPOSITION with no entries (border case, fail) 
- 
COMPOSITION with one entry (fail) 
- 
COMPOSITION with 3 entries (border case, success) 
Combine those cases with:
- 
COMPOSITION with no context 
- 
COMPOSITION with context but no other_context 
- 
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 | 
14.2.10. Test Case CONT-COMP-content_card_opt-context_mand
Description: COMPOSITION content cardinality 0..1, context occurrences 1..1
COMPOSITION data sets:
- 
COMPOSITION with no entries (border case, success) 
- 
COMPOSITION with one entry (border case, success) 
- 
COMPOSITION with 3 entries (fail) 
Combine those cases with:
- 
COMPOSITION with no context 
- 
COMPOSITION with context but no other_context 
- 
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 | 
14.2.11. Test Case CONT-COMP-content_card_mand-context_mand
Description: COMPOSITION content cardinality 1..1, context occurrences 1..1
COMPOSITION data sets:
- 
COMPOSITION with no entries (border case, fail) 
- 
COMPOSITION with one entry (border case, success) 
- 
COMPOSITION with 3 entries (fail) 
Combine those cases with:
- 
COMPOSITION with no context 
- 
COMPOSITION with context but no other_context 
- 
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 | 
14.2.12. Test Case CONT-COMP-content_card_3to5-context_mand
Description: COMPOSITION content cardinality 3..5, context occurrences 1..1
COMPOSITION data sets:
- 
COMPOSITION with no entries (fail) 
- 
COMPOSITION with one entry (fail) 
- 
COMPOSITION with 3 entries (border case, success) 
Combine those cases with:
- 
COMPOSITION with no context 
- 
COMPOSITION with context but no other_context 
- 
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 | 
14.3. OBSERVATION Test Cases
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:
- 
OBSERVATION with no state and no protocol 
- 
OBSERVATION with no state and protocol 
- 
OBSERVATION with state and no protocol 
- 
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:
- 
Isolation: by not constraining OBSERVATION.data, OBSERVATION.state and OBSERVATION.protocol, or using the open/'any allowed' constraint \{*} for those attributes. 
- 
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. | 
14.3.1. Test Case 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 | 
14.3.2. Test Case 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 | 
14.3.3. Test Case 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 | 
14.3.4. Test Case 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 | 
14.4. HISTORY Test Cases
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:
- 
HISTORY with no events and no summary 
- 
HISTORY with events and no summary 
- 
HISTORY with no events and summary 
- 
HISTORY with events and summary 
The constraints combinations described below could be tested in two ways:
- 
Isolation: by not constraining HISTORY.events and HISTORY.summary, or using the open/'any allowed' constraint \{*} for those attributes. 
- 
Combination: with constraints defined at the EVENT level (for events) and ITEM_STRUCTURE (for summary). 
| Note | we suggest to test with both strategies. | 
14.4.1. Test Case 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 | 
14.4.2. Test Case 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 | 
14.4.3. Test Case 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 | 
14.4.4. Test Case 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 | 
14.4.5. Test Case 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 | 
14.4.6. Test Case 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 | 
14.4.7. Test Case 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 | 
14.4.8. Test Case 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 | 
14.4.9. Test Case 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 | 
14.4.10. Test Case 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 | 
14.4.11. Test Case 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 | 
14.4.12. Test Case 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 | 
14.5. EVENT Test Cases
EVENT data sets:
- 
EVENT with no state 
- 
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:
- 
EVENT is POINT_EVENT 
- 
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:
- 
Isolation: by not constraining EVENT.data and EVENT.state, or using the open/‘any allowed’ constraint \{*} for those attributes. 
- 
Combination: with constraints defined at the ITEM_STRUCTURE level (for data and state). 
| Note | we suggest to test with both strategies. | 
14.5.1. Test Case 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 | 
14.5.2. Test Case 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 | 
14.5.3. Test Case 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 | 
14.6. ITEM_STRUCTURE Test Cases
ITEM_STRUCTURE type combinations:
- 
ITEM_STRUCTURE is ITEM_TREE 
- 
ITEM_STRUCTURE is ITEM_LIST 
- 
ITEM_STRUCTURE is ITEM_TABLE 
- 
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. | 
14.6.1. Test Case 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 | 
14.6.2. Test Case 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 | 
14.6.3. Test Case 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 | 
14.7. Data Types - Basic Package
14.7.1. DV_BOOLEAN
Internally DV_BOOLEAN is constrained by C_BOOLEAN.
14.7.1.1. Test Case CONT-DV_BOOLEAN-anything_allowed
| value | C_BOOLEAN.true_valid | C_BOOLEAN.false_valid | expected | constraints violated | 
|---|---|---|---|---|
| true | true | true | accepted | |
| false | true | true | accepted | 
14.7.2. DV_IDENTIFIER
Internally DV_IDENTIFIER attributes are constrainted by C_STRING.
Note the constraints for each attribute are all checked, so the errors are accumulated. If one validation fails for one attribute, the validation for the whole type fails.
14.7.2.1. Test Case CONT-DV_IDENTIFIER-validate_all_pattern
| issuer | C_STRING.pattern | C_STRING.list | expected | constraints violated | 
|---|---|---|---|---|
| NULL | XYZ.* | NULL | rejected | C_STRING.pattern | 
| ABC | XYZ.* | NULL | rejected | C_STRING.pattern | 
| XYZ | XYZ.* | NULL | accepted | 
| assigner | C_STRING.pattern | C_STRING.list | expected | constraints violated | 
|---|---|---|---|---|
| NULL | XYZ.* | NULL | rejected | C_STRING.pattern | 
| ABC | XYZ.* | NULL | rejected | C_STRING.pattern | 
| XYZ | XYZ.* | NULL | accepted | 
| id | C_STRING.pattern | C_STRING.list | expected | constraints violated | 
|---|---|---|---|---|
| NULL | XYZ.* | NULL | rejected | RM/Schema: this is mandatory in the RM | 
| ABC | XYZ.* | NULL | rejected | C_STRING.pattern | 
| XYZ | XYZ.* | NULL | accepted | 
| type | C_STRING.pattern | C_STRING.list | expected | constraints violated | 
|---|---|---|---|---|
| NULL | XYZ.* | NULL | rejected | C_STRING.pattern | 
| ABC | XYZ.* | NULL | rejected | C_STRING.pattern | 
| XYZ | XYZ.* | NULL | accepted | 
14.7.2.2. Test Case CONT-DV_IDENTIFIER-validate_all_list
| issuer | C_STRING.pattern | C_STRING.list | expected | constraints violated | 
|---|---|---|---|---|
| NULL | NULL | [XYZ] | rejected | C_STRING.list | 
| ABC | NULL | [XYZ] | rejected | C_STRING.list | 
| XYZ | NULL | [XYZ] | accepted | 
| assigner | C_STRING.pattern | C_STRING.list | expected | constraints violated | 
|---|---|---|---|---|
| NULL | NULL | [XYZ] | rejected | C_STRING.list | 
| ABC | NULL | [XYZ] | rejected | C_STRING.list | 
| XYZ | NULL | [XYZ] | accepted | 
| id | C_STRING.pattern | C_STRING.list | expected | constraints violated | 
|---|---|---|---|---|
| NULL | NULL | [XYZ] | rejected | RM/Schema: this is mandatory in the RM | 
| ABC | NULL | [XYZ] | rejected | C_STRING.list | 
| XYZ | NULL | [XYZ] | accepted | 
| type | C_STRING.pattern | C_STRING.list | expected | constraints violated | 
|---|---|---|---|---|
| NULL | NULL | [XYZ] | rejected | C_STRING.list | 
| ABC | NULL | [XYZ] | rejected | C_STRING.list | 
| XYZ | NULL | [XYZ] | accepted | 
14.7.3. DV_STATE
| Note | this datatype is not used and not supported by modeling tools (Discourse discussion). | 
14.8. Data Types - text Package
14.8.1. DV_TEXT
Internally DV_TEXT can be constrained by a C_STRING. This type also allows an instance of the subclass DV_CODED_TEXT at runtime.
14.8.1.1. Test Case CONT-DV_TEXT-validate_open
In ADL this would mean the C_OBJECT for DV_TEXT matches {*}, but different Archetype Editors might model this differently, for instance LinkEHR does a DV_TEXT.value matches {'.*'} which is using the C_STRING pattern that matches anything.
| value | C_STRING.pattern | C_STRING.list | expected | constraints violated | 
|---|---|---|---|---|
| NULL | NULL | NULL | rejected | RM/Schema mandatory | 
| ABC | NULL | NULL | accepted | |
| XYZ | NULL | NULL | accepted | 
14.8.1.2. Test Case CONT-DV_TEXT-validate_open
| Note | if the type is DV_CODED_TEXT at runtime, the value attribte still needs to comply with the C_STRING constraint. | 
| value | C_STRING.pattern | C_STRING.list | expected | constraints violated | 
|---|---|---|---|---|
| NULL | XYZ | NULL | rejected | RM/Schema mandatory | 
| ABC | XYZ | NULL | rejected | C_STRING.pattern | 
| XYZ | XYZ | NULL | accepted | 
14.8.1.3. Test Case CONT-DV_TEXT-validate_list
| Note | if the type is DV_CODED_TEXT at runtime, the value attribte still needs to comply with the C_STRING constraint. | 
| value | C_STRING.pattern | C_STRING.list | expected | constraints violated | 
|---|---|---|---|---|
| NULL | NULL | [XYZ, OPQ] | rejected | RM/Schema mandatory | 
| ABC | NULL | [XYZ, OPQ] | rejected | C_STRING.list | 
| XYZ | NULL | [XYZ, OPQ] | accepted | 
14.8.2. DV_CODED_TEXT
Internally the DV_CODED_TEXT can be constrained by a C_CODE_PHRASE. Note that in the cases for DV_TEXT we already tested when the type is constrained by a C_STRING (when the declared type is DV_TEXT but the runtime type is DV_CODED_TEXT).
14.8.2.1. Test Case CONT-DV_CODED_TEXT-validate_open
In ADL this would mean the C_OBJECT for DV_CODED_TEXT matches {*}.
| code_string | terminology_id | C_CODE_PHRASE. code_list | C_CODE_PHRASE. terminology_id | expected | constraints violated | 
|---|---|---|---|---|---|
| NULL | NULL | NULL | NULL | rejected | RM/Schema mandatory both code_String and terminology_id | 
| ABC | NULL | NULL | NULL | rejected | RM/Schema mandatory terminology_id | 
| NULL | local | NULL | NULL | rejected | RM/Schema mandatory code_string | 
| ABC | local | NULL | NULL | accepted | |
| 82272006 | SNOMED-CT | NULL | NULL | accepted | 
14.8.2.2. Test Case CONT-DV_CODED_TEXT-validate_local_codes
| Note | having C_CODE_PHRASE.terminology_id = local and C_CODE_PHRASE.code_list = EMPTY, would be possible at the archetype level, but would be invalid at the template level, so that case is not considered here since it should be validated when the template is uploaded to the SUT. | 
| code_string | terminology_id | C_CODE_PHRASE. code_list | C_CODE_PHRASE. terminology_id | expected | constraints violated | 
|---|---|---|---|---|---|
| NULL | NULL | [ABC, OPQ] | local | rejected | RM/Schema mandatory both code_String and terminology_id | 
| ABC | NULL | [ABC, OPQ] | local | rejected | RM/Schema mandatory terminology_id | 
| NULL | local | [ABC, OPQ] | local | rejected | RM/Schema mandatory code_string | 
| ABC | local | [ABC, OPQ] | local | accepted | |
| 82272006 | SNOMED-CT | [ABC, OPQ] | local | rejected | C_CODE_PHRASE.terminology_id | 
14.8.2.3. Test Case CONT-DV_CODED_TEXT-validate_ext_term
In this case the DV_CODED_TEXT is constrained by a CONSTRAINT_REF. For the CONSTRAINT_REF to be valid in the template, there shoudld be a constraint_binding entry in the template ontology for the acNNNN code of the CONSTRAINT_REF. Without that, the SUT doesn’t know which terminology_id can be used in that DV_CODED_TEXT. Note that multiple bindings are possible, so there could be more than one terminology_id for the coded text. The cases where there are no constraint_bindings are not tested here, that should be part of the OPT validation.
| Note | the COSNTRAINT_REF in ADL is transformed by the Template Designer into a C_CODE_REFERENCE in OPT, which is a C_CODE_PHRASE subclass with an extra referenceSetUri attribute. | 
| code_string | terminology_id | CONSTRAINT_REF. reference | constraint_bindings | expected | constraints violated | 
|---|---|---|---|---|---|
| NULL | NULL | ac0001 | [SNOMED_CT] | rejected | RM/Schema mandatory both code_String and terminology_id | 
| ABC | NULL | ac0001 | [SNOMED_CT] | rejected | RM/Schema mandatory terminology_id | 
| NULL | local | ac0001 | [SNOMED_CT] | rejected | RM/Schema mandatory code_string | 
| ABC | local | ac0001 | [SNOMED_CT] | rejected | constraint_binding: terminology_id not found | 
| 82272006 | SNOMED-CT | ac0001 | [SNOMED_CT] | accepted | 
14.8.3. DV_PARAGRAPH
| Note | this DB is not used or supported by modeling tools, see https://discourse.openehr.org/t/is-dv-paragraph-used/2187 | 
14.9. Data Types - quantity Package
14.9.1. DV_ORDINAL
DV_ORDINAL is constrained by C_DV_ORDINAL from the openEHR AM 1.4 Archetype Profile, which contains a list of DV_ORDINAL that could be empty.
| Note | in ADL it is possible to have a C_DV_ORDINAL constraint with an empty list constraint. At the OPT level this case should be invalid, since is like defining a constraint for a DV_CODED_TEXT with terminology_id localbut no given codes, since all codes in a C_DV_ORDINAL have terminology_idlocal, at least one code in the list is required at the OPT level. This constraint is valid at the archetypel evel. See commend on 2.3.2. | 
14.9.1.1. Test Case CONT-DV_ORDINAL-validate_open
This case is when the ADL has DV_ORDINAL matches {*}
| symbol | value | expected | constraints violated | 
|---|---|---|---|
| NULL | NULL | rejected | RM/Schema value and symbol are mandatory | 
| NULL | 1 | rejected | RM/Schema symbol is mandatory | 
| local::at0005 | NULL | rejected | RM/Schema value is mandatory | 
| local::at0005 | 1 | accepted | |
| local::at0005 | 666 | accepted | 
14.9.1.2. Test Case CONT-DV_ORDINAL-validate_constraint
| symbol | value | C_DV_ORDINAL.list | expected | constraints violated | 
|---|---|---|---|---|
| local::at0005 | 1 | 1|[local::at0005], 2|[local::at0006] | accepted | |
| local::at0005 | 666 | 1|[local::at0005], 2|[local::at0006] | rejected | C_DV_ORDINAL.list: no matching value | 
| local::at0666 | 1 | 1|[local::at0005], 2|[local::at0006] | rejected | C_DV_ORDINAL.list: no matching symbol | 
14.9.2. DV_SCALE
DV_SCALE was introduced to the RM 1.1.0 (Discourse discussion), it is analogous to DV_ORDINAL with a Real value. So test cases for DV_SCALE and DV_ORDINAL are similar.
| Note | if this specification is implemented on a system that supports a RM < 1.1.0, then these tests shouldn’t run against the system. | 
14.9.2.1. Test Case CONT-DV_SCALE-validate_open
This case is when the ADL has DV_SCALE matches {*}
| symbol | value | expected | constraints violated | 
|---|---|---|---|
| NULL | NULL | rejected | RM/Schema value and symbol are mandatory | 
| NULL | 1.5 | rejected | RM/Schema symbol is mandatory | 
| local::at0005 | NULL | rejected | RM/Schema value is mandatory | 
| local::at0005 | 1.5 | accepted | |
| local::at0005 | 666 | accepted | 
14.9.2.2. Test Case CONT-DV_SCALE-validate_constraint
| Note | there is no current C_DV_SCALE constraint in the Archetype Profile, so modeling tools are not yet supporting constraints for this type. This is a [known issue](https://openehr.atlassian.net/browse/SPECPR-381). Though we can assume the constraint type will be analogous to the C_DV_ORDINAL. | 
| symbol | value | C_DV_SCALE.list | expected | constraints violated | 
|---|---|---|---|---|
| local::at0005 | 1.5 | 1.5|[local::at0005], 2.0|[local::at0006] | accepted | |
| local::at0005 | 66.6 | 1.5|[local::at0005], 2.0|[local::at0006] | rejected | C_DV_SCALE.list: no matching value | 
| local::at0666 | 1.5 | 1.5|[local::at0005], 2.0|[local::at0006] | rejected | C_DV_SCALE.list: no matching symbol | 
14.9.3. DV_COUNT
Internally this type is constrained by a C_INTEGER which could contain a range or a list of values.
14.9.3.1. Test Case CONT-DV_COUNT-validate_open
This case represents the DV_COUNT matching {*}, in this case the C_INTEGER is not present in the OPT.
| magnitude | expected | constraints violated | 
|---|---|---|
| NULL | rejected | RM/Schema magnitude is mandatory | 
| 0 | accepted | |
| 1 | accepted | |
| 15 | accepted | |
| 30 | accepted | 
14.9.3.2. Test Case CONT-DV_COUNT-validate_range
| magnitude | C_INTEGER.range | C_INTEGER.list | expected | constraints violated | 
|---|---|---|---|---|
| NULL | 10..20 | NULL | rejected | RM/Schema magnitude is mandatory | 
| 0 | 10..20 | NULL | rejected | C_INTEGER.range | 
| 1 | 10..20 | NULL | rejected | C_INTEGER.range | 
| 15 | 10..20 | NULL | accepted | |
| 30 | 10..20 | NULL | rejected | C_INTEGER.range | 
14.9.3.3. Test Case CONT-DV_COUNT-validate_list
| Note | some modeling tools might not support the list constraint. | 
| magnitude | C_INTEGER.range | C_INTEGER.list | expected | constraints violated | 
|---|---|---|---|---|
| NULL | NULL | [10,15,20] | rejected | RM/Schema magnitude is mandatory | 
| 0 | NULL | [10,15,20] | rejected | C_INTEGER.list | 
| 1 | NULL | [10,15,20] | rejected | C_INTEGER.list | 
| 15 | NULL | [10,15,20] | accepted | |
| 30 | NULL | [10,15,20] | rejected | C_INTEGER.list | 
14.9.4. DV_QUANTITY
Internally DV_QUANTITY is constrained by a C_DV_QUANTITY, which allows to specify an optional physical property and a list of C_QUANTITY_ITEM, which can contain a mandatory units and optional interval constraints for magnitude and precision.
14.9.4.1. Test Case CONT-DV_QUANTITY-validate_open
This case represents the DV_QUANTITY matching {*}, in this case the C_DV_QUANTITY is not present in the OPT.
| magnitude | units | expected | constraints violated | 
|---|---|---|---|
| NULL | NULL | rejected | RM/Schema both magnitude and untis are mandatory | 
| NULL | cm | rejected | RM/Schema magnitude is mandatory | 
| 1.0 | NULL | rejected | RM/Schema untis is mandatory | 
| 0.0 | cm | accepted | |
| 1.0 | cm | accepted | |
| 5.7 | cm | accepted | |
| 10.0 | cm | accepted | 
14.9.4.2. Test Case CONT-DV_QUANTITY-validate_property
The C_DV_QUANTITY is present in the OPT and has a value for property, but doesn’t have a list of C_QUANTITY_ITEM.
| Note | in this case all units for the propertyare allowed, so the validation should look into UCUM for all the possible units of measure or that physical property (the possible values are not un the OPT). | 
| magnitude | units | C_DV_QUANTITY.property | C_DV_QUANTITY.list | expected | constraints violated | 
|---|---|---|---|---|---|
| NULL | NULL | openehr::122 (length) | NULL | rejected | RM/Schema both magnitude and untis are mandatory | 
| NULL | cm | openehr::122 (length) | NULL | rejected | RM/Schema magnitude is mandatory | 
| 1.0 | NULL | openehr::122 (length) | NULL | rejected | RM/Schema untis is mandatory | 
| 0.0 | mg | openehr::122 (length) | NULL | rejected | C_DV_QUANTITY.property:  | 
| 0.0 | cm | openehr::122 (length) | NULL | accepted | |
| 1.0 | cm | openehr::122 (length) | NULL | accepted | |
| 5.7 | cm | openehr::122 (length) | NULL | accepted | |
| 10.0 | cm | openehr::122 (length) | NULL | accepted | 
14.9.4.3. Test Case CONT-DV_QUANTITY-validate_property_units
| magnitude | units | C_DV_QUANTITY.property | C_DV_QUANTITY.list | expected | constraints violated | 
|---|---|---|---|---|---|
| NULL | NULL | openehr::122 (length) | [cm, m] | rejected | RM/Schema both magnitude and untis are mandatory | 
| NULL | cm | openehr::122 (length) | [cm, m] | rejected | RM/Schema magnitude is mandatory | 
| 1.0 | NULL | openehr::122 (length) | [cm, m] | rejected | RM/Schema untis is mandatory | 
| 0.0 | mg | openehr::122 (length) | [cm, m] | rejected | C_DV_QUANTITY.property:  | 
| 0.0 | cm | openehr::122 (length) | [cm, m] | accepted | |
| 0.0 | km | openehr::122 (length) | [cm, m] | rejected | C_DV_QUANTITY.list:  | 
| 1.0 | cm | openehr::122 (length) | [cm, m] | accepted | |
| 5.7 | cm | openehr::122 (length) | [cm, m] | accepted | |
| 10.0 | cm | openehr::122 (length) | [cm, m] | accepted | 
14.9.4.4. Test Case CONT-DV_QUANTITY-validate_property_units_mag
| magnitude | units | C_DV_QUANTITY.property | C_DV_QUANTITY.list | expected | constraints violated | 
|---|---|---|---|---|---|
| NULL | NULL | openehr::122 (length) | [cm 5.0..10.0, m] | rejected | RM/Schema both magnitude and untis are mandatory | 
| NULL | cm | openehr::122 (length) | [cm 5.0..10.0, m] | rejected | RM/Schema magnitude is mandatory | 
| 1.0 | NULL | openehr::122 (length) | [cm 5.0..10.0, m] | rejected | RM/Schema untis is mandatory | 
| 0.0 | mg | openehr::122 (length) | [cm 5.0..10.0, m] | rejected | C_DV_QUANTITY.property:  | 
| 0.0 | cm | openehr::122 (length) | [cm 5.0..10.0, m] | rejected | C_DV_QUANTITY.list: magnitude not in range for unit | 
| 0.0 | km | openehr::122 (length) | [cm 5.0..10.0, m] | rejected | C_DV_QUANTITY.list:  | 
| 1.0 | cm | openehr::122 (length) | [cm 5.0..10.0, m] | rejected | C_DV_QUANTITY.list: magnitude not in range for unit | 
| 5.7 | cm | openehr::122 (length) | [cm 5.0..10.0, m] | accepted | |
| 10.0 | cm | openehr::122 (length) | [cm 5.0..10.0, m] | accepted | 
14.9.5. DV_PROPORTION
The DV_PROPORTION is contrained by a C_COMPLEX_OBJECT, which internally has C_REAL constraints for numerator and denominator. C_REAL defines two types of constraints: range and list of values. Though current modeling tools only allow range contraints. For the type atribute, a C_INTEGER constraint is used, which can hold list and range constraints but modeling tools only use the list.
This type has intrinsic constraints that should be semantically consistent depending on the value of the numerator, denominator, precision and type attributes. For instance, this if type = 2, the denominator value should be 100 and can’t be anything else. In te table below we express the valid combinations of attribute values.
| type | meaning (kind) | numerator | denominator | precision | comment | 
|---|---|---|---|---|---|
| 0 | ratio | any | any != 0 | any | |
| 1 | unitary | any | 1 | any | |
| 2 | percent | any | 100 | any | |
| 3 | fraction | integer | integer != 0 | 0 | presentation is num/den | 
| 4 | integer fraction | integer | integer != 0 | 0 | presentation is integral(num/den) decimal(num/den), e.g. for num=3 den=2: 1 1/2 | 
| Note | the difference between fraction and integer fraction is the presentation, the data and constraints are the same. | 
14.9.5.1. Test Case CONT-DV_PROPORTION-validate_open
This test case is used to check the internal rules of the DV_PROPORTION are correctly implemented by the SUT.
| type | meaning (kind) | numerator | denominator | precision | expected | constraints violated | 
|---|---|---|---|---|---|---|
| 0 | ratio | 10 | 500 | 0 | accepted | |
| 0 | ratio | 10 | 0 | 0 | rejected | valid_denominator (invariant) | 
| 1 | unitary | 10 | 1 | 0 | accepted | |
| 1 | unitary | 10 | 0 | 0 | rejected | valid_denominator (invariant) | 
| 1 | unitary | 10 | 500 | 0 | rejected | unitary_validity (invariant) | 
| 2 | percent | 10 | 0 | 0 | rejected | valid_denominator (invariant) | 
| 2 | percent | 10 | 100 | 0 | accepted | |
| 2 | percent | 10 | 500 | 0 | rejected | percent_validity (invariant) | 
| 3 | fraction | 10 | 0 | 0 | rejected | valid_denominator (invariant) | 
| 3 | fraction | 10 | 100 | 0 | accepted | |
| 3 | fraction | 10 | 500 | 1 | rejected | fraction_validity (invariant) | 
| 3 | fraction | 10.5 | 500 | 1 | rejected | is_integral_validity (invariant) | 
| 3 | fraction | 10 | 500.5 | 1 | rejected | is_integral_validity (invariant) | 
| 4 | integer fraction | 10 | 0 | 0 | rejected | valid_denominator (invariant) | 
| 4 | integer fraction | 10 | 100 | 0 | accepted | |
| 4 | integer fraction | 10 | 500 | 1 | rejected | fraction_validity (invariant) | 
| 4 | integer fraction | 10.5 | 500 | 1 | rejected | is_integral_validity (invariant) | 
| 4 | integer fraction | 10 | 500.5 | 1 | rejected | is_integral_validity (invariant) | 
| 666 | 10 | 500 | 0 | rejected | type_validity (invariant) | 
14.9.5.2. Test Case CONT-DV_PROPORTION-validate_ratio
The C_INTEGER constraint applies to the type attribute.
| type | meaning (kind) | numerator | denominator | precision | C_INTEGER.list | expected | constraints violated | 
|---|---|---|---|---|---|---|---|
| 0 | ratio | 10 | 500 | 0 | [0] | accepted | |
| 1 | unitary | 10 | 1 | 0 | [0] | rejected | C_INTEGER.list | 
| 2 | percent | 10 | 100 | 0 | [0] | rejected | C_INTEGER.list | 
| 3 | fraction | 10 | 500 | 0 | [0] | rejected | C_INTEGER.list | 
| 4 | integer fraction | 10 | 500 | 0 | [0] | rejected | C_INTEGER.list | 
| Note | all the fail cases related with invariants were already contemplated in 3.6.1. | 
14.9.5.3. Test Case CONT-DV_PROPORTION-validate_unitary
The C_INTEGER constraint applies to the type attribute.
| type | meaning (kind) | numerator | denominator | precision | C_INTEGER.list | expected | constraints violated | 
|---|---|---|---|---|---|---|---|
| 0 | ratio | 10 | 500 | 0 | [1] | reejcted | C_INTEGER.list | 
| 1 | unitary | 10 | 1 | 0 | [1] | accepted | |
| 2 | percent | 10 | 100 | 0 | [1] | rejected | C_INTEGER.list | 
| 3 | fraction | 10 | 500 | 0 | [1] | rejected | C_INTEGER.list | 
| 4 | integer fraction | 10 | 500 | 0 | [1] | rejected | C_INTEGER.list | 
14.9.5.4. Test Case CONT-DV_PROPORTION-validate_percent
The C_INTEGER constraint applies to the type attribute.
| type | meaning (kind) | numerator | denominator | precision | C_INTEGER.list | expected | constraints violated | 
|---|---|---|---|---|---|---|---|
| 0 | ratio | 10 | 500 | 0 | [2] | reejcted | C_INTEGER.list | 
| 1 | unitary | 10 | 1 | 0 | [2] | rejected | C_INTEGER.list | 
| 2 | percent | 10 | 100 | 0 | [2] | accepted | |
| 3 | fraction | 10 | 500 | 0 | [2] | rejected | C_INTEGER.list | 
| 4 | integer fraction | 10 | 500 | 0 | [2] | rejected | C_INTEGER.list | 
14.9.5.5. Test Case CONT-DV_PROPORTION-validate_fraction
The C_INTEGER constraint applies to the type attribute.
| type | meaning (kind) | numerator | denominator | precision | C_INTEGER.list | expected | constraints violated
| 0 | ratio | 10 | 500 | 0 | [3] | rejected | C_INTEGER.list | 
|---|---|---|---|---|---|---|---|
| 1 | unitary | 10 | 1 | 0 | [3] | rejected | C_INTEGER.list | 
| 2 | percent | 10 | 100 | 0 | [3] | rejected | C_INTEGER.list | 
| 3 | fraction | 10 | 500 | 0 | [3] | accepted | |
| 4 | integer fraction | 10 | 500 | 0 | [3] | rejected | C_INTEGER.list | 
14.9.5.6. Test Case CONT-DV_PROPORTION-validate_integer_fraction
The C_INTEGER constraint applies to the type attribute.
| type | meaning (kind) | numerator | denominator | precision | C_INTEGER.list | expected | constraints violated | 
|---|---|---|---|---|---|---|---|
| 0 | ratio | 10 | 500 | 0 | [4] | reejcted | C_INTEGER.list | 
| 1 | unitary | 10 | 1 | 0 | [4] | rejected | C_INTEGER.list | 
| 2 | percent | 10 | 100 | 0 | [4] | rejected | C_INTEGER.list | 
| 3 | fraction | 10 | 500 | 0 | [4] | rejected | C_INTEGER.list | 
| 4 | integer fraction | 10 | 500 | 0 | [4] | accepted | 
14.9.5.7. Test Case CONT-DV_PROPORTION-validate_any_fraction
This case is similar to the previous one, it just tests a combination of possible types for the proportion.
| type | meaning (kind) | numerator | denominator | precision | C_INTEGER.list | expected | constraints violated | 
|---|---|---|---|---|---|---|---|
| 0 | ratio | 10 | 500 | 0 | [3, 4] | reejcted | C_INTEGER.list | 
| 1 | unitary | 10 | 1 | 0 | [3, 4] | rejected | C_INTEGER.list | 
| 2 | percent | 10 | 100 | 0 | [3, 4] | rejected | C_INTEGER.list | 
| 3 | fraction | 10 | 500 | 0 | [3, 4] | accepted | |
| 4 | integer fraction | 10 | 500 | 0 | [3, 4] | accepted | 
14.9.5.8. Test Case CONT-DV_PROPORTION-validate_ratio_range
The C_INTEGER constraint applies to the type attribute. The C_REAL constraints apply to numerator and denominator respectively.
| type | meaning (kind) | numerator | denominator | precision | C_INTEGER.list | C_REAL.range (num) | C_REAL.range (den) | expected | constraints violated | 
|---|---|---|---|---|---|---|---|---|---|
| 0 | ratio | 10 | 500 | 0 | [0] | 5..20 | 200..600 | accepted | |
| 0 | ratio | 10 | 1 | 0 | [0] | 5..20 | 200..600 | rejected | C_REAL.range (den) | 
| 0 | ratio | 30 | 500 | 0 | [0] | 5..20 | 200..600 | rejected | C_REAL.range (num) | 
| 0 | ratio | 3 | 1000 | 0 | [0] | 5..20 | 200..600 | rejected | C_REAL.range (num), C_REAL.range (den) | 
14.9.6. DV_INTERVAL<DV_COUNT>
14.9.6.1. Test Case CONT-DV_INTERVAL_DV_COUNT-validate_open
The DV_INTERVAL<DV_COUNT> constraint is {*}.
| Note | the failure instance for this test case are related with violated interval semantics. | 
| lower | upper | lower_unbounded | upper_unbounded | lower_included | upper_included | expected | constraints violated | 
|---|---|---|---|---|---|---|---|
| NULL | NULL | true | true | false | false | accepted | |
| NULL | 100 | true | false | false | false | accepted | |
| NULL | 100 | true | false | false | true | accepted | |
| 0 | NULL | false | true | false | false | accepted | |
| 0 | NULL | false | true | true | false | accepted | |
| -20 | -5 | false | false | false | false | accepted | |
| 0 | 100 | false | false | true | true | accepted | |
| 10 | 100 | false | false | true | true | accepted | |
| -50 | 50 | false | false | true | true | accepted | |
| NULL | NULL | true | true | true | false | rejected | lower_included_valid (invariant) | 
| 0 | NULL | false | true | false | true | rejected | upper_included_valid (invariant) | 
| 200 | 100 | false | false | true | true | rejected | limits_consistent (invariant) | 
14.9.6.2. Test Case CONT-DV_INTERVAL_DV_COUNT-validate_lower_upper
Lower and upper are DV_COUNT, which are constrainted internally by C_INTEGER. C_INTEGER has range and list constraints.
| Note | the lower and upper limits are not constrained in terms of existence or occurrences, so both are optional. | 
| lower | upper | lower_unbounded | upper_unbounded | lower_included | upper_included | C_INTEGER.range (lower) | C_INTEGER.range (upper) | expected | constraints violated | 
|---|---|---|---|---|---|---|---|---|---|
| NULL | NULL | true | true | false | false | 0..100 | 0..100 | accepted | |
| 0 | NULL | false | true | true | false | 0..100 | 0..100 | accepted | |
| NULL | 100 | true | false | false | true | 0..100 | 0..100 | accepted | |
| 0 | 100 | false | false | true | true | 0..100 | 0..100 | accepted | |
| -10 | 100 | false | false | true | true | 0..100 | 0..100 | rejected | C_INTEGER.range (lower) | 
| 0 | 200 | false | false | true | true | 0..100 | 0..100 | rejected | C_INTEGER.range (upper) | 
| -10 | 200 | false | false | true | true | 0..100 | 0..100 | rejected | C_INTEGER.range (lower), C_INTEGER.range (upper) | 
14.9.6.3. Test Case CONT-DV_INTERVAL_DV_COUNT-validate_lower_upper_list
Lower and upper are DV_COUNT, which are constrainted internally by C_INTEGER. C_INTEGER has range and list constraints.
| Note | not all modeling tools allow a list constraint for the lower and upper attributes of the DV_INTERVAL. | 
| lower | upper | lower_unbounded | upper_unbounded | lower_included | upper_included | C_INTEGER.list (lower) | C_INTEGER.list (upper) | expected | constraints violated | 
|---|---|---|---|---|---|---|---|---|---|
| NULL | NULL | true | true | false | false | [0, 5, 10, 100] | [0, 5, 10, 100] | accepted | |
| 0 | NULL | false | true | true | false | [0, 5, 10, 100] | [0, 5, 10, 100] | accepted | |
| NULL | 100 | true | false | false | true | [0, 5, 10, 100] | [0, 5, 10, 100] | accepted | |
| 0 | 100 | false | false | true | true | [0, 5, 10, 100] | [0, 5, 10, 100] | accepted | |
| -10 | 100 | false | false | true | true | [0, 5, 10, 100] | [0, 5, 10, 100] | rejected | C_INTEGER.list (lower) | 
| 0 | 200 | false | false | true | true | [0, 5, 10, 100] | [0, 5, 10, 100] | rejected | C_INTEGER.list (upper) | 
| -10 | 200 | false | false | true | true | [0, 5, 10, 100] | [0, 5, 10, 100] | rejected | C_INTEGER.list (lower), C_INTEGER.list (upper) | 
14.9.7. DV_INTERVAL<DV_QUANTITY>
14.9.7.1. Test Case CONT-DV_INTERVAL_DV_QUANTITY-validate_open
The DV_INTERVAL<DV_QUANTITY> constraint is {*}.
| Note | the failure instance for this test case are related with violated interval semantics. | 
| lower | upper | lower_unbounded | upper_unbounded | lower_included | upper_included | expected | constraints violated | 
|---|---|---|---|---|---|---|---|
| NULL | NULL | true | true | false | false | accepted | |
| NULL | 100 mg | true | false | false | false | accepted | |
| NULL | 100 mg | true | false | false | true | accepted | |
| 0 mg | NULL | false | true | false | false | accepted | |
| 0 mg | NULL | false | true | true | false | accepted | |
| 0 mg | 100 mg | false | false | true | true | accepted | |
| 10 mg | 100 mg | false | false | true | true | accepted | |
| NULL | NULL | true | true | true | false | rejected | lower_included_valid (invariant) | 
| 0 mg | NULL | false | true | false | true | rejected | upper_included_valid (invariant) | 
| 200 mg | 100 mg | false | false | true | true | rejected | limits_consistent (invariant) | 
14.9.7.2. Test Case CONT-DV_INTERVAL_DV_QUANTITY-validate_upper_lower
The lower and upper constraints are C_DV_QUANTITY.
| Note | in all cases the C_DV_QUANTITY.property referes to temperatureto keep tests as simple as possible and be able to use negative values (for other physical properties negative values don’t make sense). All temperatures will be measured in degree Celsius (Celin UCUM). | 
| lower | upper | lower_unbounded | upper_unbounded | lower_included | upper_included | C_DV_QUANTITY.list (lower) | C_DV_QUANTITY.list (upper) | expected | constraints violated | 
|---|---|---|---|---|---|---|---|---|---|
| NULL | NULL | true | true | false | false | [0..100 Cel] | [0..100 Cel] | accepted | |
| 0 Cel | NULL | false | true | true | false | [0..100 Cel] | [0..100 Cel] | accepted | |
| NULL | 100 Cel | true | false | false | true | [0..100 Cel] | [0..100 Cel] | accepted | |
| 0 Cel | 100 Cel | false | false | true | true | [0..100 Cel] | [0..100 Cel] | accepted | |
| -10 Cel | 100 Cel | false | false | true | true | [0..100 Cel] | [0..100 Cel] | rejected | C_DV_QUANTITY (lower) | 
| 0 Cel | 200 Cel | false | false | true | true | [0..100 Cel] | [0..100 Cel] | rejected | C_DV_QUANTITY (upper) | 
| -10 Cel | 200 Cel | false | false | true | true | [0..100 Cel] | [0..100 Cel] | rejected | C_DV_QUANTITY (lower),C_DV_QUANTITY (upper) | 
14.9.8. DV_INTERVAL<DV_DATE_TIME>
14.9.8.1. Test Case CONT-DV_INTERVAL_DV_DATE_TIME-validate_open
The DV_INTERVAL<DV_DATE_TIME> constraint is {*}.
| lower | upper | lower_unbounded | upper_unbounded | lower_included | upper_included | expected | constraints violated | 
|---|---|---|---|---|---|---|---|
| NULL | NULL | false | false | true | true | rejected | RM/Schema: value is mandatory for lower and upper | 
| NULL | "" | false | false | true | true | rejected | RM/Schema: value is mandatory for lower. ISO8601: at least year is required for upper. | 
| "" | NULL | false | false | true | true | rejected | ISO8601: at least year is required for lower. RM/Schema: value is mandatory for upper. | 
| 2021 | NULL | false | false | true | true | rejected | RM/Schema: value is mandatory for upper. | 
| NULL | 2022 | false | false | true | true | rejected | RM/Schema: value is mandatory for lower. | 
| 2021 | 2022 | false | false | true | true | accepted | |
| 2021-00 | 2022-01 | false | false | true | true | rejected | ISO8601: month in 01..12 for lower. | 
| 2021-01 | 2022-01 | false | false | true | true | accepted | |
| 2021-01-00 | 2022-01-01 | false | false | true | true | rejected | ISO8601: day in 01..31 for lower. | 
| 2021-01-32 | 2022-01-01 | false | false | true | true | rejected | ISO8601: day in 01..31 for lower. | 
| 2021-01-01 | 2022-01-00 | false | false | true | true | rejected | ISO8601: day in 01..31 for upper. | 
| 2021-01-30 | 2022-01-00 | false | false | true | true | rejected | ISO8601: day in 01..31 for upper. | 
| 2021-01-30 | 2022-01-15 | false | false | true | true | accepted | |
| 2021-10-24T48 | 2022-01-15T10 | false | false | true | true | rejected | ISO8601: hours in 00..23 for lower. | 
| 2021-10-24T21 | 2022-01-15T73 | false | false | true | true | rejected | ISO8601: hours in 00..23 for upper. | 
| 2021-10-24T05 | 2022-01-15T10 | false | false | true | true | accepted | |
| 2021-10-24T05:95 | 2022-01-15T10:45 | false | false | true | true | rejected | ISO8601: minutes in 00..59 for lower. | 
| 2021-10-24T05:30 | 2022-01-15T10:61 | false | false | true | true | rejected | ISO8601: minutes in 00..59 for upper. | 
| 2021-10-24T05:30 | 2022-01-15T10:45 | false | false | true | true | accepted | |
| 2021-10-24T05:30:78 | 2022-01-15T10:45:13 | false | false | true | true | rejected | ISO8601: seconds in 00..59 for lower. | 
| 2021-10-24T05:30:47 | 2022-01-15T10:45:69 | false | false | true | true | rejected | ISO8601: seconds in 00..59 for upper. | 
| 2021-10-24T05:30:47 | 2022-01-15T10:45:13 | false | false | true | true | accepted | |
| 2021-10-24T05:30:47.5 | 2022-01-15T10:45:13.6 | false | false | true | true | accepted | |
| 2021-10-24T05:30:47.333 | 2022-01-15T10:45:13.555 | false | false | true | true | accepted | |
| 2021-10-24T05:30:47.333333 | 2022-01-15T10:45:13.555555 | false | false | true | true | accepted | |
| 2021-10-24T05:30:47Z | 2022-01-15T10:45:13Z | false | false | true | true | accepted | |
| 2021-10-24T05:30:47-03:00 | 2022-01-15T10:45:13-03:00 | false | false | true | true | accepted | 
14.9.8.2. Test Case CONT-DV_INTERVAL_DV_DATE_TIME-validate_lower_upper_constraint
| Note | the C_DATE_TIME has invariants that define if a higher precision component is optional or prohibited, lower precision components should be optional or prohibited. In other words, if monthis optional,day,hours,minutes, etc. are optional or prohibited. These invariants should be checked in an archetype editor and template editor, we consider the following tests to follow those rules without checking them, since that is related to archetype/template validation, not with data validation. | 
| Note | if different components of each lower/upper date time expression fail the validity constraint for mandatory, the only required contraint violated to be reported is the higher precision one, since it implies the lower precision components will also fail. For instance if the hour, second and millisecond aremandatory, and the corresponding date time expression doesn’t have hour, it is accepted if the reported constraints violated is only the hour_validity, and optionally the SUT can report the minute_validity, second_validity and millisecond_validity constraints as violated too. In the data sets below we show all the constraints violated. | 
| lower | upper | lower_unbounded | upper_unbounded | lower_included | upper_included | month_val. (lower) | day_val. (lower) | month_val. (upper) | day_val. (upper) | hour_val. (lower) | minute_val. (lower) | second_val. (lower) | millisecond_val. (lower) | timezone_val. (lower) | hour_val. (upper) | minute_val. (upper) | second_val. (upper) | millisecond_val. (upper) | timezone_val. (upper) | expected | constraints violated | 
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2021 | 2022 | false | false | true | true | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | rejected | month_val. (lower), day_val. (lower), month_val. (upper), day_val. (upper), hour_val. (lower), hour_val. (upper), minute_val. (lower), minute_val. (upper), second_val. (lower), second_val. (upper), millisecond_val. (lower), millisecond_val. (upper), timezone_val. (lower), timezone__val. (upper) | 
| 2021 | 2022 | false | false | true | true | mandatory | optional | mandatory | optional | optional | optional | optional | optional | mandatory | optional | optional | optional | optional | mandatory | rejected | month_validity (lower), month_validity (upper), timezone_val. (lower), timezone__val. (upper) | 
| 2021 | 2022 | false | false | true | true | mandatory | optional | mandatory | optional | optional | optional | optional | optional | optional | optional | optional | optional | optional | optional | rejected | month_validity (lower), month_validity (upper) | 
| 2021 | 2022 | false | false | true | true | optional | optional | optional | optional | optional | optional | optional | optional | mandatory | optional | optional | optional | optional | mandatory | rejected | timezone_val. (lower), timezone__val. (upper) | 
| 2021 | 2022 | false | false | true | true | optional | optional | optional | optional | optional | optional | optional | optional | optional | optional | optional | optional | optional | optional | accepted | |
| 2021 | 2022 | false | false | true | true | mandatory | prohibited | mandatory | prohibited | prohibited | prohibited | prohibited | prohibited | mandatory | prohibited | prohibited | prohibited | prohibited | mandatory | rejected | month_validity (lower), month_validity (upper), timezone_val. (lower), timezone__val. (upper) | 
| 2021 | 2022 | false | false | true | true | mandatory | prohibited | mandatory | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | month_validity (lower), month_validity (upper) | 
| 2021 | 2022 | false | false | true | true | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | mandatory | prohibited | prohibited | prohibited | prohibited | mandatory | rejected | timezone_val. (lower), timezone__val. (upper) | 
| 2021 | 2022 | false | false | true | true | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | accepted | |
| 2021-10 | 2022-10 | false | false | true | true | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | rejected | day_validity (lower), day_validity (upper), hour_val. (lower), hour_val. (upper), minute_val. (lower), minute_val. (upper), second_val. (lower), second_val. (upper), millisecond_val. (lower), millisecond_val. (upper), timezone_val. (lower), timezone__val. (upper) | 
| 2021-10 | 2022-10 | false | false | true | true | mandatory | optional | mandatory | optional | optional | optional | optional | optional | mandatory | optional | optional | optional | optional | mandatory | rejected | timezone_val. (lower), timezone_val. (upper) | 
| 2021-10 | 2022-10 | false | false | true | true | mandatory | optional | mandatory | optional | optional | optional | optional | optional | optional | optional | optional | optional | optional | optional | accepted | |
| 2021-10 | 2022-10 | false | false | true | true | mandatory | prohibited | mandatory | prohibited | prohibited | prohibited | prohibited | prohibited | mandatory | prohibited | prohibited | prohibited | mandatory | mandatory | rejected | timezone_val. (lower), timezone_val. (upper) | 
| 2021-10 | 2022-10 | false | false | true | true | mandatory | prohibited | mandatory | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | accepted | |
| 2021-10 | 2022-10 | false | false | true | true | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | mandatory | prohibited | prohibited | prohibited | prohibited | mandatory | rejected | month_validity (lower), month_validity (upper), timezone_val. (lower), timezone_val. (upper) | 
| 2021-10 | 2022-10 | false | false | true | true | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | month_validity (lower), month_validity (upper) | 
| lower | upper | lower_unbounded | upper_unbounded | lower_included | upper_included | month_val. (lower) | day_val. (lower) | month_val. (upper) | day_val. (upper) | hour_val. (lower) | minute_val. (lower) | second_val. (lower) | millisecond_val. (lower) | timezone_val. (lower) | hour_val. (upper) | minute_val. (upper) | second_val. (upper) | millisecond_val. (upper) | timezone_val. (upper) | expected | constraints violated | 
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2021-10-24 | 2022-10-24 | false | false | true | true | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | rejected | hour_val. (lower), hour_val. (upper), minute_val. (lower), minute_val. (upper), second_val. (lower), second_val. (upper), millisecond_val. (lower), millisecond_val. (upper), timezone_val. (lower), timezone_val. (upper) | 
| 2021-10-24 | 2022-10-24 | false | false | true | true | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | optional | optional | mandatory | mandatory | optional | optional | optional | mandatory | rejected | hour_val. (lower), hour_val. (upper), minute_val. (lower), minute_val. (upper), timezone_val. (lower), timezone_val. (upper) | 
| 2021-10-24 | 2022-10-24 | false | false | true | true | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | optional | optional | optional | mandatory | optional | optional | optional | optional | rejected | hour_val. (lower), hour_val. (upper), minute_val. (lower), minute_val. (upper) | 
| 2021-10-24 | 2022-10-24 | false | false | true | true | mandatory | optional | mandatory | optional | optional | optional | optional | optional | mandatory | optional | optional | optional | optional | mandatory | rejected | timezone_val. (lower), timezone__val. (upper) | 
| 2021-10-24 | 2022-10-24 | false | false | true | true | mandatory | optional | mandatory | optional | optional | optional | optional | optional | optional | optional | optional | optional | optional | optional | accepted | |
| 2021-10-24 | 2022-10-24 | false | false | true | true | optional | optional | optional | optional | optional | optional | optional | optional | mandatory | optional | optional | optional | optional | mandatory | rejected | timezone_val. (lower), timezone__val. (upper) | 
| 2021-10-24 | 2022-10-24 | false | false | true | true | mandatory | prohibited | mandatory | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | day_validity (lower), day_validity (upper) | 
| 2021-10-24 | 2022-10-24 | false | false | true | true | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | month_validity (lower), day_validity (lower), month_validity (upper), day_validity (upper) | 
| 2021-10-24T22 | 2022-10-24T07 | false | false | true | true | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | rejected | minute_val. (lower), minute_val. (upper), second_val. (lower), second_val. (upper), millisecond_val. (lower), millisecond_val. (upper), timezone_val. (lower), timezone_val. (upper) | 
| 2021-10-24T22 | 2022-10-24T07 | false | false | true | true | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | optional | optional | mandatory | mandatory | optional | optional | optional | mandatory | rejected | minute_val. (lower), minute_val. (upper), timezone_val. (lower), timezone_val. (upper) | 
| 2021-10-24T22 | 2022-10-24T07 | false | false | true | true | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | optional | optional | optional | mandatory | optional | optional | optional | optional | rejected | minute_val. (lower), minute_val. (upper) | 
| 2021-10-24T22 | 2022-10-24T07 | false | false | true | true | mandatory | optional | mandatory | optional | optional | optional | optional | optional | mandatory | optional | optional | optional | optional | mandatory | rejected | timezone_val. (lower), timezone__val. (upper) | 
| 2021-10-24T22 | 2022-10-24T07 | false | false | true | true | mandatory | optional | mandatory | optional | optional | optional | optional | optional | optional | optional | optional | optional | optional | optional | accepted | |
| 2021-10-24T22 | 2022-10-24T07 | false | false | true | true | optional | optional | optional | optional | optional | optional | optional | optional | mandatory | optional | optional | optional | optional | mandatory | rejected | timezone_val. (lower), timezone__val. (upper) | 
| 2021-10-24T22 | 2022-10-24T07 | false | false | true | true | mandatory | prohibited | mandatory | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | day_validity (lower), day_validity (upper), hour_val. (lower), hour_val. (upper) | 
| 2021-10-24T22 | 2022-10-24T07 | false | false | true | true | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | month_validity (lower), day_validity (lower), month_validity (upper), day_validity (upper), hour_val. (lower), hour_val. (upper) | 
| lower | upper | lower_unbounded | upper_unbounded | lower_included | upper_included | month_val. (lower) | day_val. (lower) | month_val. (upper) | day_val. (upper) | hour_val. (lower) | minute_val. (lower) | second_val. (lower) | millisecond_val. (lower) | timezone_val. (lower) | hour_val. (upper) | minute_val. (upper) | second_val. (upper) | millisecond_val. (upper) | timezone_val. (upper) | expected | constraints violated | 
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2021-10-24T22:10 | 2022-10-24T07:47 | false | false | true | true | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | rejected | second_val. (lower), second_val. (upper), millisecond_val. (lower), millisecond_val. (upper), timezone_val. (lower), timezone_val. (upper) | 
| 2021-10-24T22:10 | 2022-10-24T07:47 | false | false | true | true | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | optional | optional | mandatory | mandatory | optional | optional | optional | mandatory | rejected | timezone_val. (lower), timezone_val. (upper) | 
| 2021-10-24T22:10 | 2022-10-24T07:47 | false | false | true | true | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | optional | optional | optional | mandatory | optional | optional | optional | optional | accepted | |
| 2021-10-24T22:10 | 2022-10-24T07:47 | false | false | true | true | mandatory | optional | mandatory | optional | optional | optional | optional | optional | mandatory | optional | optional | optional | optional | mandatory | rejected | timezone_val. (lower), timezone__val. (upper) | 
| 2021-10-24T22:10 | 2022-10-24T07:47 | false | false | true | true | mandatory | optional | mandatory | optional | optional | optional | optional | optional | optional | optional | optional | optional | optional | optional | accepted | |
| 2021-10-24T22:10 | 2022-10-24T07:47 | false | false | true | true | optional | optional | optional | optional | optional | optional | optional | optional | mandatory | optional | optional | optional | optional | mandatory | rejected | timezone_val. (lower), timezone__val. (upper) | 
| 2021-10-24T22:10 | 2022-10-24T07:47 | false | false | true | true | mandatory | prohibited | mandatory | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | day_validity (lower), day_validity (upper), hour_val. (lower), hour_val. (upper), minute_val. (lower), minute_val. (upper) | 
| 2021-10-24T22:10 | 2022-10-24T07:47 | false | false | true | true | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | month_validity (lower), day_validity (lower), month_validity (upper), day_validity (upper), hour_val. (lower), hour_val. (upper), minute_val. (lower), minute_val. (upper) | 
| 2021-10-24T22:10:45 | 2022-10-24T07:47:13 | false | false | true | true | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | rejected | millisecond_val. (lower), millisecond_val. (upper), timezone_val. (lower), timezone_val. (upper) | 
| 2021-10-24T22:10:45 | 2022-10-24T07:47:13 | false | false | true | true | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | optional | optional | mandatory | mandatory | optional | optional | optional | mandatory | rejected | timezone_val. (lower), timezone_val. (upper) | 
| 2021-10-24T22:10:45 | 2022-10-24T07:47:13 | false | false | true | true | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | optional | optional | optional | mandatory | optional | optional | optional | optional | accepted | |
| 2021-10-24T22:10:45 | 2022-10-24T07:47:13 | false | false | true | true | mandatory | optional | mandatory | optional | optional | optional | optional | optional | mandatory | optional | optional | optional | optional | mandatory | rejected | timezone_val. (lower), timezone__val. (upper) | 
| 2021-10-24T22:10:45 | 2022-10-24T07:47:13 | false | false | true | true | mandatory | optional | mandatory | optional | optional | optional | optional | optional | optional | optional | optional | optional | optional | optional | accepted | |
| 2021-10-24T22:10:45 | 2022-10-24T07:47:13 | false | false | true | true | optional | optional | optional | optional | optional | optional | optional | optional | mandatory | optional | optional | optional | optional | mandatory | rejected | timezone_val. (lower), timezone__val. (upper) | 
| 2021-10-24T22:10:45 | 2022-10-24T07:47:13 | false | false | true | true | mandatory | prohibited | mandatory | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | day_validity (lower), day_validity (upper), hour_val. (lower), hour_val. (upper), minute_val. (lower), minute_val. (upper), second_val. (lower), second_val. (upper) | 
| 2021-10-24T22:10:45 | 2022-10-24T07:47:13 | false | false | true | true | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | month_validity (lower), day_validity (lower), month_validity (upper), day_validity (upper), hour_val. (lower), hour_val. (upper), minute_val. (lower), minute_val. (upper), second_val. (lower), second_val. (upper) | 
| lower | upper | lower_unbounded | upper_unbounded | lower_included | upper_included | month_val. (lower) | day_val. (lower) | month_val. (upper) | day_val. (upper) | hour_val. (lower) | minute_val. (lower) | second_val. (lower) | millisecond_val. (lower) | timezone_val. (lower) | hour_val. (upper) | minute_val. (upper) | second_val. (upper) | millisecond_val. (upper) | timezone_val. (upper) | expected | constraints violated | 
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2021-10-24T22:10:45.5 | 2022-10-24T07:47:13.666666 | false | false | true | true | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | rejected | timezone_val. (lower), timezone_val. (upper) | 
| 2021-10-24T22:10:45.5 | 2022-10-24T07:47:13.666666 | false | false | true | true | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | optional | optional | mandatory | mandatory | optional | optional | optional | mandatory | rejected | timezone_val. (lower), timezone_val. (upper) | 
| 2021-10-24T22:10:45.5 | 2022-10-24T07:47:13.666666 | false | false | true | true | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | optional | optional | optional | mandatory | optional | optional | optional | optional | accepted | |
| 2021-10-24T22:10:45.5 | 2022-10-24T07:47:13.666666 | false | false | true | true | mandatory | optional | mandatory | optional | optional | optional | optional | optional | mandatory | optional | optional | optional | optional | mandatory | rejected | timezone_val. (lower), timezone__val. (upper) | 
| 2021-10-24T22:10:45.5 | 2022-10-24T07:47:13.666666 | false | false | true | true | mandatory | optional | mandatory | optional | optional | optional | optional | optional | optional | optional | optional | optional | optional | optional | accepted | |
| 2021-10-24T22:10:45.5 | 2022-10-24T07:47:13.666666 | false | false | true | true | optional | optional | optional | optional | optional | optional | optional | optional | mandatory | optional | optional | optional | optional | mandatory | rejected | timezone_val. (lower), timezone__val. (upper) | 
| 2021-10-24T22:10:45.5 | 2022-10-24T07:47:13.666666 | false | false | true | true | mandatory | prohibited | mandatory | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | day_validity (lower), day_validity (upper), hour_val. (lower), hour_val. (upper), minute_val. (lower), minute_val. (upper), seoncd_val. (lower), second_val. (upper), millisecond_val. (lower), millisecond_val. (upper) | 
| 2021-10-24T22:10:45.5 | 2022-10-24T07:47:13.666666 | false | false | true | true | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | month_validity (lower), day_validity (lower), month_validity (upper), day_validity (upper), hour_val. (lower), hour_val. (upper), minute_val. (lower), minute_val. (upper), seoncd_val. (lower), second_val. (upper), millisecond_val. (lower), millisecond_val. (upper) | 
| 2021-10-24T22:10:45Z | 2022-10-24T07:47:13Z | false | false | true | true | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | rejected | millisecond_val. (lower), millisecond_val. (upper) | 
| 2021-10-24T22:10:45Z | 2022-10-24T07:47:13Z | false | false | true | true | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | optional | optional | mandatory | mandatory | optional | optional | optional | mandatory | accepted | |
| 2021-10-24T22:10:45Z | 2022-10-24T07:47:13Z | false | false | true | true | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | optional | optional | optional | mandatory | optional | optional | optional | optional | accepted | |
| 2021-10-24T22:10:45Z | 2022-10-24T07:47:13Z | false | false | true | true | mandatory | optional | mandatory | optional | optional | optional | optional | optional | mandatory | optional | optional | optional | optional | mandatory | accepted | |
| 2021-10-24T22:10:45Z | 2022-10-24T07:47:13Z | false | false | true | true | mandatory | optional | mandatory | optional | optional | optional | optional | optional | optional | optional | optional | optional | optional | optional | accepted | |
| 2021-10-24T22:10:45Z | 2022-10-24T07:47:13Z | false | false | true | true | optional | optional | optional | optional | optional | optional | optional | optional | mandatory | optional | optional | optional | optional | mandatory | accepted | |
| 2021-10-24T22:10:45Z | 2022-10-24T07:47:13Z | false | false | true | true | mandatory | prohibited | mandatory | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | day_validity (lower), day_validity (upper), hour_val. (lower), hour_val. (upper), minute_val. (lower), minute_val. (upper), second_val. (lower), second_val. (upper), timezone_val. (lower), timezone_val. (upper) | 
| 2021-10-24T22:10:45Z | 2022-10-24T07:47:13Z | false | false | true | true | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | month_validity (lower), day_validity (lower), month_validity (upper), day_validity (upper), hour_val. (lower), hour_val. (upper), minute_val. (lower), minute_val. (upper), second_val. (lower), second_val. (upper), timezone_val. (lower), timezone_val. (upper) | 
14.9.8.3. Test Case CONT-DV_INTERVAL_DV_DATE_TIME-validate_lower_upper_range
| lower | upper | lower_unbounded | upper_unbounded | lower_included | upper_included | C_DATE_TIME.range (lower) | C_DATE_TIME.range (upper) | expected | constraints violated | 
|---|---|---|---|---|---|---|---|---|---|
| 2021 | 2022 | false | false | true | true | 2020..2030 | 2020..2030 | accepted | |
| 2021 | 2022 | false | false | true | true | 2000..2010 | 2020..2030 | rejected | C_DATE_TIME.range (lower) | 
| 2021 | 2022 | false | false | true | true | 2020..2030 | 2020..2021 | rejected | C_DATE_TIME.range (upper) | 
| 2021-10 | 2022-11 | false | false | true | true | 2020-01..2030-12 | 2020-01..2030-12 | accepted | |
| 2021-10 | 2022-11 | false | false | true | true | 2000-01..2010-12 | 2020-01..2030-12 | rejected | C_DATE_TIME.range (lower) | 
| 2021-10 | 2022-11 | false | false | true | true | 2020-01..2030-12 | 2020-01..2021-12 | rejected | C_DATE_TIME.range (upper) | 
| 2021-10-24 | 2022-11-02 | false | false | true | true | 2020-01-01..2030-12-31 | 2020-01-01..2030-12-31 | accepted | |
| 2021-10-24 | 2022-11-02 | false | false | true | true | 2000-01-01..2010-12-31 | 2020-01-01..2030-12-31 | rejected | C_DATE_TIME.range (lower) | 
| 2021-10-24 | 2022-11-02 | false | false | true | true | 2020-01-01..2030-12-31 | 2020-01-01..2021-12-31 | rejected | C_DATE_TIME.range (upper) | 
| 2021-10-24T10 | 2022-11-02T19 | false | false | true | true | 2020-01-01T00..2030-12-31T23 | 2020-01-01T00..2030-12-31T23 | accepted | |
| 2021-10-24T10 | 2022-11-02T19 | false | false | true | true | 2000-01-01T00..2010-12-31T23 | 2020-01-01T00..2030-12-31T23 | rejected | C_DATE_TIME.range (lower) | 
| 2021-10-24T10 | 2022-11-02T19 | false | false | true | true | 2020-01-01T00..2030-12-31T23 | 2020-01-01T00..2021-12-31T23 | rejected | C_DATE_TIME.range (upper) | 
| 2021-10-24T10:00 | 2022-11-02T19:32 | false | false | true | true | 2020-01-01T00:00..2030-12-31T23:59 | 2020-01-01T00:00..2030-12-31T23:59 | accepted | |
| 2021-10-24T10:00 | 2022-11-02T19:32 | false | false | true | true | 2000-01-01T00:00..2010-12-31T23:59 | 2020-01-01T00:00..2030-12-31T23:59 | rejected | C_DATE_TIME.range (lower) | 
| 2021-10-24T10:00 | 2022-11-02T19:32 | false | false | true | true | 2020-01-01T00:00..2030-12-31T23:59 | 2020-01-01T00:00..2021-12-31T23:59 | rejected | C_DATE_TIME.range (upper) | 
| 2021-10-24T10:00:10 | 2022-11-02T19:32:40 | false | false | true | true | 2020-01-01T00:00:00..2030-12-31T23:59:59 | 2020-01-01T00:00..2030-12-31T23:59 | accepted | |
| 2021-10-24T10:00:10 | 2022-11-02T19:32:40 | false | false | true | true | 2000-01-01T00:00:00..2010-12-31T23:59:59 | 2020-01-01T00:00..2030-12-31T23:59 | rejected | C_DATE_TIME.range (lower) | 
| 2021-10-24T10:00:10 | 2022-11-02T19:32:40 | false | false | true | true | 2020-01-01T00:00:00..2030-12-31T23:59:59 | 2020-01-01T00:00..2021-12-31T23:59 | rejected | C_DATE_TIME.range (upper) | 
| 2021-10-24T10:00:10.5 | 2022-11-02T19:32:40.333 | false | false | true | true | 2020-01-01T00:00:00.0..2030-12-31T23:59:59.999999 | 2020-01-01T00:00..2030-12-31T23:59 | accepted | |
| 2021-10-24T10:00:10.5 | 2022-11-02T19:32:40.333 | false | false | true | true | 2000-01-01T00:00:00.0..2010-12-31T23:59:59.999999 | 2020-01-01T00:00..2030-12-31T23:59 | rejected | C_DATE_TIME.range (lower) | 
| 2021-10-24T10:00:10.5 | 2022-11-02T19:32:40.333 | false | false | true | true | 2020-01-01T00:00:00.0..2030-12-31T23:59:59.999999 | 2020-01-01T00:00..2021-12-31T23:59 | rejected | C_DATE_TIME.range (upper) | 
| 2021-10-24T10:00:10Z | 2022-11-02T19:32:40Z | false | false | true | true | 2020-01-01T00:00:00Z..2030-12-31T23:59:59Z | 2020-01-01T00:00..2030-12-31T23:59 | accepted | |
| 2021-10-24T10:00:10Z | 2022-11-02T19:32:40Z | false | false | true | true | 2000-01-01T00:00:00Z..2010-12-31T23:59:59Z | 2020-01-01T00:00..2030-12-31T23:59 | rejected | C_DATE_TIME.range (lower) | 
| 2021-10-24T10:00:10Z | 2022-11-02T19:32:40Z | false | false | true | true | 2020-01-01T00:00:00Z..2030-12-31T23:59:59Z | 2020-01-01T00:00..2021-12-31T23:59 | rejected | C_DATE_TIME.range (upper) | 
14.9.9. DV_INTERVAL<DV_DATE>
14.9.9.1. Test Case CONT-DV_INTERVAL_DV_DATE-validate_open
On this case, the own rules/invariants of the DV_INTERVAL apply to the validation.
| lower | upper | lower_unbounded | upper_unbounded | lower_included | upper_included | expected | constraints violated | 
|---|---|---|---|---|---|---|---|
| NULL | NULL | false | false | true | true | rejected | IMO should fail, see https://discourse.openehr.org/t/is-dv-interval-missing-invariants/2210 | 
| NULL | 2022 | false | false | true | true | rejected | IMO should fail, see https://discourse.openehr.org/t/is-dv-interval-missing-invariants/2210 | 
| 2021 | NULL | false | false | true | true | rejected | IMO should fail, see https://discourse.openehr.org/t/is-dv-interval-missing-invariants/2210 | 
| 2021 | 2022 | false | false | true | true | accepted | |
| 2021-01 | 2022-08 | false | false | true | true | accepted | |
| 2021-01-20 | 2022-08-11 | false | false | true | true | accepted | |
| 2021 | 2021-10 | false | false | true | true | rejected | IMO two dates with different components and common higher order components (year on this case) shouldn’t be strictly comparable, see https://discourse.openehr.org/t/issues-with-date-time-comparison-for-partial-date-time-expressions/2173 | 
| NULL | NULL | true | true | false | false | accepted | 
14.9.9.2. Test Case CONT-DV_INTERVAL_DV_DATE-validate_lower_upper_constraint
| Note | this test case doesn’t include all the possible combinations of lower/upper data and constraints for the internal since there could be tens of possible combinations. It would be in the scope of a revision to add more combinations of an exhaustive test case. | 
| Note | the C_DATE has invariants that define if a higher precision component is optional or prohibited, lower precision components should be optional or prohibited. In other words, if monthis optional,dayshould be optional or prohibited. These invariants should be checked in an archetype editor and template editor, we consider the following tests to follow those rules without checking them, since that is related to archetype/template validation, not with data validation. | 
| lower | upper | lower_unbounded | upper_unbounded | lower_included | upper_included | month_val. (lower) | day_val. (lower) | month_val. (upper) | day_val. (upper) | expected | constraints violated | 
|---|---|---|---|---|---|---|---|---|---|---|---|
| 2021 | 2022 | false | false | true | true | mandatory | mandatory | mandatory | mandatory | rejected | month_validity (lower), day_validity (lower), month_validity (upper), day_validity (upper) | 
| 2021 | 2022 | false | false | true | true | mandatory | optional | mandatory | optional | rejected | month_validity (lower), month_validity (upper) | 
| 2021 | 2022 | false | false | true | true | optional | optional | optional | optional | accepted | |
| 2021 | 2022 | false | false | true | true | mandatory | prohibited | mandatory | prohibited | rejected | month_validity (lower), month_validity (upper) | 
| 2021 | 2022 | false | false | true | true | prohibited | prohibited | prohibited | prohibited | accepted | |
| 2021-10 | 2022-10 | false | false | true | true | mandatory | mandatory | mandatory | mandatory | rejected | day_validity (lower), day_validity (upper) | 
| 2021-10 | 2022-10 | false | false | true | true | mandatory | optional | mandatory | optional | accepted | |
| 2021-10 | 2022-10 | false | false | true | true | optional | optional | optional | optional | accepted | |
| 2021-10 | 2022-10 | false | false | true | true | mandatory | prohibited | mandatory | prohibited | accepted | |
| 2021-10 | 2022-10 | false | false | true | true | prohibited | prohibited | prohibited | prohibited | rejected | month_validity (lower), month_validity (upper) | 
| 2021-10-24 | 2022-10-24 | false | false | true | true | mandatory | mandatory | mandatory | mandatory | accepted | |
| 2021-10-24 | 2022-10-24 | false | false | true | true | mandatory | optional | mandatory | optional | accepted | |
| 2021-10-24 | 2022-10-24 | false | false | true | true | optional | optional | optional | optional | accepted | |
| 2021-10-24 | 2022-10-24 | false | false | true | true | mandatory | prohibited | mandatory | prohibited | rejected | day_validity (lower), day_validity (upper) | 
| 2021-10-24 | 2022-10-24 | false | false | true | true | prohibited | prohibited | prohibited | prohibited | rejected | month_validity (lower), day_validity (lower), month_validity (upper), day_validity (upper) | 
| 2021 | 2022 | false | false | true | true | mandatory | mandatory | mandatory | optional | rejected | month_validity (lower), day_validity (lower), month_validity (upper) | 
| 2021 | 2022 | false | false | true | true | mandatory | mandatory | optional | optional | rejected | month_validity (lower), day_validity (lower) | 
| 2021 | 2022 | false | false | true | true | mandatory | mandatory | mandatory | prohibited | rejected | month_validity (lower), day_validity (lower), month_validity (upper) | 
| 2021 | 2022 | false | false | true | true | mandatory | mandatory | prohibited | prohibited | rejected | month_validity (lower), day_validity (lower) | 
| 2021 | 2022-10 | false | false | true | true | mandatory | mandatory | mandatory | mandatory | rejected | month_validity (lower), day_validity (lower), day_validity (upper) | 
| 2021 | 2022-10 | false | false | true | true | mandatory | mandatory | mandatory | optional | rejected | month_validity (lower), day_validity (lower) | 
| 2021 | 2022-10 | false | false | true | true | mandatory | mandatory | optional | optional | rejected | month_validity (lower), day_validity (lower) | 
| 2021 | 2022-10 | false | false | true | true | mandatory | mandatory | mandatory | prohibited | rejected | month_validity (lower), day_validity (lower) | 
| 2021 | 2022-10 | false | false | true | true | mandatory | mandatory | prohibited | prohibited | rejected | month_validity (lower), day_validity (lower), month_validity (upper) | 
| 2021 | 2022-10-24 | false | false | true | true | mandatory | mandatory | mandatory | mandatory | rejected | month_validity (lower), day_validity (lower) | 
| 2021 | 2022-10-24 | false | false | true | true | mandatory | mandatory | mandatory | optional | rejected | month_validity (lower), day_validity (lower) | 
| 2021 | 2022-10-24 | false | false | true | true | mandatory | mandatory | optional | optional | rejected | month_validity (lower), day_validity (lower) | 
| 2021 | 2022-10-24 | false | false | true | true | mandatory | mandatory | mandatory | prohibited | rejected | month_validity (lower), day_validity (lower), day_validity (upper) | 
| 2021 | 2022-10-24 | false | false | true | true | mandatory | mandatory | prohibited | prohibited | rejected | month_validity (lower), day_validity (lower), month_validity (upper), day_validity (upper) | 
14.9.9.3. Test Case CONT-DV_INTERVAL_DV_DATE-validate_lower_upper_range
| lower | upper | lower_unbounded | upper_unbounded | lower_included | upper_included | C_DATE.range (lower) | C_DATE.range (upper) | expected | constraints violated | 
|---|---|---|---|---|---|---|---|---|---|
| 2021 | 2022 | false | false | true | true | 1900..2030 | 1900..2030 | accepted | |
| 2021 | 2022 | false | false | true | true | 2022..2030 | 1900..2030 | rejected | C_DATE.range (lower) | 
| 2021 | 2022 | false | false | true | true | 1900..2030 | 2023..2030 | rejected | C_DATE.range (upper) | 
| 2021 | 2022 | false | false | true | true | 2022..2030 | 2023..2030 | rejected | C_DATE.range (lower), C_DATE.range (upper) | 
14.9.10. DV_INTERVAL<DV_TIME>
14.9.10.1. Test Case CONT-DV_INTERVAL_DV_TIME-validate_open
| lower | upper | lower_unbounded | upper_unbounded | lower_included | upper_included | expected | constraints violated | 
|---|---|---|---|---|---|---|---|
| NULL | NULL | false | false | true | true | rejected | IMO should fail, see https://discourse.openehr.org/t/is-dv-interval-missing-invariants/2210 | 
| NULL | T11:00:00 | false | false | true | true | rejected | IMO should fail, see https://discourse.openehr.org/t/is-dv-interval-missing-invariants/2210 | 
| T10:00:00 | NULL | false | false | true | true | rejected | IMO should fail, see https://discourse.openehr.org/t/is-dv-interval-missing-invariants/2210 | 
| T10 | T11 | false | false | true | true | accepted | |
| T10:00 | T11:00 | false | false | true | true | accepted | |
| T10:00:00 | T11:00:00 | false | false | true | true | accepted | |
| T10 | T10:45:00 | false | false | true | true | rejected | IMO two times with different components and common higher order components (hour on this case) shouldn’t be strictly comparable, see https://discourse.openehr.org/t/issues-with-date-time-comparison-for-partial-date-time-expressions/2173 | 
| NULL | NULL | true | true | false | false | accepted | 
14.9.10.2. Test Case CONT-DV_INTERVAL_DV_TIME-validate_lower_upper_constraint
| lower | upper | lower_unbounded | upper_unbounded | lower_included | upper_included | minute_val. (lower) | second_val. (lower) | millisecond_val. (lower) | timezone_val. (lower) | minute_val. (upper) | second_val. (upper) | millisecond_val. (upper) | timezone_val. (upper) | expected | constraints violated | 
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| T10 | T11 | false | false | true | true | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | rejected | minute_val. (lower), second_val. (lower), millisecond_val. (lower), timezone_val. (lower), minute_val. (upper), second_val. (upper), millisecond_val. (upper), timezone_val. (upper) | 
| T10:00 | T11:00 | false | false | true | true | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | rejected | second_val. (lower), millisecond_val. (lower), timezone_val. (lower), second_val. (upper), millisecond_val. (upper), timezone_val. (upper) | 
| T10:00:00 | T11:00:00 | false | false | true | true | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | rejected | millisecond_val. (lower), timezone_val. (lower), millisecond_val. (upper), timezone_val. (upper) | 
| T10:00:00.5 | T11:00:00.5 | false | false | true | true | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | rejected | timezone_val. (lower) timezone_val. (upper) | 
| T10:00:00.5Z | T11:00:00.5Z | false | false | true | true | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | accepted | 
TBD: combinations of other values for validity.
14.9.10.3. Test Case CONT-DV_INTERVAL_DV_TIME-validate_lower_upper_range
| lower | upper | lower_unbounded | upper_unbounded | lower_included | upper_included | C_TIME.range (lower) | C_TIME.range (upper) | expected | constraints violated | 
|---|---|---|---|---|---|---|---|---|---|
| T10 | T11 | false | false | true | true | T09..T11 | T10..T12 | accepted | |
| T10:00 | T11:00 | false | false | true | true | T09:00..T11:00 | T10:00..T12:00 | accepted | |
| T10:00:00 | T11:00:00 | false | false | true | true | T09:00:00..T11:00:00 | T10:00:00..T12:00:00 | accepted | |
| T10:00:00.5 | T11:00:00.5 | false | false | true | true | T09:00:00.0..T11:00:00.0 | T10:00:00.0..T12:00:00.0 | accepted | |
| T10:00:00.5Z | T11:00:00.5Z | false | false | true | true | T09:00:00.0..T11:00:00.0Z | T10:00:00.0Z..T12:00:00.0Z | accepted | |
| T10 | T11 | false | false | true | true | T11..T12 | T11..T12 | rejected | C_TIME.range (lower) | 
| T10 | T12 | false | false | true | true | T10..T11 | T10..T11 | rejected | C_TIME.range (upper) | 
| null | T11 | true | false | false | true | T09..T11 | T10..T12 | rejected | C_TIME.range (lower) | 
| T10 | null | false | true | true | false | T09..T11 | T10..T12 | accepted | C_TIME.range (upper) | 
14.9.11. DV_INTERVAL<DV_DURATION>
14.9.11.1. Test Case CONT-DV_INTERVAL_DV_DURATION-validate_open
| Note | this considers the lowervalue of the interval should have all it’s components lower or equals to the corresponding component in theuppervalue. This is to avoid normalization problems. For instance we could have an intervalP1Y6M..P2Ywhich is semantically correct. But if we have values outside the normal boundaries of each component, likeP1Y37M..P2Ythere is a need of normalization to know ifP1Y37Mis really lower or equals toP2Y, which is the check ofr a valid internal. In some cases this normalization is doable, but in other cases it is not. For instance, some implementations might not know how many days in a month are, since months have a variable number of days. In the previous case, we know each year has 12 months soP1Y37Mcan actually be normalized toP4Y1M, butP61Dcan’t be strictly compared with, let’s say,P3M, since months could have 28, 29, 30 or 31 days, so without other informationP61Dcould be lower or greater thanP3M. To simplify this, some implementations might consider the measure of amonth, in a duration expression, to be exactly 30 days. These considerations should be stated in the SUT Conformance Statement Document. To simplify writing the test cases for any implementation, we consider iflowerisP1Y37M, the validuppervalues have Y >= 1 and M >= 37, soP2Ywouldn’t be valid in this context, butP1Y37M..P1Y38MorP1Y37M..P2Y37Mwould be valid intervals for the test cases. One extra simplification would be to consider values are inside their normal boundaries (hours < 24, days < 31, etc.) but this won’t be encouraged but these test cases. If each component is inside it’s constrainsts it is possible to compare expressions that differ in the components likeP1D3HandP10D, since comparison doesn’t require normalization and both values form a semantically valid interval. | 
| lower | upper | lower_unbounded | upper_unbounded | lower_included | upper_included | expected | constraints violated | comment | 
|---|---|---|---|---|---|---|---|---|
| NULL | NULL | false | false | true | true | rejected | IMO should fail, see https://discourse.openehr.org/t/is-dv-interval-missing-invariants/2210 | |
| NULL | PT2H | false | false | true | true | rejected | IMO should fail, see https://discourse.openehr.org/t/is-dv-interval-missing-invariants/2210 | |
| PT1H | NULL | false | false | true | true | rejected | IMO should fail, see https://discourse.openehr.org/t/is-dv-interval-missing-invariants/2210 | |
| PT1H | PT2H | false | false | true | true | accepted | ||
| PT1H | PT2H | false | false | true | true | accepted | ||
| P1Y7M3D | P1Y8M3D | false | false | true | true | accepted | ||
| P1M5DT3H | P10M | false | false | true | true | accepted | See Note 1. | |
| P2M | P1M | false | false | true | true | rejected | limits_consistent (invariant) | |
| P10M | P1M5DT3H | false | false | true | true | rejected | limits_consistent (invariant) | 
Notes:
- 
this case has different components in the lower and upper values, this is possible because the values don’t exceed their normal boundaries, e.g. days31. Without this condition a normalization of the values would be needed, and in some cases the normalization is not possible without some extra constraints, for instance consideringP1Mis equivalent toP30D.
14.9.11.2. Test Case CONT-DV_INTERVAL_DV_DURATION-validate_constraint
| Note | in the openEHR specifications only the seconds can have a fraction, but in the ISO8601 standard, the component at the lowest precision can have a fraction, for instance P0.5Yis a valid ISO 8601 duration. | 
| lower | upper | lower_ unbounded | upper_ unbounded | lower_ included | upper_ included | years_ allowed (lower) | months_ allowed (lower) | weeks_ allowed (lower) | days_ allowed (lower) | hours_ allowed (lower) | minutes_ allowed (lower) | seconds_ allowed (lower) | fractional_ seconds_ allowed (lower) | years_ allowed (upper) | months_ allowed (upper) | weeks_ allowed (upper) | days_ allowed (upper) | hours_ allowed (upper) | minutes_ allowed (upper) | seconds_ allowed (upper) | fractional_ seconds_ allowed (upper) | expected | constraints violated | comment | 
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| P1Y | P2Y | false | false | true | true | true | true | true | true | true | true | true | true | true | true | true | true | true | true | true | true | accepted | ||
| P3W | P5W | false | false | true | true | true | true | true | true | true | true | true | true | true | true | true | true | true | true | true | true | accepted | ||
| P1Y | P2Y | false | false | true | true | false | true | true | true | true | true | true | true | true | true | true | true | true | true | true | true | rejected | years_allowed (lower) | |
| P1Y | P2Y | false | false | true | true | true | true | true | true | true | true | true | true | false | true | true | true | true | true | true | true | rejected | years_allowed (upper) | |
| P1Y1M1DT1H1M1.5S | P2Y | false | false | true | true | true | false | true | true | true | true | true | true | true | true | true | true | true | true | true | true | rejected | months_allowed (lower) | |
| P2W | P2Y | false | false | true | true | true | true | false | true | true | true | true | true | true | true | true | true | true | true | true | true | rejected | weeks_allowed (lower) | |
| P1Y1M1DT1H1M1.5S | P2Y | false | false | true | true | true | true | true | false | true | true | true | true | true | true | true | true | true | true | true | true | rejected | days_allowed (lower) | |
| P1Y1M1DT1H1M1.5S | P2Y | false | false | true | true | true | true | true | true | false | true | true | true | true | true | true | true | true | true | true | true | rejected | hours_allowed (lower) | |
| P1Y1M1DT1H1M1.5S | P2Y | false | false | true | true | true | true | true | true | true | false | true | true | true | true | true | true | true | true | true | true | rejected | minutes_allowed (lower) | |
| P1Y1M1DT1H1M1.5S | P2Y | false | false | true | true | true | true | true | true | true | true | false | true | true | true | true | true | true | true | true | true | rejected | seconds_allowed (lower) | |
| P1Y1M1DT1H1M1.5S | P2Y | false | false | true | true | true | true | true | true | true | true | true | false | true | true | true | true | true | true | true | true | rejected | fractional_seconds_allowed (lower) | 
14.9.11.3. Test Case CONT-DV_INTERVAL_DV_DURATION-validate_range
| lower | upper | lower_unbounded | upper_unbounded | lower_included | upper_included | range.lower (lower) | range.upper (lower) | range.lower (upper) | range.upper (upper) | expected | constraints violated | comment | 
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| P1Y | P2Y | false | false | true | true | P1Y | P3Y | P1Y | P3Y | accepted | ||
| P1Y | P2Y | false | false | true | true | P2Y | P3Y | P1Y | P3Y | rejected | range.lower (lower) | |
| P1Y | P2Y | false | false | true | true | P1Y | P3Y | P3Y | P4Y | rejected | range.lower (upper) | |
| P5Y | P10Y | false | false | true | true | P2Y | P3Y | P5Y | P15Y | rejected | range.upper (lower) | |
| P5Y | P10Y | false | false | true | true | P1Y | P9Y | P3Y | P9Y | rejected | range.upper (upper) | |
| P5Y4M | P10Y | false | false | true | true | P1Y | P9Y | P3Y | P15Y | accepted | ||
| P5Y4M | P10Y | false | false | true | true | P6Y | P9Y | P3Y | P15Y | rejected | range.lower (lower) | |
| P5Y4M | P10Y | false | false | true | true | P5Y4M2D | P9Y | P3Y | P15Y | rejected | range.lower (lower) | |
| P5Y4M20D | P10Y | false | false | true | true | P1Y | P9Y | P3Y | P15Y | accepted | ||
| P5Y4M20D | P10Y | false | false | true | true | P5Y6M | P9Y | P3Y | P15Y | rejected | range.lower (lower) | 
14.9.12. DV_INTERVAL<DV_ORDINAL>
| Note | some modeling tools don’t support representing DV_INTERVAL<DV_ORDINAL>. | 
14.9.12.1. Test Case CONT-DV_INTERVAL_DV_ORDINAL-validate_open
This case is when the ADL has DV_ORDINAL matches {*}
| lower.symbol | lower.value | upper.symbol | upper.value | lower_unbounded | upper_unbounded | lower_included | upper_included | expected | constraints violated | 
|---|---|---|---|---|---|---|---|---|---|
| NULL | NULL | NULL | NULL | false | false | true | true | rejected | RM/Schema value and symbol are mandatory for lower and upper | 
| NULL | 1 | NULL | 5 | false | false | true | true | rejected | RM/Schema symbol is mandatory for lower and upper | 
| local::at0005 | NULL | local::at0003 | NULL | false | false | true | true | rejected | RM/Schema value is mandatory for lower and upper | 
| local::at0005 | 1 | local::at0002 | 5 | false | false | true | true | accepted | |
| local::at0004 | 666 | local::at0003 | 777 | false | false | true | true | accepted | |
| local::at0003 | 777 | local::at0004 | 666 | false | false | true | true | rejected | RM invariante Interval.Limits_comparable | 
14.9.12.2. Test Case CONT-DV_INTERVAL_DV_ORDINAL-validate_constraint
| lower.symbol | lower.value | upper.symbol | upper.value | lower_unbounded | upper_unbounded | lower_included | upper_included | lower.C_DV_ORDINAL.list | upper.C_DV_ORDINAL.list | expected | constraints violated | 
|---|---|---|---|---|---|---|---|---|---|---|---|
| local::at0005 | 1 | local::at0002 | 5 | false | false | true | true | 1|[local::at0005], 2|[local::at0006] | 5|[local::at0002], 2|[local::at0006] | accepted | |
| local::at0004 | 666 | local::at0003 | 777 | false | false | true | true | 8|[local::at0004], 2|[local::at0006] | 9|[local::at0003], 2|[local::at0006] | rejected | C_DV_ORDINAL.list: no matching value for lower and upper | 
| local::at0666 | 1 | local::at0777 | 2 | false | false | true | true | 1|[local::at0005], 2|[local::at0006] | 1|[local::at0005], 2|[local::at0006] | rejected | C_DV_ORDINAL.list: no matching symbol for lower and upper | 
| local::at0004 | 666 | local::at0003 | 777 | false | false | true | true | 8|[local::at0004], 2|[local::at0006] | 777|[local::at0003], 2|[local::at0006] | rejected | C_DV_ORDINAL.list: no matching value for lower | 
| local::at0666 | 1 | local::at0777 | 2 | false | false | true | true | 1|[local::at0005], 2|[local::at0006] | 1|[local::at0005], 2|[local::at0777] | rejected | C_DV_ORDINAL.list: no matching symbol for lower | 
| local::at0004 | 666 | local::at0003 | 777 | false | false | true | true | 666|[local::at0004], 2|[local::at0006] | 9|[local::at0003], 2|[local::at0006] | rejected | C_DV_ORDINAL.list: no matching value for upper | 
| local::at0005 | 1 | local::at0777 | 5 | false | false | true | true | 1|[local::at0005], 2|[local::at0006] | 1|[local::at0005], 5|[local::at0999] | rejected | C_DV_ORDINAL.list: no matching symbol for upper | 
14.9.13. DV_INTERVAL<DV_SCALE>
DV_SCALE was introduced to the RM 1.1.0 (Discourse discussion), it is analogous to DV_ORDINAL with a Real value. So test cases for DV_SCALE and DV_ORDINAL are similar.
| Note | if this specification is implemented on a system that supports a RM < 1.1.0, then these tests shouldn’t run against the system. | 
| Note | some modeling tools don’t support representing DV_INTERVAL<DV_SCALE> | 
14.9.13.1. Test Case CONT-DV_INTERVAL_DV_SCALE-validate_open
This case is when the ADL has DV_ORDINAL matches {*}
| lower.symbol | lower.value | upper.symbol | upper.value | lower_unbounded | upper_unbounded | lower_included | upper_included | expected | constraints violated | 
|---|---|---|---|---|---|---|---|---|---|
| NULL | NULL | NULL | NULL | false | false | true | true | rejected | RM/Schema value and symbol are mandatory for lower and upper | 
| NULL | 1.5 | NULL | 5.3 | false | false | true | true | rejected | RM/Schema symbol is mandatory for lower and upper | 
| local::at0005 | NULL | local::at0003 | NULL | false | false | true | true | rejected | RM/Schema value is mandatory for lower and upper | 
| local::at0005 | 1.5 | local::at0002 | 5.3 | false | false | true | true | accepted | |
| local::at0004 | 666.1 | local::at0003 | 777.1 | false | false | true | true | accepted | |
| local::at0003 | 777.1 | local::at0004 | 666.1 | false | false | true | true | rejected | RM invariante Interval.Limits_comparable | 
14.9.13.2. Test Case CONT-DV_INTERVAL_DV_SCALE-validate_constraint
| lower.symbol | lower.value | upper.symbol | upper.value | lower_unbounded | upper_unbounded | lower_included | upper_included | lower.C_DV_ORDINAL.list | upper.C_DV_ORDINAL.list | expected | constraints violated | 
|---|---|---|---|---|---|---|---|---|---|---|---|
| local::at0005 | 1.5 | local::at0002 | 5.3 | false | false | true | true | 1.5|[local::at0005], 2.4|[local::at0006] | 5.3|[local::at0002], 2.4|[local::at0006] | accepted | |
| local::at0004 | 666.1 | local::at0003 | 777.1 | false | false | true | true | 8.9|[local::at0004], 2.4|[local::at0006] | 9.7|[local::at0003], 2.4|[local::at0006] | rejected | C_DV_ORDINAL.list: no matching value for lower and upper | 
| local::at0666 | 1.5 | local::at0777 | 2.4 | false | false | true | true | 1.5|[local::at0005], 2.4|[local::at0006] | 1.5|[local::at0005], 2.4|[local::at0006] | rejected | C_DV_ORDINAL.list: no matching symbol for lower and upper | 
| local::at0004 | 666.1 | local::at0003 | 777.1 | false | false | true | true | 8.9|[local::at0004], 2.4|[local::at0006] | 777.1|[local::at0003], 2.4|[local::at0006] | rejected | C_DV_ORDINAL.list: no matching value for lower | 
| local::at0666 | 1.5 | local::at0777 | 2.4 | false | false | true | true | 1.5|[local::at0005], 2.4|[local::at0006] | 1.5|[local::at0005], 2.4|[local::at0777] | rejected | C_DV_ORDINAL.list: no matching symbol for lower | 
| local::at0004 | 666.1 | local::at0003 | 777.1 | false | false | true | true | 666.1|[local::at0004], 2.4|[local::at0006] | 9.7|[local::at0003], 2.4|[local::at0006] | rejected | C_DV_ORDINAL.list: no matching value for upper | 
| local::at0005 | 1.5 | local::at0777 | 5.3 | false | false | true | true | 1.5|[local::at0005], 2.4|[local::at0006] | 1.5|[local::at0005], 5.3|[local::at0999] | rejected | C_DV_ORDINAL.list: no matching symbol for upper | 
14.9.14. DV_INTERVAL<DV_PROPORTION>
| Note | some modeling tools don’t support representing DV_INTERVAL<DV_PROPORTION>. | 
14.9.14.1. Test Case CONT-DV_INTERVAL_DV_PROPORTION-validate_open
The test data sets for lower and upper are divided into multiple tables because there are many attributes in the DV_PROPORTION.
Data set both valid ratios
DV_INTERVAL.lower
| type | meaning (kind) | numerator | denominator | precision | 
|---|---|---|---|---|
| 0 | ratio | 10 | 500 | 0 | 
DV_INTERVAL.upper
| type | meaning (kind) | numerator | denominator | precision | 
|---|---|---|---|---|
| 0 | ratio | 20 | 500 | 0 | 
| expected | constraints violated | 
|---|---|
| accepted | 
Data set different limit types
This data set fails beacause DV_INTERVAL.Limits_consistent need both lower and upper to have the same type.
DV_INTERVAL.lower
| type | meaning (kind) | numerator | denominator | precision | 
|---|---|---|---|---|
| 0 | unitary | 10 | 1 | 0 | 
DV_INTERVAL.upper
| type | meaning (kind) | numerator | denominator | precision | 
|---|---|---|---|---|
| 0 | ratio | 10 | 500 | 0 | 
| expected | constraints violated | 
|---|---|
| rejected | DV_INTERVAL.Limits_consistent (invariant) | 
14.9.14.2. Test Case CONT-DV_INTERVAL_DV_PROPORTION-validate_ratio
The constraint is on the type of each limit of the interval as a C_INTEGER.list = [0], constraining the type as a ratio.
14.9.14.3. Test Case CONT-DV_INTERVAL_DV_PROPORTION-validate_unitary
The constraint is on the type of each limit of the interval as a C_INTEGER.list = [1], constraining the type as unitary.
14.9.14.4. Test Case CONT-DV_INTERVAL_DV_PROPORTION-validate_percentage
The constraint is on the type of each limit of the interval as a C_INTEGER.list = [2], constraining the type as percentage.
14.9.14.5. Test Case CONT-DV_INTERVAL_DV_PROPORTION-validate_fraction
The constraint is on the type of each limit of the interval as a C_INTEGER.list = [3], constraining the type as fraction.
14.9.14.6. Test Case CONT-DV_INTERVAL_DV_PROPORTION-validate_integer_fraction
The constraint is on the type of each limit of the interval as a C_INTEGER.list = [3], constraining the type as fraction.
14.9.14.7. Test Case CONT-DV_INTERVAL_DV_PROPORTION-validate_ratio_range
The constraint is on the type of each limit of the interval as a C_INTEGER.list = [0], constraining the type as a ratio. For the limits, the constraints are C_REAL using the range attribute.
Data set valid ratios
DV_INTERVAL.lower
| type | meaning (kind) | numerator | denominator | precision | C_REAL.range (num) | C_REAL.range (den) | |
|---|---|---|---|---|---|---|---|
| 0 | ratio | 10 | 500 | 0 | 0..15 | 100..1000 | 
DV_INTERVAL.upper
| type | meaning (kind) | numerator | denominator | precision | C_REAL.range (num) | C_REAL.range (den) | |
|---|---|---|---|---|---|---|---|
| 0 | ratio | 20 | 500 | 0 | 0..50 | 100..1000 | 
| expected | constraints violated | 
|---|---|
| accepted | 
Data set ratios, invalid lower
DV_INTERVAL.lower
| type | meaning (kind) | numerator | denominator | precision | C_REAL.range (num) | C_REAL.range (den) | |
|---|---|---|---|---|---|---|---|
| 0 | ratio | 10 | 500 | 0 | 0..5 | 100..1000 | 
DV_INTERVAL.upper
| type | meaning (kind) | numerator | denominator | precision | C_REAL.range (num) | C_REAL.range (den) | |
|---|---|---|---|---|---|---|---|
| 0 | ratio | 20 | 500 | 0 | 0..50 | 100..1000 | 
| expected | constraints violated | 
|---|---|
| rejected | C_REAL.range (num) for lower | 
Data set ratios, invalid upper
DV_INTERVAL.lower
| type | meaning (kind) | numerator | denominator | precision | C_REAL.range (num) | C_REAL.range (den) | |
|---|---|---|---|---|---|---|---|
| 0 | ratio | 10 | 500 | 0 | 0..15 | 100..1000 | 
DV_INTERVAL.upper
| type | meaning (kind) | numerator | denominator | precision | C_REAL.range (num) | C_REAL.range (den) | |
|---|---|---|---|---|---|---|---|
| 0 | ratio | 20 | 500 | 0 | 0..10 | 100..1000 | 
| expected | constraints violated | 
|---|---|
| rejected | C_REAL.range (num) for upper | 
14.10. Data Types - quantity.date_time Package
| Note | All test data sets for date/time/datetime expressions are represented in the ISO 8601 extended format. An openEHR CDR could choose to use the extended (with field delimiter characters) or basic format (without field delimiters) of ISO 8601, or support any of the two formats. In the test implementations it is probable that the data sets are represented as JSON or XML documents, in which the date and time expressions are always representede in the ISO 8601 extended format, but internally the SUT could store any of the two formats. If the test implementation doesn’t use JSON or XML, the date and time expression formats could use the ISO 8601 basic format. | 
14.10.1. DV_DURATION
| Note | different duration implementations might affect the DV_DURATION related test cases. For instance, some implementations might not support daysin the same duration expression that containsmonths, since there is no exact correspondence between the number ofdaysandmonths(months could have 28, 29, 30 or 31 days). Then other implementations might simplify themonthmeasurement to be 30 days. This also happens with some implementations that consider adayis exactly24 hoursas a simplification.> It is worth mentioning that openEHR provides means for calculating this based on averages, in DV_DURATION.magnitude(), which is implemented in terms of Iso8601_duration.to_seconds(), it usesTime_Definitions.Average_days_in_yearas an approximation to the numbers of days in a year, andTime_Definitions.Average_days_in_monthas an approximation to the numbers of days in a month. So to normalize an expression that is P1Y3M5D todayswe would have1 * Average_days_in_year + 3 * Average_days_in_month + 5. In case the SUT has an implementation decision to be considered, the developers should mention it in the Conformance Statement Document. | 
The openEHR specifications have two exceptions to the ISO 8601-1 rules:
- 
a negative sign may be used before a Duration expression, for example -P10D, meaning '10 days before [origin]', where the 'origin' is a timepoint understood as the origin for the duration;
- 
the Wdesignator may be mixed with other designators in the duration expression.
Note those exceptions are invalid in terms of ISO 8601-1_2019, but, those are valid in terms for ISO 8601-2_2019, which defines some extensions to the ISO 8601-1 standard. From ISO 8601-2:
Expressions in the following four examples below are not valid in ISO 8601-1, but are valid as specified in this clause.
EXAMPLE 3 'P3W2D', duration of three weeks and two days, which is 23 days (equivalent to the expression 'P23D'). In ISO 8601-1, ["W"] is not permitted to occur along with any other component. EXAMPLE 4 'P5Y10W', duration of five years and ten weeks. ... EXAMPLE 7 '-P2M1D' is equivalent to 'P-2M-1D'.
14.10.1.1. Test Case CONT-DV_DURATION-validate_open
| value | expected | violated constraints | 
|---|---|---|
| NULL | rejected | DV_DURATION.value is mandatory in the RM | 
| 1Y | rejected | invalid ISO 8601-1 duration: missing duration desingator 'P' | 
| P1Y | accepted | |
| P1Y3M | accepted | |
| P1W | accepted | |
| P1Y3M4D | accepted | |
| P1Y3M4DT2H | accepted | |
| P1Y3M4DT2H14M | accepted | |
| P1Y3M4DT2H14M5S | accepted | |
| P1Y3M4DT2H14M15.5S | accepted | |
| P1Y3M4DT2H14.5M | rejected | openEHR: fractions for minutes are not allowed | 
| P1Y3M4DT2.5H | rejected | openEHR: fractions for hours are not allowed | 
| P3M1W | accepted | |
| -P2M | accepted | 
14.10.1.2. Test Case CONT-DV_DURATION-validate_fields
The allowed fields are defined in the C_DURATION class, which allows to constraint the DV_DURATION.value attribute.
| value | years_allowed | months_allowed | weeks_allowed | days_allowed | hours_allowed | minutes_allowed | seconds_allowed | fractional_seconds_allowed | expected | violated constraints | 
|---|---|---|---|---|---|---|---|---|---|---|
| P1Y | true | true | true | true | true | true | true | true | accepted | |
| P1Y | false | true | true | true | true | true | true | true | rejected | C_DURATION.years_allowed | 
| P1Y3M | true | true | true | true | true | true | true | true | accepted | |
| P1Y3M | true | false | true | true | true | true | true | true | rejected | C_DURATION.months_allowed | 
| P1Y3M15D | true | true | true | true | true | true | true | true | accepted | |
| P1Y3M15D | true | true | true | false | true | true | true | true | rejected | C_DURATION.days_allowed | 
| P1W | true | true | true | true | true | true | true | true | accepted | |
| P7W | true | true | false | true | true | true | true | true | rejected | C_DURATION.weeks_allowed | 
| P1Y3M15DT23H | true | true | true | true | true | true | true | true | accepted | |
| P1Y3M15DT23H | true | true | true | true | false | true | true | true | rejected | C_DURATION.hours_allowed | 
| P1Y3M15DT23H35M | true | true | true | true | true | true | true | true | accepted | |
| P1Y3M15DT23H35M | true | true | true | true | true | false | true | true | rejected | C_DURATION.minutes_allowed | 
| P1Y3M15DT23H35M22S | true | true | true | true | true | true | true | true | accepted | |
| P1Y3M15DT23H35M22S | true | true | true | true | true | true | false | true | rejected | C_DURATION.seconds_allowed | 
| P1Y3M15DT23H35M22.5S | true | true | true | true | true | true | true | true | accepted | |
| P1Y3M15DT23H35M22.5S | true | true | true | true | true | true | true | false | rejected | C_DURATION.fractional_seconds_allowed | 
| P1W3D | true | true | true | true | true | true | true | true | accepted | |
| P1W3D | true | true | false | true | true | true | true | true | rejected | C_DURATION.weeks_allowed | 
| Note | the fractional_seconds_allowedfield is not so clear since the ISO8601 would allow fractions on the lowest order component, which means if the duration lowest component isminutesthen it’s valid to have5.23M. Also consider in programming languages like Java, a duration string with fractions on other fields than seconds can’t be parsed (for instance using Java CHarSequence). | 
14.10.1.3. Test Case CONT-DV_DURATION-validate_range
In order to compare durations, the DV_DURATION.magnitude() should be used, which will calculate the seconds in the duration based on the avg. days in year and days in month. If the SUT does calculate the magnitude() in a different way, it should be stated in the Conformance Statement Document.
| value | range.lower | range.upper | expected | violated constraints | 
|---|---|---|---|---|
| P1Y | P0Y | P50Y | accepted | |
| P1Y | P1Y | P50Y | accepted | |
| P1Y | P2Y | P50Y | rejected | C_DURATION.range.lower | 
| P1M | P0M | P50M | accepted | |
| P1M | P1M | P50M | accepted | |
| P1M | P2M | P50M | rejected | C_DURATION.range.lower | 
| P1D | P0D | P50D | accepted | |
| P1D | P1D | P50D | accepted | |
| P1D | P2D | P50D | rejected | C_DURATION.range.lower | 
| P1Y2M | P0Y | P50Y | accepted | |
| P1Y2M | P1Y | P50Y | accepted | |
| P1Y2M | P2Y | P50Y | rejected | C_DURATION.range.lower | 
| P1Y20M | P0Y | P50Y | accepted | |
| P1Y20M | P1Y | P50Y | accepted | |
| P1Y20M | P2Y | P50Y | accepted | |
| P2W | P0W | P3W | accepted | |
| P2W | P2W | P3W | accepted | |
| P2W | P3W | P3W | rejected | C_DURATION.range.lower | 
| P2W3D | P3W | P4W | rejected | C_DURATION.range.lower | 
| P2W8D | P3W | P4W | accepted | |
| P2W15D | P3W | P4W | rejected | C_DURATION.range.upper | 
14.10.1.4. Test Case CONT-DV_DURATION-validate_fields_range
In the AOM specification it is allowed to combine allowed and range: "Both range and the constraint pattern can be set at the same time, corresponding to the ADL constraint PWD/|P0W..P50W|. See C_DURATION class.
| value | years_allowed | months_allowed | weeks_allowed | days_allowed | hours_allowed | minutes_allowed | seconds_allowed | fractional_seconds_allowed | range.lower | range.upper | expected | violated constraints | 
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| P1Y | true | true | true | true | true | true | true | true | P0Y | P50Y | accepted | |
| P1Y | true | true | true | true | true | true | true | true | P2Y | P50Y | rejected | C_DURATION.range.lower | 
| P1Y | false | true | true | true | true | true | true | true | P0Y | P50Y | rejected | C_DURATION.years_allowed | 
| P1Y | false | true | true | true | true | true | true | true | P2Y | P50Y | rejected | C_DURATION.years_allowed, C_DURATION.range.lower | 
| P1Y3M | true | true | true | true | true | true | true | true | P1Y | P50Y | accepted | |
| P1Y3M | true | false | true | true | true | true | true | true | P1Y | P50Y | rejected | C_DURATION.months_allowed | 
| P1Y3M | true | true | true | true | true | true | true | true | P3Y | P50Y | rejected | C_DURATION.lower | 
| P1Y3M | true | false | true | true | true | true | true | true | P3Y | P50Y | rejected | C_DURATION.months_allowed. C_DURATION.lower | 
| PT2M43.5S | true | true | true | true | true | true | true | false | PT1M | PT60M | rejected | C_DURATION.fractional_seconds_allowed | 
14.10.2. DV_TIME
DV_TIME constraints are defined by C_TIME, which specifies two types of constraints: validity kind and range. The validity kind constraints are expressed in terms of mandatory/optional/prohibited flags for each part of the time expression: minute, second, millisecond and timezone. The range constraint is an Interval<Time>, which are both openEHR Foundation Types.
| Note | the Time class mentioned in the AOM 1.4 specification is actually the Iso8601_time class. This is a known bug in the specs. So in C_TIME, range being anInterval<Time>should be anInterval<Iso8601_time>. | 
Time expressions in openEHR are considered an absolute point in time from the start of the current day, that is T10 represents 10:00:00.000 AM in the local timezone.
14.10.2.1. Test Case CONT-DV_TIME-validate_open
This case is when DV_TIME matches {*}.
| Note | the decimal mark for the seconds fraction could be ,(comma) or.(period) at in-memory and storage representations of time expressions, but since in most popular exchange formats the.is preferred, and considering the implementation of these test cases will surelly use those exchange formats, we only specify test data sets which use the decimal mark.. Nevetheless, the,is totally valid at in-memory and storage levels. In the same line, basic and extended formats are allowed at in-memory and storage representations. Basic format being the time parts without any separators and the extended being the parts with separators:(colon). The extended format is also preferred by the most common exchange fornats, so only test data sets using extended format will be specified. | 
| Note | "There is no limit on the number of decimal places for the decimal fraction. However, the number of decimal places needs to be agreed to by the communicating parties." see ISO8601 Times. | 
| Note | the time marker Tcan be ommitted for the extended format in ISO8601:2019, because there is no risk of ambiguity. Since this is nor mandatory, our test data sets all include theTtime marker. | 
| Note | if no timezone information is included, the time expression is considered local time. | 
| Note | one clarification about the seconds fraction in ISO8601 is that is not exactly an expression of milliseconds as the AOM specification implies considering the millisecond_validityfield. For instance.5represents half a second, which is indeed 500 milliseconds but.5is not syntactically500 ms, or.333333represents one third of a second, and syntactically333333goes beyond the precision of milliseconds which is just 3 digits long. Consider.33333is totally valid in ISO8601 for the seconds fraction (see NOTE 2). | 
| value | expected | violated constraints | 
|---|---|---|
| NULL | rejected | RM/Schema: value is mandatory | 
| '' | rejected | ISO8601: at least hours are required | 
| T10 | accepted | |
| T48 | rejected | ISO8601: hours in 0..23 | 
| T10:30 | accepted | |
| T10:95 | rejected | ISO8601: minutes in 0..59 | 
| T10:30:47 | accepted | |
| T10:30:78 | rejected | ISO8601: seconds in 0..59 | 
| T10:30:47.5 | accepted | |
| T10:30:47.333 | accepted | |
| T10:30:47.333333 | accepted | |
| T10:30:47Z | accepted | |
| T10:30:78Z | rejected | ISO8601: seconds in 0..59 | 
| T10:30:47.5Z | accepted | |
| T10:30:47.333Z | accepted | |
| T10:30:47.333333Z | accepted | |
| T10:30:47-03:00 | accepted | |
| T10:30:78-03:00 | rejected | ISO8601: seconds in 0..59 | 
| T10:30:47.5-03:00 | accepted | |
| T10:30:47.333-03:00 | accepted | |
| T10:30:47.333333-03:00 | accepted | |
| T10.5 | rejected | openEHR doesn’t allow fractional hours in partial time expressions, an openEHR exception over the ISO 8601 spec | 
| T10:05.5 | rejected | openEHR doesn’t allow fractional minutes in partial time expressions, an openEHR exception over the ISO 8601 spec | 
14.10.2.2. Test Case CONT-DV_TIME-validate_constraint
| Note | the C_TIME has invariants that define if a lower precision component is optional or prohibited (e.g. minutes) then the higher precision components (e.g. seconds) should be optional or prohibited. In other words, if minutesis optional thensecondsshould be optional or prohibited. These invariants should be checked in an archetype/template editor, since that is part of archetype/template validation. Here we consider the archetypes and templates used are valid. | 
| value | minute_validity | second_validity | millisecond_validity | timezone_validity | expected | violated constraints | 
|---|---|---|---|---|---|---|
| T10 | mandatory | mandatory | mandatory | mandatory | rejected | minute_validity, second_validity, millisecond_validity, timezone_validity | 
| T10 | mandatory | mandatory | mandatory | optional | rejected | minute_validity, second_validity, millisecond_validity | 
| T10 | mandatory | mandatory | optional | optional | rejected | minute_validity, second_validity | 
| T10 | mandatory | optional | optional | optional | rejected | minute_validity | 
| T10 | optional | optional | optional | optional | accepted | |
| T10 | mandatory | mandatory | mandatory | prohibited | rejected | minute_validity, second_validity, millisecond_validity | 
| T10 | mandatory | mandatory | prohibited | prohibited | rejected | minute_validity, second_validity | 
| T10 | mandatory | prohibited | prohibited | prohibited | rejected | minute_validity | 
| T10 | prohibited | prohibited | prohibited | prohibited | accepted | 
| value | minute_validity | second_validity | millisecond_validity | timezone_validity | expected | violated constraints | 
|---|---|---|---|---|---|---|
| T10:30 | mandatory | mandatory | mandatory | mandatory | rejected | second_validity, millisecond_validity, timezone_validity | 
| T10:30 | mandatory | mandatory | mandatory | optional | rejected | second_validity, millisecond_validity | 
| T10:30 | mandatory | mandatory | optional | optional | rejected | second_validity | 
| T10:30 | mandatory | optional | optional | optional | accepted | |
| T10:30 | optional | optional | optional | optional | accepted | |
| T10:30 | mandatory | mandatory | mandatory | prohibited | rejected | second_validity, millisecond_validity | 
| T10:30 | mandatory | mandatory | prohibited | prohibited | rejected | second_validity | 
| T10:30 | mandatory | prohibited | prohibited | prohibited | accepted | |
| T10:30 | prohibited | prohibited | prohibited | prohibited | rejected | minute_validity | 
| value | minute_validity | second_validity | millisecond_validity | timezone_validity | expected | violated constraints | 
|---|---|---|---|---|---|---|
| T10:30:47 | mandatory | mandatory | mandatory | mandatory | rejected | millisecond_validity, timezone_validity | 
| T10:30:47 | mandatory | mandatory | mandatory | optional | rejected | millisecond_validity | 
| T10:30:47 | mandatory | mandatory | optional | optional | accepted | |
| T10:30:47 | mandatory | optional | optional | optional | accepted | |
| T10:30:47 | optional | optional | optional | optional | accepted | |
| T10:30:47 | mandatory | mandatory | mandatory | prohibited | rejected | millisecond_validity | 
| T10:30:47 | mandatory | mandatory | prohibited | prohibited | accepted | |
| T10:30:47 | mandatory | prohibited | prohibited | prohibited | rejected | second_validity | 
| T10:30:47 | prohibited | prohibited | prohibited | prohibited | rejected | minute_validity, second_validity | 
| value | minute_validity | second_validity | millisecond_validity | timezone_validity | expected | violated constraints | 
|---|---|---|---|---|---|---|
| T10:30:47.5 | mandatory | mandatory | mandatory | mandatory | rejected | timezone_validity | 
| T10:30:47.5 | mandatory | mandatory | mandatory | optional | accepted | |
| T10:30:47.5 | mandatory | mandatory | optional | optional | accepted | |
| T10:30:47.5 | mandatory | optional | optional | optional | accepted | |
| T10:30:47.5 | optional | optional | optional | optional | accepted | |
| T10:30:47.5 | mandatory | mandatory | mandatory | prohibited | accepted | |
| T10:30:47.5 | mandatory | mandatory | prohibited | prohibited | rejected | millisecond_validity | 
| T10:30:47.5 | mandatory | prohibited | prohibited | prohibited | rejected | second_validity, millisecond_validity | 
| T10:30:47.5 | prohibited | prohibited | prohibited | prohibited | rejected | minute_validity, second_validity, millisecond_validity | 
| value | minute_validity | second_validity | millisecond_validity | timezone_validity | expected | violated constraints | 
|---|---|---|---|---|---|---|
| T10:30:47Z | mandatory | mandatory | mandatory | mandatory | rejected | millisecond_validity | 
| T10:30:47Z | mandatory | mandatory | mandatory | optional | rejected | millisecond_validity | 
| T10:30:47Z | mandatory | mandatory | optional | optional | accepted | |
| T10:30:47Z | mandatory | optional | optional | optional | accepted | |
| T10:30:47Z | optional | optional | optional | optional | accepted | |
| T10:30:47Z | mandatory | mandatory | mandatory | prohibited | rejected | millisecond_validity, timezone_validity | 
| T10:30:47Z | mandatory | mandatory | prohibited | prohibited | rejected | timezone_validity | 
| T10:30:47Z | mandatory | prohibited | prohibited | prohibited | rejected | second_validity, timezone_validity | 
| T10:30:47Z | prohibited | prohibited | prohibited | prohibited | rejected | minute_validity, second_validity, timezone_validity | 
| value | minute_validity | second_validity | millisecond_validity | timezone_validity | expected | violated constraints | 
|---|---|---|---|---|---|---|
| T10:30:47.5Z | mandatory | mandatory | mandatory | mandatory | accepted | |
| T10:30:47.5Z | mandatory | mandatory | mandatory | optional | accepted | |
| T10:30:47.5Z | mandatory | mandatory | optional | optional | accepted | |
| T10:30:47.5Z | mandatory | optional | optional | optional | accepted | |
| T10:30:47.5Z | optional | optional | optional | optional | accepted | |
| T10:30:47.5Z | mandatory | mandatory | mandatory | prohibited | rejected | timezone_validity | 
| T10:30:47.5Z | mandatory | mandatory | prohibited | prohibited | rejected | millisecond_validity, timezone_validity | 
| T10:30:47.5Z | mandatory | prohibited | prohibited | prohibited | rejected | second_validity, millisecond_validity, timezone_validity | 
| T10:30:47.5Z | prohibited | prohibited | prohibited | prohibited | rejected | minute_validity, second_validity, millisecond_validity, timezone_validity | 
| value | minute_validity | second_validity | millisecond_validity | timezone_validity | expected | violated constraints | 
|---|---|---|---|---|---|---|
| T10:30:47.5-03:00 | mandatory | mandatory | mandatory | mandatory | accepted | |
| T10:30:47.5-03:00 | mandatory | mandatory | mandatory | optional | accepted | |
| T10:30:47.5-03:00 | mandatory | mandatory | optional | optional | accepted | |
| T10:30:47.5-03:00 | mandatory | optional | optional | optional | accepted | |
| T10:30:47.5-03:00 | optional | optional | optional | optional | accepted | |
| T10:30:47.5-03:00 | mandatory | mandatory | mandatory | prohibited | rejected | timezone_validity | 
| T10:30:47.5-03:00 | mandatory | mandatory | prohibited | prohibited | rejected | millisecond_validity, timezone_validity | 
| T10:30:47.5-03:00 | mandatory | prohibited | prohibited | prohibited | rejected | second_validity, millisecond_validity, timezone_validity | 
| T10:30:47.5-03:00 | prohibited | prohibited | prohibited | prohibited | rejected | minute_validity, second_validity, millisecond_validity, timezone_validity | 
14.10.2.3. Test Case CONT-DV_TIME-validate_range
The C_TIME.range constraint is an Interval<Time>, which are both Foundation Types.
| Note | the Time class mentioned in the AOM 1.4 specification is actually the Iso8601_time class. This is a known bug in the specs. So in C_TIME, range being anInterval<Time>should be anInterval<Iso8601_time>. | 
| Note | there is an open issue in the comparability of two date/time/datetime expressions with different precisions but shared values for the components they contain. For instance, in ISO 8601-1_2019, the expression T23:20is referring to a specific hour and minute, andT23is referring to a specific hour. Then, numerically, it’s not possible to say ifT23 < T23:20or ifT23 > T23:20. That is because the expressions represent different time components, which are really intervals of time, and one interval contains the oher (the 23rd hour of the day contains the minute 23:30). Though when the precisions are not the same but there are no shared components, then the expressions are comparable, for instance we can sayT22 < T2320, because all the minutes and seconds in the 22nd hour of the day come before the minute 23:20. Similarly we can sayT22:45 < T23, since the whole minute 22:45 comes before all minutes and seconds in the 23rd hour of the day. This issue is currently being discussed in the openEHR SEC because it changes the definition of the method is_strictly_comparable_to() for DV_DATE, DV_TIME and DV_DATE_TIME. This is commented here because this test case needs to compare time expressions to be able to check the range constraint. | 
| Note | Besides noting that reduced precision time expressions represent an interval or range when those reduced precision time expressions are used as limits for an openEHR Interval, then it seems reasonable to interpret the whole range as the interval defined by the beginning of the lower limit and the end of the upper limit. For instance T11represents the whole 11th hour of the day, from start to end, andT23represents the whole 23rd hour of the day from start to end, thenT11..T23represents all hours, minutes and seconds from the start of hour 11 to the end of hour 23 (yes the end not the start!). So something that might be counterintuitive by using this interpretation is: in this notation isT23:30would be contained in theT11..T23interval, though it is not strictly comparable toT23. | 
| Note | More about these considerations in the openEHR discourse. | 
| value | C_TIME.range | expected | violated constraints | 
|---|---|---|---|
| T10 | T00..T23 | accepted | |
| T10 | T00:00..T23:59 | accepted | |
| T10 | T00:00:00..T23:59:59 | accepted | |
| T10 | T00:00:00.0..T23:59:59.999 | accepted | |
| T10 | T11..T23 | rejected | C_TIME.range | 
| T10 | T11:00..T23:59 | rejected | C_TIME.range | 
| T10 | T11:00:00..T23:59:59 | rejected | C_TIME.range | 
| T10 | T11:00:00.0..T23:59:59.999 | rejected | C_TIME.range | 
| T10 | T00..T09 | rejected | C_TIME.range | 
| T10 | T00:00..T09:59 | rejected | C_TIME.range | 
| T10 | T00:00:00..T09:59:59 | rejected | C_TIME.range | 
| T10 | T00:00:00.0..T09:59:59.999 | rejected | C_TIME.range | 
| T10 | >=T00 | accepted | |
| T10 | >=T00:00 | accepted | |
| T10 | >=T00:00:00 | accepted | |
| T10 | >=T00:00:00.0 | accepted | |
| T10 | >=T11 | rejected | C_TIME.range | 
| T10 | >=T11:00 | rejected | C_TIME.range | 
| T10 | >=T11:00:00 | rejected | C_TIME.range | 
| T10 | >=T11:00:00.0 | rejected | C_TIME.range | 
| T10 | ⇐T09 | rejected | C_TIME.range | 
| T10 | ⇐T09:59 | rejected | C_TIME.range | 
| T10 | ⇐T09:59:59 | rejected | C_TIME.range | 
| T10 | ⇐T09:59:59.999 | rejected | C_TIME.range | 
| Note | the range with the timezone included doesn’t make sense when the time value doesn’t have a timezone, since will compare a local time (without TZ) with a global time (with TZ). This case should be considered an error at the archetype level. Analogously, if the DV_TIME value has a timezome, the C_TIME.range constraints should include the timezone. | 
| value | C_TIME.range | expected | violated constraints | 
|---|---|---|---|
| T10:30 | T00..T23 | accepted | |
| T10:30 | T00:00..T23:59 | accepted | |
| T10:30 | T00:00:00..T23:59:59 | accepted | |
| T10:30 | T00:00:00.0..T23:59:59.999 | accepted | |
| T10:30 | T11..T23 | rejected | C_TIME.range | 
| T10:30 | T11:00..T23:59 | rejected | C_TIME.range | 
| T10:30 | T11:00:00..T23:59:59 | rejected | C_TIME.range | 
| T10:30 | T11:00:00.0..T23:59:59.999 | rejected | C_TIME.range | 
| T10:30 | T00..T09 | rejected | C_TIME.range | 
| T10:30 | T00:00..T09:59 | rejected | C_TIME.range | 
| T10:30 | T00:00:00..T09:59:59 | rejected | C_TIME.range | 
| T10:30 | T00:00:00.0..T09:59:59.999 | rejected | C_TIME.range | 
| T10:30 | >=T00 | accepted | |
| T10:30 | >=T00:00 | accepted | |
| T10:30 | >=T00:00:00 | accepted | |
| T10:30 | >=T00:00:00.0 | accepted | |
| T10:30 | >=T11 | rejected | C_TIME.range | 
| T10:30 | >=T11:00 | rejected | C_TIME.range | 
| T10:30 | >=T11:00:00 | rejected | C_TIME.range | 
| T10:30 | >=T11:00:00.0 | rejected | C_TIME.range | 
| T10:30 | ⇐T09 | rejected | C_TIME.range | 
| T10:30 | ⇐T09:59 | rejected | C_TIME.range | 
| T10:30 | ⇐T09:59:59 | rejected | C_TIME.range | 
| T10:30 | ⇐T09:59:59.999 | rejected | C_TIME.range | 
| value | C_TIME.range | expected | violated constraints | 
|---|---|---|---|
| T10:30:47 | T00..T23 | accepted | |
| T10:30:47 | T00:00..T23:59 | accepted | |
| T10:30:47 | T00:00:00..T23:59:59 | accepted | |
| T10:30:47 | T00:00:00.0..T23:59:59.999 | accepted | |
| T10:30:47 | T11..T23 | rejected | C_TIME.range | 
| T10:30:47 | T11:00..T23:59 | rejected | C_TIME.range | 
| T10:30:47 | T11:00:00..T23:59:59 | rejected | C_TIME.range | 
| T10:30:47 | T11:00:00.0..T23:59:59.999 | rejected | C_TIME.range | 
| T10:30:47 | T00..T09 | rejected | C_TIME.range | 
| T10:30:47 | T00:00..T09:59 | rejected | C_TIME.range | 
| T10:30:47 | T00:00:00..T09:59:59 | rejected | C_TIME.range | 
| T10:30:47 | T00:00:00.0..T09:59:59.999 | rejected | C_TIME.range | 
| T10:30:47 | >=T00 | accepted | |
| T10:30:47 | >=T00:00 | accepted | |
| T10:30:47 | >=T00:00:00 | accepted | |
| T10:30:47 | >=T00:00:00.0 | accepted | |
| T10:30:47 | >=T11 | rejected | C_TIME.range | 
| T10:30:47 | >=T11:00 | rejected | C_TIME.range | 
| T10:30:47 | >=T11:00:00 | rejected | C_TIME.range | 
| T10:30:47 | >=T11:00:00.0 | rejected | C_TIME.range | 
| T10:30:47 | ⇐T09 | rejected | C_TIME.range | 
| T10:30:47 | ⇐T09:59 | rejected | C_TIME.range | 
| T10:30:47 | ⇐T09:59:59 | rejected | C_TIME.range | 
| T10:30:47 | ⇐T09:59:59.999 | rejected | C_TIME.range | 
| value | C_TIME.range | expected | violated constraints | 
|---|---|---|---|
| T10:30:47.5 | T00..T23 | accepted | |
| T10:30:47.5 | T00:00..T23:59 | accepted | |
| T10:30:47.5 | T00:00:00..T23:59:59 | accepted | |
| T10:30:47.5 | T00:00:00.0..T23:59:59.999 | accepted | |
| T10:30:47.5 | T11..T23 | rejected | C_TIME.range | 
| T10:30:47.5 | T11:00..T23:59 | rejected | C_TIME.range | 
| T10:30:47.5 | T11:00:00..T23:59:59 | rejected | C_TIME.range | 
| T10:30:47.5 | T11:00:00.0..T23:59:59.999 | rejected | C_TIME.range | 
| T10:30:47.5 | T00..T09 | rejected | C_TIME.range | 
| T10:30:47.5 | T00:00..T09:59 | rejected | C_TIME.range | 
| T10:30:47.5 | T00:00:00..T09:59:59 | rejected | C_TIME.range | 
| T10:30:47.5 | T00:00:00.0..T09:59:59.999 | rejected | C_TIME.range | 
| T10:30:47.5 | >=T00 | accepted | |
| T10:30:47.5 | >=T00:00 | accepted | |
| T10:30:47.5 | >=T00:00:00 | accepted | |
| T10:30:47.5 | >=T00:00:00.0 | accepted | |
| T10:30:47.5 | >=T11 | rejected | C_TIME.range | 
| T10:30:47.5 | >=T11:00 | rejected | C_TIME.range | 
| T10:30:47.5 | >=T11:00:00 | rejected | C_TIME.range | 
| T10:30:47.5 | >=T11:00:00.0 | rejected | C_TIME.range | 
| T10:30:47.5 | ⇐T09 | rejected | C_TIME.range | 
| T10:30:47.5 | ⇐T09:59 | rejected | C_TIME.range | 
| T10:30:47.5 | ⇐T09:59:59 | rejected | C_TIME.range | 
| T10:30:47.5 | ⇐T09:59:59.999 | rejected | C_TIME.range | 
| value | C_TIME.range | expected | violated constraints | 
|---|---|---|---|
| T10:30:47Z | T00Z..T23Z | accepted | |
| T10:30:47Z | T00:00Z..T23:59Z | accepted | |
| T10:30:47Z | T00:00:00Z..T23:59:59Z | accepted | |
| T10:30:47Z | T00:00:00.0Z..T23:59:59.999Z | accepted | |
| T10:30:47Z | T11Z..T23Z | rejected | C_TIME.range | 
| T10:30:47Z | T11:00Z..T23:59Z | rejected | C_TIME.range | 
| T10:30:47Z | T11:00:00Z..T23:59:59Z | rejected | C_TIME.range | 
| T10:30:47Z | T11:00:00.0Z..T23:59:59.999Z | rejected | C_TIME.range | 
| T10:30:47Z | T00Z..T09Z | rejected | C_TIME.range | 
| T10:30:47Z | T00:00Z..T09:59Z | rejected | C_TIME.range | 
| T10:30:47Z | T00:00:00Z..T09:59:59Z | rejected | C_TIME.range | 
| T10:30:47Z | T00:00:00.0Z..T09:59:59.999Z | rejected | C_TIME.range | 
| T10:30:47Z | >=T00Z | accepted | |
| T10:30:47Z | >=T00:00Z | accepted | |
| T10:30:47Z | >=T00:00:00Z | accepted | |
| T10:30:47Z | >=T00:00:00.0Z | accepted | |
| T10:30:47Z | >=T11Z | rejected | C_TIME.range | 
| T10:30:47Z | >=T11:00Z | rejected | C_TIME.range | 
| T10:30:47Z | >=T11:00:00Z | rejected | C_TIME.range | 
| T10:30:47Z | >=T11:00:00.0Z | rejected | C_TIME.range | 
| T10:30:47Z | ⇐T09Z | rejected | C_TIME.range | 
| T10:30:47Z | ⇐T09:59Z | rejected | C_TIME.range | 
| T10:30:47Z | ⇐T09:59:59Z | rejected | C_TIME.range | 
| T10:30:47Z | ⇐T09:59:59.999Z | rejected | C_TIME.range | 
| value | C_TIME.range | expected | violated constraints | 
|---|---|---|---|
| T10:30:47.5Z | T00Z..T23Z | accepted | |
| T10:30:47.5Z | T00:00Z..T23:59Z | accepted | |
| T10:30:47.5Z | T00:00:00Z..T23:59:59Z | accepted | |
| T10:30:47.5Z | T00:00:00.0Z..T23:59:59.999Z | accepted | |
| T10:30:47.5Z | T11Z..T23Z | rejected | C_TIME.range | 
| T10:30:47.5Z | T11:00Z..T23:59Z | rejected | C_TIME.range | 
| T10:30:47.5Z | T11:00:00Z..T23:59:59Z | rejected | C_TIME.range | 
| T10:30:47.5Z | T11:00:00.0Z..T23:59:59.999Z | rejected | C_TIME.range | 
| T10:30:47.5Z | T00Z..T09Z | rejected | C_TIME.range | 
| T10:30:47.5Z | T00:00Z..T09:59Z | rejected | C_TIME.range | 
| T10:30:47.5Z | T00:00:00Z..T09:59:59Z | rejected | C_TIME.range | 
| T10:30:47.5Z | T00:00:00.0Z..T09:59:59.999Z | rejected | C_TIME.range | 
| T10:30:47.5Z | >=T00Z | accepted | |
| T10:30:47.5Z | >=T00:00Z | accepted | |
| T10:30:47.5Z | >=T00:00:00Z | accepted | |
| T10:30:47.5Z | >=T00:00:00.0Z | accepted | |
| T10:30:47.5Z | >=T11Z | rejected | C_TIME.range | 
| T10:30:47.5Z | >=T11:00Z | rejected | C_TIME.range | 
| T10:30:47.5Z | >=T11:00:00Z | rejected | C_TIME.range | 
| T10:30:47.5Z | >=T11:00:00.0Z | rejected | C_TIME.range | 
| T10:30:47.5Z | ⇐T09Z | rejected | C_TIME.range | 
| T10:30:47.5Z | ⇐T09:59Z | rejected | C_TIME.range | 
| T10:30:47.5Z | ⇐T09:59:59Z | rejected | C_TIME.range | 
| T10:30:47.5Z | ⇐T09:59:59.999Z | rejected | C_TIME.range | 
| value | C_TIME.range | expected | violated constraints | 
|---|---|---|---|
| T10:30:47-03:00 | T00-03:00..T23-03:00 | accepted | |
| T10:30:47-03:00 | T00:00-03:00..T23:59-03:00 | accepted | |
| T10:30:47-03:00 | T00:00:00-03:00..T23:59:59-03:00 | accepted | |
| T10:30:47-03:00 | T00:00:00.0-03:00..T23:59:59.999-03:00 | accepted | |
| T10:30:47-03:00 | T11-03:00..T23-03:00 | rejected | C_TIME.range | 
| T10:30:47-03:00 | T11:00-03:00..T23:59-03:00 | rejected | C_TIME.range | 
| T10:30:47-03:00 | T11:00:00-03:00..T23:59:59-03:00 | rejected | C_TIME.range | 
| T10:30:47-03:00 | T11:00:00.0-03:00..T23:59:59.999-03:00 | rejected | C_TIME.range | 
| T10:30:47-03:00 | T00-03:00..T09-03:00 | rejected | C_TIME.range | 
| T10:30:47-03:00 | T00:00-03:00..T09:59-03:00 | rejected | C_TIME.range | 
| T10:30:47-03:00 | T00:00:00-03:00..T09:59:59-03:00 | rejected | C_TIME.range | 
| T10:30:47-03:00 | T00:00:00.0-03:00..T09:59:59.999-03:00 | rejected | C_TIME.range | 
| T10:30:47-03:00 | >=T00-03:00 | accepted | |
| T10:30:47-03:00 | >=T00:00-03:00 | accepted | |
| T10:30:47-03:00 | >=T00:00:00-03:00 | accepted | |
| T10:30:47-03:00 | >=T00:00:00.0-03:00 | accepted | |
| T10:30:47-03:00 | >=T11-03:00 | rejected | C_TIME.range | 
| T10:30:47-03:00 | >=T11:00-03:00 | rejected | C_TIME.range | 
| T10:30:47-03:00 | >=T11:00:00-03:00 | rejected | C_TIME.range | 
| T10:30:47-03:00 | >=T11:00:00.0-03:00 | rejected | C_TIME.range | 
| T10:30:47-03:00 | ⇐T09-03:00 | rejected | C_TIME.range | 
| T10:30:47-03:00 | ⇐T09:59-03:00 | rejected | C_TIME.range | 
| T10:30:47-03:00 | ⇐T09:59:59-03:00 | rejected | C_TIME.range | 
| T10:30:47-03:00 | ⇐T09:59:59.999-03:00 | rejected | C_TIME.range | 
| value | C_TIME.range | expected | violated constraints | 
|---|---|---|---|
| T10:30:47.5-03:00 | T00-03:00..T23-03:00 | accepted | |
| T10:30:47.5-03:00 | T00:00-03:00..T23:59-03:00 | accepted | |
| T10:30:47.5-03:00 | T00:00:00-03:00..T23:59:59-03:00 | accepted | |
| T10:30:47.5-03:00 | T00:00:00.0-03:00..T23:59:59.999-03:00 | accepted | |
| T10:30:47.5-03:00 | T11-03:00..T23-03:00 | rejected | C_TIME.range | 
| T10:30:47.5-03:00 | T11:00-03:00..T23:59-03:00 | rejected | C_TIME.range | 
| T10:30:47.5-03:00 | T11:00:00-03:00..T23:59:59-03:00 | rejected | C_TIME.range | 
| T10:30:47.5-03:00 | T11:00:00.0-03:00..T23:59:59.999-03:00 | rejected | C_TIME.range | 
| T10:30:47.5-03:00 | T00-03:00..T09-03:00 | rejected | C_TIME.range | 
| T10:30:47.5-03:00 | T00:00-03:00..T09:59-03:00 | rejected | C_TIME.range | 
| T10:30:47.5-03:00 | T00:00:00-03:00..T09:59:59-03:00 | rejected | C_TIME.range | 
| T10:30:47.5-03:00 | T00:00:00.0-03:00..T09:59:59.999-03:00 | rejected | C_TIME.range | 
| T10:30:47.5-03:00 | >=T00-03:00 | accepted | |
| T10:30:47.5-03:00 | >=T00:00-03:00 | accepted | |
| T10:30:47.5-03:00 | >=T00:00:00-03:00 | accepted | |
| T10:30:47.5-03:00 | >=T00:00:00.0-03:00 | accepted | |
| T10:30:47.5-03:00 | >=T11-03:00 | rejected | C_TIME.range | 
| T10:30:47.5-03:00 | >=T11:00-03:00 | rejected | C_TIME.range | 
| T10:30:47.5-03:00 | >=T11:00:00-03:00 | rejected | C_TIME.range | 
| T10:30:47.5-03:00 | >=T11:00:00.0-03:00 | rejected | C_TIME.range | 
| T10:30:47.5-03:00 | ⇐T09-03:00 | rejected | C_TIME.range | 
| T10:30:47.5-03:00 | ⇐T09:59-03:00 | rejected | C_TIME.range | 
| T10:30:47.5-03:00 | ⇐T09:59:59-03:00 | rejected | C_TIME.range | 
| T10:30:47.5-03:00 | ⇐T09:59:59.999-03:00 | rejected | C_TIME.range | 
14.10.3. DV_DATE
DV_DATE constraints are defined by C_DATE, which specifies two types of constraints: validity kind and range. The validity kind constraints are expressed in terms of mandatory/optional/prohibited flags for each part of the date expression: day and month. The range constraint is an Interval<Date>.
NOTE 1: the basic and extended formats are allowed at in-memory and storage representations. Basic format being the time parts without any separators and the extended being the parts with separatos - (hyphen). Since most popular exchange formats use the extended format, and considering the implementation of these test cases will surelly use those exchange formats, we only specify test data sets which use the extended format.
NOTE 2: by the ISO8601 standard, only years >1582 are valid, since that was the year in which the Gregorian Calendar was put in place. For representing other years, there should be a mutual agreement between information interchange partners.
Some exceptions to ISO 8601 specs is that in openEHR date/time/duration types, which dates back to RM 1.0.2 (and maybe before that):
ISO 8601 semantics not used in openEHR include:
- 
“expanded” dates, which have year numbers of greater than 4 digits, and may be negative; in openEHR, only 4-digit year numbers are assumed; 
- 
the YYYY-WW-DD method of expressing dates (since this is imprecise and difficult to compute with due to variable week starting dates, and not required in health); 
- 
partial date/times with fractional minutes or hours, e.g. hh,hhh or mm,mm; in openEHR, only fractional seconds are supported; 
- 
the interval syntax. Intervals of date/times are supported in openEHR, but their syntax form is defined by ADL, and is standardised across all comparable types, not just dates and times. 
Following those rules, will include test data sets that break the openEHR rules, even if those are ISO 8601 valid, the SUT should mark them as invalid.
14.10.3.1. Test Case CONT-DV_DATE-validate_open
| value | expected | violated constraints | 
|---|---|---|
| NULL | rejected | RM/Schema: value is mandatory | 
| '' | rejected | ISO8601: at least year is required (see note below) | 
| '' | rejected | openEHR RM/AOM: at least year is required (see note below) | 
| 2021 | accepted | |
| 2021-10 | accepted | |
| 2021-00 | rejected | ISO8601: month in 01..12 | 
| 2021-13 | rejected | ISO8601: month in 01..12 | 
| 2021-10-24 | accepted | |
| 2021-10-00 | rejected | ISO8601: day in 01..31 | 
| 2021-10-32 | rejected | ISO8601: day in 01..31 | 
| Note | this is the author’s interpretation of a minimal valid date in the context of openEHR noting the description of C_DATE: "There is no validity flag for ‘year’, since it must always be by definition mandatory in order to have a sensible date at all.". Though the ISO 8601 standard allows partial year expressions like 198to denoted the80’sand19to denote de1900’s. | 
14.10.3.2. Test Case CONT-DV_DATE-validate_constraint
| Note | the C_DATE has invariants that define if a higher precision component is optional or prohibited, lower precision components should be optional or prohibited. In other words, if monthis optional,dayshould be optional or prohibited. These invariants should be checked in an archetype editor and template editor, we consider the following tests to follow those rules without checking them, since that is related to archetype/template validation, not with data validation. | 
| value | month_validity | day_validity | expected | violated constraints | 
|---|---|---|---|---|
| 2021 | mandatory | mandatory | rejected | month_validity, day_validity | 
| 2021 | mandatory | optional | rejected | month_validity | 
| 2021 | optional | optional | accepted | |
| 2021 | mandatory | prohibited | rejected | month_validity | 
| 2021 | prohibited | prohibited | accepted | |
| 2021-10 | mandatory | mandatory | rejected | day_validity | 
| 2021-10 | mandatory | optional | accepted | |
| 2021-10 | optional | optional | accepted | |
| 2021-10 | mandatory | prohibited | accepted | |
| 2021-10 | prohibited | prohibited | rejected | month_validity | 
| 2021-10-24 | mandatory | mandatory | accepted | |
| 2021-10-24 | mandatory | optional | accepted | |
| 2021-10-24 | optional | optional | accepted | |
| 2021-10-24 | mandatory | prohibited | rejected | day_validity | 
| 2021-10-24 | prohibited | prohibited | rejected | month_validity, day_validity | 
14.10.3.3. Test Case CONT-DV_DATE-validate_range
The C_DATE.range constraint is an Interval<Date>, which are both Foundation Types.
| Note | the Dateclass mentioned in the AOM 1.4 specification is actually the Iso8601_date class. This is a known bug in the specs. | 
| value | C_DATE.range | expected | violated constraints | 
|---|---|---|---|
| 2021 | 1900..2030 | accepted | |
| 2021 | 2022..2030 | rejected | C_DATE.range | 
| 2021 | 1900..2020 | rejected | C_DATE.range | 
| value | C_DATE.range | expected | violated constraints | 
|---|---|---|---|
| 2021-10 | 1900-03..2030-07 | accepted | |
| 2021-10 | 2022-03..2030-07 | rejected | C_DATE.range | 
| 2021-10 | 1900-03..2020-07 | rejected | C_DATE.range | 
| value | C_DATE.range | expected | violated constraints | 
|---|---|---|---|
| 2021-10-24 | 1900-03-13..2030-07-09 | accepted | |
| 2021-10-24 | 2022-03-13..2030-07-09 | rejected | C_DATE.range | 
| 2021-10-24 | 1900-03-13..2020-07-09 | rejected | C_DATE.range | 
| Note | the DV_DATE value and the C_DATE.range limits should be comparable, that means the value and range limits should have the same components, for instance a year-only date 2021 can’t be compared to a year+month date like 2021-10, because 2021 refers to a whole year, and 2021-10 refers to a month in that year, but it’s not possible to say if 2021 < 2021-10 or 2021 2021-10, since both are refering to different things. What we could say is 2020 < 2021, and 2021-10 < 2021-11. | 
14.10.4. DV_DATE_TIME
DV_DATE_TIME constraints are defined by C_DATE_TIME, which specifies two types of constraints: validity kind and range. The validity kind constraints are expressed in terms of mandatory/optional/prohibited flags for each part of the date expression: hour, minute, second, millisecond, timezone, day and month. The range constraint is an Interval<DateTime>.
14.10.4.1. Test Case CONT-DV_DATE_TIME-validate_open
| value | expected | violated constraints | 
|---|---|---|
| NULL | rejected | RM/Schema: value is mandatory | 
| '' | rejected | openEHR RM/AOM: at least year is required | 
| 2021 | accepted | |
| 2021-10 | accepted | |
| 2021-00 | rejected | ISO8601: month in 01..12 | 
| 2021-13 | rejected | ISO8601: month in 01..12 | 
| 2021-10-24 | accepted | |
| 2021-10-00 | rejected | ISO8601: day in 01..31 | 
| 2021-10-32 | rejected | ISO8601: day in 01..31 | 
| 2021-10-24T10 | accepted | |
| 2021-10-24T48 | rejected | ISO8601: hours in 0..23 | 
| 2021-10-24T10:30 | accepted | |
| 2021-10-24T10:95 | rejected | ISO8601: minutes in 0..59 | 
| 2021-10-24T10:30:47 | accepted | |
| 2021-10-24T10:30:78 | rejected | ISO8601: seconds in 0..59 | 
| 2021-10-24T10:30:47.5 | accepted | |
| 2021-10-24T10:30:47.333 | accepted | |
| 2021-10-24T10:30:47.333333 | accepted | |
| 2021-10-24T10:30:47Z | accepted | |
| 2021-10-24T10:30:78Z | rejected | ISO8601: seconds in 0..59 | 
| 2021-10-24T10:30:47.5Z | accepted | |
| 2021-10-24T10:30:47.333Z | accepted | |
| 2021-10-24T10:30:47.333333Z | accepted | |
| 2021-10-24T10:30:47-03:00 | accepted | |
| 2021-10-24T10:30:78-03:00 | rejected | ISO8601: seconds in 0..59 | 
| 2021-10-24T10:30:47.5-03:00 | accepted | |
| 2021-10-24T10:30:47.333-03:00 | accepted | |
| 2021-10-24T10:30:47.333333-03:00 | accepted | 
| Note | to verify the date time expression used this regex, note that the rejected values don’t match the regex. | 
14.10.4.2. Test Case CONT-DV_DATE_TIME-validate_constraint
| value | month_validity | day_validity | hour_validity | minute_validity | second_validity | millisecond_validity | timezone_validity | expected | violated constraints | 
|---|---|---|---|---|---|---|---|---|---|
| 2021 | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | rejected | month_validity, day_validity, hour_validity, minute_validity, second_validity, millisecond_validity, timezone_validity | 
| 2021 | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | optional | rejected | month_validity, day_validity, hour_validity, minute_validity, second_validity, millisecond_validity | 
| 2021 | mandatory | mandatory | mandatory | mandatory | mandatory | optional | optional | rejected | month_validity, day_validity, hour_validity, minute_validity, second_validity | 
| 2021 | mandatory | mandatory | mandatory | mandatory | optional | optional | optional | rejected | month_validity, day_validity, hour_validity, minute_validity | 
| 2021 | mandatory | mandatory | mandatory | optional | optional | optional | optional | rejected | month_validity, day_validity, hour_validity | 
| 2021 | mandatory | mandatory | optional | optional | optional | optional | optional | rejected | month_validity, day_validity | 
| 2021 | mandatory | optional | optional | optional | optional | optional | optional | rejected | month_validity | 
| 2021 | optional | optional | optional | optional | optional | optional | optional | accepted | |
| 2021 | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | prohibited | rejected | month_validity, day_validity, hour_validity, minute_validity, second_validity, millisecond_validity | 
| 2021 | mandatory | mandatory | mandatory | mandatory | mandatory | prohibited | prohibited | rejected | month_validity, day_validity, hour_validity, minute_validity, second_validity | 
| 2021 | mandatory | mandatory | mandatory | mandatory | prohibited | prohibited | prohibited | rejected | month_validity, day_validity, hour_validity, minute_validity | 
| 2021 | mandatory | mandatory | mandatory | prohibited | prohibited | prohibited | prohibited | rejected | month_validity, day_validity, hour_validity | 
| 2021 | mandatory | mandatory | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | month_validity, day_validity | 
| 2021 | mandatory | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | month_validity | 
| 2021 | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | accepted | 
| value | month_validity | day_validity | hour_validity | minute_validity | second_validity | millisecond_validity | timezone_validity | expected | violated constraints | 
|---|---|---|---|---|---|---|---|---|---|
| 2021-10 | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | rejected | day_validity, hour_validity, minute_validity, second_validity, millisecond_validity, timezone_validity | 
| 2021-10 | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | optional | rejected | day_validity, hour_validity, minute_validity, second_validity, millisecond_validity | 
| 2021-10 | mandatory | mandatory | mandatory | mandatory | mandatory | optional | optional | rejected | day_validity, hour_validity, minute_validity, second_validity | 
| 2021-10 | mandatory | mandatory | mandatory | mandatory | optional | optional | optional | rejected | day_validity, hour_validity, minute_validity | 
| 2021-10 | mandatory | mandatory | mandatory | optional | optional | optional | optional | rejected | day_validity, hour_validity | 
| 2021-10 | mandatory | mandatory | optional | optional | optional | optional | optional | rejected | day_validity | 
| 2021-10 | mandatory | optional | optional | optional | optional | optional | optional | accepted | |
| 2021-10 | optional | optional | optional | optional | optional | optional | optional | accepted | |
| 2021-10 | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | prohibited | rejected | day_validity, hour_validity, minute_validity, second_validity, millisecond_validity | 
| 2021-10 | mandatory | mandatory | mandatory | mandatory | mandatory | prohibited | prohibited | rejected | day_validity, hour_validity, minute_validity, second_validity | 
| 2021-10 | mandatory | mandatory | mandatory | mandatory | prohibited | prohibited | prohibited | rejected | day_validity, hour_validity, minute_validity | 
| 2021-10 | mandatory | mandatory | mandatory | prohibited | prohibited | prohibited | prohibited | rejected | day_validity, hour_validity | 
| 2021-10 | mandatory | mandatory | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | day_validity | 
| 2021-10 | mandatory | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | accepted | |
| 2021-10 | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | month_validity | 
| value | month_validity | day_validity | hour_validity | minute_validity | second_validity | millisecond_validity | timezone_validity | expected | violated constraints | 
|---|---|---|---|---|---|---|---|---|---|
| 2021-10-24 | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | rejected | hour_validity, minute_validity, second_validity, millisecond_validity, timezone_validity | 
| 2021-10-24 | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | optional | rejected | hour_validity, minute_validity, second_validity, millisecond_validity | 
| 2021-10-24 | mandatory | mandatory | mandatory | mandatory | mandatory | optional | optional | rejected | hour_validity, minute_validity, second_validity | 
| 2021-10-24 | mandatory | mandatory | mandatory | mandatory | optional | optional | optional | rejected | hour_validity, minute_validity | 
| 2021-10-24 | mandatory | mandatory | mandatory | optional | optional | optional | optional | rejected | hour_validity | 
| 2021-10-24 | mandatory | mandatory | optional | optional | optional | optional | optional | accepted | |
| 2021-10-24 | mandatory | optional | optional | optional | optional | optional | optional | accepted | |
| 2021-10-24 | optional | optional | optional | optional | optional | optional | optional | accepted | |
| 2021-10-24 | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | prohibited | rejected | hour_validity, minute_validity, second_validity, millisecond_validity | 
| 2021-10-24 | mandatory | mandatory | mandatory | mandatory | mandatory | prohibited | prohibited | rejected | hour_validity, minute_validity, second_validity | 
| 2021-10-24 | mandatory | mandatory | mandatory | mandatory | prohibited | prohibited | prohibited | rejected | hour_validity, minute_validity | 
| 2021-10-24 | mandatory | mandatory | mandatory | prohibited | prohibited | prohibited | prohibited | rejected | hour_validity | 
| 2021-10-24 | mandatory | mandatory | prohibited | prohibited | prohibited | prohibited | prohibited | accepted | |
| 2021-10-24 | mandatory | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | day_validity | 
| 2021-10-24 | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | month_validity, day_validity | 
| value | month_validity | day_validity | hour_validity | minute_validity | second_validity | millisecond_validity | timezone_validity | expected | violated constraints | 
|---|---|---|---|---|---|---|---|---|---|
| 2021-10-24T10 | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | rejected | minute_validity, second_validity, millisecond_validity, timezone_validity | 
| 2021-10-24T10 | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | optional | rejected | minute_validity, second_validity, millisecond_validity | 
| 2021-10-24T10 | mandatory | mandatory | mandatory | mandatory | mandatory | optional | optional | rejected | minute_validity, second_validity | 
| 2021-10-24T10 | mandatory | mandatory | mandatory | mandatory | optional | optional | optional | rejected | minute_validity | 
| 2021-10-24T10 | mandatory | mandatory | mandatory | optional | optional | optional | optional | accepted | |
| 2021-10-24T10 | mandatory | mandatory | optional | optional | optional | optional | optional | accepted | |
| 2021-10-24T10 | mandatory | optional | optional | optional | optional | optional | optional | accepted | |
| 2021-10-24T10 | optional | optional | optional | optional | optional | optional | optional | accepted | |
| 2021-10-24T10 | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | prohibited | rejected | minute_validity, second_validity, millisecond_validity | 
| 2021-10-24T10 | mandatory | mandatory | mandatory | mandatory | mandatory | prohibited | prohibited | rejected | minute_validity, second_validity | 
| 2021-10-24T10 | mandatory | mandatory | mandatory | mandatory | prohibited | prohibited | prohibited | rejected | minute_validity | 
| 2021-10-24T10 | mandatory | mandatory | mandatory | prohibited | prohibited | prohibited | prohibited | accepted | |
| 2021-10-24T10 | mandatory | mandatory | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | hour_validity | 
| 2021-10-24T10 | mandatory | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | day_validity, hour_validity | 
| 2021-10-24T10 | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | month_validity, day_validity, hour_validity | 
| value | month_validity | day_validity | hour_validity | minute_validity | second_validity | millisecond_validity | timezone_validity | expected | violated constraints | 
|---|---|---|---|---|---|---|---|---|---|
| 2021-10-24T10:30 | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | rejected | second_validity, millisecond_validity, timezone_validity | 
| 2021-10-24T10:30 | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | optional | rejected | second_validity, millisecond_validity | 
| 2021-10-24T10:30 | mandatory | mandatory | mandatory | mandatory | mandatory | optional | optional | rejected | second_validity | 
| 2021-10-24T10:30 | mandatory | mandatory | mandatory | mandatory | optional | optional | optional | accepted | |
| 2021-10-24T10:30 | mandatory | mandatory | mandatory | optional | optional | optional | optional | accepted | |
| 2021-10-24T10:30 | mandatory | mandatory | optional | optional | optional | optional | optional | accepted | |
| 2021-10-24T10:30 | mandatory | optional | optional | optional | optional | optional | optional | accepted | |
| 2021-10-24T10:30 | optional | optional | optional | optional | optional | optional | optional | accepted | |
| 2021-10-24T10:30 | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | prohibited | rejected | second_validity, millisecond_validity | 
| 2021-10-24T10:30 | mandatory | mandatory | mandatory | mandatory | mandatory | prohibited | prohibited | rejected | second_validity | 
| 2021-10-24T10:30 | mandatory | mandatory | mandatory | mandatory | prohibited | prohibited | prohibited | accepted | |
| 2021-10-24T10:30 | mandatory | mandatory | mandatory | prohibited | prohibited | prohibited | prohibited | rejected | minute_validity | 
| 2021-10-24T10:30 | mandatory | mandatory | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | hour_validity, minute_validity | 
| 2021-10-24T10:30 | mandatory | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | day_validity, hour_validity, minute_validity | 
| 2021-10-24T10:30 | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | month_validity, day_validity, hour_validity, minute_validity | 
| value | month_validity | day_validity | hour_validity | minute_validity | second_validity | millisecond_validity | timezone_validity | expected | violated constraints | 
|---|---|---|---|---|---|---|---|---|---|
| 2021-10-24T10:30:47 | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | rejected | millisecond_validity, timezone_validity | 
| 2021-10-24T10:30:47 | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | optional | rejected | millisecond_validity | 
| 2021-10-24T10:30:47 | mandatory | mandatory | mandatory | mandatory | mandatory | optional | optional | accepted | |
| 2021-10-24T10:30:47 | mandatory | mandatory | mandatory | mandatory | optional | optional | optional | accepted | |
| 2021-10-24T10:30:47 | mandatory | mandatory | mandatory | optional | optional | optional | optional | accepted | |
| 2021-10-24T10:30:47 | mandatory | mandatory | optional | optional | optional | optional | optional | accepted | |
| 2021-10-24T10:30:47 | mandatory | optional | optional | optional | optional | optional | optional | accepted | |
| 2021-10-24T10:30:47 | optional | optional | optional | optional | optional | optional | optional | accepted | |
| 2021-10-24T10:30:47 | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | prohibited | rejected | millisecond_validity | 
| 2021-10-24T10:30:47 | mandatory | mandatory | mandatory | mandatory | mandatory | prohibited | prohibited | accepted | |
| 2021-10-24T10:30:47 | mandatory | mandatory | mandatory | mandatory | prohibited | prohibited | prohibited | rejected | second_validity | 
| 2021-10-24T10:30:47 | mandatory | mandatory | mandatory | prohibited | prohibited | prohibited | prohibited | rejected | minute_validity, second_validity | 
| 2021-10-24T10:30:47 | mandatory | mandatory | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | hour_validity, minute_validity, second_validity | 
| 2021-10-24T10:30:47 | mandatory | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | day_validity, hour_validity, minute_validity, second_validity | 
| 2021-10-24T10:30:47 | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | month_validity, day_validity, hour_validity, minute_validity, second_validity | 
| value | month_validity | day_validity | hour_validity | minute_validity | second_validity | millisecond_validity | timezone_validity | expected | violated constraints | 
|---|---|---|---|---|---|---|---|---|---|
| 2021-10-24T10:30:47.5 | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | rejected | timezone_validity | 
| 2021-10-24T10:30:47.5 | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | optional | accepted | |
| 2021-10-24T10:30:47.5 | mandatory | mandatory | mandatory | mandatory | mandatory | optional | optional | accepted | |
| 2021-10-24T10:30:47.5 | mandatory | mandatory | mandatory | mandatory | optional | optional | optional | accepted | |
| 2021-10-24T10:30:47.5 | mandatory | mandatory | mandatory | optional | optional | optional | optional | accepted | |
| 2021-10-24T10:30:47.5 | mandatory | mandatory | optional | optional | optional | optional | optional | accepted | |
| 2021-10-24T10:30:47.5 | mandatory | optional | optional | optional | optional | optional | optional | accepted | |
| 2021-10-24T10:30:47.5 | optional | optional | optional | optional | optional | optional | optional | accepted | |
| 2021-10-24T10:30:47.5 | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | prohibited | accepted | |
| 2021-10-24T10:30:47.5 | mandatory | mandatory | mandatory | mandatory | mandatory | prohibited | prohibited | rejected | millisecond_validity | 
| 2021-10-24T10:30:47.5 | mandatory | mandatory | mandatory | mandatory | prohibited | prohibited | prohibited | rejected | second_validity, millisecond_validity | 
| 2021-10-24T10:30:47.5 | mandatory | mandatory | mandatory | prohibited | prohibited | prohibited | prohibited | rejected | minute_validity, second_validity, millisecond_validity | 
| 2021-10-24T10:30:47.5 | mandatory | mandatory | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | hour_validity, minute_validity, second_validity, millisecond_validity | 
| 2021-10-24T10:30:47.5 | mandatory | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | day_validity, hour_validity, minute_validity, second_validity, millisecond_validity | 
| 2021-10-24T10:30:47.5 | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | month_validity, day_validity, hour_validity, minute_validity, second_validity, millisecond_validity | 
| value | month_validity | day_validity | hour_validity | minute_validity | second_validity | millisecond_validity | timezone_validity | expected | violated constraints | 
|---|---|---|---|---|---|---|---|---|---|
| 2021-10-24T10:30:47.5Z | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | accepted | |
| 2021-10-24T10:30:47.5Z | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | optional | accepted | |
| 2021-10-24T10:30:47.5Z | mandatory | mandatory | mandatory | mandatory | mandatory | optional | optional | accepted | |
| 2021-10-24T10:30:47.5Z | mandatory | mandatory | mandatory | mandatory | optional | optional | optional | accepted | |
| 2021-10-24T10:30:47.5Z | mandatory | mandatory | mandatory | optional | optional | optional | optional | accepted | |
| 2021-10-24T10:30:47.5Z | mandatory | mandatory | optional | optional | optional | optional | optional | accepted | |
| 2021-10-24T10:30:47.5Z | mandatory | optional | optional | optional | optional | optional | optional | accepted | |
| 2021-10-24T10:30:47.5Z | optional | optional | optional | optional | optional | optional | optional | accepted | |
| 2021-10-24T10:30:47.5Z | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | prohibited | rejected | timezone_validity | 
| 2021-10-24T10:30:47.5Z | mandatory | mandatory | mandatory | mandatory | mandatory | prohibited | prohibited | rejected | millisecond_validity, timezone_validity | 
| 2021-10-24T10:30:47.5Z | mandatory | mandatory | mandatory | mandatory | prohibited | prohibited | prohibited | rejected | second_validity, millisecond_validity, timezone_validity | 
| 2021-10-24T10:30:47.5Z | mandatory | mandatory | mandatory | prohibited | prohibited | prohibited | prohibited | rejected | minute_validity, second_validity, millisecond_validity, timezone_validity | 
| 2021-10-24T10:30:47.5Z | mandatory | mandatory | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | hour_validity, minute_validity, second_validity, millisecond_validity, timezone_validity | 
| 2021-10-24T10:30:47.5Z | mandatory | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | day_validity, hour_validity, minute_validity, second_validity, millisecond_validity, timezone_validity | 
| 2021-10-24T10:30:47.5Z | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | month_validity, day_validity, hour_validity, minute_validity, second_validity, millisecond_validity, timezone_validity | 
| value | month_validity | day_validity | hour_validity | minute_validity | second_validity | millisecond_validity | timezone_validity | expected | violated constraints | 
|---|---|---|---|---|---|---|---|---|---|
| 2021-10-24T10:30:47Z | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | rejected | millisecond_validity | 
| 2021-10-24T10:30:47Z | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | optional | rejected | millisecond_validity | 
| 2021-10-24T10:30:47Z | mandatory | mandatory | mandatory | mandatory | mandatory | optional | optional | accepted | |
| 2021-10-24T10:30:47Z | mandatory | mandatory | mandatory | mandatory | optional | optional | optional | accepted | |
| 2021-10-24T10:30:47Z | mandatory | mandatory | mandatory | optional | optional | optional | optional | accepted | |
| 2021-10-24T10:30:47Z | mandatory | mandatory | optional | optional | optional | optional | optional | accepted | |
| 2021-10-24T10:30:47Z | mandatory | optional | optional | optional | optional | optional | optional | accepted | |
| 2021-10-24T10:30:47Z | optional | optional | optional | optional | optional | optional | optional | accepted | |
| 2021-10-24T10:30:47Z | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | prohibited | rejected | millisecond_validity, timezone_validity | 
| 2021-10-24T10:30:47Z | mandatory | mandatory | mandatory | mandatory | mandatory | prohibited | prohibited | rejected | timezone_validity | 
| 2021-10-24T10:30:47Z | mandatory | mandatory | mandatory | mandatory | prohibited | prohibited | prohibited | rejected | second_validity, timezone_validity | 
| 2021-10-24T10:30:47Z | mandatory | mandatory | mandatory | prohibited | prohibited | prohibited | prohibited | rejected | minute_validity, second_validity, timezone_validity | 
| 2021-10-24T10:30:47Z | mandatory | mandatory | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | hour_validity, minute_validity, second_validity, timezone_validity | 
| 2021-10-24T10:30:47Z | mandatory | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | day_validity, hour_validity, minute_validity, second_validity, timezone_validity | 
| 2021-10-24T10:30:47Z | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | month_validity, day_validity, hour_validity, minute_validity, second_validity, timezone_validity | 
| value | month_validity | day_validity | hour_validity | minute_validity | second_validity | millisecond_validity | timezone_validity | expected | violated constraints | 
|---|---|---|---|---|---|---|---|---|---|
| 2021-10-24T10:30:47.5-03:00 | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | accepted | |
| 2021-10-24T10:30:47.5-03:00 | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | optional | accepted | |
| 2021-10-24T10:30:47.5-03:00 | mandatory | mandatory | mandatory | mandatory | mandatory | optional | optional | accepted | |
| 2021-10-24T10:30:47.5-03:00 | mandatory | mandatory | mandatory | mandatory | optional | optional | optional | accepted | |
| 2021-10-24T10:30:47.5-03:00 | mandatory | mandatory | mandatory | optional | optional | optional | optional | accepted | |
| 2021-10-24T10:30:47.5-03:00 | mandatory | mandatory | optional | optional | optional | optional | optional | accepted | |
| 2021-10-24T10:30:47.5-03:00 | mandatory | optional | optional | optional | optional | optional | optional | accepted | |
| 2021-10-24T10:30:47.5-03:00 | optional | optional | optional | optional | optional | optional | optional | accepted | |
| 2021-10-24T10:30:47.5-03:00 | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | prohibited | rejected | timezone_validity | 
| 2021-10-24T10:30:47.5-03:00 | mandatory | mandatory | mandatory | mandatory | mandatory | prohibited | prohibited | rejected | millisecond_validity, timezone_validity | 
| 2021-10-24T10:30:47.5-03:00 | mandatory | mandatory | mandatory | mandatory | prohibited | prohibited | prohibited | rejected | second_validity, millisecond_validity, timezone_validity | 
| 2021-10-24T10:30:47.5-03:00 | mandatory | mandatory | mandatory | prohibited | prohibited | prohibited | prohibited | rejected | minute_validity, second_validity, millisecond_validity, timezone_validity | 
| 2021-10-24T10:30:47.5-03:00 | mandatory | mandatory | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | hour_validity, minute_validity, second_validity, millisecond_validity, timezone_validity | 
| 2021-10-24T10:30:47.5-03:00 | mandatory | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | day_validity, hour_validity, minute_validity, second_validity, millisecond_validity, timezone_validity | 
| 2021-10-24T10:30:47.5-03:00 | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | month_validity, day_validity, hour_validity, minute_validity, second_validity, millisecond_validity, timezone_validity | 
| value | month_validity | day_validity | hour_validity | minute_validity | second_validity | millisecond_validity | timezone_validity | expected | violated constraints | 
|---|---|---|---|---|---|---|---|---|---|
| 2021-10-24T10:30:47-03:00 | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | rejected | millisecond_validity | 
| 2021-10-24T10:30:47-03:00 | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | optional | rejected | millisecond_validity | 
| 2021-10-24T10:30:47-03:00 | mandatory | mandatory | mandatory | mandatory | mandatory | optional | optional | accepted | |
| 2021-10-24T10:30:47-03:00 | mandatory | mandatory | mandatory | mandatory | optional | optional | optional | accepted | |
| 2021-10-24T10:30:47-03:00 | mandatory | mandatory | mandatory | optional | optional | optional | optional | accepted | |
| 2021-10-24T10:30:47-03:00 | mandatory | mandatory | optional | optional | optional | optional | optional | accepted | |
| 2021-10-24T10:30:47-03:00 | mandatory | optional | optional | optional | optional | optional | optional | accepted | |
| 2021-10-24T10:30:47-03:00 | optional | optional | optional | optional | optional | optional | optional | accepted | |
| 2021-10-24T10:30:47-03:00 | mandatory | mandatory | mandatory | mandatory | mandatory | mandatory | prohibited | rejected | millisecond_validity, timezone_validity | 
| 2021-10-24T10:30:47-03:00 | mandatory | mandatory | mandatory | mandatory | mandatory | prohibited | prohibited | rejected | timezone_validity | 
| 2021-10-24T10:30:47-03:00 | mandatory | mandatory | mandatory | mandatory | prohibited | prohibited | prohibited | rejected | second_validity, timezone_validity | 
| 2021-10-24T10:30:47-03:00 | mandatory | mandatory | mandatory | prohibited | prohibited | prohibited | prohibited | rejected | minute_validity, second_validity, timezone_validity | 
| 2021-10-24T10:30:47-03:00 | mandatory | mandatory | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | hour_validity, minute_validity, second_validity, timezone_validity | 
| 2021-10-24T10:30:47-03:00 | mandatory | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | day_validity, hour_validity, minute_validity, second_validity, timezone_validity | 
| 2021-10-24T10:30:47-03:00 | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | prohibited | rejected | month_validity, day_validity, hour_validity, minute_validity, second_validity, timezone_validity | 
14.10.4.3. Test Case CONT-DV_DATE_TIME-validate_range
The C_DATE_TIME.range constraint is an Interval<Date_time>, which are both Foundation Types.
| Note | the Date_time class mentioned in the AOM specification is actually the Iso8601_date_time class. This is a known bug in the specs. | 
| value | C_DATE_TIME.range | expected | violated constraints | 
|---|---|---|---|
| 2021 | 1900..2030 | accepted | |
| 2021 | 2022..2030 | rejected | C_DATE_TIME.range | 
| 2021 | 1900..2020 | rejected | C_DATE_TIME.range | 
| value | C_DATE_TIME.range | expected | violated constraints | 
|---|---|---|---|
| 2021-10 | 1900-03..2030-07 | accepted | |
| 2021-10 | 2022-03..2030-07 | rejected | C_DATE_TIME.range | 
| 2021-10 | 1900-03..2020-07 | rejected | C_DATE_TIME.range | 
| value | C_DATE_TIME.range | expected | violated constraints | 
|---|---|---|---|
| 2021-10-24 | 1900-03-13..2030-07-09 | accepted | |
| 2021-10-24 | 2022-03-13..2030-07-09 | rejected | C_DATE_TIME.range | 
| 2021-10-24 | 1900-03-13..2020-07-09 | rejected | C_DATE_TIME.range | 
| value | C_DATE_TIME.range | expected | violated constraints | Notes | 
|---|---|---|---|---|
| 2021-05 | 1900..2030 | accepted | ||
| 2021-05 | 2022..2030 | rejected | C_DATE_TIME.range | |
| 2021-05 | 1900..2021 | accepted | 1900..2021 is interpreted as 1900-01-01..2021-12-31, so 2021-05 is contained in that range | |
| 2021 | 2020-07..2022-03 | accepted | 2020-07..2022-03 is interpreted as 2020-07-01..2022-03-31, and 2021 is 2021-01-01..2021-12-31, which is fully contained in the range constraint | 
TBD: there is an open question about strictly comparability between time expressions with different components. Is "T10" comparable to "T00:00"?
| value | C_DATE_TIME.range | expected | violated constraints | 
|---|---|---|---|
| 2021-10-24T10 | 1900-03-13T00..1900-03-13T23 | accepted | |
| 2021-10-24T10 | 1900-03-13T00:00..1900-03-13T23:59 | accepted | |
| 2021-10-24T10 | 1900-03-13T00:00:00..1900-03-13T23:59:59 | accepted | |
| 2021-10-24T10 | 1900-03-13T00:00:00.0..1900-03-13T23:59:59.999 | accepted | |
| 2021-10-24T10 | 1900-03-13T11..1900-03-13T23 | rejected | C_DATE_TIME.range | 
| 2021-10-24T10 | 1900-03-13T11:00..1900-03-13T23:59 | rejected | C_DATE_TIME.range | 
| 2021-10-24T10 | 1900-03-13T11:00:00..1900-03-13T23:59:59 | rejected | C_DATE_TIME.range | 
| 2021-10-24T10 | 1900-03-13T11:00:00.0..1900-03-13T23:59:59.999 | rejected | C_DATE_TIME.range | 
| 2021-10-24T10 | 1900-03-13T00..1900-03-13T09 | rejected | C_DATE_TIME.range | 
| 2021-10-24T10 | 1900-03-13T00:00..1900-03-13T09:59 | rejected | C_DATE_TIME.range | 
| 2021-10-24T10 | 1900-03-13T00:00:00..1900-03-13T09:59:59 | rejected | C_DATE_TIME.range | 
| 2021-10-24T10 | 1900-03-13T00:00:00.0..1900-03-13T09:59:59.999 | rejected | C_DATE_TIME.range | 
| 2021-10-24T10 | >=1900-03-13T00 | accepted | |
| 2021-10-24T10 | >=1900-03-13T00:00 | accepted | |
| 2021-10-24T10 | >=1900-03-13T00:00:00 | accepted | |
| 2021-10-24T10 | >=1900-03-13T00:00:00.0 | accepted | |
| 2021-10-24T10 | >=1900-03-13T11 | rejected | C_DATE_TIME.range | 
| 2021-10-24T10 | >=1900-03-13T11:00 | rejected | C_DATE_TIME.range | 
| 2021-10-24T10 | >=1900-03-13T11:00:00 | rejected | C_DATE_TIME.range | 
| 2021-10-24T10 | >=1900-03-13T11:00:00.0 | rejected | C_DATE_TIME.range | 
| 2021-10-24T10 | ⇐1900-03-13T09 | rejected | C_DATE_TIME.range | 
| 2021-10-24T10 | ⇐1900-03-13T09:59 | rejected | C_DATE_TIME.range | 
| 2021-10-24T10 | ⇐1900-03-13T09:59:59 | rejected | C_DATE_TIME.range | 
| 2021-10-24T10 | ⇐1900-03-13T09:59:59.999 | rejected | C_DATE_TIME.range | 
14.11. Data Types - time_specification Package
14.12. Data Types - encapsulated Package
14.12.1. DV_PARSABLE
14.12.1.1. Test Case CONT-DV_PARSABLE-validate_open
| value | formalism | expected | violated constraints | 
|---|---|---|---|
| NULL | NULL | rejected | RM/schema value and formalism are required | 
| abc | NULL | rejected | RM/schema formalism is required | 
| NULL | abc | rejected | RM/schema value is required | 
| xxx | abc | accepted | 
14.12.1.2. Test Case CONT-DV_PARSABLE-validate_value_formalism
Each field of the DV_PARSABLE could be constrained by a C_STRING.
| value | formalism | C_STRING.pattern (value) | C_STRING.list (value) | C_STRING.pattern (formalism) | C_STRING.list (formalism) | expected | violated constraints | 
|---|---|---|---|---|---|---|---|
| xxx | abc | x* | NULL | abc | NULL | accepted | |
| xxx | abc | a* | NULL | abc | NULL | rejected | C_STRING.pattern (value) | 
| xxx | abc | x* | NULL | x* | NULL | rejected | C_STRING.pattern (formalism) | 
| xxx | abc | NULL | [xxx, yyy, zzz] | abc | NULL | accepted | |
| xxx | abc | NULL | [yyy, zzz] | abc | NULL | rejected | C_STRING.list (value) | 
| xxx | abc | NULL | [xxx, yyy, zzz] | NULL | [abc, bbb, aaa] | accepted | |
| xxx | abc | NULL | [xxx, yyy, zzz] | NULL | [bbb, aaa] | rejected | C_STRING.list (formalism) | 
14.12.2. DV_MULTIMEDIA
14.12.2.1. Test Case CONT-DV_MULTIMEDIA-validate_open
| media_type | size | expected | violated constraints | 
|---|---|---|---|
| NULL | NULL | rejected | RM/schema media_type and size are required | 
| abc | NULL | rejected | media_type is not in the media type openEHR term set, RM/schema size is required | 
| NULL | 123 | rejected | RM/schema media_type is required | 
| application/dicom | 123 | accepted | 
14.12.2.2. Test Case CONT-DV_MULTIMEDIA-validate_media_type
| Note | media_type could be constrained by a C_CODE_PHRASE and size could be constrained by C_INTEGER. A NULL C_CODE_PHRASE for the media_type means any code is allowed from the openEHR media type codeset. | 
| media_type | size | C_CODE_PHRASE | C_INTEGER.list | C_INTEGER.range | expected | violated constraints | 
|---|---|---|---|---|---|---|
| application/dicom | 123 | NULL | [10, 100, 1000] | NULL | rejected | C_INTEGER.list | 
| application/dicom | 100 | NULL | [10, 100, 1000] | NULL | accepted | |
| application/dicom | 123 | NULL | NULL | 0..1000 | accepted | |
| application/dicom | 123 | NULL | NULL | 200..1000 | rejected | C_INTEGER.range | 
| application/dicom | 100 | [application/dicom, text/plain, text/html] | [10, 100, 1000] | NULL | accepted | |
| application/dicom | 100 | [text/plain, text/html] | [10, 100, 1000] | NULL | rejected | C_CODE_PHRASE | 
| application/dicom | 100 | [application/dicom, text/plain, text/html] | NULL | 0..1000 | accepted | |
| application/dicom | 100 | [text/plain, text/html] | NULL | 200..1000 | rejected | C_CODE_PHRASE, C_INTEGER.range | 
14.13. Data Types - uri Package
14.13.1. DV_URI
14.13.1.1. Test Case CONT-DV_URI-validate_open
On this test case, only invalid URIs should be rejected. Any RFC3986-compliant URI should be accepted.
| value | expected | violated constraints | 
|---|---|---|
| NULL | rejected | RM/schema: value is required | 
| xyz | rejected | value doesn’t comply with RFC3986 | 
| accepted | ||
| accepted | ||
| ldap://[2001:db8::7]/c=GB?objectClass?one | accepted | |
| mailto:John.Doe@example.com | accepted | |
| news:comp.infosystems.www.servers.unix | accepted | |
| tel:+1-816-555-1212 | accepted | |
| telnet://192.0.2.16:80/ | accepted | |
| urn:oasis:names:specification:docbook:dtd:xml:4.1.2 | accepted | |
| accepted | 
14.13.1.2. Test Case CONT-DV_URI-validate_pattern
| Note | to use the pattern constraint, the pattern should comply with the URI format from RFC3986, so the pattern defines a subset of valid URIs. If the pattern doesn’t comply with the URI format, modeling tools should be responsible to notify the modeler and shouldn’t allow to export archetypes or templates in that case. Testing this is not part of the data validation compliance scope, because it is validation of AOM objects not RM. | 
| value | C_STRING.pattern | expected | violated constraints | 
|---|---|---|---|
| xyz | rejected | C_STRING.pattern | |
| accepted | 
14.13.1.3. Test Case CONT-DV_URI-validate_list
| Note | the values in the C_STRING.list should be valid URIs compliant with RFC3986. If this doesn’t happen, the archetype/template is invalid. Testing this case is not in the scope of the data validation. | 
| value | C_STRING.list | expected | violated constraints | 
|---|---|---|---|
| xyz | rejected | C_STRING.list | |
| accepted | 
14.13.2. DV_EHR_URI
14.13.2.1. Test Case CONT-DV_EHR_URI-validate_open
| value | expected | violated constraints | notes | 
|---|---|---|---|
| NULL | rejected | RM/schema: value is required | |
| xyz | rejected | value doesn’t comply with RFC3986 | |
| rejected | URI doesn’t have schema = 'ehr' | ||
| rejected | URI doesn’t have schema = 'ehr' | ||
| ldap://[2001:db8::7]/c=GB?objectClass?one | rejected | URI doesn’t have schema = 'ehr' | |
| mailto:John.Doe@example.com | rejected | URI doesn’t have schema = 'ehr' | |
| news:comp.infosystems.www.servers.unix | rejected | URI doesn’t have schema = 'ehr' | |
| tel:+1-816-555-1212 | rejected | URI doesn’t have schema = 'ehr' | |
| telnet://192.0.2.16:80/ | rejected | URI doesn’t have schema = 'ehr' | |
| urn:oasis:names:specification:docbook:dtd:xml:4.1.2 | rejected | URI doesn’t have schema = 'ehr' | |
| rejected | URI doesn’t have schema = 'ehr' | ehr:/89c0752e-0815-47d7-8b3c-b3aaea2cea7a | |
| accepted | This should be a valid reference to an EHR | ehr:/89c0752e-0815-47d7-8b3c-b3aaea2cea7a/031f2513-b9ef-47b2-bbef-8db24ae68c2f::EHRSERVER::1 | |
| accepted | This should be a valid reference to a COMPOSITION or FOLDER in an EHR (some top-level VERSIONED_OBJECT) | ehr:/89c0752e-0815-47d7-8b3c-b3aaea2cea7a/031f2513-b9ef-47b2-bbef-8db24ae68c2f::EHRSERVER::1/context/other_context[at0001]/items[archetype_id=openEHR-EHR-CLUSTER.sample_symptom.v1]/items[at0034]/items[at0021]/value | |
| accepted | This should be a valid reference to a DATA_VALUE node in a COMPOSITION from an EHR | ehr://CLOUD_EHRSERVER/89c0752e-0815-47d7-8b3c-b3aaea2cea7a | |
| accepted | Similar to the examples above, with given system_id as the URI  | ehr://CLOUD_EHRSERVER/89c0752e-0815-47d7-8b3c-b3aaea2cea7a/031f2513-b9ef-47b2-bbef-8db24ae68c2f::EHRSERVER::1 | |
| accepted | Similar to the examples above, with given system_id as the URI  | ehr://CLOUD_EHRSERVER/89c0752e-0815-47d7-8b3c-b3aaea2cea7a/031f2513-b9ef-47b2-bbef-8db24ae68c2f::EHRSERVER::1/context/other_context[at0001]/items[archetype_id=openEHR-EHR-CLUSTER.sample_symptom.v1]/items[at0034]/items[at0021]/value | |
| accepted | Similar to the examples above, with given system_id as the URI  | 
14.13.2.2. Test Case CONT-DV_EHR_URI-validate_pattern
| Note | to use the pattern constraint, the pattern should comply with the URI format from RFC3986, so the pattern defines a subset of valid URIs. If the pattern doesn’t comply with the URI format, modeling tools should be responsible to notify the modeler and shouldn’t allow to export archetypes or templates in that case. Testing this is not part of the data validation compliance scope, because it is validation of AOM objects not RM. | 
| value | C_STRING.pattern | expected | violated constraints | 
|---|---|---|---|
| xyz | ehr://.* | rejected | C_STRING.pattern | 
| ehr://.* | rejected | C_STRING.pattern | |
| ehr://CLOUD_EHRSERVER/89c0752e-0815-47d7-8b3c-b3aaea2cea7a | ehr://.* | accepted | 
14.13.2.3. Test Case CONT-DV_EHR_URI-validate_list
| Note | the values in the C_STRING.list should be valid URIs compliant with RFC3986. If this doesn’t happen, the archetype/template is invalid. Testing this case is not in the scope of the data validation. | 
| value | C_STRING.list | expected | violated constraints | 
|---|---|---|---|
| xyz | [ehr:/89c0752e-0815-47d7-8b3c-b3aaea2cea7a, ehr://CLOUD_EHRSERVER/89c0752e-0815-47d7-8b3c-b3aaea2cea7a] | rejected | C_STRING.list | 
| [ehr:/89c0752e-0815-47d7-8b3c-b3aaea2cea7a, ehr://CLOUD_EHRSERVER/89c0752e-0815-47d7-8b3c-b3aaea2cea7a] | rejected | C_STRING.list | |
| ehr:/89c0752e-0815-47d7-8b3c-b3aaea2cea7a | [ehr:/89c0752e-0815-47d7-8b3c-b3aaea2cea7a, ehr://CLOUD_EHRSERVER/89c0752e-0815-47d7-8b3c-b3aaea2cea7a] | accepted | 
15. Amendment Record
| Issue | Details | Raiser | Completed | 
|---|---|---|---|
| CNF Release 1.0.0 (unreleased) | |||
| Improved headings based on openEHR Service Model; simplified test categories. | P Pazos | ||
| 0.8.5 | Improve identifiers, structure; | T Beale, | 21 Feb 2022 | 
| 0.8.0 | Rewrite main schedule based on EhrBase (Github commit 674e8b2) | P Pazos; | 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, | 26 Aug 2017 | 
| 0.6.1 | Major rework from SEC call 9 Aug 2017. | C Chevalley, | 11 Aug 2017 | 
| 0.5.0 | SPECCNF-1: Initial Writing. | B Naess, | 01 Jun 2017 | 
