davinci_dtr_test_kit 0.13.0 → 0.14.0
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/davinci_dtr_test_kit/client_groups/dinner_adaptive/dtr_adaptive_questionnaire_completion_group.rb +23 -0
- data/lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/dtr_adaptive_questionnaire_followup_questions_group.rb +26 -0
- data/lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/dtr_adaptive_questionnaire_next_question_request_test.rb +93 -0
- data/lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/dtr_adaptive_questionnaire_next_question_request_validation_test.rb +62 -0
- data/lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/dtr_adaptive_questionnaire_next_question_retrieval_group.rb +23 -0
- data/lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/dtr_adaptive_questionnaire_response_validation_test.rb +66 -0
- data/lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/dtr_full_ehr_adaptive_dinner_questionnaire_workflow_group.rb +76 -0
- data/lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/dtr_full_ehr_adaptive_questionnaire_initial_retrieval_group.rb +27 -0
- data/lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/dtr_full_ehr_adaptive_questionnaire_request_test.rb +63 -0
- data/lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/dtr_smart_app_adaptive_questionnaire_initial_retrieval_group.rb +24 -0
- data/lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/dtr_smart_app_adaptive_questionnaire_request_test.rb +148 -0
- data/lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/dtr_smart_app_questionnaire_workflow_group.rb +75 -0
- data/lib/davinci_dtr_test_kit/client_groups/dinner_static/dtr_full_ehr_questionnaire_workflow_group.rb +22 -38
- data/lib/davinci_dtr_test_kit/client_groups/dinner_static/dtr_smart_app_dinner_questionnaire_package_request_test.rb +13 -16
- data/lib/davinci_dtr_test_kit/client_groups/dinner_static/dtr_smart_app_questionnaire_workflow_group.rb +9 -31
- data/lib/davinci_dtr_test_kit/client_groups/{dinner_static → full_ehr}/dtr_full_ehr_launch_attestation_test.rb +7 -6
- data/lib/davinci_dtr_test_kit/client_groups/{dinner_static → full_ehr}/dtr_full_ehr_prepopulation_attestation_test.rb +7 -7
- data/lib/davinci_dtr_test_kit/client_groups/{dinner_static → full_ehr}/dtr_full_ehr_prepopulation_override_attestation_test.rb +7 -7
- data/lib/davinci_dtr_test_kit/client_groups/{dinner_static/dtr_full_ehr_dinner_questionnaire_package_request_test.rb → full_ehr/dtr_full_ehr_questionnaire_package_request_test.rb} +2 -3
- data/lib/davinci_dtr_test_kit/client_groups/{dinner_static/dtr_full_ehr_dinner_static_questionnaire_response_conformance_test.rb → full_ehr/dtr_full_ehr_questionnaire_response_conformance_test.rb} +7 -3
- data/lib/davinci_dtr_test_kit/client_groups/{dinner_static/dtr_full_ehr_dinner_static_questionnaire_response_correctness_test.rb → full_ehr/dtr_full_ehr_questionnaire_response_correctness_test.rb} +14 -7
- data/lib/davinci_dtr_test_kit/client_groups/{dinner_static → full_ehr}/dtr_full_ehr_rendering_enabled_questions_attestation_test.rb +7 -7
- data/lib/davinci_dtr_test_kit/client_groups/full_ehr/dtr_full_ehr_saving_questionnaire_response_group.rb +29 -0
- data/lib/davinci_dtr_test_kit/client_groups/{dinner_static → full_ehr}/dtr_full_ehr_store_attestation_test.rb +7 -7
- data/lib/davinci_dtr_test_kit/client_groups/resp_assist_device/dtr_questionnaire_rendering_attestation_test.rb +7 -6
- data/lib/davinci_dtr_test_kit/client_groups/resp_assist_device/dtr_resp_questionnaire_package_request_test.rb +15 -18
- data/lib/davinci_dtr_test_kit/client_groups/shared/dtr_questionnaire_response_basic_conformance_test.rb +5 -1
- data/lib/davinci_dtr_test_kit/client_groups/shared/dtr_questionnaire_response_pre_population_test.rb +12 -5
- data/lib/davinci_dtr_test_kit/client_groups/{dinner_static → smart_app}/dtr_smart_app_prepopulation_attestation_test.rb +7 -7
- data/lib/davinci_dtr_test_kit/client_groups/{dinner_static → smart_app}/dtr_smart_app_prepopulation_override_attestation_test.rb +7 -6
- data/lib/davinci_dtr_test_kit/client_groups/{dinner_static → smart_app}/dtr_smart_app_questionnaire_response_save_test.rb +17 -7
- data/lib/davinci_dtr_test_kit/client_groups/{dinner_static → smart_app}/dtr_smart_app_rendering_enabled_questions_attestation_test.rb +7 -7
- data/lib/davinci_dtr_test_kit/client_groups/smart_app/dtr_smart_app_saving_questionnaire_response_group.rb +27 -0
- data/lib/davinci_dtr_test_kit/cql_test.rb +37 -140
- data/lib/davinci_dtr_test_kit/create_test.rb +25 -0
- data/lib/davinci_dtr_test_kit/docs/dtr_full_ehr_suite_description_v201.md +95 -37
- data/lib/davinci_dtr_test_kit/docs/dtr_light_ehr_suite_description_v201.md +11 -6
- data/lib/davinci_dtr_test_kit/docs/dtr_payer_server_suite_description_v201.md +32 -29
- data/lib/davinci_dtr_test_kit/docs/dtr_smart_app_suite_description_v201.md +48 -32
- data/lib/davinci_dtr_test_kit/dtr_full_ehr_suite.rb +13 -17
- data/lib/davinci_dtr_test_kit/dtr_light_ehr_suite.rb +67 -2
- data/lib/davinci_dtr_test_kit/dtr_payer_server_suite.rb +9 -20
- data/lib/davinci_dtr_test_kit/dtr_questionnaire_response_validation.rb +18 -10
- data/lib/davinci_dtr_test_kit/dtr_smart_app_suite.rb +32 -59
- data/lib/davinci_dtr_test_kit/endpoints/cors.rb +20 -0
- data/lib/davinci_dtr_test_kit/endpoints/mock_authorization/authorize_endpoint.rb +32 -0
- data/lib/davinci_dtr_test_kit/endpoints/mock_authorization/simple_token_endpoint.rb +19 -0
- data/lib/davinci_dtr_test_kit/endpoints/mock_authorization/token_endpoint.rb +116 -0
- data/lib/davinci_dtr_test_kit/endpoints/mock_authorization.rb +83 -0
- data/lib/davinci_dtr_test_kit/endpoints/mock_ehr/fhir_get_endpoint.rb +95 -0
- data/lib/davinci_dtr_test_kit/endpoints/mock_ehr/questionnaire_response_endpoint.rb +22 -0
- data/lib/davinci_dtr_test_kit/endpoints/mock_ehr.rb +25 -0
- data/lib/davinci_dtr_test_kit/endpoints/mock_payer/full_ehr_next_question_endpoint.rb +11 -0
- data/lib/davinci_dtr_test_kit/endpoints/mock_payer/full_ehr_questionnaire_package_endpoint.rb +11 -0
- data/lib/davinci_dtr_test_kit/endpoints/mock_payer/next_question_endpoint.rb +162 -0
- data/lib/davinci_dtr_test_kit/endpoints/mock_payer/next_question_proxy_endpoint.rb +36 -0
- data/lib/davinci_dtr_test_kit/endpoints/mock_payer/questionnaire_package_endpoint.rb +62 -0
- data/lib/davinci_dtr_test_kit/endpoints/mock_payer/questionnaire_package_proxy_endpoint.rb +38 -0
- data/lib/davinci_dtr_test_kit/endpoints/mock_payer.rb +36 -0
- data/lib/davinci_dtr_test_kit/fixtures/dinner_adaptive/dinner_order_adaptive_next_question_burrito.json +10 -2
- data/lib/davinci_dtr_test_kit/fixtures/dinner_adaptive/dinner_order_adaptive_next_question_hamburger.json +10 -2
- data/lib/davinci_dtr_test_kit/fixtures/dinner_adaptive/dinner_order_adaptive_next_question_initial.json +10 -2
- data/lib/davinci_dtr_test_kit/fixtures/dinner_adaptive/questionnaire_dinner_order_adaptive.json +4 -3
- data/lib/davinci_dtr_test_kit/fixtures.rb +24 -1
- data/lib/davinci_dtr_test_kit/payer_server_groups/adaptive_form_libraries_test.rb +2 -2
- data/lib/davinci_dtr_test_kit/payer_server_groups/adaptive_form_questionnaire_expressions_test.rb +4 -3
- data/lib/davinci_dtr_test_kit/payer_server_groups/adaptive_form_questionnaire_extensions_test.rb +3 -2
- data/lib/davinci_dtr_test_kit/payer_server_groups/adaptive_next_questionnaire_expressions_test.rb +6 -6
- data/lib/davinci_dtr_test_kit/payer_server_groups/adaptive_next_questionnaire_extensions_test.rb +6 -5
- data/lib/davinci_dtr_test_kit/payer_server_groups/payer_server_adaptive_group.rb +2 -2
- data/lib/davinci_dtr_test_kit/payer_server_groups/payer_server_adaptive_response_bundles_validation_test.rb +6 -9
- data/lib/davinci_dtr_test_kit/payer_server_groups/payer_server_adaptive_response_search_validation_test.rb +15 -12
- data/lib/davinci_dtr_test_kit/payer_server_groups/payer_server_adaptive_response_validation_test.rb +33 -23
- data/lib/davinci_dtr_test_kit/payer_server_groups/payer_server_next_response_complete_test.rb +4 -4
- data/lib/davinci_dtr_test_kit/payer_server_groups/payer_server_next_response_validation_test.rb +16 -12
- data/lib/davinci_dtr_test_kit/payer_server_groups/static_form_libraries_test.rb +2 -2
- data/lib/davinci_dtr_test_kit/payer_server_groups/static_form_questionnaire_expressions_test.rb +5 -4
- data/lib/davinci_dtr_test_kit/payer_server_groups/static_form_questionnaire_extensions_test.rb +4 -3
- data/lib/davinci_dtr_test_kit/payer_server_groups/static_form_response_validation_test.rb +32 -25
- data/lib/davinci_dtr_test_kit/profiles/communication_request/communication_request_read.rb +29 -0
- data/lib/davinci_dtr_test_kit/profiles/communication_request/communication_request_validation.rb +35 -0
- data/lib/davinci_dtr_test_kit/profiles/communication_request_group.rb +39 -0
- data/lib/davinci_dtr_test_kit/profiles/coverage/coverage_read.rb +29 -0
- data/lib/davinci_dtr_test_kit/profiles/coverage/coverage_validation.rb +35 -0
- data/lib/davinci_dtr_test_kit/profiles/coverage_group.rb +38 -0
- data/lib/davinci_dtr_test_kit/profiles/device_request/device_request_read.rb +29 -0
- data/lib/davinci_dtr_test_kit/profiles/device_request/device_request_validation.rb +35 -0
- data/lib/davinci_dtr_test_kit/profiles/device_request_group.rb +39 -0
- data/lib/davinci_dtr_test_kit/profiles/encounter/encounter_read.rb +29 -0
- data/lib/davinci_dtr_test_kit/profiles/encounter/encounter_validation.rb +35 -0
- data/lib/davinci_dtr_test_kit/profiles/encounter_group.rb +39 -0
- data/lib/davinci_dtr_test_kit/profiles/medication_request/medication_request_read.rb +29 -0
- data/lib/davinci_dtr_test_kit/profiles/medication_request/medication_request_validation.rb +35 -0
- data/lib/davinci_dtr_test_kit/profiles/medication_request_group.rb +39 -0
- data/lib/davinci_dtr_test_kit/profiles/nutrition_order/nutrition_order_read.rb +29 -0
- data/lib/davinci_dtr_test_kit/profiles/nutrition_order/nutrition_order_validation.rb +35 -0
- data/lib/davinci_dtr_test_kit/profiles/nutrition_order_group.rb +39 -0
- data/lib/davinci_dtr_test_kit/profiles/questionnaire_response/questionnaire_response_context_search.rb +35 -0
- data/lib/davinci_dtr_test_kit/profiles/questionnaire_response/questionnaire_response_create.rb +26 -0
- data/lib/davinci_dtr_test_kit/profiles/questionnaire_response/questionnaire_response_patient_search.rb +55 -0
- data/lib/davinci_dtr_test_kit/profiles/questionnaire_response/questionnaire_response_read.rb +22 -0
- data/lib/davinci_dtr_test_kit/profiles/questionnaire_response/questionnaire_response_update.rb +26 -0
- data/lib/davinci_dtr_test_kit/profiles/questionnaire_response/questionnaire_response_validation.rb +37 -0
- data/lib/davinci_dtr_test_kit/profiles/questionnaire_response_group.rb +66 -0
- data/lib/davinci_dtr_test_kit/profiles/service_request/service_request_read.rb +29 -0
- data/lib/davinci_dtr_test_kit/profiles/service_request/service_request_validation.rb +35 -0
- data/lib/davinci_dtr_test_kit/profiles/service_request_group.rb +39 -0
- data/lib/davinci_dtr_test_kit/profiles/task/task_create.rb +26 -0
- data/lib/davinci_dtr_test_kit/profiles/task/task_read.rb +29 -0
- data/lib/davinci_dtr_test_kit/profiles/task/task_update.rb +26 -0
- data/lib/davinci_dtr_test_kit/profiles/task/task_validation.rb +35 -0
- data/lib/davinci_dtr_test_kit/profiles/task_group.rb +52 -0
- data/lib/davinci_dtr_test_kit/profiles/vision_prescription/vision_prescription_read.rb +29 -0
- data/lib/davinci_dtr_test_kit/profiles/vision_prescription/vision_prescription_validation.rb +35 -0
- data/lib/davinci_dtr_test_kit/profiles/vision_prescription_group.rb +39 -0
- data/lib/davinci_dtr_test_kit/read_test.rb +22 -0
- data/lib/davinci_dtr_test_kit/tags.rb +5 -7
- data/lib/davinci_dtr_test_kit/update_test.rb +25 -0
- data/lib/davinci_dtr_test_kit/validation_test.rb +19 -4
- data/lib/davinci_dtr_test_kit/version.rb +1 -1
- metadata +109 -20
- data/lib/davinci_dtr_test_kit/ext/inferno_core/record_response_route.rb +0 -98
- data/lib/davinci_dtr_test_kit/ext/inferno_core/request.rb +0 -19
- data/lib/davinci_dtr_test_kit/ext/inferno_core/runnable.rb +0 -35
- data/lib/davinci_dtr_test_kit/mock_auth_server.rb +0 -228
- data/lib/davinci_dtr_test_kit/mock_ehr.rb +0 -105
- data/lib/davinci_dtr_test_kit/mock_payer.rb +0 -100
|
@@ -10,6 +10,7 @@ module DaVinciDTRTestKit
|
|
|
10
10
|
Inferno will wait for a DTR questionnaire package request from the client. Upon receipt, Inferno will generate and
|
|
11
11
|
send a response.
|
|
12
12
|
)
|
|
13
|
+
config options: { accepts_multiple_requests: true }
|
|
13
14
|
input :smart_app_launch,
|
|
14
15
|
type: 'radio',
|
|
15
16
|
title: 'SMART App Launch',
|
|
@@ -20,38 +21,34 @@ module DaVinciDTRTestKit
|
|
|
20
21
|
input :launch_uri,
|
|
21
22
|
optional: true,
|
|
22
23
|
description: 'Required if "Launch from Inferno" is selected'
|
|
23
|
-
input :
|
|
24
|
+
input :resp_smart_patient_id,
|
|
24
25
|
optional: true,
|
|
25
26
|
title: 'SMART App Launch Patient ID (Respiratory Assist Device)',
|
|
26
27
|
type: 'text',
|
|
27
28
|
description: %(
|
|
28
|
-
Patient instance
|
|
29
|
-
Launch.
|
|
29
|
+
Patient instance ID to be provided by Inferno as the patient as a part of the SMART App Launch.
|
|
30
30
|
),
|
|
31
31
|
default: 'pat015'
|
|
32
|
-
input :
|
|
32
|
+
input :resp_smart_fhir_context,
|
|
33
33
|
optional: true,
|
|
34
34
|
title: 'SMART App Launch fhirContext (Respiratory Assist Device)',
|
|
35
35
|
type: 'textarea',
|
|
36
36
|
description: %(
|
|
37
|
-
References to be provided by Inferno as the
|
|
37
|
+
References to be provided by Inferno as the fhirContext as a part of the SMART App
|
|
38
38
|
Launch. These references help determine the behavior of the app. Referenced instances
|
|
39
39
|
may be provided in the "EHR-available resources" input.
|
|
40
40
|
),
|
|
41
41
|
default: JSON.pretty_generate([{ reference: 'Coverage/cov015' },
|
|
42
42
|
{ reference: 'DeviceRequest/devreqe0470' }])
|
|
43
|
-
input :
|
|
43
|
+
input :resp_ehr_bundle,
|
|
44
44
|
optional: true,
|
|
45
45
|
title: 'EHR-available resources (Respiratory Assist Device)',
|
|
46
46
|
type: 'textarea',
|
|
47
47
|
description: %(
|
|
48
48
|
Resources available from the EHR needed to drive the respiratory assist device workflow.
|
|
49
|
-
Formatted as a FHIR bundle that contains resources, each with an
|
|
50
|
-
instance present will be available for retrieval from Inferno at the endpoint
|
|
51
|
-
|
|
52
|
-
```
|
|
53
|
-
[fhir-base]/[resource type]/[instance id]
|
|
54
|
-
```
|
|
49
|
+
Formatted as a FHIR bundle that contains resources, each with an ID property populated. Each
|
|
50
|
+
instance present will be available for retrieval from Inferno at the endpoint:
|
|
51
|
+
<fhir-base>/<resource type>/<instance id>
|
|
55
52
|
)
|
|
56
53
|
|
|
57
54
|
def example_client_jwt_payload_part
|
|
@@ -61,19 +58,19 @@ module DaVinciDTRTestKit
|
|
|
61
58
|
run do
|
|
62
59
|
# validate relevant inputs and provide warnings if they are bad
|
|
63
60
|
warning do
|
|
64
|
-
if
|
|
65
|
-
assert_valid_json(
|
|
61
|
+
if resp_smart_fhir_context
|
|
62
|
+
assert_valid_json(resp_smart_fhir_context,
|
|
66
63
|
'The **SMART App Launch fhirContext** input is not valid JSON, so it will not be included in
|
|
67
64
|
the access token response.')
|
|
68
65
|
end
|
|
69
66
|
end
|
|
70
67
|
|
|
71
68
|
warning do
|
|
72
|
-
if
|
|
73
|
-
assert_valid_json(
|
|
69
|
+
if resp_ehr_bundle
|
|
70
|
+
assert_valid_json(resp_ehr_bundle,
|
|
74
71
|
'The **EHR-available resources** input is not valid JSON, so no tester-specified instances
|
|
75
72
|
will be available to access from Inferno.')
|
|
76
|
-
assert(FHIR.from_contents(
|
|
73
|
+
assert(FHIR.from_contents(resp_ehr_bundle).is_a?(FHIR::Bundle),
|
|
77
74
|
'The **EHR-available resources** input does not contain a FHIR Bundle, so no tester-specified instances
|
|
78
75
|
will be available to access from Inferno.')
|
|
79
76
|
end
|
|
@@ -117,7 +114,7 @@ module DaVinciDTRTestKit
|
|
|
117
114
|
an `Authorization` header with value:
|
|
118
115
|
|
|
119
116
|
```
|
|
120
|
-
Bearer
|
|
117
|
+
Bearer eyJhbGciOiJub25lIn0.#{example_client_jwt_payload_part}.
|
|
121
118
|
```
|
|
122
119
|
|
|
123
120
|
### Continuing the Tests
|
|
@@ -14,11 +14,15 @@ module DaVinciDTRTestKit
|
|
|
14
14
|
to the DTR Questionnaire Response resource profile.
|
|
15
15
|
)
|
|
16
16
|
|
|
17
|
+
def profile_url
|
|
18
|
+
config.options[:qr_profile_url]
|
|
19
|
+
end
|
|
20
|
+
|
|
17
21
|
run do
|
|
18
22
|
assert request.url == questionnaire_response_url,
|
|
19
23
|
"Request made to wrong URL: #{request.url}. Should instead be to #{questionnaire_response_url}"
|
|
20
24
|
|
|
21
|
-
verify_basic_conformance(request.request_body)
|
|
25
|
+
verify_basic_conformance(request.request_body, profile_url)
|
|
22
26
|
end
|
|
23
27
|
end
|
|
24
28
|
end
|
data/lib/davinci_dtr_test_kit/client_groups/shared/dtr_questionnaire_response_pre_population_test.rb
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
1
|
require_relative '../../dtr_questionnaire_response_validation'
|
|
4
2
|
require_relative '../../fixtures'
|
|
5
3
|
|
|
@@ -27,9 +25,18 @@ module DaVinciDTRTestKit
|
|
|
27
25
|
questionnaire_response_json = request.request_body
|
|
28
26
|
check_is_questionnaire_response(questionnaire_response_json)
|
|
29
27
|
questionnaire_response = FHIR.from_contents(questionnaire_response_json)
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
if config.options[:adaptive]
|
|
29
|
+
questionnaire = questionnaire_response.contained.find { |res| res.resourceType == 'Questionnaire' }
|
|
30
|
+
assert questionnaire, 'Adaptive QuestionnaireResponse must have a contained Questionnaire resource.'
|
|
31
|
+
check_origin_sources(questionnaire.item, questionnaire_response.item, expected_overrides: ['PBD.2'])
|
|
32
|
+
required_link_ids = extract_required_link_ids(questionnaire.item)
|
|
33
|
+
check_answer_presence(questionnaire_response.item, required_link_ids)
|
|
34
|
+
assert(messages.none? { |m| m[:type] == 'error' }, 'QuestionnaireResponse is not correct, see error message(s)')
|
|
35
|
+
else
|
|
36
|
+
questionnaire = Fixtures.questionnaire_for_test(id)
|
|
37
|
+
response_template = Fixtures.questionnaire_response_for_test(id)
|
|
38
|
+
validate_questionnaire_pre_population(questionnaire, response_template, questionnaire_response)
|
|
39
|
+
end
|
|
33
40
|
end
|
|
34
41
|
end
|
|
35
42
|
end
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
+
require 'securerandom'
|
|
1
2
|
require_relative '../../urls'
|
|
2
3
|
|
|
3
4
|
module DaVinciDTRTestKit
|
|
4
|
-
class
|
|
5
|
+
class DTRSmartAppPrepopulationAttestationTest < Inferno::Test
|
|
5
6
|
include URLs
|
|
6
7
|
|
|
7
|
-
id :
|
|
8
|
+
id :dtr_smart_app_prepopulation_attestation
|
|
8
9
|
title 'Check that the client pre-populates the questionnaire (Attestation)'
|
|
9
10
|
description %(
|
|
10
11
|
Validate that pre-population of patient name information occurs as expected.
|
|
11
12
|
)
|
|
12
|
-
input :client_id
|
|
13
|
-
|
|
14
13
|
run do
|
|
14
|
+
random_id = SecureRandom.uuid
|
|
15
15
|
wait(
|
|
16
|
-
identifier:
|
|
16
|
+
identifier: random_id,
|
|
17
17
|
message: %(
|
|
18
18
|
I attest that the client application pre-populates the following questions with the respective values:
|
|
19
19
|
- Last Name: Oster
|
|
20
20
|
- First Name: William
|
|
21
21
|
|
|
22
|
-
[Click here](#{resume_pass_url}?client_id=#{
|
|
22
|
+
[Click here](#{resume_pass_url}?client_id=#{random_id}) if the above statement is **true**.
|
|
23
23
|
|
|
24
|
-
[Click here](#{resume_fail_url}?client_id=#{
|
|
24
|
+
[Click here](#{resume_fail_url}?client_id=#{random_id}) if the above statement is **false**.
|
|
25
25
|
)
|
|
26
26
|
)
|
|
27
27
|
end
|
|
@@ -1,28 +1,29 @@
|
|
|
1
|
+
require 'securerandom'
|
|
1
2
|
require_relative '../../urls'
|
|
2
3
|
|
|
3
4
|
module DaVinciDTRTestKit
|
|
4
|
-
class
|
|
5
|
+
class DTRSmartAppPrepopulationOverrideAttestationTest < Inferno::Test
|
|
5
6
|
include URLs
|
|
6
7
|
|
|
7
|
-
id :
|
|
8
|
+
id :dtr_smart_app_prepopulation_override_attestation
|
|
8
9
|
title 'Validate the user can override pre-populated data (Attestation)'
|
|
9
10
|
description %(
|
|
10
11
|
Validate that the user can edit a pre-populated item and replace it with another value.
|
|
11
12
|
)
|
|
12
|
-
input :client_id
|
|
13
13
|
|
|
14
14
|
run do
|
|
15
|
+
random_id = SecureRandom.uuid
|
|
15
16
|
wait(
|
|
16
|
-
identifier:
|
|
17
|
+
identifier: random_id,
|
|
17
18
|
message: %(
|
|
18
19
|
I attest that
|
|
19
20
|
|
|
20
21
|
1. The client pre-populated an answer for question 'Location'.
|
|
21
22
|
2. I have changed the answer to a different value.
|
|
22
23
|
|
|
23
|
-
[Click here](#{resume_pass_url}?client_id=#{
|
|
24
|
+
[Click here](#{resume_pass_url}?client_id=#{random_id}) if the above statement is **true**.
|
|
24
25
|
|
|
25
|
-
[Click here](#{resume_fail_url}?client_id=#{
|
|
26
|
+
[Click here](#{resume_fail_url}?client_id=#{random_id}) if the above statement is **false**.
|
|
26
27
|
)
|
|
27
28
|
)
|
|
28
29
|
end
|
|
@@ -1,30 +1,40 @@
|
|
|
1
1
|
require_relative '../../urls'
|
|
2
2
|
|
|
3
3
|
module DaVinciDTRTestKit
|
|
4
|
-
class
|
|
4
|
+
class DTRSmartAppQuestionnaireResponseSaveTest < Inferno::Test
|
|
5
5
|
include URLs
|
|
6
6
|
|
|
7
|
-
id :
|
|
7
|
+
id :dtr_smart_app_questionnaire_response_save
|
|
8
8
|
title 'Save the QuestionnaireResponse after completing it'
|
|
9
9
|
description %(
|
|
10
10
|
Inferno, acting as the EHR, will wait for a request to save the QuestionnaireResponse from the client.
|
|
11
11
|
)
|
|
12
12
|
input :client_id
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
def prompt
|
|
15
|
+
if config.options[:adaptive]
|
|
16
|
+
'Store the completed questionnaire back into the EHR.'
|
|
17
|
+
else
|
|
18
|
+
<<~DESCRIPTION
|
|
18
19
|
Complete the questionnaire, leaving the following items unmodified, because a subsequent test will expect
|
|
19
20
|
their pre-populated values:
|
|
20
21
|
|
|
21
22
|
- First Name
|
|
22
23
|
- Last Name
|
|
24
|
+
DESCRIPTION
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
run do
|
|
29
|
+
wait(
|
|
30
|
+
identifier: client_id,
|
|
31
|
+
message: <<~MESSAGE
|
|
32
|
+
#{prompt}
|
|
23
33
|
|
|
24
34
|
Inferno will wait for a POST request at:
|
|
25
35
|
|
|
26
36
|
`#{questionnaire_response_url}`
|
|
27
|
-
|
|
37
|
+
MESSAGE
|
|
28
38
|
)
|
|
29
39
|
end
|
|
30
40
|
end
|
|
@@ -1,28 +1,28 @@
|
|
|
1
|
+
require 'securerandom'
|
|
1
2
|
require_relative '../../urls'
|
|
2
3
|
|
|
3
4
|
module DaVinciDTRTestKit
|
|
4
|
-
class
|
|
5
|
+
class DTRSmartAppRenderingEnabledQuestionsAttestationTest < Inferno::Test
|
|
5
6
|
include URLs
|
|
6
7
|
|
|
7
|
-
id :
|
|
8
|
+
id :dtr_smart_app_rendering_enabled_questions_attestation
|
|
8
9
|
title 'Check that the client renders enabled questions appropriately (Attestation)'
|
|
9
10
|
description %(
|
|
10
11
|
Validate that the rendering of the questionnaire includes only the "What would you like on..."
|
|
11
12
|
question appropriate for the dinner selection, if made.
|
|
12
13
|
)
|
|
13
|
-
input :client_id
|
|
14
|
-
|
|
15
14
|
run do
|
|
15
|
+
random_id = SecureRandom.uuid
|
|
16
16
|
wait(
|
|
17
|
-
identifier:
|
|
17
|
+
identifier: random_id,
|
|
18
18
|
message: %(
|
|
19
19
|
I attest that the client application does not display any "What would you like on..."
|
|
20
20
|
questions until I have selected a dinner choice and then only displays the
|
|
21
21
|
"What would you like on..." question relevant for the dinner request:
|
|
22
22
|
|
|
23
|
-
[Click here](#{resume_pass_url}?client_id=#{
|
|
23
|
+
[Click here](#{resume_pass_url}?client_id=#{random_id}) if the above statement is **true**.
|
|
24
24
|
|
|
25
|
-
[Click here](#{resume_fail_url}?client_id=#{
|
|
25
|
+
[Click here](#{resume_fail_url}?client_id=#{random_id}) if the above statement is **false**.
|
|
26
26
|
)
|
|
27
27
|
)
|
|
28
28
|
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require_relative 'dtr_smart_app_questionnaire_response_save_test'
|
|
2
|
+
require_relative '../shared/dtr_questionnaire_response_basic_conformance_test'
|
|
3
|
+
require_relative '../shared/dtr_questionnaire_response_pre_population_test'
|
|
4
|
+
|
|
5
|
+
module DaVinciDTRTestKit
|
|
6
|
+
class DTRSmartAppSavingQuestionnaireResponseGroup < Inferno::TestGroup
|
|
7
|
+
id :dtr_smart_app_saving_questionnaire_response
|
|
8
|
+
title 'Saving the QuestionnaireResponse'
|
|
9
|
+
description %(
|
|
10
|
+
The tester will complete the questionnaire such that a QuestionnaireResponse is stored
|
|
11
|
+
back into Inferno's EHR endpoint. The stored QuestionnaireResponse will be evaluated for
|
|
12
|
+
conformance, completeness, and correct indicators on pre-populated and manually-overriden
|
|
13
|
+
items.
|
|
14
|
+
)
|
|
15
|
+
run_as_group
|
|
16
|
+
|
|
17
|
+
# Test 1: wait for a QuestionnaireResponse
|
|
18
|
+
test from: :dtr_smart_app_questionnaire_response_save,
|
|
19
|
+
receives_request: :questionnaire_response_save
|
|
20
|
+
# Test 2: validate basic conformance of the QuestionnaireResponse
|
|
21
|
+
test from: :dtr_questionnaire_response_basic_conformance,
|
|
22
|
+
uses_request: :questionnaire_response_save
|
|
23
|
+
# Test 3: validate workflow-specific details such as pre-population and overrides
|
|
24
|
+
test from: :dtr_questionnaire_response_pre_population,
|
|
25
|
+
uses_request: :questionnaire_response_save
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -48,53 +48,10 @@ module DaVinciDTRTestKit
|
|
|
48
48
|
extension_presence.each_key { |k| extension_presence[k] = false }
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
-
def
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
next unless individual_resource.resourceType == 'QuestionnaireResponse'
|
|
55
|
-
|
|
56
|
-
individual_resource.contained.each_with_index do |questionnaire, q_index|
|
|
57
|
-
# Do out put parameters have a bundle?
|
|
58
|
-
next unless questionnaire.resourceType == 'Questionnaire'
|
|
59
|
-
|
|
60
|
-
# check the libraries first so references in questionnaires can be checked after
|
|
61
|
-
found_questionnaire = true
|
|
62
|
-
check_questionnaire_extensions(questionnaire, q_index)
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
found_questionnaire
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def evaluate_parameters_extensions(resource)
|
|
69
|
-
found_questionnaire = false
|
|
70
|
-
resource.parameter.each do |param|
|
|
71
|
-
# Do out put parameters have a bundle?
|
|
72
|
-
next unless param.resource.resourceType == 'Bundle'
|
|
73
|
-
|
|
74
|
-
param.resource.entry.each_with_index do |entry, q_index|
|
|
75
|
-
# check questionnaire extensions
|
|
76
|
-
next unless entry.resource.resourceType == 'Questionnaire'
|
|
77
|
-
|
|
78
|
-
found_questionnaire = true
|
|
79
|
-
check_questionnaire_extensions(entry.resource, q_index)
|
|
80
|
-
## NEED TO FIGURE OUT HOW TO FAIL TEST WHEN POORLY FORMATTED EXPRESSIONS FOUND
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
found_questionnaire
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
# extensions
|
|
87
|
-
def questionnaire_extensions_test(response)
|
|
88
|
-
resource = process_response(response)
|
|
89
|
-
assert !resource.nil?, 'Response is null or not a valid type.'
|
|
90
|
-
found_questionnaire = false
|
|
91
|
-
if resource.instance_of? Array
|
|
92
|
-
found_questionnaire = evaluate_responses_extensions(resource)
|
|
93
|
-
elsif resource.resourceType == 'Parameters'
|
|
94
|
-
found_questionnaire = evaluate_parameters_extensions(resource)
|
|
95
|
-
end
|
|
51
|
+
def verify_questionnaire_extensions(questionnaires)
|
|
52
|
+
assert questionnaires&.any? && questionnaires.all? { |q| q.is_a? FHIR::Questionnaire }, 'No questionnaires found.'
|
|
53
|
+
questionnaires.each_with_index { |q, q_index| check_questionnaire_extensions(q, q_index) }
|
|
96
54
|
check_library_references
|
|
97
|
-
assert found_questionnaire, 'No questionnaires found.'
|
|
98
55
|
assert extension_presence.value?(true), 'No extensions found. Questionnaire must demonstrate prepopulation.'
|
|
99
56
|
assert cql_presence['variable'], 'Variable expression logic not written in CQL.'
|
|
100
57
|
assert cql_presence['launch_context'], 'Launch context expression logic not written in CQL.'
|
|
@@ -140,53 +97,11 @@ module DaVinciDTRTestKit
|
|
|
140
97
|
assert misformatted_expressions.compact.empty?, 'Expression in questionnaire misformatted.'
|
|
141
98
|
end
|
|
142
99
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
resource.each_with_index do |individual_resource, q_index|
|
|
147
|
-
next unless individual_resource.resourceType == 'QuestionnaireResponse'
|
|
148
|
-
|
|
149
|
-
individual_resource.contained.each do |questionnaire|
|
|
150
|
-
next unless questionnaire.resourceType == 'Questionnaire'
|
|
100
|
+
def verify_questionnaire_items(questionnaires, final_cql_test: false)
|
|
101
|
+
assert questionnaires&.any? && questionnaires.all? { |q| q.is_a? FHIR::Questionnaire }, 'No questionnaires found.'
|
|
102
|
+
questionnaires.each_with_index { |q, q_index| check_questionnaire_items(q, q_index) }
|
|
151
103
|
|
|
152
|
-
# check the libraries first so references in questionnaires can be checked after
|
|
153
|
-
found_questionnaire = true
|
|
154
|
-
check_questionnaire_items(questionnaire, q_index)
|
|
155
|
-
end
|
|
156
|
-
end
|
|
157
|
-
found_questionnaire
|
|
158
|
-
end
|
|
159
|
-
|
|
160
|
-
def evaluate_parameters_items(resource)
|
|
161
|
-
found_bundle = found_questionnaire = false
|
|
162
|
-
resource.parameter.each do |param|
|
|
163
|
-
next unless param.resource.resourceType == 'Bundle'
|
|
164
|
-
|
|
165
|
-
found_bundle = true
|
|
166
|
-
# check the libraries first so references in questionnaires can be checked after
|
|
167
|
-
param.resource.entry.each_with_index do |entry, q_index|
|
|
168
|
-
if entry.resource.resourceType == 'Questionnaire'
|
|
169
|
-
found_questionnaire = true
|
|
170
|
-
check_questionnaire_items(entry.resource, q_index)
|
|
171
|
-
end
|
|
172
|
-
end
|
|
173
|
-
end
|
|
174
|
-
[found_bundle, found_questionnaire]
|
|
175
|
-
end
|
|
176
|
-
|
|
177
|
-
def questionnaire_items_test(response, final_cql_test)
|
|
178
|
-
resource = process_response(response)
|
|
179
|
-
assert !resource.nil?, 'Response is null or not a valid type.'
|
|
180
|
-
found_questionnaire = false
|
|
181
|
-
# are extensions present in any questionnaire?
|
|
182
|
-
if resource.instance_of? Array
|
|
183
|
-
found_questionnaire = evaluate_responses_items(resource)
|
|
184
|
-
elsif resource.resourceType == 'Parameters'
|
|
185
|
-
found_bundle, found_questionnaire = evaluate_parameters_items(resource)
|
|
186
|
-
assert found_bundle, 'No questionnaire bundles found.'
|
|
187
|
-
end
|
|
188
104
|
begin
|
|
189
|
-
assert found_questionnaire, 'No questionnaires found.'
|
|
190
105
|
assert !found_non_cql_expression, 'Found non-cql expression.'
|
|
191
106
|
assert extension_presence.value?(true), 'No extensions found. Questionnaire must demonstrate prepopulation.'
|
|
192
107
|
assert cql_presence['init_expression'], 'Initial expression logic not written in CQL.'
|
|
@@ -281,12 +196,12 @@ module DaVinciDTRTestKit
|
|
|
281
196
|
assert misformatted_expressions.compact.to_set.empty?, 'Expression in questionnaire misformatted.'
|
|
282
197
|
end
|
|
283
198
|
|
|
284
|
-
def evaluate_library(
|
|
199
|
+
def evaluate_library(library)
|
|
285
200
|
found_cql = found_elm = false
|
|
286
|
-
|
|
201
|
+
library.content.each do |content|
|
|
287
202
|
if content.data.nil?
|
|
288
203
|
messages << { type: 'info',
|
|
289
|
-
message: format_markdown("[library #{
|
|
204
|
+
message: format_markdown("[library #{library.url}] content element included no data.") }
|
|
290
205
|
end
|
|
291
206
|
if content.contentType == 'text/cql'
|
|
292
207
|
found_cql = true
|
|
@@ -294,42 +209,30 @@ module DaVinciDTRTestKit
|
|
|
294
209
|
found_elm = true
|
|
295
210
|
else
|
|
296
211
|
messages << { type: 'info',
|
|
297
|
-
message: format_markdown("[library #{
|
|
212
|
+
message: format_markdown("[library #{library.url}] has non-cql/elm content.") }
|
|
298
213
|
true
|
|
299
214
|
end
|
|
300
|
-
next unless library_names.include?
|
|
215
|
+
next unless library_names.include? library.name
|
|
301
216
|
|
|
302
217
|
found_duplicate_library_name = true
|
|
303
|
-
messages << { type: 'info', message: format_markdown("[library #{
|
|
304
|
-
#{
|
|
218
|
+
messages << { type: 'info', message: format_markdown("[library #{library.url}] has a name,
|
|
219
|
+
#{library.name}, that is already included in the bundle.") }
|
|
305
220
|
assert !found_duplicate_library_name, 'Found duplicate library names - all names must be unique.'
|
|
306
221
|
end
|
|
307
|
-
assert found_cql, "[library #{
|
|
308
|
-
assert found_elm, "[library #{
|
|
222
|
+
assert found_cql, "[library #{library.url}] does not include CQL."
|
|
223
|
+
assert found_elm, "[library #{library.url}] does not include ELM."
|
|
309
224
|
end
|
|
310
225
|
|
|
311
|
-
def check_libraries(
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
found_bundle = true
|
|
321
|
-
# check the libraries first so references in questionnaires can be checked after
|
|
322
|
-
param.resource.entry.each_with_index do |entry, index|
|
|
323
|
-
next unless entry.resource.resourceType == 'Library'
|
|
324
|
-
|
|
325
|
-
found_libraries = true
|
|
326
|
-
library_urls.add(entry.resource.url) unless entry.resource.url.nil?
|
|
327
|
-
evaluate_library(entry, index)
|
|
328
|
-
library_names.add(entry.resource.name)
|
|
329
|
-
end
|
|
330
|
-
assert found_libraries, 'No Libraries found.'
|
|
226
|
+
def check_libraries(questionnaire_bundles)
|
|
227
|
+
libraries = extract_libraries_from_bundles(questionnaire_bundles)
|
|
228
|
+
|
|
229
|
+
assert libraries.any?, 'No Libraries found.'
|
|
230
|
+
|
|
231
|
+
libraries.each do |lib|
|
|
232
|
+
library_urls.add(lib.url) unless lib.url.nil?
|
|
233
|
+
evaluate_library(lib)
|
|
234
|
+
library_names.add(lib.name)
|
|
331
235
|
end
|
|
332
|
-
assert found_bundle, 'No questionnaire bundles found.'
|
|
333
236
|
end
|
|
334
237
|
|
|
335
238
|
def check_library_references
|
|
@@ -405,28 +308,22 @@ module DaVinciDTRTestKit
|
|
|
405
308
|
end
|
|
406
309
|
end
|
|
407
310
|
|
|
408
|
-
def
|
|
409
|
-
questionnaire_responses
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
questionnaire_responses << fhir_resource if fhir_resource.resourceType == 'QuestionnaireResponse'
|
|
413
|
-
next unless resource.instance_of? Inferno::Entities::Request
|
|
414
|
-
|
|
415
|
-
if fhir_resource.resourceType == 'Questionnaire' || fhir_resource.resourceType == 'Parameters'
|
|
416
|
-
return fhir_resource
|
|
417
|
-
end
|
|
418
|
-
end
|
|
419
|
-
questionnaire_responses
|
|
311
|
+
def extract_contained_questionnaires(questionnaire_responses)
|
|
312
|
+
questionnaire_responses&.filter_map do |qr|
|
|
313
|
+
qr.contained&.filter { |resource| resource.is_a?(FHIR::Questionnaire) }
|
|
314
|
+
end&.flatten&.compact
|
|
420
315
|
end
|
|
421
316
|
|
|
422
|
-
def
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
end
|
|
317
|
+
def extract_questionnaires_from_bundles(questionnaire_bundles)
|
|
318
|
+
questionnaire_bundles.filter_map do |qb|
|
|
319
|
+
qb.entry.filter_map { |entry| entry.resource if entry.resource.is_a?(FHIR::Questionnaire) }
|
|
320
|
+
end&.flatten&.compact
|
|
321
|
+
end
|
|
428
322
|
|
|
429
|
-
|
|
323
|
+
def extract_libraries_from_bundles(questionnaire_bundles)
|
|
324
|
+
questionnaire_bundles.filter_map do |qb|
|
|
325
|
+
qb.entry.filter_map { |entry| entry.resource if entry&.resource.is_a?(FHIR::Library) }
|
|
326
|
+
end&.flatten&.compact
|
|
430
327
|
end
|
|
431
328
|
end
|
|
432
329
|
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module DaVinciDTRTestKit
|
|
2
|
+
module CreateTest
|
|
3
|
+
def perform_create_test(create_resources, resource_type)
|
|
4
|
+
skip_if(create_resources.blank?, "No `#{resource_type}` resources to create provided, skipping test.")
|
|
5
|
+
assert_valid_json(create_resources)
|
|
6
|
+
create_resources_list = JSON.parse(create_resources)
|
|
7
|
+
skip_if(!create_resources_list.is_a?(Array), 'Resources to create not inputted in list format, skipping test.')
|
|
8
|
+
|
|
9
|
+
valid_create_resources =
|
|
10
|
+
create_resources_list
|
|
11
|
+
.compact_blank
|
|
12
|
+
.map { |resource| FHIR.from_contents(resource.to_json) }
|
|
13
|
+
.select { |resource| resource.resourceType == resource_type }
|
|
14
|
+
.select { |resource| resource_is_valid?(resource:) }
|
|
15
|
+
|
|
16
|
+
skip_if(valid_create_resources.blank?,
|
|
17
|
+
%(No valid #{resource_type} resources were provided to send in Create requests, skipping test.))
|
|
18
|
+
|
|
19
|
+
valid_create_resources.each do |create_resource|
|
|
20
|
+
fhir_create(create_resource)
|
|
21
|
+
assert_response_status(201)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|