onc_certification_g10_test_kit 7.2.3 → 7.2.4
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/config/presets/g10_reference_server_preset.json +2 -2
- data/lib/onc_certification_g10_test_kit/bulk_data_group_export_validation.rb +2 -0
- data/lib/onc_certification_g10_test_kit/configuration_checker.rb +1 -1
- data/lib/onc_certification_g10_test_kit/g10_certification_suite.rb +614 -0
- data/lib/onc_certification_g10_test_kit/requirements/(g)(10)-test-procedure_requirements.xlsx +0 -0
- data/lib/onc_certification_g10_test_kit/requirements/generated/g10_certification_requirements_coverage.csv +468 -0
- data/lib/onc_certification_g10_test_kit/requirements/onc_certification_g10_test_kit_requirements.csv +468 -0
- data/lib/onc_certification_g10_test_kit/smart_fine_grained_scopes_group.rb +5 -0
- data/lib/onc_certification_g10_test_kit/smart_fine_grained_scopes_group_stu2_2.rb +5 -0
- data/lib/onc_certification_g10_test_kit/smart_fine_grained_scopes_us_core_7_group.rb +5 -0
- data/lib/onc_certification_g10_test_kit/smart_fine_grained_scopes_us_core_7_group_stu2_2.rb +5 -0
- data/lib/onc_certification_g10_test_kit/test_procedure_requirements_manager.rb +83 -0
- data/lib/onc_certification_g10_test_kit/version.rb +2 -2
- data/lib/onc_certification_g10_test_kit.rb +1 -554
- metadata +14 -10
- data/lib/onc_certification_g10_test_kit/short_id_manager.rb +0 -48
- /data/lib/onc_certification_g10_test_kit/{short_id_map.yml → g10_certification_suite_short_id_map.yml} +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e3a2a44cd79877dcc54e05adbbe2bb3e3e915a7d529f3d9fd28a288969a19a82
|
4
|
+
data.tar.gz: 4e64800d5bee93ae2d74b9f2cd414174e9bb9928b6c2a5c4c0bd33ff49e535e7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 823703ab44fce50a5242d9661663001e2420b9182c9b93629ca297790d627badb932b83cf4ed21cd45e4e890090cc3936c923e809b3d32a0551a2a59c9d295f6
|
7
|
+
data.tar.gz: 22ec29dc499c97f322d993c3ca6ed3c2aced6cd5af3c29f244f1338ab86ecbafd0bc09073d49f3ac98781b1ce4753c7eb95a8a1f0a118922ce1493280112aa06
|
@@ -449,7 +449,7 @@
|
|
449
449
|
},
|
450
450
|
{
|
451
451
|
"name": "additional_patient_ids",
|
452
|
-
"value": "85,355",
|
452
|
+
"value": "85,355,907",
|
453
453
|
"_title": "Additional Patient IDs",
|
454
454
|
"_description": "Comma separated list of Patient IDs that together with the Patient\nID from the SMART App Launch contain all MUST SUPPORT elements.\n",
|
455
455
|
"_type": "text",
|
@@ -479,7 +479,7 @@
|
|
479
479
|
},
|
480
480
|
{
|
481
481
|
"name": "bulk_patient_ids_in_group",
|
482
|
-
"value": "85,355",
|
482
|
+
"value": "85,355,907",
|
483
483
|
"_title": "Patient IDs in exported Group",
|
484
484
|
"_description": "Comma separated list of every Patient ID that is in the specified Group. This information is provided by\nthe system under test to verify that data returned matches expectations. Leave blank to not verify Group\ninclusion.\n",
|
485
485
|
"_type": "text",
|
@@ -393,6 +393,7 @@ module ONCCertificationG10TestKit
|
|
393
393
|
* http://hl7.org/fhir/us/core/StructureDefinition/us-core-respiratory-rate
|
394
394
|
|
395
395
|
For US Core v6.1.0, this test expects evidence of the following US Core profiles
|
396
|
+
* http://hl7.org/fhir/us/core/StructureDefinition/us-core-observation-clinical-result
|
396
397
|
* http://hl7.org/fhir/us/core/StructureDefinition/us-core-observation-lab
|
397
398
|
* http://hl7.org/fhir/us/core/StructureDefinition/us-core-observation-occupation
|
398
399
|
* http://hl7.org/fhir/us/core/StructureDefinition/us-core-observation-pregnancyintent
|
@@ -413,6 +414,7 @@ module ONCCertificationG10TestKit
|
|
413
414
|
* http://hl7.org/fhir/us/core/StructureDefinition/us-core-respiratory-rate
|
414
415
|
|
415
416
|
For US Core v7.0.0, this test expects evidence of the following US Core profiles
|
417
|
+
* http://hl7.org/fhir/us/core/StructureDefinition/us-core-observation-clinical-result
|
416
418
|
* http://hl7.org/fhir/us/core/StructureDefinition/us-core-observation-lab
|
417
419
|
* http://hl7.org/fhir/us/core/StructureDefinition/us-core-observation-occupation
|
418
420
|
* http://hl7.org/fhir/us/core/StructureDefinition/us-core-observation-pregnancyintent
|
@@ -2,7 +2,7 @@ require_relative '../inferno/terminology/tasks/check_built_terminology'
|
|
2
2
|
|
3
3
|
module ONCCertificationG10TestKit
|
4
4
|
class ConfigurationChecker
|
5
|
-
EXPECTED_HL7_VALIDATOR_VERSION = '1.0.
|
5
|
+
EXPECTED_HL7_VALIDATOR_VERSION = '1.0.66'.freeze
|
6
6
|
HL7_VALIDATOR_VERSION_KEY = 'validatorWrapperVersion'.freeze
|
7
7
|
|
8
8
|
def configuration_messages
|
@@ -0,0 +1,614 @@
|
|
1
|
+
require_relative 'metadata'
|
2
|
+
require_relative 'configuration_checker'
|
3
|
+
require_relative 'urls'
|
4
|
+
|
5
|
+
require_relative 'feature'
|
6
|
+
require_relative 'g10_options'
|
7
|
+
require_relative 'multi_patient_api_stu1'
|
8
|
+
require_relative 'multi_patient_api_stu2'
|
9
|
+
require_relative 'single_patient_api_group'
|
10
|
+
require_relative 'single_patient_us_core_4_api_group'
|
11
|
+
require_relative 'single_patient_us_core_5_api_group'
|
12
|
+
require_relative 'single_patient_us_core_6_api_group'
|
13
|
+
require_relative 'single_patient_us_core_7_api_group'
|
14
|
+
require_relative 'smart_app_launch_invalid_aud_group'
|
15
|
+
require_relative 'smart_asymmetric_launch_group'
|
16
|
+
require_relative 'smart_granular_scope_selection_group'
|
17
|
+
require_relative 'smart_invalid_token_group'
|
18
|
+
require_relative 'smart_invalid_token_group_stu2'
|
19
|
+
require_relative 'smart_invalid_pkce_group'
|
20
|
+
require_relative 'smart_limited_app_group'
|
21
|
+
require_relative 'smart_standalone_patient_app_group'
|
22
|
+
require_relative 'smart_public_standalone_launch_group'
|
23
|
+
require_relative 'smart_public_standalone_launch_group_stu2'
|
24
|
+
require_relative 'smart_public_standalone_launch_group_stu2_2'
|
25
|
+
require_relative 'smart_ehr_patient_launch_group'
|
26
|
+
require_relative 'smart_ehr_patient_launch_group_stu2'
|
27
|
+
require_relative 'smart_ehr_patient_launch_group_stu2_2'
|
28
|
+
require_relative 'smart_ehr_practitioner_app_group'
|
29
|
+
require_relative 'smart_fine_grained_scopes_group'
|
30
|
+
require_relative 'smart_fine_grained_scopes_group_stu2_2'
|
31
|
+
require_relative 'smart_fine_grained_scopes_us_core_7_group'
|
32
|
+
require_relative 'smart_fine_grained_scopes_us_core_7_group_stu2_2'
|
33
|
+
require_relative 'smart_v1_scopes_group'
|
34
|
+
require_relative 'terminology_binding_validator'
|
35
|
+
require_relative 'token_introspection_group'
|
36
|
+
require_relative 'token_introspection_group_stu2_2'
|
37
|
+
require_relative 'token_revocation_group'
|
38
|
+
require_relative 'visual_inspection_and_attestations_group'
|
39
|
+
|
40
|
+
require_relative '../inferno/terminology'
|
41
|
+
|
42
|
+
require_relative 'test_procedure_requirements_manager'
|
43
|
+
|
44
|
+
Inferno::Terminology::Loader.load_validators
|
45
|
+
|
46
|
+
module ONCCertificationG10TestKit
|
47
|
+
class G10CertificationSuite < Inferno::TestSuite
|
48
|
+
title 'ONC Certification (g)(10) Standardized API'
|
49
|
+
short_title '(g)(10) Standardized API'
|
50
|
+
id :g10_certification
|
51
|
+
links [
|
52
|
+
{
|
53
|
+
label: 'Report Issue',
|
54
|
+
url: 'https://github.com/onc-healthit/onc-certification-g10-test-kit/issues/'
|
55
|
+
},
|
56
|
+
{
|
57
|
+
label: 'Open Source',
|
58
|
+
url: 'https://github.com/onc-healthit/onc-certification-g10-test-kit/'
|
59
|
+
},
|
60
|
+
{
|
61
|
+
label: 'Download',
|
62
|
+
url: 'https://github.com/onc-healthit/onc-certification-g10-test-kit/releases'
|
63
|
+
}
|
64
|
+
]
|
65
|
+
|
66
|
+
requirement_sets(
|
67
|
+
{
|
68
|
+
identifier: '170.315(g)(10)-test-procedure',
|
69
|
+
title: '170.315(g)(10) Standardized API for patient and population services test procedure',
|
70
|
+
actor: 'Server',
|
71
|
+
requirements: 'APP-REG-1,APP-REG-2,SEC-CNN-1,AUT-PAT-1,AUT-PAT-2,AUT-PAT-3,AUT-PAT-4,AUT-PAT-10,AUT-PAT-33,' \
|
72
|
+
'AUT-PAT-11,AUT-PAT-12,AUT-PAT-37,AUT-PAT-14,AUT-PAT-35,AUT-PAT-17,AUT-PAT-18,AUT-PAT-36,' \
|
73
|
+
'AUT-PAT-20,AUT-PAT-21,AUT-PAT-22,AUT-PAT-23,PAR-1,AUT-SYS-1,AUT-SYS-2,AUT-SYS-3,' \
|
74
|
+
'AUT-SYS-4,AUT-SYS-5,AUT-SYS-6,AUT-SYS-7,AUT-SYS-8,AUT-SYS-9,AUT-SYS-10,TOK-INTRO-1,' \
|
75
|
+
'SH-PAT-1,SH-PAT-2,SH-PAT-3,SH-PAT-4,SH-PAT-5,DAT-PAT-1,DAT-PAT-18,DAT-PAT-2,DAT-PAT-3,' \
|
76
|
+
'DAT-PAT-4,DAT-PAT-5,DAT-PAT-6,DAT-PAT-7,DAT-PAT-8,DAT-PAT-17,DAT-PAT-9,DAT-PAT-10,DAT-PAT-11,' \
|
77
|
+
'DAT-PAT-12,DAT-PAT-13,DAT-PAT-14,DAT-PAT-15,API-DOC-1,API-DOC-2,API-DOC-3'
|
78
|
+
},
|
79
|
+
{
|
80
|
+
identifier: '170.315(g)(10)-test-procedure',
|
81
|
+
title: '170.315(g)(10) Standardized API for patient and population services test procedure',
|
82
|
+
actor: 'Server',
|
83
|
+
suite_options: {
|
84
|
+
smart_app_launch_version: G10Options::SMART_1
|
85
|
+
},
|
86
|
+
requirements: 'AUT-PAT-5,AUT-PAT-6,AUT-PAT-7,AUT-PAT-8,AUT-PAT-9,AUT-PAT-13,AUT-PAT-15,AUT-PAT-16,AUT-PAT-19'
|
87
|
+
},
|
88
|
+
{
|
89
|
+
identifier: '170.315(g)(10)-test-procedure',
|
90
|
+
title: '170.315(g)(10) Standardized API for patient and population services test procedure',
|
91
|
+
actor: 'Server',
|
92
|
+
suite_options: {
|
93
|
+
smart_app_launch_version: G10Options::SMART_2
|
94
|
+
},
|
95
|
+
requirements: 'AUT-PAT-24,AUT-PAT-25,AUT-PAT-26,AUT-PAT-27,AUT-PAT-28,AUT-PAT-29,AUT-PAT-30,AUT-PAT-31'
|
96
|
+
},
|
97
|
+
{
|
98
|
+
identifier: '170.315(g)(10)-test-procedure',
|
99
|
+
title: '170.315(g)(10) Standardized API for patient and population services test procedure',
|
100
|
+
actor: 'Server',
|
101
|
+
suite_options: {
|
102
|
+
smart_app_launch_version: G10Options::SMART_2_2
|
103
|
+
},
|
104
|
+
requirements: 'AUT-PAT-24,AUT-PAT-25,AUT-PAT-26,AUT-PAT-27,AUT-PAT-28,AUT-PAT-29,AUT-PAT-30,AUT-PAT-31'
|
105
|
+
},
|
106
|
+
{
|
107
|
+
identifier: '170.315(g)(10)-test-procedure',
|
108
|
+
title: '170.315(g)(10) Standardized API for patient and population services test procedure',
|
109
|
+
actor: 'Server',
|
110
|
+
suite_options: {
|
111
|
+
us_core_version: G10Options::US_CORE_6
|
112
|
+
},
|
113
|
+
requirements: 'AUT-PAT-32,AUT-PAT-34'
|
114
|
+
},
|
115
|
+
{
|
116
|
+
identifier: '170.315(g)(10)-test-procedure',
|
117
|
+
title: '170.315(g)(10) Standardized API for patient and population services test procedure',
|
118
|
+
actor: 'Server',
|
119
|
+
suite_options: {
|
120
|
+
us_core_version: G10Options::US_CORE_7
|
121
|
+
},
|
122
|
+
requirements: 'AUT-PAT-32,AUT-PAT-34'
|
123
|
+
}
|
124
|
+
)
|
125
|
+
|
126
|
+
check_configuration do
|
127
|
+
ConfigurationChecker.new.configuration_messages
|
128
|
+
end
|
129
|
+
|
130
|
+
WARNING_INCLUSION_FILTERS = [
|
131
|
+
/Unknown CodeSystem/,
|
132
|
+
/Unknown ValueSet/
|
133
|
+
].freeze
|
134
|
+
|
135
|
+
ERROR_FILTERS = [
|
136
|
+
/\A\S+: \S+: Unknown [Cc]ode/,
|
137
|
+
/\A\S+: \S+: None of the codings provided are in the value set/,
|
138
|
+
/\A\S+: \S+: The code provided \(\S*\) is not in the value set/,
|
139
|
+
/\A\S+: \S+: The Coding provided \(\S*\) is not in the value set/,
|
140
|
+
/\A\S+: \S+: The Coding provided \(\S*\) was not found in the value set/,
|
141
|
+
/\A\S+: \S+: A definition for CodeSystem '.*' could not be found, so the code cannot be validated/,
|
142
|
+
/\A\S+: \S+: URL value '.*' does not resolve/,
|
143
|
+
/\A\S+: \S+: .*\[No server available\]/, # Catch-all for certain errors when TX server is disabled
|
144
|
+
%r{\A\S+: \S+: .*\[Error from http://tx.fhir.org/r4:} # Catch-all for TX server errors that slip through
|
145
|
+
].freeze
|
146
|
+
|
147
|
+
def self.setup_validator(us_core_version_requirement) # rubocop:disable Metrics/CyclomaticComplexity
|
148
|
+
fhir_resource_validator :default, required_suite_options: us_core_version_requirement do
|
149
|
+
cli_context do
|
150
|
+
txServer nil
|
151
|
+
displayWarnings true
|
152
|
+
disableDefaultResourceFetcher true
|
153
|
+
end
|
154
|
+
|
155
|
+
us_core_version_num = G10Options::US_CORE_VERSION_NUMBERS[us_core_version_requirement[:us_core_version]]
|
156
|
+
|
157
|
+
igs("hl7.fhir.us.core##{us_core_version_num}")
|
158
|
+
|
159
|
+
us_core_message_filters =
|
160
|
+
case us_core_version_requirement[:us_core_version]
|
161
|
+
when G10Options::US_CORE_3
|
162
|
+
USCoreTestKit::USCoreV311::USCoreTestSuite::VALIDATION_MESSAGE_FILTERS
|
163
|
+
when G10Options::US_CORE_4
|
164
|
+
USCoreTestKit::USCoreV400::USCoreTestSuite::VALIDATION_MESSAGE_FILTERS
|
165
|
+
when G10Options::US_CORE_5
|
166
|
+
USCoreTestKit::USCoreV501::USCoreTestSuite::VALIDATION_MESSAGE_FILTERS
|
167
|
+
when G10Options::US_CORE_6
|
168
|
+
USCoreTestKit::USCoreV610::USCoreTestSuite::VALIDATION_MESSAGE_FILTERS
|
169
|
+
when G10Options::US_CORE_7
|
170
|
+
USCoreTestKit::USCoreV700::USCoreTestSuite::VALIDATION_MESSAGE_FILTERS
|
171
|
+
end
|
172
|
+
|
173
|
+
exclude_message do |message|
|
174
|
+
if message.type == 'info' ||
|
175
|
+
(message.type == 'warning' && WARNING_INCLUSION_FILTERS.none? do |filter|
|
176
|
+
filter.match? message.message
|
177
|
+
end) ||
|
178
|
+
us_core_message_filters.any? { |filter| filter.match? message.message } ||
|
179
|
+
(message.type == 'error' && ERROR_FILTERS.any? { |filter| message.message.match? filter })
|
180
|
+
true
|
181
|
+
else
|
182
|
+
false
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
perform_additional_validation do |resource, profile_url|
|
187
|
+
versionless_profile_url, profile_version = profile_url.split('|')
|
188
|
+
profile_version = case profile_version
|
189
|
+
when '6.1.0'
|
190
|
+
'610'
|
191
|
+
when '4.0.0'
|
192
|
+
'400'
|
193
|
+
when '5.0.1'
|
194
|
+
'501'
|
195
|
+
else
|
196
|
+
# This open-ended else is primarily for Vital Signs profiles in v3.1.1, which are tagged
|
197
|
+
# with the base FHIR version (4.0.1). The profiles were migrated to US Core in later
|
198
|
+
# versions.
|
199
|
+
'311'
|
200
|
+
end
|
201
|
+
|
202
|
+
us_core_suite = USCoreTestKit.const_get("USCoreV#{profile_version}")::USCoreTestSuite
|
203
|
+
metadata = us_core_suite.metadata.find do |metadata_candidate|
|
204
|
+
metadata_candidate.profile_url == versionless_profile_url
|
205
|
+
end
|
206
|
+
next if metadata.nil?
|
207
|
+
|
208
|
+
validation_messages = if resource.instance_of?(FHIR::Provenance)
|
209
|
+
USCoreTestKit::ProvenanceValidator.validate(resource)
|
210
|
+
else
|
211
|
+
[]
|
212
|
+
end
|
213
|
+
|
214
|
+
terminology_validation_messages = metadata.bindings
|
215
|
+
.select { |binding_definition| binding_definition[:strength] == 'required' }
|
216
|
+
.flat_map do |binding_definition|
|
217
|
+
TerminologyBindingValidator.validate(resource, binding_definition)
|
218
|
+
rescue Inferno::UnknownValueSetException, Inferno::UnknownCodeSystemException => e
|
219
|
+
{ type: 'warning', message: e.message }
|
220
|
+
end.compact
|
221
|
+
|
222
|
+
validation_messages.concat(terminology_validation_messages)
|
223
|
+
validation_messages
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
[
|
229
|
+
G10Options::US_CORE_3_REQUIREMENT,
|
230
|
+
G10Options::US_CORE_4_REQUIREMENT,
|
231
|
+
G10Options::US_CORE_5_REQUIREMENT,
|
232
|
+
G10Options::US_CORE_6_REQUIREMENT,
|
233
|
+
G10Options::US_CORE_7_REQUIREMENT
|
234
|
+
|
235
|
+
].each do |us_core_version_requirement|
|
236
|
+
setup_validator(us_core_version_requirement)
|
237
|
+
end
|
238
|
+
|
239
|
+
def self.jwks_json
|
240
|
+
bulk_data_jwks =
|
241
|
+
JSON.parse(
|
242
|
+
File.read(ENV.fetch('G10_BULK_DATA_JWKS', File.join(__dir__, 'bulk_data_jwks.json')))
|
243
|
+
)
|
244
|
+
@jwks_json ||= JSON.pretty_generate(
|
245
|
+
{ keys: bulk_data_jwks['keys'].select { |key| key['key_ops']&.include?('verify') } }
|
246
|
+
)
|
247
|
+
end
|
248
|
+
|
249
|
+
def self.well_known_route_handler
|
250
|
+
->(_env) { [200, { 'Content-Type' => 'application/json' }, [jwks_json]] }
|
251
|
+
end
|
252
|
+
|
253
|
+
route(
|
254
|
+
:get,
|
255
|
+
'/.well-known/jwks.json',
|
256
|
+
well_known_route_handler
|
257
|
+
)
|
258
|
+
|
259
|
+
suite_option :us_core_version,
|
260
|
+
title: 'US Core Version',
|
261
|
+
list_options: [
|
262
|
+
{
|
263
|
+
label: 'US Core 3.1.1 / USCDI v1',
|
264
|
+
value: G10Options::US_CORE_3
|
265
|
+
},
|
266
|
+
{
|
267
|
+
label: 'US Core 4.0.0 / USCDI v1',
|
268
|
+
value: G10Options::US_CORE_4
|
269
|
+
},
|
270
|
+
{
|
271
|
+
label: 'US Core 6.1.0 / USCDI v3',
|
272
|
+
value: G10Options::US_CORE_6
|
273
|
+
},
|
274
|
+
{
|
275
|
+
label: 'US Core 7.0.0 / USCDI v4',
|
276
|
+
value: G10Options::US_CORE_7
|
277
|
+
}
|
278
|
+
]
|
279
|
+
|
280
|
+
suite_option :smart_app_launch_version,
|
281
|
+
title: 'SMART App Launch Version',
|
282
|
+
list_options: [
|
283
|
+
{
|
284
|
+
label: 'SMART App Launch 1.0.0',
|
285
|
+
value: G10Options::SMART_1
|
286
|
+
},
|
287
|
+
{
|
288
|
+
label: 'SMART App Launch 2.0.0',
|
289
|
+
value: G10Options::SMART_2
|
290
|
+
},
|
291
|
+
{
|
292
|
+
label: 'SMART App Launch 2.2.0',
|
293
|
+
value: G10Options::SMART_2_2
|
294
|
+
}
|
295
|
+
]
|
296
|
+
|
297
|
+
suite_option :multi_patient_version,
|
298
|
+
title: 'Bulk Data Version',
|
299
|
+
list_options: [
|
300
|
+
{
|
301
|
+
label: 'Bulk Data 1.0.1',
|
302
|
+
value: G10Options::BULK_DATA_1
|
303
|
+
},
|
304
|
+
{
|
305
|
+
label: 'Bulk Data 2.0.0',
|
306
|
+
value: G10Options::BULK_DATA_2
|
307
|
+
}
|
308
|
+
]
|
309
|
+
|
310
|
+
config(
|
311
|
+
options: {
|
312
|
+
post_authorization_uri: "#{Inferno::Application['base_url']}/custom/smart_stu2/post_auth",
|
313
|
+
incorrectly_permitted_tls_version_message_type: 'warning'
|
314
|
+
}
|
315
|
+
)
|
316
|
+
|
317
|
+
description %(
|
318
|
+
The ONC Certification (g)(10) Standardized API Test Suite is a testing
|
319
|
+
tool for Health Level 7 (HL7®) Fast Healthcare Interoperability Resources
|
320
|
+
(FHIR®) services seeking to meet the requirements of the Standardized API
|
321
|
+
for Patient and Population Services criterion § 170.315(g)(10) in the ONC
|
322
|
+
Certification Program.
|
323
|
+
|
324
|
+
This test suite is organized into testing scenarios that in sum cover all
|
325
|
+
requirements within the § 170.315(g)(10) certification criterion. The
|
326
|
+
scenarios are intended to be run in order during certification, but can
|
327
|
+
be run out of order to support testing during development or certification
|
328
|
+
preparation. Some scenarios depend on data collected during previous
|
329
|
+
scenarios to function. In these cases, the scenario description describes
|
330
|
+
these dependencies.
|
331
|
+
|
332
|
+
The best way to learn about how to use these tests is the
|
333
|
+
[(g)(10) Standardized API Test Kit walkthrough](https://github.com/onc-healthit/onc-certification-g10-test-kit/wiki/Walkthrough),
|
334
|
+
which demonstrates the tests running against a simulated system.
|
335
|
+
|
336
|
+
The first three scenarios require the system under test to demonstrate
|
337
|
+
basic SMART App Launch functionality. The fourth uses a valid token
|
338
|
+
provided during earlier tests to verify support for the Single Patient API
|
339
|
+
as described in the criterion. The fifth verifies support for the Multi
|
340
|
+
Patient API, including Backend Services for authorization. Not all
|
341
|
+
authorization-related requirements are verified in the first three
|
342
|
+
scenarios, and the 'Additional Authorization Tests' verify these
|
343
|
+
additional requirements. The last scenario contains a list of
|
344
|
+
'attestations' and 'visual inspections' for requirements that could not
|
345
|
+
be verified through automated testing.
|
346
|
+
|
347
|
+
To get started with the first group of scenarios, please first register the
|
348
|
+
Inferno client as a SMART App with the following information:
|
349
|
+
|
350
|
+
* SMART Launch URI: `#{LAUNCH_URI}`
|
351
|
+
* OAuth Redirect URI: `#{REDIRECT_URI}`
|
352
|
+
|
353
|
+
For the multi-patient API, register Inferno with the following JWK Set
|
354
|
+
Url:
|
355
|
+
|
356
|
+
* `#{Inferno::Application[:base_url]}/custom/g10_certification/.well-known/jwks.json`
|
357
|
+
|
358
|
+
Systems must pass all tests to qualify for ONC certification.
|
359
|
+
)
|
360
|
+
|
361
|
+
suite_summary %(
|
362
|
+
The ONC Certification (g)(10) Standardized API Test Kit is a testing tool
|
363
|
+
for Health Level 7 (HL7®) Fast Healthcare Interoperability Resources
|
364
|
+
(FHIR®) services seeking to meet the requirements of the Standardized API
|
365
|
+
for Patient and Population Services criterion § 170.315(g)(10) in the ONC Certification Program.
|
366
|
+
|
367
|
+
Systems may adopt later versions of standards than those named in the rule
|
368
|
+
as approved by the ONC Standards Version Advancement Process (SVAP).
|
369
|
+
When using US Core v7, the tester must select SMART v2 or above
|
370
|
+
because SMART App Launch granular scopes are required by US Core v7
|
371
|
+
and are not available in SMART v1. Please select which approved version
|
372
|
+
of each standard to use, and click ‘Start Testing’ to begin testing.
|
373
|
+
)
|
374
|
+
|
375
|
+
input_instructions %(
|
376
|
+
Register Inferno as a SMART app using the following information:
|
377
|
+
|
378
|
+
* Launch URI: `#{LAUNCH_URI}`
|
379
|
+
* Redirect URI: `#{REDIRECT_URI}`
|
380
|
+
|
381
|
+
For the multi-patient API, register Inferno with the following JWK Set
|
382
|
+
Url:
|
383
|
+
|
384
|
+
* `#{Inferno::Application[:base_url]}/custom/g10_certification/.well-known/jwks.json`
|
385
|
+
)
|
386
|
+
|
387
|
+
group from: 'g10_smart_standalone_patient_app'
|
388
|
+
|
389
|
+
group from: 'g10_smart_limited_app' do
|
390
|
+
# This has to be configured here, otherwise the `smart_auth_info` config
|
391
|
+
# will get clobbered and will use `standalone_smart_auth_info` instead of
|
392
|
+
# `limited_smart_auth_info`
|
393
|
+
groups
|
394
|
+
.select { |group| group.id.include? 'smart_standalone_launch' }
|
395
|
+
.flat_map(&:tests)
|
396
|
+
.select { |test| test.id.include? 'g10_patient_context' }
|
397
|
+
.each do |test|
|
398
|
+
test
|
399
|
+
.config(
|
400
|
+
inputs: {
|
401
|
+
patient_id: { name: :limited_patient_id },
|
402
|
+
smart_auth_info: { name: :limited_smart_auth_info }
|
403
|
+
}
|
404
|
+
)
|
405
|
+
end
|
406
|
+
end
|
407
|
+
|
408
|
+
group from: 'g10_smart_ehr_practitioner_app'
|
409
|
+
|
410
|
+
group from: 'g10_single_patient_api',
|
411
|
+
required_suite_options: G10Options::US_CORE_3_REQUIREMENT
|
412
|
+
group from: 'g10_single_patient_us_core_4_api',
|
413
|
+
required_suite_options: G10Options::US_CORE_4_REQUIREMENT
|
414
|
+
group from: 'g10_single_patient_us_core_5_api',
|
415
|
+
required_suite_options: G10Options::US_CORE_5_REQUIREMENT
|
416
|
+
group from: 'g10_single_patient_us_core_6_api',
|
417
|
+
required_suite_options: G10Options::US_CORE_6_REQUIREMENT
|
418
|
+
group from: 'g10_single_patient_us_core_7_api',
|
419
|
+
required_suite_options: G10Options::US_CORE_7_REQUIREMENT
|
420
|
+
|
421
|
+
group from: 'multi_patient_api',
|
422
|
+
required_suite_options: G10Options::BULK_DATA_1_REQUIREMENT
|
423
|
+
group from: 'multi_patient_api_stu2',
|
424
|
+
required_suite_options: G10Options::BULK_DATA_2_REQUIREMENT
|
425
|
+
|
426
|
+
group do
|
427
|
+
title 'Additional Authorization Tests'
|
428
|
+
id 'Group06'
|
429
|
+
description %(
|
430
|
+
The (g)(10) Standardized Test Suite attempts to minimize effort required
|
431
|
+
by testers by creating scenarios that validate as many requirements as
|
432
|
+
possible with just a handful of SMART App Launches. However, not all
|
433
|
+
SMART App Launch and (g)(10) Standardized API criterion requirements
|
434
|
+
that need to be verified fit within the first few test scenarios in this
|
435
|
+
suite.
|
436
|
+
|
437
|
+
The scenarios contained in this section verify remaining testing
|
438
|
+
requirements for the (g)(10) Standardized API criterion relevant to
|
439
|
+
the SMART App Launch implementation specification. Each of these scenarios
|
440
|
+
need to be run independently. Please read the instructions for each in
|
441
|
+
the 'About' section, as they may require special setup on the part of
|
442
|
+
the tester.
|
443
|
+
)
|
444
|
+
|
445
|
+
default_redirect_message_proc = lambda do |auth_url|
|
446
|
+
%(
|
447
|
+
### #{self.class.parent.title}
|
448
|
+
|
449
|
+
[Follow this link to authorize with the SMART server](#{auth_url}).
|
450
|
+
|
451
|
+
Tests will resume once Inferno receives a request at
|
452
|
+
`#{REDIRECT_URI}` with a state of `#{state}`.
|
453
|
+
)
|
454
|
+
end
|
455
|
+
|
456
|
+
group from: :g10_public_standalone_launch,
|
457
|
+
required_suite_options: G10Options::SMART_1_REQUIREMENT,
|
458
|
+
config: { options: { redirect_message_proc: default_redirect_message_proc } }
|
459
|
+
group from: :g10_public_standalone_launch_stu2,
|
460
|
+
required_suite_options: G10Options::SMART_2_REQUIREMENT,
|
461
|
+
config: { options: { redirect_message_proc: default_redirect_message_proc } }
|
462
|
+
group from: :g10_public_standalone_launch_stu2_2, # rubocop:disable Naming/VariableNumber
|
463
|
+
required_suite_options: G10Options::SMART_2_2_REQUIREMENT,
|
464
|
+
config: { options: { redirect_message_proc: default_redirect_message_proc } }
|
465
|
+
|
466
|
+
group from: :g10_token_revocation
|
467
|
+
|
468
|
+
group from: :g10_smart_invalid_aud,
|
469
|
+
config: { options: { redirect_message_proc: default_redirect_message_proc } }
|
470
|
+
|
471
|
+
group from: :g10_smart_invalid_token_request,
|
472
|
+
required_suite_options: G10Options::SMART_1_REQUIREMENT,
|
473
|
+
config: { options: { redirect_message_proc: default_redirect_message_proc } }
|
474
|
+
group from: :g10_smart_invalid_token_request_stu2,
|
475
|
+
required_suite_options: G10Options::SMART_2_REQUIREMENT,
|
476
|
+
config: { options: { redirect_message_proc: default_redirect_message_proc } }
|
477
|
+
group from: :g10_smart_invalid_token_request_stu2,
|
478
|
+
id: :g10_smart_invalid_token_request_stu2_2, # rubocop:disable Naming/VariableNumber
|
479
|
+
required_suite_options: G10Options::SMART_2_2_REQUIREMENT,
|
480
|
+
config: { options: { redirect_message_proc: default_redirect_message_proc } }
|
481
|
+
|
482
|
+
group from: :g10_smart_invalid_pkce_code_verifier_group,
|
483
|
+
required_suite_options: G10Options::SMART_2_REQUIREMENT
|
484
|
+
group from: :g10_smart_invalid_pkce_code_verifier_group,
|
485
|
+
id: :g10_smart_invalid_pkce_code_verifier_group_stu2_2, # rubocop:disable Naming/VariableNumber
|
486
|
+
required_suite_options: G10Options::SMART_2_2_REQUIREMENT
|
487
|
+
|
488
|
+
group from: :g10_ehr_patient_launch,
|
489
|
+
required_suite_options: G10Options::SMART_1_REQUIREMENT
|
490
|
+
group from: :g10_ehr_patient_launch_stu2,
|
491
|
+
required_suite_options: G10Options::SMART_2_REQUIREMENT
|
492
|
+
group from: :g10_ehr_patient_launch_stu2_2, # rubocop:disable Naming/VariableNumber
|
493
|
+
required_suite_options: G10Options::SMART_2_2_REQUIREMENT
|
494
|
+
|
495
|
+
group from: :g10_token_introspection,
|
496
|
+
required_suite_options: G10Options::SMART_2_REQUIREMENT
|
497
|
+
group from: :g10_token_introspection_stu2_2, # rubocop:disable Naming/VariableNumber
|
498
|
+
required_suite_options: G10Options::SMART_2_2_REQUIREMENT
|
499
|
+
|
500
|
+
group from: :g10_asymmetric_launch,
|
501
|
+
required_suite_options: G10Options::SMART_2_REQUIREMENT
|
502
|
+
group from: :g10_asymmetric_launch,
|
503
|
+
id: :g10_asymmetric_launch_stu2_2, # rubocop:disable Naming/VariableNumber
|
504
|
+
required_suite_options: G10Options::SMART_2_2_REQUIREMENT
|
505
|
+
|
506
|
+
group from: :g10_smart_v1_scopes,
|
507
|
+
required_suite_options: G10Options::SMART_2_REQUIREMENT
|
508
|
+
group from: :g10_smart_v1_scopes,
|
509
|
+
id: :g10_smart_v1_scopes_stu2_2, # rubocop:disable Naming/VariableNumber
|
510
|
+
required_suite_options: G10Options::SMART_2_2_REQUIREMENT
|
511
|
+
|
512
|
+
group from: :g10_smart_fine_grained_scopes, exclude_optional: true do
|
513
|
+
required_suite_options G10Options::SMART_2_REQUIREMENT.merge(G10Options::US_CORE_6_REQUIREMENT)
|
514
|
+
groups.first.config(
|
515
|
+
inputs: {
|
516
|
+
smart_auth_info: { name: :granular_scopes_1_auth_info }
|
517
|
+
},
|
518
|
+
outputs: {
|
519
|
+
smart_auth_info: { name: :granular_scopes_1_auth_info }
|
520
|
+
}
|
521
|
+
)
|
522
|
+
|
523
|
+
groups.last.config(
|
524
|
+
inputs: {
|
525
|
+
smart_auth_info: { name: :granular_scopes_2_auth_info }
|
526
|
+
},
|
527
|
+
outputs: {
|
528
|
+
smart_auth_info: { name: :granular_scopes_2_auth_info }
|
529
|
+
}
|
530
|
+
)
|
531
|
+
end
|
532
|
+
|
533
|
+
group from: :g10_smart_fine_grained_scopes_stu2_2, exclude_optional: true do # rubocop:disable Naming/VariableNumber
|
534
|
+
required_suite_options G10Options::SMART_2_2_REQUIREMENT.merge(G10Options::US_CORE_6_REQUIREMENT)
|
535
|
+
groups.first.config(
|
536
|
+
inputs: {
|
537
|
+
smart_auth_info: { name: :granular_scopes_1_auth_info }
|
538
|
+
},
|
539
|
+
outputs: {
|
540
|
+
smart_auth_info: { name: :granular_scopes_1_auth_info }
|
541
|
+
}
|
542
|
+
)
|
543
|
+
|
544
|
+
groups.last.config(
|
545
|
+
inputs: {
|
546
|
+
smart_auth_info: { name: :granular_scopes_2_auth_info }
|
547
|
+
},
|
548
|
+
outputs: {
|
549
|
+
smart_auth_info: { name: :granular_scopes_2_auth_info }
|
550
|
+
}
|
551
|
+
)
|
552
|
+
end
|
553
|
+
|
554
|
+
group from: :g10_us_core_7_smart_fine_grained_scopes, exclude_optional: true do
|
555
|
+
required_suite_options G10Options::SMART_2_REQUIREMENT.merge(G10Options::US_CORE_7_REQUIREMENT)
|
556
|
+
groups.first.config(
|
557
|
+
inputs: {
|
558
|
+
smart_auth_info: { name: :granular_scopes_1_auth_info }
|
559
|
+
},
|
560
|
+
outputs: {
|
561
|
+
smart_auth_info: { name: :granular_scopes_1_auth_info }
|
562
|
+
}
|
563
|
+
)
|
564
|
+
|
565
|
+
groups.last.config(
|
566
|
+
inputs: {
|
567
|
+
smart_auth_info: { name: :granular_scopes_2_auth_info }
|
568
|
+
},
|
569
|
+
outputs: {
|
570
|
+
smart_auth_info: { name: :granular_scopes_2_auth_info }
|
571
|
+
}
|
572
|
+
)
|
573
|
+
end
|
574
|
+
|
575
|
+
group from: :g10_us_core_7_smart_fine_grained_scopes_stu2_2, exclude_optional: true do # rubocop:disable Naming/VariableNumber
|
576
|
+
required_suite_options G10Options::SMART_2_2_REQUIREMENT.merge(G10Options::US_CORE_7_REQUIREMENT)
|
577
|
+
groups.first.config(
|
578
|
+
inputs: {
|
579
|
+
smart_auth_info: { name: :granular_scopes_1_auth_info }
|
580
|
+
},
|
581
|
+
outputs: {
|
582
|
+
smart_auth_info: { name: :granular_scopes_1_auth_info }
|
583
|
+
}
|
584
|
+
)
|
585
|
+
|
586
|
+
groups.last.config(
|
587
|
+
inputs: {
|
588
|
+
smart_auth_info: { name: :granular_scopes_2_auth_info }
|
589
|
+
},
|
590
|
+
outputs: {
|
591
|
+
smart_auth_info: { name: :granular_scopes_2_auth_info }
|
592
|
+
}
|
593
|
+
)
|
594
|
+
end
|
595
|
+
|
596
|
+
group from: :g10_smart_granular_scope_selection,
|
597
|
+
required_suite_options: G10Options::SMART_2_REQUIREMENT.merge(G10Options::US_CORE_6_REQUIREMENT)
|
598
|
+
group from: :g10_smart_granular_scope_selection,
|
599
|
+
id: :g10_smart_granular_scope_selection_stu2_2, # rubocop:disable Naming/VariableNumber
|
600
|
+
required_suite_options: G10Options::SMART_2_2_REQUIREMENT.merge(G10Options::US_CORE_6_REQUIREMENT)
|
601
|
+
|
602
|
+
group from: :g10_smart_granular_scope_selection,
|
603
|
+
id: :g10_us_core_7_smart_granular_scope_selection,
|
604
|
+
required_suite_options: G10Options::SMART_2_REQUIREMENT.merge(G10Options::US_CORE_7_REQUIREMENT)
|
605
|
+
group from: :g10_smart_granular_scope_selection,
|
606
|
+
id: :g10_us_core_7_smart_granular_scope_selection_stu2_2, # rubocop:disable Naming/VariableNumber
|
607
|
+
required_suite_options: G10Options::SMART_2_2_REQUIREMENT.merge(G10Options::US_CORE_7_REQUIREMENT)
|
608
|
+
end
|
609
|
+
|
610
|
+
group from: :g10_visual_inspection_and_attestations
|
611
|
+
end
|
612
|
+
end
|
613
|
+
|
614
|
+
ONCCertificationG10TestKit::TestProcedureRequirementsManager.assign_test_procedure_requirements
|