onc_certification_g10_test_kit 2.1.0 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/onc_certification_g10_test_kit/bulk_data_authorization.rb +7 -7
- data/lib/onc_certification_g10_test_kit/bulk_data_group_export.rb +6 -6
- data/lib/onc_certification_g10_test_kit/bulk_data_group_export_validation.rb +2 -2
- data/lib/onc_certification_g10_test_kit/bulk_export_validation_tester.rb +31 -5
- data/lib/onc_certification_g10_test_kit/configuration_checker.rb +16 -1
- data/lib/onc_certification_g10_test_kit/multi_patient_api.rb +2 -2
- data/lib/onc_certification_g10_test_kit/single_patient_api_group.rb +9 -5
- data/lib/onc_certification_g10_test_kit/smart_ehr_practitioner_app_group.rb +15 -1
- data/lib/onc_certification_g10_test_kit/smart_standalone_patient_app_group.rb +14 -1
- data/lib/onc_certification_g10_test_kit/version.rb +1 -1
- data/lib/onc_certification_g10_test_kit/well_known_capabilities_test.rb +1 -11
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b212142dbe987304c75b5323fd3ac1b2323f929a4e01b41f7722bff79db61fee
|
4
|
+
data.tar.gz: 3100cda0404c14b097e68adbdfbbc2e8e77590f53b6912c34c69560410e17a70
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 15417eeffcbbf4ba250c19b810ef4d8a6e5cd7a967e736321c92a5c39a1ba24aff1d9be8d362f41a368cb1d52a25be1bb756db0352c55bf9fff851d1ca688c1c
|
7
|
+
data.tar.gz: 171dcdaaf6bc3be2ec31a1169aaea28d255ae920732042989d48983e9db90aafb8859447fa18526aef86c36d945d29ded1581a2b921283acb7aee95e39f97443
|
@@ -6,8 +6,8 @@ module ONCCertificationG10TestKit
|
|
6
6
|
short_description 'Demonstrate SMART Backend Services Authorization for Bulk Data.'
|
7
7
|
description <<~DESCRIPTION
|
8
8
|
Bulk Data servers are required to authorize clients using the
|
9
|
-
[Backend Service Authorization](http://hl7.org/fhir/uv/bulkdata/STU1/authorization/index.html)
|
10
|
-
specification as defined in the [FHIR Bulk Data Access IG v1.0.
|
9
|
+
[Backend Service Authorization](http://hl7.org/fhir/uv/bulkdata/STU1.0.1/authorization/index.html)
|
10
|
+
specification as defined in the [FHIR Bulk Data Access IG v1.0.1](http://hl7.org/fhir/uv/bulkdata/STU1.0.1/).
|
11
11
|
|
12
12
|
In this set of tests, Inferno serves as a Bulk Data client that requests authorization
|
13
13
|
from the Bulk Data authorization server. It also performs a number of negative tests
|
@@ -89,7 +89,7 @@ module ONCCertificationG10TestKit
|
|
89
89
|
error response as described in [Section 5.2](https://tools.ietf.org/html/rfc6749#section-5.2).
|
90
90
|
```
|
91
91
|
DESCRIPTION
|
92
|
-
# link 'http://hl7.org/fhir/uv/bulkdata/STU1/authorization/index.html#protocol-details'
|
92
|
+
# link 'http://hl7.org/fhir/uv/bulkdata/STU1.0.1/authorization/index.html#protocol-details'
|
93
93
|
|
94
94
|
run do
|
95
95
|
post_request_content = AuthorizationRequestBuilder.build(encryption_method: bulk_encryption_method,
|
@@ -120,7 +120,7 @@ module ONCCertificationG10TestKit
|
|
120
120
|
error response as described in [Section 5.2](https://tools.ietf.org/html/rfc6749#section-5.2).
|
121
121
|
```
|
122
122
|
DESCRIPTION
|
123
|
-
# link 'http://hl7.org/fhir/uv/bulkdata/STU1/authorization/index.html#protocol-details'
|
123
|
+
# link 'http://hl7.org/fhir/uv/bulkdata/STU1.0.1/authorization/index.html#protocol-details'
|
124
124
|
|
125
125
|
run do
|
126
126
|
post_request_content = AuthorizationRequestBuilder.build(encryption_method: bulk_encryption_method,
|
@@ -160,7 +160,7 @@ module ONCCertificationG10TestKit
|
|
160
160
|
error response as described in [Section 5.2](https://tools.ietf.org/html/rfc6749#section-5.2).
|
161
161
|
```
|
162
162
|
DESCRIPTION
|
163
|
-
# link 'http://hl7.org/fhir/uv/bulkdata/STU1/authorization/index.html#protocol-details'
|
163
|
+
# link 'http://hl7.org/fhir/uv/bulkdata/STU1.0.1/authorization/index.html#protocol-details'
|
164
164
|
|
165
165
|
run do
|
166
166
|
post_request_content = AuthorizationRequestBuilder.build(encryption_method: bulk_encryption_method,
|
@@ -180,7 +180,7 @@ module ONCCertificationG10TestKit
|
|
180
180
|
description <<~DESCRIPTION
|
181
181
|
If the access token request is valid and authorized, the authorization server SHALL issue an access token in response.
|
182
182
|
DESCRIPTION
|
183
|
-
# link 'http://hl7.org/fhir/uv/bulkdata/STU1/authorization/index.html#issuing-access-tokens'
|
183
|
+
# link 'http://hl7.org/fhir/uv/bulkdata/STU1.0.1/authorization/index.html#issuing-access-tokens'
|
184
184
|
|
185
185
|
output :authentication_response
|
186
186
|
|
@@ -211,7 +211,7 @@ module ONCCertificationG10TestKit
|
|
211
211
|
| expires_in | required | The lifetime in seconds of the access token. The recommended value is 300, for a five-minute token lifetime. |
|
212
212
|
| scope | required | Scope of access authorized. Note that this can be different from the scopes requested by the app. |
|
213
213
|
DESCRIPTION
|
214
|
-
# link 'http://hl7.org/fhir/uv/bulkdata/STU1/authorization/index.html#issuing-access-tokens'
|
214
|
+
# link 'http://hl7.org/fhir/uv/bulkdata/STU1.0.1/authorization/index.html#issuing-access-tokens'
|
215
215
|
|
216
216
|
input :authentication_response
|
217
217
|
output :bearer_token
|
@@ -130,11 +130,11 @@ module ONCCertificationG10TestKit
|
|
130
130
|
description <<~DESCRIPTION
|
131
131
|
The FHIR server SHALL limit the data returned to only those FHIR resources for which the client is authorized.
|
132
132
|
|
133
|
-
[FHIR R4 Security](
|
133
|
+
[FHIR R4 Security](https://www.hl7.org/fhir/security.html#AccessDenied) and
|
134
134
|
[The OAuth 2.0 Authorization Framework: Bearer Token Usage](https://tools.ietf.org/html/rfc6750#section-3.1)
|
135
135
|
recommend using HTTP status code 401 for invalid token but also allow the actual result be controlled by policy and context.
|
136
136
|
DESCRIPTION
|
137
|
-
# link 'http://hl7.org/fhir/uv/bulkdata/STU1/export/index.html#bulk-data-kick-off-request'
|
137
|
+
# link 'http://hl7.org/fhir/uv/bulkdata/STU1.0.1/export/index.html#bulk-data-kick-off-request'
|
138
138
|
|
139
139
|
include ExportKickOffPerformer
|
140
140
|
|
@@ -154,7 +154,7 @@ module ONCCertificationG10TestKit
|
|
154
154
|
* HTTP Status Code of 202 Accepted
|
155
155
|
* Content-Location header with the absolute URL of an endpoint for subsequent status requests (polling location)
|
156
156
|
DESCRIPTION
|
157
|
-
# link 'http://hl7.org/fhir/uv/bulkdata/STU1/export/index.html#response---success'
|
157
|
+
# link 'http://hl7.org/fhir/uv/bulkdata/STU1.0.1/export/index.html#response---success'
|
158
158
|
|
159
159
|
include ExportKickOffPerformer
|
160
160
|
|
@@ -183,7 +183,7 @@ module ONCCertificationG10TestKit
|
|
183
183
|
|
184
184
|
* transactionTime, request, requiresAccessToken, output, and error
|
185
185
|
DESCRIPTION
|
186
|
-
# link 'http://hl7.org/fhir/uv/bulkdata/STU1/export/index.html#bulk-data-status-request'
|
186
|
+
# link 'http://hl7.org/fhir/uv/bulkdata/STU1.0.1/export/index.html#bulk-data-status-request'
|
187
187
|
|
188
188
|
input :polling_url
|
189
189
|
|
@@ -248,7 +248,7 @@ module ONCCertificationG10TestKit
|
|
248
248
|
|
249
249
|
* url - the path to the file. The format of the file SHOULD reflect that requested in the _outputFormat parameter of the initial kick-off request.
|
250
250
|
DESCRIPTION
|
251
|
-
# link 'http://hl7.org/fhir/uv/bulkdata/STU1/export/index.html#response---complete-status'
|
251
|
+
# link 'http://hl7.org/fhir/uv/bulkdata/STU1.0.1/export/index.html#response---complete-status'
|
252
252
|
|
253
253
|
input :status_response
|
254
254
|
|
@@ -277,7 +277,7 @@ module ONCCertificationG10TestKit
|
|
277
277
|
After a bulk data request has been started, a client MAY send a delete request to the URL provided in the Content-Location header to cancel the request.
|
278
278
|
Bulk Data Server MUST support client's delete request and return HTTP Status Code of "202 Accepted"
|
279
279
|
DESCRIPTION
|
280
|
-
# link 'http://hl7.org/fhir/uv/bulkdata/STU1/export/index.html#bulk-data-delete-request'
|
280
|
+
# link 'http://hl7.org/fhir/uv/bulkdata/STU1.0.1/export/index.html#bulk-data-delete-request'
|
281
281
|
|
282
282
|
include ExportKickOffPerformer
|
283
283
|
|
@@ -54,12 +54,12 @@ module ONCCertificationG10TestKit
|
|
54
54
|
If the requiresAccessToken field in the Complete Status body is set to true, the request SHALL include a valid#{' '}
|
55
55
|
access token.
|
56
56
|
|
57
|
-
[FHIR R4 Security](
|
57
|
+
[FHIR R4 Security](https://www.hl7.org/fhir/security.html#AccessDenied) and
|
58
58
|
[The OAuth 2.0 Authorization Framework: Bearer Token Usage](https://tools.ietf.org/html/rfc6750#section-3.1)
|
59
59
|
recommend using HTTP status code 401 for invalid token but also allow the actual result be controlled by policy#{' '}
|
60
60
|
and context.
|
61
61
|
DESCRIPTION
|
62
|
-
# link 'http://hl7.org/fhir/uv/bulkdata/STU1/export/index.html#file-request'
|
62
|
+
# link 'http://hl7.org/fhir/uv/bulkdata/STU1.0.1/export/index.html#file-request'
|
63
63
|
|
64
64
|
input :bulk_download_url
|
65
65
|
|
@@ -55,6 +55,10 @@ module ONCCertificationG10TestKit
|
|
55
55
|
@resources_from_all_files ||= {}
|
56
56
|
end
|
57
57
|
|
58
|
+
def first_error
|
59
|
+
@first_error ||= {}
|
60
|
+
end
|
61
|
+
|
58
62
|
def patient_ids_seen
|
59
63
|
scratch[:patient_ids_seen] ||= []
|
60
64
|
end
|
@@ -166,7 +170,13 @@ module ONCCertificationG10TestKit
|
|
166
170
|
scratch[:patient_ids_seen] = patient_ids_seen | [resource.id] if resource_type == 'Patient'
|
167
171
|
|
168
172
|
unless resource_is_valid?(resource: resource, profile_url: profile_url)
|
169
|
-
|
173
|
+
if first_error.key?(:line_number)
|
174
|
+
@invalid_resource_count += 1
|
175
|
+
else
|
176
|
+
@invalid_resource_count = 1
|
177
|
+
first_error[:line_number] = line_count
|
178
|
+
first_error[:messages] = messages.dup
|
179
|
+
end
|
170
180
|
end
|
171
181
|
}
|
172
182
|
|
@@ -184,6 +194,19 @@ module ONCCertificationG10TestKit
|
|
184
194
|
line_count
|
185
195
|
end
|
186
196
|
|
197
|
+
def process_validation_errors(resource_count)
|
198
|
+
return if @invalid_resource_count.nil? || @invalid_resource_count.zero?
|
199
|
+
|
200
|
+
first_error_message = "The line number for the first failed resource is #{first_error[:line_number]}."
|
201
|
+
|
202
|
+
messages.clear
|
203
|
+
messages.concat(first_error[:messages])
|
204
|
+
|
205
|
+
assert false,
|
206
|
+
"#{@invalid_resource_count} / #{resource_count} #{resource_type} resources failed profile validation. " \
|
207
|
+
"#{first_error_message}"
|
208
|
+
end
|
209
|
+
|
187
210
|
def perform_bulk_export_validation
|
188
211
|
skip_if status_output.blank?, 'Could not verify this functionality when Bulk Status Output is not provided'
|
189
212
|
skip_if (requires_access_token == 'true' && bearer_token.blank?),
|
@@ -192,19 +215,22 @@ module ONCCertificationG10TestKit
|
|
192
215
|
file_list = JSON.parse(status_output).select { |file| file['type'] == resource_type }
|
193
216
|
if file_list.empty?
|
194
217
|
message = "No #{resource_type} resource file item returned by server."
|
195
|
-
omit_if (OMIT_KLASS.include? resource_type), message
|
218
|
+
omit_if (OMIT_KLASS.include? resource_type), "#{message} #{resource_type} resources are optional."
|
196
219
|
skip message
|
197
220
|
end
|
198
221
|
|
199
222
|
@resources_from_all_files = {}
|
200
|
-
|
223
|
+
resource_count = 0
|
224
|
+
|
201
225
|
file_list.each do |file|
|
202
|
-
|
226
|
+
resource_count += check_file_request(file['url'])
|
203
227
|
end
|
204
228
|
|
229
|
+
process_validation_errors(resource_count)
|
230
|
+
|
205
231
|
validate_conformance(resources_from_all_files)
|
206
232
|
|
207
|
-
pass "Successfully validated #{
|
233
|
+
pass "Successfully validated #{resource_count} #{resource_type} resource(s)."
|
208
234
|
end
|
209
235
|
end
|
210
236
|
end
|
@@ -5,7 +5,7 @@ module ONCCertificationG10TestKit
|
|
5
5
|
EXPECTED_VALIDATOR_VERSION = '2.1.0'.freeze
|
6
6
|
|
7
7
|
def configuration_messages
|
8
|
-
validator_version_message + terminology_messages
|
8
|
+
validator_version_message + terminology_messages + version_message
|
9
9
|
end
|
10
10
|
|
11
11
|
def terminology_checker
|
@@ -101,5 +101,20 @@ module ONCCertificationG10TestKit
|
|
101
101
|
|
102
102
|
messages
|
103
103
|
end
|
104
|
+
|
105
|
+
def version_message
|
106
|
+
return [] if VERSION.match?(/\A\d+\.\d+\.\d+\z/)
|
107
|
+
|
108
|
+
[{
|
109
|
+
type: 'error',
|
110
|
+
message: <<~MESSAGE
|
111
|
+
This is a development version (`#{VERSION}`) of the ONC Certification
|
112
|
+
(g)(10) Standardized API Test Kit and is not suitable for
|
113
|
+
certification. Please [download an official
|
114
|
+
release](https://github.com/onc-healthit/onc-certification-g10-test-kit/releases)
|
115
|
+
if you did not intend to use the development version.
|
116
|
+
MESSAGE
|
117
|
+
}]
|
118
|
+
end
|
104
119
|
end
|
105
120
|
end
|
@@ -21,8 +21,8 @@ module ONCCertificationG10TestKit
|
|
21
21
|
description %(
|
22
22
|
Demonstrate the ability to export clinical data for multiple patients in
|
23
23
|
a group using [FHIR Bulk Data Access
|
24
|
-
IG](http://hl7.org/fhir/uv/bulkdata/STU1/). This test uses [Backend Services
|
25
|
-
Authorization](http://hl7.org/fhir/uv/bulkdata/STU1/authorization/index.html)
|
24
|
+
IG](http://hl7.org/fhir/uv/bulkdata/STU1.0.1/). This test uses [Backend Services
|
25
|
+
Authorization](http://hl7.org/fhir/uv/bulkdata/STU1.0.1/authorization/index.html)
|
26
26
|
to obtain an access token from the server. After authorization, a group
|
27
27
|
level bulk data export request is initialized. Finally, this test reads
|
28
28
|
exported NDJSON files from the server and validates the resources in
|
@@ -61,11 +61,15 @@ module ONCCertificationG10TestKit
|
|
61
61
|
run do
|
62
62
|
smart_app_launch_patient_id = patient_id.presence
|
63
63
|
additional_patient_ids_list =
|
64
|
-
additional_patient_ids
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
64
|
+
if additional_patient_ids.present?
|
65
|
+
additional_patient_ids
|
66
|
+
.split(',')
|
67
|
+
.map(&:strip)
|
68
|
+
.map(&:presence)
|
69
|
+
.compact
|
70
|
+
else
|
71
|
+
[]
|
72
|
+
end
|
69
73
|
|
70
74
|
all_patient_ids = ([smart_app_launch_patient_id] + additional_patient_ids_list).compact.uniq
|
71
75
|
|
@@ -47,7 +47,21 @@ module ONCCertificationG10TestKit
|
|
47
47
|
input_order :url, :ehr_client_id, :ehr_client_secret
|
48
48
|
|
49
49
|
group from: :smart_discovery do
|
50
|
-
test from: 'g10_smart_well_known_capabilities'
|
50
|
+
test from: 'g10_smart_well_known_capabilities',
|
51
|
+
config: {
|
52
|
+
options: {
|
53
|
+
required_capabilities: [
|
54
|
+
'launch-ehr',
|
55
|
+
'client-confidential-symmetric',
|
56
|
+
'sso-openid-connect',
|
57
|
+
'context-banner',
|
58
|
+
'context-style',
|
59
|
+
'context-ehr-patient',
|
60
|
+
'permission-offline',
|
61
|
+
'permission-user'
|
62
|
+
]
|
63
|
+
}
|
64
|
+
}
|
51
65
|
end
|
52
66
|
|
53
67
|
group from: :smart_ehr_launch do
|
@@ -49,7 +49,20 @@ module ONCCertificationG10TestKit
|
|
49
49
|
input_order :url, :standalone_client_id, :standalone_client_secret
|
50
50
|
|
51
51
|
group from: :smart_discovery do
|
52
|
-
test from: 'g10_smart_well_known_capabilities'
|
52
|
+
test from: 'g10_smart_well_known_capabilities',
|
53
|
+
config: {
|
54
|
+
options: {
|
55
|
+
required_capabilities: [
|
56
|
+
'launch-standalone',
|
57
|
+
'client-public',
|
58
|
+
'client-confidential-symmetric',
|
59
|
+
'sso-openid-connect',
|
60
|
+
'context-standalone-patient',
|
61
|
+
'permission-offline',
|
62
|
+
'permission-patient'
|
63
|
+
]
|
64
|
+
}
|
65
|
+
}
|
53
66
|
end
|
54
67
|
|
55
68
|
group from: :smart_standalone_launch do
|
@@ -19,17 +19,7 @@ module ONCCertificationG10TestKit
|
|
19
19
|
assert capabilities.is_a?(Array),
|
20
20
|
"Expected the well-known capabilities to be an Array, but found #{capabilities.class.name}"
|
21
21
|
|
22
|
-
|
23
|
-
'launch-standalone',
|
24
|
-
'client-public',
|
25
|
-
'client-confidential-symmetric',
|
26
|
-
'sso-openid-connect',
|
27
|
-
'context-standalone-patient',
|
28
|
-
'permission-offline',
|
29
|
-
'permission-patient'
|
30
|
-
]
|
31
|
-
|
32
|
-
missing_capabilities = required_smart_capabilities - capabilities
|
22
|
+
missing_capabilities = (config.options[:required_capabilities] || []) - capabilities
|
33
23
|
assert missing_capabilities.empty?,
|
34
24
|
"The following capabilities required for this scenario are missing: #{missing_capabilities.join(', ')}"
|
35
25
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: onc_certification_g10_test_kit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.0
|
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-05-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bloomer
|
@@ -114,14 +114,14 @@ dependencies:
|
|
114
114
|
requirements:
|
115
115
|
- - '='
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version: 0.1.
|
117
|
+
version: 0.1.3
|
118
118
|
type: :runtime
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
122
|
- - '='
|
123
123
|
- !ruby/object:Gem::Version
|
124
|
-
version: 0.1.
|
124
|
+
version: 0.1.3
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
126
|
name: tls_test_kit
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -142,14 +142,14 @@ dependencies:
|
|
142
142
|
requirements:
|
143
143
|
- - '='
|
144
144
|
- !ruby/object:Gem::Version
|
145
|
-
version: 0.2.
|
145
|
+
version: 0.2.2
|
146
146
|
type: :runtime
|
147
147
|
prerelease: false
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
150
|
- - '='
|
151
151
|
- !ruby/object:Gem::Version
|
152
|
-
version: 0.2.
|
152
|
+
version: 0.2.2
|
153
153
|
- !ruby/object:Gem::Dependency
|
154
154
|
name: database_cleaner-sequel
|
155
155
|
requirement: !ruby/object:Gem::Requirement
|