us_core_test_kit 0.4.0 → 0.4.2
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 +4 -4
- data/lib/us_core_test_kit/generated/v3.1.1/allergy_intolerance/metadata.yml +1 -24
- data/lib/us_core_test_kit/generated/v3.1.1/bodyheight/metadata.yml +0 -52
- data/lib/us_core_test_kit/generated/v3.1.1/bodytemp/metadata.yml +0 -52
- data/lib/us_core_test_kit/generated/v3.1.1/bodyweight/metadata.yml +0 -52
- data/lib/us_core_test_kit/generated/v3.1.1/bp/metadata.yml +0 -76
- data/lib/us_core_test_kit/generated/v3.1.1/care_plan/metadata.yml +0 -28
- data/lib/us_core_test_kit/generated/v3.1.1/care_team/metadata.yml +0 -16
- data/lib/us_core_test_kit/generated/v3.1.1/condition/metadata.yml +1 -39
- data/lib/us_core_test_kit/generated/v3.1.1/device/metadata.yml +1 -1013
- data/lib/us_core_test_kit/generated/v3.1.1/diagnostic_report_lab/metadata.yml +1 -1021
- data/lib/us_core_test_kit/generated/v3.1.1/diagnostic_report_note/metadata.yml +1 -1017
- data/lib/us_core_test_kit/generated/v3.1.1/document_reference/document_reference_must_support_test.rb +0 -1
- data/lib/us_core_test_kit/generated/v3.1.1/document_reference/document_reference_reference_resolution_test.rb +0 -1
- data/lib/us_core_test_kit/generated/v3.1.1/document_reference/metadata.yml +1 -81
- data/lib/us_core_test_kit/generated/v3.1.1/encounter/metadata.yml +2 -85
- data/lib/us_core_test_kit/generated/v3.1.1/goal/metadata.yml +1 -46
- data/lib/us_core_test_kit/generated/v3.1.1/head_circumference/metadata.yml +0 -52
- data/lib/us_core_test_kit/generated/v3.1.1/heartrate/metadata.yml +0 -52
- data/lib/us_core_test_kit/generated/v3.1.1/immunization/metadata.yml +0 -48
- data/lib/us_core_test_kit/generated/v3.1.1/medication_request/metadata.yml +0 -60
- data/lib/us_core_test_kit/generated/v3.1.1/metadata.yml +14 -6471
- data/lib/us_core_test_kit/generated/v3.1.1/observation_lab/metadata.yml +1 -1053
- data/lib/us_core_test_kit/generated/v3.1.1/organization/metadata.yml +0 -20
- data/lib/us_core_test_kit/generated/v3.1.1/patient/metadata.yml +1 -29
- data/lib/us_core_test_kit/generated/v3.1.1/pediatric_bmi_for_age/metadata.yml +0 -52
- data/lib/us_core_test_kit/generated/v3.1.1/pediatric_weight_for_height/metadata.yml +0 -52
- data/lib/us_core_test_kit/generated/v3.1.1/practitioner/metadata.yml +0 -16
- data/lib/us_core_test_kit/generated/v3.1.1/procedure/metadata.yml +1 -1049
- data/lib/us_core_test_kit/generated/v3.1.1/provenance/metadata.yml +0 -36
- data/lib/us_core_test_kit/generated/v3.1.1/pulse_oximetry/metadata.yml +0 -76
- data/lib/us_core_test_kit/generated/v3.1.1/resprate/metadata.yml +0 -52
- data/lib/us_core_test_kit/generated/v3.1.1/smokingstatus/metadata.yml +1 -62
- data/lib/us_core_test_kit/generated/v3.1.1/us_core_test_suite.rb +20 -1
- data/lib/us_core_test_kit/generated/v4.0.0/allergy_intolerance/metadata.yml +1 -24
- data/lib/us_core_test_kit/generated/v4.0.0/blood_pressure/metadata.yml +0 -80
- data/lib/us_core_test_kit/generated/v4.0.0/bmi/metadata.yml +0 -56
- data/lib/us_core_test_kit/generated/v4.0.0/body_height/metadata.yml +0 -56
- data/lib/us_core_test_kit/generated/v4.0.0/body_temperature/metadata.yml +0 -56
- data/lib/us_core_test_kit/generated/v4.0.0/body_weight/metadata.yml +0 -56
- data/lib/us_core_test_kit/generated/v4.0.0/care_plan/metadata.yml +0 -28
- data/lib/us_core_test_kit/generated/v4.0.0/care_team/metadata.yml +0 -16
- data/lib/us_core_test_kit/generated/v4.0.0/condition/metadata.yml +1 -39
- data/lib/us_core_test_kit/generated/v4.0.0/device/metadata.yml +1 -1013
- data/lib/us_core_test_kit/generated/v4.0.0/diagnostic_report_lab/metadata.yml +1 -1021
- data/lib/us_core_test_kit/generated/v4.0.0/diagnostic_report_note/metadata.yml +1 -1017
- data/lib/us_core_test_kit/generated/v4.0.0/document_reference/metadata.yml +1 -78
- data/lib/us_core_test_kit/generated/v4.0.0/encounter/metadata.yml +2 -85
- data/lib/us_core_test_kit/generated/v4.0.0/goal/metadata.yml +1 -46
- data/lib/us_core_test_kit/generated/v4.0.0/head_circumference/metadata.yml +0 -56
- data/lib/us_core_test_kit/generated/v4.0.0/head_circumference_percentile/metadata.yml +0 -56
- data/lib/us_core_test_kit/generated/v4.0.0/heart_rate/metadata.yml +0 -56
- data/lib/us_core_test_kit/generated/v4.0.0/immunization/metadata.yml +0 -48
- data/lib/us_core_test_kit/generated/v4.0.0/medication_request/metadata.yml +0 -60
- data/lib/us_core_test_kit/generated/v4.0.0/metadata.yml +13 -6618
- data/lib/us_core_test_kit/generated/v4.0.0/observation_lab/metadata.yml +1 -1053
- data/lib/us_core_test_kit/generated/v4.0.0/organization/metadata.yml +0 -20
- data/lib/us_core_test_kit/generated/v4.0.0/patient/metadata.yml +1 -29
- data/lib/us_core_test_kit/generated/v4.0.0/pediatric_bmi_for_age/metadata.yml +0 -56
- data/lib/us_core_test_kit/generated/v4.0.0/pediatric_weight_for_height/metadata.yml +0 -56
- data/lib/us_core_test_kit/generated/v4.0.0/practitioner/metadata.yml +0 -16
- data/lib/us_core_test_kit/generated/v4.0.0/procedure/metadata.yml +1 -1049
- data/lib/us_core_test_kit/generated/v4.0.0/provenance/metadata.yml +0 -40
- data/lib/us_core_test_kit/generated/v4.0.0/pulse_oximetry/metadata.yml +0 -80
- data/lib/us_core_test_kit/generated/v4.0.0/respiratory_rate/metadata.yml +0 -56
- data/lib/us_core_test_kit/generated/v4.0.0/smokingstatus/metadata.yml +0 -56
- data/lib/us_core_test_kit/generated/v4.0.0/us_core_test_suite.rb +20 -1
- data/lib/us_core_test_kit/generated/v5.0.1/allergy_intolerance/metadata.yml +1 -24
- data/lib/us_core_test_kit/generated/v5.0.1/blood_pressure/metadata.yml +0 -80
- data/lib/us_core_test_kit/generated/v5.0.1/bmi/metadata.yml +0 -56
- data/lib/us_core_test_kit/generated/v5.0.1/body_height/metadata.yml +0 -56
- data/lib/us_core_test_kit/generated/v5.0.1/body_temperature/metadata.yml +0 -56
- data/lib/us_core_test_kit/generated/v5.0.1/body_weight/metadata.yml +0 -56
- data/lib/us_core_test_kit/generated/v5.0.1/care_plan/metadata.yml +0 -28
- data/lib/us_core_test_kit/generated/v5.0.1/care_team/metadata.yml +0 -16
- data/lib/us_core_test_kit/generated/v5.0.1/condition_encounter_diagnosis/metadata.yml +1 -43
- data/lib/us_core_test_kit/generated/v5.0.1/condition_problems_health_concerns/metadata.yml +2 -44
- data/lib/us_core_test_kit/generated/v5.0.1/device/metadata.yml +1 -1013
- data/lib/us_core_test_kit/generated/v5.0.1/diagnostic_report_lab/metadata.yml +1 -1021
- data/lib/us_core_test_kit/generated/v5.0.1/diagnostic_report_note/metadata.yml +1 -1021
- data/lib/us_core_test_kit/generated/v5.0.1/document_reference/metadata.yml +1 -82
- data/lib/us_core_test_kit/generated/v5.0.1/encounter/metadata.yml +2 -85
- data/lib/us_core_test_kit/generated/v5.0.1/goal/metadata.yml +2 -1047
- data/lib/us_core_test_kit/generated/v5.0.1/head_circumference/metadata.yml +0 -56
- data/lib/us_core_test_kit/generated/v5.0.1/head_circumference_percentile/metadata.yml +0 -56
- data/lib/us_core_test_kit/generated/v5.0.1/heart_rate/metadata.yml +0 -56
- data/lib/us_core_test_kit/generated/v5.0.1/immunization/metadata.yml +0 -48
- data/lib/us_core_test_kit/generated/v5.0.1/medication_request/metadata.yml +5 -65
- data/lib/us_core_test_kit/generated/v5.0.1/metadata.yml +27 -11041
- data/lib/us_core_test_kit/generated/v5.0.1/observation_clinical_test/metadata.yml +0 -52
- data/lib/us_core_test_kit/generated/v5.0.1/observation_imaging/metadata.yml +1 -1053
- data/lib/us_core_test_kit/generated/v5.0.1/observation_lab/metadata.yml +1 -1053
- data/lib/us_core_test_kit/generated/v5.0.1/observation_sdoh_assessment/metadata.yml +0 -57
- data/lib/us_core_test_kit/generated/v5.0.1/observation_sexual_orientation/metadata.yml +1 -62
- data/lib/us_core_test_kit/generated/v5.0.1/observation_social_history/metadata.yml +1 -1058
- data/lib/us_core_test_kit/generated/v5.0.1/organization/metadata.yml +0 -20
- data/lib/us_core_test_kit/generated/v5.0.1/patient/metadata.yml +1 -29
- data/lib/us_core_test_kit/generated/v5.0.1/pediatric_bmi_for_age/metadata.yml +0 -56
- data/lib/us_core_test_kit/generated/v5.0.1/pediatric_weight_for_height/metadata.yml +0 -56
- data/lib/us_core_test_kit/generated/v5.0.1/practitioner/metadata.yml +0 -20
- data/lib/us_core_test_kit/generated/v5.0.1/procedure/metadata.yml +1 -1049
- data/lib/us_core_test_kit/generated/v5.0.1/provenance/metadata.yml +0 -40
- data/lib/us_core_test_kit/generated/v5.0.1/pulse_oximetry/metadata.yml +0 -80
- data/lib/us_core_test_kit/generated/v5.0.1/questionnaire_response/metadata.yml +0 -20
- data/lib/us_core_test_kit/generated/v5.0.1/related_person/metadata.yml +0 -12
- data/lib/us_core_test_kit/generated/v5.0.1/respiratory_rate/metadata.yml +0 -56
- data/lib/us_core_test_kit/generated/v5.0.1/service_request/metadata.yml +1 -1041
- data/lib/us_core_test_kit/generated/v5.0.1/smokingstatus/metadata.yml +0 -56
- data/lib/us_core_test_kit/generated/v5.0.1/us_core_test_suite.rb +20 -1
- data/lib/us_core_test_kit/generator/must_support_metadata_extractor.rb +17 -7
- data/lib/us_core_test_kit/generator/search_definition_metadata_extractor.rb +13 -93
- data/lib/us_core_test_kit/generator/suite_generator.rb +11 -0
- data/lib/us_core_test_kit/generator/terminology_binding_metadata_extractor.rb +15 -3
- data/lib/us_core_test_kit/generator/value_extractor.rb +101 -0
- data/lib/us_core_test_kit/provenance_validator.rb +37 -0
- data/lib/us_core_test_kit/version.rb +1 -1
- metadata +4 -2
|
@@ -168,66 +168,10 @@
|
|
|
168
168
|
- Observation.value[x]
|
|
169
169
|
- Observation.component.code
|
|
170
170
|
:bindings:
|
|
171
|
-
- :type: code
|
|
172
|
-
:strength: preferred
|
|
173
|
-
:system: http://hl7.org/fhir/ValueSet/languages
|
|
174
|
-
:path: language
|
|
175
171
|
- :type: code
|
|
176
172
|
:strength: required
|
|
177
173
|
:system: http://hl7.org/fhir/us/core/ValueSet/us-core-observation-smoking-status-status
|
|
178
174
|
:path: status
|
|
179
|
-
- :type: CodeableConcept
|
|
180
|
-
:strength: preferred
|
|
181
|
-
:system: http://hl7.org/fhir/ValueSet/observation-category
|
|
182
|
-
:path: category
|
|
183
|
-
- :type: CodeableConcept
|
|
184
|
-
:strength: preferred
|
|
185
|
-
:system: http://hl7.org/fhir/ValueSet/observation-category
|
|
186
|
-
:path: category
|
|
187
|
-
- :type: CodeableConcept
|
|
188
|
-
:strength: extensible
|
|
189
|
-
:system: http://hl7.org/fhir/us/core/ValueSet/us-core-smoking-status-observation-codes
|
|
190
|
-
:path: code
|
|
191
|
-
- :type: CodeableConcept
|
|
192
|
-
:strength: preferred
|
|
193
|
-
:system: http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.11.20.9.38
|
|
194
|
-
:path: value
|
|
195
|
-
- :type: CodeableConcept
|
|
196
|
-
:strength: extensible
|
|
197
|
-
:system: http://hl7.org/fhir/ValueSet/data-absent-reason
|
|
198
|
-
:path: dataAbsentReason
|
|
199
|
-
- :type: CodeableConcept
|
|
200
|
-
:strength: extensible
|
|
201
|
-
:system: http://hl7.org/fhir/ValueSet/observation-interpretation
|
|
202
|
-
:path: interpretation
|
|
203
|
-
- :type: CodeableConcept
|
|
204
|
-
:strength: example
|
|
205
|
-
:system: http://hl7.org/fhir/ValueSet/body-site
|
|
206
|
-
:path: bodySite
|
|
207
|
-
- :type: CodeableConcept
|
|
208
|
-
:strength: example
|
|
209
|
-
:system: http://hl7.org/fhir/ValueSet/observation-methods
|
|
210
|
-
:path: method
|
|
211
|
-
- :type: CodeableConcept
|
|
212
|
-
:strength: preferred
|
|
213
|
-
:system: http://hl7.org/fhir/ValueSet/referencerange-meaning
|
|
214
|
-
:path: referenceRange.type
|
|
215
|
-
- :type: CodeableConcept
|
|
216
|
-
:strength: example
|
|
217
|
-
:system: http://hl7.org/fhir/ValueSet/referencerange-appliesto
|
|
218
|
-
:path: referenceRange.appliesTo
|
|
219
|
-
- :type: CodeableConcept
|
|
220
|
-
:strength: example
|
|
221
|
-
:system: http://hl7.org/fhir/ValueSet/observation-codes
|
|
222
|
-
:path: component.code
|
|
223
|
-
- :type: CodeableConcept
|
|
224
|
-
:strength: extensible
|
|
225
|
-
:system: http://hl7.org/fhir/ValueSet/data-absent-reason
|
|
226
|
-
:path: component.dataAbsentReason
|
|
227
|
-
- :type: CodeableConcept
|
|
228
|
-
:strength: extensible
|
|
229
|
-
:system: http://hl7.org/fhir/ValueSet/observation-interpretation
|
|
230
|
-
:path: component.interpretation
|
|
231
175
|
:references:
|
|
232
176
|
- :path: Observation.basedOn
|
|
233
177
|
:profiles:
|
|
@@ -3,6 +3,7 @@ require_relative '../../version'
|
|
|
3
3
|
require_relative '../../custom_groups/v5.0.1/capability_statement_group'
|
|
4
4
|
require_relative '../../custom_groups/v4.0.0/clinical_notes_guidance_group'
|
|
5
5
|
require_relative '../../custom_groups/data_absent_reason_group'
|
|
6
|
+
require_relative '../../provenance_validator'
|
|
6
7
|
require_relative 'patient_group'
|
|
7
8
|
require_relative 'allergy_intolerance_group'
|
|
8
9
|
require_relative 'care_plan_group'
|
|
@@ -48,13 +49,27 @@ module USCoreTestKit
|
|
|
48
49
|
module USCoreV501
|
|
49
50
|
class USCoreTestSuite < Inferno::TestSuite
|
|
50
51
|
title 'US Core v5.0.1'
|
|
52
|
+
description %(
|
|
53
|
+
The US Core Test Kit tests systems for their conformance to the [US Core
|
|
54
|
+
Implementation Guide](http://hl7.org/fhir/us/core/STU5.0.1).
|
|
55
|
+
|
|
56
|
+
Resources are validated with the FHIR Java validator using `tx.fhir.org`
|
|
57
|
+
as the terminology server. Users should note that the although the ONC
|
|
58
|
+
Certification (g)(10) Standardized API Test Suite includes tests from
|
|
59
|
+
this suite, [it uses a different method to perform terminology
|
|
60
|
+
validation](https://github.com/onc-healthit/onc-certification-g10-test-kit/wiki/FAQ#q-why-do-some-resources-fail-in-us-core-test-kit-with-terminology-validation-errors).
|
|
61
|
+
As a result, resource validation results may not be consistent between
|
|
62
|
+
the US Core Test Suite and the ONC Certification (g)(10) Standardized
|
|
63
|
+
API Test Suite.
|
|
64
|
+
)
|
|
51
65
|
version VERSION
|
|
52
66
|
|
|
53
67
|
VALIDATION_MESSAGE_FILTERS = [
|
|
54
68
|
%r{Sub-extension url 'introspect' is not defined by the Extension http://fhir-registry\.smarthealthit\.org/StructureDefinition/oauth-uris$},
|
|
55
69
|
%r{Sub-extension url 'revoke' is not defined by the Extension http://fhir-registry\.smarthealthit\.org/StructureDefinition/oauth-uris$},
|
|
56
70
|
/Observation\.effective\.ofType\(Period\): .*vs-1:/, # Invalid invariant in FHIR v4.0.1
|
|
57
|
-
/Observation\.effective\.ofType\(Period\): .*us-core-1
|
|
71
|
+
/Observation\.effective\.ofType\(Period\): .*us-core-1:/, # Invalid invariant in US Core v3.1.1
|
|
72
|
+
/Provenance.agent\[\d*\]: Rule provenance-1/ #Invalid invariant in US Core v5.0.1
|
|
58
73
|
].freeze
|
|
59
74
|
|
|
60
75
|
def self.metadata
|
|
@@ -68,6 +83,10 @@ module USCoreTestKit
|
|
|
68
83
|
exclude_message do |message|
|
|
69
84
|
VALIDATION_MESSAGE_FILTERS.any? { |filter| filter.match? message.message }
|
|
70
85
|
end
|
|
86
|
+
|
|
87
|
+
perform_additional_validation do |resource, profile_url|
|
|
88
|
+
ProvenanceValidator.validate(resource) if resource.instance_of?(FHIR::Provenance)
|
|
89
|
+
end
|
|
71
90
|
end
|
|
72
91
|
|
|
73
92
|
id :us_core_v501
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require_relative 'value_extractor'
|
|
2
|
+
|
|
1
3
|
module USCoreTestKit
|
|
2
4
|
class Generator
|
|
3
5
|
class MustSupportMetadataExtractor
|
|
@@ -97,13 +99,10 @@ module USCoreTestKit
|
|
|
97
99
|
elsif pattern_element.binding&.strength == 'required' &&
|
|
98
100
|
pattern_element.binding&.valueSet.present?
|
|
99
101
|
|
|
100
|
-
|
|
101
|
-
bound_systems = value_set&.compose&.include&.reject { |code| code.concept.blank? }
|
|
102
|
-
values = []
|
|
102
|
+
value_extractor = ValueExactor.new(ig_resources, resource, profile_elements)
|
|
103
103
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
end
|
|
104
|
+
values = value_extractor.values_from_value_set_binding(pattern_element).presence ||
|
|
105
|
+
value_extractor.values_from_resource_metadata([metadata[:path]]).presence || []
|
|
107
106
|
|
|
108
107
|
{
|
|
109
108
|
type: 'requiredBinding',
|
|
@@ -292,6 +291,8 @@ module USCoreTestKit
|
|
|
292
291
|
add_must_support_choices
|
|
293
292
|
|
|
294
293
|
case profile.version
|
|
294
|
+
when '3.1.1'
|
|
295
|
+
remove_document_reference_custodian
|
|
295
296
|
when '4.0.0'
|
|
296
297
|
add_device_distinct_identifier
|
|
297
298
|
add_patient_uscdi_elements
|
|
@@ -354,6 +355,15 @@ module USCoreTestKit
|
|
|
354
355
|
end
|
|
355
356
|
end
|
|
356
357
|
|
|
358
|
+
# US Core clarified that server implmentation is not required to support DocumentReference.custodian (FHIR-28393)
|
|
359
|
+
def remove_document_reference_custodian
|
|
360
|
+
if profile.type == 'DocumentReference'
|
|
361
|
+
@must_supports[:elements].delete_if do |element|
|
|
362
|
+
element[:path] == 'custodian'
|
|
363
|
+
end
|
|
364
|
+
end
|
|
365
|
+
end
|
|
366
|
+
|
|
357
367
|
def remove_document_reference_attachment_data_url
|
|
358
368
|
if profile.type == 'DocumentReference'
|
|
359
369
|
@must_supports[:elements].delete_if do |element|
|
|
@@ -482,7 +492,7 @@ module USCoreTestKit
|
|
|
482
492
|
|
|
483
493
|
slice = @must_supports[:slices].find{|slice| slice[:path] == 'category'}
|
|
484
494
|
|
|
485
|
-
slice[:discriminator][:values]
|
|
495
|
+
slice[:discriminator][:values] = ['clinical-note'] if slice.present?
|
|
486
496
|
end
|
|
487
497
|
|
|
488
498
|
# FHIR-37794 Server systems are not required to support US Core QuestionnaireResponse
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require_relative 'value_extractor'
|
|
2
|
+
|
|
1
3
|
module USCoreTestKit
|
|
2
4
|
class Generator
|
|
3
5
|
class SearchDefinitionMetadataExtractor
|
|
@@ -112,103 +114,21 @@ module USCoreTestKit
|
|
|
112
114
|
end
|
|
113
115
|
|
|
114
116
|
def values
|
|
115
|
-
|
|
116
|
-
(
|
|
117
|
-
|
|
118
|
-
values_from_required_binding_slices +
|
|
119
|
-
values_from_fixed_codes +
|
|
120
|
-
values_from_pattern_coding +
|
|
121
|
-
values_from_pattern_codeable_concept
|
|
122
|
-
).uniq.presence || values_from_value_set_binding(profile_element)
|
|
123
|
-
).presence || values_from_resource_metadata
|
|
124
|
-
values
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
def slices
|
|
128
|
-
return [] unless contains_multiple?
|
|
129
|
-
|
|
130
|
-
profile_elements.select do |element|
|
|
131
|
-
full_paths.include?(element.path) &&
|
|
132
|
-
element.sliceName.present? &&
|
|
133
|
-
(
|
|
134
|
-
element.patternCodeableConcept.present? ||
|
|
135
|
-
element.binding.present? && element.binding.strength == 'required'
|
|
136
|
-
)
|
|
137
|
-
end
|
|
117
|
+
value_extractor.values_from_slicing(profile_element, type).presence ||
|
|
118
|
+
value_extractor.values_from_value_set_binding(profile_element).presence ||
|
|
119
|
+
values_from_resource_metadata(paths).presence || []
|
|
138
120
|
end
|
|
139
121
|
|
|
140
|
-
def
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
def values_from_required_binding_slices
|
|
147
|
-
slices.map do |slice|
|
|
148
|
-
if slice.binding.present? && slice.binding.strength == 'required'
|
|
149
|
-
values_from_value_set_binding(slice)
|
|
150
|
-
end
|
|
151
|
-
end.flatten.compact
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
def values_from_fixed_codes
|
|
155
|
-
return [] unless type == 'CodeableConcept'
|
|
156
|
-
|
|
157
|
-
profile_elements
|
|
158
|
-
.select { |element| element.path == "#{profile_element.path}.coding.code" && element.fixedCode.present? }
|
|
159
|
-
.map { |element| element.fixedCode }
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
def values_from_pattern_coding
|
|
163
|
-
return [] unless type == 'CodeableConcept'
|
|
164
|
-
|
|
165
|
-
profile_elements
|
|
166
|
-
.select { |element| element.path == "#{profile_element.path}.coding" && element.patternCoding.present? }
|
|
167
|
-
.map { |element| element.patternCoding.code }
|
|
168
|
-
end
|
|
169
|
-
|
|
170
|
-
def values_from_pattern_codeable_concept
|
|
171
|
-
return [] if type != 'CodeableConcept' || profile_element.patternCodeableConcept.blank?
|
|
172
|
-
|
|
173
|
-
[profile_element.patternCodeableConcept.coding.first.code]
|
|
174
|
-
end
|
|
175
|
-
|
|
176
|
-
def value_set_binding(the_element)
|
|
177
|
-
the_element&.binding
|
|
178
|
-
end
|
|
179
|
-
|
|
180
|
-
def value_set(the_element)
|
|
181
|
-
ig_resources.value_set_by_url(value_set_binding(the_element)&.valueSet)
|
|
182
|
-
end
|
|
183
|
-
|
|
184
|
-
def bound_systems(the_element)
|
|
185
|
-
value_set(the_element)&.compose&.include&.reject { |code| code.concept.nil? }
|
|
186
|
-
end
|
|
187
|
-
|
|
188
|
-
def values_from_value_set_binding(the_element)
|
|
189
|
-
bound_systems = bound_systems(the_element)
|
|
190
|
-
|
|
191
|
-
return [] if bound_systems.blank?
|
|
192
|
-
|
|
193
|
-
bound_systems.flat_map { |system| system.concept.map { |code| code.code } }.uniq
|
|
194
|
-
end
|
|
195
|
-
|
|
196
|
-
def fhir_metadata(current_path)
|
|
197
|
-
FHIR.const_get(resource)::METADATA[current_path]
|
|
198
|
-
end
|
|
199
|
-
|
|
200
|
-
def values_from_resource_metadata
|
|
201
|
-
values = []
|
|
202
|
-
|
|
203
|
-
paths.each do |current_path|
|
|
204
|
-
current_metadata = fhir_metadata(current_path)
|
|
205
|
-
|
|
206
|
-
if current_metadata&.dig('valid_codes').present?
|
|
207
|
-
values = values + current_metadata['valid_codes'].values.flatten
|
|
208
|
-
end
|
|
122
|
+
def values_from_resource_metadata(paths)
|
|
123
|
+
if multiple_or_expectation == 'SHALL' || paths.include?('status')
|
|
124
|
+
value_extractor.values_from_resource_metadata(paths)
|
|
125
|
+
else
|
|
126
|
+
[]
|
|
209
127
|
end
|
|
128
|
+
end
|
|
210
129
|
|
|
211
|
-
|
|
130
|
+
def value_extractor
|
|
131
|
+
@value_extractor ||= ValueExactor.new(ig_resources, resource, profile_elements)
|
|
212
132
|
end
|
|
213
133
|
end
|
|
214
134
|
end
|
|
@@ -53,6 +53,17 @@ module USCoreTestKit
|
|
|
53
53
|
"#{ig_metadata.reformatted_version.upcase}_VALIDATOR_URL"
|
|
54
54
|
end
|
|
55
55
|
|
|
56
|
+
def ig_link
|
|
57
|
+
case ig_metadata.ig_version
|
|
58
|
+
when 'v5.0.1'
|
|
59
|
+
'http://hl7.org/fhir/us/core/STU5.0.1'
|
|
60
|
+
when 'v4.0.0'
|
|
61
|
+
'http://hl7.org/fhir/us/core/STU4'
|
|
62
|
+
when 'v3.1.1'
|
|
63
|
+
'http://hl7.org/fhir/us/core/STU3.1.1'
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
56
67
|
def generate
|
|
57
68
|
File.open(output_file_name, 'w') { |f| f.write(output) }
|
|
58
69
|
end
|
|
@@ -27,21 +27,33 @@ module USCoreTestKit
|
|
|
27
27
|
end
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
+
def element_has_optional_binding_slice?(element)
|
|
31
|
+
element.sliceName.present? && element.min == 0
|
|
32
|
+
end
|
|
33
|
+
|
|
30
34
|
def profile_elements_with_bindings
|
|
31
35
|
profile_elements
|
|
32
|
-
.select { |element| element.binding.present? }
|
|
33
|
-
.reject { |element| element_has_fixed_value? element }
|
|
36
|
+
.select { |element| element.binding.present? && element.binding.strength == 'required'}
|
|
37
|
+
.reject { |element| element_has_fixed_value?(element) || element_has_optional_binding_slice?(element) }
|
|
34
38
|
end
|
|
35
39
|
|
|
40
|
+
|
|
41
|
+
|
|
36
42
|
def element_terminology_bindings
|
|
37
43
|
profile_elements_with_bindings.map do |element|
|
|
38
|
-
{
|
|
44
|
+
binding = {
|
|
39
45
|
type: element.type.first.code,
|
|
40
46
|
strength: element.binding.strength,
|
|
41
47
|
# Goal.target.detail has an unbound binding
|
|
42
48
|
system: element.binding.valueSet&.split('|')&.first,
|
|
43
49
|
path: element.path.gsub('[x]', '').gsub("#{resource}.", '')
|
|
44
50
|
}
|
|
51
|
+
|
|
52
|
+
if element.sliceName.present? && element.min > 0
|
|
53
|
+
binding[:required_binding_slice] = true
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
binding
|
|
45
57
|
end
|
|
46
58
|
end
|
|
47
59
|
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
module USCoreTestKit
|
|
2
|
+
class Generator
|
|
3
|
+
class ValueExactor
|
|
4
|
+
attr_accessor :ig_resources, :resource, :profile_elements
|
|
5
|
+
|
|
6
|
+
def initialize(ig_resources, resource, profile_elements)
|
|
7
|
+
self.ig_resources = ig_resources
|
|
8
|
+
self.resource = resource
|
|
9
|
+
self.profile_elements = profile_elements
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def values_from_slicing(profile_element, type)
|
|
13
|
+
(
|
|
14
|
+
values_from_required_binding(profile_element) +
|
|
15
|
+
values_from_fixed_codes(profile_element, type) +
|
|
16
|
+
values_from_pattern_coding(profile_element, type) +
|
|
17
|
+
values_from_pattern_codeable_concept(profile_element, type)
|
|
18
|
+
).uniq
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def values_from_required_binding(profile_element)
|
|
22
|
+
return [] unless profile_element&.max == '*'
|
|
23
|
+
|
|
24
|
+
profile_elements
|
|
25
|
+
.select do |element|
|
|
26
|
+
element.path == profile_element.path && element.binding&.strength == 'required'
|
|
27
|
+
end
|
|
28
|
+
.map { |element| values_from_value_set_binding(element) }
|
|
29
|
+
.flatten.compact
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def values_from_fixed_codes(profile_element, type)
|
|
33
|
+
return [] unless type == 'CodeableConcept'
|
|
34
|
+
|
|
35
|
+
profile_elements
|
|
36
|
+
.select do
|
|
37
|
+
|element| element.path == "#{profile_element.path}.coding.code" && element.fixedCode.present?
|
|
38
|
+
end
|
|
39
|
+
.map { |element| element.fixedCode }
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def values_from_pattern_coding(profile_element, type)
|
|
43
|
+
return [] unless type == 'CodeableConcept'
|
|
44
|
+
|
|
45
|
+
profile_elements
|
|
46
|
+
.select do |element|
|
|
47
|
+
element.path == "#{profile_element.path}.coding" && element.patternCoding.present?
|
|
48
|
+
end
|
|
49
|
+
.map { |element| element.patternCoding.code }
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def values_from_pattern_codeable_concept(profile_element, type)
|
|
53
|
+
return [] unless type == 'CodeableConcept'
|
|
54
|
+
|
|
55
|
+
profile_elements
|
|
56
|
+
.select do |element|
|
|
57
|
+
element.path == profile_element.path && element.patternCodeableConcept.present? && element.min > 0
|
|
58
|
+
end
|
|
59
|
+
.map { |element| element.patternCodeableConcept.coding.first.code }
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def value_set_binding(the_element)
|
|
63
|
+
the_element&.binding
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def value_set(the_element)
|
|
67
|
+
ig_resources.value_set_by_url(value_set_binding(the_element)&.valueSet)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def bound_systems(the_element)
|
|
71
|
+
value_set(the_element)&.compose&.include&.reject { |code| code.concept.nil? }
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def values_from_value_set_binding(the_element)
|
|
75
|
+
bound_systems = bound_systems(the_element)
|
|
76
|
+
|
|
77
|
+
return [] if bound_systems.blank?
|
|
78
|
+
|
|
79
|
+
bound_systems.flat_map { |system| system.concept.map { |code| code.code } }.uniq
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def fhir_metadata(current_path)
|
|
83
|
+
FHIR.const_get(resource)::METADATA[current_path]
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def values_from_resource_metadata(paths)
|
|
87
|
+
values = []
|
|
88
|
+
|
|
89
|
+
paths.each do |current_path|
|
|
90
|
+
current_metadata = fhir_metadata(current_path)
|
|
91
|
+
|
|
92
|
+
if current_metadata&.dig('valid_codes').present?
|
|
93
|
+
values = values + current_metadata['valid_codes'].values.flatten
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
values
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module USCoreTestKit
|
|
2
|
+
class ProvenanceValidator
|
|
3
|
+
include FHIRResourceNavigation
|
|
4
|
+
|
|
5
|
+
def self.validate(...)
|
|
6
|
+
new(...).validate
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
attr_reader :resource, :validation_messages
|
|
10
|
+
|
|
11
|
+
def initialize(resource)
|
|
12
|
+
@resource = resource
|
|
13
|
+
@validation_messages = []
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def validate
|
|
17
|
+
# Invariant provenance-1 in US Core 5 causes validation error. See FHIR-39518
|
|
18
|
+
return validation_messages unless resource.instance_of?(FHIR::Provenance)
|
|
19
|
+
|
|
20
|
+
failed_provenance =
|
|
21
|
+
find_a_value_at(resource, 'agent') do |agent|
|
|
22
|
+
['Practitioner', 'Device'].any? { |resource_type| agent.who.reference&.include?(resource_type) } &&
|
|
23
|
+
agent.onBehalfOf.nil?
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
if failed_provenance.present?
|
|
28
|
+
validation_messages << {
|
|
29
|
+
type: 'error',
|
|
30
|
+
message: "#{resource.resourceType}/#{resource.id}: Rule provenance-1: 'onBehalfOf SHALL be present when Provenance.agent.who is a Practitioner or Device' Failed"
|
|
31
|
+
}
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
validation_messages
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: us_core_test_kit
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.4.
|
|
4
|
+
version: 0.4.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Stephen MacVicar
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2022-
|
|
11
|
+
date: 2022-12-08 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: inferno_core
|
|
@@ -1292,6 +1292,7 @@ files:
|
|
|
1292
1292
|
- lib/us_core_test_kit/generator/suite_generator.rb
|
|
1293
1293
|
- lib/us_core_test_kit/generator/terminology_binding_metadata_extractor.rb
|
|
1294
1294
|
- lib/us_core_test_kit/generator/validation_test_generator.rb
|
|
1295
|
+
- lib/us_core_test_kit/generator/value_extractor.rb
|
|
1295
1296
|
- lib/us_core_test_kit/igs/us_core_311.tgz
|
|
1296
1297
|
- lib/us_core_test_kit/igs/us_core_311/StructureDefinition-bodyheight.json
|
|
1297
1298
|
- lib/us_core_test_kit/igs/us_core_311/StructureDefinition-bodytemp.json
|
|
@@ -1302,6 +1303,7 @@ files:
|
|
|
1302
1303
|
- lib/us_core_test_kit/igs/us_core_400.tgz
|
|
1303
1304
|
- lib/us_core_test_kit/igs/us_core_501.tgz
|
|
1304
1305
|
- lib/us_core_test_kit/must_support_test.rb
|
|
1306
|
+
- lib/us_core_test_kit/provenance_validator.rb
|
|
1305
1307
|
- lib/us_core_test_kit/read_test.rb
|
|
1306
1308
|
- lib/us_core_test_kit/reference_resolution_test.rb
|
|
1307
1309
|
- lib/us_core_test_kit/request_logger.rb
|