onc_certification_g10_test_kit 2.0.0.rc1
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 +7 -0
- data/LICENSE +201 -0
- data/lib/inferno/exceptions.rb +31 -0
- data/lib/inferno/ext/bloomer.rb +24 -0
- data/lib/inferno/repositiories/validators.rb +17 -0
- data/lib/inferno/repositiories/value_sets.rb +26 -0
- data/lib/inferno/terminology/bcp47.rb +95 -0
- data/lib/inferno/terminology/bcp_13.rb +26 -0
- data/lib/inferno/terminology/codesystem.rb +49 -0
- data/lib/inferno/terminology/expected_manifest.yml +1123 -0
- data/lib/inferno/terminology/fhir_package_manager.rb +69 -0
- data/lib/inferno/terminology/loader.rb +298 -0
- data/lib/inferno/terminology/tasks/check_built_terminology.rb +77 -0
- data/lib/inferno/terminology/tasks/cleanup.rb +13 -0
- data/lib/inferno/terminology/tasks/cleanup_precursors.rb +23 -0
- data/lib/inferno/terminology/tasks/count_codes_in_value_set.rb +20 -0
- data/lib/inferno/terminology/tasks/create_value_set_validators.rb +34 -0
- data/lib/inferno/terminology/tasks/download_fhir_terminology.rb +27 -0
- data/lib/inferno/terminology/tasks/download_umls.rb +109 -0
- data/lib/inferno/terminology/tasks/download_umls_notice.rb +20 -0
- data/lib/inferno/terminology/tasks/expand_value_set_to_file.rb +36 -0
- data/lib/inferno/terminology/tasks/process_umls.rb +91 -0
- data/lib/inferno/terminology/tasks/process_umls_translations.rb +85 -0
- data/lib/inferno/terminology/tasks/run_umls_jar.rb +75 -0
- data/lib/inferno/terminology/tasks/temp_dir.rb +27 -0
- data/lib/inferno/terminology/tasks/unzip_umls.rb +42 -0
- data/lib/inferno/terminology/tasks/validate_code.rb +36 -0
- data/lib/inferno/terminology/tasks.rb +11 -0
- data/lib/inferno/terminology/terminology_configuration.rb +52 -0
- data/lib/inferno/terminology/terminology_validation.rb +42 -0
- data/lib/inferno/terminology/validator.rb +64 -0
- data/lib/inferno/terminology/value_set.rb +462 -0
- data/lib/inferno/terminology.rb +16 -0
- data/lib/onc_certification_g10_test_kit/authorization_request_builder.rb +87 -0
- data/lib/onc_certification_g10_test_kit/base_token_refresh_group.rb +48 -0
- data/lib/onc_certification_g10_test_kit/bulk_data_authorization.rb +235 -0
- data/lib/onc_certification_g10_test_kit/bulk_data_group_export.rb +255 -0
- data/lib/onc_certification_g10_test_kit/bulk_data_group_export_validation.rb +474 -0
- data/lib/onc_certification_g10_test_kit/bulk_data_jwks.json +58 -0
- data/lib/onc_certification_g10_test_kit/bulk_export_validation_tester.rb +171 -0
- data/lib/onc_certification_g10_test_kit/configuration_checker.rb +104 -0
- data/lib/onc_certification_g10_test_kit/export_kick_off_performer.rb +12 -0
- data/lib/onc_certification_g10_test_kit/igs/StructureDefinition-bodyheight.json +3772 -0
- data/lib/onc_certification_g10_test_kit/igs/StructureDefinition-bodytemp.json +3772 -0
- data/lib/onc_certification_g10_test_kit/igs/StructureDefinition-bodyweight.json +3772 -0
- data/lib/onc_certification_g10_test_kit/igs/StructureDefinition-bp.json +6034 -0
- data/lib/onc_certification_g10_test_kit/igs/StructureDefinition-heartrate.json +3756 -0
- data/lib/onc_certification_g10_test_kit/igs/StructureDefinition-resprate.json +3756 -0
- data/lib/onc_certification_g10_test_kit/limited_scope_grant_test.rb +66 -0
- data/lib/onc_certification_g10_test_kit/multi_patient_api.rb +43 -0
- data/lib/onc_certification_g10_test_kit/patient_context_test.rb +30 -0
- data/lib/onc_certification_g10_test_kit/profile_guesser.rb +69 -0
- data/lib/onc_certification_g10_test_kit/resource_access_test.rb +96 -0
- data/lib/onc_certification_g10_test_kit/restricted_access_test.rb +12 -0
- data/lib/onc_certification_g10_test_kit/restricted_resource_type_access_group.rb +303 -0
- data/lib/onc_certification_g10_test_kit/smart_app_launch_invalid_aud_group.rb +136 -0
- data/lib/onc_certification_g10_test_kit/smart_ehr_practitioner_app_group.rb +209 -0
- data/lib/onc_certification_g10_test_kit/smart_invalid_token_group.rb +197 -0
- data/lib/onc_certification_g10_test_kit/smart_limited_app_group.rb +123 -0
- data/lib/onc_certification_g10_test_kit/smart_public_standalone_launch_group.rb +113 -0
- data/lib/onc_certification_g10_test_kit/smart_scopes_test.rb +153 -0
- data/lib/onc_certification_g10_test_kit/smart_standalone_patient_app_group.rb +177 -0
- data/lib/onc_certification_g10_test_kit/terminology_binding_validator.rb +140 -0
- data/lib/onc_certification_g10_test_kit/token_revocation_group.rb +133 -0
- data/lib/onc_certification_g10_test_kit/unauthorized_access_test.rb +25 -0
- data/lib/onc_certification_g10_test_kit/unrestricted_resource_type_access_group.rb +375 -0
- data/lib/onc_certification_g10_test_kit/version.rb +3 -0
- data/lib/onc_certification_g10_test_kit/visual_inspection_and_attestations_group.rb +470 -0
- data/lib/onc_certification_g10_test_kit/well_known_capabilities_test.rb +37 -0
- data/lib/onc_certification_g10_test_kit.rb +223 -0
- metadata +310 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
module ONCCertificationG10TestKit
|
|
2
|
+
class LimitedScopeGrantTest < Inferno::Test
|
|
3
|
+
title 'OAuth token exchange response grants scope that is limited to those selected by user'
|
|
4
|
+
description %(
|
|
5
|
+
The ONC certification criteria requires that patients are capable of
|
|
6
|
+
choosing which FHIR resources to authorize to the application. For this
|
|
7
|
+
test, the tester specifies which resources will be selected during
|
|
8
|
+
authorization, and this verifies that only those resources are granted
|
|
9
|
+
according to the scopes returned during the access token response.
|
|
10
|
+
)
|
|
11
|
+
id :g10_limited_scope_grant
|
|
12
|
+
|
|
13
|
+
input :received_scopes, :expected_resources
|
|
14
|
+
|
|
15
|
+
def possible_resources
|
|
16
|
+
[
|
|
17
|
+
'AllergyIntolerance',
|
|
18
|
+
'CarePlan',
|
|
19
|
+
'CareTeam',
|
|
20
|
+
'Condition',
|
|
21
|
+
'Device',
|
|
22
|
+
'DiagnosticReport',
|
|
23
|
+
'DocumentReference',
|
|
24
|
+
'Goal',
|
|
25
|
+
'Immunization',
|
|
26
|
+
'MedicationRequest',
|
|
27
|
+
'Observation',
|
|
28
|
+
'Procedure',
|
|
29
|
+
'Patient'
|
|
30
|
+
]
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def scope_granting_access?(resource_type, scopes)
|
|
34
|
+
scopes.any? do |scope|
|
|
35
|
+
scope.start_with?("patient/#{resource_type}", 'patient/*') && scope.end_with?('*', 'read')
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
run do
|
|
40
|
+
expected_resources_list = expected_resources.split(',').map(&:strip).map(&:downcase)
|
|
41
|
+
allowed_resources =
|
|
42
|
+
possible_resources.select { |resource_type| expected_resources_list.include? resource_type.downcase }
|
|
43
|
+
forbidden_resources = possible_resources - allowed_resources
|
|
44
|
+
|
|
45
|
+
received_scope_list = received_scopes.split
|
|
46
|
+
|
|
47
|
+
improperly_granted_resources =
|
|
48
|
+
forbidden_resources.select { |resource_type| scope_granting_access?(resource_type, received_scope_list) }
|
|
49
|
+
improperly_denied_resources =
|
|
50
|
+
allowed_resources.reject { |resource_type| scope_granting_access?(resource_type, received_scope_list) }
|
|
51
|
+
|
|
52
|
+
assert improperly_granted_resources.empty?,
|
|
53
|
+
'User expected to deny the following resources that were granted: ' \
|
|
54
|
+
"#{improperly_granted_resources.join(', ')}"
|
|
55
|
+
assert improperly_denied_resources.empty?,
|
|
56
|
+
'User expected to grant access to the following resources: ' \
|
|
57
|
+
"#{improperly_denied_resources.join(', ')}"
|
|
58
|
+
|
|
59
|
+
assert forbidden_resources.present?,
|
|
60
|
+
'This test requires at least one resource to be denied, but the received scopes ' \
|
|
61
|
+
"`#{received_scopes}` grant access to all resource types."
|
|
62
|
+
|
|
63
|
+
pass "Resources to be denied: #{forbidden_resources.join(', ')}"
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require_relative 'bulk_data_authorization'
|
|
2
|
+
require_relative 'bulk_data_group_export'
|
|
3
|
+
require_relative 'bulk_data_group_export_validation'
|
|
4
|
+
|
|
5
|
+
module ONCCertificationG10TestKit
|
|
6
|
+
class MultiPatientAPIGroup < Inferno::TestGroup
|
|
7
|
+
title 'Multi-Patient Authorization and API'
|
|
8
|
+
short_title 'Multi-Patient API'
|
|
9
|
+
|
|
10
|
+
input_instructions %(
|
|
11
|
+
Register Inferno as a bulk data client with the following information, and
|
|
12
|
+
enter the client id and client registration in the appropriate fields.
|
|
13
|
+
This set of tests only checks the Group export. Enter the group export
|
|
14
|
+
information in the appropriate box.
|
|
15
|
+
|
|
16
|
+
Register Inferno with the following JWK Set Url:
|
|
17
|
+
|
|
18
|
+
* `#{Inferno::Application[:base_url]}/custom/g10_certification/.well-known/jwks.json`
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
description %(
|
|
22
|
+
Demonstrate the ability to export clinical data for multiple patients in
|
|
23
|
+
a group using [FHIR Bulk Data Access
|
|
24
|
+
IG](https://hl7.org/fhir/uv/bulkdata/). This test uses [Backend Services
|
|
25
|
+
Authorization](https://hl7.org/fhir/uv/bulkdata/authorization/index.html)
|
|
26
|
+
to obtain an access token from the server. After authorization, a group
|
|
27
|
+
level bulk data export request is initialized. Finally, this test reads
|
|
28
|
+
exported NDJSON files from the server and validates the resources in
|
|
29
|
+
each file. To run the test successfully, the selected group export is
|
|
30
|
+
required to have every type of resource mapped to [USCDI data
|
|
31
|
+
elements](https://www.healthit.gov/isa/us-core-data-interoperability-uscdi).
|
|
32
|
+
Additionally, it is expected the server will provide Encounter,
|
|
33
|
+
Location, Organization, and Practitioner resources as they are
|
|
34
|
+
referenced as must support elements in required resources.
|
|
35
|
+
)
|
|
36
|
+
id :multi_patient_api
|
|
37
|
+
run_as_group
|
|
38
|
+
|
|
39
|
+
group from: :bulk_data_authorization
|
|
40
|
+
group from: :bulk_data_group_export
|
|
41
|
+
group from: :bulk_data_group_export_validation
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module ONCCertificationG10TestKit
|
|
2
|
+
class PatientContextTest < Inferno::Test
|
|
3
|
+
title 'OAuth token exchange response body contains patient context and patient resource can be retrieved'
|
|
4
|
+
description %(
|
|
5
|
+
The `patient` field is a String value with a patient id, indicating that
|
|
6
|
+
the app was launched in the context of this FHIR Patient.
|
|
7
|
+
)
|
|
8
|
+
id :g10_patient_context
|
|
9
|
+
input :patient_id, :url
|
|
10
|
+
input :smart_credentials, type: :oauth_credentials
|
|
11
|
+
|
|
12
|
+
fhir_client :authenticated do
|
|
13
|
+
url :url
|
|
14
|
+
oauth_credentials :smart_credentials
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
run do
|
|
18
|
+
skip_if smart_credentials.access_token.blank?, 'No access token was received during the SMART launch'
|
|
19
|
+
|
|
20
|
+
skip_if patient_id.blank?, 'Token response did not contain `patient` field'
|
|
21
|
+
|
|
22
|
+
skip_if request.status != 200, 'Token was not successfully refreshed' if config.options[:refresh_test]
|
|
23
|
+
|
|
24
|
+
fhir_read(:patient, patient_id, client: :authenticated)
|
|
25
|
+
|
|
26
|
+
assert_response_status(200)
|
|
27
|
+
assert_resource_type(:patient)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
module ONCCertificationG10TestKit
|
|
2
|
+
module ProfileGuesser
|
|
3
|
+
def extract_profile(profile)
|
|
4
|
+
if ['Location', 'Medication'].include?(profile)
|
|
5
|
+
return USCoreTestKit::USCoreTestSuite.metadata.find do |meta|
|
|
6
|
+
meta.resource == profile
|
|
7
|
+
end.profile_url
|
|
8
|
+
end
|
|
9
|
+
"USCoreTestKit::#{profile}Group".constantize.metadata.profile_url
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def observation_contains_code(observation_resource, code)
|
|
13
|
+
observation_resource&.code&.coding&.any? { |coding| coding&.code == code }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def resource_contains_category(resource, category_code, category_system = nil) # rubocop:disable Metrics/CyclomaticComplexity
|
|
17
|
+
resource&.category&.any? do |category|
|
|
18
|
+
category.coding&.any? do |coding|
|
|
19
|
+
coding.code == category_code &&
|
|
20
|
+
(category_system.blank? || coding.system.blank? || category_system == coding.system)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def guess_profile(resource) # rubocop:disable Metrics/CyclomaticComplexity
|
|
26
|
+
case resource.resourceType
|
|
27
|
+
when 'DiagnosticReport'
|
|
28
|
+
return extract_profile('DiagnosticReportLab') if resource_contains_category(resource, 'LAB', 'http://terminology.hl7.org/CodeSystem/v2-0074')
|
|
29
|
+
|
|
30
|
+
extract_profile('DiagnosticReportNote')
|
|
31
|
+
when 'Observation'
|
|
32
|
+
return extract_profile('Smokingstatus') if observation_contains_code(resource, '72166-2')
|
|
33
|
+
|
|
34
|
+
return extract_profile('ObservationLab') if resource_contains_category(resource, 'laboratory', 'http://terminology.hl7.org/CodeSystem/observation-category')
|
|
35
|
+
|
|
36
|
+
return extract_profile('PediatricBmiForAge') if observation_contains_code(resource, '59576-9')
|
|
37
|
+
|
|
38
|
+
return extract_profile('PediatricWeightForHeight') if observation_contains_code(resource, '77606-2')
|
|
39
|
+
|
|
40
|
+
return extract_profile('PulseOximetry') if observation_contains_code(resource, '59408-5')
|
|
41
|
+
|
|
42
|
+
return extract_profile('HeadCircumference') if observation_contains_code(resource, '8289-1')
|
|
43
|
+
|
|
44
|
+
# FHIR Vital Signs profiles: https://www.hl7.org/fhir/observation-vitalsigns.html
|
|
45
|
+
# Vital Signs Panel, Oxygen Saturation are not required by USCDI
|
|
46
|
+
# Body Mass Index is replaced by :pediatric_bmi_age Profile
|
|
47
|
+
# Systolic Blood Pressure, Diastolic Blood Pressure are covered by :blood_pressure Profile
|
|
48
|
+
# Head Circumference is replaced by US Core Head Occipital-frontal Circumference Percentile Profile
|
|
49
|
+
return extract_profile('Bp') if observation_contains_code(resource, '85354-9')
|
|
50
|
+
|
|
51
|
+
return extract_profile('Bodyheight') if observation_contains_code(resource, '8302-2')
|
|
52
|
+
|
|
53
|
+
return extract_profile('Bodytemp') if observation_contains_code(resource, '8310-5')
|
|
54
|
+
|
|
55
|
+
return extract_profile('Bodyweight') if observation_contains_code(resource, '29463-7')
|
|
56
|
+
|
|
57
|
+
return extract_profile('Heartrate') if observation_contains_code(resource, '8867-4')
|
|
58
|
+
|
|
59
|
+
return extract_profile('Resprate') if observation_contains_code(resource, '9279-1')
|
|
60
|
+
|
|
61
|
+
nil
|
|
62
|
+
else
|
|
63
|
+
extract_profile(resource.resourceType)
|
|
64
|
+
end
|
|
65
|
+
rescue StandardError
|
|
66
|
+
skip "Could not determine profile of \"#{resource.resourceType}\" resource."
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
module ONCCertificationG10TestKit
|
|
2
|
+
class ResourceAccessTest < Inferno::Test
|
|
3
|
+
id :g10_resource_access_test
|
|
4
|
+
input :patient_id, :received_scopes
|
|
5
|
+
|
|
6
|
+
title 'Access to resources are restricted properly based on patient-selected scope'
|
|
7
|
+
description %(
|
|
8
|
+
This test ensures that access to the resource is granted or denied
|
|
9
|
+
based on the selection by the tester prior to the execution of the test.
|
|
10
|
+
If the tester indicated that access will be granted to this resource,
|
|
11
|
+
this test verifies that a search by patient in this resource does not
|
|
12
|
+
result in an access denied result. If the tester indicated that access
|
|
13
|
+
will be denied for this resource, this verifies that search by patient
|
|
14
|
+
in the resource results in an access denied result.
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
def resource_group
|
|
18
|
+
raise StandardError, '#resource_group must be overridden'
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def search_params
|
|
22
|
+
@search_params ||=
|
|
23
|
+
resource_group.metadata.searches.first[:names].each_with_object({}) do |name, params|
|
|
24
|
+
params[name] = search_param_value(name)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def search_param_value(name)
|
|
29
|
+
return patient_id if ['patient', '_id', 'subject'].include?(name)
|
|
30
|
+
|
|
31
|
+
resource_group.metadata.search_definitions[name.to_sym][:values].first
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def status_search_params
|
|
35
|
+
{
|
|
36
|
+
"#{status_search_param_name}": search_param_value(status_search_param_name)
|
|
37
|
+
}
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def status_search_param_name
|
|
41
|
+
@status_search_param_name ||=
|
|
42
|
+
resource_group.metadata.search_definitions.keys.find { |key| key.to_s.include? 'status' }
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def status_search_param_value
|
|
46
|
+
@status_search_param_value ||=
|
|
47
|
+
resource_group.metadata.search_definitions[status_search_param_name][:values].first
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def resource_search_test
|
|
51
|
+
resource_group.tests.first
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def request_should_succeed?
|
|
55
|
+
true
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def resource_type
|
|
59
|
+
resource_search_test.properties.resource_type
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
run do
|
|
63
|
+
skip_if patient_id.blank?, 'Patient ID not provided to test.'
|
|
64
|
+
skip_if received_scopes.blank?, 'No scopes were received.'
|
|
65
|
+
|
|
66
|
+
fhir_search(resource_type, params: search_params)
|
|
67
|
+
|
|
68
|
+
if request_should_succeed?
|
|
69
|
+
if request.status == 400 && resource_search_test.properties.possible_status_search?
|
|
70
|
+
error_message = %(
|
|
71
|
+
Server is expected to grant access to the resource. A search
|
|
72
|
+
without a status can return an HTTP 400 status, but must also must
|
|
73
|
+
include an OperationOutcome. No OperationOutcome is present in the
|
|
74
|
+
body of the response.
|
|
75
|
+
)
|
|
76
|
+
begin
|
|
77
|
+
parsed_body = JSON.parse(response[:body])
|
|
78
|
+
assert parsed_body['resourceType'] == 'OperationOutcome', error_message
|
|
79
|
+
rescue JSON::ParserError
|
|
80
|
+
assert false, error_message
|
|
81
|
+
end
|
|
82
|
+
fhir_search(
|
|
83
|
+
:allergy_intolerance,
|
|
84
|
+
params: search_params.merge(status_search_params)
|
|
85
|
+
)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
assert_response_status(200)
|
|
89
|
+
pass "Access expected to be granted and request properly returned #{request.status}"
|
|
90
|
+
else
|
|
91
|
+
message = "Bad response code: expected 403 (Forbidden) or 401 (Unauthorized), but found #{request.status}."
|
|
92
|
+
assert [401, 403].include?(request.status), message
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
require_relative 'resource_access_test'
|
|
2
|
+
|
|
3
|
+
module ONCCertificationG10TestKit
|
|
4
|
+
class RestrictedAccessTest < ResourceAccessTest
|
|
5
|
+
id :g10_restricted_access_test
|
|
6
|
+
input :expected_resources
|
|
7
|
+
|
|
8
|
+
def request_should_succeed?
|
|
9
|
+
expected_resources.split(',').any? { |resource| resource.strip.casecmp? resource_type }
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
require_relative 'restricted_access_test'
|
|
2
|
+
|
|
3
|
+
module ONCCertificationG10TestKit
|
|
4
|
+
class RestrictedResourceTypeAccessGroup < Inferno::TestGroup
|
|
5
|
+
title 'Restricted Resource Type Access'
|
|
6
|
+
description %(
|
|
7
|
+
This test ensures that patients are able to grant or deny access to a
|
|
8
|
+
subset of resources to an app as requied by the certification criteria.
|
|
9
|
+
The tester provides a list of resources that will be granted during the
|
|
10
|
+
SMART App Launch process, and this test verifies that the scopes granted
|
|
11
|
+
are consistent with what the tester provided. It also formulates queries
|
|
12
|
+
to ensure that the app is either given access to, or denied access to, the
|
|
13
|
+
appropriate resource types based on those chosen by the tester.
|
|
14
|
+
|
|
15
|
+
Resources that can be mapped to USCDI are checked in this test, including:
|
|
16
|
+
|
|
17
|
+
* AllergyIntolerance
|
|
18
|
+
* CarePlan
|
|
19
|
+
* CareTeam
|
|
20
|
+
* Condition
|
|
21
|
+
* Device
|
|
22
|
+
* DiagnosticReport
|
|
23
|
+
* DocumentReference
|
|
24
|
+
* Goal
|
|
25
|
+
* Immunization
|
|
26
|
+
* MedicationRequest
|
|
27
|
+
* Observation
|
|
28
|
+
* Procedure
|
|
29
|
+
|
|
30
|
+
For each of the resources that can be mapped to USCDI data class or
|
|
31
|
+
elements, this set of tests performs a minimum number of requests to
|
|
32
|
+
determine if access to the resource type is appropriately allowed or
|
|
33
|
+
denied given the scope granted. In the case of the Patient resource, this
|
|
34
|
+
test simply performs a read request. For other resources, it performs a
|
|
35
|
+
search by patient that must be supported by the server. In some cases,
|
|
36
|
+
servers can return an error message if a status search parameter is not
|
|
37
|
+
provided. For these, the test will perform an additional search with the
|
|
38
|
+
required status search parameter.
|
|
39
|
+
|
|
40
|
+
This set of tests does not attempt to access resources that do not
|
|
41
|
+
directly map to USCDI v1, including Encounter, Location, Organization, and
|
|
42
|
+
Practitioner. It also does not test Provenance, as this resource type is
|
|
43
|
+
accessed by queries through other resource types. These resource types are
|
|
44
|
+
accessed in the more comprehensive Single Patient Query tests.
|
|
45
|
+
|
|
46
|
+
If the tester chooses to not grant access to a resource, the queries
|
|
47
|
+
associated with that resource must result in either a 401 (Unauthorized)
|
|
48
|
+
or 403 (Forbidden) status code. The flexiblity provided here is due to
|
|
49
|
+
some ambiguity in the specifications tested.
|
|
50
|
+
)
|
|
51
|
+
id :g10_restricted_resource_type_access
|
|
52
|
+
|
|
53
|
+
input :url, :patient_id, :received_scopes, :expected_resources
|
|
54
|
+
input :smart_credentials, type: :oauth_credentials
|
|
55
|
+
|
|
56
|
+
config(
|
|
57
|
+
inputs: {
|
|
58
|
+
client_secret: {
|
|
59
|
+
optional: false
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
fhir_client do
|
|
65
|
+
url :url
|
|
66
|
+
oauth_credentials :smart_credentials
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
test from: :g10_restricted_access_test do
|
|
70
|
+
title 'Access to Patient resources are restricted properly based on patient-selected scope'
|
|
71
|
+
description %(
|
|
72
|
+
This test ensures that access to the Patient is granted or
|
|
73
|
+
denied based on the selection by the tester prior to the execution of
|
|
74
|
+
the test. If the tester indicated that access will be granted to this
|
|
75
|
+
resource, this test verifies that a search by patient in this resource
|
|
76
|
+
does not result in an access denied result. If the tester indicated that
|
|
77
|
+
access will be denied for this resource, this verifies that search by
|
|
78
|
+
patient in the resource results in an access denied result.
|
|
79
|
+
)
|
|
80
|
+
id :g10_patient_restricted_access
|
|
81
|
+
|
|
82
|
+
def resource_group
|
|
83
|
+
USCoreTestKit::PatientGroup
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
test from: :g10_restricted_access_test do
|
|
88
|
+
title 'Access to AllergyIntolerance resources are restricted properly based on patient-selected scope'
|
|
89
|
+
description %(
|
|
90
|
+
This test ensures that access to the AllergyIntolerance is granted or
|
|
91
|
+
denied based on the selection by the tester prior to the execution of
|
|
92
|
+
the test. If the tester indicated that access will be granted to this
|
|
93
|
+
resource, this test verifies that a search by patient in this resource
|
|
94
|
+
does not result in an access denied result. If the tester indicated that
|
|
95
|
+
access will be denied for this resource, this verifies that search by
|
|
96
|
+
patient in the resource results in an access denied result.
|
|
97
|
+
)
|
|
98
|
+
id :g10_allergy_intolerance_restricted_access
|
|
99
|
+
|
|
100
|
+
def resource_group
|
|
101
|
+
USCoreTestKit::AllergyIntoleranceGroup
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
test from: :g10_restricted_access_test do
|
|
106
|
+
title 'Access to CarePlan resources are restricted properly based on patient-selected scope'
|
|
107
|
+
description %(
|
|
108
|
+
This test ensures that access to the CarePlan is granted or
|
|
109
|
+
denied based on the selection by the tester prior to the execution of
|
|
110
|
+
the test. If the tester indicated that access will be granted to this
|
|
111
|
+
resource, this test verifies that a search by patient in this resource
|
|
112
|
+
does not result in an access denied result. If the tester indicated that
|
|
113
|
+
access will be denied for this resource, this verifies that search by
|
|
114
|
+
patient in the resource results in an access denied result.
|
|
115
|
+
)
|
|
116
|
+
id :g10_care_plan_restricted_access
|
|
117
|
+
|
|
118
|
+
def resource_group
|
|
119
|
+
USCoreTestKit::CarePlanGroup
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
test from: :g10_restricted_access_test do
|
|
124
|
+
title 'Access to CareTeam resources are restricted properly based on patient-selected scope'
|
|
125
|
+
description %(
|
|
126
|
+
This test ensures that access to the CareTeam is granted or
|
|
127
|
+
denied based on the selection by the tester prior to the execution of
|
|
128
|
+
the test. If the tester indicated that access will be granted to this
|
|
129
|
+
resource, this test verifies that a search by patient in this resource
|
|
130
|
+
does not result in an access denied result. If the tester indicated that
|
|
131
|
+
access will be denied for this resource, this verifies that search by
|
|
132
|
+
patient in the resource results in an access denied result.
|
|
133
|
+
)
|
|
134
|
+
id :g10_care_team_restricted_access
|
|
135
|
+
|
|
136
|
+
def resource_group
|
|
137
|
+
USCoreTestKit::CareTeamGroup
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
test from: :g10_restricted_access_test do
|
|
142
|
+
title 'Access to Condition resources are restricted properly based on patient-selected scope'
|
|
143
|
+
description %(
|
|
144
|
+
This test ensures that access to the Condition is granted or
|
|
145
|
+
denied based on the selection by the tester prior to the execution of
|
|
146
|
+
the test. If the tester indicated that access will be granted to this
|
|
147
|
+
resource, this test verifies that a search by patient in this resource
|
|
148
|
+
does not result in an access denied result. If the tester indicated that
|
|
149
|
+
access will be denied for this resource, this verifies that search by
|
|
150
|
+
patient in the resource results in an access denied result.
|
|
151
|
+
)
|
|
152
|
+
id :g10_condition_restricted_access
|
|
153
|
+
|
|
154
|
+
def resource_group
|
|
155
|
+
USCoreTestKit::ConditionGroup
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
test from: :g10_restricted_access_test do
|
|
160
|
+
title 'Access to Device resources are restricted properly based on patient-selected scope'
|
|
161
|
+
description %(
|
|
162
|
+
This test ensures that access to the Device is granted or
|
|
163
|
+
denied based on the selection by the tester prior to the execution of
|
|
164
|
+
the test. If the tester indicated that access will be granted to this
|
|
165
|
+
resource, this test verifies that a search by patient in this resource
|
|
166
|
+
does not result in an access denied result. If the tester indicated that
|
|
167
|
+
access will be denied for this resource, this verifies that search by
|
|
168
|
+
patient in the resource results in an access denied result.
|
|
169
|
+
)
|
|
170
|
+
id :g10_device_restricted_access
|
|
171
|
+
|
|
172
|
+
def resource_group
|
|
173
|
+
USCoreTestKit::DeviceGroup
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
test from: :g10_restricted_access_test do
|
|
178
|
+
title 'Access to DiagnosticReport resources are restricted properly based on patient-selected scope'
|
|
179
|
+
description %(
|
|
180
|
+
This test ensures that access to the DiagnosticReport is granted or
|
|
181
|
+
denied based on the selection by the tester prior to the execution of
|
|
182
|
+
the test. If the tester indicated that access will be granted to this
|
|
183
|
+
resource, this test verifies that a search by patient in this resource
|
|
184
|
+
does not result in an access denied result. If the tester indicated that
|
|
185
|
+
access will be denied for this resource, this verifies that search by
|
|
186
|
+
patient in the resource results in an access denied result.
|
|
187
|
+
)
|
|
188
|
+
id :g10_diagnostic_report_restricted_access
|
|
189
|
+
|
|
190
|
+
def resource_group
|
|
191
|
+
USCoreTestKit::DiagnosticReportLabGroup
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
test from: :g10_restricted_access_test do
|
|
196
|
+
title 'Access to DocumentReference resources are restricted properly based on patient-selected scope'
|
|
197
|
+
description %(
|
|
198
|
+
This test ensures that access to the DocumentReference is granted or
|
|
199
|
+
denied based on the selection by the tester prior to the execution of
|
|
200
|
+
the test. If the tester indicated that access will be granted to this
|
|
201
|
+
resource, this test verifies that a search by patient in this resource
|
|
202
|
+
does not result in an access denied result. If the tester indicated that
|
|
203
|
+
access will be denied for this resource, this verifies that search by
|
|
204
|
+
patient in the resource results in an access denied result.
|
|
205
|
+
)
|
|
206
|
+
id :g10_document_reference_restricted_access
|
|
207
|
+
|
|
208
|
+
def resource_group
|
|
209
|
+
USCoreTestKit::DocumentReferenceGroup
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
test from: :g10_restricted_access_test do
|
|
214
|
+
title 'Access to Goal resources are restricted properly based on patient-selected scope'
|
|
215
|
+
description %(
|
|
216
|
+
This test ensures that access to the Goal is granted or
|
|
217
|
+
denied based on the selection by the tester prior to the execution of
|
|
218
|
+
the test. If the tester indicated that access will be granted to this
|
|
219
|
+
resource, this test verifies that a search by patient in this resource
|
|
220
|
+
does not result in an access denied result. If the tester indicated that
|
|
221
|
+
access will be denied for this resource, this verifies that search by
|
|
222
|
+
patient in the resource results in an access denied result.
|
|
223
|
+
)
|
|
224
|
+
id :g10_goal_restricted_access
|
|
225
|
+
|
|
226
|
+
def resource_group
|
|
227
|
+
USCoreTestKit::GoalGroup
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
test from: :g10_restricted_access_test do
|
|
232
|
+
title 'Access to Immunization resources are restricted properly based on patient-selected scope'
|
|
233
|
+
description %(
|
|
234
|
+
This test ensures that access to the Immunization is granted or
|
|
235
|
+
denied based on the selection by the tester prior to the execution of
|
|
236
|
+
the test. If the tester indicated that access will be granted to this
|
|
237
|
+
resource, this test verifies that a search by patient in this resource
|
|
238
|
+
does not result in an access denied result. If the tester indicated that
|
|
239
|
+
access will be denied for this resource, this verifies that search by
|
|
240
|
+
patient in the resource results in an access denied result.
|
|
241
|
+
)
|
|
242
|
+
id :g10_immunization_restricted_access
|
|
243
|
+
|
|
244
|
+
def resource_group
|
|
245
|
+
USCoreTestKit::ImmunizationGroup
|
|
246
|
+
end
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
test from: :g10_restricted_access_test do
|
|
250
|
+
title 'Access to MedicationRequest resources are restricted properly based on patient-selected scope'
|
|
251
|
+
description %(
|
|
252
|
+
This test ensures that access to the MedicationRequest is granted or
|
|
253
|
+
denied based on the selection by the tester prior to the execution of
|
|
254
|
+
the test. If the tester indicated that access will be granted to this
|
|
255
|
+
resource, this test verifies that a search by patient in this resource
|
|
256
|
+
does not result in an access denied result. If the tester indicated that
|
|
257
|
+
access will be denied for this resource, this verifies that search by
|
|
258
|
+
patient in the resource results in an access denied result.
|
|
259
|
+
)
|
|
260
|
+
id :g10_medication_request_access
|
|
261
|
+
|
|
262
|
+
def resource_group
|
|
263
|
+
USCoreTestKit::MedicationRequestGroup
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
test from: :g10_restricted_access_test do
|
|
268
|
+
title 'Access to Observation resources are restricted properly based on patient-selected scope'
|
|
269
|
+
description %(
|
|
270
|
+
This test ensures that access to the Observation is granted or
|
|
271
|
+
denied based on the selection by the tester prior to the execution of
|
|
272
|
+
the test. If the tester indicated that access will be granted to this
|
|
273
|
+
resource, this test verifies that a search by patient in this resource
|
|
274
|
+
does not result in an access denied result. If the tester indicated that
|
|
275
|
+
access will be denied for this resource, this verifies that search by
|
|
276
|
+
patient in the resource results in an access denied result.
|
|
277
|
+
)
|
|
278
|
+
id :g10_observation_restricted_access
|
|
279
|
+
|
|
280
|
+
def resource_group
|
|
281
|
+
USCoreTestKit::PulseOximetryGroup
|
|
282
|
+
end
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
test from: :g10_restricted_access_test do
|
|
286
|
+
title 'Access to Procedure resources are restricted properly based on patient-selected scope'
|
|
287
|
+
description %(
|
|
288
|
+
This test ensures that access to the Procedure is granted or
|
|
289
|
+
denied based on the selection by the tester prior to the execution of
|
|
290
|
+
the test. If the tester indicated that access will be granted to this
|
|
291
|
+
resource, this test verifies that a search by patient in this resource
|
|
292
|
+
does not result in an access denied result. If the tester indicated that
|
|
293
|
+
access will be denied for this resource, this verifies that search by
|
|
294
|
+
patient in the resource results in an access denied result.
|
|
295
|
+
)
|
|
296
|
+
id :g10_procedure_restricted_access
|
|
297
|
+
|
|
298
|
+
def resource_group
|
|
299
|
+
USCoreTestKit::ProcedureGroup
|
|
300
|
+
end
|
|
301
|
+
end
|
|
302
|
+
end
|
|
303
|
+
end
|