onc_certification_g10_test_kit 2.0.0 → 2.1.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 +4 -4
- data/lib/inferno/terminology/tasks/check_built_terminology.rb +14 -12
- data/lib/onc_certification_g10_test_kit/bulk_data_authorization.rb +7 -4
- data/lib/onc_certification_g10_test_kit/bulk_data_group_export.rb +60 -17
- data/lib/onc_certification_g10_test_kit/bulk_data_group_export_validation.rb +10 -6
- data/lib/onc_certification_g10_test_kit/bulk_export_validation_tester.rb +37 -16
- data/lib/onc_certification_g10_test_kit/configuration_checker.rb +6 -5
- data/lib/onc_certification_g10_test_kit/multi_patient_api.rb +11 -0
- data/lib/onc_certification_g10_test_kit/onc_program_procedure.yml +1451 -0
- data/lib/onc_certification_g10_test_kit/profile_guesser.rb +2 -2
- data/lib/onc_certification_g10_test_kit/restricted_resource_type_access_group.rb +13 -13
- data/lib/onc_certification_g10_test_kit/single_patient_api_group.rb +89 -0
- data/lib/onc_certification_g10_test_kit/smart_app_launch_invalid_aud_group.rb +13 -12
- data/lib/onc_certification_g10_test_kit/smart_ehr_practitioner_app_group.rb +11 -5
- data/lib/onc_certification_g10_test_kit/smart_invalid_launch_group.rb +13 -16
- data/lib/onc_certification_g10_test_kit/smart_invalid_token_group.rb +11 -4
- data/lib/onc_certification_g10_test_kit/smart_limited_app_group.rb +18 -4
- data/lib/onc_certification_g10_test_kit/smart_public_standalone_launch_group.rb +15 -3
- data/lib/onc_certification_g10_test_kit/smart_standalone_patient_app_group.rb +8 -3
- data/lib/onc_certification_g10_test_kit/tasks/generate_matrix.rb +243 -0
- data/lib/onc_certification_g10_test_kit/tasks/test_procedure.rb +65 -0
- data/lib/onc_certification_g10_test_kit/token_revocation_group.rb +60 -60
- data/lib/onc_certification_g10_test_kit/unrestricted_resource_type_access_group.rb +13 -13
- data/lib/onc_certification_g10_test_kit/version.rb +1 -1
- data/lib/onc_certification_g10_test_kit/visual_inspection_and_attestations_group.rb +7 -6
- data/lib/onc_certification_g10_test_kit.rb +15 -82
- metadata +16 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 136583ee432ecaa86193ce86c3e09ba9c3fd69cd745d6663243a8fc4b0ab2071
|
4
|
+
data.tar.gz: b914f640ba8c3c577d1d531952944027fec53582f6faa22efedbb62d5fe018a7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6e0b7538709edc9dc43a3069197df5550ba403193d12dea576851fba09b472679c3475f9d47e3d3f6496d6c8dd35c20981fe46f968824919b1dce7e3ae4c0032
|
7
|
+
data.tar.gz: 18ad6fce7e21583ef641a74765a58ffdccc559a5a8b70038330368c6bbafe29584a5204cc36bbc1bb62122aea2b89c321b9fa76865ccd768355e6df7e03f091a
|
@@ -4,9 +4,11 @@ module Inferno
|
|
4
4
|
module Terminology
|
5
5
|
module Tasks
|
6
6
|
class CheckBuiltTerminology
|
7
|
-
|
7
|
+
NON_UMLS_SYSTEMS = [
|
8
8
|
'http://hl7.org/fhir/ValueSet/mimetypes',
|
9
|
-
'urn:ietf:bcp:13'
|
9
|
+
'urn:ietf:bcp:13',
|
10
|
+
'http://hl7.org/fhir/us/core/ValueSet/simple-language',
|
11
|
+
'urn:ietf:bcp:47'
|
10
12
|
].freeze
|
11
13
|
|
12
14
|
def run
|
@@ -15,16 +17,16 @@ module Inferno
|
|
15
17
|
return
|
16
18
|
end
|
17
19
|
|
18
|
-
if
|
19
|
-
Inferno.logger.info <<~
|
20
|
+
if only_non_umls_mismatch?
|
21
|
+
Inferno.logger.info <<~NON_UMLS
|
20
22
|
Terminology built successfully.
|
21
23
|
|
22
|
-
|
23
|
-
result of
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
24
|
+
Some terminology not based on UMLS did not match, but this can be
|
25
|
+
a result of these terminologies having a different update schedule
|
26
|
+
than UMLS. As long as the actual number of codes is close to the
|
27
|
+
expected number, this does not does not reflect a problem with the
|
28
|
+
terminology build.
|
29
|
+
NON_UMLS
|
28
30
|
else
|
29
31
|
Inferno.logger.info 'Terminology build results different than expected.'
|
30
32
|
end
|
@@ -61,8 +63,8 @@ module Inferno
|
|
61
63
|
new_manifest.find { |value_set| value_set[:url] == url }
|
62
64
|
end
|
63
65
|
|
64
|
-
def
|
65
|
-
mismatched_value_sets.all? { |value_set|
|
66
|
+
def only_non_umls_mismatch?
|
67
|
+
mismatched_value_sets.all? { |value_set| NON_UMLS_SYSTEMS.include? value_set[:url] }
|
66
68
|
end
|
67
69
|
|
68
70
|
def mismatched_value_set_message(expected_value_set)
|
@@ -21,8 +21,9 @@ module ONCCertificationG10TestKit
|
|
21
21
|
|
22
22
|
input :bulk_token_endpoint,
|
23
23
|
title: 'Backend Services Token Endpoint',
|
24
|
-
description:
|
25
|
-
|
24
|
+
description: <<~DESCRIPTION
|
25
|
+
The OAuth 2.0 Token Endpoint used by the Backend Services specification to provide bearer tokens.
|
26
|
+
DESCRIPTION
|
26
27
|
input :bulk_client_id,
|
27
28
|
title: 'Bulk Data Client ID',
|
28
29
|
description: 'Client ID provided at registration to the Inferno application.'
|
@@ -32,8 +33,10 @@ module ONCCertificationG10TestKit
|
|
32
33
|
default: 'system/*.read'
|
33
34
|
input :bulk_encryption_method,
|
34
35
|
title: 'Encryption Method',
|
35
|
-
description:
|
36
|
-
|
36
|
+
description: <<~DESCRIPTION,
|
37
|
+
The server is required to suport either ES384 or RS384 encryption methods for JWT signature verification.
|
38
|
+
Select which method to use.
|
39
|
+
DESCRIPTION
|
37
40
|
type: 'radio',
|
38
41
|
default: 'ES384',
|
39
42
|
options: {
|
@@ -19,11 +19,12 @@ module ONCCertificationG10TestKit
|
|
19
19
|
description: 'The Group ID associated with the group of patients to be exported.'
|
20
20
|
input :bulk_timeout,
|
21
21
|
title: 'Export Times Out after (1-600)',
|
22
|
-
description:
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
22
|
+
description: <<~DESCRIPTION,
|
23
|
+
While testing, Inferno waits for the server to complete the exporting task. If the calculated totalTime is
|
24
|
+
greater than the timeout value specified here, Inferno bulk client stops testing. Please enter an integer
|
25
|
+
for the maximum wait time in seconds. If timeout is less than 1, Inferno uses default value 180. If the
|
26
|
+
timeout is greater than 600 (10 minutes), Inferno uses the maximum value 600.
|
27
|
+
DESCRIPTION
|
27
28
|
default: 180
|
28
29
|
|
29
30
|
output :requires_access_token, :status_output, :bulk_download_url
|
@@ -56,9 +57,30 @@ module ONCCertificationG10TestKit
|
|
56
57
|
test do
|
57
58
|
title 'Bulk Data Server declares support for Group export operation in CapabilityStatement'
|
58
59
|
description <<~DESCRIPTION
|
59
|
-
|
60
|
+
This test verifies that the Bulk Data Server declares support for
|
61
|
+
Group/[id]/$export operation in its server CapabilityStatement.
|
62
|
+
|
63
|
+
Given flexibility in the FHIR specification for declaring constrained
|
64
|
+
OperationDefinitions, this test only verifies that the server declares
|
65
|
+
any operation on the Group resource. It does not verify that it
|
66
|
+
declares the standard group export OperationDefinition provided in the
|
67
|
+
Bulk Data specification, nor does it attempt to resolve any non-standard
|
68
|
+
OperationDefinitions to verify if it is a constrained version of the
|
69
|
+
standard OperationDefintion.
|
70
|
+
|
71
|
+
This test will provide a warning if no operations are declared at
|
72
|
+
`Group/[id]/$export`, via the
|
73
|
+
`CapabilityStatement.rest.resource.operation.name` element. It will
|
74
|
+
also provide an informational message if an operation on the Group
|
75
|
+
resource exists, but does not point to the standard OperationDefinition
|
76
|
+
canonical URL:
|
77
|
+
http://hl7.org/fhir/uv/bulkdata/OperationDefinition/group-export
|
78
|
+
|
79
|
+
Additionally, this test provides a warning if the bulk data server does
|
80
|
+
not include the following URL in its `CapabilityStatement.instantiates`
|
81
|
+
element: http://hl7.org/fhir/uv/bulkdata/CapabilityStatement/bulk-data
|
82
|
+
|
60
83
|
DESCRIPTION
|
61
|
-
# link 'http://hl7.org/fhir/uv/bulkdata/STU1/OperationDefinition-group-export.html'
|
62
84
|
|
63
85
|
run do
|
64
86
|
fhir_get_capability_statement(client: :bulk_server)
|
@@ -67,18 +89,39 @@ module ONCCertificationG10TestKit
|
|
67
89
|
assert_valid_json(request.response_body)
|
68
90
|
capability_statement = FHIR.from_contents(request.response_body)
|
69
91
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
92
|
+
warning do
|
93
|
+
has_instantiates = capability_statement&.instantiates&.any? do |canonical|
|
94
|
+
canonical.match(%r{^http://hl7.org/fhir/uv/bulkdata/CapabilityStatement/bulk-data(\|\S+)?$})
|
95
|
+
end
|
96
|
+
assert has_instantiates,
|
97
|
+
'Server did not declare conformance to the Bulk Data IG by including ' \
|
98
|
+
"'http://hl7.org/fhir/uv/bulkdata/CapabilityStatement/bulk-data' in " \
|
99
|
+
" CapabilityStatement.instantiates element (#{capability_statement&.instantiates})"
|
100
|
+
end
|
101
|
+
|
102
|
+
group_resource_capabilities = nil
|
103
|
+
|
104
|
+
capability_statement&.rest&.each do |rest|
|
105
|
+
group_resource_capabilities = rest.resource&.find do |resource|
|
106
|
+
resource.type == 'Group'
|
77
107
|
end
|
78
108
|
end
|
79
109
|
|
80
|
-
assert
|
81
|
-
'Server CapabilityStatement did not declare support for
|
110
|
+
assert group_resource_capabilities.respond_to?(:operation) && group_resource_capabilities.operation&.any?,
|
111
|
+
'Server CapabilityStatement did not declare support for any operations on the Group resource'
|
112
|
+
|
113
|
+
has_export_operation = group_resource_capabilities.operation&.any? do |operation|
|
114
|
+
name_match = (operation.name == 'export')
|
115
|
+
if name_match && !operation.definition&.match(%r{^http://hl7.org/fhir/uv/bulkdata/OperationDefinition/group-export(\|\S+)?$})
|
116
|
+
info('Server CapabilityStatement does not include export operation with definition http://hl7.org/fhir/uv/bulkdata/OperationDefinition/group-export')
|
117
|
+
end
|
118
|
+
name_match
|
119
|
+
end
|
120
|
+
warning do
|
121
|
+
assert has_export_operation,
|
122
|
+
'Server CapabilityStatement did not declare support for an operation named "export" in the Group ' \
|
123
|
+
' resource (operation.name should be "export")'
|
124
|
+
end
|
82
125
|
end
|
83
126
|
end
|
84
127
|
|
@@ -161,7 +204,7 @@ module ONCCertificationG10TestKit
|
|
161
204
|
start = Time.now
|
162
205
|
|
163
206
|
loop do
|
164
|
-
get(polling_url, headers: { authorization: "Bearer #{bearer_token}" })
|
207
|
+
get(polling_url, headers: { authorization: "Bearer #{bearer_token}", accept: 'application/json' })
|
165
208
|
|
166
209
|
retry_after_val = request.response_header('retry-after')&.value.to_i
|
167
210
|
|
@@ -17,14 +17,18 @@ module ONCCertificationG10TestKit
|
|
17
17
|
optional: true
|
18
18
|
input :bulk_patient_ids_in_group,
|
19
19
|
title: 'Patient IDs in exported Group',
|
20
|
-
description:
|
21
|
-
|
22
|
-
|
20
|
+
description: <<~DESCRIPTION
|
21
|
+
Comma separated list of every Patient ID that is in the specified Group. This information is provided by
|
22
|
+
the system under test to verify that data returned matches expectations. Leave blank to not verify Group
|
23
|
+
inclusion.
|
24
|
+
DESCRIPTION
|
23
25
|
input :bulk_device_types_in_group,
|
24
26
|
title: 'Implantable Device Type Codes in exported Group',
|
25
|
-
description:
|
26
|
-
|
27
|
-
|
27
|
+
description: <<~DESCRIPTION,
|
28
|
+
Comma separated list of every Implantable Device type that is in the specified Group. This information is
|
29
|
+
provided by the system under test to verify that data returned matches expectations. Leave blank to verify
|
30
|
+
all Device resources against the Implantable Device profile.
|
31
|
+
DESCRIPTION
|
28
32
|
optional: true
|
29
33
|
|
30
34
|
test from: :tls_version_test do
|
@@ -13,23 +13,26 @@ module ONCCertificationG10TestKit
|
|
13
13
|
|
14
14
|
def observation_metadata
|
15
15
|
[
|
16
|
-
USCoreTestKit::PediatricBmiForAgeGroup.metadata,
|
17
|
-
USCoreTestKit::PediatricWeightForHeightGroup.metadata,
|
18
|
-
USCoreTestKit::ObservationLabGroup.metadata,
|
19
|
-
USCoreTestKit::PulseOximetryGroup.metadata,
|
20
|
-
USCoreTestKit::SmokingstatusGroup.metadata,
|
21
|
-
USCoreTestKit::HeadCircumferenceGroup.metadata,
|
22
|
-
USCoreTestKit::BpGroup.metadata,
|
23
|
-
USCoreTestKit::BodyheightGroup.metadata,
|
24
|
-
USCoreTestKit::BodytempGroup.metadata,
|
25
|
-
USCoreTestKit::BodyweightGroup.metadata,
|
26
|
-
USCoreTestKit::HeartrateGroup.metadata,
|
27
|
-
USCoreTestKit::ResprateGroup.metadata
|
16
|
+
USCoreTestKit::USCoreV311::PediatricBmiForAgeGroup.metadata,
|
17
|
+
USCoreTestKit::USCoreV311::PediatricWeightForHeightGroup.metadata,
|
18
|
+
USCoreTestKit::USCoreV311::ObservationLabGroup.metadata,
|
19
|
+
USCoreTestKit::USCoreV311::PulseOximetryGroup.metadata,
|
20
|
+
USCoreTestKit::USCoreV311::SmokingstatusGroup.metadata,
|
21
|
+
USCoreTestKit::USCoreV311::HeadCircumferenceGroup.metadata,
|
22
|
+
USCoreTestKit::USCoreV311::BpGroup.metadata,
|
23
|
+
USCoreTestKit::USCoreV311::BodyheightGroup.metadata,
|
24
|
+
USCoreTestKit::USCoreV311::BodytempGroup.metadata,
|
25
|
+
USCoreTestKit::USCoreV311::BodyweightGroup.metadata,
|
26
|
+
USCoreTestKit::USCoreV311::HeartrateGroup.metadata,
|
27
|
+
USCoreTestKit::USCoreV311::ResprateGroup.metadata
|
28
28
|
]
|
29
29
|
end
|
30
30
|
|
31
31
|
def diagnostic_metadata
|
32
|
-
[
|
32
|
+
[
|
33
|
+
USCoreTestKit::USCoreV311::DiagnosticReportLabGroup.metadata,
|
34
|
+
USCoreTestKit::USCoreV311::DiagnosticReportNoteGroup.metadata
|
35
|
+
]
|
33
36
|
end
|
34
37
|
|
35
38
|
def determine_metadata
|
@@ -37,11 +40,11 @@ module ONCCertificationG10TestKit
|
|
37
40
|
return diagnostic_metadata if resource_type == 'DiagnosticReport'
|
38
41
|
|
39
42
|
if resource_type == 'Location' || resource_type == 'Medication'
|
40
|
-
return Array.wrap(USCoreTestKit::USCoreTestSuite.metadata.find do |meta|
|
43
|
+
return Array.wrap(USCoreTestKit::USCoreV311::USCoreTestSuite.metadata.find do |meta|
|
41
44
|
meta.resource == resource_type
|
42
45
|
end)
|
43
46
|
end
|
44
|
-
["USCoreTestKit::#{resource_type}Group".constantize.metadata]
|
47
|
+
["USCoreTestKit::USCoreV311::#{resource_type}Group".constantize.metadata]
|
45
48
|
end
|
46
49
|
|
47
50
|
def metadata_list
|
@@ -58,7 +61,7 @@ module ONCCertificationG10TestKit
|
|
58
61
|
headers
|
59
62
|
end
|
60
63
|
|
61
|
-
def stream_ndjson(endpoint, headers, process_chunk_line, process_response)
|
64
|
+
def stream_ndjson(endpoint, headers, process_chunk_line, process_response) # rubocop:disable Metrics/CyclomaticComplexity
|
62
65
|
hanging_chunk = String.new
|
63
66
|
|
64
67
|
process_body = proc { |chunk|
|
@@ -74,6 +77,24 @@ module ONCCertificationG10TestKit
|
|
74
77
|
|
75
78
|
stream(process_body, endpoint, headers: headers)
|
76
79
|
|
80
|
+
max_redirect = 5
|
81
|
+
|
82
|
+
while [301, 302, 303, 307].include?(response[:status]) &&
|
83
|
+
request.response_header('location')&.value.present? &&
|
84
|
+
max_redirect.positive?
|
85
|
+
|
86
|
+
max_redirect -= 1
|
87
|
+
|
88
|
+
redirect_url = request.response_header('location')&.value
|
89
|
+
|
90
|
+
# handle relative redirects
|
91
|
+
redirect_url = URI.parse(endpoint).merge(redirect_url).to_s unless redirect_url.start_with?('http')
|
92
|
+
|
93
|
+
redirect_headers = headers.reject { |key, _value| key == :authorization }
|
94
|
+
|
95
|
+
stream(process_body, redirect_url, headers: redirect_headers)
|
96
|
+
end
|
97
|
+
|
77
98
|
process_chunk_line.call(hanging_chunk)
|
78
99
|
process_response.call(response)
|
79
100
|
end
|
@@ -55,7 +55,7 @@ module ONCCertificationG10TestKit
|
|
55
55
|
success_messages << "* `#{url}`: #{actual_value_set[:count]} codes"
|
56
56
|
elsif actual_value_set.nil?
|
57
57
|
error_messages << "* `#{url}`: Not loaded"
|
58
|
-
elsif terminology_checker.class::
|
58
|
+
elsif terminology_checker.class::NON_UMLS_SYSTEMS.include? url
|
59
59
|
warning_messages <<
|
60
60
|
"* `#{url}`: Expected codes: #{expected_value_set[:count]} Actual codes: #{actual_value_set[:count]}"
|
61
61
|
else
|
@@ -74,10 +74,11 @@ module ONCCertificationG10TestKit
|
|
74
74
|
|
75
75
|
if warning_messages.present?
|
76
76
|
warning_message = <<~WARNING
|
77
|
-
|
78
|
-
result of
|
79
|
-
|
80
|
-
|
77
|
+
Some terminology not based on UMLS did not match, but this can be a
|
78
|
+
result of these terminologies having a different update schedule than
|
79
|
+
UMLS. As long as the actual number of codes is close to the expected
|
80
|
+
number, this does not does not reflect a problem with the terminology
|
81
|
+
build.
|
81
82
|
WARNING
|
82
83
|
messages << {
|
83
84
|
type: 'warning',
|
@@ -36,6 +36,17 @@ module ONCCertificationG10TestKit
|
|
36
36
|
id :multi_patient_api
|
37
37
|
run_as_group
|
38
38
|
|
39
|
+
input_order :bulk_server_url,
|
40
|
+
:bulk_token_endpoint,
|
41
|
+
:bulk_client_id,
|
42
|
+
:bulk_scope,
|
43
|
+
:bulk_encryption_method,
|
44
|
+
:group_id,
|
45
|
+
:bulk_patient_ids_in_group,
|
46
|
+
:bulk_device_types_in_group,
|
47
|
+
:lines_to_validate,
|
48
|
+
:bulk_timeout
|
49
|
+
|
39
50
|
group from: :bulk_data_authorization
|
40
51
|
group from: :bulk_data_group_export
|
41
52
|
group from: :bulk_data_group_export_validation
|