davinci_dtr_test_kit 0.16.0 → 0.16.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.
- checksums.yaml +4 -4
- data/config/presets/full_ehr_postman_dinner_order_example.json.erb +41 -0
- data/config/presets/full_ehr_postman_respiratory_device_example.json +1 -1
- data/config/presets/smart_app_postman_dinner_order_example.json +8 -1
- data/config/presets/smart_app_postman_respiratory_device_example.json +1 -1
- data/lib/davinci_dtr_test_kit/certs/InfernoCA.key +52 -0
- data/lib/davinci_dtr_test_kit/certs/InfernoCA.pem +35 -0
- data/lib/davinci_dtr_test_kit/certs/TestKit.pem +32 -0
- data/lib/davinci_dtr_test_kit/certs/TestKitPrivateKey.key +28 -0
- data/lib/davinci_dtr_test_kit/client_groups/adaptive_questionnaire/custom/dtr_custom_next_question_response_validation_test.rb +95 -0
- data/lib/davinci_dtr_test_kit/client_groups/adaptive_questionnaire/custom/dtr_full_ehr_custom_adaptive_request_test.rb +87 -0
- data/lib/davinci_dtr_test_kit/client_groups/adaptive_questionnaire/custom/dtr_full_ehr_custom_adaptive_workflow_group.rb +136 -0
- data/lib/davinci_dtr_test_kit/client_groups/adaptive_questionnaire/custom/dtr_smart_app_custom_adaptive_request_test.rb +171 -0
- data/lib/davinci_dtr_test_kit/client_groups/adaptive_questionnaire/custom/dtr_smart_app_custom_adaptive_workflow_group.rb +146 -0
- data/lib/davinci_dtr_test_kit/client_groups/{dinner_adaptive → adaptive_questionnaire/dinner_order}/dtr_adaptive_next_question_retrieval_group.rb +3 -3
- data/lib/davinci_dtr_test_kit/client_groups/{dinner_adaptive → adaptive_questionnaire/dinner_order}/dtr_full_ehr_adaptive_dinner_workflow_group.rb +21 -11
- data/lib/davinci_dtr_test_kit/client_groups/{dinner_adaptive → adaptive_questionnaire/dinner_order}/dtr_full_ehr_adaptive_initial_retrieval_group.rb +6 -6
- data/lib/davinci_dtr_test_kit/client_groups/{dinner_adaptive → adaptive_questionnaire/dinner_order}/dtr_smart_app_adaptive_dinner_workflow_group.rb +5 -5
- data/lib/davinci_dtr_test_kit/client_groups/{dinner_adaptive → adaptive_questionnaire/dinner_order}/dtr_smart_app_adaptive_initial_retrieval_group.rb +5 -5
- data/lib/davinci_dtr_test_kit/client_groups/{dinner_adaptive → adaptive_questionnaire}/dtr_adaptive_next_question_request_test.rb +9 -24
- data/lib/davinci_dtr_test_kit/client_groups/{dinner_adaptive → adaptive_questionnaire}/dtr_adaptive_next_question_request_validation_test.rb +36 -17
- data/lib/davinci_dtr_test_kit/client_groups/adaptive_questionnaire/dtr_adaptive_response_validation_test.rb +130 -0
- data/lib/davinci_dtr_test_kit/client_groups/auth/dtr_client_payer_auth_smart_group.rb +29 -0
- data/lib/davinci_dtr_test_kit/client_groups/auth/dtr_client_payer_auth_udap_group.rb +29 -0
- data/lib/davinci_dtr_test_kit/client_groups/custom_static/dtr_full_ehr_custom_static_workflow_group.rb +15 -14
- data/lib/davinci_dtr_test_kit/client_groups/custom_static/dtr_smart_app_custom_static_workflow_group.rb +5 -5
- data/lib/davinci_dtr_test_kit/client_groups/dinner_static/dtr_full_ehr_static_dinner_workflow_group.rb +14 -10
- data/lib/davinci_dtr_test_kit/client_groups/dinner_static/dtr_smart_app_static_dinner_workflow_group.rb +1 -1
- data/lib/davinci_dtr_test_kit/client_groups/{dinner_adaptive → full_ehr}/dtr_full_ehr_adaptive_request_test.rb +11 -14
- data/lib/davinci_dtr_test_kit/client_groups/full_ehr/dtr_full_ehr_questionnaire_package_request_test.rb +9 -17
- data/lib/davinci_dtr_test_kit/client_groups/full_ehr/dtr_full_ehr_questionnaire_response_correctness_test.rb +10 -1
- data/lib/davinci_dtr_test_kit/client_groups/full_ehr/dtr_full_ehr_store_attestation_test.rb +3 -3
- data/lib/davinci_dtr_test_kit/client_groups/light_ehr/fhir_context_references_test.rb +4 -5
- data/lib/davinci_dtr_test_kit/client_groups/must_support/dtr_full_ehr_ms_questionnaire_package_request_test.rb +75 -0
- data/lib/davinci_dtr_test_kit/client_groups/must_support/dtr_full_ehr_questionnaire_must_support_group.rb +85 -0
- data/lib/davinci_dtr_test_kit/client_groups/must_support/dtr_must_support_attestation_test.rb +39 -0
- data/lib/davinci_dtr_test_kit/client_groups/must_support/dtr_questionnaire_must_support_test.rb +42 -0
- data/lib/davinci_dtr_test_kit/client_groups/must_support/dtr_smart_app_ms_questionnaire_package_request_test.rb +148 -0
- data/lib/davinci_dtr_test_kit/client_groups/must_support/dtr_smart_app_questionnaire_must_support_group.rb +85 -0
- data/lib/davinci_dtr_test_kit/client_groups/must_support/questionnaire_must_support_elements.rb +55 -0
- data/lib/davinci_dtr_test_kit/client_groups/payer_registration/configuration_display_smart_test.rb +35 -0
- data/lib/davinci_dtr_test_kit/client_groups/payer_registration/configuration_display_udap_test.rb +35 -0
- data/lib/davinci_dtr_test_kit/client_groups/payer_registration/dtr_client_registration_group.rb +48 -0
- data/lib/davinci_dtr_test_kit/client_groups/shared/dtr_custom_questionnaire_expressions_test.rb +36 -0
- data/lib/davinci_dtr_test_kit/client_groups/shared/dtr_custom_questionnaire_extensions_test.rb +32 -0
- data/lib/davinci_dtr_test_kit/client_groups/{custom_static → shared}/dtr_custom_questionnaire_libraries_test.rb +7 -2
- data/lib/davinci_dtr_test_kit/client_groups/{custom_static → shared}/dtr_custom_questionnaire_package_validation_test.rb +6 -2
- data/lib/davinci_dtr_test_kit/client_groups/shared/dtr_questionnaire_package_request_validation_test.rb +6 -2
- data/lib/davinci_dtr_test_kit/client_groups/shared/dtr_questionnaire_response_prepopulation_test.rb +7 -1
- data/lib/davinci_dtr_test_kit/client_groups/smart_app/dtr_smart_app_questionnaire_response_correctness_test.rb +4 -3
- data/lib/davinci_dtr_test_kit/descriptions.rb +8 -0
- data/lib/davinci_dtr_test_kit/docs/dtr_full_ehr_suite_description_v201.md +145 -78
- data/lib/davinci_dtr_test_kit/docs/dtr_smart_app_suite_description_v201.md +4 -3
- data/lib/davinci_dtr_test_kit/dtr_client_options.rb +13 -0
- data/lib/davinci_dtr_test_kit/dtr_full_ehr_suite.rb +47 -7
- data/lib/davinci_dtr_test_kit/dtr_questionnaire_response_validation.rb +33 -21
- data/lib/davinci_dtr_test_kit/dtr_smart_app_suite.rb +7 -4
- data/lib/davinci_dtr_test_kit/endpoints/mock_ehr.rb +1 -1
- data/lib/davinci_dtr_test_kit/endpoints/mock_payer/full_ehr_next_question_endpoint.rb +20 -1
- data/lib/davinci_dtr_test_kit/endpoints/mock_payer/full_ehr_questionnaire_package_endpoint.rb +21 -1
- data/lib/davinci_dtr_test_kit/endpoints/mock_payer/next_question_endpoint.rb +29 -4
- data/lib/davinci_dtr_test_kit/endpoints/mock_payer/questionnaire_package_endpoint.rb +1 -1
- data/lib/davinci_dtr_test_kit/endpoints/mock_udap_smart_server/token_endpoint.rb +36 -0
- data/lib/davinci_dtr_test_kit/requirements/davinci-dtr-test-kit_out_of_scope_requirements.csv +6 -5
- data/lib/davinci_dtr_test_kit/requirements/davinci-dtr-test-kit_requirements.csv +10 -9
- data/lib/davinci_dtr_test_kit/requirements/generated/davinci-dtr-test-kit_requirements_coverage.csv +21 -21
- data/lib/davinci_dtr_test_kit/urls.rb +21 -4
- data/lib/davinci_dtr_test_kit/version.rb +2 -2
- metadata +59 -21
- data/config/presets/full_ehr_postman_dinner_order_example_postman.json +0 -19
- data/lib/davinci_dtr_test_kit/client_groups/custom_static/dtr_custom_questionnaire_expressions_test.rb +0 -22
- data/lib/davinci_dtr_test_kit/client_groups/custom_static/dtr_custom_questionnaire_extensions_test.rb +0 -19
- data/lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/dtr_adaptive_response_validation_test.rb +0 -68
- /data/lib/davinci_dtr_test_kit/client_groups/{dinner_adaptive → adaptive_questionnaire/dinner_order}/dtr_adaptive_completion_group.rb +0 -0
- /data/lib/davinci_dtr_test_kit/client_groups/{dinner_adaptive → adaptive_questionnaire/dinner_order}/dtr_adaptive_followup_questions_group.rb +0 -0
- /data/lib/davinci_dtr_test_kit/client_groups/{dinner_adaptive → smart_app}/dtr_smart_app_adaptive_request_test.rb +0 -0
@@ -1,14 +1,15 @@
|
|
1
|
-
require_relative '
|
1
|
+
require_relative '../../../tags'
|
2
2
|
require_relative 'dtr_full_ehr_adaptive_initial_retrieval_group'
|
3
|
-
require_relative '
|
4
|
-
require_relative '
|
3
|
+
require_relative '../../full_ehr/dtr_full_ehr_prepopulation_attestation_test'
|
4
|
+
require_relative '../../full_ehr/dtr_full_ehr_prepopulation_override_attestation_test'
|
5
5
|
require_relative 'dtr_adaptive_followup_questions_group'
|
6
6
|
require_relative 'dtr_adaptive_completion_group'
|
7
|
+
require_relative '../../full_ehr/dtr_full_ehr_store_attestation_test'
|
7
8
|
|
8
9
|
module DaVinciDTRTestKit
|
9
10
|
class DTRFullEHRAdaptiveDinnerWorkflowGroup < Inferno::TestGroup
|
10
11
|
id :dtr_full_ehr_adaptive_dinner_workflow
|
11
|
-
title 'Adaptive Questionnaire Workflow'
|
12
|
+
title 'Dinner Order Adaptive Questionnaire Workflow'
|
12
13
|
description %(
|
13
14
|
This test validates that a DTR Full EHR client can perform a full DTR Adaptive Questionnaire workflow
|
14
15
|
using a mocked questionnaire requesting what a patient wants for dinner. The client system must
|
@@ -67,12 +68,21 @@ module DaVinciDTRTestKit
|
|
67
68
|
}
|
68
69
|
}
|
69
70
|
|
70
|
-
group from: :dtr_adaptive_completion
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
71
|
+
group from: :dtr_adaptive_completion do
|
72
|
+
config(
|
73
|
+
options: {
|
74
|
+
accepts_multiple_requests: true,
|
75
|
+
next_tag: "completion_#{CLIENT_NEXT_TAG}"
|
76
|
+
}
|
77
|
+
)
|
78
|
+
group do
|
79
|
+
title 'Attestation: QuestionnaireResponse Completion and Storage'
|
80
|
+
description %(
|
81
|
+
The tester will attest to the completion of the questionnaire such that the results are stored for later use.
|
82
|
+
)
|
83
|
+
|
84
|
+
test from: :dtr_full_ehr_store_attest
|
85
|
+
end
|
86
|
+
end
|
77
87
|
end
|
78
88
|
end
|
@@ -1,9 +1,9 @@
|
|
1
|
-
require_relative '
|
2
|
-
require_relative '
|
3
|
-
require_relative 'dtr_full_ehr_adaptive_request_test'
|
4
|
-
require_relative '
|
5
|
-
require_relative 'dtr_adaptive_next_question_request_validation_test'
|
6
|
-
require_relative 'dtr_adaptive_response_validation_test'
|
1
|
+
require_relative '../../../tags'
|
2
|
+
require_relative '../../full_ehr/dtr_full_ehr_launch_attestation_test'
|
3
|
+
require_relative '../../full_ehr/dtr_full_ehr_adaptive_request_test'
|
4
|
+
require_relative '../../shared/dtr_questionnaire_package_request_validation_test'
|
5
|
+
require_relative '../dtr_adaptive_next_question_request_validation_test'
|
6
|
+
require_relative '../dtr_adaptive_response_validation_test'
|
7
7
|
|
8
8
|
module DaVinciDTRTestKit
|
9
9
|
class DTRFullEHRAdaptiveInitialRetrievalGroup < Inferno::TestGroup
|
@@ -1,15 +1,15 @@
|
|
1
|
-
require_relative '
|
1
|
+
require_relative '../../../tags'
|
2
2
|
require_relative 'dtr_smart_app_adaptive_initial_retrieval_group'
|
3
|
-
require_relative '
|
4
|
-
require_relative '
|
3
|
+
require_relative '../../smart_app/dtr_smart_app_prepopulation_attestation_test'
|
4
|
+
require_relative '../../smart_app/dtr_smart_app_prepopulation_override_attestation_test'
|
5
5
|
require_relative 'dtr_adaptive_followup_questions_group'
|
6
6
|
require_relative 'dtr_adaptive_completion_group'
|
7
|
-
require_relative '
|
7
|
+
require_relative '../../shared/dtr_questionnaire_response_prepopulation_test'
|
8
8
|
|
9
9
|
module DaVinciDTRTestKit
|
10
10
|
class DTRSmartAppAdaptiveDinnerWorkflowGroup < Inferno::TestGroup
|
11
11
|
id :dtr_smart_app_adaptive_dinner_workflow
|
12
|
-
title 'Adaptive Questionnaire Workflow'
|
12
|
+
title 'Dinner Order Adaptive Questionnaire Workflow'
|
13
13
|
description %(
|
14
14
|
This test validates that a DTR SMART App client can perform a full DTR Adaptive Questionnaire workflow
|
15
15
|
using a mocked questionnaire requesting what a patient wants for dinner. The client system must
|
@@ -1,8 +1,8 @@
|
|
1
|
-
require_relative '
|
2
|
-
require_relative 'dtr_smart_app_adaptive_request_test'
|
3
|
-
require_relative '
|
4
|
-
require_relative 'dtr_adaptive_next_question_request_validation_test'
|
5
|
-
require_relative 'dtr_adaptive_response_validation_test'
|
1
|
+
require_relative '../../../tags'
|
2
|
+
require_relative '../../smart_app/dtr_smart_app_adaptive_request_test'
|
3
|
+
require_relative '../../shared/dtr_questionnaire_package_request_validation_test'
|
4
|
+
require_relative '../dtr_adaptive_next_question_request_validation_test'
|
5
|
+
require_relative '../dtr_adaptive_response_validation_test'
|
6
6
|
|
7
7
|
module DaVinciDTRTestKit
|
8
8
|
class DTRSmartAppAdaptiveInitialRetrievalGroup < Inferno::TestGroup
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require_relative '../../descriptions'
|
1
2
|
require_relative '../../urls'
|
2
3
|
|
3
4
|
module DaVinciDTRTestKit
|
@@ -14,19 +15,12 @@ module DaVinciDTRTestKit
|
|
14
15
|
)
|
15
16
|
verifies_requirements 'hl7.fhir.us.davinci-dtr_2.0.1@264'
|
16
17
|
|
17
|
-
input :
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
def request_identification
|
24
|
-
if config.options[:smart_app]
|
25
|
-
"eyJhbGciOiJub25lIn0.#{example_client_jwt_payload_part}"
|
26
|
-
else
|
27
|
-
access_token
|
28
|
-
end
|
29
|
-
end
|
18
|
+
input :client_id,
|
19
|
+
title: 'Client Id',
|
20
|
+
type: 'text',
|
21
|
+
optional: true,
|
22
|
+
locked: true,
|
23
|
+
description: INPUT_CLIENT_ID_LOCKED
|
30
24
|
|
31
25
|
def cont_test_description
|
32
26
|
<<~DESCRIPTION
|
@@ -34,7 +28,7 @@ module DaVinciDTRTestKit
|
|
34
28
|
|
35
29
|
When the DTR application has finished loading the Questionnaire,
|
36
30
|
including any clinical data requests to support pre-population,
|
37
|
-
[Click here](#{resume_pass_url}?token=#{
|
31
|
+
[Click here](#{resume_pass_url}?token=#{client_id}) to continue.
|
38
32
|
DESCRIPTION
|
39
33
|
end
|
40
34
|
|
@@ -67,7 +61,7 @@ module DaVinciDTRTestKit
|
|
67
61
|
|
68
62
|
run do
|
69
63
|
wait(
|
70
|
-
identifier:
|
64
|
+
identifier: client_id,
|
71
65
|
message: <<~MESSAGE
|
72
66
|
### #{next_question_prompt_title}
|
73
67
|
|
@@ -77,15 +71,6 @@ module DaVinciDTRTestKit
|
|
77
71
|
|
78
72
|
#{prompt_cont}
|
79
73
|
|
80
|
-
### Request Identification
|
81
|
-
|
82
|
-
In order to identify requests for this session, Inferno will look for
|
83
|
-
an `Authorization` header with value:
|
84
|
-
|
85
|
-
```
|
86
|
-
Bearer #{request_identification}
|
87
|
-
```
|
88
|
-
|
89
74
|
#{cont_test_description if config.options[:accepts_multiple_requests]}
|
90
75
|
MESSAGE
|
91
76
|
)
|
@@ -24,6 +24,9 @@ module DaVinciDTRTestKit
|
|
24
24
|
If it is a Parameters resource, it must contain one parameter named `questionnaire-response`
|
25
25
|
with a `resource` attribute set to a FHIR QuestionnaireResponse instance, as specified above.
|
26
26
|
|
27
|
+
This test may process multiple resources, labeling messages with the corresponding tested resources
|
28
|
+
in the order that they were received.
|
29
|
+
|
27
30
|
The QuestionnaireResponse resource's structure and conformance will be validated
|
28
31
|
in the following test ('Adaptive QuestionnaireResponse is valid').
|
29
32
|
)
|
@@ -39,25 +42,41 @@ module DaVinciDTRTestKit
|
|
39
42
|
config.options[:next_tag]
|
40
43
|
end
|
41
44
|
|
45
|
+
def perform_requests_validation
|
46
|
+
requests.each_with_index do |r, index|
|
47
|
+
if r.url != next_url
|
48
|
+
add_message('warning',
|
49
|
+
"Request #{index} made to wrong URL: #{r.url}. Should instead be to #{next_url}")
|
50
|
+
end
|
51
|
+
assert_valid_json(r.request_body)
|
52
|
+
input_params = FHIR.from_contents(r.request_body)
|
53
|
+
assert input_params.present?, 'Request does not contain a recognized FHIR object'
|
54
|
+
assert_valid_resource_type(input_params)
|
55
|
+
|
56
|
+
if input_params.is_a?(FHIR::Parameters)
|
57
|
+
questionnaire_response_params = input_params.parameter.select do |param|
|
58
|
+
param.name == 'questionnaire-response'
|
59
|
+
end
|
60
|
+
qr_params_count = questionnaire_response_params.length
|
61
|
+
assert qr_params_count == 1,
|
62
|
+
"Input parameter must contain one `parameter:questionnaire-response` slice. Found #{qr_params_count}"
|
63
|
+
|
64
|
+
questionnaire_response = questionnaire_response_params.first.resource
|
65
|
+
assert_resource_type(:questionnaire_response, resource: questionnaire_response)
|
66
|
+
end
|
67
|
+
rescue Inferno::Exceptions::AssertionException => e
|
68
|
+
add_message('error', "Request #{index}: #{e.message}")
|
69
|
+
next
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
42
73
|
run do
|
43
74
|
load_tagged_requests next_request_tag
|
44
|
-
skip_if
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
assert input_params.present?, 'Request does not contain a recognized FHIR object'
|
50
|
-
assert_valid_resource_type(input_params)
|
51
|
-
|
52
|
-
if input_params.is_a?(FHIR::Parameters)
|
53
|
-
questionnaire_response_params = input_params.parameter.select { |param| param.name == 'questionnaire-response' }
|
54
|
-
qr_params_count = questionnaire_response_params.length
|
55
|
-
assert qr_params_count == 1,
|
56
|
-
"Input parameter must contain one `parameter:questionnaire-response` slice. Found #{qr_params_count}"
|
57
|
-
|
58
|
-
questionnaire_response = questionnaire_response_params.first.resource
|
59
|
-
assert_resource_type(:questionnaire_response, resource: questionnaire_response)
|
60
|
-
end
|
75
|
+
skip_if requests.blank?, 'A $next-question request must be made prior to running this test'
|
76
|
+
|
77
|
+
perform_requests_validation
|
78
|
+
|
79
|
+
assert messages.none? { |m| m[:type] == 'error' }, 'next-quest request(s) not comformant'
|
61
80
|
end
|
62
81
|
end
|
63
82
|
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
require_relative '../../urls'
|
2
|
+
require_relative '../../dtr_questionnaire_response_validation'
|
3
|
+
|
4
|
+
module DaVinciDTRTestKit
|
5
|
+
class DTRAdaptiveResponseValidationTest < Inferno::Test
|
6
|
+
include URLs
|
7
|
+
include DTRQuestionnaireResponseValidation
|
8
|
+
|
9
|
+
id :dtr_adaptive_response_validation
|
10
|
+
title 'Adaptive QuestionnaireResponse is valid'
|
11
|
+
description %(
|
12
|
+
This test validates the conformance of the Adaptive QuestionnaireResponse to the
|
13
|
+
[SDCQuestionnaireResponseAdapt](http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaireresponse-adapt)
|
14
|
+
structure. It verifies the presence of mandatory elements and that elements
|
15
|
+
with required bindings contain appropriate values.
|
16
|
+
|
17
|
+
It also ensures that all required questions are answered, and that the `origin.source`
|
18
|
+
extension is correct for each answer:
|
19
|
+
- `PBD.1` (Last Name) and `LOC.1` (Location): `auto`
|
20
|
+
- `PBD.2` (First Name): `override`
|
21
|
+
- `3` (all nested dinner questions): `manual`
|
22
|
+
|
23
|
+
Note: For the initial next-question request, only the conformance to the profile is checked
|
24
|
+
since neither the QuestionnaireResponse nor the contained Questionnaire will have any items,
|
25
|
+
as no questions are yet known.
|
26
|
+
)
|
27
|
+
verifies_requirements 'hl7.fhir.us.davinci-dtr_2.0.1@38', 'hl7.fhir.us.davinci-dtr_2.0.1@210',
|
28
|
+
'hl7.fhir.us.davinci-dtr_2.0.1@264'
|
29
|
+
|
30
|
+
def profile_url
|
31
|
+
'http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaireresponse-adapt'
|
32
|
+
end
|
33
|
+
|
34
|
+
def next_request_tag
|
35
|
+
config.options[:next_tag]
|
36
|
+
end
|
37
|
+
|
38
|
+
def perform_questionnaire_reponses_validation(custom_questionnaires) # rubocop:disable Metrics/CyclomaticComplexity
|
39
|
+
requests.each_with_index do |r, index|
|
40
|
+
if r.url != next_url
|
41
|
+
add_message('warning',
|
42
|
+
"Request #{index} made to wrong URL: #{r.url}. Should instead be to #{next_url}")
|
43
|
+
end
|
44
|
+
|
45
|
+
assert_valid_json(r.request_body)
|
46
|
+
input_params = FHIR.from_contents(r.request_body)
|
47
|
+
assert input_params.present?, 'Request does not contain a recognized FHIR object'
|
48
|
+
|
49
|
+
qr = nil
|
50
|
+
if input_params.is_a?(FHIR::QuestionnaireResponse)
|
51
|
+
qr = input_params
|
52
|
+
elsif input_params.is_a?(FHIR::Parameters)
|
53
|
+
qr = input_params.parameter&.find do |param|
|
54
|
+
param.name == 'questionnaire-response'
|
55
|
+
end&.resource
|
56
|
+
end
|
57
|
+
|
58
|
+
assert qr.present?, 'QuestionnaireResponse resource not provided.'
|
59
|
+
verify_basic_conformance(qr.to_json, profile_url)
|
60
|
+
|
61
|
+
questionnaire = qr.contained.find { |res| res.resourceType == 'Questionnaire' }
|
62
|
+
assert questionnaire, 'QuestionnaireResponse does not contained a Questionnaire'
|
63
|
+
|
64
|
+
scratch[:contained_questionnaires] ||= []
|
65
|
+
scratch[:contained_questionnaires] << questionnaire
|
66
|
+
|
67
|
+
verify_contained_questionnaire(questionnaire, index, custom_questionnaires)
|
68
|
+
check_missing_origin_sources(qr, index) if index == requests.length - 1
|
69
|
+
|
70
|
+
expected_overrides = next_request_tag&.include?('custom') ? [] : ['PBD.2']
|
71
|
+
check_origin_sources(questionnaire.item, qr.item, expected_overrides:, index:)
|
72
|
+
|
73
|
+
required_link_ids = extract_required_link_ids(questionnaire.item)
|
74
|
+
check_answer_presence(qr.item, required_link_ids, index)
|
75
|
+
rescue Inferno::Exceptions::AssertionException => e
|
76
|
+
prefix = e.message.include?('Workflow not') ? '' : "Request #{index}: "
|
77
|
+
add_message('error', "#{prefix}#{e.message}")
|
78
|
+
next
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def verify_contained_questionnaire(questionnaire, index, custom_questionnaires)
|
83
|
+
return unless next_request_tag&.include?('custom')
|
84
|
+
return unless index.positive? && custom_questionnaires.present?
|
85
|
+
|
86
|
+
expected_questionnaire = custom_questionnaires[index - 1]
|
87
|
+
return unless expected_questionnaire
|
88
|
+
|
89
|
+
actual_items = questionnaire.to_hash['item']
|
90
|
+
expected_items = expected_questionnaire['item']
|
91
|
+
|
92
|
+
assert actual_items == expected_items, %(
|
93
|
+
Invalid QuestionnaireResponse: the contained Questionnaire `item` does not match the expected content.
|
94
|
+
**Expected**: #{expected_items.inspect}
|
95
|
+
**Received**: #{actual_items.inspect}
|
96
|
+
)
|
97
|
+
end
|
98
|
+
|
99
|
+
def verify_workflow_completion(custom_questionnaires)
|
100
|
+
return unless next_request_tag&.include?('custom')
|
101
|
+
|
102
|
+
assert requests.length > custom_questionnaires.length, %(
|
103
|
+
Workflow not completed: expected #{custom_questionnaires.length + 1} next-question requests,
|
104
|
+
but received #{requests.length}.
|
105
|
+
)
|
106
|
+
end
|
107
|
+
|
108
|
+
run do
|
109
|
+
load_tagged_requests next_request_tag
|
110
|
+
skip_if requests.blank?, 'A $next-question request must be made prior to running this test'
|
111
|
+
|
112
|
+
custom_questionnaires = []
|
113
|
+
if next_request_tag&.include?('custom')
|
114
|
+
begin
|
115
|
+
custom_questionnaires = [JSON.parse(custom_next_question_questionnaires)].flatten
|
116
|
+
rescue JSON::ParserError
|
117
|
+
add_message(
|
118
|
+
'error',
|
119
|
+
'Workflow not completed: the provided questionnaires input for next-question requests is not valid JSON'
|
120
|
+
)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
perform_questionnaire_reponses_validation(custom_questionnaires)
|
125
|
+
verify_workflow_completion(custom_questionnaires)
|
126
|
+
|
127
|
+
assert(messages.none? { |m| m[:type] == 'error' }, 'QuestionnaireResponse is not correct, see error message(s)')
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'smart_app_launch_test_kit'
|
2
|
+
require_relative '../../tags'
|
3
|
+
|
4
|
+
module DaVinciDTRTestKit
|
5
|
+
class DTRClientPayerAuthSMARTGroup < Inferno::TestGroup
|
6
|
+
id :dtr_client_payer_auth_smart
|
7
|
+
title 'Review Authentication Interactions'
|
8
|
+
description %(
|
9
|
+
During these tests, Inferno will verify that the client interacted with Inferno's
|
10
|
+
simulated SMART authorization server in a conformant manner when requesting access tokens
|
11
|
+
and that the client under test was able to use provided access tokens to make DTR
|
12
|
+
requests.
|
13
|
+
|
14
|
+
Before running these tests, perform at least one DTR workflow group so that the client
|
15
|
+
will request an access token and use it on a DTR request.
|
16
|
+
)
|
17
|
+
run_as_group
|
18
|
+
|
19
|
+
# smart auth verification
|
20
|
+
test from: :smart_client_token_request_bsca_verification,
|
21
|
+
config: {
|
22
|
+
options: { endpoint_suite_id: :dtr_full_ehr }
|
23
|
+
}
|
24
|
+
test from: :smart_client_token_use_verification,
|
25
|
+
config: {
|
26
|
+
options: { access_request_tags: [QUESTIONNAIRE_PACKAGE_TAG, CLIENT_NEXT_TAG] }
|
27
|
+
}
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'udap_security_test_kit'
|
2
|
+
require_relative '../../tags'
|
3
|
+
|
4
|
+
module DaVinciDTRTestKit
|
5
|
+
class DTRClientPayerAuthUDAPGroup < Inferno::TestGroup
|
6
|
+
id :dtr_client_payer_auth_udap
|
7
|
+
title 'Review Authentication Interactions'
|
8
|
+
description %(
|
9
|
+
During these tests, Inferno will verify that the client interacted with Inferno's
|
10
|
+
simulated UDAP authorization server in a conformant manner when requesting access tokens
|
11
|
+
and that the client under test was able to use provided access tokens to make DTR
|
12
|
+
requests.
|
13
|
+
|
14
|
+
Before running these tests, perform at least one DTR workflow group so that the client
|
15
|
+
will request an access token and use it on a DTR request.
|
16
|
+
)
|
17
|
+
run_as_group
|
18
|
+
|
19
|
+
# udap auth verification
|
20
|
+
test from: :udap_client_token_request_cc_verification,
|
21
|
+
config: {
|
22
|
+
options: { endpoint_suite_id: :dtr_full_ehr }
|
23
|
+
}
|
24
|
+
test from: :udap_client_token_use_verification,
|
25
|
+
config: {
|
26
|
+
options: { access_request_tags: [QUESTIONNAIRE_PACKAGE_TAG, CLIENT_NEXT_TAG] }
|
27
|
+
}
|
28
|
+
end
|
29
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
|
-
require_relative 'dtr_custom_questionnaire_package_validation_test'
|
2
|
-
require_relative 'dtr_custom_questionnaire_libraries_test'
|
3
|
-
require_relative 'dtr_custom_questionnaire_extensions_test'
|
4
|
-
require_relative 'dtr_custom_questionnaire_expressions_test'
|
1
|
+
require_relative '../shared/dtr_custom_questionnaire_package_validation_test'
|
2
|
+
require_relative '../shared/dtr_custom_questionnaire_libraries_test'
|
3
|
+
require_relative '../shared/dtr_custom_questionnaire_extensions_test'
|
4
|
+
require_relative '../shared/dtr_custom_questionnaire_expressions_test'
|
5
5
|
require_relative '../full_ehr/dtr_full_ehr_launch_attestation_test'
|
6
6
|
require_relative '../full_ehr/dtr_full_ehr_questionnaire_package_request_test'
|
7
7
|
require_relative '../shared/dtr_questionnaire_package_request_validation_test'
|
@@ -29,6 +29,8 @@ module DaVinciDTRTestKit
|
|
29
29
|
)
|
30
30
|
verifies_requirements 'hl7.fhir.us.davinci-dtr_2.0.1@35', 'hl7.fhir.us.davinci-dtr_2.0.1@208'
|
31
31
|
|
32
|
+
input_order :custom_questionnaire_package_response, :static_custom_questionnaire_response
|
33
|
+
|
32
34
|
group do
|
33
35
|
id :dtr_full_ehr_custom_static_retrieval
|
34
36
|
title 'Retrieving the Static Questionnaire'
|
@@ -46,7 +48,7 @@ module DaVinciDTRTestKit
|
|
46
48
|
)
|
47
49
|
run_as_group
|
48
50
|
|
49
|
-
input_order :
|
51
|
+
input_order :custom_questionnaire_package_response
|
50
52
|
|
51
53
|
# Test 0: attest to launch
|
52
54
|
test from: :dtr_full_ehr_launch_attest,
|
@@ -55,7 +57,13 @@ module DaVinciDTRTestKit
|
|
55
57
|
title: 'Launch DTR (Attestation)'
|
56
58
|
# Test 1: wait for the $questionnaire-package request
|
57
59
|
test from: :dtr_full_ehr_qp_request do
|
58
|
-
input :custom_questionnaire_package_response
|
60
|
+
input :custom_questionnaire_package_response,
|
61
|
+
title: 'Custom Questionnaire Package Response JSON',
|
62
|
+
description: %(
|
63
|
+
Provide a JSON FHIR Bundle containing a custom questionnaire for Inferno to use as a response to
|
64
|
+
the $questionnaire-package request.
|
65
|
+
),
|
66
|
+
optional: false
|
59
67
|
end
|
60
68
|
# Test 2: validate the $questionnaire-package body
|
61
69
|
test from: :dtr_qp_request_validation
|
@@ -89,17 +97,10 @@ module DaVinciDTRTestKit
|
|
89
97
|
end
|
90
98
|
|
91
99
|
group from: :dtr_full_ehr_saving_qr do
|
92
|
-
input :custom_questionnaire_package_response,
|
93
|
-
title: 'Custom Questionnaire Package Response JSON',
|
94
|
-
description: %(
|
95
|
-
A JSON PackageBundle may be provided here to replace Inferno's response to the
|
96
|
-
$questionnaire-package request.
|
97
|
-
),
|
98
|
-
type: 'textarea'
|
99
|
-
|
100
100
|
config(
|
101
101
|
inputs: {
|
102
102
|
questionnaire_response: {
|
103
|
+
name: 'static_custom_questionnaire_response',
|
103
104
|
description: "The QuestionnaireResponse as exported from the EHR after completion of the Questionnaire.
|
104
105
|
IMPORTANT: If you have not yet run the 'Filling Out the Static Questionnaire' group, leave this blank
|
105
106
|
until you have done so. Then, run just the 'Saving the QuestionnaireResponse' group and populate
|
@@ -1,7 +1,7 @@
|
|
1
|
-
require_relative 'dtr_custom_questionnaire_package_validation_test'
|
2
|
-
require_relative 'dtr_custom_questionnaire_libraries_test'
|
3
|
-
require_relative 'dtr_custom_questionnaire_extensions_test'
|
4
|
-
require_relative 'dtr_custom_questionnaire_expressions_test'
|
1
|
+
require_relative '../shared/dtr_custom_questionnaire_package_validation_test'
|
2
|
+
require_relative '../shared/dtr_custom_questionnaire_libraries_test'
|
3
|
+
require_relative '../shared/dtr_custom_questionnaire_extensions_test'
|
4
|
+
require_relative '../shared/dtr_custom_questionnaire_expressions_test'
|
5
5
|
require_relative '../smart_app/dtr_smart_app_questionnaire_package_request_test'
|
6
6
|
require_relative '../shared/dtr_questionnaire_package_request_validation_test'
|
7
7
|
require_relative '../shared/dtr_prepopulation_attestation_test'
|
@@ -68,7 +68,7 @@ module DaVinciDTRTestKit
|
|
68
68
|
title 'Filling Out the Static Questionnaire'
|
69
69
|
description %(
|
70
70
|
The tester will interact with the questionnaire within their client system
|
71
|
-
such that pre-population steps are taken, the
|
71
|
+
such that pre-population steps are taken, the questionnaire is rendered, and
|
72
72
|
they are able to fill it out. The tester will attest that questionnaire pre-population
|
73
73
|
and rendering directives were followed.
|
74
74
|
)
|
@@ -61,16 +61,20 @@ module DaVinciDTRTestKit
|
|
61
61
|
test from: :dtr_static_dinner_enabled_questions_attest
|
62
62
|
end
|
63
63
|
|
64
|
-
group from: :dtr_full_ehr_saving_qr
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
}
|
64
|
+
group from: :dtr_full_ehr_saving_qr do
|
65
|
+
config(
|
66
|
+
inputs: {
|
67
|
+
questionnaire_response: {
|
68
|
+
name: 'static_dinner_questionnaire_response',
|
69
|
+
description: "The QuestionnaireResponse as exported from the EHR after completion of the Questionnaire.
|
70
|
+
IMPORTANT: If you have not yet run the 'Filling Out the Static Questionnaire' group, leave this blank
|
71
|
+
until you have done so. Then, run just the 'Saving the QuestionnaireResponse' group and populate
|
72
|
+
this input."
|
74
73
|
}
|
74
|
+
}
|
75
|
+
)
|
76
|
+
# custom qp input not used - Inferno-defined questionnaire
|
77
|
+
children[2].inputs.delete(:custom_questionnaire_package_response)
|
78
|
+
end
|
75
79
|
end
|
76
80
|
end
|
@@ -46,7 +46,7 @@ module DaVinciDTRTestKit
|
|
46
46
|
title 'Filling Out the Static Questionnaire'
|
47
47
|
description %(
|
48
48
|
The tester will interact with the questionnaire within their client system
|
49
|
-
such that pre-population steps are taken, the
|
49
|
+
such that pre-population steps are taken, the questionnaire is rendered, and
|
50
50
|
they are able to fill it out. Inferno will check that appropriate interactions
|
51
51
|
with the server occur and the tester will attest that questionnaire pre-population
|
52
52
|
and rendering directives were followed.
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require_relative '../../descriptions'
|
1
2
|
require_relative '../../urls'
|
2
3
|
|
3
4
|
module DaVinciDTRTestKit
|
@@ -20,17 +21,22 @@ module DaVinciDTRTestKit
|
|
20
21
|
'hl7.fhir.us.davinci-dtr_2.0.1@264'
|
21
22
|
|
22
23
|
config options: { accepts_multiple_requests: true }
|
23
|
-
input :
|
24
|
+
input :client_id,
|
25
|
+
title: 'Client Id',
|
26
|
+
type: 'text',
|
27
|
+
optional: true,
|
28
|
+
locked: true,
|
29
|
+
description: INPUT_CLIENT_ID_LOCKED
|
24
30
|
|
25
31
|
run do
|
26
32
|
wait(
|
27
|
-
identifier:
|
33
|
+
identifier: client_id,
|
28
34
|
message: %(
|
29
35
|
### Adaptive Questionnaire Retrieval
|
30
36
|
|
31
37
|
1. **Questionnaire Package Request**:
|
32
38
|
- Invoke the `$questionnaire-package` operation by sending a POST request to the following
|
33
|
-
|
39
|
+
endpoint to retrieve the adaptive questionnaire package:
|
34
40
|
|
35
41
|
`#{questionnaire_package_url}`.
|
36
42
|
|
@@ -38,7 +44,7 @@ module DaVinciDTRTestKit
|
|
38
44
|
|
39
45
|
2. **Initial Next Question Request**:
|
40
46
|
- After receiving the questionnaire package, invoke the `$next-question` operation by sending
|
41
|
-
|
47
|
+
a POST request to the following endpoint to retrieve the first set of questions:
|
42
48
|
|
43
49
|
`#{next_url}`.
|
44
50
|
|
@@ -46,18 +52,9 @@ module DaVinciDTRTestKit
|
|
46
52
|
|
47
53
|
Inferno will wait for both of these requests to be made.
|
48
54
|
|
49
|
-
### Request Identification
|
50
|
-
|
51
|
-
In order to identify requests for this session, Inferno will look for
|
52
|
-
an `Authorization` header with value:
|
53
|
-
|
54
|
-
```
|
55
|
-
Bearer #{access_token}
|
56
|
-
```
|
57
|
-
|
58
55
|
### Continuing the Tests
|
59
56
|
|
60
|
-
When both requests have been made, [Click here](#{resume_pass_url}?token=#{
|
57
|
+
When both requests have been made, [Click here](#{resume_pass_url}?token=#{client_id}) to continue.
|
61
58
|
)
|
62
59
|
)
|
63
60
|
end
|