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,239 @@
|
|
1
|
+
require_relative 'fhir_resource_navigation'
|
2
|
+
|
3
|
+
module CancerPathologyDataSharingTestKit
|
4
|
+
module MustSupportTest
|
5
|
+
extend Forwardable
|
6
|
+
include FHIRResourceNavigation
|
7
|
+
|
8
|
+
def_delegators 'self.class', :metadata
|
9
|
+
|
10
|
+
def all_scratch_resources
|
11
|
+
scratch_resources[:all]
|
12
|
+
end
|
13
|
+
|
14
|
+
def perform_must_support_test(resources)
|
15
|
+
skip_if resources.blank?, "No #{resource_type} resources were found"
|
16
|
+
|
17
|
+
missing_elements(resources)
|
18
|
+
missing_slices(resources)
|
19
|
+
missing_extensions(resources)
|
20
|
+
|
21
|
+
handle_must_support_choices if metadata.must_supports[:choices].present?
|
22
|
+
|
23
|
+
assert (missing_elements + missing_slices + missing_extensions).empty?, "Could not find #{missing_must_support_strings.join(', ')} " \
|
24
|
+
"in the #{resources.length} " \
|
25
|
+
"provided #{resource_type} resource(s)"
|
26
|
+
end
|
27
|
+
|
28
|
+
def handle_must_support_choices # rubocop:disable Metrics/CyclomaticComplexity
|
29
|
+
missing_elements.delete_if do |element|
|
30
|
+
choices = metadata.must_supports[:choices].find { |choice| choice[:paths]&.include?(element[:path]) }
|
31
|
+
is_any_choice_supported?(choices)
|
32
|
+
end
|
33
|
+
|
34
|
+
missing_extensions.delete_if do |extension|
|
35
|
+
choices = metadata.must_supports[:choices].find { |choice| choice[:extension_ids]&.include?(extension[:id]) }
|
36
|
+
is_any_choice_supported?(choices)
|
37
|
+
end
|
38
|
+
|
39
|
+
missing_slices.delete_if do |slice|
|
40
|
+
choices = metadata.must_supports[:choices].find { |choice| choice[:slice_names]&.include?(slice[:name]) }
|
41
|
+
is_any_choice_supported?(choices)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def is_any_choice_supported?(choices) # rubocop:disable Metrics/CyclomaticComplexity,Naming/PredicateName
|
46
|
+
choices.present? &&
|
47
|
+
(
|
48
|
+
choices[:paths]&.any? { |path| missing_elements.none? { |element| element[:path] == path } } ||
|
49
|
+
choices[:extension_ids]&.any? { |extension_id| missing_extensions.none? { |extension| extension[:id] == extension_id } } ||
|
50
|
+
choices[:slice_names]&.any? { |slice_name| missing_slices.none? { |slice| slice[:name] == slice_name } }
|
51
|
+
)
|
52
|
+
end
|
53
|
+
|
54
|
+
def missing_must_support_strings
|
55
|
+
missing_elements.map { |element_definition| missing_element_string(element_definition) } +
|
56
|
+
missing_slices.map { |slice_definition| slice_definition[:slice_id] } +
|
57
|
+
missing_extensions.map { |extension_definition| extension_definition[:id] }
|
58
|
+
end
|
59
|
+
|
60
|
+
def missing_element_string(element_definition)
|
61
|
+
if element_definition[:fixed_value].present?
|
62
|
+
"#{element_definition[:path]}:#{element_definition[:fixed_value]}"
|
63
|
+
else
|
64
|
+
element_definition[:path]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def exclude_uscdi_only_test?
|
69
|
+
config.options[:exclude_uscdi_only_test] == true
|
70
|
+
end
|
71
|
+
|
72
|
+
def must_support_extensions
|
73
|
+
if exclude_uscdi_only_test?
|
74
|
+
metadata.must_supports[:extensions].reject { |extension| extension[:uscdi_only] }
|
75
|
+
else
|
76
|
+
metadata.must_supports[:extensions]
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def missing_extensions(resources = [])
|
81
|
+
@missing_extensions ||=
|
82
|
+
must_support_extensions.select do |extension_definition|
|
83
|
+
resources.none? do |resource|
|
84
|
+
path = extension_definition[:path]
|
85
|
+
|
86
|
+
if path == 'extension'
|
87
|
+
resource.extension.any? { |extension| extension.url == extension_definition[:url] }
|
88
|
+
else
|
89
|
+
extension = find_a_value_at(resource, path) do |el|
|
90
|
+
el.url == extension_definition[:url]
|
91
|
+
end
|
92
|
+
|
93
|
+
extension.present?
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def must_support_elements
|
100
|
+
if exclude_uscdi_only_test?
|
101
|
+
metadata.must_supports[:elements].reject { |element| element[:uscdi_only] }
|
102
|
+
else
|
103
|
+
metadata.must_supports[:elements]
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def missing_elements(resources = [])
|
108
|
+
@missing_elements ||= find_missing_elements(resources, must_support_elements)
|
109
|
+
@missing_elements
|
110
|
+
end
|
111
|
+
|
112
|
+
def find_missing_elements(resources, must_support_elements) # rubocop:disable Metrics/CyclomaticComplexity
|
113
|
+
must_support_elements.select do |element_definition|
|
114
|
+
resources.none? do |resource|
|
115
|
+
path = element_definition[:path]
|
116
|
+
ms_extension_urls = must_support_extensions.select { |ex| ex[:path] == "#{path}.extension" }
|
117
|
+
.map { |ex| ex[:url] }
|
118
|
+
|
119
|
+
value_found = find_a_value_at(resource, path) do |value|
|
120
|
+
if value.instance_of?(CancerPathologyDataSharingTestKit::PrimitiveType) && ms_extension_urls.present?
|
121
|
+
urls = value.extension&.map(&:url)
|
122
|
+
has_ms_extension = (urls & ms_extension_urls).present?
|
123
|
+
end
|
124
|
+
|
125
|
+
unless has_ms_extension
|
126
|
+
value = value.value if value.instance_of?(CancerPathologyDataSharingTestKit::PrimitiveType)
|
127
|
+
value_without_extensions =
|
128
|
+
value.respond_to?(:to_hash) ? value.to_hash.except('extension') : value
|
129
|
+
end
|
130
|
+
|
131
|
+
(has_ms_extension || value_without_extensions.present? || value_without_extensions == false) &&
|
132
|
+
(element_definition[:fixed_value].blank? || value == element_definition[:fixed_value])
|
133
|
+
end
|
134
|
+
# Note that false.present? => false, which is why we need to add this extra check
|
135
|
+
value_found.present? || value_found == false
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def must_support_slices
|
141
|
+
if exclude_uscdi_only_test?
|
142
|
+
metadata.must_supports[:slices].reject { |slice| slice[:uscdi_only] }
|
143
|
+
else
|
144
|
+
metadata.must_supports[:slices]
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def missing_slices(resources = [])
|
149
|
+
@missing_slices ||=
|
150
|
+
must_support_slices.select do |slice|
|
151
|
+
resources.none? do |resource|
|
152
|
+
path = slice[:path] # .delete_suffix('[x]')
|
153
|
+
find_slice(resource, path, slice[:discriminator]).present?
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def find_slice(resource, path, discriminator) # rubocop:disable Metrics/CyclomaticComplexity
|
159
|
+
find_a_value_at(resource, path) do |element|
|
160
|
+
case discriminator[:type]
|
161
|
+
when 'patternCodeableConcept'
|
162
|
+
coding_path = discriminator[:path].present? ? "#{discriminator[:path]}.coding" : 'coding'
|
163
|
+
find_a_value_at(element, coding_path) do |coding|
|
164
|
+
coding.code == discriminator[:code] && coding.system == discriminator[:system]
|
165
|
+
end
|
166
|
+
when 'patternCoding'
|
167
|
+
coding_path = discriminator[:path].present? ? discriminator[:path] : ''
|
168
|
+
find_a_value_at(element, coding_path) do |coding|
|
169
|
+
coding.code == discriminator[:code] && coding.system == discriminator[:system]
|
170
|
+
end
|
171
|
+
when 'patternIdentifier'
|
172
|
+
find_a_value_at(element, discriminator[:path]) { |identifier| identifier.system == discriminator[:system] }
|
173
|
+
when 'value'
|
174
|
+
values = discriminator[:values].map { |value| value.merge(path: value[:path].split('.')) }
|
175
|
+
find_slice_by_values(element, values)
|
176
|
+
when 'type'
|
177
|
+
case discriminator[:code]
|
178
|
+
when 'Date'
|
179
|
+
begin
|
180
|
+
Date.parse(element)
|
181
|
+
rescue ArgumentError
|
182
|
+
false
|
183
|
+
end
|
184
|
+
when 'DateTime'
|
185
|
+
begin
|
186
|
+
DateTime.parse(element)
|
187
|
+
rescue ArgumentError
|
188
|
+
false
|
189
|
+
end
|
190
|
+
when 'String'
|
191
|
+
element.is_a? String
|
192
|
+
else
|
193
|
+
if element.is_a? FHIR::Bundle::Entry
|
194
|
+
element.resource.resourceType == discriminator[:code]
|
195
|
+
else
|
196
|
+
element.is_a? FHIR.const_get(discriminator[:code])
|
197
|
+
end
|
198
|
+
end
|
199
|
+
when 'requiredBinding'
|
200
|
+
coding_path = discriminator[:path].present? ? "#{discriminator[:path]}.coding" : 'coding'
|
201
|
+
|
202
|
+
find_a_value_at(element, coding_path) do |coding|
|
203
|
+
discriminator[:values].any? { |value| value[:system] == coding.system && value[:code] == coding.code }
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
def find_slice_by_values(element, value_definitions) # rubocop:disable Metrics/CyclomaticComplexity
|
210
|
+
path_prefixes = value_definitions.map { |value_definition| value_definition[:path].first }.uniq
|
211
|
+
Array.wrap(element).find do |el|
|
212
|
+
path_prefixes.all? do |path_prefix|
|
213
|
+
value_definitions_for_path =
|
214
|
+
value_definitions
|
215
|
+
.select { |value_definition| value_definition[:path].first == path_prefix }
|
216
|
+
.each { |value_definition| value_definition[:path].shift }
|
217
|
+
|
218
|
+
find_a_value_at(el, path_prefix) do |el_found|
|
219
|
+
child_element_value_definitions, current_element_value_definitions =
|
220
|
+
value_definitions_for_path.partition { |value_definition| value_definition[:path].present? }
|
221
|
+
|
222
|
+
current_element_values_match =
|
223
|
+
current_element_value_definitions
|
224
|
+
.all? { |value_definition| value_definition[:value] == el_found }
|
225
|
+
|
226
|
+
child_element_values_match =
|
227
|
+
if child_element_value_definitions.present?
|
228
|
+
find_slice_by_values(el_found, child_element_value_definitions)
|
229
|
+
else
|
230
|
+
true
|
231
|
+
end
|
232
|
+
|
233
|
+
current_element_values_match && child_element_values_match
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module CancerPathologyDataSharingTestKit
|
2
|
+
class DataAbsentReasonCodeSystem < Inferno::Test
|
3
|
+
id :cpds_data_absent_reason_code_system
|
4
|
+
title 'Server represents missing data with the DataAbsentReason CodeSystem'
|
5
|
+
description %(
|
6
|
+
For coded data elements with example, preferred, or extensible binding
|
7
|
+
strengths to ValueSets which do not include an appropriate "unknown"
|
8
|
+
code, servers SHALL use the "unknown" code from the DataAbsentReason
|
9
|
+
CodeSystem.
|
10
|
+
)
|
11
|
+
input :dar_code_found,
|
12
|
+
title: 'Data Absent Reason CodeSystem Found',
|
13
|
+
locked: true,
|
14
|
+
optional: true,
|
15
|
+
default: 'false'
|
16
|
+
|
17
|
+
run do
|
18
|
+
assert dar_code_found == 'true',
|
19
|
+
'No resources using the DataAbsentReason CodeSystem have been found'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module CancerPathologyDataSharingTestKit
|
2
|
+
class DataAbsentReasonExtension < Inferno::Test
|
3
|
+
id :cpds_data_absent_reason_extension
|
4
|
+
title 'Server represents missing data with the DataAbsentReason Extension'
|
5
|
+
description %(
|
6
|
+
For non-coded data elements, servers SHALL use the DataAbsentReason
|
7
|
+
Extension to represent missing data in a required field
|
8
|
+
)
|
9
|
+
input :dar_extension_found,
|
10
|
+
title: 'Data Absent Reason Extension Found',
|
11
|
+
locked: true,
|
12
|
+
optional: true,
|
13
|
+
default: 'false'
|
14
|
+
|
15
|
+
run do
|
16
|
+
assert dar_extension_found == 'true',
|
17
|
+
'No resources using the DataAbsentReason Extension have been found'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module CancerPathologyDataSharingTestKit
|
2
|
+
class SendingHideMissing < Inferno::Test
|
3
|
+
id :cpds_data_absent_sending_hide_missing
|
4
|
+
title 'Sender does not send data element(s) with missing information'
|
5
|
+
description %(
|
6
|
+
In situations where information on a particular data element is not present, the Sender SHALL NOT include the data element
|
7
|
+
in the resource instance if the cardinality is 0..n.
|
8
|
+
)
|
9
|
+
|
10
|
+
run do
|
11
|
+
identifier = SecureRandom.hex(32)
|
12
|
+
wait(
|
13
|
+
identifier:,
|
14
|
+
message: <<~MESSAGE
|
15
|
+
The system under test has demonstrated that it meets the following [requirement](https://hl7.org/fhir/us/cancer-reporting/STU1.0.1/specification.html#must-support-and-missing-data):
|
16
|
+
|
17
|
+
[Specifically](https://hl7.org/fhir/us/cancer-reporting/STU1.0.1/specification.html#must-support-and-missing-data)
|
18
|
+
|
19
|
+
> Sending Systems [of the [US Pathology Bundle](https://hl7.org/fhir/us/cancer-reporting/STU1.0.1/StructureDefinition-us-pathology-exchange-bundle.html)] In situations where information on a particular data element is not present, the Sender SHALL NOT include the data element in the resource instance if the cardinality is 0..n.
|
20
|
+
|
21
|
+
[Click here](#{resume_pass_url}?token=#{identifier}) if the system **meets** this requirement.
|
22
|
+
|
23
|
+
[Click here](#{resume_fail_url}?token=#{identifier}) if the system **does not meet** this requirement.
|
24
|
+
MESSAGE
|
25
|
+
)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require_relative 'data_absent/sending_hide_missing'
|
2
|
+
require_relative 'data_absent/data_absent_reason_extension'
|
3
|
+
require_relative 'data_absent/data_absent_reason_code_system'
|
4
|
+
|
5
|
+
module CancerPathologyDataSharingTestKit
|
6
|
+
class DataAbsentGroup < Inferno::TestGroup
|
7
|
+
id :cpds_data_absent_reason
|
8
|
+
title 'Missing Data Tests'
|
9
|
+
short_description 'Verify that the server is capable of representing missing data.'
|
10
|
+
|
11
|
+
description %(
|
12
|
+
The [CPDS Missing Data
|
13
|
+
Guidance](https://hl7.org/fhir/us/cancer-reporting/STU1.0.1/specification.html#must-support-and-missing-data)
|
14
|
+
gives instructions on how to represent various types of missing data.
|
15
|
+
|
16
|
+
In the previous resource tests, each resource returned from the server was
|
17
|
+
checked for the presence of missing data. These tests will pass if the
|
18
|
+
specified method of representing missing data was observed in the earlier
|
19
|
+
tests.
|
20
|
+
)
|
21
|
+
run_as_group
|
22
|
+
|
23
|
+
test from: :cpds_data_absent_sending_hide_missing
|
24
|
+
test from: :cpds_data_absent_reason_extension
|
25
|
+
test from: :cpds_data_absent_reason_code_system
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require_relative '../../../must_support_test'
|
2
|
+
require_relative '../../../group_metadata'
|
3
|
+
|
4
|
+
module CancerPathologyDataSharingTestKit
|
5
|
+
module V101
|
6
|
+
class EncounterMustSupportTest < Inferno::Test
|
7
|
+
include CancerPathologyDataSharingTestKit::MustSupportTest
|
8
|
+
|
9
|
+
title 'All must support elements are provided in the US Core Encounter resources'
|
10
|
+
description %(
|
11
|
+
Report generators SHALL be capable of populating all must support data elements
|
12
|
+
defined in the [US Pathology ExchangeBundle profile](https://hl7.org/fhir/us/cancer-reporting/STU1.0.1/StructureDefinition-us-pathology-exchange-bundle.html)
|
13
|
+
and profiles it references. This test will look through the Encounter resources
|
14
|
+
found in the provided report Bundles for the following must support elements:
|
15
|
+
|
16
|
+
* Encounter.class
|
17
|
+
* Encounter.hospitalization
|
18
|
+
* Encounter.hospitalization.dischargeDisposition
|
19
|
+
* Encounter.identifier
|
20
|
+
* Encounter.identifier.system
|
21
|
+
* Encounter.identifier.value
|
22
|
+
* Encounter.location
|
23
|
+
* Encounter.location.location
|
24
|
+
* Encounter.participant
|
25
|
+
* Encounter.participant.individual
|
26
|
+
* Encounter.participant.period
|
27
|
+
* Encounter.participant.type
|
28
|
+
* Encounter.period
|
29
|
+
* Encounter.reasonCode
|
30
|
+
* Encounter.status
|
31
|
+
* Encounter.subject
|
32
|
+
* Encounter.type
|
33
|
+
)
|
34
|
+
|
35
|
+
id :cpds_v101_us_core_v311_encounter_must_support_test
|
36
|
+
|
37
|
+
def resource_type
|
38
|
+
'Encounter'
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.metadata
|
42
|
+
@metadata ||= GroupMetadata.new(YAML.load_file(File.join(__dir__, 'metadata.yml'), aliases: true))
|
43
|
+
end
|
44
|
+
|
45
|
+
run do
|
46
|
+
all_resources = scratch[:cpds_resources]&.values&.map do |bundle_resources|
|
47
|
+
bundle_resources['Encounter'] || []
|
48
|
+
end
|
49
|
+
perform_must_support_test(all_resources&.flatten)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require_relative '../../../bundle_parse'
|
2
|
+
require_relative '../../../validation_test'
|
3
|
+
|
4
|
+
module CancerPathologyDataSharingTestKit
|
5
|
+
class EncounterValidationTest < Inferno::Test
|
6
|
+
include CancerPathologyDataSharingTestKit::ValidationTest
|
7
|
+
include CancerPathologyDataSharingTestKit::BundleParse
|
8
|
+
|
9
|
+
title 'Encounter resource in each bundle conforms to the US Core Encounter profile'
|
10
|
+
description %(
|
11
|
+
This test verifies that any Encounter resource returned from each bundle conforms to
|
12
|
+
the [US Core Encounter Profile](http://hl7.org/fhir/us/core/StructureDefinition/us-core-encounter).
|
13
|
+
|
14
|
+
It verifies the presence of mandatory elements and that elements with
|
15
|
+
required bindings contain appropriate values. CodeableConcept element
|
16
|
+
bindings will fail if none of their codings have a code/system belonging
|
17
|
+
to the bound ValueSet. Quantity, Coding, and code element bindings will
|
18
|
+
fail if their code/system are not found in the valueset.
|
19
|
+
)
|
20
|
+
|
21
|
+
id :cpds_encounter_validation_test
|
22
|
+
|
23
|
+
def resource_type
|
24
|
+
'Encounter'
|
25
|
+
end
|
26
|
+
|
27
|
+
output :dar_code_found, :dar_extension_found
|
28
|
+
|
29
|
+
run do
|
30
|
+
invalid_bundles = []
|
31
|
+
total_resources = 0
|
32
|
+
scratch[:cpds_resources].each do |bundle_id, bundle_resources|
|
33
|
+
resources = bundle_resources['Encounter'] || []
|
34
|
+
total_resources += resources.length
|
35
|
+
|
36
|
+
profile_url = PE_BUNDLE_SLICE_RESOURCES['Encounter']
|
37
|
+
invalid_bundles << bundle_id if perform_strict_validation_test('Encounter', bundle_id, resources, profile_url,
|
38
|
+
'5.0.1', skip_if_empty: false,
|
39
|
+
restriction: 'no_more_than_one')
|
40
|
+
end
|
41
|
+
|
42
|
+
skip_if total_resources.zero?,
|
43
|
+
"No #{resource_type} resources found in any of the given bundles"
|
44
|
+
|
45
|
+
check_for_errors(invalid_bundles)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|