service_base_url_test_kit 0.10.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9a699526f6d06f8063e2d7036a51aba54fe68d2c2c9f160440517ecb34aea65e
4
- data.tar.gz: 509c6f78c00322be2603803f3d138c3ec39b34fd0e18888a9df5b201293c7a72
3
+ metadata.gz: 638bed4317d3630a7ffdfbc9cef4be2dc266ab285de017d890a1ceadec4858fc
4
+ data.tar.gz: fab6cb020b68f87db82348891f3b80eb0d5e3bc9181639c9bf1b5a9505611de4
5
5
  SHA512:
6
- metadata.gz: 9cd8a0ee15f013e8da8a531b0f8c95a8f838927615096456a32f96f0032a2e31ce7f7722988c51e5779bc85b33b45f2d8491fbd1ce64cf0a06496068e85418fc
7
- data.tar.gz: fd5cf2fd1794d0204f9b15da318560a61225a8017871dc301117117aec6500fe31ab5ec4c577de3bc257f5967df326203708798fcff9a5068c038277432401c1
6
+ metadata.gz: 61b58536e24b25039953dc99cc4a507202c08297a8be0f70edb0d340ec0fa77824dbaee0de8be5bb548306eaf5c0e5b47dc143405882ebb5f91537bd258ccb68
7
+ data.tar.gz: 1fccec1d67cb3642771fa89360e90b3ad9f157bed70d35ee5beb09324cc5b649f74554638df4202834ffba3ca43c1578751477df79eb7c626707371ace21d205
@@ -1,40 +1,40 @@
1
1
  module ServiceBaseURLTestKit
2
2
  class ServiceBaseURLEndpointQueryGroup < Inferno::TestGroup
3
3
  id :service_base_url_retrieve_list
4
- title 'Retrieve Service Base URL List'
4
+ title 'Retrieve Service Base URL Publication'
5
5
  description %(
6
- A developer's Service Base URL list must be publicly available. This test
6
+ A developer's Service Base URL publication must be publicly available. This test
7
7
  issues a HTTP GET request against the supplied URL and expects to receive
8
- the service base url list at this location.
8
+ the service base url publication at this location.
9
9
  )
10
10
  run_as_group
11
11
 
12
- input :service_base_url_list_url,
13
- title: 'Service Base URL List URL',
14
- description: 'The URL to the developer\'s public Service Base URL List'
15
-
16
12
  http_client do
17
- url :service_base_url_list_url
18
- headers 'Accept': 'application/json, application/fhir+json'
13
+ url :service_base_url_publication_url
14
+ headers Accept: 'application/json, application/fhir+json'
19
15
  end
20
16
 
21
17
  test do
22
18
  id :service_base_url_retrieve_list_test
23
- title 'Server returns publicly accessible Service Base URL List'
19
+ title 'Server returns publicly accessible Service Base URL Publication'
24
20
  description %(
25
21
  Verify that the developer's list of Service Base URLs can be publicly
26
22
  accessed at the supplied URL location.
27
23
  )
28
24
 
25
+ input :service_base_url_publication_url,
26
+ optional: true
27
+
29
28
  output :bundle_response
30
29
 
31
30
  makes_request :bundle_request
32
31
 
33
32
  run do
34
- get
33
+ omit_if service_base_url_publication_url.blank?, 'URL for Service Base URL Publication not Inputted.'
34
+
35
+ get(tags: ['service_base_url_bundle'])
35
36
  assert_response_status(200)
36
- output bundle_response: resource.to_json
37
- end
37
+ end
38
38
  end
39
39
  end
40
40
  end
@@ -4,26 +4,53 @@ require_relative 'service_base_url_retrieve_group'
4
4
  module ServiceBaseURLTestKit
5
5
  class ServiceBaseURLGroup < Inferno::TestGroup
6
6
  id :service_base_url_test_group
7
- title 'Retrieve and Validate Service Base URL List'
8
- description %(
9
- Verify that the developer makes its Service Base URL list publicly available
10
- in the Bundle resource format with valid Endpoint and Organization entries.
11
- This test group will issue a HTTP GET request against the supplied URL to
12
- retrieve the developer's Service Base URL list and ensure the list is
13
- publicly accessible. It will then ensure that the returned service base URL
14
- list is in the Bundle resource format containing its service base URLs and
15
- related organizational details in valid Endpoint and Organization resources
16
- that follow the specifications detailed in the HTI-1 rule in the API
17
- Condition and Maintenance of Certification.
18
-
19
- For systems that provide the service base URL Bundle at a URL, please run
20
- all tests within this group. While it is the expectation of the
21
- specification for the service base URL Bundle to be served at a
22
- public-facing endpoint, testers can validate a Service Base URL Bundle not
23
- served at a public endpoint by running Test 1.2: Validate Service Base URL
24
- List validation individually.
7
+ title 'Validate Service Base URL Publication'
8
+ description %(
9
+ Verify that the developer makes its Service Base URL publication publicly available
10
+ in the Bundle resource format with valid Endpoint and Organization entries.
11
+ This test group will issue a HTTP GET request against the supplied URL to
12
+ retrieve the developer's Service Base URL publication and ensure the list is
13
+ publicly accessible. It will then ensure that the returned service base URL
14
+ publication is in the Bundle resource format containing its service base URLs and
15
+ related organizational details in valid Endpoint and Organization resources
16
+ that follow the specifications detailed in the HTI-1 rule and the API
17
+ Condition and Maintenance of Certification.
18
+
19
+ For systems that provide the service base URL Bundle at a URL, please run
20
+ this test with the Service Base URL Publication URL input populated and the Service Base URL Publication Bundle
21
+ input left blank. While it is the expectation of the specification for the service base URL Bundle to be served at a
22
+ public-facing endpoint, testers can validate a Service Base URL Bundle not served at a public endpoint by running
23
+ these tests with the Service Base URL Publication Bundle input populated and the Service Base URL Publication URL
24
+ input left blank.
25
25
  )
26
-
26
+
27
+ input_instructions <<~INSTRUCTIONS
28
+ For systems that make their Service Base URL Bundle available at a public endpoint, please input
29
+ the Service Base URL Publication URL to retrieve the Bundle from there in order to perform validation.
30
+
31
+ For systems that do not have a Service Base URL Bundle served at a public endpoint, testers can validate by
32
+ providing the Service Base URL Publication Bundle as an input and leaving the Service Base URL Publication URL
33
+ input blank.
34
+ INSTRUCTIONS
35
+
36
+ run_as_group
37
+
38
+ input :service_base_url_publication_url,
39
+ title: 'Service Base URL Publication URL',
40
+ description: %(The URL to the developer's public Service Base URL Publication. Insert your Service Base URL
41
+ publication URL if you host your Bundle at a public-facing endpoint and want Inferno to retrieve the Bundle
42
+ from there.),
43
+ optional: true
44
+
45
+ input :service_base_url_bundle,
46
+ title: 'Service Base URL Publication Bundle',
47
+ description: %(The developer's Service Base URL Publication in the JSON string format. If this input is
48
+ populated, Inferno will use the Bundle inserted here to do validation. Insert your Service Base URL
49
+ Publication Bundle in the JSON format in this input to validate your list without Inferno needing to access
50
+ the Bundle via a public-facing endpoint.),
51
+ type: 'textarea',
52
+ optional: true
53
+
27
54
  group from: :service_base_url_retrieve_list
28
55
  group from: :service_base_url_validate_list
29
56
  end
@@ -1,41 +1,87 @@
1
1
  module ServiceBaseURLTestKit
2
2
  class ServiceBaseURLBundleTestGroup < Inferno::TestGroup
3
3
  id :service_base_url_validate_list
4
- title 'Validate Service Base URL List'
4
+ title 'Validate Service Base URL Publication'
5
5
  description %(
6
- These tests ensure that the developer's Service Base URL list is in the
7
- Bundle resource format, with its service base URLs and organizational
6
+ These tests ensure that the developer's Service Base URL publication is in
7
+ the Bundle resource format, with its service base URLs and organizational
8
8
  details contained in valid Endpoint and Organization entries that follow
9
- the specifications detailed in the HTI-1 rule in the API Condition and
9
+ the specifications detailed in the HTI-1 rule and the API Condition and
10
10
  Maintenance of Certification.
11
+
12
+ These tests may be run individually, bypassing the first test group, if the Service Base URL Publication Bundle
13
+ input is populated and the Service Base URL Publication URL is left blank (or if it does not successfully return
14
+ a Service Base URL Publication Bundle). You may insert your Service Base URL Publication Bundle in the JSON
15
+ format in the Service Base URL Publication Bundle input to validate your list without Inferno needing to retrieve
16
+ the Bundle via a public-facing endpoint.
11
17
  )
12
18
  run_as_group
13
19
 
14
- input :bundle_response,
15
- title: 'Service Base URL List Bundle',
16
- description: 'The developer\'s Service Base URL List in the JSON string format',
17
- type: 'textarea'
18
-
20
+ input :service_base_url_bundle,
21
+ optional: true
22
+
23
+ input :endpoint_availability_success_rate,
24
+ title: 'Endpoint Availability Success Rate',
25
+ description: %(
26
+ Select an option to choose how many Endpoints have to be available and send back a valid capability
27
+ statement for the Endpoint validation test to pass.
28
+ ),
29
+ type: 'radio',
30
+ options: {
31
+ list_options: [
32
+ {
33
+ label: 'All',
34
+ value: 'all'
35
+ },
36
+ {
37
+ label: 'At Least One',
38
+ value: 'at_least_1'
39
+ },
40
+ {
41
+ label: 'None',
42
+ value: 'none'
43
+ }
44
+ ]
45
+ },
46
+ default: 'all'
47
+
48
+ input :endpoint_availability_limit,
49
+ title: 'Endpoint Availability Limit',
50
+ description: %(
51
+ In the case where the Endpoint Availability Success Rate is 'All', input a number to cap the number of
52
+ Endpoints that Inferno will send requests to check for availability. This can help speed up validation when
53
+ there are large number of endpoints in the Service Base URL Bundle.
54
+ ),
55
+ optional: true
56
+
19
57
  # @private
20
58
  def find_referenced_org(bundle_resource, endpoint_id)
21
59
  bundle_resource
22
- .entry
23
- .map(&:resource)
24
- .select { |resource| resource.resourceType == 'Organization' }
25
- .map { |resource| resource.endpoint }
26
- .flatten
27
- .map(&:reference)
28
- .select { |reference| reference.include? endpoint_id }
60
+ .entry
61
+ .map(&:resource)
62
+ .select { |resource| resource.resourceType == 'Organization' }
63
+ .map(&:endpoint)
64
+ .flatten
65
+ .map(&:reference)
66
+ .select { |reference| reference.include? endpoint_id }
29
67
  end
30
68
 
31
69
  # @private
32
70
  def find_referenced_endpoint(bundle_resource, endpoint_id_ref)
33
71
  bundle_resource
34
- .entry
35
- .map(&:resource)
36
- .select { |resource| resource.resourceType == 'Endpoint' }
37
- .map(&:id)
38
- .select { |endpoint_id| endpoint_id_ref.include? endpoint_id }
72
+ .entry
73
+ .map(&:resource)
74
+ .select { |resource| resource.resourceType == 'Endpoint' }
75
+ .map(&:id)
76
+ .select { |endpoint_id| endpoint_id_ref.include? endpoint_id }
77
+ end
78
+
79
+ def skip_message
80
+ %(
81
+ No Service Base URL request was made in the previous test, and no Service Base URL Publication Bundle
82
+ was provided as input instead. Either provide a Service Base URL Publication URL to retrieve the Bundle via a
83
+ HTTP GET request, or provide the Bundle as an input.
84
+ )
39
85
  end
40
86
 
41
87
  # Valid BUNDLE TESTS
@@ -47,8 +93,16 @@ module ServiceBaseURLTestKit
47
93
  )
48
94
 
49
95
  run do
96
+ bundle_response = if service_base_url_bundle.blank?
97
+ load_tagged_requests('service_base_url_bundle')
98
+ skip skip_message if requests.length != 1
99
+ requests.first.response_body
100
+ else
101
+ service_base_url_bundle
102
+ end
50
103
  skip_if bundle_response.blank?, 'No Bundle response was provided'
51
104
 
105
+ assert_valid_json(bundle_response)
52
106
  bundle_resource = FHIR.from_contents(bundle_response)
53
107
  assert_valid_resource(resource: bundle_resource)
54
108
 
@@ -58,13 +112,24 @@ module ServiceBaseURLTestKit
58
112
  The given Bundle does not contain any resources
59
113
  )
60
114
  end
61
- end
115
+
116
+ additional_resources = bundle_resource.entry
117
+ .map { |entry| entry.resource.resourceType }
118
+ .reject { |resource_type| ['Organization', 'Endpoint'].include?(resource_type) }
119
+ .uniq
120
+
121
+ warning do
122
+ assert(additional_resources.empty?, %(
123
+ The Service Base URL List contained the following additional resources other than Endpoint and
124
+ Organization resources: #{additional_resources.join(', ')}))
125
+ end
126
+ end
62
127
  end
63
128
 
64
129
  # VALID ENDPOINT TESTS
65
130
  test do
66
131
  id :service_base_url_valid_endpoints
67
- title 'Service Base URL List contains valid Endpoint resources'
132
+ title 'Service Base URL Publication contains valid Endpoint resources'
68
133
  description %(
69
134
  Verify that Bundle of Service Base URLs contains Endpoints that are
70
135
  valid Endpoint resources according to the format defined in FHIR v4.0.1.
@@ -79,19 +144,25 @@ module ServiceBaseURLTestKit
79
144
  )
80
145
 
81
146
  run do
82
-
147
+ bundle_response = if service_base_url_bundle.blank?
148
+ load_tagged_requests('service_base_url_bundle')
149
+ skip skip_message if requests.length != 1
150
+ requests.first.response_body
151
+ else
152
+ service_base_url_bundle
153
+ end
83
154
  skip_if bundle_response.blank?, 'No Bundle response was provided'
84
155
 
156
+ assert_valid_json(bundle_response)
85
157
  bundle_resource = FHIR.from_contents(bundle_response)
86
158
 
87
159
  skip_if bundle_resource.entry.empty?, 'The given Bundle does not contain any resources'
88
160
 
89
161
  assert_valid_bundle_entries(bundle: bundle_resource,
90
- resource_types: {
91
- 'Endpoint': nil
92
- }
93
- )
94
-
162
+ resource_types: {
163
+ Endpoint: nil
164
+ })
165
+
95
166
  endpoint_ids =
96
167
  bundle_resource
97
168
  .entry
@@ -99,13 +170,12 @@ module ServiceBaseURLTestKit
99
170
  .select { |resource| resource.resourceType == 'Endpoint' }
100
171
  .map(&:id)
101
172
 
102
-
103
- for endpoint_id in endpoint_ids
173
+ endpoint_ids.each do |endpoint_id|
104
174
  endpoint_referenced_orgs = find_referenced_org(bundle_resource, endpoint_id)
105
- assert !endpoint_referenced_orgs.empty?, "Endpoint with id: #{endpoint_id} does not have any associated Organizations in the Bundle."
106
-
175
+ assert !endpoint_referenced_orgs.empty?,
176
+ "Endpoint with id: #{endpoint_id} does not have any associated Organizations in the Bundle."
107
177
  end
108
- end
178
+ end
109
179
  end
110
180
 
111
181
  # ENDPOINT VALID URL TESTS
@@ -113,49 +183,97 @@ module ServiceBaseURLTestKit
113
183
  id :service_base_url_valid_urls
114
184
  title 'All Endpoint resource referenced URLS should be valid and available'
115
185
  description %(
116
- Verify that Bundle of Service Base URLs contains Endpoints that contain service base URLs that are both valid and available.
186
+ Verify that Bundle of Service Base URLs contains Endpoints that contain service base URLs that are both valid
187
+ and available.
117
188
  )
118
189
 
119
- output :testing
120
-
121
190
  run do
191
+ bundle_response = if service_base_url_bundle.blank?
192
+ load_tagged_requests('service_base_url_bundle')
193
+ skip skip_message if requests.length != 1
194
+ requests.first.response_body
195
+ else
196
+ service_base_url_bundle
197
+ end
122
198
  skip_if bundle_response.blank?, 'No Bundle response was provided'
123
199
 
200
+ assert_valid_json(bundle_response)
124
201
  bundle_resource = FHIR.from_contents(bundle_response)
125
202
 
126
203
  skip_if bundle_resource.entry.empty?, 'The given Bundle does not contain any resources'
127
204
 
205
+ endpoint_list = bundle_resource
206
+ .entry
207
+ .map(&:resource)
208
+ .select { |resource| resource.resourceType == 'Endpoint' }
209
+ .map(&:address)
210
+ .uniq
211
+
212
+ if endpoint_availability_limit.present? && endpoint_availability_limit.to_i < endpoint_list.count
213
+ info %(
214
+ Only the first #{endpoint_availability_limit.to_i} endpoints of #{endpoint_list.count} total will be
215
+ checked.
216
+ )
217
+ end
128
218
 
129
- bundle_resource
130
- .entry
131
- .map(&:resource)
132
- .select { |resource| resource.resourceType == 'Endpoint' }
133
- .map(&:address)
134
- .each do |address|
135
- assert_valid_http_uri(address)
136
-
137
- address = address.delete_suffix("/")
138
- get("#{address}/metadata", client: nil, headers: {'Accept': 'application/json, application/fhir+json'})
139
- assert_response_status(200)
140
- assert_resource_type(:capability_statement)
219
+ one_endpoint_valid = false
220
+ endpoint_list.each_with_index do |address, index|
221
+ assert_valid_http_uri(address)
222
+
223
+ next if endpoint_availability_success_rate == 'none' ||
224
+ (endpoint_availability_limit.present? && endpoint_availability_limit.to_i <= index)
225
+
226
+ address = address.delete_suffix('/')
227
+
228
+ response = nil
229
+ warning do
230
+ response = get("#{address}/metadata", client: nil, headers: { Accept: 'application/fhir+json' })
231
+ end
232
+
233
+ if endpoint_availability_success_rate == 'all'
234
+ assert response.present?, "Encountered issues while trying to make a request to #{address}/metadata."
235
+ assert_response_status(200)
236
+ assert resource.present?, 'The content received does not appear to be a valid FHIR resource'
237
+ assert_resource_type(:capability_statement)
238
+ else
239
+ if response.present?
240
+ warning do
241
+ assert_response_status(200)
242
+ assert resource.present?, 'The content received does not appear to be a valid FHIR resource'
243
+ assert_resource_type(:capability_statement)
244
+ end
245
+ end
246
+
247
+ if !one_endpoint_valid && response.present? && response.status == 200 && resource.present? &&
248
+ resource.resourceType == 'CapabilityStatement'
249
+ one_endpoint_valid = true
250
+ end
251
+ end
141
252
  end
142
- end
143
- end
144
253
 
254
+ if endpoint_availability_success_rate == 'at_least_1'
255
+ assert(one_endpoint_valid, %(
256
+ There were no Endpoints that were available and returned a valid Capability Statement in the Service Base
257
+ URL Bundle'
258
+ ))
259
+ end
260
+ end
261
+ end
145
262
 
146
263
  # ORGANIZATION TESTS
147
264
  test do
148
265
  id :service_base_url_valid_organizations
149
- title 'Service Base URL List contains valid Organization resources'
266
+ title 'Service Base URL Publication contains valid Organization resources'
150
267
  description %(
151
268
 
152
- Verify that Bundle of Service Base URLs contains Organizations that are valid Organization resources according to the format defined in FHIR v4.0.1.
269
+ Verify that Bundle of Service Base URLs contains Organizations that are valid Organization resources according
270
+ to the format defined in FHIR v4.0.1.
153
271
 
154
272
  Each Organization must:
155
273
  - Contain must have elements including:
156
274
  - active
157
275
  - name
158
- - Include the organization's name, location, and provider identifier
276
+ - Include the organization's name, location, and facility identifier
159
277
  - Use the endpoint field to reference Endpoints associated with the Organization:
160
278
  - Must reference only Endpoint resources in the endpoint field
161
279
  - Must reference at least one Endpoint resource in the endpoint field
@@ -163,39 +281,53 @@ module ServiceBaseURLTestKit
163
281
  )
164
282
 
165
283
  run do
284
+ bundle_response = if service_base_url_bundle.blank?
285
+ load_tagged_requests('service_base_url_bundle')
286
+ skip skip_message if requests.length != 1
287
+ requests.first.response_body
288
+ else
289
+ service_base_url_bundle
290
+ end
166
291
  skip_if bundle_response.blank?, 'No Bundle response was provided'
167
292
 
293
+ assert_valid_json(bundle_response)
168
294
  bundle_resource = FHIR.from_contents(bundle_response)
169
295
 
170
296
  skip_if bundle_resource.entry.empty?, 'The given Bundle does not contain any resources'
171
297
 
172
298
  assert_valid_bundle_entries(bundle: bundle_resource,
173
- resource_types: {
174
- 'Organization': nil
175
- }
176
- )
177
-
178
- endpoint_ids =
179
- bundle_resource
180
- .entry
181
- .map(&:resource)
182
- .select { |resource| resource.resourceType == 'Endpoint' }
183
- .map(&:id)
184
-
299
+ resource_types: {
300
+ Organization: nil
301
+ })
302
+
303
+ organization_resources = bundle_resource
304
+ .entry
305
+ .map(&:resource)
306
+ .select { |resource| resource.resourceType == 'Organization' }
307
+
308
+ warning do
309
+ # This was requested to be included because a publication with only a single organization
310
+ # seems like a likely error and should be checked manually.
311
+ assert(organization_resources.length > 1,
312
+ 'The provided Service Base URL List contains only 1 Organization resource')
313
+ end
185
314
 
186
- for organization in bundle_resource.entry.map(&:resource).select { |resource| resource.resourceType == 'Organization' }
315
+ organization_resources.each do |organization|
316
+ assert !organization.endpoint.empty?,
317
+ "Organization with id: #{organization.id} does not have the endpoint field populated"
318
+ assert !organization.address.empty?,
319
+ "Organization with id: #{organization.id} does not have the address field populated"
187
320
 
188
- assert !organization.endpoint.empty?, "Organization with id: #{organization.id} does not have the endpoint field populated"
189
- assert !organization.address.empty?, "Organization with id: #{organization.id} does not have the address field populated"
321
+ endpoint_references = organization.endpoint.map(&:reference)
190
322
 
191
-
192
- for endpoint_id_ref in organization.endpoint.map(&:reference)
323
+ endpoint_references.each do |endpoint_id_ref|
193
324
  organization_referenced_endpts = find_referenced_endpoint(bundle_resource, endpoint_id_ref)
194
- assert !organization_referenced_endpts.empty?, "Organization with id: #{organization.id} references an Endpoint that is not contained in this bundle."
195
-
325
+ assert !organization_referenced_endpts.empty?,
326
+ "Organization with id: #{organization.id} references an Endpoint that is not contained in this
327
+ bundle."
196
328
  end
197
- end
198
- end
329
+ end
330
+ end
199
331
  end
200
332
  end
201
- end
333
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ServiceBaseURLTestKit
4
- VERSION = '0.10.0'
4
+ VERSION = '0.11.0'
5
5
  end
@@ -7,52 +7,69 @@ module ServiceBaseURLTestKit
7
7
  id :service_base_url
8
8
  title 'Service Base URL Test Suite'
9
9
  description %(
10
- This test kit provides a draft set of tests to validate conformance to
11
- [HTI-1](https://www.healthit.gov/topic/laws-regulation-and-policy/health-data-technology-and-interoperability-certification-program)
12
- [rule](https://www.ecfr.gov/current/title-45/subtitle-A/subchapter-D/part-170/subpart-D/section-170.404#p-170.404(b)(2))
13
- from the API Condition and Maintenance of Certification to include the
14
- requirement for Certified API Developers with patient-facing apps to
15
- publish their service base URLs in [a specified
16
- format](https://www.federalregister.gov/d/2023-07229/p-2342).
17
-
18
- A Certified API developer must publish, at no charge, the service base
19
- URLs and related organizational details that can be used by patients to
20
- access their electronic health information. This test kit will test that a
21
- server's service base URL list conforms to the following:
22
- - Service base URL list is publicly accessible
23
- - Service based URLs are published in the Endpoint resource format
24
- according to the standard adopted in § 170.215\(a\) - FHIR 4.0.1 release
25
- - Organization details for each service base URL are published in the
26
- Organization resource format according to the standard adopted in §
27
- 170.215\(a\) - FHIR 4.0.1 release
28
- - Each Endpoint resource must:
29
- - Have at least one Organization resource that references it in the Bundle
30
- - Each Organization resource must:
31
- - Have a populated Organization.endpoint field that contains
32
- references to the Endpoint resources containing service base URLs
33
- managed by this organization
34
- - Contain the organization's name, location, and provider identifier
35
- - Endpoint and Organization resources must be:
36
- - Collected into a Bundle resource formatted according to the standard
37
- adopted in FHIR v4.0.1: § 170.215\(a\) for publication
38
-
39
- While these tests do not specifically verify conformance to
40
- [Patient-Access
41
- Brands](https://build.fhir.org/ig/HL7/smart-app-launch/brands.html) within
42
- the draft SMART App Launch v2.2.0 standard, systems that implement that
43
- standard should pass these tests. Please report an issue if there are any
44
- problems.
45
-
46
- The tests within this test kit are available for developers that would
47
- like to evaluate their service list against the specified format. This is
48
- a draft set of tests and may contain errors or issues. Please provide
49
- feedback on these tests by reporting an issue in
10
+ This Test Kit provides a set of tests that verify conformance of Service
11
+ Base URL publications to data format requirements as described in
12
+ [Conditions and Maintenance of Certification - Application programming
13
+ interfaces](https://www.ecfr.gov/current/title-45/subtitle-A/subchapter-D/part-170/subpart-D/section-170.404#p-170.404(b)(2))
14
+ and the [ONC HTI-1 Final
15
+ Rule](https://www.healthit.gov/topic/laws-regulation-and-policy/health-data-technology-and-interoperability-certification-program).
16
+ Please review the [Application Programming Interfaces Certification Companion
17
+ Guide](https://www.healthit.gov/condition-ccg/application-programming-interfaces)
18
+ for additional guidance.
19
+
20
+ This Test Kit is provided as a tool to help developers identify potential
21
+ issues or problems with the structure of their Service Base URL
22
+ publication. Test failures do not necessarily indicate non-conformance to
23
+ the Conditions and Maintenance of Certification. Use of these tests is
24
+ not required for the participants of the ONC Health IT Certification Program.
25
+ Please provide feedback on these tests by reporting an issue in
50
26
  [GitHub](https://github.com/inferno-framework/service-base-url-test-kit/issues),
51
27
  or by reaching out to the team on the [Inferno FHIR Zulip
52
28
  channel](https://chat.fhir.org/#narrow/stream/179309-inferno).
29
+
30
+ Relevant requirements from the [Conditions and Maintenance of
31
+ Certification - Application programming
32
+ interfaces](https://www.ecfr.gov/current/title-45/subtitle-A/subchapter-D/part-170/subpart-D/section-170.404#p-170.404(b)(2)):
33
+
34
+ Service Base URL publication:
35
+
36
+ For all Health IT Modules certified to § 170.315(g)(10), a Certified API
37
+ Developer must publish, at no charge, the service base URLs and related
38
+ organization details that can be used by patients to access their
39
+ electronic health information, by December 31, 2024. This includes all
40
+ customers regardless of whether the Health IT Modules certified to §
41
+ 170.315(g)(10) are centrally managed by the Certified API Developer or
42
+ locally deployed by an API Information Source. These service base URLs and
43
+ organization details must conform to the following:
44
+
45
+ - Service base URLs must be publicly published in Endpoint resource format
46
+ according to the standard adopted in § 170.215(a) (FHIR v4.0.1).
47
+ - Organization details for each service base URL must be publicly published in Organization
48
+ resource format according to the standard adopted in § 170.215(a) (FHIR v4.0.1). Each
49
+ Organization resource must contain:
50
+ - A reference, in the Organization endpoint element, to the Endpoint
51
+ resources containing service base URLs managed by this organization.
52
+ - The organization's name, location, and facility identifier.
53
+ - Endpoint and Organization resources must be:
54
+ - Collected into a Bundle resource formatted according to the standard
55
+ adopted in § 170.215(a) (FHIR v4.0.1) for publication;
56
+ - and Reviewed quarterly and, as
57
+ necessary, updated.
58
+
59
+
53
60
  )
54
61
  version VERSION
55
62
 
63
+ input_instructions <<~INSTRUCTIONS
64
+ For systems that make their Service Base URL Bundle available at a public endpoint, please input
65
+ the Service Base URL Publication URL to retrieve the Bundle from there in order to perform validation, and leave
66
+ the Service Base URL Publication Bundle input blank.
67
+
68
+ For systems that do not have a Service Base URL Bundle served at a public endpoint, testers can validate by
69
+ providing the Service Base URL Publication Bundle as an input and leaving the Service Base URL Publication URL
70
+ input blank.
71
+ INSTRUCTIONS
72
+
56
73
  links [
57
74
  {
58
75
  label: 'Report Issue',
@@ -61,6 +78,14 @@ module ServiceBaseURLTestKit
61
78
  {
62
79
  label: 'Open Source',
63
80
  url: 'https://github.com/inferno-framework/service-base-url-test-kit'
81
+ },
82
+ {
83
+ label: 'Service base URL requirements',
84
+ url: 'https://www.ecfr.gov/current/title-45/subtitle-A/subchapter-D/part-170/subpart-D/section-170.404#p-170.404(b)(2)'
85
+ },
86
+ {
87
+ label: 'Certification Companion Guide',
88
+ url: 'https://www.healthit.gov/condition-ccg/application-programming-interfaces'
64
89
  }
65
90
  ]
66
91
 
@@ -71,11 +96,9 @@ module ServiceBaseURLTestKit
71
96
  my_bundle = JSON.parse(erb_template.result).to_json
72
97
  filename = filename.delete_suffix('.erb')
73
98
  end
74
- if filename.include?("CapabilityStatement")
75
- filename = filename.delete_suffix('.json') + "/metadata"
76
- end
99
+ filename = "#{filename.delete_suffix('.json')}/metadata" if filename.include?('CapabilityStatement')
77
100
  my_bundle_route_handler = proc { [200, { 'Content-Type' => 'application/json' }, [my_bundle]] }
78
-
101
+
79
102
  # Serve a JSON file at INFERNO_PATH/custom/service_base_url/examples/filename
80
103
  route :get, File.join('/examples/', filename), my_bundle_route_handler
81
104
  end
@@ -83,7 +106,7 @@ module ServiceBaseURLTestKit
83
106
  VALIDATION_MESSAGE_FILTERS = [
84
107
  /A resource should have narrative for robust management/,
85
108
  /\A\S+: \S+: URL value '.*' does not resolve/
86
- ]
109
+ ].freeze
87
110
 
88
111
  # All FHIR validation requests will use this FHIR validator
89
112
  fhir_resource_validator :default do
@@ -94,4 +117,4 @@ module ServiceBaseURLTestKit
94
117
 
95
118
  group from: :service_base_url_test_group
96
119
  end
97
- end
120
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: service_base_url_test_kit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.0
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Inferno Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-06-06 00:00:00.000000000 Z
11
+ date: 2024-09-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: inferno_core