davinci_pdex_test_kit 0.12.0 → 0.12.2
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/pdex_payer_client_postman_preset.json.erb +67 -0
- data/lib/davinci_pdex_test_kit/docs/payer_client_suite_description_v200.md +124 -32
- data/lib/davinci_pdex_test_kit/pdex_payer_client/client_auth_smart_alca_group.rb +32 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/client_auth_smart_alcs_group.rb +32 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/client_auth_smart_alp_group.rb +32 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/client_auth_udap_group.rb +31 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/client_member_match_tests/client_member_match_validation_test.rb +0 -1
- data/lib/davinci_pdex_test_kit/pdex_payer_client/client_registration/configuration_display_smart_test.rb +38 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/client_registration/configuration_display_udap_test.rb +38 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/client_registration_group.rb +67 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/client_validation_test.rb +10 -2
- data/lib/davinci_pdex_test_kit/pdex_payer_client/client_workflow_interaction_test.rb +37 -7
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/allergyintolerance_clinical_data_request_test.rb +0 -1
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/careplan_clinical_data_request_test.rb +0 -1
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/careteam_clinical_data_request_test.rb +0 -1
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/condition_clinical_data_request_test.rb +0 -1
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/device_clinical_data_request_test.rb +1 -2
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/diagnosticreport_clinical_data_request_test.rb +0 -1
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/documentreference_clinical_data_request_test.rb +0 -1
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/encounter_clinical_data_request_test.rb +0 -1
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/explanationofbenefit_clinical_data_request_test.rb +0 -1
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/goal_clinical_data_request_test.rb +0 -1
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/immunization_clinical_data_request_test.rb +0 -1
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/location_clinical_data_request_test.rb +0 -1
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/medicationdispense_clinical_data_request_test.rb +0 -1
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/medicationrequest_clinical_data_request_test.rb +0 -1
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/observation_clinical_data_request_test.rb +0 -1
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/organization_clinical_data_request_test.rb +0 -1
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/patient_clinical_data_request_test.rb +0 -1
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/practitioner_clinical_data_request_test.rb +0 -1
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/practitionerrole_clinical_data_request_test.rb +0 -1
- data/lib/davinci_pdex_test_kit/pdex_payer_client/clinical_data_request_tests/procedure_clinical_data_request_test.rb +0 -1
- data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server/export_endpoint.rb +1 -1
- data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server/export_status_endpoint.rb +1 -1
- data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server/next_page_endpoint.rb +9 -2
- data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server/patient_endpoint.rb +1 -1
- data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server/proxy_endpoint.rb +15 -6
- data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server/resource_read_endpoint.rb +1 -1
- data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server/resource_search_endpoint.rb +1 -1
- data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server.rb +28 -2
- data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_udap_smart_server/authorization_endpoint.rb +53 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_udap_smart_server/token_endpoint.rb +85 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/pdex_client_options.rb +26 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/tags.rb +8 -9
- data/lib/davinci_pdex_test_kit/pdex_payer_client/urls.rb +17 -9
- data/lib/davinci_pdex_test_kit/pdex_payer_client/visual_inspection_and_attestation/authentication.rb +34 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/visual_inspection_and_attestation/must_support.rb +40 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/visual_inspection_and_attestation/provenance.rb +32 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/visual_inspection_and_attestation/receive_must_support.rb +34 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client/visual_inspection_and_attestation.rb +24 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_client_suite.rb +65 -2
- data/lib/davinci_pdex_test_kit/pdex_payer_server/urls.rb +27 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server/visual_inspection_and_attestation/bulk_data_transmission_restrictions.rb +33 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server/visual_inspection_and_attestation/consent_failure.rb +40 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server/visual_inspection_and_attestation/consent_requirements.rb +40 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server/visual_inspection_and_attestation/hrex_must_support.rb +35 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server/visual_inspection_and_attestation/licensing.rb +37 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server/visual_inspection_and_attestation/member_auth.rb +81 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server/visual_inspection_and_attestation/mtls.rb +61 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server/visual_inspection_and_attestation/payer_consent_compliance.rb +33 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server/visual_inspection_and_attestation/prior_authorization_decisions.rb +35 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server/visual_inspection_and_attestation/provenance_records.rb +40 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server/visual_inspection_and_attestation/read_and_search_hrex.rb +35 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server/visual_inspection_and_attestation/resources_in_capability_statement.rb +35 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server/visual_inspection_and_attestation.rb +39 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server/workflow_export_group.rb +2 -0
- data/lib/davinci_pdex_test_kit/pdex_payer_server_suite.rb +29 -3
- data/lib/davinci_pdex_test_kit/pdex_provider_client_suite.rb +8 -0
- data/lib/davinci_pdex_test_kit/requirements/davinci_pdex_test_kit_requirements.csv +115 -0
- data/lib/davinci_pdex_test_kit/requirements/generated/pdex_payer_client_requirements_coverage.csv +29 -0
- data/lib/davinci_pdex_test_kit/requirements/generated/pdex_payer_server_requirements_coverage.csv +479 -0
- data/lib/davinci_pdex_test_kit/requirements/hl7.fhir.us.davinci-pdex_2.0.0_reqs.xlsx +0 -0
- data/lib/davinci_pdex_test_kit/version.rb +2 -2
- data/lib/davinci_pdex_test_kit.rb +0 -1
- metadata +70 -17
- data/config/presets/pdex_payer_client_postman_preset.json +0 -12
- data/lib/davinci_pdex_test_kit/pdex_payer_client/mock_server/token_endpoint.rb +0 -27
- data/lib/davinci_pdex_test_kit/requirements/davinci-pdex-test-kit_out_of_scope_requirements.csv +0 -1
- data/lib/davinci_pdex_test_kit/requirements/davinci-pdex-test-kit_requirements.csv +0 -64
- data/lib/davinci_pdex_test_kit/requirements/generated/davinci-pdex-test-kit_requirements_coverage.csv +0 -64
- data/lib/inferno_requirements_tools/ext/inferno_core/runnable.rb +0 -22
- data/lib/inferno_requirements_tools/rake/rakefile_template +0 -19
- data/lib/inferno_requirements_tools/tasks/requirements_coverage.rb +0 -284
- data/lib/requirements_config.yaml +0 -17
@@ -4,12 +4,10 @@ module DaVinciPDexTestKit
|
|
4
4
|
module PDexPayerClient
|
5
5
|
|
6
6
|
module URLs
|
7
|
-
BASE_PATH = "#{Inferno::Application['base_url']}/custom/pdex_payer_client"
|
8
|
-
TOKEN_PATH = '/mock_auth/token'
|
9
7
|
PATIENT_PATH = '/fhir/Patient'
|
8
|
+
PATIENT_INSTANCE_PATH = '/fhir/Patient/:patient'
|
10
9
|
RESOURCE_PATH = '/fhir/:endpoint'
|
11
10
|
INSTANCE_PATH = '/fhir/:endpoint/:id'
|
12
|
-
SUBMIT_PATH = '/fhir/:endpoint' # FIXME duplicate
|
13
11
|
BINARY_PATH = '/fhir/Binary/:id'
|
14
12
|
METADATA_PATH = '/fhir/metadata'
|
15
13
|
EVERYTHING_PATH = '/fhir/Patient/:patient/$everything'
|
@@ -19,7 +17,9 @@ module DaVinciPDexTestKit
|
|
19
17
|
BASE_FHIR_PATH = '/fhir'
|
20
18
|
RESUME_PASS_PATH = '/resume_pass'
|
21
19
|
RESUME_CLINICAL_DATA_PATH = '/resume_clinical_data'
|
22
|
-
RESUME_FAIL_PATH = '/resume_fail'
|
20
|
+
RESUME_FAIL_PATH = '/resume_fail'
|
21
|
+
AUTHORIZATION_PATH = '/auth/authorization'
|
22
|
+
TOKEN_PATH = '/auth/token'
|
23
23
|
|
24
24
|
constants.each do |path_constant|
|
25
25
|
# For each constant X_PATH, define x_path()
|
@@ -29,20 +29,28 @@ module DaVinciPDexTestKit
|
|
29
29
|
|
30
30
|
# For each constant X_PATH, define x_url(), which includes base
|
31
31
|
define_method(path_constant.to_s.downcase.gsub(/_path$/, '_url')) do
|
32
|
-
|
32
|
+
base_url + URLs.const_get(path_constant)
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
+
def suite_id
|
37
|
+
PDexPayerClientSuite.id
|
38
|
+
end
|
39
|
+
|
36
40
|
# overwrite base_url which is irregular
|
37
41
|
def base_url
|
38
|
-
|
42
|
+
@base_url ||= "#{Inferno::Application['base_url']}/custom/#{suite_id}"
|
39
43
|
end
|
40
44
|
|
41
|
-
# overwrite
|
42
|
-
def
|
43
|
-
|
45
|
+
# overwrite fhir_base_url which is irregular
|
46
|
+
def fhir_base_url
|
47
|
+
base_url + BASE_FHIR_PATH
|
44
48
|
end
|
45
49
|
|
50
|
+
# alias for smart and udap tests
|
51
|
+
def client_fhir_base_url
|
52
|
+
fhir_base_url
|
53
|
+
end
|
46
54
|
end
|
47
55
|
|
48
56
|
# Add all constants and dynamically defined methods to PDexPayerClient namespace
|
data/lib/davinci_pdex_test_kit/pdex_payer_client/visual_inspection_and_attestation/authentication.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
module DaVinciPDexTestKit
|
2
|
+
module PDexPayerClient
|
3
|
+
class PDexMemberAuthenticationTest < Inferno::Test
|
4
|
+
title 'Uses recognized Health Plan credentials'
|
5
|
+
|
6
|
+
description <<~DESCRIPTION
|
7
|
+
The Health IT Module requires members to authenticate
|
8
|
+
using credentials issued or recognized by the Health Plan, such as credentials used to access
|
9
|
+
a member portal, and accepts only those credentials when processing member-authorized requests.
|
10
|
+
DESCRIPTION
|
11
|
+
|
12
|
+
id :pdex_member_authentication_test
|
13
|
+
|
14
|
+
verifies_requirements 'hl7.fhir.us.davinci-pdex_2.0.0@10'
|
15
|
+
|
16
|
+
run do
|
17
|
+
identifier = SecureRandom.hex(32)
|
18
|
+
|
19
|
+
wait(
|
20
|
+
identifier:,
|
21
|
+
message: <<~MESSAGE
|
22
|
+
I attest that the Health IT Module requires members to authenticate
|
23
|
+
using credentials issued or recognized by the Health Plan, such as credentials used to access
|
24
|
+
a member portal, and accepts only those credentials when processing member-authorized requests.
|
25
|
+
|
26
|
+
[Click here](#{resume_pass_url}?token=#{identifier}) if the system **meets** this requirement.
|
27
|
+
|
28
|
+
[Click here](#{resume_fail_url}?token=#{identifier}) if the system **does not meet** this requirement.
|
29
|
+
MESSAGE
|
30
|
+
)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/davinci_pdex_test_kit/pdex_payer_client/visual_inspection_and_attestation/must_support.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
module DaVinciPDexTestKit
|
2
|
+
module PDexPayerClient
|
3
|
+
class PDexClientMustSupportInterpretationTest < Inferno::Test
|
4
|
+
title 'Interprets Must Support according to US Core and HRex'
|
5
|
+
|
6
|
+
description <<~DESCRIPTION
|
7
|
+
The Health IT Module applies Must Support rules for all profiles it implements as follows:
|
8
|
+
|
9
|
+
- For US Core profiles, Must Support elements are interpreted according to the US Core IG.
|
10
|
+
- For HRex profiles, Must Support elements are interpreted according to the HRex IG.
|
11
|
+
- For PDex profiles, Must Support elements are interpreted according to the US Core IG.
|
12
|
+
DESCRIPTION
|
13
|
+
|
14
|
+
id :pdex_client_must_support_interpretation_test
|
15
|
+
|
16
|
+
verifies_requirements 'hl7.fhir.us.davinci-pdex_2.0.0@4',
|
17
|
+
'hl7.fhir.us.davinci-pdex_2.0.0@6',
|
18
|
+
'hl7.fhir.us.davinci-pdex_2.0.0@8'
|
19
|
+
|
20
|
+
run do
|
21
|
+
identifier = SecureRandom.hex(32)
|
22
|
+
|
23
|
+
wait(
|
24
|
+
identifier:,
|
25
|
+
message: <<~MESSAGE
|
26
|
+
The developer of the Health IT Module attests that:
|
27
|
+
|
28
|
+
- For US Core profiles, Must Support elements are interpreted according to the US Core IG.
|
29
|
+
- For HRex profiles, Must Support elements are interpreted according to the HRex IG.
|
30
|
+
- For PDex profiles, Must Support elements are interpreted according to the US Core IG.
|
31
|
+
|
32
|
+
[Click here](#{resume_pass_url}?token=#{identifier}) if the system **meets** these requirements.
|
33
|
+
|
34
|
+
[Click here](#{resume_fail_url}?token=#{identifier}) if the system **does not meet** these requirements.
|
35
|
+
MESSAGE
|
36
|
+
)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/davinci_pdex_test_kit/pdex_payer_client/visual_inspection_and_attestation/provenance.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
module DaVinciPDexTestKit
|
2
|
+
module PDexPayerClient
|
3
|
+
class PDexRetainProvenanceFromPayerExchangeTest < Inferno::Test
|
4
|
+
title 'Accepts and retains Provenance in member-authorized payer-to-payer exchange'
|
5
|
+
|
6
|
+
description <<~DESCRIPTION
|
7
|
+
The Health IT Module accepts and retains
|
8
|
+
Provenance records received with data as part of a member-authorized payer-to-payer exchange.
|
9
|
+
DESCRIPTION
|
10
|
+
|
11
|
+
id :pdex_accept_retain_provenance_test
|
12
|
+
|
13
|
+
verifies_requirements 'hl7.fhir.us.davinci-pdex_2.0.0@28'
|
14
|
+
|
15
|
+
run do
|
16
|
+
identifier = SecureRandom.hex(32)
|
17
|
+
|
18
|
+
wait(
|
19
|
+
identifier:,
|
20
|
+
message: <<~MESSAGE
|
21
|
+
I attest that the Health IT Module accepts and retains
|
22
|
+
Provenance records received with data as part of a member-authorized payer-to-payer exchange.
|
23
|
+
|
24
|
+
[Click here](#{resume_pass_url}?token=#{identifier}) if the system **meets** this requirement.
|
25
|
+
|
26
|
+
[Click here](#{resume_fail_url}?token=#{identifier}) if the system **does not meet** this requirement.
|
27
|
+
MESSAGE
|
28
|
+
)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module DaVinciPDexTestKit
|
2
|
+
module PDexPayerClient
|
3
|
+
class PDexMustSupportSubElementHandlingTest < Inferno::Test
|
4
|
+
title 'Accepts Must Support elements without error'
|
5
|
+
|
6
|
+
description <<~DESCRIPTION
|
7
|
+
The Health IT Module ensures that it can accept sub-elements marked Must Support
|
8
|
+
without generating errors — unless those sub-elements belong to a parent element
|
9
|
+
that has a minimum cardinality of 0 and no Must Support flag.
|
10
|
+
DESCRIPTION
|
11
|
+
|
12
|
+
id :pdex_must_support_sub_element_handling_test
|
13
|
+
|
14
|
+
verifies_requirements 'hl7.fhir.us.davinci-pdex_2.0.0@53'
|
15
|
+
|
16
|
+
run do
|
17
|
+
identifier = SecureRandom.hex(32)
|
18
|
+
|
19
|
+
wait(
|
20
|
+
identifier:,
|
21
|
+
message: <<~MESSAGE
|
22
|
+
The developer of the Health IT Module attests that the Health IT System can accept sub-elements marked Must Support
|
23
|
+
without generating errors — unless those sub-elements belong to a parent element
|
24
|
+
that has a minimum cardinality of 0 and no Must Support flag.
|
25
|
+
|
26
|
+
[Click here](#{resume_pass_url}?token=#{identifier}) if the system **meets** this requirement.
|
27
|
+
|
28
|
+
[Click here](#{resume_fail_url}?token=#{identifier}) if the system **does not meet** this requirement.
|
29
|
+
MESSAGE
|
30
|
+
)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require_relative 'visual_inspection_and_attestation/must_support'
|
2
|
+
require_relative 'visual_inspection_and_attestation/receive_must_support'
|
3
|
+
require_relative 'visual_inspection_and_attestation/provenance'
|
4
|
+
require_relative 'visual_inspection_and_attestation/authentication'
|
5
|
+
|
6
|
+
module DaVinciPDexTestKit
|
7
|
+
module PDexPayerClient
|
8
|
+
class PDexClientVisualInspectionAndAttestationGroup < Inferno::TestGroup
|
9
|
+
id :pdex_client_visual_inspection_and_attestation
|
10
|
+
title 'Visual Inspection and Attestation'
|
11
|
+
|
12
|
+
description <<~DESCRIPTION
|
13
|
+
Perform visual inspections or attestations to ensure that the Client is conformant to the Da Vinci Payer Data Exchange IG requirements.
|
14
|
+
DESCRIPTION
|
15
|
+
|
16
|
+
run_as_group
|
17
|
+
|
18
|
+
test from: :pdex_member_authentication_test
|
19
|
+
test from: :pdex_client_must_support_interpretation_test
|
20
|
+
test from: :pdex_must_support_sub_element_handling_test
|
21
|
+
test from: :pdex_accept_retain_provenance_test
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require_relative 'pdex_payer_client/pdex_client_options'
|
1
2
|
require_relative 'pdex_payer_client/urls'
|
2
3
|
require_relative 'pdex_payer_client/tags'
|
3
4
|
require_relative 'pdex_payer_client/collection'
|
@@ -5,6 +6,11 @@ require_relative 'pdex_payer_client/mock_server'
|
|
5
6
|
# require_relative 'must_support_test'
|
6
7
|
# require_relative 'pdex_payer_client/client_validation_test'
|
7
8
|
|
9
|
+
require_relative 'pdex_payer_client/client_registration_group'
|
10
|
+
require_relative 'pdex_payer_client/client_auth_smart_alca_group'
|
11
|
+
require_relative 'pdex_payer_client/client_auth_smart_alcs_group'
|
12
|
+
require_relative 'pdex_payer_client/client_auth_smart_alp_group'
|
13
|
+
require_relative 'pdex_payer_client/client_auth_udap_group'
|
8
14
|
require_relative 'pdex_payer_client/client_workflow_interaction_test'
|
9
15
|
require_relative 'pdex_payer_client/client_member_match_tests/client_member_match_validation_test'
|
10
16
|
|
@@ -31,6 +37,8 @@ require_relative 'pdex_payer_client/clinical_data_request_tests/practitioner_cli
|
|
31
37
|
require_relative 'pdex_payer_client/clinical_data_request_tests/practitionerrole_clinical_data_request_test'
|
32
38
|
require_relative 'pdex_payer_client/clinical_data_request_tests/procedure_clinical_data_request_test'
|
33
39
|
|
40
|
+
require_relative 'pdex_payer_client/visual_inspection_and_attestation'
|
41
|
+
|
34
42
|
module DaVinciPDexTestKit
|
35
43
|
class PDexPayerClientSuite < Inferno::TestSuite
|
36
44
|
include PDexPayerClient
|
@@ -70,6 +78,35 @@ module DaVinciPDexTestKit
|
|
70
78
|
end
|
71
79
|
end
|
72
80
|
|
81
|
+
requirement_sets(
|
82
|
+
{
|
83
|
+
identifier: 'hl7.fhir.us.davinci-pdex_2.0.0',
|
84
|
+
title: 'Da Vinci Payer Data Exchange (PDex) v2.0.0',
|
85
|
+
actor: 'Client'
|
86
|
+
}
|
87
|
+
)
|
88
|
+
|
89
|
+
suite_option :client_type,
|
90
|
+
title: 'Client Security Type',
|
91
|
+
list_options: [
|
92
|
+
{
|
93
|
+
label: 'SMART App Launch Public Client',
|
94
|
+
value: PDexClientOptions::SMART_APP_LAUNCH_PUBLIC
|
95
|
+
},
|
96
|
+
{
|
97
|
+
label: 'SMART App Launch Confidential Symmetric Client',
|
98
|
+
value: PDexClientOptions::SMART_APP_LAUNCH_CONFIDENTIAL_SYMMETRIC
|
99
|
+
},
|
100
|
+
{
|
101
|
+
label: 'SMART App Launch Confidential Asymmetric Client',
|
102
|
+
value: PDexClientOptions::SMART_APP_LAUNCH_CONFIDENTIAL_ASYMMETRIC
|
103
|
+
},
|
104
|
+
{
|
105
|
+
label: 'UDAP Authorization Code Client',
|
106
|
+
value: PDexClientOptions::UDAP_AUTHORIZATION_CODE
|
107
|
+
}
|
108
|
+
]
|
109
|
+
|
73
110
|
resume_test_route :get, RESUME_PASS_PATH do |request|
|
74
111
|
PDexPayerClientSuite.extract_token_from_query_params(request)
|
75
112
|
end
|
@@ -82,18 +119,37 @@ module DaVinciPDexTestKit
|
|
82
119
|
PDexPayerClientSuite.extract_token_from_query_params(request)
|
83
120
|
end
|
84
121
|
|
122
|
+
group from: :pdex_client_registration
|
123
|
+
|
85
124
|
group do
|
86
125
|
run_as_group
|
87
|
-
title '
|
126
|
+
title 'Verify PDex Data Access'
|
88
127
|
id :payer_to_payer_workflow
|
89
128
|
|
90
129
|
group do
|
91
130
|
title 'Interaction Tests'
|
92
|
-
id :
|
131
|
+
id :pdex_client_workflow_interaction
|
93
132
|
|
94
133
|
test from: :pdex_client_workflow_interaction
|
95
134
|
end
|
96
135
|
|
136
|
+
group from: :pdex_client_auth_smart_alca,
|
137
|
+
required_suite_options: {
|
138
|
+
client_type: PDexClientOptions::SMART_APP_LAUNCH_CONFIDENTIAL_ASYMMETRIC
|
139
|
+
}
|
140
|
+
group from: :pdex_client_auth_smart_alcs,
|
141
|
+
required_suite_options: {
|
142
|
+
client_type: PDexClientOptions::SMART_APP_LAUNCH_CONFIDENTIAL_SYMMETRIC
|
143
|
+
}
|
144
|
+
group from: :pdex_client_auth_smart_alp,
|
145
|
+
required_suite_options: {
|
146
|
+
client_type: PDexClientOptions::SMART_APP_LAUNCH_PUBLIC
|
147
|
+
}
|
148
|
+
group from: :pdex_client_auth_udap,
|
149
|
+
required_suite_options: {
|
150
|
+
client_type: PDexClientOptions::UDAP_AUTHORIZATION_CODE
|
151
|
+
}
|
152
|
+
|
97
153
|
group do
|
98
154
|
title '$member-match validation'
|
99
155
|
id :member_match_validation
|
@@ -130,8 +186,15 @@ module DaVinciPDexTestKit
|
|
130
186
|
end
|
131
187
|
end
|
132
188
|
|
189
|
+
group from: :pdex_client_visual_inspection_and_attestation do
|
190
|
+
optional
|
191
|
+
end
|
192
|
+
|
193
|
+
|
133
194
|
# TODO: must support validation
|
134
195
|
|
196
|
+
|
197
|
+
|
135
198
|
private
|
136
199
|
|
137
200
|
def self.extract_token_from_query_params(request)
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DaVinciPDexTestKit
|
4
|
+
module PDexPayerServer
|
5
|
+
RESUME_PASS_PATH = '/resume_pass'
|
6
|
+
RESUME_FAIL_PATH = '/resume_fail'
|
7
|
+
|
8
|
+
# URLs
|
9
|
+
module URLs
|
10
|
+
def base_url
|
11
|
+
@base_url ||= "#{Inferno::Application['base_url']}/custom/#{suite_id}"
|
12
|
+
end
|
13
|
+
|
14
|
+
def resume_pass_url
|
15
|
+
@resume_pass_url ||= base_url + RESUME_PASS_PATH
|
16
|
+
end
|
17
|
+
|
18
|
+
def resume_fail_url
|
19
|
+
@resume_fail_url ||= base_url + RESUME_FAIL_PATH
|
20
|
+
end
|
21
|
+
|
22
|
+
def suite_id
|
23
|
+
PDexPayerServerSuite.id
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require_relative '../urls'
|
2
|
+
|
3
|
+
module DaVinciPDexTestKit
|
4
|
+
class BulkDataTransmissionRestrictionsTest < Inferno::Test
|
5
|
+
include PDexPayerServer::URLs
|
6
|
+
|
7
|
+
title 'Properly restricts Bulk Data transmission of individual member data'
|
8
|
+
|
9
|
+
description <<~DESCRIPTION
|
10
|
+
The Health IT Module's use of the Bulk FHIR specification for transmission of individual member data honors jurisdictional and personal privacy restrictions.
|
11
|
+
DESCRIPTION
|
12
|
+
|
13
|
+
id :pdex_bulk_data_transmission_restrictions_test
|
14
|
+
|
15
|
+
verifies_requirements 'hl7.fhir.us.davinci-pdex_2.0.0@11'
|
16
|
+
|
17
|
+
run do
|
18
|
+
identifier = SecureRandom.hex(32)
|
19
|
+
|
20
|
+
wait(
|
21
|
+
identifier:,
|
22
|
+
message: <<~MESSAGE
|
23
|
+
The developer of the Health IT Module attests that the Health IT Module's use of the Bulk FHIR specification for transmission of individual member data
|
24
|
+
honors jurisdictional and personal privacy restrictions that are relevant to a member's health record.
|
25
|
+
|
26
|
+
[Click here](#{resume_pass_url}?token=#{identifier}) if the system **meets** this requirement.
|
27
|
+
|
28
|
+
[Click here](#{resume_fail_url}?token=#{identifier}) if the system **does not meet** this requirement.
|
29
|
+
MESSAGE
|
30
|
+
)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require_relative '../urls'
|
2
|
+
|
3
|
+
module DaVinciPDexTestKit
|
4
|
+
class PDexMemberMatchConsentFailureHandlingTest < Inferno::Test
|
5
|
+
include PDexPayerServer::URLs
|
6
|
+
|
7
|
+
title 'Handles consent non-compliance correctly during $member-match'
|
8
|
+
|
9
|
+
description <<~DESCRIPTION
|
10
|
+
The Health IT Module correctly handles situations where during the `$member-match` operation:
|
11
|
+
- If a unique match to a member is found but the consent request cannot be honored (e.g., due to unsupported data segmentation policies), the system does not return a Patient ID in the response.
|
12
|
+
- In such cases, the system returns an HTTP 422 status code with an accompanying Operation Outcome that explains why the consent request could not be honored.
|
13
|
+
|
14
|
+
DESCRIPTION
|
15
|
+
|
16
|
+
id :pdex_member_match_consent_failure_test
|
17
|
+
|
18
|
+
verifies_requirements 'hl7.fhir.us.davinci-pdex_2.0.0@38',
|
19
|
+
'hl7.fhir.us.davinci-pdex_2.0.0@39'
|
20
|
+
|
21
|
+
run do
|
22
|
+
identifier = SecureRandom.hex(32)
|
23
|
+
|
24
|
+
wait(
|
25
|
+
identifier:,
|
26
|
+
message: <<~MESSAGE
|
27
|
+
The developer of the Health IT Module attests that during the `$member-match` operation:
|
28
|
+
|
29
|
+
- If a unique match to a member is found but the consent request cannot be honored (e.g., due to unsupported data segmentation policies), the system does not return a Patient ID in the response.
|
30
|
+
|
31
|
+
- In such cases, the system returns an HTTP 422 status code with an accompanying Operation Outcome that explains why the consent request could not be honored.
|
32
|
+
|
33
|
+
[Click here](#{resume_pass_url}?token=#{identifier}) if the system **meets** these requirements.
|
34
|
+
|
35
|
+
[Click here](#{resume_fail_url}?token=#{identifier}) if the system **does not meet** these requirements.
|
36
|
+
MESSAGE
|
37
|
+
)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require_relative '../urls'
|
2
|
+
|
3
|
+
module DaVinciPDexTestKit
|
4
|
+
class ConsentRequirementsTest < Inferno::Test
|
5
|
+
include PDexPayerServer::URLs
|
6
|
+
|
7
|
+
title 'Assesses consent requirements'
|
8
|
+
|
9
|
+
description <<~DESCRIPTION
|
10
|
+
The Health IT Module considers consent requirements to be met only if:
|
11
|
+
- Member Identity is matched
|
12
|
+
- Consent Policy (Everything or only Non-Sensitive data) matches the data release segmentation capabilities of the receiving payer
|
13
|
+
- Date period for consent is valid
|
14
|
+
- Payer requesting retrieval of data is matched.
|
15
|
+
DESCRIPTION
|
16
|
+
|
17
|
+
id :pdex_consent_requirements_test
|
18
|
+
|
19
|
+
verifies_requirements 'hl7.fhir.us.davinci-pdex_2.0.0@40'
|
20
|
+
|
21
|
+
run do
|
22
|
+
identifier = SecureRandom.hex(32)
|
23
|
+
|
24
|
+
wait(
|
25
|
+
identifier:,
|
26
|
+
message: <<~MESSAGE
|
27
|
+
The developer of the Health IT Module attests that the Health IT Module considers consent requirements to be met only if:
|
28
|
+
- Member Identity is matched
|
29
|
+
- Consent Policy (Everything or only Non-Sensitive data) matches the data release segmentation capabilities of the receiving payer
|
30
|
+
- Date period for consent is valid
|
31
|
+
- Payer requesting retrieval of data is matched.
|
32
|
+
|
33
|
+
[Click here](#{resume_pass_url}?token=#{identifier}) if the system **meets** this requirement.
|
34
|
+
|
35
|
+
[Click here](#{resume_fail_url}?token=#{identifier}) if the system **does not meet** this requirement.
|
36
|
+
MESSAGE
|
37
|
+
)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require_relative '../urls'
|
2
|
+
|
3
|
+
module DaVinciPDexTestKit
|
4
|
+
class PDexMustSupportDefinedByHRexTest < Inferno::Test
|
5
|
+
include PDexPayerServer::URLs
|
6
|
+
|
7
|
+
title 'Uses HRex Must Support definitions for HRex profiles'
|
8
|
+
|
9
|
+
description <<~DESCRIPTION
|
10
|
+
The Health IT Module applies the definition of "Must Support" as defined
|
11
|
+
by the Da Vinci HRex Implementation Guide for all HRex profiles referenced in PDex.
|
12
|
+
DESCRIPTION
|
13
|
+
|
14
|
+
id :pdex_must_support_defined_by_hrex_test
|
15
|
+
|
16
|
+
verifies_requirements 'hl7.fhir.us.davinci-pdex_2.0.0@5'
|
17
|
+
|
18
|
+
run do
|
19
|
+
identifier = SecureRandom.hex(32)
|
20
|
+
|
21
|
+
wait(
|
22
|
+
identifier:,
|
23
|
+
message: <<~MESSAGE
|
24
|
+
The developer of the Health IT Module attests that the system applies the definition
|
25
|
+
of "Must Support" as defined by the Da Vinci HRex Implementation Guide for all
|
26
|
+
HRex profiles referenced in PDex.
|
27
|
+
|
28
|
+
[Click here](#{resume_pass_url}?token=#{identifier}) if the system **meets** this requirement.
|
29
|
+
|
30
|
+
[Click here](#{resume_fail_url}?token=#{identifier}) if the system **does not meet** this requirement.
|
31
|
+
MESSAGE
|
32
|
+
)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/davinci_pdex_test_kit/pdex_payer_server/visual_inspection_and_attestation/licensing.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require_relative '../urls'
|
2
|
+
|
3
|
+
module DaVinciPDexTestKit
|
4
|
+
class PDexLicensingTest < Inferno::Test
|
5
|
+
include PDexPayerServer::URLs
|
6
|
+
|
7
|
+
title 'Complies with licensing requirements'
|
8
|
+
|
9
|
+
description <<~DESCRIPTION
|
10
|
+
The Health IT Module abides by the license
|
11
|
+
requirements for each terminology content artifact utilized within a functioning implementation and obtained
|
12
|
+
terminology licenses from the Third-Party IP owner for each code system and/or other specified artifact used.
|
13
|
+
DESCRIPTION
|
14
|
+
|
15
|
+
id :pdex_licensing_test
|
16
|
+
|
17
|
+
verifies_requirements 'hl7.fhir.us.davinci-pdex_2.0.0@1',
|
18
|
+
'hl7.fhir.us.davinci-pdex_2.0.0@2'
|
19
|
+
|
20
|
+
run do
|
21
|
+
identifier = SecureRandom.hex(32)
|
22
|
+
|
23
|
+
wait(
|
24
|
+
identifier:,
|
25
|
+
message: <<~MESSAGE
|
26
|
+
The developer of the Health IT Module attests that the Health IT Module abides by the license
|
27
|
+
requirements for each terminology content artifact utilized within a functioning implementation and obtained
|
28
|
+
terminology licenses from the Third-Party IP owner for each code system and/or other specified artifact used.
|
29
|
+
|
30
|
+
[Click here](#{resume_pass_url}?token=#{identifier}) if the system **meets** these requirements.
|
31
|
+
|
32
|
+
[Click here](#{resume_fail_url}?token=#{identifier}) if the system **does not meet** these requirements.
|
33
|
+
MESSAGE
|
34
|
+
)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/davinci_pdex_test_kit/pdex_payer_server/visual_inspection_and_attestation/member_auth.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
require_relative '../urls'
|
2
|
+
|
3
|
+
module DaVinciPDexTestKit
|
4
|
+
class PDexMemberAuthorizedExchangeTest < Inferno::Test
|
5
|
+
include PDexPayerServer::URLs
|
6
|
+
|
7
|
+
title 'Supports Payer-to-Payer member-authorized exchange'
|
8
|
+
|
9
|
+
description <<~DESCRIPTION
|
10
|
+
The Health IT Module supports Payer-to-Payer member-authorized
|
11
|
+
information exchange using SMART on FHIR and OAuth 2.0 by satisfying the following criteria.
|
12
|
+
|
13
|
+
The Health IT Module is acting as the **source** Health Plan, and is the Health Plan the member would like to get data from.
|
14
|
+
The **target** Health Plan is the Health PLan the member would like to share data to.
|
15
|
+
|
16
|
+
1. **Client Authorization Credentials**
|
17
|
+
The Health IT Module issues the target Health Plan OAuth 2.0 client application credentials during client registration.
|
18
|
+
|
19
|
+
1. **Member Consent Flow**
|
20
|
+
After the member authenticates to the Health IT Module's authorization server, the system presents an Authorization
|
21
|
+
screen enabling the member to approve sharing with the target Health Plan.
|
22
|
+
|
23
|
+
The Authorization process aligns with applicable privacy policy and regulations, allowing members to
|
24
|
+
select what data may be shared.
|
25
|
+
|
26
|
+
4. **Token Issuance**
|
27
|
+
Upon successful authorization, the Health IT Module issues an Access Token to the target Health Plan.
|
28
|
+
The scopes associated with the Access Token are limited to the information and permissions authorized by the member.
|
29
|
+
|
30
|
+
6. **Refresh Token Handling**:
|
31
|
+
Any Access Token subsequently issued by the Health IT Module using a Refresh Token enforces the same scope and member-specific
|
32
|
+
restrictions as the original authorization.
|
33
|
+
DESCRIPTION
|
34
|
+
|
35
|
+
id :pdex_member_authorized_exchange_test
|
36
|
+
|
37
|
+
verifies_requirements 'hl7.fhir.us.davinci-pdex_2.0.0@20',
|
38
|
+
'hl7.fhir.us.davinci-pdex_2.0.0@21',
|
39
|
+
'hl7.fhir.us.davinci-pdex_2.0.0@22',
|
40
|
+
'hl7.fhir.us.davinci-pdex_2.0.0@23',
|
41
|
+
'hl7.fhir.us.davinci-pdex_2.0.0@25',
|
42
|
+
'hl7.fhir.us.davinci-pdex_2.0.0@26'
|
43
|
+
|
44
|
+
run do
|
45
|
+
identifier = SecureRandom.hex(32)
|
46
|
+
|
47
|
+
wait(
|
48
|
+
identifier:,
|
49
|
+
message: <<~MESSAGE
|
50
|
+
I attest that the Health IT Module supports Payer-to-Payer member-authorized
|
51
|
+
information exchange using SMART on FHIR and OAuth 2.0 by satisfying the following criteria.
|
52
|
+
|
53
|
+
The **source** Health Plan is the Health Plan the member would like to get data from, and the **etarget**
|
54
|
+
Health Plan is the Health PLan the member would like to share data to.
|
55
|
+
|
56
|
+
1. **Client Authorization Credentials**
|
57
|
+
The Health IT Module issues the target Health Plan OAuth 2.0 client application credentials during client registration.
|
58
|
+
|
59
|
+
1. **Member Consent Flow**
|
60
|
+
After the member authenticates to the Health IT Module's authorization server, the system presents an Authorization
|
61
|
+
screen enabling the member to approve sharing with the target Health Plan.
|
62
|
+
|
63
|
+
The Authorization process aligns with applicable privacy policy and regulations, allowing members to
|
64
|
+
select what data may be shared.
|
65
|
+
|
66
|
+
4. **Token Issuance**
|
67
|
+
Upon successful authorization, the Health IT Module issues an Access Token to the target Health Plan.
|
68
|
+
The scopes associated with the Access Token are limited to the information and permissions authorized by the member.
|
69
|
+
|
70
|
+
6. **Refresh Token Handling**:
|
71
|
+
Any Access Token subsequently issued by the Health IT Module using a Refresh Token enforces the same scope and member-specific
|
72
|
+
restrictions as the original authorization.
|
73
|
+
|
74
|
+
[Click here](#{resume_pass_url}?token=#{identifier}) if the system **meets** these requirements.
|
75
|
+
|
76
|
+
[Click here](#{resume_fail_url}?token=#{identifier}) if the system **does not meet** these requirements.
|
77
|
+
MESSAGE
|
78
|
+
)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|