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.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +201 -0
  3. data/config/presets/demo_report.json +14 -0
  4. data/config/presets/inferno_reference_server_preset.json.erb +39 -0
  5. data/lib/cancer_pathology_data_sharing_test_kit/bundle_parse.rb +53 -0
  6. data/lib/cancer_pathology_data_sharing_test_kit/docs/data_access_suite_description.md +83 -0
  7. data/lib/cancer_pathology_data_sharing_test_kit/docs/report_generation_suite_description.md +118 -0
  8. data/lib/cancer_pathology_data_sharing_test_kit/fhir_resource_navigation.rb +174 -0
  9. data/lib/cancer_pathology_data_sharing_test_kit/group_metadata.rb +82 -0
  10. data/lib/cancer_pathology_data_sharing_test_kit/igs/.keep +0 -0
  11. data/lib/cancer_pathology_data_sharing_test_kit/igs/README.md +21 -0
  12. data/lib/cancer_pathology_data_sharing_test_kit/metadata.rb +75 -0
  13. data/lib/cancer_pathology_data_sharing_test_kit/must_support_test.rb +239 -0
  14. data/lib/cancer_pathology_data_sharing_test_kit/primitive_type.rb +5 -0
  15. data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/data_absent/data_absent_reason_code_system.rb +22 -0
  16. data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/data_absent/data_absent_reason_extension.rb +20 -0
  17. data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/data_absent/sending_hide_missing.rb +28 -0
  18. data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/data_absent_group.rb +27 -0
  19. data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/encounter/encounter_must_support_test.rb +53 -0
  20. data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/encounter/encounter_validation_test.rb +48 -0
  21. data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/encounter/metadata.yml +281 -0
  22. data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/patient/metadata.yml +305 -0
  23. data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/patient/patient_must_support_test.rb +58 -0
  24. data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/patient/patient_validation_test.rb +47 -0
  25. data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/practitioner_role/metadata.yml +44 -0
  26. data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/practitioner_role/practitioner_role_must_support_test.rb +45 -0
  27. data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/practitioner_role/practitioner_role_validation_test.rb +47 -0
  28. data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/service_request/metadata.yml +75 -0
  29. data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/service_request/service_request_must_support_test.rb +52 -0
  30. data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/service_request/service_request_validation_test.rb +47 -0
  31. data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/specimen/metadata.yml +51 -0
  32. data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/specimen/specimen_must_support_test.rb +53 -0
  33. data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/specimen/specimen_validation_test.rb +47 -0
  34. data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/us_pathology_diagnostic_report/diagnostic_report_validation_test.rb +47 -0
  35. data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/us_pathology_diagnostic_report/metadata.yml +77 -0
  36. 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
  37. data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/us_pathology_exchange_bundle/exchange_bundle_validation_test.rb +56 -0
  38. data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle/us_pathology_exchange_bundle/metadata.yml +78 -0
  39. 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
  40. data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite/exchange_bundle_group.rb +104 -0
  41. data/lib/cancer_pathology_data_sharing_test_kit/report_generation_suite.rb +73 -0
  42. data/lib/cancer_pathology_data_sharing_test_kit/urls.rb +25 -0
  43. data/lib/cancer_pathology_data_sharing_test_kit/us_core_data_access_suite/us_core_group.rb +72 -0
  44. data/lib/cancer_pathology_data_sharing_test_kit/us_core_data_access_suite.rb +58 -0
  45. data/lib/cancer_pathology_data_sharing_test_kit/validation_test.rb +96 -0
  46. data/lib/cancer_pathology_data_sharing_test_kit/version.rb +4 -0
  47. data/lib/cancer_pathology_data_sharing_test_kit.rb +3 -0
  48. 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
@@ -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