us_core_test_kit 0.4.1 → 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.
Files changed (115) hide show
  1. checksums.yaml +4 -4
  2. data/lib/us_core_test_kit/generated/v3.1.1/allergy_intolerance/metadata.yml +1 -24
  3. data/lib/us_core_test_kit/generated/v3.1.1/bodyheight/metadata.yml +0 -52
  4. data/lib/us_core_test_kit/generated/v3.1.1/bodytemp/metadata.yml +0 -52
  5. data/lib/us_core_test_kit/generated/v3.1.1/bodyweight/metadata.yml +0 -52
  6. data/lib/us_core_test_kit/generated/v3.1.1/bp/metadata.yml +0 -76
  7. data/lib/us_core_test_kit/generated/v3.1.1/care_plan/metadata.yml +0 -28
  8. data/lib/us_core_test_kit/generated/v3.1.1/care_team/metadata.yml +0 -16
  9. data/lib/us_core_test_kit/generated/v3.1.1/condition/metadata.yml +1 -39
  10. data/lib/us_core_test_kit/generated/v3.1.1/device/metadata.yml +1 -1013
  11. data/lib/us_core_test_kit/generated/v3.1.1/diagnostic_report_lab/metadata.yml +1 -1021
  12. data/lib/us_core_test_kit/generated/v3.1.1/diagnostic_report_note/metadata.yml +1 -1017
  13. data/lib/us_core_test_kit/generated/v3.1.1/document_reference/metadata.yml +1 -78
  14. data/lib/us_core_test_kit/generated/v3.1.1/encounter/metadata.yml +2 -85
  15. data/lib/us_core_test_kit/generated/v3.1.1/goal/metadata.yml +1 -46
  16. data/lib/us_core_test_kit/generated/v3.1.1/head_circumference/metadata.yml +0 -52
  17. data/lib/us_core_test_kit/generated/v3.1.1/heartrate/metadata.yml +0 -52
  18. data/lib/us_core_test_kit/generated/v3.1.1/immunization/metadata.yml +0 -48
  19. data/lib/us_core_test_kit/generated/v3.1.1/medication_request/metadata.yml +0 -60
  20. data/lib/us_core_test_kit/generated/v3.1.1/metadata.yml +14 -6468
  21. data/lib/us_core_test_kit/generated/v3.1.1/observation_lab/metadata.yml +1 -1053
  22. data/lib/us_core_test_kit/generated/v3.1.1/organization/metadata.yml +0 -20
  23. data/lib/us_core_test_kit/generated/v3.1.1/patient/metadata.yml +1 -29
  24. data/lib/us_core_test_kit/generated/v3.1.1/pediatric_bmi_for_age/metadata.yml +0 -52
  25. data/lib/us_core_test_kit/generated/v3.1.1/pediatric_weight_for_height/metadata.yml +0 -52
  26. data/lib/us_core_test_kit/generated/v3.1.1/practitioner/metadata.yml +0 -16
  27. data/lib/us_core_test_kit/generated/v3.1.1/procedure/metadata.yml +1 -1049
  28. data/lib/us_core_test_kit/generated/v3.1.1/provenance/metadata.yml +0 -36
  29. data/lib/us_core_test_kit/generated/v3.1.1/pulse_oximetry/metadata.yml +0 -76
  30. data/lib/us_core_test_kit/generated/v3.1.1/resprate/metadata.yml +0 -52
  31. data/lib/us_core_test_kit/generated/v3.1.1/smokingstatus/metadata.yml +1 -62
  32. data/lib/us_core_test_kit/generated/v3.1.1/us_core_test_suite.rb +20 -1
  33. data/lib/us_core_test_kit/generated/v4.0.0/allergy_intolerance/metadata.yml +1 -24
  34. data/lib/us_core_test_kit/generated/v4.0.0/blood_pressure/metadata.yml +0 -80
  35. data/lib/us_core_test_kit/generated/v4.0.0/bmi/metadata.yml +0 -56
  36. data/lib/us_core_test_kit/generated/v4.0.0/body_height/metadata.yml +0 -56
  37. data/lib/us_core_test_kit/generated/v4.0.0/body_temperature/metadata.yml +0 -56
  38. data/lib/us_core_test_kit/generated/v4.0.0/body_weight/metadata.yml +0 -56
  39. data/lib/us_core_test_kit/generated/v4.0.0/care_plan/metadata.yml +0 -28
  40. data/lib/us_core_test_kit/generated/v4.0.0/care_team/metadata.yml +0 -16
  41. data/lib/us_core_test_kit/generated/v4.0.0/condition/metadata.yml +1 -39
  42. data/lib/us_core_test_kit/generated/v4.0.0/device/metadata.yml +1 -1013
  43. data/lib/us_core_test_kit/generated/v4.0.0/diagnostic_report_lab/metadata.yml +1 -1021
  44. data/lib/us_core_test_kit/generated/v4.0.0/diagnostic_report_note/metadata.yml +1 -1017
  45. data/lib/us_core_test_kit/generated/v4.0.0/document_reference/metadata.yml +1 -78
  46. data/lib/us_core_test_kit/generated/v4.0.0/encounter/metadata.yml +2 -85
  47. data/lib/us_core_test_kit/generated/v4.0.0/goal/metadata.yml +1 -46
  48. data/lib/us_core_test_kit/generated/v4.0.0/head_circumference/metadata.yml +0 -56
  49. data/lib/us_core_test_kit/generated/v4.0.0/head_circumference_percentile/metadata.yml +0 -56
  50. data/lib/us_core_test_kit/generated/v4.0.0/heart_rate/metadata.yml +0 -56
  51. data/lib/us_core_test_kit/generated/v4.0.0/immunization/metadata.yml +0 -48
  52. data/lib/us_core_test_kit/generated/v4.0.0/medication_request/metadata.yml +0 -60
  53. data/lib/us_core_test_kit/generated/v4.0.0/metadata.yml +13 -6618
  54. data/lib/us_core_test_kit/generated/v4.0.0/observation_lab/metadata.yml +1 -1053
  55. data/lib/us_core_test_kit/generated/v4.0.0/organization/metadata.yml +0 -20
  56. data/lib/us_core_test_kit/generated/v4.0.0/patient/metadata.yml +1 -29
  57. data/lib/us_core_test_kit/generated/v4.0.0/pediatric_bmi_for_age/metadata.yml +0 -56
  58. data/lib/us_core_test_kit/generated/v4.0.0/pediatric_weight_for_height/metadata.yml +0 -56
  59. data/lib/us_core_test_kit/generated/v4.0.0/practitioner/metadata.yml +0 -16
  60. data/lib/us_core_test_kit/generated/v4.0.0/procedure/metadata.yml +1 -1049
  61. data/lib/us_core_test_kit/generated/v4.0.0/provenance/metadata.yml +0 -40
  62. data/lib/us_core_test_kit/generated/v4.0.0/pulse_oximetry/metadata.yml +0 -80
  63. data/lib/us_core_test_kit/generated/v4.0.0/respiratory_rate/metadata.yml +0 -56
  64. data/lib/us_core_test_kit/generated/v4.0.0/smokingstatus/metadata.yml +0 -56
  65. data/lib/us_core_test_kit/generated/v4.0.0/us_core_test_suite.rb +20 -1
  66. data/lib/us_core_test_kit/generated/v5.0.1/allergy_intolerance/metadata.yml +1 -24
  67. data/lib/us_core_test_kit/generated/v5.0.1/blood_pressure/metadata.yml +0 -80
  68. data/lib/us_core_test_kit/generated/v5.0.1/bmi/metadata.yml +0 -56
  69. data/lib/us_core_test_kit/generated/v5.0.1/body_height/metadata.yml +0 -56
  70. data/lib/us_core_test_kit/generated/v5.0.1/body_temperature/metadata.yml +0 -56
  71. data/lib/us_core_test_kit/generated/v5.0.1/body_weight/metadata.yml +0 -56
  72. data/lib/us_core_test_kit/generated/v5.0.1/care_plan/metadata.yml +0 -28
  73. data/lib/us_core_test_kit/generated/v5.0.1/care_team/metadata.yml +0 -16
  74. data/lib/us_core_test_kit/generated/v5.0.1/condition_encounter_diagnosis/metadata.yml +1 -43
  75. data/lib/us_core_test_kit/generated/v5.0.1/condition_problems_health_concerns/metadata.yml +2 -44
  76. data/lib/us_core_test_kit/generated/v5.0.1/device/metadata.yml +1 -1013
  77. data/lib/us_core_test_kit/generated/v5.0.1/diagnostic_report_lab/metadata.yml +1 -1021
  78. data/lib/us_core_test_kit/generated/v5.0.1/diagnostic_report_note/metadata.yml +1 -1021
  79. data/lib/us_core_test_kit/generated/v5.0.1/document_reference/metadata.yml +1 -82
  80. data/lib/us_core_test_kit/generated/v5.0.1/encounter/metadata.yml +2 -85
  81. data/lib/us_core_test_kit/generated/v5.0.1/goal/metadata.yml +2 -1047
  82. data/lib/us_core_test_kit/generated/v5.0.1/head_circumference/metadata.yml +0 -56
  83. data/lib/us_core_test_kit/generated/v5.0.1/head_circumference_percentile/metadata.yml +0 -56
  84. data/lib/us_core_test_kit/generated/v5.0.1/heart_rate/metadata.yml +0 -56
  85. data/lib/us_core_test_kit/generated/v5.0.1/immunization/metadata.yml +0 -48
  86. data/lib/us_core_test_kit/generated/v5.0.1/medication_request/metadata.yml +0 -64
  87. data/lib/us_core_test_kit/generated/v5.0.1/metadata.yml +22 -11040
  88. data/lib/us_core_test_kit/generated/v5.0.1/observation_clinical_test/metadata.yml +0 -52
  89. data/lib/us_core_test_kit/generated/v5.0.1/observation_imaging/metadata.yml +1 -1053
  90. data/lib/us_core_test_kit/generated/v5.0.1/observation_lab/metadata.yml +1 -1053
  91. data/lib/us_core_test_kit/generated/v5.0.1/observation_sdoh_assessment/metadata.yml +0 -57
  92. data/lib/us_core_test_kit/generated/v5.0.1/observation_sexual_orientation/metadata.yml +1 -62
  93. data/lib/us_core_test_kit/generated/v5.0.1/observation_social_history/metadata.yml +1 -1058
  94. data/lib/us_core_test_kit/generated/v5.0.1/organization/metadata.yml +0 -20
  95. data/lib/us_core_test_kit/generated/v5.0.1/patient/metadata.yml +1 -29
  96. data/lib/us_core_test_kit/generated/v5.0.1/pediatric_bmi_for_age/metadata.yml +0 -56
  97. data/lib/us_core_test_kit/generated/v5.0.1/pediatric_weight_for_height/metadata.yml +0 -56
  98. data/lib/us_core_test_kit/generated/v5.0.1/practitioner/metadata.yml +0 -20
  99. data/lib/us_core_test_kit/generated/v5.0.1/procedure/metadata.yml +1 -1049
  100. data/lib/us_core_test_kit/generated/v5.0.1/provenance/metadata.yml +0 -40
  101. data/lib/us_core_test_kit/generated/v5.0.1/pulse_oximetry/metadata.yml +0 -80
  102. data/lib/us_core_test_kit/generated/v5.0.1/questionnaire_response/metadata.yml +0 -20
  103. data/lib/us_core_test_kit/generated/v5.0.1/related_person/metadata.yml +0 -12
  104. data/lib/us_core_test_kit/generated/v5.0.1/respiratory_rate/metadata.yml +0 -56
  105. data/lib/us_core_test_kit/generated/v5.0.1/service_request/metadata.yml +1 -1041
  106. data/lib/us_core_test_kit/generated/v5.0.1/smokingstatus/metadata.yml +0 -56
  107. data/lib/us_core_test_kit/generated/v5.0.1/us_core_test_suite.rb +20 -1
  108. data/lib/us_core_test_kit/generator/must_support_metadata_extractor.rb +1 -1
  109. data/lib/us_core_test_kit/generator/search_definition_metadata_extractor.rb +8 -57
  110. data/lib/us_core_test_kit/generator/suite_generator.rb +11 -0
  111. data/lib/us_core_test_kit/generator/terminology_binding_metadata_extractor.rb +15 -3
  112. data/lib/us_core_test_kit/generator/value_extractor.rb +53 -2
  113. data/lib/us_core_test_kit/provenance_validator.rb +37 -0
  114. data/lib/us_core_test_kit/version.rb +1 -1
  115. metadata +3 -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:/ # Invalid invariant in US Core v3.1.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
@@ -99,7 +99,7 @@ module USCoreTestKit
99
99
  elsif pattern_element.binding&.strength == 'required' &&
100
100
  pattern_element.binding&.valueSet.present?
101
101
 
102
- value_extractor = ValueExactor.new(ig_resources, resource)
102
+ value_extractor = ValueExactor.new(ig_resources, resource, profile_elements)
103
103
 
104
104
  values = value_extractor.values_from_value_set_binding(pattern_element).presence ||
105
105
  value_extractor.values_from_resource_metadata([metadata[:path]]).presence || []
@@ -114,70 +114,21 @@ module USCoreTestKit
114
114
  end
115
115
 
116
116
  def values
117
- values = (
118
- values_from_pattern_codeable_concept_slices +
119
- values_from_required_binding_slices +
120
- values_from_fixed_codes +
121
- values_from_pattern_coding +
122
- values_from_pattern_codeable_concept
123
- ).uniq.presence ||
117
+ value_extractor.values_from_slicing(profile_element, type).presence ||
124
118
  value_extractor.values_from_value_set_binding(profile_element).presence ||
125
- value_extractor.values_from_resource_metadata(paths).presence || []
126
-
127
- values
119
+ values_from_resource_metadata(paths).presence || []
128
120
  end
129
121
 
130
- def slices
131
- return [] unless contains_multiple?
132
-
133
- profile_elements.select do |element|
134
- full_paths.include?(element.path) &&
135
- element.sliceName.present? &&
136
- (
137
- element.patternCodeableConcept.present? ||
138
- element.binding.present? && element.binding.strength == 'required'
139
- )
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
+ []
140
127
  end
141
128
  end
142
129
 
143
- def values_from_pattern_codeable_concept_slices
144
- slices.map do |slice|
145
- slice.patternCodeableConcept.coding.first.code if slice.patternCodeableConcept.present?
146
- end.compact
147
- end
148
-
149
- def values_from_required_binding_slices
150
- slices.map do |slice|
151
- if slice.binding.present? && slice.binding.strength == 'required'
152
- value_extractor.values_from_value_set_binding(slice)
153
- end
154
- end.flatten.compact
155
- end
156
-
157
- def values_from_fixed_codes
158
- return [] unless type == 'CodeableConcept'
159
-
160
- profile_elements
161
- .select { |element| element.path == "#{profile_element.path}.coding.code" && element.fixedCode.present? }
162
- .map { |element| element.fixedCode }
163
- end
164
-
165
- def values_from_pattern_coding
166
- return [] unless type == 'CodeableConcept'
167
-
168
- profile_elements
169
- .select { |element| element.path == "#{profile_element.path}.coding" && element.patternCoding.present? }
170
- .map { |element| element.patternCoding.code }
171
- end
172
-
173
- def values_from_pattern_codeable_concept
174
- return [] if type != 'CodeableConcept' || profile_element.patternCodeableConcept.blank?
175
-
176
- [profile_element.patternCodeableConcept.coding.first.code]
177
- end
178
-
179
130
  def value_extractor
180
- @value_extractor ||= ValueExactor.new(ig_resources, resource)
131
+ @value_extractor ||= ValueExactor.new(ig_resources, resource, profile_elements)
181
132
  end
182
133
  end
183
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
 
@@ -1,11 +1,62 @@
1
1
  module USCoreTestKit
2
2
  class Generator
3
3
  class ValueExactor
4
- attr_accessor :ig_resources, :resource
4
+ attr_accessor :ig_resources, :resource, :profile_elements
5
5
 
6
- def initialize(ig_resources, resource)
6
+ def initialize(ig_resources, resource, profile_elements)
7
7
  self.ig_resources = ig_resources
8
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 }
9
60
  end
10
61
 
11
62
  def value_set_binding(the_element)
@@ -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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module USCoreTestKit
4
- VERSION = '0.4.1'
4
+ VERSION = '0.4.2'
5
5
  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.1
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-04 00:00:00.000000000 Z
11
+ date: 2022-12-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: inferno_core
@@ -1303,6 +1303,7 @@ files:
1303
1303
  - lib/us_core_test_kit/igs/us_core_400.tgz
1304
1304
  - lib/us_core_test_kit/igs/us_core_501.tgz
1305
1305
  - lib/us_core_test_kit/must_support_test.rb
1306
+ - lib/us_core_test_kit/provenance_validator.rb
1306
1307
  - lib/us_core_test_kit/read_test.rb
1307
1308
  - lib/us_core_test_kit/reference_resolution_test.rb
1308
1309
  - lib/us_core_test_kit/request_logger.rb