cancer_pathology_data_sharing_test_kit 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +201 -0
- data/config/presets/demo_report.json +14 -0
- data/config/presets/inferno_reference_server_preset.json.erb +39 -0
- data/lib/cancer_pathology_data_sharing_test_kit/bundle_parse.rb +53 -0
- data/lib/cancer_pathology_data_sharing_test_kit/docs/data_access_suite_description.md +83 -0
- data/lib/cancer_pathology_data_sharing_test_kit/docs/report_generation_suite_description.md +118 -0
- data/lib/cancer_pathology_data_sharing_test_kit/fhir_resource_navigation.rb +174 -0
- data/lib/cancer_pathology_data_sharing_test_kit/group_metadata.rb +82 -0
- data/lib/cancer_pathology_data_sharing_test_kit/igs/.keep +0 -0
- data/lib/cancer_pathology_data_sharing_test_kit/igs/README.md +21 -0
- data/lib/cancer_pathology_data_sharing_test_kit/metadata.rb +75 -0
- data/lib/cancer_pathology_data_sharing_test_kit/must_support_test.rb +239 -0
- data/lib/cancer_pathology_data_sharing_test_kit/primitive_type.rb +5 -0
- data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/data_absent/data_absent_reason_code_system.rb +22 -0
- data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/data_absent/data_absent_reason_extension.rb +20 -0
- data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/data_absent/sending_hide_missing.rb +28 -0
- data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/data_absent_group.rb +27 -0
- data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/encounter/encounter_must_support_test.rb +53 -0
- data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/encounter/encounter_validation_test.rb +48 -0
- data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/encounter/metadata.yml +281 -0
- data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/patient/metadata.yml +305 -0
- data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/patient/patient_must_support_test.rb +58 -0
- data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/patient/patient_validation_test.rb +47 -0
- data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/practitioner_role/metadata.yml +44 -0
- data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/practitioner_role/practitioner_role_must_support_test.rb +45 -0
- data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/practitioner_role/practitioner_role_validation_test.rb +47 -0
- data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/service_request/metadata.yml +75 -0
- data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/service_request/service_request_must_support_test.rb +52 -0
- data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/service_request/service_request_validation_test.rb +47 -0
- data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/specimen/metadata.yml +51 -0
- data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/specimen/specimen_must_support_test.rb +53 -0
- data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/specimen/specimen_validation_test.rb +47 -0
- data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/us_pathology_diagnostic_report/diagnostic_report_validation_test.rb +47 -0
- data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/us_pathology_diagnostic_report/metadata.yml +77 -0
- data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/us_pathology_diagnostic_report/us_pathology_diagnostic_report_must_support_test.rb +51 -0
- data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/us_pathology_exchange_bundle/exchange_bundle_validation_test.rb +56 -0
- data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/us_pathology_exchange_bundle/metadata.yml +78 -0
- data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/us_pathology_exchange_bundle/us_pathology_exchange_bundle_must_support_test.rb +41 -0
- data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle_group.rb +104 -0
- data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite.rb +73 -0
- data/lib/cancer_pathology_data_sharing_test_kit/urls.rb +25 -0
- data/lib/cancer_pathology_data_sharing_test_kit/us_core_data_access_suite/us_core_group.rb +72 -0
- data/lib/cancer_pathology_data_sharing_test_kit/us_core_data_access_suite.rb +58 -0
- data/lib/cancer_pathology_data_sharing_test_kit/validation_test.rb +96 -0
- data/lib/cancer_pathology_data_sharing_test_kit/version.rb +4 -0
- data/lib/cancer_pathology_data_sharing_test_kit.rb +3 -0
- metadata +124 -0
@@ -0,0 +1,83 @@
|
|
1
|
+
## Overview
|
2
|
+
|
3
|
+
The Cancer Pathology Data Sharing (CPDS) Data Access Test Suite verifies the ability of
|
4
|
+
clinical systems to make [US Core](http://hl7.org/fhir/us/core/STU5.0.1/)
|
5
|
+
data accessible to other systems per the
|
6
|
+
STU 1.0.1 version of the HL7® FHIR® [Cancer Pathology Data Sharing IG](https://hl7.org/fhir/us/cancer-reporting/STU1.0.1/).
|
7
|
+
|
8
|
+
## Scope
|
9
|
+
|
10
|
+
The CPDS IG requires that both [Laboratory Information System (LIS)](https://hl7.org/fhir/us/cancer-reporting/STU1.0.1/CapabilityStatement-pathology-lab-information-system.html)
|
11
|
+
and [Electronic Health Record (EHR)](https://hl7.org/fhir/us/cancer-reporting/STU1.0.1/CapabilityStatement-central-cancer-registry-reporting-ehr-pathology.html)
|
12
|
+
systems support "searching and retrieval of resources using US Core APIs". This test suite
|
13
|
+
verifies that a system exposes the full list of US Core v5 APIs and profiles.
|
14
|
+
|
15
|
+
Other capabilities that the CPDS IG requires of these systems are currently out of scope
|
16
|
+
for this test suite, including
|
17
|
+
- EHR requirements around ServiceRequest creation.
|
18
|
+
- LIS requirements around DiagnosticReport creation.
|
19
|
+
|
20
|
+
## Test Methodology
|
21
|
+
|
22
|
+
Inferno will simulate a FHIR client using the search and read API required by the
|
23
|
+
[Laboratory Information System (LIS)](https://hl7.org/fhir/us/cancer-reporting/STU1.0.1/CapabilityStatement-pathology-lab-information-system.html)
|
24
|
+
and [Electronic Health Record (EHR)](https://hl7.org/fhir/us/cancer-reporting/STU1.0.1/CapabilityStatement-central-cancer-registry-reporting-ehr-pathology.html) CapabilityStatements.
|
25
|
+
Through a combination of tester input and details returned by the searches it makes, Inferno will
|
26
|
+
attempt to search for and read resources conforming to each profile. This includes
|
27
|
+
- Testing required search parameter combinations and verifying that the results returned are appropriate.
|
28
|
+
- For each must support element, observing an instance with that element populated.
|
29
|
+
- For each must support reference element, verifying that a populated reference can be resolved.
|
30
|
+
|
31
|
+
## Running the tests
|
32
|
+
|
33
|
+
### Quick Start
|
34
|
+
|
35
|
+
The minimal amount of information Inferno needs to run these tests includes the following inputs:
|
36
|
+
- **FHIR Endpoint**: URL of the system's FHIR endpoint.
|
37
|
+
- **OAuth Credentials / Access Token** (optional): If needed, a token that Inferno will include in the `Authorization`
|
38
|
+
HTTP header in the form `Bearer <input value>` on each request it makes to the system under test
|
39
|
+
- **Patient IDs**: Comma separated list of patient IDs. Inferno will use these when building searches.
|
40
|
+
|
41
|
+
### Demonstration
|
42
|
+
|
43
|
+
If you would like to try out the tests using the [Inferno Reference Server](https://inferno.healthit.gov/reference-server)
|
44
|
+
([code](https://github.com/inferno-framework/inferno-reference-server)) as the system under test,
|
45
|
+
use the "Inferno Reference Server" preset.
|
46
|
+
|
47
|
+
## Current Limitations
|
48
|
+
|
49
|
+
### Report generation and data access differences
|
50
|
+
|
51
|
+
The CPDS STU 1.0.1 IG contains mismatches between the profiles made available through
|
52
|
+
the [EHR Data Access API](https://hl7.org/fhir/us/cancer-reporting/STU1.0.1/CapabilityStatement-central-cancer-registry-reporting-ehr-pathology.html)
|
53
|
+
and those that need to be included in [cancer pathology reports](https://hl7.org/fhir/us/cancer-reporting/STU1.0.1/StructureDefinition-us-pathology-exchange-bundle.html),
|
54
|
+
both in terms of:
|
55
|
+
- **The number of profiles**: The [EHR Capability Statement](https://hl7.org/fhir/us/cancer-reporting/STU1.0.1/CapabilityStatement-central-cancer-registry-reporting-ehr-pathology.html)
|
56
|
+
requires support for US Core STU 5 APIs which can return instances conforming to up to [45 profiles](https://www.hl7.org/fhir/us/core/STU5/profiles-and-extensions.html) while the [Pathology Cancer Exchange Bundle profile](https://hl7.org/fhir/us/cancer-reporting/STU1.0.1/StructureDefinition-us-pathology-exchange-bundle.html)
|
57
|
+
requires explicit support for only 6 profiles. Strictly speaking, the US Core IG does not require implementing systems to support APIs that
|
58
|
+
return all US Core profiles. However, the CPDS IG does not provide explicit guidance on which resource types and profiles to support
|
59
|
+
either in the Capability Statement or through the scope of entries to include in the report Bundle (see the **Extra Bundle entries**
|
60
|
+
limitation on the report generation suite for details).
|
61
|
+
- **Which profiles**: The [Pathology Cancer Exchange Bundle profile](https://hl7.org/fhir/us/cancer-reporting/STU1.0.1/StructureDefinition-us-pathology-exchange-bundle.html)
|
62
|
+
requires entry conformance to specific profiles for which there are no APIs defined in the CPDS [EHR Capability Statement](https://hl7.org/fhir/us/cancer-reporting/STU1.0.1/CapabilityStatement-central-cancer-registry-reporting-ehr-pathology.html)
|
63
|
+
or the referenced [US Core Server CapabilityStatement](https://www.hl7.org/fhir/us/core/STU5/CapabilityStatement-us-core-server.html).
|
64
|
+
For example, the report requires [US Pathology Specimen profile](https://hl7.org/fhir/us/cancer-reporting/STU1.0.1/StructureDefinition-us-pathology-specimen.html)
|
65
|
+
but the [EHR Capability Statement](https://hl7.org/fhir/us/cancer-reporting/STU1.0.1/CapabilityStatement-central-cancer-registry-reporting-ehr-pathology.html)
|
66
|
+
does not require support for a Specimen resource API directly the referenced version of US Core ([STU 5](https://www.hl7.org/fhir/us/core/STU5/profiles-and-extensions.html))
|
67
|
+
does not define a profile or API for the Specimen resource type. Additionally, for resource types for which US Core does define APIs, e.g.,
|
68
|
+
[DiagnosticReport](https://hl7.org/fhir/us/core/STU5.0.1/StructureDefinition-us-core-diagnosticreport-note.html),
|
69
|
+
CPDS doesn't explicitly indicate the need for EHRs to support the CPDS-specific profile in their APIs,
|
70
|
+
e.g., for [US Pathology DiagnosticReport](https://hl7.org/fhir/us/cancer-reporting/STU1.0.1/StructureDefinition-us-pathology-diagnostic-report.html).
|
71
|
+
|
72
|
+
Currently this report generation suite and the data access suite test the requirements indicated in the
|
73
|
+
IG, including API support for all US Core Profiles, despite the mismatch and their potential to cause
|
74
|
+
interoperability issues or extra implementation burden. Future versions of this test suite may update this
|
75
|
+
approach based on community feedback and IG updates.
|
76
|
+
|
77
|
+
### Limited authentication and authorization options
|
78
|
+
|
79
|
+
This test suite currently provides only one option for testers to adjust the requests that Inferno makes
|
80
|
+
so that the system under test can identify Inferno as the requestor. If the **Access Token** input is populated,
|
81
|
+
the provided value will be placed in the HTTP `Authorization` header with the prefix `Bearer `.
|
82
|
+
Support for Inferno to obtain bearer tokens using SMART on FHIR workflows or other auth schemes may be added
|
83
|
+
in the future based on community feedback.
|
@@ -0,0 +1,118 @@
|
|
1
|
+
## Overview
|
2
|
+
The Cancer Pathology Data Sharing Report Generation Test Suite verifies the conformance of clinical systems,
|
3
|
+
including laboratory information systems (LISs) & electronic health records (EHRs) to the report generation
|
4
|
+
requirements in the STU 1.0.1 version of the HL7® FHIR®
|
5
|
+
[Cancer Pathology Data Sharing (CPDS) IG](https://hl7.org/fhir/us/cancer-reporting/STU1.0.1/).
|
6
|
+
|
7
|
+
## Scope
|
8
|
+
This test suite focuses on the report creation portion of a system's role in submitting pathology reports to
|
9
|
+
central cancer registries. Specifically, these tests verify that a system can produce a set of comformant
|
10
|
+
and complete [Pathology Cancer Exchange Bundle(s)](https://hl7.org/fhir/us/cancer-reporting/STU1.0.1/StructureDefinition-us-pathology-exchange-bundle.html).
|
11
|
+
|
12
|
+
The IG defines other capabilities of clinical systems that are currently out of scope for this suite, including:
|
13
|
+
- The gathering of report content from other systems, if necessary.
|
14
|
+
- The transmission of reports to registries.
|
15
|
+
- The exchange of data between LIS and EHR systems, including service requests and diagnostic reports.
|
16
|
+
|
17
|
+
## Test Methodology
|
18
|
+
|
19
|
+
To verify that the system under test can produce conformant and complete cancer pathology reports, Inferno asks
|
20
|
+
the tester to provide as input a set of [Pathology Cancer Exchange Bundles](https://hl7.org/fhir/us/cancer-reporting/STU1.0.1/StructureDefinition-us-pathology-exchange-bundle.html)
|
21
|
+
generated from the system under test. Inferno will check that each Bundle and the must support entry types
|
22
|
+
are conformant to the required profile. Additionally, to verify completeness the tests check for a populated example of each
|
23
|
+
must support element designated must support Bundle entry types as well as the profiles required for those entries.
|
24
|
+
|
25
|
+
## Running the tests
|
26
|
+
|
27
|
+
### Quick Start
|
28
|
+
|
29
|
+
The minimal amount of information Inferno needs to run these tests includes the following inputs:
|
30
|
+
- **Cancer Reports**: A comma-Separated list of one or more FHIR Pathology Cancer Exchange Bundles
|
31
|
+
in JSON format generated by the system under test.
|
32
|
+
|
33
|
+
Testers will need to generate one or more reports using the system they are testing, paste them into
|
34
|
+
the input in Inferno and run the tests. Inferno will evaluate the reports and provide test results.
|
35
|
+
|
36
|
+
### Demonstration
|
37
|
+
|
38
|
+
If you would like to try out the tests using example data from the CPDS IG, use the "Demo Report"
|
39
|
+
preset, which contains the [US Pathology Exchange bundle example](https://hl7.org/fhir/us/cancer-reporting/STU1.0.1/Bundle-us-pathology-exchange-bundle-example.json.html)
|
40
|
+
with the [Service Request - Cancer Pathology example](https://hl7.org/fhir/us/cancer-reporting/STU1.0.1/ServiceRequest-cancer-path-example.json.html) added to it so as to cover all required entry types. The demo report should pass all the tests.
|
41
|
+
|
42
|
+
## Current Limitations
|
43
|
+
|
44
|
+
### Report generation and data access differences
|
45
|
+
|
46
|
+
The CPDS STU 1.0.1 IG contains mismatches between the profiles made available through
|
47
|
+
the [EHR Data Access API](https://hl7.org/fhir/us/cancer-reporting/STU1.0.1/CapabilityStatement-central-cancer-registry-reporting-ehr-pathology.html)
|
48
|
+
and those that need to be included in [cancer pathology reports](https://hl7.org/fhir/us/cancer-reporting/STU1.0.1/StructureDefinition-us-pathology-exchange-bundle.html),
|
49
|
+
both in terms of:
|
50
|
+
- **The number of profiles**: The [EHR Capability Statement](https://hl7.org/fhir/us/cancer-reporting/STU1.0.1/CapabilityStatement-central-cancer-registry-reporting-ehr-pathology.html)
|
51
|
+
requires support for US Core STU 5 APIs which can return instances conforming to up to [45 profiles](https://www.hl7.org/fhir/us/core/STU5/profiles-and-extensions.html) while the [Pathology Cancer Exchange Bundle profile](https://hl7.org/fhir/us/cancer-reporting/STU1.0.1/StructureDefinition-us-pathology-exchange-bundle.html)
|
52
|
+
requires explicit support for only 6 profiles. Strictly speaking, the US Core IG does not require implementing systems to support APIs that
|
53
|
+
return all US Core profiles. However, the CPDS IG does not provide explicit guidance on which resource types and profiles to support
|
54
|
+
either in the Capability Statement or through the scope of entries to include in the report Bundle (see the **Extra Bundle entries**
|
55
|
+
limitation on the report generation suite for details).
|
56
|
+
- **Which profiles**: The [Pathology Cancer Exchange Bundle profile](https://hl7.org/fhir/us/cancer-reporting/STU1.0.1/StructureDefinition-us-pathology-exchange-bundle.html)
|
57
|
+
requires entry conformance to specific profiles for which there are no APIs defined in the CPDS [EHR Capability Statement](https://hl7.org/fhir/us/cancer-reporting/STU1.0.1/CapabilityStatement-central-cancer-registry-reporting-ehr-pathology.html)
|
58
|
+
or the referenced [US Core Server CapabilityStatement](https://www.hl7.org/fhir/us/core/STU5/CapabilityStatement-us-core-server.html).
|
59
|
+
For example, the report requires [US Pathology Specimen profile](https://hl7.org/fhir/us/cancer-reporting/STU1.0.1/StructureDefinition-us-pathology-specimen.html)
|
60
|
+
but the [EHR Capability Statement](https://hl7.org/fhir/us/cancer-reporting/STU1.0.1/CapabilityStatement-central-cancer-registry-reporting-ehr-pathology.html)
|
61
|
+
does not require support for a Specimen resource API directly the referenced version of US Core ([STU 5](https://www.hl7.org/fhir/us/core/STU5/profiles-and-extensions.html))
|
62
|
+
does not define a profile or API for the Specimen resource type. Additionally, for resource types for which US Core does define APIs, e.g.,
|
63
|
+
[DiagnosticReport](https://hl7.org/fhir/us/core/STU5.0.1/StructureDefinition-us-core-diagnosticreport-note.html),
|
64
|
+
CPDS doesn't explicitly indicate the need for EHRs to support the CPDS-specific profile in their APIs,
|
65
|
+
e.g., for [US Pathology DiagnosticReport](https://hl7.org/fhir/us/cancer-reporting/STU1.0.1/StructureDefinition-us-pathology-diagnostic-report.html).
|
66
|
+
|
67
|
+
Currently this report generation suite and the data access suite test the requirements indicated in the
|
68
|
+
IG, including API support for all US Core Profiles, despite the mismatch and their potential to cause
|
69
|
+
interoperability issues or extra implementation burden. Future versions of this test suite may update this
|
70
|
+
approach based on community feedback and IG updates.
|
71
|
+
|
72
|
+
### Bundle slicing
|
73
|
+
|
74
|
+
The [Pathology Cancer Exchange Bundle profile](https://hl7.org/fhir/us/cancer-reporting/STU1.0.1/StructureDefinition-us-pathology-exchange-bundle.html)
|
75
|
+
describes the required contents in terms of slices on `Bundle.entry` using specific profiles
|
76
|
+
as [the discriminator](https://build.fhir.org/profiling.html#discriminator). This means, for example,
|
77
|
+
that a Bundle with two Patient entries would be valid as long as only one of those Patients
|
78
|
+
did not conform to the [US Core Patient profile](http://hl7.org/fhir/us/core/STU5.0.1/StructureDefinition-us-core-patient.html)
|
79
|
+
specified in the patient slice. That interpretation does not align with other forms of these reports,
|
80
|
+
such as [NAACCR Volume V](https://hl7.org/fhir/us/cancer-reporting/STU1.0.1/background.html#fhir-profiles-to-capture-naaccr-volume-v)
|
81
|
+
which would require exactly one patient.
|
82
|
+
|
83
|
+
These tests check [Pathology Cancer Exchange Bundles](https://hl7.org/fhir/us/cancer-reporting/STU1.0.1/StructureDefinition-us-pathology-exchange-bundle.html) as if the slicing were discriminated by
|
84
|
+
resource type, meaning that any Patient entries are part of the Patient slice. Since the Patient slice
|
85
|
+
has a cardinality of exactly 1, a Bundle with multiple Patient entries would be invalid regardless of
|
86
|
+
which profiles they conform to. Future versions of this test suite may update this approach based on
|
87
|
+
community feedback and IG updates.
|
88
|
+
|
89
|
+
### Extra Bundle entries
|
90
|
+
|
91
|
+
This test suite currently only checks for the presence of instances of the six resource types indicated in the
|
92
|
+
[Pathology Cancer Exchange Bundle(s)](https://hl7.org/fhir/us/cancer-reporting/STU1.0.1/StructureDefinition-us-pathology-exchange-bundle.html) and their conformance to the indicated profiles.
|
93
|
+
The tests do not check that
|
94
|
+
- Instances recursively referenced from these instances are also present in the Bundle.
|
95
|
+
- Recursively referenced instances that are present in the Bundle conform to the profile(s) required
|
96
|
+
by the referencing element(s).
|
97
|
+
- All must support elements for recursively referenced profiles are demonstrated.
|
98
|
+
|
99
|
+
For example the [US Core Encounter profile](https://hl7.org/fhir/us/core/STU5.0.1/StructureDefinition-us-core-encounter.html)
|
100
|
+
is referenced from a must support `entry` element slice in the [Pathology Cancer Exchange Bundle(s)](https://hl7.org/fhir/us/cancer-reporting/STU1.0.1/StructureDefinition-us-pathology-exchange-bundle.html)
|
101
|
+
and the [US Core Encounter profile](https://hl7.org/fhir/us/core/STU5.0.1/StructureDefinition-us-core-encounter.html)
|
102
|
+
requires support for the [US Core Practitioner profile](https://hl7.org/fhir/us/core/STU5.0.1/StructureDefinition-us-core-practitioner.html)
|
103
|
+
on the `participant.individual` element. This test suite does not currently test that in a
|
104
|
+
Bundle where `participant.individual` is demonstrated referencing a Practitioner that the referenced
|
105
|
+
instance is also present in the Bundle and that it conforms to the [US Core Practitioner profile](https://hl7.org/fhir/us/core/STU5.0.1/StructureDefinition-us-core-practitioner.html).
|
106
|
+
Must support elements for the [US Core Practitioner profile](https://hl7.org/fhir/us/core/STU5.0.1/StructureDefinition-us-core-practitioner.html)
|
107
|
+
also do not need to be demonstrated currently.
|
108
|
+
|
109
|
+
The CPDS IG does not explicitly require that the above requirements are met, but they are likely
|
110
|
+
to be necessary or at least helpful in practical applications of report exchange. Future versions
|
111
|
+
of this test suite may update this approach based on community feedback and IG updates.
|
112
|
+
|
113
|
+
### No API-based Submission
|
114
|
+
|
115
|
+
The CPDS IG refers to the MedMorph framework for submission which uses FHIR Messaging. Currently, this test suite
|
116
|
+
does not support submission of reports using this standards-based approach and instead requires manual provision of
|
117
|
+
the reports using Inferno inputs. Future versions may include support for FHIR Messaging or other approaches
|
118
|
+
to submission.
|
@@ -0,0 +1,174 @@
|
|
1
|
+
require_relative 'primitive_type'
|
2
|
+
|
3
|
+
module CancerPathologyDataSharingTestKit
|
4
|
+
module FHIRResourceNavigation
|
5
|
+
DAR_EXTENSION_URL = 'http://hl7.org/fhir/StructureDefinition/data-absent-reason'.freeze
|
6
|
+
PRIMITIVE_DATA_TYPES = FHIR::PRIMITIVES.keys
|
7
|
+
|
8
|
+
def resolve_path(elements, path)
|
9
|
+
elements = Array.wrap(elements)
|
10
|
+
return elements if path.blank?
|
11
|
+
|
12
|
+
paths = path.split(/(?<!hl7)\./)
|
13
|
+
segment = paths.first
|
14
|
+
remaining_path = paths.drop(1).join('.')
|
15
|
+
|
16
|
+
elements.flat_map do |element|
|
17
|
+
child = get_next_value(element, segment)
|
18
|
+
resolve_path(child, remaining_path)
|
19
|
+
end.compact
|
20
|
+
end
|
21
|
+
|
22
|
+
def find_a_value_at(element, path, include_dar: false, &block) # rubocop:disable Metrics/CyclomaticComplexity
|
23
|
+
return nil if element.nil?
|
24
|
+
|
25
|
+
elements = Array.wrap(element)
|
26
|
+
if path.empty?
|
27
|
+
unless include_dar
|
28
|
+
elements = elements.reject do |el|
|
29
|
+
el.respond_to?(:extension) && el.extension.any? { |ext| ext.url == DAR_EXTENSION_URL }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
return elements.find(&block) if block_given?
|
34
|
+
|
35
|
+
return elements.first
|
36
|
+
end
|
37
|
+
|
38
|
+
path_segments = path.split(/(?<!hl7)\./)
|
39
|
+
|
40
|
+
segment = path_segments
|
41
|
+
.shift
|
42
|
+
.delete_suffix('[x]')
|
43
|
+
.gsub(/^class$/, 'local_class')
|
44
|
+
.gsub(/^method$/, 'local_method')
|
45
|
+
.gsub('[x]:', ':')
|
46
|
+
.to_sym
|
47
|
+
no_elements_present =
|
48
|
+
elements.none? do |element| # rubocop:disable Lint/ShadowingOuterLocalVariable
|
49
|
+
child = get_next_value(element, segment)
|
50
|
+
child.present? || child == false
|
51
|
+
end
|
52
|
+
return nil if no_elements_present
|
53
|
+
|
54
|
+
remaining_path = path_segments.join('.')
|
55
|
+
elements.each do |element| # rubocop:disable Lint/ShadowingOuterLocalVariable
|
56
|
+
child = get_next_value(element, segment)
|
57
|
+
element_found =
|
58
|
+
if block_given?
|
59
|
+
find_a_value_at(child, remaining_path, include_dar: include_dar, &block)
|
60
|
+
else
|
61
|
+
find_a_value_at(child, remaining_path, include_dar: include_dar)
|
62
|
+
end
|
63
|
+
return element_found if element_found.present? || element_found == false
|
64
|
+
end
|
65
|
+
|
66
|
+
nil
|
67
|
+
end
|
68
|
+
|
69
|
+
def get_next_value(element, property)
|
70
|
+
extension_url = property[/(?<=where\(url=').*(?='\))/]
|
71
|
+
if extension_url.present?
|
72
|
+
element.url == extension_url ? element : nil
|
73
|
+
elsif property.to_s.include?(':') && !property.to_s.include?('url')
|
74
|
+
find_slice_via_discriminator(element, property)
|
75
|
+
|
76
|
+
else
|
77
|
+
value = element.send(property)
|
78
|
+
primitive_value = get_primitive_type_value(element, property, value)
|
79
|
+
primitive_value.present? ? primitive_value : value
|
80
|
+
end
|
81
|
+
rescue NoMethodError
|
82
|
+
nil
|
83
|
+
end
|
84
|
+
|
85
|
+
def get_primitive_type_value(element, property, value)
|
86
|
+
source_value = element.source_hash["_#{property}"]
|
87
|
+
|
88
|
+
return nil unless source_value.present?
|
89
|
+
|
90
|
+
primitive_value = CancerPathologyDataSharingTestKit::PrimitiveType.new(source_value)
|
91
|
+
primitive_value.value = value
|
92
|
+
primitive_value
|
93
|
+
end
|
94
|
+
|
95
|
+
def find_slice_via_discriminator(element, property) # rubocop:disable Metrics/CyclomaticComplexity
|
96
|
+
element_name = property.to_s.split(':')[0].gsub(/^class$/, 'local_class').gsub(/^method$/, 'local_method')
|
97
|
+
slice_name = property.to_s.split(':')[1].gsub(/^class$/, 'local_class').gsub(/^method$/, 'local_method')
|
98
|
+
if metadata.present?
|
99
|
+
slice_by_name = metadata.must_supports[:slices].find { |slice| slice[:slice_name] == slice_name }
|
100
|
+
discriminator = slice_by_name[:discriminator]
|
101
|
+
slices = Array.wrap(element.send(element_name))
|
102
|
+
slices.find do |slice|
|
103
|
+
case discriminator[:type]
|
104
|
+
when 'patternCodeableConcept'
|
105
|
+
slice_value = discriminator[:path].present? ? slice.send(discriminator[:path].to_s)&.coding : slice.coding
|
106
|
+
slice_value&.any? { |coding| coding.code == discriminator[:code] && coding.system == discriminator[:system] }
|
107
|
+
when 'patternCoding'
|
108
|
+
slice_value = discriminator[:path].present? ? slice.send(discriminator[:path]) : slice
|
109
|
+
slice_value&.code == discriminator[:code] && slice_value&.system == discriminator[:system]
|
110
|
+
when 'patternIdentifier'
|
111
|
+
slice.identifier.system == discriminator[:system]
|
112
|
+
when 'value'
|
113
|
+
values = discriminator[:values].map { |value| value.merge(path: value[:path].split('.')) }
|
114
|
+
verify_slice_by_values(slice, values)
|
115
|
+
when 'type'
|
116
|
+
case discriminator[:code]
|
117
|
+
when 'Date'
|
118
|
+
begin
|
119
|
+
Date.parse(slice)
|
120
|
+
rescue ArgumentError # rubocop:disable Metrics/BlockNesting
|
121
|
+
false
|
122
|
+
end
|
123
|
+
when 'DateTime'
|
124
|
+
begin
|
125
|
+
DateTime.parse(slice)
|
126
|
+
rescue ArgumentError # rubocop:disable Metrics/BlockNesting
|
127
|
+
false
|
128
|
+
end
|
129
|
+
when 'String'
|
130
|
+
slice.is_a? String
|
131
|
+
else
|
132
|
+
if slice.is_a? FHIR::Bundle::Entry # rubocop:disable Metrics/BlockNesting
|
133
|
+
slice.resource.resourceType == discriminator[:code]
|
134
|
+
else
|
135
|
+
slice.is_a? FHIR.const_get(discriminator[:code])
|
136
|
+
end
|
137
|
+
end
|
138
|
+
when 'requiredBinding'
|
139
|
+
discriminator[:path].present? ? slice.send(discriminator[:path].to_s).coding : slice.coding
|
140
|
+
slice_value { |coding| discriminator[:values].include?(coding.code) }
|
141
|
+
end
|
142
|
+
end
|
143
|
+
else # rubocop:disable Style/EmptyElse
|
144
|
+
# TODO: Error handling for if this file doesn't have access to metadata for some reason (begin/rescue with StandardError?)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def verify_slice_by_values(element, value_definitions) # rubocop:disable Metrics/CyclomaticComplexity
|
149
|
+
path_prefixes = value_definitions.map { |value_definition| value_definition[:path].first }.uniq
|
150
|
+
path_prefixes.all? do |path_prefix|
|
151
|
+
value_definitions_for_path =
|
152
|
+
value_definitions
|
153
|
+
.select { |value_definition| value_definition[:path].first == path_prefix }
|
154
|
+
.each { |value_definition| value_definition[:path].shift }
|
155
|
+
find_a_value_at(element, path_prefix) do |el_found|
|
156
|
+
child_element_value_definitions, current_element_value_definitions =
|
157
|
+
value_definitions_for_path.partition { |value_definition| value_definition[:path].present? }
|
158
|
+
|
159
|
+
current_element_values_match =
|
160
|
+
current_element_value_definitions
|
161
|
+
.all? { |value_definition| value_definition[:value] == el_found }
|
162
|
+
|
163
|
+
child_element_values_match =
|
164
|
+
if child_element_value_definitions.present?
|
165
|
+
verify_slice_by_values(el_found, child_element_value_definitions)
|
166
|
+
else
|
167
|
+
true
|
168
|
+
end
|
169
|
+
current_element_values_match && child_element_values_match
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module CancerPathologyDataSharingTestKit
|
2
|
+
class GroupMetadata
|
3
|
+
ATTRIBUTES = [
|
4
|
+
:name,
|
5
|
+
:class_name,
|
6
|
+
:version,
|
7
|
+
:reformatted_version,
|
8
|
+
:resource,
|
9
|
+
:profile_url,
|
10
|
+
:profile_name,
|
11
|
+
:profile_version,
|
12
|
+
:title,
|
13
|
+
:short_description,
|
14
|
+
:is_delayed,
|
15
|
+
:interactions,
|
16
|
+
:operations,
|
17
|
+
:searches,
|
18
|
+
:search_definitions,
|
19
|
+
:include_params,
|
20
|
+
:revincludes,
|
21
|
+
:required_concepts,
|
22
|
+
:must_supports,
|
23
|
+
:mandatory_elements,
|
24
|
+
:bindings,
|
25
|
+
:references,
|
26
|
+
:tests,
|
27
|
+
:id,
|
28
|
+
:file_name,
|
29
|
+
:delayed_references
|
30
|
+
].freeze
|
31
|
+
|
32
|
+
ATTRIBUTES.each { |name| attr_accessor name }
|
33
|
+
|
34
|
+
def initialize(metadata)
|
35
|
+
metadata.each do |key, value|
|
36
|
+
raise "Unknown attribute #{key}" unless ATTRIBUTES.include? key
|
37
|
+
|
38
|
+
instance_variable_set(:"@#{key}", value)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def exclude_search_tests?
|
43
|
+
delayed? && !searchable_delayed_resource?
|
44
|
+
end
|
45
|
+
|
46
|
+
def add_test(id:, file_name:)
|
47
|
+
self.tests ||= []
|
48
|
+
test_metadata = {
|
49
|
+
id: id,
|
50
|
+
file_name: file_name
|
51
|
+
}
|
52
|
+
self.tests << test_metadata
|
53
|
+
end
|
54
|
+
|
55
|
+
def add_granular_scope_test(id:, file_name:)
|
56
|
+
self.granular_scope_tests ||= []
|
57
|
+
|
58
|
+
self.granular_scope_tests << {
|
59
|
+
id:,
|
60
|
+
file_name:
|
61
|
+
}
|
62
|
+
end
|
63
|
+
|
64
|
+
def to_hash
|
65
|
+
ATTRIBUTES.each_with_object({}) { |key, hash| hash[key] = send(key) unless send(key).nil? }
|
66
|
+
end
|
67
|
+
|
68
|
+
def add_delayed_references(delayed_profiles, ig_resources)
|
69
|
+
self.delayed_references =
|
70
|
+
references
|
71
|
+
.select { |reference| (reference[:profiles] & delayed_profiles).present? }
|
72
|
+
.map do |reference|
|
73
|
+
profile_urls = (reference[:profiles] & delayed_profiles)
|
74
|
+
delayed_resources = profile_urls.map { |url| ig_resources.resource_for_profile(url) }
|
75
|
+
{
|
76
|
+
path: reference[:path].gsub("#{resource}.", ''),
|
77
|
+
resources: delayed_resources
|
78
|
+
}
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
File without changes
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# Note on this IGs folder
|
2
|
+
|
3
|
+
There are three reasons why it would be necessary to put an IG package.tgz in this folder. If none of these apply, you do not need to put any files here, or can consider removing any existing files to make it clear they are unused.
|
4
|
+
|
5
|
+
## 1. Generated Test Suites
|
6
|
+
Some test kits use a "generator" to automatically generate the contents of a test suite for an IG. The IG files are required every time the test suites need to be regenerated. Examples of test kits that use this approach are the US Core Test Kit and CARIN IG for Blue Button® Test Kit.
|
7
|
+
|
8
|
+
|
9
|
+
## 2. Non-published IG
|
10
|
+
If your IG, or the specific version of the IG you want to test against, is not published, then the validator service needs to load the IG from file in order to be able to validate resources with it. The IG must be referenced in the `fhir_resource_validator` block in the test suite definition by filename, ie:
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
fhir_resource_validator do
|
14
|
+
igs 'igs/filename.tgz'
|
15
|
+
|
16
|
+
...
|
17
|
+
end
|
18
|
+
```
|
19
|
+
|
20
|
+
## 3. Inferno Validator UI
|
21
|
+
The Inferno Validator UI is configured to auto-load any IGs present in the igs folder and include them in all validations. In general, the Inferno team is currently leaving IGs in this folder even if not otherwise necessary to make it easy to re-enable the validator UI.
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require_relative 'version'
|
2
|
+
|
3
|
+
module CancerPathologyDataSharingTestKit
|
4
|
+
class Metadata < Inferno::TestKit
|
5
|
+
id :cancer_pathology_data_sharing_test_kit
|
6
|
+
title 'Cancer Pathology Data Sharing IG Test Kit'
|
7
|
+
description <<~DESCRIPTION
|
8
|
+
|
9
|
+
The Cancer Pathology Data Sharing (CPDS) Test Kit is a testing tool for Health IT systems
|
10
|
+
seeking to meet the requirements of the STU 1.0.0 version of the HL7® FHIR®
|
11
|
+
[Cancer Pathology Data Sharing IG](https://hl7.org/fhir/us/cancer-reporting/STU1.0.1/).
|
12
|
+
|
13
|
+
<!-- break -->
|
14
|
+
|
15
|
+
This test kit currently contains suites that verify the conformance of systems playing the following roles:
|
16
|
+
- **Report Generation**: Verifies that the Health IT system can generate
|
17
|
+
conformant and complete cancer pathology reports to send to a cancer registry.
|
18
|
+
- **Data Access**: Verifies that the Health IT system can respond to queries
|
19
|
+
for the data needed to create a cancer pathology report.
|
20
|
+
|
21
|
+
## Getting Started
|
22
|
+
|
23
|
+
To run CPDS tests, select the suite corresponding to the functionality you wish to test
|
24
|
+
and click ‘Create Test Session’.
|
25
|
+
|
26
|
+
## Status
|
27
|
+
|
28
|
+
These tests are a **DRAFT** intended to allow CPDS IG implementers to
|
29
|
+
perform preliminary checks of their implementations against the IG's requirements and provide feedback
|
30
|
+
on the tests. Future versions of these tests may validate other requirements and may change how these
|
31
|
+
are tested.
|
32
|
+
|
33
|
+
## Known Limitations
|
34
|
+
|
35
|
+
This test kit does not currently include test suites for all actors and all capabilities defined by the CPDS IG.
|
36
|
+
Out of scope areas of the IG include the Cancer Registry actor and details related to the use of the
|
37
|
+
[MedMorph framework](https://hl7.org/fhir/us/medmorph/STU1/) by all actors to coordinate reporting triggering,
|
38
|
+
report content, and report delivery requirements.
|
39
|
+
|
40
|
+
The existing Report Generation and Data Access suites focus on report content and do not currently
|
41
|
+
test most details of the report exchange workflow. The following areas are not tested:
|
42
|
+
- Data Access requirements around authentication and authorization.
|
43
|
+
- Report Generation requirements around the gathering of report contents from clinical systems and the
|
44
|
+
delivery of completed reports using FHIR APIs.
|
45
|
+
|
46
|
+
For additional details on suite-specific limitations, see the suite documention in the running tests or the
|
47
|
+
corresponding content in the source repository ([Data Access suite limitations](https://github.com/inferno-framework/cancer-pathology-data-sharing-test-kit/blob/main/lib/cancer_pathology_data_sharing_test_kit/docs/data_access_suite_description.md#current-limitations),
|
48
|
+
[Report Generation suite limitations](https://github.com/inferno-framework/cancer-pathology-data-sharing-test-kit/blob/main/lib/cancer_pathology_data_sharing_test_kit/docs/report_generation_suite_description.md#current-limitations))
|
49
|
+
|
50
|
+
## Repository and Resources
|
51
|
+
|
52
|
+
The Cancer Pathology Data Sharing Test Kit can be [downloaded](https://github.com/inferno-framework/cancer-pathology-data-sharing-test-kit/releases)
|
53
|
+
from its [GitHub repository](https://github.com/inferno-framework/cancer-pathology-data-sharing-test-kit).
|
54
|
+
|
55
|
+
## Providing Feedback and Reporting Issues
|
56
|
+
|
57
|
+
We welcome feedback on the tests, including but not limited to the following areas:
|
58
|
+
- Validation logic, such as potential bugs, lax checks, and unexpected failures.
|
59
|
+
- Requirements coverage, such as requirements that have been missed, tests that necessitate features that the
|
60
|
+
IG does not require, or other issues with the interpretation of the IG’s requirements.
|
61
|
+
- User experience, such as confusing or missing information in the test UI.
|
62
|
+
|
63
|
+
Please report any issues with this set of tests in the [issues section](https://github.com/inferno-framework/cancer-pathology-data-sharing-test-kit/issues)
|
64
|
+
of the repository.
|
65
|
+
|
66
|
+
DESCRIPTION
|
67
|
+
suite_ids [:cpds_report_generation, :cpds_data_access]
|
68
|
+
tags []
|
69
|
+
last_updated LAST_UPDATED
|
70
|
+
version VERSION
|
71
|
+
maturity 'Low'
|
72
|
+
authors ['MITRE Inferno Team']
|
73
|
+
repo 'https://github.com/inferno-framework/cancer-pathology-data-sharing-test-kit/'
|
74
|
+
end
|
75
|
+
end
|