onc_certification_g10_test_kit 6.0.3 → 7.0.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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/lib/inferno/repositiories/validators.rb +0 -6
  3. data/lib/inferno/repositiories/value_sets.rb +1 -7
  4. data/lib/inferno/terminology/expected_manifest.yml +5 -5
  5. data/lib/inferno/terminology/fhir_package_manager.rb +13 -4
  6. data/lib/inferno/terminology/loader.rb +2 -1
  7. data/lib/inferno/terminology/tasks/download_fhir_terminology.rb +2 -1
  8. data/lib/inferno/terminology/tasks/download_umls.rb +2 -1
  9. data/lib/inferno/terminology/tasks/expand_value_set_to_file.rb +1 -1
  10. data/lib/inferno/terminology/tasks/run_umls_jar.rb +2 -1
  11. data/lib/inferno/terminology/validator.rb +1 -0
  12. data/lib/inferno/terminology/value_set.rb +2 -0
  13. data/lib/onc_certification_g10_test_kit/all_resources.rb +74 -0
  14. data/lib/onc_certification_g10_test_kit/bulk_data_group_export_validation.rb +361 -59
  15. data/lib/onc_certification_g10_test_kit/bulk_export_validation_tester.rb +4 -3
  16. data/lib/onc_certification_g10_test_kit/g10_options.rb +20 -1
  17. data/lib/onc_certification_g10_test_kit/limited_scope_grant_test.rb +4 -0
  18. data/lib/onc_certification_g10_test_kit/multi_patient_api_stu1.rb +2 -1
  19. data/lib/onc_certification_g10_test_kit/multi_patient_api_stu2.rb +2 -1
  20. data/lib/onc_certification_g10_test_kit/patient_scope_test.rb +1 -1
  21. data/lib/onc_certification_g10_test_kit/profile_selector.rb +40 -15
  22. data/lib/onc_certification_g10_test_kit/restricted_resource_type_access_group.rb +89 -2
  23. data/lib/onc_certification_g10_test_kit/short_id_map.yml +1417 -12
  24. data/lib/onc_certification_g10_test_kit/single_patient_us_core_7_api_group.rb +219 -0
  25. data/lib/onc_certification_g10_test_kit/smart_app_launch_invalid_aud_group.rb +41 -1
  26. data/lib/onc_certification_g10_test_kit/smart_asymmetric_launch_group.rb +33 -1
  27. data/lib/onc_certification_g10_test_kit/smart_ehr_patient_launch_group_stu2_2.rb +128 -0
  28. data/lib/onc_certification_g10_test_kit/smart_ehr_practitioner_app_group.rb +234 -0
  29. data/lib/onc_certification_g10_test_kit/smart_fine_grained_scopes_group_stu2_2.rb +188 -0
  30. data/lib/onc_certification_g10_test_kit/smart_fine_grained_scopes_us_core_7_group.rb +188 -0
  31. data/lib/onc_certification_g10_test_kit/smart_fine_grained_scopes_us_core_7_group_stu2_2.rb +188 -0
  32. data/lib/onc_certification_g10_test_kit/smart_granular_scope_selection_group.rb +67 -1
  33. data/lib/onc_certification_g10_test_kit/smart_limited_app_group.rb +128 -1
  34. data/lib/onc_certification_g10_test_kit/smart_public_standalone_launch_group_stu2_2.rb +162 -0
  35. data/lib/onc_certification_g10_test_kit/smart_scopes_test.rb +10 -2
  36. data/lib/onc_certification_g10_test_kit/smart_standalone_patient_app_group.rb +159 -0
  37. data/lib/onc_certification_g10_test_kit/smart_v1_scopes_group.rb +117 -0
  38. data/lib/onc_certification_g10_test_kit/terminology_binding_validator.rb +5 -1
  39. data/lib/onc_certification_g10_test_kit/token_introspection_group_stu2_2.rb +97 -0
  40. data/lib/onc_certification_g10_test_kit/unrestricted_resource_type_access_group.rb +85 -31
  41. data/lib/onc_certification_g10_test_kit/version.rb +1 -1
  42. data/lib/onc_certification_g10_test_kit/visual_inspection_and_attestations_group.rb +171 -0
  43. data/lib/onc_certification_g10_test_kit/well_known_capabilities_test.rb +1 -1
  44. data/lib/onc_certification_g10_test_kit.rb +72 -5
  45. metadata +18 -10
@@ -0,0 +1,188 @@
1
+ module ONCCertificationG10TestKit
2
+ class SmartFineGrainedScopesUSCore7GroupSTU22 < USCoreTestKit::USCoreV700::SmartGranularScopesGroup
3
+ title 'SMART App Launch with fine-grained scopes'
4
+ short_title 'SMART Launch with Fine-Grained Scopes'
5
+
6
+ input_instructions %(
7
+ If necessary, register Inferno as a standalone application using the following information:
8
+
9
+ * Redirect URI: `#{SMARTAppLaunch::AppRedirectTest.config.options[:redirect_uri]}`
10
+
11
+ Inferno may be registered multiple times with different `client_ids`, or this
12
+ may reuse a single registration of Inferno.`
13
+
14
+ This test will perform two launches, with each launch requiring a separate
15
+ separate set of finer-grained scopes to be granted:
16
+
17
+ Group 1:
18
+ * `Condition.rs?category=http://terminology.hl7.org/CodeSystem/condition-category|encounter-diagnosis`
19
+ * `Condition.rs?category=http://hl7.org/fhir/us/core/CodeSystem/condition-category|health-concern`
20
+ * `Observation.rs?category=http://terminology.hl7.org/CodeSystem/observation-category|laboratory`
21
+ * `Observation.rs?category=http://terminology.hl7.org/CodeSystem/observation-category|social-history`
22
+
23
+ Group 2:
24
+ * `Condition.rs?category=http://terminology.hl7.org/CodeSystem/condition-category|problem-list-item`
25
+ * `Observation.rs?category=http://terminology.hl7.org/CodeSystem/observation-category|vital-signs`
26
+ * `Observation.rs?category=http://terminology.hl7.org/CodeSystem/observation-category|survey`
27
+ * `Observation.rs?category=http://hl7.org/fhir/us/core/CodeSystem/us-core-category|sdoh`
28
+ )
29
+
30
+ description <<~DESCRIPTION
31
+
32
+ As finalized in the [HTI-1 Final Rule](https://www.federalregister.gov/d/2023-28857/p-1250), Health IT Modules are
33
+ required to support SMART App Launch v2.0.0 "Finer-grained resource
34
+ constraints using search parameters" for the "category" parameter for the
35
+ Condition resource with Condition sub-resources Encounter Diagnosis, Problem
36
+ List, and Health Concern, and the Observation resource with Observation
37
+ sub-resources Clinical Test, Laboratory, Social History, SDOH, Survey, and
38
+ Vital Signs.
39
+
40
+ This is also reflected in the (g)(10) Standardized API for patient and
41
+ populations [Test
42
+ Procedure](https://www.healthit.gov/test-method/standardized-api-patient-and-population-services#test_procedure):
43
+
44
+ > [AUT-PAT-28] SMART v2 scope syntax for patient-level and user-level scopes to support
45
+ the “permission-v2” “SMART on FHIR® Capability”, including support for
46
+ finer-grained resource constraints using search parameters according to
47
+ section 3.0.2.3 of the implementation specification at § 170.215(c)(2) for
48
+ the “category” parameter for the following resources: (1) Condition
49
+ resource with Condition sub-resources Encounter Diagnosis, Problem List,
50
+ and Health Concern; and (2) Observation resource with Observation
51
+ sub-resources Clinical Test, Laboratory, Social History, SDOH, Survey, and
52
+ Vital Signs
53
+
54
+ Prior to running this scenario, first run the Single Patient API tests using
55
+ resource-level scopes, as this scenario uses content saved from that scenario
56
+ as a baseline for comparison when finer-grained scopes are granted.
57
+
58
+ This scenario contains two groups of finer-grained scope tests, each of
59
+ which includes a SMART Standalone Launch that requests a subset of
60
+ finer-grained scopes, followed by FHIR API requests to verify that scopes
61
+ are appropriately granted. The app launches require that the subset of the
62
+ requested finer-grained scopes are granted by the user. The FHIR API tests then repeat all
63
+ of the queries from the original Single Patient API tests that were run
64
+ using resource-level scopes, and verify that only resources matching the
65
+ current finer-grained scopes are returned. Each group requires a separate
66
+ set of finer-grained scopes to be granted:
67
+
68
+ Group 1:
69
+ * `Condition.rs?category=http://terminology.hl7.org/CodeSystem/condition-category|encounter-diagnosis`
70
+ * `Condition.rs?category=http://hl7.org/fhir/us/core/CodeSystem/condition-category|health-concern`
71
+ * `Observation.rs?category=http://terminology.hl7.org/CodeSystem/observation-category|laboratory`
72
+ * `Observation.rs?category=http://terminology.hl7.org/CodeSystem/observation-category|social-history`
73
+
74
+ Group 2:
75
+ * `Condition.rs?category=http://terminology.hl7.org/CodeSystem/condition-category|problem-list-item`
76
+ * `Observation.rs?category=http://terminology.hl7.org/CodeSystem/observation-category|vital-signs`
77
+ * `Observation.rs?category=http://terminology.hl7.org/CodeSystem/observation-category|survey`
78
+ * `Observation.rs?category=http://hl7.org/fhir/us/core/CodeSystem/us-core-category|sdoh`
79
+
80
+ Note that Inferno will only request the finer grained scopes in each case,
81
+ but the system under test can display more scopes to the tester during
82
+ authorization. In this case, it is expected that the tester will only
83
+ approve the appropriate scopes in each group as described above.
84
+
85
+ For more information, please refer to [finer-grained resource constraints
86
+ using search
87
+ parameters](https://hl7.org/fhir/smart-app-launch/STU2.2/scopes-and-launch-context.html#finer-grained-resource-constraints-using-search-parameters).
88
+
89
+ DESCRIPTION
90
+
91
+ id :g10_us_core_7_smart_fine_grained_scopes_stu2_2 # rubocop:disable Naming/VariableNumber
92
+
93
+ input :url
94
+
95
+ children.each(&:run_as_group)
96
+
97
+ # Replace generic finer-grained scope auth group with which allows standalone or
98
+ # ehr launch with just the standalone launch group
99
+ granular_scopes_group1 = children.first
100
+ granular_scopes_group1.children[0] = granular_scopes_group1.children.first.children[1]
101
+ standalone_launch_group1 = granular_scopes_group1.children[0]
102
+ standalone_launch_group1.required
103
+
104
+ granular_scopes_group2 = children.last
105
+ granular_scopes_group2.children[0] = granular_scopes_group2.children.first.children[1]
106
+ standalone_launch_group2 = granular_scopes_group2.children[0]
107
+ standalone_launch_group2.required
108
+
109
+ # Move the granular scope API groups to the top level
110
+ api_group1 = granular_scopes_group1.children.pop
111
+ api_group1.children.each do |group|
112
+ group.children.select!(&:required?)
113
+ granular_scopes_group1.children << group
114
+ end
115
+
116
+ api_group2 = granular_scopes_group2.children.pop
117
+ api_group2.children.each do |group|
118
+ group.children.select!(&:required?)
119
+ granular_scopes_group2.children << group
120
+ end
121
+
122
+ # Remove OIDC and refresh token tests
123
+ standalone_launch_group1.children.pop(2)
124
+ standalone_launch_group2.children.pop(2)
125
+
126
+ config(
127
+ inputs: {
128
+ authorization_method: {
129
+ name: :granular_scopes_authorization_method,
130
+ title: 'Granular Scopes Authorization Request Method'
131
+ },
132
+ client_auth_type: {
133
+ name: :granular_scopes_client_auth_type,
134
+ title: 'Granular Scopes Client Authentication Type'
135
+ },
136
+ received_scopes: {
137
+ name: :standalone_received_scopes
138
+ }
139
+ }
140
+ )
141
+
142
+ granular_scopes_group1.config(
143
+ inputs: {
144
+ client_id: {
145
+ name: :granular_scopes1_client_id,
146
+ title: 'Granular Scopes Group 1 Client ID'
147
+ },
148
+ client_secret: {
149
+ name: :granular_scopes1_client_secret,
150
+ title: 'Granular Scopes Group 1 Client Secret'
151
+ },
152
+ requested_scopes: {
153
+ title: 'Granular Scopes Group 1 Scopes'
154
+ }
155
+ }
156
+ )
157
+
158
+ granular_scopes_group2.config(
159
+ inputs: {
160
+ client_id: {
161
+ name: :granular_scopes2_client_id,
162
+ title: 'Granular Scopes Group 2 Client ID'
163
+ },
164
+ client_secret: {
165
+ name: :granular_scopes2_client_secret,
166
+ title: 'Granular Scopes Group 2 Client Secret'
167
+ },
168
+ requested_scopes: {
169
+ title: 'Granular Scopes Group 2 Scopes'
170
+ }
171
+ }
172
+ )
173
+
174
+ input_order :url,
175
+ :granular_scopes1_client_id,
176
+ :requested_scopes_group1,
177
+ :granular_scopes_authorization_method,
178
+ :granular_scopes_client_auth_type,
179
+ :granular_scopes1_client_secret,
180
+ :client_auth_encryption_method,
181
+ :granular_scopes2_client_id,
182
+ :requested_scopes_group2,
183
+ :granular_scopes2_client_secret,
184
+ :use_pkce,
185
+ :pkce_code_challenge_method,
186
+ :patient_ids
187
+ end
188
+ end
@@ -84,9 +84,13 @@ module ONCCertificationG10TestKit
84
84
  }
85
85
  )
86
86
 
87
- group from: :smart_discovery_stu2
87
+ group from: :smart_discovery_stu2,
88
+ required_suite_options: G10Options::SMART_2_REQUIREMENT
89
+ group from: :smart_discovery_stu2_2, # rubocop:disable Naming/VariableNumber
90
+ required_suite_options: G10Options::SMART_2_2_REQUIREMENT
88
91
 
89
92
  group from: :smart_standalone_launch_stu2 do
93
+ required_suite_options(G10Options::SMART_2_REQUIREMENT)
90
94
  id :g10_granular_scope_selection_v2_scopes
91
95
  title 'Granular Scope Selection with v2 Scopes'
92
96
 
@@ -145,6 +149,68 @@ module ONCCertificationG10TestKit
145
149
  end
146
150
  end
147
151
 
152
+ test from: :g10_smart_granular_scope_selection
153
+ end
154
+ group from: :smart_standalone_launch_stu2_2 do # rubocop:disable Naming/VariableNumber
155
+ required_suite_options(G10Options::SMART_2_2_REQUIREMENT)
156
+ id :g10_granular_scope_selection_v2_2_scopes
157
+ title 'Granular Scope Selection with v2 Scopes'
158
+
159
+ config(
160
+ inputs: {
161
+ client_id: {
162
+ name: :granular_scope_selection_v2_client_id,
163
+ title: 'Granular Scope Selection w/v2 Scopes Client ID'
164
+ },
165
+ client_secret: {
166
+ name: :granular_scope_selection_v2_client_secret,
167
+ title: 'Granular Scope Selection w/v2 Scopes Client Secret',
168
+ default: nil,
169
+ optional: true
170
+ },
171
+ requested_scopes: {
172
+ name: :granular_scope_selection_v2_requested_scopes,
173
+ title: 'Granular Scope Selection v2 Scopes',
174
+ default: %(
175
+ launch/patient openid fhirUser offline_access patient/Condition.rs
176
+ patient/Observation.rs patient/Patient.rs
177
+ ).gsub(/\s{2,}/, ' ').strip
178
+ },
179
+ received_scopes: { name: :granular_scope_selection_v2_received_scopes }
180
+ },
181
+ outputs: {
182
+ requested_scopes: { name: :granular_scope_selection_v2_requested_scopes },
183
+ received_scopes: { name: :granular_scope_selection_v2_received_scopes }
184
+ },
185
+ options: {
186
+ redirect_message_proc: proc do |auth_url|
187
+ %(
188
+ ### #{self.class.parent&.parent&.title}
189
+
190
+ [Follow this link to authorize with the SMART server](#{auth_url}).
191
+
192
+ Tests will resume once Inferno receives a request at
193
+ `#{config.options[:redirect_uri]}` with a state of `#{state}`.
194
+ )
195
+ end,
196
+ ignore_missing_scopes_check: true
197
+ }
198
+ )
199
+
200
+ test from: :g10_smart_scopes do
201
+ config(
202
+ options: {
203
+ scope_version: :v22,
204
+ required_scope_type: 'patient',
205
+ required_scopes: ['openid', 'fhirUser', 'launch/patient', 'offline_access']
206
+ }
207
+ )
208
+
209
+ def patient_compartment_resource_types
210
+ ['Patient', 'Condition', 'Observation']
211
+ end
212
+ end
213
+
148
214
  test from: :g10_smart_granular_scope_selection
149
215
  end
150
216
  end
@@ -210,7 +210,134 @@ module ONCCertificationG10TestKit
210
210
  Sequence](http://hl7.org/fhir/smart-app-launch/STU2/app-launch.html#launch-app-standalone-launch)
211
211
  )
212
212
 
213
- required_suite_options G10Options::SMART_2_REQUIREMENT
213
+ required_suite_options(G10Options::SMART_2_REQUIREMENT)
214
+
215
+ config(
216
+ inputs: {
217
+ client_id: { locked: true },
218
+ client_secret: { locked: true },
219
+ url: { locked: true },
220
+ requested_scopes: { locked: true },
221
+ code: { name: :limited_code },
222
+ state: { name: :limited_state },
223
+ patient_id: { name: :limited_patient_id },
224
+ access_token: { name: :limited_access_token },
225
+ # TODO: separate standalone/ehr discovery outputs
226
+ smart_authorization_url: { locked: true, title: 'SMART Authorization Url' },
227
+ smart_token_url: { locked: true, title: 'SMART Token Url' },
228
+ received_scopes: { name: :limited_received_scopes },
229
+ smart_credentials: { name: :limited_smart_credentials },
230
+ client_auth_type: {
231
+ locked: true,
232
+ default: 'confidential_symmetric'
233
+ }
234
+ },
235
+ outputs: {
236
+ code: { name: :limited_code },
237
+ token_retrieval_time: { name: :limited_token_retrieval_time },
238
+ state: { name: :limited_state },
239
+ id_token: { name: :limited_id_token },
240
+ refresh_token: { name: :limited_refresh_token },
241
+ access_token: { name: :limited_access_token },
242
+ expires_in: { name: :limited_expires_in },
243
+ patient_id: { name: :limited_patient_id },
244
+ encounter_id: { name: :limited_encounter_id },
245
+ received_scopes: { name: :limited_received_scopes },
246
+ intent: { name: :limited_intent },
247
+ smart_credentials: { name: :limited_smart_credentials }
248
+ },
249
+ requests: {
250
+ redirect: { name: :limited_redirect },
251
+ token: { name: :limited_token }
252
+ },
253
+ options: {
254
+ ignore_missing_scopes_check: true,
255
+ redirect_message_proc: lambda do |auth_url|
256
+ expected_resource_string =
257
+ expected_resources
258
+ .split(',')
259
+ .map(&:strip)
260
+ .map { |resource_type| "* #{resource_type}\n" }
261
+ .join
262
+
263
+ <<~MESSAGE
264
+ ### #{self.class.parent.parent.title}
265
+
266
+ [Follow this link to authorize with the SMART
267
+ server](#{auth_url}).
268
+
269
+ Tests will resume once Inferno receives a request at
270
+ `#{config.options[:redirect_uri]}` with a state of `#{state}`.
271
+
272
+ Access should only be granted to the following resources:
273
+
274
+ #{expected_resource_string}
275
+ MESSAGE
276
+ end
277
+ }
278
+ )
279
+
280
+ input :expected_resources,
281
+ title: 'Expected Resource Grant for Limited Access Launch',
282
+ description: 'The user will only grant access to the following resources during authorization.',
283
+ default: 'Patient, Condition, Observation'
284
+
285
+ test from: :g10_patient_context,
286
+ config: {
287
+ inputs: {
288
+ patient_id: { name: :limited_patient_id },
289
+ smart_credentials: { name: :limited_smart_credentials }
290
+ }
291
+ }
292
+
293
+ test from: :g10_limited_scope_grant do
294
+ config(
295
+ inputs: {
296
+ received_scopes: { name: :limited_received_scopes }
297
+ }
298
+ )
299
+ end
300
+ end
301
+
302
+ group from: :smart_standalone_launch_stu2_2, # rubocop:disable Naming/VariableNumber
303
+ config: {
304
+ inputs: {
305
+ use_pkce: {
306
+ default: 'true',
307
+ locked: true
308
+ },
309
+ pkce_code_challenge_method: {
310
+ locked: true
311
+ }
312
+ }
313
+ } do
314
+ title 'Standalone Launch With Limited Scope'
315
+ description %(
316
+ # Background
317
+
318
+ The [Standalone
319
+ Launch Sequence](http://hl7.org/fhir/smart-app-launch/STU2.2/app-launch.html#launch-app-standalone-launch)
320
+ allows an app, like Inferno, to be launched independent of an
321
+ existing EHR session. It is one of the two launch methods described in
322
+ the SMART App Launch Framework alongside EHR Launch. The app will
323
+ request authorization for the provided scope from the authorization
324
+ endpoint, ultimately receiving an authorization token which can be used
325
+ to gain access to resources on the FHIR server.
326
+
327
+ # Test Methodology
328
+
329
+ Inferno will redirect the user to the the authorization endpoint so that
330
+ they may provide any required credentials and authorize the application.
331
+ Upon successful authorization, Inferno will exchange the authorization
332
+ code provided for an access token.
333
+
334
+ For more information on the #{title}:
335
+
336
+ * [Standalone Launch
337
+ Sequence](http://hl7.org/fhir/smart-app-launch/STU2.2/app-launch.html#launch-app-standalone-launch)
338
+ )
339
+
340
+ required_suite_options(G10Options::SMART_2_2_REQUIREMENT)
214
341
 
215
342
  config(
216
343
  inputs: {
@@ -0,0 +1,162 @@
1
+ module ONCCertificationG10TestKit
2
+ class SMARTPublicStandaloneLaunchGroupTestSTU22 < SMARTAppLaunch::StandaloneLaunchGroupSTU2
3
+ title 'Public Client Standalone Launch with OpenID Connect'
4
+ short_title 'Public Client Launch'
5
+ input_instructions %(
6
+ Register Inferno as a standalone application using the following information:
7
+
8
+ * Redirect URI: `#{SMARTAppLaunch::AppRedirectTest.config.options[:redirect_uri]}`
9
+
10
+ Enter in the appropriate scope to enable patient-level access to all
11
+ relevant resources. In addition, support for the OpenID Connect (openid
12
+ fhirUser), refresh tokens (offline_access), and patient context
13
+ (launch/patient) are required.
14
+ )
15
+ description %(
16
+
17
+ This scenario verifies the ability of systems to support public clients
18
+ as described in the SMART App Launch implementation specification. Previous
19
+ scenarios have not required the system under test to demonstrate this
20
+ specific type of SMART App Launch client.
21
+
22
+ Prior to executing this test, register Inferno as a public standalone
23
+ application using the following information:
24
+
25
+ * Redirect URI: `#{SMARTAppLaunch::AppRedirectTest.config.options[:redirect_uri]}`
26
+
27
+ Inferno will act as a public client redirect the tester to the the
28
+ authorization endpoint so that they may provide any required credentials
29
+ and authorize the application. Upon successful authorization, Inferno will
30
+ exchange the authorization code provided for an access token.
31
+
32
+ For more information on the #{title}:
33
+
34
+ * [Standalone Launch Sequence](http://hl7.org/fhir/smart-app-launch/STU2.2/index.html#standalone-launch-sequence)
35
+ )
36
+ id :g10_public_standalone_launch_stu2_2 # rubocop:disable Naming/VariableNumber
37
+ run_as_group
38
+
39
+ config(
40
+ inputs: {
41
+ client_id: {
42
+ name: :public_client_id,
43
+ title: 'Public Launch Client ID'
44
+ },
45
+ client_secret: {
46
+ name: :public_client_secret,
47
+ title: 'Public Launch Client Secret',
48
+ default: nil,
49
+ optional: true,
50
+ locked: true
51
+ },
52
+ requested_scopes: {
53
+ name: :public_requested_scopes,
54
+ title: 'Public Launch Scope',
55
+ default: %(
56
+ launch/patient openid fhirUser offline_access patient/Medication.rs
57
+ patient/AllergyIntolerance.rs patient/CarePlan.rs
58
+ patient/CareTeam.rs patient/Condition.rs patient/Device.rs
59
+ patient/DiagnosticReport.rs patient/DocumentReference.rs
60
+ patient/Encounter.rs patient/Goal.rs patient/Immunization.rs
61
+ patient/Location.rs patient/MedicationRequest.rs
62
+ patient/Observation.rs patient/Organization.rs patient/Patient.rs
63
+ patient/Practitioner.rs patient/Procedure.rs patient/Provenance.rs
64
+ patient/PractitionerRole.rs
65
+ ).gsub(/\s{2,}/, ' ').strip
66
+ },
67
+ url: {
68
+ title: 'Public Launch FHIR Endpoint',
69
+ description: 'URL of the FHIR endpoint used by standalone applications'
70
+ },
71
+ code: {
72
+ name: :public_code
73
+ },
74
+ state: {
75
+ name: :public_state
76
+ },
77
+ smart_authorization_url: {
78
+ title: 'OAuth 2.0 Authorize Endpoint',
79
+ description: 'OAuth 2.0 Authorize Endpoint provided during the patient standalone launch'
80
+ },
81
+ smart_token_url: {
82
+ title: 'OAuth 2.0 Token Endpoint',
83
+ description: 'OAuth 2.0 Token Endpoint provided during the patient standalone launch'
84
+ },
85
+ smart_credentials: {
86
+ name: :public_smart_credentials
87
+ },
88
+ use_pkce: {
89
+ default: 'true',
90
+ locked: true
91
+ },
92
+ pkce_code_challenge_method: {
93
+ locked: true
94
+ },
95
+ client_auth_type: {
96
+ name: :public_client_auth_type,
97
+ locked: true,
98
+ default: 'public'
99
+ }
100
+ },
101
+ outputs: {
102
+ code: { name: :public_code },
103
+ token_retrieval_time: { name: :public_token_retrieval_time },
104
+ state: { name: :public_state },
105
+ id_token: { name: :public_id_token },
106
+ refresh_token: { name: :public_refresh_token },
107
+ access_token: { name: :public_access_token },
108
+ expires_in: { name: :public_expires_in },
109
+ patient_id: { name: :public_patient_id },
110
+ encounter_id: { name: :public_encounter_id },
111
+ received_scopes: { name: :public_received_scopes },
112
+ intent: { name: :public_intent },
113
+ smart_credentials: { name: :public_smart_credentials }
114
+ },
115
+ requests: {
116
+ redirect: { name: :public_redirect },
117
+ token: { name: :public_token }
118
+ }
119
+ )
120
+
121
+ input_order :url,
122
+ :public_client_id,
123
+ :public_client_secret,
124
+ :public_requested_scopes,
125
+ :use_pkce,
126
+ :pkce_code_challenge_method,
127
+ :smart_authorization_url,
128
+ :smart_token_url,
129
+ :authorization_method,
130
+ :public_client_auth_type
131
+
132
+ test from: :g10_patient_context,
133
+ config: {
134
+ inputs: {
135
+ patient_id: { name: :public_patient_id },
136
+ smart_credentials: { name: :public_smart_credentials }
137
+ }
138
+ }
139
+
140
+ test do
141
+ title 'OAuth token exchange response contains OpenID Connect id_token'
142
+ description %(
143
+ This test requires that an OpenID Connect id_token is provided to
144
+ demonstrate authentication capabilies for public clients.
145
+ )
146
+ id :g10_public_launch_id_token
147
+
148
+ input :id_token,
149
+ name: :public_id_token,
150
+ locked: true,
151
+ optional: true
152
+
153
+ run do
154
+ assert id_token.present?, 'Token response did not provide an id_token as required.'
155
+ end
156
+ end
157
+
158
+ children.each do |child|
159
+ child.inputs.delete(:client_auth_encryption_method)
160
+ end
161
+ end
162
+ end
@@ -46,6 +46,8 @@ module ONCCertificationG10TestKit
46
46
  V6_VALID_RESOURCE_TYPES =
47
47
  (V5_VALID_RESOURCE_TYPES + ['Coverage', 'MedicationDispense', 'RelatedPerson', 'Specimen']).freeze
48
48
 
49
+ V7_VALID_RESOURCE_TYPES = (V6_VALID_RESOURCE_TYPES + ['Location'])
50
+
49
51
  PATIENT_COMPARTMENT_RESOURCE_TYPES = [
50
52
  '*',
51
53
  'Patient',
@@ -69,6 +71,8 @@ module ONCCertificationG10TestKit
69
71
  V6_PATIENT_COMPARTMENT_RESOURCE_TYPES =
70
72
  (V5_PATIENT_COMPARTMENT_RESOURCE_TYPES + ['Coverage', 'MedicationDispense', 'Specimen']).freeze
71
73
 
74
+ V7_PATIENT_COMPARTMENT_RESOURCE_TYPES = (V6_PATIENT_COMPARTMENT_RESOURCE_TYPES + ['Location']).freeze
75
+
72
76
  attr_accessor :received_or_requested
73
77
 
74
78
  def patient_compartment_resource_types
@@ -76,6 +80,8 @@ module ONCCertificationG10TestKit
76
80
 
77
81
  return V6_PATIENT_COMPARTMENT_RESOURCE_TYPES if using_us_core_6?
78
82
 
83
+ return V7_PATIENT_COMPARTMENT_RESOURCE_TYPES if using_us_core_7?
84
+
79
85
  PATIENT_COMPARTMENT_RESOURCE_TYPES
80
86
  end
81
87
 
@@ -84,6 +90,8 @@ module ONCCertificationG10TestKit
84
90
 
85
91
  return V6_VALID_RESOURCE_TYPES if using_us_core_6?
86
92
 
93
+ return V7_VALID_RESOURCE_TYPES if using_us_core_7?
94
+
87
95
  VALID_RESOURCE_TYPES
88
96
  end
89
97
 
@@ -117,7 +125,7 @@ module ONCCertificationG10TestKit
117
125
  case scope_version
118
126
  when :v1
119
127
  "#{v1_read_format} | *"
120
- when :v2
128
+ when :v2, :v22
121
129
  "#{v2_read_format} | *"
122
130
  else
123
131
  [v1_read_format, v2_read_format, '*'].join(' | ')
@@ -128,7 +136,7 @@ module ONCCertificationG10TestKit
128
136
  case scope_version
129
137
  when :v1
130
138
  /\A(\*|read)\b/
131
- when :v2
139
+ when :v2, :v22
132
140
  /\A(\*|c?ru?d?s?)\b/
133
141
  else
134
142
  /\A(\*|read|c?ru?d?s?)\b/