davinci_dtr_test_kit 0.16.0 → 0.16.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/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 +10 -25
- data/lib/davinci_dtr_test_kit/client_groups/{dinner_adaptive → adaptive_questionnaire}/dtr_adaptive_next_question_request_validation_test.rb +37 -18
- 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 +13 -16
- data/lib/davinci_dtr_test_kit/client_groups/full_ehr/dtr_full_ehr_questionnaire_package_request_test.rb +10 -18
- 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 +55 -7
- data/lib/davinci_dtr_test_kit/dtr_light_ehr_suite.rb +8 -0
- data/lib/davinci_dtr_test_kit/dtr_payer_server_suite.rb +8 -0
- data/lib/davinci_dtr_test_kit/dtr_questionnaire_response_validation.rb +33 -21
- data/lib/davinci_dtr_test_kit/dtr_smart_app_suite.rb +15 -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_requirements.csv → davinci_dtr_test_kit_requirements.csv} +375 -357
- data/lib/davinci_dtr_test_kit/requirements/generated/dtr_full_ehr_requirements_coverage.csv +140 -0
- data/lib/davinci_dtr_test_kit/requirements/generated/dtr_light_ehr_requirements_coverage.csv +69 -0
- data/lib/davinci_dtr_test_kit/requirements/generated/dtr_payer_server_requirements_coverage.csv +147 -0
- data/lib/davinci_dtr_test_kit/requirements/generated/dtr_smart_app_requirements_coverage.csv +214 -0
- data/lib/davinci_dtr_test_kit/requirements/hl7.fhir.us.davinci-dtr_2.0.1_requirements.xlsx +0 -0
- data/lib/davinci_dtr_test_kit/urls.rb +21 -4
- data/lib/davinci_dtr_test_kit/version.rb +2 -2
- data/lib/davinci_dtr_test_kit.rb +0 -1
- metadata +67 -30
- 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/requirements/davinci-dtr-test-kit_out_of_scope_requirements.csv +0 -13
- data/lib/davinci_dtr_test_kit/requirements/generated/davinci-dtr-test-kit_requirements_coverage.csv +0 -372
- data/lib/inferno_requirements_tools/ext/inferno_core/runnable.rb +0 -22
- data/lib/inferno_requirements_tools/rake/rakefile_template +0 -31
- data/lib/inferno_requirements_tools/tasks/requirements_coverage.rb +0 -284
- data/lib/requirements_config.yaml +0 -25
- /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,12 +1,19 @@
|
|
1
|
+
require 'udap_security_test_kit'
|
2
|
+
require 'smart_app_launch_test_kit'
|
1
3
|
require_relative 'client_groups/custom_static/dtr_full_ehr_custom_static_workflow_group'
|
2
4
|
require_relative 'client_groups/dinner_static/dtr_full_ehr_static_dinner_workflow_group'
|
3
|
-
require_relative 'client_groups/
|
4
|
-
require_relative '
|
5
|
+
require_relative 'client_groups/adaptive_questionnaire/dinner_order/dtr_full_ehr_adaptive_dinner_workflow_group'
|
6
|
+
require_relative 'client_groups/adaptive_questionnaire/custom/dtr_full_ehr_custom_adaptive_workflow_group'
|
7
|
+
require_relative 'client_groups/payer_registration/dtr_client_registration_group'
|
8
|
+
require_relative 'client_groups/must_support/dtr_full_ehr_questionnaire_must_support_group'
|
9
|
+
require_relative 'client_groups/auth/dtr_client_payer_auth_smart_group'
|
10
|
+
require_relative 'client_groups/auth/dtr_client_payer_auth_udap_group'
|
5
11
|
require_relative 'endpoints/cors'
|
6
|
-
require_relative 'endpoints/
|
12
|
+
require_relative 'endpoints/mock_udap_smart_server/token_endpoint'
|
7
13
|
require_relative 'endpoints/mock_payer/full_ehr_questionnaire_package_endpoint'
|
8
14
|
require_relative 'endpoints/mock_payer/full_ehr_next_question_endpoint'
|
9
15
|
require_relative 'version'
|
16
|
+
require_relative 'dtr_client_options'
|
10
17
|
|
11
18
|
module DaVinciDTRTestKit
|
12
19
|
class DTRFullEHRSuite < Inferno::TestSuite
|
@@ -35,9 +42,30 @@ module DaVinciDTRTestKit
|
|
35
42
|
}
|
36
43
|
]
|
37
44
|
|
45
|
+
requirement_sets(
|
46
|
+
{
|
47
|
+
identifier: 'hl7.fhir.us.davinci-dtr_2.0.1',
|
48
|
+
title: 'Da Vinci Documentation Templates and Rules (DTR) v2.0.1',
|
49
|
+
actor: 'Full EHR'
|
50
|
+
}
|
51
|
+
)
|
52
|
+
|
53
|
+
suite_option :client_type,
|
54
|
+
title: 'Client Security Type',
|
55
|
+
list_options: [
|
56
|
+
{
|
57
|
+
label: 'SMART Backend Services',
|
58
|
+
value: DTRClientOptions::SMART_BACKEND_SERVICES_CONFIDENTIAL_ASYMMETRIC
|
59
|
+
},
|
60
|
+
{
|
61
|
+
label: 'UDAP B2B Client Credentials',
|
62
|
+
value: DTRClientOptions::UDAP_CLIENT_CREDENTIALS
|
63
|
+
}
|
64
|
+
]
|
65
|
+
|
38
66
|
# Hl7 Validator Wrapper:
|
39
67
|
fhir_resource_validator do
|
40
|
-
igs '
|
68
|
+
igs 'igs/davinci_dtr_2.0.1.tgz'
|
41
69
|
|
42
70
|
exclude_message do |message|
|
43
71
|
message.message.match?(/\A\S+: \S+: URL value '.*' does not resolve/)
|
@@ -46,7 +74,16 @@ module DaVinciDTRTestKit
|
|
46
74
|
|
47
75
|
allow_cors QUESTIONNAIRE_PACKAGE_PATH, NEXT_PATH
|
48
76
|
|
49
|
-
|
77
|
+
route(:get, UDAPSecurityTestKit::UDAP_DISCOVERY_PATH, lambda { |_env|
|
78
|
+
UDAPSecurityTestKit::MockUDAPServer.udap_server_metadata(id)
|
79
|
+
})
|
80
|
+
route(:get, SMARTAppLaunch::SMART_DISCOVERY_PATH, lambda { |_env|
|
81
|
+
SMARTAppLaunch::MockSMARTServer.smart_server_metadata(id)
|
82
|
+
})
|
83
|
+
|
84
|
+
suite_endpoint :post, UDAPSecurityTestKit::REGISTRATION_PATH,
|
85
|
+
UDAPSecurityTestKit::MockUDAPServer::RegistrationEndpoint
|
86
|
+
suite_endpoint :post, UDAPSecurityTestKit::TOKEN_PATH, MockUdapSmartServer::TokenEndpoint
|
50
87
|
|
51
88
|
suite_endpoint :post, QUESTIONNAIRE_PACKAGE_PATH, MockPayer::FullEHRQuestionnairePackageEndpoint
|
52
89
|
suite_endpoint :post, NEXT_PATH, MockPayer::FullEHRNextQuestionEndpoint
|
@@ -59,13 +96,13 @@ module DaVinciDTRTestKit
|
|
59
96
|
request.query_parameters['token']
|
60
97
|
end
|
61
98
|
|
62
|
-
group from: :
|
99
|
+
group from: :dtr_client_payer_registration
|
63
100
|
group do
|
64
101
|
id :dtr_full_ehr_basic_workflows
|
65
102
|
title 'Basic Workflows'
|
66
103
|
|
67
104
|
group from: :dtr_full_ehr_custom_static_workflow
|
68
|
-
group from: :
|
105
|
+
group from: :dtr_full_ehr_custom_adaptive_workflow
|
69
106
|
end
|
70
107
|
group do
|
71
108
|
id :dtr_full_ehr_questionnaire_functionality
|
@@ -75,6 +112,17 @@ module DaVinciDTRTestKit
|
|
75
112
|
covering additional pre-population features of questionnaires.
|
76
113
|
)
|
77
114
|
group from: :dtr_full_ehr_static_dinner_workflow
|
115
|
+
group from: :dtr_full_ehr_adaptive_dinner_workflow
|
78
116
|
end
|
117
|
+
group from: :dtr_full_ehr_questionnaire_ms
|
118
|
+
|
119
|
+
group from: :dtr_client_payer_auth_smart,
|
120
|
+
required_suite_options: {
|
121
|
+
client_type: DTRClientOptions::SMART_BACKEND_SERVICES_CONFIDENTIAL_ASYMMETRIC
|
122
|
+
}
|
123
|
+
group from: :dtr_client_payer_auth_udap,
|
124
|
+
required_suite_options: {
|
125
|
+
client_type: DTRClientOptions::UDAP_CLIENT_CREDENTIALS
|
126
|
+
}
|
79
127
|
end
|
80
128
|
end
|
@@ -43,6 +43,14 @@ module DaVinciDTRTestKit
|
|
43
43
|
}
|
44
44
|
]
|
45
45
|
|
46
|
+
requirement_sets(
|
47
|
+
{
|
48
|
+
identifier: 'hl7.fhir.us.davinci-dtr_2.0.1',
|
49
|
+
title: 'Da Vinci Documentation Templates and Rules (DTR) v2.0.1',
|
50
|
+
actor: 'Light EHR'
|
51
|
+
}
|
52
|
+
)
|
53
|
+
|
46
54
|
# Hl7 Validator Wrapper:
|
47
55
|
fhir_resource_validator do
|
48
56
|
igs('hl7.fhir.us.davinci-dtr#2.0.1', 'hl7.fhir.us.davinci-pas#2.0.1', 'hl7.fhir.us.davinci-crd#2.0.1')
|
@@ -34,6 +34,14 @@ module DaVinciDTRTestKit
|
|
34
34
|
}
|
35
35
|
]
|
36
36
|
|
37
|
+
requirement_sets(
|
38
|
+
{
|
39
|
+
identifier: 'hl7.fhir.us.davinci-dtr_2.0.1',
|
40
|
+
title: 'Da Vinci Documentation Templates and Rules (DTR) v2.0.1',
|
41
|
+
actor: 'Payer Service'
|
42
|
+
}
|
43
|
+
)
|
44
|
+
|
37
45
|
# These inputs will be available to all tests in this suite
|
38
46
|
|
39
47
|
input :retrieval_method,
|
@@ -29,14 +29,7 @@ module DaVinciDTRTestKit
|
|
29
29
|
"Couldn't find Questionnaire #{qr.questionnaire} in the provided custom questionnaire package
|
30
30
|
to validate the QuestionnaireResponse."
|
31
31
|
|
32
|
-
|
33
|
-
unless missing_origin_sources.empty?
|
34
|
-
add_message(
|
35
|
-
'error',
|
36
|
-
'All origin sources (auto, manual, override) must be present in the QuestionnaireResponse. ' \
|
37
|
-
"Missing #{missing_origin_sources.to_sentence}"
|
38
|
-
)
|
39
|
-
end
|
32
|
+
check_missing_origin_sources(qr)
|
40
33
|
end
|
41
34
|
|
42
35
|
check_origin_sources(questionnaire.item, qr.item, expected_overrides:)
|
@@ -46,6 +39,18 @@ module DaVinciDTRTestKit
|
|
46
39
|
assert(messages.none? { |m| m[:type] == 'error' }, 'QuestionnaireResponse is not correct, see error message(s)')
|
47
40
|
end
|
48
41
|
|
42
|
+
def check_missing_origin_sources(questionnaire_response, index = nil)
|
43
|
+
missing_origin_sources = ['auto', 'manual', 'override'] - extract_origin_sources(questionnaire_response.item)
|
44
|
+
return if missing_origin_sources.empty?
|
45
|
+
|
46
|
+
prefix = index ? "Request #{index}: " : ''
|
47
|
+
add_message(
|
48
|
+
'error',
|
49
|
+
"#{prefix}All origin sources (auto, manual, override) must be present in the QuestionnaireResponse. " \
|
50
|
+
"Missing #{missing_origin_sources.to_sentence}"
|
51
|
+
)
|
52
|
+
end
|
53
|
+
|
49
54
|
def check_is_questionnaire_response(questionnaire_response_json)
|
50
55
|
assert_valid_json(questionnaire_response_json)
|
51
56
|
questionnaire_response = begin
|
@@ -65,9 +70,10 @@ module DaVinciDTRTestKit
|
|
65
70
|
end
|
66
71
|
|
67
72
|
# This only checks answers in the questionnaire response, meaning it does not catch missing answers
|
68
|
-
def check_origin_sources(questionnaire_items, response_items, expected_overrides: [])
|
73
|
+
def check_origin_sources(questionnaire_items, response_items, expected_overrides: [], index: nil)
|
74
|
+
prefix = index ? "Request #{index}: " : ''
|
69
75
|
response_items&.each do |response_item|
|
70
|
-
check_origin_sources(questionnaire_items, response_item.item, expected_overrides:)
|
76
|
+
check_origin_sources(questionnaire_items, response_item.item, expected_overrides:, index:)
|
71
77
|
next unless response_item.answer&.any?
|
72
78
|
|
73
79
|
link_id = response_item.linkId
|
@@ -76,20 +82,25 @@ module DaVinciDTRTestKit
|
|
76
82
|
is_cql_expression = item_is_cql_expression?(questionnaire_item)
|
77
83
|
|
78
84
|
if origin_source.nil?
|
79
|
-
add_message('error', "Required `origin.source` extension not present on answer to item `#{link_id}`")
|
85
|
+
add_message('error', "#{prefix}Required `origin.source` extension not present on answer to item `#{link_id}`")
|
80
86
|
else
|
81
|
-
check_origin_source(
|
87
|
+
check_origin_source(
|
88
|
+
origin_source, link_id, is_cql_expression,
|
89
|
+
override: expected_overrides.include?(link_id),
|
90
|
+
index:
|
91
|
+
)
|
82
92
|
end
|
83
93
|
end
|
84
94
|
end
|
85
95
|
|
86
|
-
def check_origin_source(origin_source, link_id, is_cql_expression, override: false)
|
96
|
+
def check_origin_source(origin_source, link_id, is_cql_expression, override: false, index: nil) # rubocop:disable Metrics/CyclomaticComplexity
|
97
|
+
prefix = index ? "Request #{index}: " : ''
|
87
98
|
if override
|
88
|
-
origin_source_error(link_id, ['override'], origin_source) unless origin_source == 'override'
|
99
|
+
origin_source_error(link_id, ['override'], origin_source, prefix) unless origin_source == 'override'
|
89
100
|
elsif is_cql_expression && !['auto', 'override'].include?(origin_source)
|
90
|
-
origin_source_error(link_id, 'auto or override', origin_source)
|
101
|
+
origin_source_error(link_id, 'auto or override', origin_source, prefix)
|
91
102
|
elsif !is_cql_expression && origin_source != 'manual'
|
92
|
-
origin_source_error(link_id, 'manual', origin_source)
|
103
|
+
origin_source_error(link_id, 'manual', origin_source, prefix)
|
93
104
|
end
|
94
105
|
end
|
95
106
|
|
@@ -104,11 +115,13 @@ module DaVinciDTRTestKit
|
|
104
115
|
|
105
116
|
# Ensures that all required questions have been answered.
|
106
117
|
# If required_link_ids not provided, all questions are treated as optional.
|
107
|
-
def check_answer_presence(response_items, required_link_ids = [])
|
118
|
+
def check_answer_presence(response_items, required_link_ids = [], index = nil)
|
119
|
+
prefix = index ? "Request #{index}: " : ''
|
120
|
+
|
108
121
|
required_link_ids.each do |link_id|
|
109
122
|
item = find_item_by_link_id(response_items, link_id)
|
110
123
|
unless item&.answer&.any? { |answer| answer.value.present? }
|
111
|
-
add_message('error', "No answer for item #{link_id}")
|
124
|
+
add_message('error', "#{prefix}No answer for item #{link_id}")
|
112
125
|
end
|
113
126
|
end
|
114
127
|
end
|
@@ -176,7 +189,6 @@ module DaVinciDTRTestKit
|
|
176
189
|
questionnaire_cql_expression_link_ids,
|
177
190
|
expected_prepopulated = {},
|
178
191
|
expected_overrides = {})
|
179
|
-
|
180
192
|
questionnaire_cql_expression_link_ids.each do |target_link_id|
|
181
193
|
target_item = find_item_by_link_id(template_questionnaire_response.item, target_link_id)
|
182
194
|
raise "Template QuestionnaireResponse missing item with link id `#{target_link_id}`" unless target_item.present?
|
@@ -235,8 +247,8 @@ module DaVinciDTRTestKit
|
|
235
247
|
end
|
236
248
|
end
|
237
249
|
|
238
|
-
def origin_source_error(link_id, expected, actual)
|
239
|
-
add_message('error', %(`origin.source` extension on item `#{link_id}` contains unexpected value.
|
250
|
+
def origin_source_error(link_id, expected, actual, msg_prefix = nil)
|
251
|
+
add_message('error', %(#{msg_prefix}`origin.source` extension on item `#{link_id}` contains unexpected value.
|
240
252
|
Expected: #{expected}. Found: #{actual}))
|
241
253
|
end
|
242
254
|
|
@@ -1,8 +1,10 @@
|
|
1
1
|
require_relative 'auth_groups/oauth2_authentication_group'
|
2
2
|
require_relative 'client_groups/respiratory/dtr_smart_app_respiratory_workflow_group'
|
3
3
|
require_relative 'client_groups/dinner_static/dtr_smart_app_static_dinner_workflow_group'
|
4
|
-
require_relative 'client_groups/
|
4
|
+
require_relative 'client_groups/adaptive_questionnaire/dinner_order/dtr_smart_app_adaptive_dinner_workflow_group'
|
5
5
|
require_relative 'client_groups/custom_static/dtr_smart_app_custom_static_workflow_group'
|
6
|
+
require_relative 'client_groups/adaptive_questionnaire/custom/dtr_smart_app_custom_adaptive_workflow_group'
|
7
|
+
require_relative 'client_groups/must_support/dtr_smart_app_questionnaire_must_support_group'
|
6
8
|
require_relative 'endpoints/cors'
|
7
9
|
require_relative 'endpoints/mock_authorization'
|
8
10
|
require_relative 'endpoints/mock_authorization/authorize_endpoint'
|
@@ -41,9 +43,17 @@ module DaVinciDTRTestKit
|
|
41
43
|
}
|
42
44
|
]
|
43
45
|
|
46
|
+
requirement_sets(
|
47
|
+
{
|
48
|
+
identifier: 'hl7.fhir.us.davinci-dtr_2.0.1',
|
49
|
+
title: 'Da Vinci Documentation Templates and Rules (DTR) v2.0.1',
|
50
|
+
actor: 'SMART Client'
|
51
|
+
}
|
52
|
+
)
|
53
|
+
|
44
54
|
# Hl7 Validator Wrapper:
|
45
55
|
fhir_resource_validator do
|
46
|
-
igs '
|
56
|
+
igs 'igs/davinci_dtr_2.0.1.tgz'
|
47
57
|
|
48
58
|
exclude_message do |message|
|
49
59
|
message.message.match?(/\A\S+: \S+: URL value '.*' does not resolve/)
|
@@ -90,10 +100,9 @@ module DaVinciDTRTestKit
|
|
90
100
|
)
|
91
101
|
|
92
102
|
group from: :dtr_smart_app_custom_static_workflow
|
93
|
-
group from: :
|
103
|
+
group from: :dtr_smart_app_custom_adaptive_workflow
|
94
104
|
end
|
95
105
|
group do
|
96
|
-
id :dtr_smart_app_questionnaire_functionality
|
97
106
|
title 'Questionnaire Functionality Coverage'
|
98
107
|
description %(
|
99
108
|
Tests in this group validate that the client can complete additional DTR workflows
|
@@ -101,6 +110,8 @@ module DaVinciDTRTestKit
|
|
101
110
|
)
|
102
111
|
group from: :dtr_smart_app_resp_workflow
|
103
112
|
group from: :dtr_smart_app_static_dinner_workflow
|
113
|
+
group from: :dtr_smart_app_adaptive_dinner_workflow
|
104
114
|
end
|
115
|
+
group from: :dtr_smart_app_questionnaire_ms
|
105
116
|
end
|
106
117
|
end
|
@@ -21,7 +21,7 @@ module DaVinciDTRTestKit
|
|
21
21
|
# Overwrite the OAuth URIs returned by the reference server to point to the suite endpoints instead
|
22
22
|
oauth_uris_url = 'http://fhir-registry.smarthealthit.org/StructureDefinition/oauth-uris'
|
23
23
|
base_url = MockAuthorization.env_base_url(env, METADATA_PATH)
|
24
|
-
sec_ext = cs.rest.first&.security&.extension&.delete_if { |e| e.url == oauth_uris_url }
|
24
|
+
sec_ext = cs.rest.first&.security&.extension&.delete_if { |e| e.url == oauth_uris_url } # rubocop:disable Style/SafeNavigationChainLength
|
25
25
|
sec_ext&.push(
|
26
26
|
FHIR::Extension.new(
|
27
27
|
url: oauth_uris_url,
|
@@ -4,7 +4,26 @@ module DaVinciDTRTestKit
|
|
4
4
|
module MockPayer
|
5
5
|
class FullEHRNextQuestionEndpoint < NextQuestionEndpoint
|
6
6
|
def test_run_identifier
|
7
|
-
request.
|
7
|
+
return request.params[:session_path] if request.params[:session_path].present?
|
8
|
+
|
9
|
+
UDAPSecurityTestKit::MockUDAPServer.issued_token_to_client_id(
|
10
|
+
request.headers['authorization']&.delete_prefix('Bearer ')
|
11
|
+
)
|
12
|
+
end
|
13
|
+
|
14
|
+
def make_response
|
15
|
+
return if response.status == 401 # set in update_result (expired token handling there)
|
16
|
+
|
17
|
+
super
|
18
|
+
end
|
19
|
+
|
20
|
+
def update_result
|
21
|
+
if UDAPSecurityTestKit::MockUDAPServer.request_has_expired_token?(request)
|
22
|
+
UDAPSecurityTestKit::MockUDAPServer.update_response_for_expired_token(response, 'Bearer token')
|
23
|
+
return
|
24
|
+
end
|
25
|
+
|
26
|
+
super
|
8
27
|
end
|
9
28
|
end
|
10
29
|
end
|
data/lib/davinci_dtr_test_kit/endpoints/mock_payer/full_ehr_questionnaire_package_endpoint.rb
CHANGED
@@ -1,10 +1,30 @@
|
|
1
|
+
require 'udap_security_test_kit'
|
1
2
|
require_relative 'questionnaire_package_endpoint'
|
2
3
|
|
3
4
|
module DaVinciDTRTestKit
|
4
5
|
module MockPayer
|
5
6
|
class FullEHRQuestionnairePackageEndpoint < QuestionnairePackageEndpoint
|
6
7
|
def test_run_identifier
|
7
|
-
request.
|
8
|
+
return request.params[:session_path] if request.params[:session_path].present?
|
9
|
+
|
10
|
+
UDAPSecurityTestKit::MockUDAPServer.issued_token_to_client_id(
|
11
|
+
request.headers['authorization']&.delete_prefix('Bearer ')
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
def make_response
|
16
|
+
return if response.status == 401 # set in update_result (expired token handling there)
|
17
|
+
|
18
|
+
super
|
19
|
+
end
|
20
|
+
|
21
|
+
def update_result
|
22
|
+
if UDAPSecurityTestKit::MockUDAPServer.request_has_expired_token?(request)
|
23
|
+
UDAPSecurityTestKit::MockUDAPServer.update_response_for_expired_token(response, 'Bearer token')
|
24
|
+
return
|
25
|
+
end
|
26
|
+
|
27
|
+
super
|
8
28
|
end
|
9
29
|
end
|
10
30
|
end
|
@@ -22,6 +22,29 @@ module DaVinciDTRTestKit
|
|
22
22
|
response.body = build_questionnaire_next_response.to_json
|
23
23
|
end
|
24
24
|
|
25
|
+
def custom_next_question_requests
|
26
|
+
requests_repo.tagged_requests(test_run.test_session_id, ["custom_#{DaVinciDTRTestKit::CLIENT_NEXT_TAG}"])
|
27
|
+
end
|
28
|
+
|
29
|
+
def custom_questionnaires
|
30
|
+
return @custom_questionnaires unless @custom_questionnaires.nil?
|
31
|
+
|
32
|
+
questionnaires = JSON.parse(result.input_json)
|
33
|
+
.find { |input| input['name'].include?('custom_next_question_questionnaires') }
|
34
|
+
&.dig('value')
|
35
|
+
return unless questionnaires
|
36
|
+
|
37
|
+
@custom_questionnaires = [JSON.parse(questionnaires)].flatten.compact
|
38
|
+
end
|
39
|
+
|
40
|
+
def next_custom_questionnaire
|
41
|
+
custom_questionnaires[custom_next_question_requests.length]
|
42
|
+
end
|
43
|
+
|
44
|
+
def complete_questionnaire?
|
45
|
+
custom_questionnaires && next_custom_questionnaire.blank?
|
46
|
+
end
|
47
|
+
|
25
48
|
def update_result
|
26
49
|
results_repo.update_result(result.id, 'pass') unless test.config.options[:accepts_multiple_requests]
|
27
50
|
end
|
@@ -41,9 +64,9 @@ module DaVinciDTRTestKit
|
|
41
64
|
|
42
65
|
questionnaire_response_param = FHIR::Parameters::Parameter.new(name: 'return', resource: questionnaire_response)
|
43
66
|
|
44
|
-
if questionnaire_last_dinner_order_question_present?(questionnaire_response)
|
67
|
+
if complete_questionnaire? || questionnaire_last_dinner_order_question_present?(questionnaire_response)
|
45
68
|
# change the questionnaire response status to completed and return the parameters
|
46
|
-
return
|
69
|
+
return complete_questionnaire(questionnaire_response)
|
47
70
|
end
|
48
71
|
|
49
72
|
next_questionnaire = determine_next_questionnaire(questionnaire_response, test.id)
|
@@ -103,15 +126,17 @@ module DaVinciDTRTestKit
|
|
103
126
|
end
|
104
127
|
|
105
128
|
def determine_next_questionnaire(questionnaire_response, test_id)
|
129
|
+
if custom_questionnaires
|
130
|
+
FHIR.from_contents(next_custom_questionnaire.to_json)
|
106
131
|
# Retrieve the selected option from the response and determine the next set of questions
|
107
|
-
|
132
|
+
elsif questionnaire_dinner_order_selection_present?(questionnaire_response)
|
108
133
|
dinner_question_from_selection(questionnaire_response, test_id)
|
109
134
|
else
|
110
135
|
Fixtures.next_question_for_test(test_id)
|
111
136
|
end
|
112
137
|
end
|
113
138
|
|
114
|
-
def
|
139
|
+
def complete_questionnaire(questionnaire_response)
|
115
140
|
update_questionnaire_response(questionnaire_response)
|
116
141
|
questionnaire_response
|
117
142
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'udap_security_test_kit'
|
4
|
+
require 'smart_app_launch_test_kit'
|
5
|
+
require_relative '../../urls'
|
6
|
+
require_relative '../../tags'
|
7
|
+
|
8
|
+
module DaVinciDTRTestKit
|
9
|
+
module MockUdapSmartServer
|
10
|
+
class TokenEndpoint < Inferno::DSL::SuiteEndpoint
|
11
|
+
include SMARTAppLaunch::MockSMARTServer::SMARTTokenResponseCreation
|
12
|
+
include UDAPSecurityTestKit::MockUDAPServer::UDAPTokenResponseCreation
|
13
|
+
|
14
|
+
def test_run_identifier
|
15
|
+
UDAPSecurityTestKit::MockUDAPServer.client_id_from_client_assertion(request.params[:client_assertion])
|
16
|
+
end
|
17
|
+
|
18
|
+
def make_response
|
19
|
+
if request.params[:udap].present?
|
20
|
+
make_udap_client_credential_token_response
|
21
|
+
else
|
22
|
+
make_smart_client_credential_token_response
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def update_result
|
27
|
+
nil # never update for now
|
28
|
+
end
|
29
|
+
|
30
|
+
def tags
|
31
|
+
type_tag = request.params[:udap].present? ? UDAPSecurityTestKit::UDAP_TAG : SMARTAppLaunch::SMART_TAG
|
32
|
+
[UDAPSecurityTestKit::TOKEN_TAG, UDAPSecurityTestKit::CLIENT_CREDENTIALS_TAG, type_tag]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|