us_core_test_kit 0.11.0 → 0.11.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c5c1144b0951c2ba438152f25553f8a4eff37301e232b17dc149030bbe5b23ff
4
- data.tar.gz: 0f790cf343a074d72240ffe6f83ebc8fdab641b7a08601b2d51f4d601d8f7889
3
+ metadata.gz: 19c0ab03440b94688b25fff04431c7ca891b45ff474517595a6657203cde5b98
4
+ data.tar.gz: b13607fd2d36f35ea718cb2984677506bee66c7cd11946b9da65553d624fe8d6
5
5
  SHA512:
6
- metadata.gz: 7f4fbe3dd3524a0983715bdff2a6f6a03ee370392e4bd50346d95eaaca46144a566b6497c818265fb602a577a9329bfe2cb1ee63723eb68a4510e0990a407b27
7
- data.tar.gz: f52cd5e1baa310753831c0825f226e89c7b4fddf74e4fdaff0f797f17c6a5c30f3de24e8703e4a1ea6bf22f65144e12cd5f54bcb9732d8616e4685badf9e3d36
6
+ metadata.gz: b0f264d4c176cff39da75e135dacab88009349bd60083fdb9aea59d227de321461b6207d9ebceb03ff17fcb3f2d3294e2c1e60cca5c4e7e327c96cd255360b73
7
+ data.tar.gz: 47c6d483549723b3a76f62b5838c5e80428f85345d21d0dbed372f366b98c6d63dca6bcc076a76c9469cab00ccc51a777d1b032a9b24c260d11f3288f20ae782
@@ -22,7 +22,7 @@ module USCoreTestKit
22
22
  "No #{resource_type} reads found"
23
23
  previous_resources_for_reads = previous_request_resources.values.flatten
24
24
 
25
- resource_specific_granular_scope_search_params.each do |scope|
25
+ resource_specific_granular_scope_search_params.each do |scope|
26
26
  current_scope = granular_scopes.find {|granular| granular.include?(scope[:name]) && granular.include?(scope[:value])}
27
27
 
28
28
  resource_matching_scope = previous_resources_for_reads.find do |prev_resource|
@@ -37,19 +37,26 @@ module USCoreTestKit
37
37
  end
38
38
 
39
39
  nonmatching_resource = previous_resources_for_reads.find do |prev_resource|
40
- resource_specific_granular_scope_search_params.none? do |scope|
40
+ resource_specific_granular_scope_search_params.none? do |scope|
41
41
  resource_matches_param?(prev_resource, scope[:name], scope[:value])
42
42
  end
43
43
  end
44
44
  if nonmatching_resource
45
45
  fhir_read resource_type, nonmatching_resource.id
46
46
  assert (response && response[:status]) != 200, "Server incorrectly responded with a successful status, read should fail due to scopes."
47
- assert (resource && resource.resourceType != resource_type), "Server incorrectly returned a #{resource_type}, read should fail due to scopes"
47
+
48
+ begin
49
+ res = resource
50
+ rescue NoMethodError
51
+ res = nil
52
+ end
53
+
54
+ assert (!res || res.resourceType == 'OperationOutcome'), "Read shall fail due to scopes. Server shall return 4xx status code with an optional OperationOutcome payload."
48
55
  else
49
56
  info "Unable to find a resource that does not match scopes."
50
57
  end
51
58
  end
52
-
59
+
53
60
  def load_previous_requests
54
61
  params = metadata.searches.first[:names]
55
62
  search_params_as_hash = params.each_with_object({}) do |name, hash|
@@ -14,221 +14,7 @@ module USCoreTestKit
14
14
  def perform_must_support_test(resources)
15
15
  skip_if resources.blank?, "No #{resource_type} resources were found"
16
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
- if (missing_elements + missing_slices + missing_extensions).length.zero?
24
- pass
25
- end
26
- skip "Could not find #{missing_must_support_strings.join(', ')} in the #{resources.length} " \
27
- "provided #{resource_type} resource(s)"
28
- end
29
-
30
- def handle_must_support_choices
31
- missing_elements.delete_if do |element|
32
- choices = metadata.must_supports[:choices].find { |choice| choice[:paths]&.include?(element[:path]) }
33
- is_any_choice_supported?(choices)
34
- end
35
-
36
- missing_extensions.delete_if do |extension|
37
- choices = metadata.must_supports[:choices].find { |choice| choice[:extension_ids]&.include?(extension[:id]) }
38
- is_any_choice_supported?(choices)
39
- end
40
-
41
- missing_slices.delete_if do |slice|
42
- choices = metadata.must_supports[:choices].find { |choice| choice[:slice_names]&.include?(slice[:name]) }
43
- is_any_choice_supported?(choices)
44
- end
45
- end
46
-
47
- def is_any_choice_supported? (choices)
48
- choices.present? &&
49
- (
50
- choices[:paths]&.any? { |path| missing_elements.none? { |element| element[:path] == path } } ||
51
- choices[:extension_ids]&.any? { |extension_id| missing_extensions.none? { |extension| extension[:id] == extension_id} } ||
52
- choices[:slice_names]&.any? { |slice_name| missing_slices.none? { |slice| slice[:name] == slice_name} }
53
- )
54
- end
55
-
56
- def missing_must_support_strings
57
- missing_elements.map { |element_definition| missing_element_string(element_definition) } +
58
- missing_slices.map { |slice_definition| slice_definition[:slice_id] } +
59
- missing_extensions.map { |extension_definition| extension_definition[:id] }
60
- end
61
-
62
- def missing_element_string(element_definition)
63
- if element_definition[:fixed_value].present?
64
- "#{element_definition[:path]}:#{element_definition[:fixed_value]}"
65
- else
66
- element_definition[:path]
67
- end
68
- end
69
-
70
- def exclude_uscdi_only_test?
71
- config.options[:exclude_uscdi_only_test] == true
72
- end
73
-
74
- def must_support_extensions
75
- if exclude_uscdi_only_test?
76
- metadata.must_supports[:extensions].reject{ |extension| extension[:uscdi_only] }
77
- else
78
- metadata.must_supports[:extensions]
79
- end
80
- end
81
-
82
- def missing_extensions(resources = [])
83
- @missing_extensions ||=
84
- must_support_extensions.select do |extension_definition|
85
- resources.none? do |resource|
86
- path = extension_definition[:path]
87
-
88
- if path == 'extension'
89
- resource.extension.any? { |extension| extension.url == extension_definition[:url] }
90
- else
91
- extension = find_a_value_at(resource, path) do |el|
92
- el.url == extension_definition[:url]
93
- end
94
-
95
- extension.present?
96
- end
97
- end
98
- end
99
- end
100
-
101
- def must_support_elements
102
- if exclude_uscdi_only_test?
103
- metadata.must_supports[:elements].reject{ |element| element[:uscdi_only] }
104
- else
105
- metadata.must_supports[:elements]
106
- end
107
- end
108
-
109
- def missing_elements(resources = [])
110
- @missing_elements ||= find_missing_elements(resources, must_support_elements)
111
- @missing_elements
112
- end
113
-
114
- def find_missing_elements(resources, must_support_elements)
115
- must_support_elements.select do |element_definition|
116
- resources.none? do |resource|
117
- path = element_definition[:path]
118
- ms_extension_urls = must_support_extensions.select { |ex| ex[:path] == "#{path}.extension" }
119
- .map { |ex| ex[:url] }
120
-
121
- value_found = find_a_value_at(resource, path) do |value|
122
- if value.instance_of?(USCoreTestKit::PrimitiveType) && ms_extension_urls.present?
123
- urls = value.extension&.map(&:url)
124
- has_ms_extension = (urls & ms_extension_urls).present?
125
- end
126
-
127
- unless has_ms_extension
128
- value = value.value if value.instance_of?(USCoreTestKit::PrimitiveType)
129
- value_without_extensions =
130
- value.respond_to?(:to_hash) ? value.to_hash.reject { |key, _| key == 'extension' } : value
131
- end
132
-
133
- (has_ms_extension || value_without_extensions.present? || value_without_extensions == false) &&
134
- (element_definition[:fixed_value].blank? || value == element_definition[:fixed_value])
135
- end
136
- # Note that false.present? => false, which is why we need to add this extra check
137
- value_found.present? || value_found == false
138
- end
139
- end
140
- end
141
-
142
- def must_support_slices
143
- if exclude_uscdi_only_test?
144
- metadata.must_supports[:slices].reject{ |slice| slice[:uscdi_only] }
145
- else
146
- metadata.must_supports[:slices]
147
- end
148
- end
149
-
150
- def missing_slices(resources = [])
151
- @missing_slices ||=
152
- must_support_slices.select do |slice|
153
- resources.none? do |resource|
154
- path = slice[:path] # .delete_suffix('[x]')
155
- find_slice(resource, path, slice[:discriminator]).present?
156
- end
157
- end
158
- end
159
-
160
- def find_slice(resource, path, discriminator)
161
- find_a_value_at(resource, path) do |element|
162
- case discriminator[:type]
163
- when 'patternCodeableConcept'
164
- coding_path = discriminator[:path].present? ? "#{discriminator[:path]}.coding" : 'coding'
165
- find_a_value_at(element, coding_path) do |coding|
166
- coding.code == discriminator[:code] && coding.system == discriminator[:system]
167
- end
168
- when 'patternCoding'
169
- coding_path = discriminator[:path].present? ? discriminator[:path] : ''
170
- find_a_value_at(element, coding_path) do |coding|
171
- coding.code == discriminator[:code] && coding.system == discriminator[:system]
172
- end
173
- when 'patternIdentifier'
174
- find_a_value_at(element, discriminator[:path]) { |identifier| identifier.system == discriminator[:system] }
175
- when 'value'
176
- values = discriminator[:values].map { |value| value.merge(path: value[:path].split('.')) }
177
- find_slice_by_values(element, values)
178
- when 'type'
179
- case discriminator[:code]
180
- when 'Date'
181
- begin
182
- Date.parse(element)
183
- rescue ArgumentError
184
- false
185
- end
186
- when 'DateTime'
187
- begin
188
- DateTime.parse(element)
189
- rescue ArgumentError
190
- false
191
- end
192
- when 'String'
193
- element.is_a? String
194
- else
195
- element.is_a? FHIR.const_get(discriminator[:code])
196
- end
197
- when 'requiredBinding'
198
- coding_path = discriminator[:path].present? ? "#{discriminator[:path]}.coding" : 'coding'
199
-
200
- find_a_value_at(element, coding_path) do |coding|
201
- discriminator[:values].any? { |value| value[:system] == coding.system && value[:code] == coding.code }
202
- end
203
- end
204
- end
205
- end
206
-
207
- def find_slice_by_values(element, value_definitions)
208
- path_prefixes = value_definitions.map { |value_definition| value_definition[:path].first }.uniq
209
- Array.wrap(element).find do |el|
210
- path_prefixes.all? do |path_prefix|
211
- value_definitions_for_path =
212
- value_definitions
213
- .select { |value_definition| value_definition[:path].first == path_prefix }
214
- .each { |value_definition| value_definition[:path].shift }
215
-
216
- find_a_value_at(el, path_prefix) do |el_found|
217
- child_element_value_definitions, current_element_value_definitions =
218
- value_definitions_for_path.partition { |value_definition| value_definition[:path].present? }
219
-
220
- current_element_values_match =
221
- current_element_value_definitions
222
- .all? { |value_definition| value_definition[:value] == el_found }
223
-
224
- child_element_values_match =
225
- child_element_value_definitions.present? ?
226
- find_slice_by_values(el_found, child_element_value_definitions) : true
227
-
228
- current_element_values_match && child_element_values_match
229
- end
230
- end
231
- end
17
+ skip { assert_must_support_elements_present(resources, nil, metadata:) }
232
18
  end
233
19
  end
234
20
  end
@@ -25,7 +25,7 @@ module USCoreTestKit
25
25
 
26
26
  def verify_practitioner_address
27
27
  references = scratch.dig(:references, 'Practitioner')
28
- assert references.any?, 'No Pracitioner references found.'
28
+ assert references.any?, 'No Practitioner references found.'
29
29
 
30
30
  @missing_elements = MUST_SUPPORT_ELEMENTS
31
31
  practitioners = []
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module USCoreTestKit
4
- VERSION = '0.11.0'
5
- LAST_UPDATED = '2025-03-18'
4
+ VERSION = '0.11.1'
5
+ LAST_UPDATED = '2025-04-07'
6
6
  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.11.0
4
+ version: 0.11.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen MacVicar
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-03-19 00:00:00.000000000 Z
11
+ date: 2025-04-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: inferno_core
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.6.4
19
+ version: 0.6.8
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 0.6.4
26
+ version: 0.6.8
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: smart_app_launch_test_kit
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 0.6.0
33
+ version: 0.6.1
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: 0.6.0
40
+ version: 0.6.1
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: tls_test_kit
43
43
  requirement: !ruby/object:Gem::Requirement