davinci_dtr_test_kit 0.14.2 → 0.15.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.
Files changed (158) hide show
  1. checksums.yaml +4 -4
  2. data/config/presets/full_ehr_postman_dinner_order_example_postman.json +19 -0
  3. data/config/presets/full_ehr_postman_respiratory_device_example.json +15 -0
  4. data/config/presets/light_ehr_ref_server_local.json +105 -0
  5. data/config/presets/light_ehr_ref_server_prod.json +85 -0
  6. data/config/presets/payer_server_adaptive_client_flow.json +37 -0
  7. data/config/presets/payer_server_adaptive_manual_flow.json +44 -0
  8. data/config/presets/payer_server_run_against_smart_app_tests.json +35 -0
  9. data/config/presets/smart_app_postman_dinner_order_example.json +44 -0
  10. data/config/presets/smart_app_postman_respiratory_device_example.json +43 -0
  11. data/lib/davinci_dtr_test_kit/auth_groups/token_validation_test.rb +1 -1
  12. data/lib/davinci_dtr_test_kit/client_groups/custom_static/dtr_custom_questionnaire_expressions_test.rb +22 -0
  13. data/lib/davinci_dtr_test_kit/client_groups/custom_static/dtr_custom_questionnaire_extensions_test.rb +19 -0
  14. data/lib/davinci_dtr_test_kit/client_groups/custom_static/dtr_custom_questionnaire_libraries_test.rb +21 -0
  15. data/lib/davinci_dtr_test_kit/client_groups/custom_static/dtr_custom_questionnaire_package_validation_test.rb +39 -0
  16. data/lib/davinci_dtr_test_kit/client_groups/custom_static/dtr_full_ehr_custom_static_workflow_group.rb +121 -0
  17. data/lib/davinci_dtr_test_kit/client_groups/custom_static/dtr_smart_app_custom_static_workflow_group.rb +91 -0
  18. data/lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/{dtr_adaptive_questionnaire_completion_group.rb → dtr_adaptive_completion_group.rb} +4 -4
  19. data/lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/{dtr_adaptive_questionnaire_followup_questions_group.rb → dtr_adaptive_followup_questions_group.rb} +4 -4
  20. data/lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/{dtr_adaptive_questionnaire_next_question_request_test.rb → dtr_adaptive_next_question_request_test.rb} +2 -2
  21. data/lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/{dtr_adaptive_questionnaire_next_question_request_validation_test.rb → dtr_adaptive_next_question_request_validation_test.rb} +2 -2
  22. data/lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/{dtr_adaptive_questionnaire_next_question_retrieval_group.rb → dtr_adaptive_next_question_retrieval_group.rb} +8 -8
  23. data/lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/{dtr_adaptive_questionnaire_response_validation_test.rb → dtr_adaptive_response_validation_test.rb} +3 -3
  24. data/lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/{dtr_full_ehr_adaptive_dinner_questionnaire_workflow_group.rb → dtr_full_ehr_adaptive_dinner_workflow_group.rb} +12 -12
  25. data/lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/{dtr_full_ehr_adaptive_questionnaire_initial_retrieval_group.rb → dtr_full_ehr_adaptive_initial_retrieval_group.rb} +10 -10
  26. data/lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/{dtr_full_ehr_adaptive_questionnaire_request_test.rb → dtr_full_ehr_adaptive_request_test.rb} +2 -2
  27. data/lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/{dtr_smart_app_questionnaire_workflow_group.rb → dtr_smart_app_adaptive_dinner_workflow_group.rb} +24 -18
  28. data/lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/dtr_smart_app_adaptive_initial_retrieval_group.rb +24 -0
  29. data/lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/{dtr_smart_app_adaptive_questionnaire_request_test.rb → dtr_smart_app_adaptive_request_test.rb} +2 -2
  30. data/lib/davinci_dtr_test_kit/client_groups/dinner_static/{dtr_full_ehr_questionnaire_workflow_group.rb → dtr_full_ehr_static_dinner_workflow_group.rb} +13 -13
  31. data/lib/davinci_dtr_test_kit/client_groups/dinner_static/{dtr_smart_app_questionnaire_workflow_group.rb → dtr_smart_app_static_dinner_workflow_group.rb} +18 -13
  32. data/lib/davinci_dtr_test_kit/client_groups/{full_ehr/dtr_full_ehr_rendering_enabled_questions_attestation_test.rb → dinner_static/dtr_static_dinner_enabled_questions_attestation_test.rb} +2 -2
  33. data/lib/davinci_dtr_test_kit/client_groups/full_ehr/dtr_full_ehr_launch_attestation_test.rb +8 -3
  34. data/lib/davinci_dtr_test_kit/client_groups/full_ehr/dtr_full_ehr_prepopulation_attestation_test.rb +1 -1
  35. data/lib/davinci_dtr_test_kit/client_groups/full_ehr/dtr_full_ehr_prepopulation_override_attestation_test.rb +1 -1
  36. data/lib/davinci_dtr_test_kit/client_groups/full_ehr/dtr_full_ehr_questionnaire_package_request_test.rb +1 -1
  37. data/lib/davinci_dtr_test_kit/client_groups/full_ehr/dtr_full_ehr_questionnaire_response_conformance_test.rb +6 -1
  38. data/lib/davinci_dtr_test_kit/client_groups/full_ehr/dtr_full_ehr_questionnaire_response_correctness_test.rb +10 -22
  39. data/lib/davinci_dtr_test_kit/client_groups/full_ehr/dtr_full_ehr_saving_questionnaire_response_group.rb +4 -4
  40. data/lib/davinci_dtr_test_kit/client_groups/full_ehr/dtr_full_ehr_store_attestation_test.rb +1 -1
  41. data/lib/davinci_dtr_test_kit/client_groups/light_ehr/dtr_smart_ehr_launch.rb +18 -0
  42. data/lib/davinci_dtr_test_kit/client_groups/light_ehr/fhir_context_coverage_test.rb +42 -0
  43. data/lib/davinci_dtr_test_kit/client_groups/light_ehr/fhir_context_references_test.rb +60 -0
  44. data/lib/davinci_dtr_test_kit/client_groups/light_ehr/fhir_launch_context_test.rb +23 -0
  45. data/lib/davinci_dtr_test_kit/client_groups/{resp_assist_device/dtr_questionnaire_package_group.rb → respiratory/dtr_respiratory_questionnaire_package_group.rb} +5 -5
  46. data/lib/davinci_dtr_test_kit/client_groups/{resp_assist_device/dtr_resp_questionnaire_package_request_test.rb → respiratory/dtr_respiratory_questionnaire_package_request_test.rb} +2 -2
  47. data/lib/davinci_dtr_test_kit/client_groups/{resp_assist_device/dtr_questionnaire_response_group.rb → respiratory/dtr_respiratory_questionnaire_response_group.rb} +7 -7
  48. data/lib/davinci_dtr_test_kit/client_groups/{resp_assist_device/dtr_questionnaire_response_save_test.rb → respiratory/dtr_respiratory_questionnaire_response_save_test.rb} +2 -2
  49. data/lib/davinci_dtr_test_kit/client_groups/{resp_assist_device/dtr_questionnaire_rendering_attestation_test.rb → respiratory/dtr_respiratory_rendering_attestation_test.rb} +2 -2
  50. data/lib/davinci_dtr_test_kit/client_groups/respiratory/dtr_respiratory_rendering_group.rb +14 -0
  51. data/lib/davinci_dtr_test_kit/client_groups/{resp_assist_device/dtr_smart_app_questionnaire_workflow_group.rb → respiratory/dtr_smart_app_respiratory_workflow_group.rb} +8 -8
  52. data/lib/davinci_dtr_test_kit/client_groups/shared/dtr_prepopulation_attestation_test.rb +31 -0
  53. data/lib/davinci_dtr_test_kit/client_groups/shared/dtr_prepopulation_override_attestation_test.rb +35 -0
  54. data/lib/davinci_dtr_test_kit/client_groups/shared/dtr_questionnaire_package_request_validation_test.rb +1 -1
  55. data/lib/davinci_dtr_test_kit/client_groups/shared/dtr_questionnaire_response_basic_conformance_test.rb +8 -4
  56. data/lib/davinci_dtr_test_kit/client_groups/shared/{dtr_questionnaire_response_pre_population_test.rb → dtr_questionnaire_response_prepopulation_test.rb} +2 -2
  57. data/lib/davinci_dtr_test_kit/client_groups/shared/dtr_rendering_attestation_test.rb +30 -0
  58. data/lib/davinci_dtr_test_kit/client_groups/smart_app/dtr_smart_app_prepopulation_attestation_test.rb +1 -1
  59. data/lib/davinci_dtr_test_kit/client_groups/smart_app/dtr_smart_app_prepopulation_override_attestation_test.rb +1 -1
  60. data/lib/davinci_dtr_test_kit/client_groups/{dinner_static/dtr_smart_app_dinner_questionnaire_package_request_test.rb → smart_app/dtr_smart_app_questionnaire_package_request_test.rb} +6 -6
  61. data/lib/davinci_dtr_test_kit/client_groups/smart_app/dtr_smart_app_questionnaire_response_correctness_test.rb +28 -0
  62. data/lib/davinci_dtr_test_kit/client_groups/smart_app/dtr_smart_app_questionnaire_response_save_test.rb +2 -2
  63. data/lib/davinci_dtr_test_kit/client_groups/smart_app/dtr_smart_app_saving_questionnaire_response_group.rb +3 -7
  64. data/lib/davinci_dtr_test_kit/cql_test.rb +58 -0
  65. data/lib/davinci_dtr_test_kit/docs/dtr_light_ehr_suite_description_v201.md +9 -6
  66. data/lib/davinci_dtr_test_kit/dtr_full_ehr_suite.rb +19 -6
  67. data/lib/davinci_dtr_test_kit/dtr_light_ehr_suite.rb +42 -36
  68. data/lib/davinci_dtr_test_kit/dtr_payer_server_suite.rb +0 -2
  69. data/lib/davinci_dtr_test_kit/dtr_questionnaire_response_validation.rb +50 -4
  70. data/lib/davinci_dtr_test_kit/dtr_smart_app_suite.rb +9 -9
  71. data/lib/davinci_dtr_test_kit/endpoints/mock_authorization.rb +10 -2
  72. data/lib/davinci_dtr_test_kit/endpoints/mock_ehr.rb +17 -1
  73. data/lib/davinci_dtr_test_kit/endpoints/mock_payer/questionnaire_package_endpoint.rb +7 -1
  74. data/lib/davinci_dtr_test_kit/fixtures.rb +6 -6
  75. data/lib/davinci_dtr_test_kit/igs/davinci_dtr_2.0.1.tgz +0 -0
  76. data/lib/davinci_dtr_test_kit/metadata.rb +104 -0
  77. data/lib/davinci_dtr_test_kit/payer_server_groups/adaptive_form_libraries_test.rb +1 -1
  78. data/lib/davinci_dtr_test_kit/payer_server_groups/adaptive_form_questionnaire_expressions_test.rb +1 -1
  79. data/lib/davinci_dtr_test_kit/payer_server_groups/adaptive_form_questionnaire_extensions_test.rb +1 -1
  80. data/lib/davinci_dtr_test_kit/payer_server_groups/payer_server_adaptive_response_bundles_validation_test.rb +1 -1
  81. data/lib/davinci_dtr_test_kit/payer_server_groups/payer_server_adaptive_response_search_validation_test.rb +1 -1
  82. data/lib/davinci_dtr_test_kit/payer_server_groups/payer_server_adaptive_response_validation_test.rb +4 -15
  83. data/lib/davinci_dtr_test_kit/payer_server_groups/payer_server_static_group.rb +1 -1
  84. data/lib/davinci_dtr_test_kit/payer_server_groups/static_form_libraries_test.rb +1 -1
  85. data/lib/davinci_dtr_test_kit/payer_server_groups/static_form_questionnaire_expressions_test.rb +1 -1
  86. data/lib/davinci_dtr_test_kit/payer_server_groups/static_form_questionnaire_extensions_test.rb +1 -1
  87. data/lib/davinci_dtr_test_kit/payer_server_groups/static_form_request_test.rb +1 -1
  88. data/lib/davinci_dtr_test_kit/payer_server_groups/static_form_response_validation_test.rb +4 -15
  89. data/lib/davinci_dtr_test_kit/profiles/communication_request/communication_request_must_support_test.rb +46 -0
  90. data/lib/davinci_dtr_test_kit/profiles/communication_request/communication_request_read.rb +6 -3
  91. data/lib/davinci_dtr_test_kit/profiles/communication_request/communication_request_validation.rb +9 -8
  92. data/lib/davinci_dtr_test_kit/profiles/communication_request/metadata.yml +135 -0
  93. data/lib/davinci_dtr_test_kit/profiles/communication_request_group.rb +9 -0
  94. data/lib/davinci_dtr_test_kit/profiles/coverage/coverage_must_support_test.rb +54 -0
  95. data/lib/davinci_dtr_test_kit/profiles/coverage/coverage_read.rb +5 -3
  96. data/lib/davinci_dtr_test_kit/profiles/coverage/coverage_validation.rb +9 -8
  97. data/lib/davinci_dtr_test_kit/profiles/coverage/metadata.yml +133 -0
  98. data/lib/davinci_dtr_test_kit/profiles/coverage_group.rb +8 -0
  99. data/lib/davinci_dtr_test_kit/profiles/device_request/device_request_must_support_test.rb +45 -0
  100. data/lib/davinci_dtr_test_kit/profiles/device_request/device_request_read.rb +6 -3
  101. data/lib/davinci_dtr_test_kit/profiles/device_request/device_request_validation.rb +9 -8
  102. data/lib/davinci_dtr_test_kit/profiles/device_request/metadata.yml +130 -0
  103. data/lib/davinci_dtr_test_kit/profiles/device_request_group.rb +9 -0
  104. data/lib/davinci_dtr_test_kit/profiles/encounter/encounter_must_support_test.rb +58 -0
  105. data/lib/davinci_dtr_test_kit/profiles/encounter/encounter_read.rb +6 -3
  106. data/lib/davinci_dtr_test_kit/profiles/encounter/encounter_validation.rb +9 -8
  107. data/lib/davinci_dtr_test_kit/profiles/encounter/metadata.yml +169 -0
  108. data/lib/davinci_dtr_test_kit/profiles/encounter_group.rb +9 -0
  109. data/lib/davinci_dtr_test_kit/profiles/medication_request/medication_request_must_support_test.rb +50 -0
  110. data/lib/davinci_dtr_test_kit/profiles/medication_request/medication_request_read.rb +6 -3
  111. data/lib/davinci_dtr_test_kit/profiles/medication_request/medication_request_validation.rb +9 -8
  112. data/lib/davinci_dtr_test_kit/profiles/medication_request/metadata.yml +159 -0
  113. data/lib/davinci_dtr_test_kit/profiles/medication_request_group.rb +9 -0
  114. data/lib/davinci_dtr_test_kit/profiles/nutrition_order/metadata.yml +94 -0
  115. data/lib/davinci_dtr_test_kit/profiles/nutrition_order/nutrition_order_must_support_test.rb +45 -0
  116. data/lib/davinci_dtr_test_kit/profiles/nutrition_order/nutrition_order_read.rb +6 -3
  117. data/lib/davinci_dtr_test_kit/profiles/nutrition_order/nutrition_order_validation.rb +9 -8
  118. data/lib/davinci_dtr_test_kit/profiles/nutrition_order_group.rb +9 -0
  119. data/lib/davinci_dtr_test_kit/profiles/questionnaire_response/questionnaire_response_context_search.rb +3 -1
  120. data/lib/davinci_dtr_test_kit/profiles/questionnaire_response/questionnaire_response_create.rb +1 -0
  121. data/lib/davinci_dtr_test_kit/profiles/questionnaire_response/questionnaire_response_must_support_test.rb +54 -0
  122. data/lib/davinci_dtr_test_kit/profiles/questionnaire_response/questionnaire_response_patient_search.rb +3 -1
  123. data/lib/davinci_dtr_test_kit/profiles/questionnaire_response/questionnaire_response_read.rb +2 -1
  124. data/lib/davinci_dtr_test_kit/profiles/questionnaire_response/questionnaire_response_update.rb +1 -0
  125. data/lib/davinci_dtr_test_kit/profiles/questionnaire_response/questionnaire_response_validation.rb +1 -1
  126. data/lib/davinci_dtr_test_kit/profiles/questionnaire_response_group.rb +11 -1
  127. data/lib/davinci_dtr_test_kit/profiles/service_request/metadata.yml +140 -0
  128. data/lib/davinci_dtr_test_kit/profiles/service_request/service_request_must_support_test.rb +47 -0
  129. data/lib/davinci_dtr_test_kit/profiles/service_request/service_request_read.rb +6 -3
  130. data/lib/davinci_dtr_test_kit/profiles/service_request/service_request_validation.rb +9 -8
  131. data/lib/davinci_dtr_test_kit/profiles/service_request_group.rb +9 -0
  132. data/lib/davinci_dtr_test_kit/profiles/task/metadata.yml +165 -0
  133. data/lib/davinci_dtr_test_kit/profiles/task/task_create.rb +1 -0
  134. data/lib/davinci_dtr_test_kit/profiles/task/task_must_support_test.rb +46 -0
  135. data/lib/davinci_dtr_test_kit/profiles/task/task_read.rb +6 -3
  136. data/lib/davinci_dtr_test_kit/profiles/task/task_update.rb +1 -0
  137. data/lib/davinci_dtr_test_kit/profiles/task/task_validation.rb +9 -8
  138. data/lib/davinci_dtr_test_kit/profiles/task_group.rb +11 -1
  139. data/lib/davinci_dtr_test_kit/profiles/vision_prescription/metadata.yml +107 -0
  140. data/lib/davinci_dtr_test_kit/profiles/vision_prescription/vision_prescription_must_support_test.rb +54 -0
  141. data/lib/davinci_dtr_test_kit/profiles/vision_prescription/vision_prescription_read.rb +6 -3
  142. data/lib/davinci_dtr_test_kit/profiles/vision_prescription/vision_prescription_validation.rb +9 -8
  143. data/lib/davinci_dtr_test_kit/profiles/vision_prescription_group.rb +9 -0
  144. data/lib/davinci_dtr_test_kit/read_test.rb +5 -0
  145. data/lib/davinci_dtr_test_kit/requirements/davinci-dtr-test-kit_out_of_scope_requirements.csv +13 -0
  146. data/lib/davinci_dtr_test_kit/requirements/davinci-dtr-test-kit_requirements.csv +374 -0
  147. data/lib/davinci_dtr_test_kit/requirements/generated/davinci-dtr-test-kit_requirements_coverage.csv +372 -0
  148. data/lib/davinci_dtr_test_kit/urls.rb +1 -0
  149. data/lib/davinci_dtr_test_kit/version.rb +2 -1
  150. data/lib/davinci_dtr_test_kit.rb +2 -0
  151. data/lib/inferno_requirements_tools/ext/inferno_core/runnable.rb +22 -0
  152. data/lib/inferno_requirements_tools/rake/rakefile_template +31 -0
  153. data/lib/inferno_requirements_tools/tasks/requirements_coverage.rb +284 -0
  154. data/lib/requirements_config.yaml +25 -0
  155. metadata +88 -37
  156. data/lib/davinci_dtr_test_kit/client_groups/dinner_adaptive/dtr_smart_app_adaptive_questionnaire_initial_retrieval_group.rb +0 -24
  157. data/lib/davinci_dtr_test_kit/client_groups/resp_assist_device/dtr_questionnaire_rendering_group.rb +0 -14
  158. data/lib/davinci_dtr_test_kit/client_groups/smart_app/dtr_smart_app_rendering_enabled_questions_attestation_test.rb +0 -30
@@ -0,0 +1,31 @@
1
+ require 'securerandom'
2
+ require_relative '../../urls'
3
+
4
+ module DaVinciDTRTestKit
5
+ class DTRPrepopulationAttestationTest < Inferno::Test
6
+ include URLs
7
+
8
+ id :dtr_prepopulation_attest
9
+ title 'Check that the client pre-populates the Questionnaire (Attestation)'
10
+ description %(
11
+ Validate that pre-population of patient's information occurs as expected.
12
+
13
+ Note that the test requires that two questions be pre-populated so that both a pre-populated
14
+ and an overridden answer can be demonstrated when the QuestionnaireResponse is generated.
15
+ )
16
+ run do
17
+ random_id = SecureRandom.uuid
18
+ wait(
19
+ identifier: random_id,
20
+ message: %(
21
+ I attest that the DTR application has automatically filled in at least two questions with
22
+ values determined by the questionnaire's pre-population logic executed on data in the EHR.
23
+
24
+ [Click here](#{resume_pass_url}?token=#{random_id}) if the above statement is **true**.
25
+
26
+ [Click here](#{resume_fail_url}?token=#{random_id}) if the above statement is **false**.
27
+ )
28
+ )
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,35 @@
1
+ require 'securerandom'
2
+ require_relative '../../urls'
3
+
4
+ module DaVinciDTRTestKit
5
+ class DTRPrepopulationOverrideAttestationTest < Inferno::Test
6
+ include URLs
7
+
8
+ id :dtr_prepopulation_override_attest
9
+ title 'Check that the user can manually populate answers in the Questionnaire (Attestation)'
10
+ description %(
11
+ Validate that the user can edit the rendered form to provide answers, including
12
+ - Providing an answer for an unanswered question.
13
+ - Overridding a pre-populated answer with a manual answer.
14
+
15
+ Note that at least one pre-populated answer must remain un-altered to demonstrate
16
+ its representaton in the resulting QuestionnaireResponse.
17
+ )
18
+ run do
19
+ random_id = SecureRandom.uuid
20
+ wait(
21
+ identifier: random_id,
22
+ message: %(
23
+ I attest that the user has done the following while filling out the form:
24
+ - Changed a pre-populated answer to a new value.
25
+ - Provided an answer to a question that was not pre-populated.
26
+ - Left a pre-populated answer unchanged.
27
+
28
+ [Click here](#{resume_pass_url}?token=#{random_id}) if the above statement is **true**.
29
+
30
+ [Click here](#{resume_fail_url}?token=#{random_id}) if the above statement is **false**.
31
+ )
32
+ )
33
+ end
34
+ end
35
+ end
@@ -4,7 +4,7 @@ module DaVinciDTRTestKit
4
4
  class DTRQuestionnairePackageValidationTest < Inferno::Test
5
5
  include URLs
6
6
 
7
- id :dtr_questionnaire_package_request_validation
7
+ id :dtr_qp_request_validation
8
8
  title 'Questionnaire Package request is valid'
9
9
  description %(
10
10
  This test validates the conformance of the client's request to the
@@ -6,12 +6,16 @@ module DaVinciDTRTestKit
6
6
  include URLs
7
7
  include DTRQuestionnaireResponseValidation
8
8
 
9
- id :dtr_questionnaire_response_basic_conformance
9
+ id :dtr_qr_basic_conformance
10
10
  title 'QuestionnaireResponse is conformant'
11
11
  description %(
12
- This test validates the conformance of QuestionnaireResponse representing the
13
- completed questionnaire. It verifies that the QuestionnaireResponse conforms
14
- to the DTR Questionnaire Response resource profile.
12
+ This test validates the conformance of a `QuestionnaireResponse` representing a completed questionnaire.
13
+ It ensures that the `QuestionnaireResponse` adheres to the appropriate profile based on its type:
14
+
15
+ - **Static QuestionnaireResponse:** Must conform to the [DTR Questionnaire Response](https://hl7.org/fhir/us/davinci-dtr/STU2/StructureDefinition-dtr-questionnaireresponse.html)
16
+ profile.
17
+ - **Adaptive QuestionnaireResponse:** Must conform to the [Adaptive Questionnaire Response](http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaireresponse-adapt)
18
+ profile.
15
19
  )
16
20
 
17
21
  def profile_url
@@ -2,10 +2,10 @@ require_relative '../../dtr_questionnaire_response_validation'
2
2
  require_relative '../../fixtures'
3
3
 
4
4
  module DaVinciDTRTestKit
5
- class DTRQuestionnaireResponsePrePopulationTest < Inferno::Test
5
+ class DTRQuestionnaireResponsePrepopulationTest < Inferno::Test
6
6
  include DTRQuestionnaireResponseValidation
7
7
 
8
- id :dtr_questionnaire_response_pre_population
8
+ id :dtr_qr_prepopulation
9
9
  title 'QuestionnaireResponse pre-population and user overrides are conformant'
10
10
  description %(
11
11
  This test validates the conformance of the client's pre-population of the QuestionnaireResponse.
@@ -0,0 +1,30 @@
1
+ require 'securerandom'
2
+ require_relative '../../urls'
3
+
4
+ module DaVinciDTRTestKit
5
+ class DTRRenderingAttestationTest < Inferno::Test
6
+ include URLs
7
+
8
+ id :dtr_rendering_attest
9
+ title 'Check that the client renders the Questionnaire (Attestation)'
10
+ description %(
11
+ The tester will attest to the ability of the client to appropriately render the
12
+ Questionnaire and allow user interaction.
13
+ )
14
+ run do
15
+ random_id = SecureRandom.uuid
16
+ wait(
17
+ identifier: random_id,
18
+ message: %(
19
+ I attest that the DTR client application has displayed the tester-provided Questionnaire
20
+ appropriately, following all rendering and formating directives within the Questionnaire
21
+ and allowing the user to interact with the questions in the form.
22
+
23
+ [Click here](#{resume_pass_url}?token=#{random_id}) if the above statement is **true**.
24
+
25
+ [Click here](#{resume_fail_url}?token=#{random_id}) if the above statement is **false**.
26
+ )
27
+ )
28
+ end
29
+ end
30
+ end
@@ -5,7 +5,7 @@ module DaVinciDTRTestKit
5
5
  class DTRSmartAppPrepopulationAttestationTest < Inferno::Test
6
6
  include URLs
7
7
 
8
- id :dtr_smart_app_prepopulation_attestation
8
+ id :dtr_smart_app_prepopulation_attest
9
9
  title 'Check that the client pre-populates the questionnaire (Attestation)'
10
10
  description %(
11
11
  Validate that pre-population of patient name information occurs as expected.
@@ -5,7 +5,7 @@ module DaVinciDTRTestKit
5
5
  class DTRSmartAppPrepopulationOverrideAttestationTest < Inferno::Test
6
6
  include URLs
7
7
 
8
- id :dtr_smart_app_prepopulation_override_attestation
8
+ id :dtr_smart_app_prepopulation_override_attest
9
9
  title 'Validate the user can override pre-populated data (Attestation)'
10
10
  description %(
11
11
  Validate that the user can edit a pre-populated item and replace it with another value.
@@ -2,10 +2,10 @@ require 'base64'
2
2
  require_relative '../../urls'
3
3
 
4
4
  module DaVinciDTRTestKit
5
- class DTRSmartAppDinnerQuestionnairePackageRequestTest < Inferno::Test
5
+ class DTRSmartAppQuestionnairePackageRequestTest < Inferno::Test
6
6
  include URLs
7
7
 
8
- id :dtr_smart_app_dinner_questionnaire_package_request
8
+ id :dtr_smart_app_qp_request
9
9
  title 'Invoke the DTR Questionnaire Package operation'
10
10
  description %(
11
11
  Inferno will wait for a DTR questionnaire package request from the client. Upon receipt, Inferno will generate and
@@ -24,7 +24,7 @@ module DaVinciDTRTestKit
24
24
  description: 'Required if "Launch from Inferno" is selected'
25
25
  input :static_smart_patient_id,
26
26
  optional: true,
27
- title: 'SMART App Launch Patient ID (Dinner Static)',
27
+ title: 'SMART App Launch Patient ID',
28
28
  type: 'text',
29
29
  description: %(
30
30
  Patient instance ID to be provided by Inferno as the patient as a part of the SMART App Launch.
@@ -32,7 +32,7 @@ module DaVinciDTRTestKit
32
32
  default: 'pat015'
33
33
  input :static_smart_fhir_context,
34
34
  optional: true,
35
- title: 'SMART App Launch fhirContext (Dinner Static)',
35
+ title: 'SMART App Launch fhirContext',
36
36
  type: 'textarea',
37
37
  description: %(
38
38
  References to be provided by Inferno as the fhirContext as a part of the SMART App
@@ -43,10 +43,10 @@ module DaVinciDTRTestKit
43
43
  { reference: 'DeviceRequest/devreqe0470' }])
44
44
  input :static_ehr_bundle,
45
45
  optional: true,
46
- title: 'EHR-available resources (Dinner Static)',
46
+ title: 'EHR-available resources',
47
47
  type: 'textarea',
48
48
  description: %(
49
- Resources available from the EHR needed to drive the dinner static workflow.
49
+ Resources available from the EHR needed to drive this workflow.
50
50
  Formatted as a FHIR bundle that contains resources, each with an ID property populated. Each
51
51
  instance present will be available for retrieval from Inferno at the endpoint:
52
52
  <fhir-base>/<resource type>/<instance id>
@@ -0,0 +1,28 @@
1
+ require_relative '../../dtr_questionnaire_response_validation'
2
+
3
+ module DaVinciDTRTestKit
4
+ class DTRSmartAppQuestionnaireResponseCorrectnessTest < Inferno::Test
5
+ include DTRQuestionnaireResponseValidation
6
+
7
+ id :dtr_smart_app_qr_correctness
8
+ title 'QuestionnaireResponse is correct for the workflow'
9
+ description %(
10
+ Verify that the QuestionnaireResponse
11
+ - Is for the Questionnaire provided by the tester.
12
+ - Has source extensions demonstrating answers that are manually entered,
13
+ automatically pre-populated, and manually overridden.
14
+ - Contains answers for all required items.
15
+ )
16
+ input :custom_questionnaire_package_response,
17
+ title: 'Custom Questionnaire Package Response JSON',
18
+ description: %(
19
+ A JSON PackageBundle may be provided here to replace Inferno's response to the
20
+ $questionnaire-package request.
21
+ ),
22
+ type: 'textarea'
23
+
24
+ run do
25
+ validate_questionnaire_response_correctness(request.request_body, custom_questionnaire_package_response)
26
+ end
27
+ end
28
+ end
@@ -4,7 +4,7 @@ module DaVinciDTRTestKit
4
4
  class DTRSmartAppQuestionnaireResponseSaveTest < Inferno::Test
5
5
  include URLs
6
6
 
7
- id :dtr_smart_app_questionnaire_response_save
7
+ id :dtr_smart_app_qr_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.
@@ -12,7 +12,7 @@ module DaVinciDTRTestKit
12
12
  input :client_id
13
13
 
14
14
  def prompt
15
- if config.options[:adaptive]
15
+ if config.options[:adaptive] || config.options[:custom]
16
16
  'Store the completed questionnaire back into the EHR.'
17
17
  else
18
18
  <<~DESCRIPTION
@@ -1,10 +1,9 @@
1
1
  require_relative 'dtr_smart_app_questionnaire_response_save_test'
2
2
  require_relative '../shared/dtr_questionnaire_response_basic_conformance_test'
3
- require_relative '../shared/dtr_questionnaire_response_pre_population_test'
4
3
 
5
4
  module DaVinciDTRTestKit
6
5
  class DTRSmartAppSavingQuestionnaireResponseGroup < Inferno::TestGroup
7
- id :dtr_smart_app_saving_questionnaire_response
6
+ id :dtr_smart_app_saving_qr
8
7
  title 'Saving the QuestionnaireResponse'
9
8
  description %(
10
9
  The tester will complete the questionnaire such that a QuestionnaireResponse is stored
@@ -15,13 +14,10 @@ module DaVinciDTRTestKit
15
14
  run_as_group
16
15
 
17
16
  # Test 1: wait for a QuestionnaireResponse
18
- test from: :dtr_smart_app_questionnaire_response_save,
17
+ test from: :dtr_smart_app_qr_save,
19
18
  receives_request: :questionnaire_response_save
20
19
  # 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,
20
+ test from: :dtr_qr_basic_conformance,
25
21
  uses_request: :questionnaire_response_save
26
22
  end
27
23
  end
@@ -1,5 +1,19 @@
1
1
  module DaVinciDTRTestKit
2
2
  module CQLTest
3
+ STATIC_QUESTIONNAIRE_PACKAGE_BUNDLE_PROFILE = 'http://hl7.org/fhir/us/davinci-dtr/StructureDefinition/DTR-QPackageBundle|2.0.1'.freeze
4
+ STATIC_QUESTIONNAIRE_PACKAGE_PARAMETER_PROFILE = 'http://hl7.org/fhir/us/davinci-dtr/StructureDefinition/dtr-qpackage-output-parameters|2.0.1'.freeze
5
+ ADAPTIVE_QUESTIONNAIRE_PACKAGE_BUNDLE_PROFILE = 'http://hl7.org/fhir/us/davinci-dtr/StructureDefinition/DTR-QPackageBundle|2.0.1'.freeze
6
+ ADAPTIVE_QUESTIONNAIRE_PACKAGE_PARAMETER_PROFILE = 'http://hl7.org/fhir/us/davinci-dtr/StructureDefinition/dtr-qpackage-output-parameters|2.0.1'.freeze
7
+
8
+ def questionnaire_package_profile_urls
9
+ {
10
+ static_bundle: STATIC_QUESTIONNAIRE_PACKAGE_BUNDLE_PROFILE,
11
+ static_parameter: STATIC_QUESTIONNAIRE_PACKAGE_PARAMETER_PROFILE,
12
+ adaptive_bundle: ADAPTIVE_QUESTIONNAIRE_PACKAGE_BUNDLE_PROFILE,
13
+ adaptive_parameter: ADAPTIVE_QUESTIONNAIRE_PACKAGE_PARAMETER_PROFILE
14
+ }
15
+ end
16
+
3
17
  def extension_presence
4
18
  @extension_presence ||= { 'found_min_launch_context' => false, 'found_min_variable' => false,
5
19
  'found_min_pop_context' => false, 'found_min_init_expression' => false,
@@ -320,6 +334,50 @@ module DaVinciDTRTestKit
320
334
  end&.flatten&.compact
321
335
  end
322
336
 
337
+ def perform_questionnaire_package_validation(resource, form = 'static')
338
+ scratch[:"#{form}_questionnaire_bundles"] = extract_questionnaire_bundles(resource)
339
+ validate_questionnaire_package(resource, form)
340
+ assert scratch[:"#{form}_questionnaire_bundles"].present?, 'No questionnaire bundle found in the response'
341
+ end
342
+
343
+ def validate_questionnaire_package(resource, form)
344
+ case resource&.resourceType
345
+ when 'Bundle'
346
+ assert_valid_resource(resource:, profile_url: questionnaire_package_profile_urls[:"#{form}_bundle"])
347
+ when 'Parameters'
348
+ assert_valid_resource(resource:, profile_url: questionnaire_package_profile_urls[:"#{form}_parameter"])
349
+ else
350
+ assert(false, "Unexpected resourceType: #{resource&.resourceType}. Expected Parameters or Bundle")
351
+ end
352
+ end
353
+
354
+ def extract_questionnaire_bundles(resource)
355
+ case resource&.resourceType
356
+ when 'Bundle'
357
+ [resource]
358
+ when 'Parameters'
359
+ extract_bundles_from_parameter(resource)
360
+ else
361
+ []
362
+ end
363
+ end
364
+
365
+ def extract_bundles_from_parameter(parameter)
366
+ return [] if parameter.blank?
367
+
368
+ parameter.parameter&.filter_map do |param|
369
+ param.resource if param.resource&.resourceType == 'Bundle'
370
+ end
371
+ end
372
+
373
+ def extract_questionnaire_from_questionnaire_package(questionnaire_pkg_json, questionnaire_url)
374
+ resource = FHIR.from_contents(questionnaire_pkg_json)
375
+ questionnaire_bundles = extract_questionnaire_bundles(resource)
376
+ questionnaires = extract_questionnaires_from_bundles(questionnaire_bundles)
377
+
378
+ questionnaires.find { |q| q.url == questionnaire_url }
379
+ end
380
+
323
381
  def extract_libraries_from_bundles(questionnaire_bundles)
324
382
  questionnaire_bundles.filter_map do |qb|
325
383
  qb.entry.filter_map { |entry| entry.resource if entry&.resource.is_a?(FHIR::Library) }
@@ -12,11 +12,18 @@ requirements and may change the test validation logic.
12
12
 
13
13
  ## Test Methodology
14
14
 
15
- Inferno will simulate a DTR SMART App that will connect to the DTR Light EHR system under test. The tester will need to launch Inferno using either an EHR launch or a Standalone launch. Once the connection between Inferno's simulated DTR SMART App and the DTR Light EHR under test is established, tests within this suite will make FHIR API requests corresponding to capabilities required by the [Light DTR EHR Capability Statement](https://hl7.org/fhir/us/davinci-dtr/STU2/CapabilityStatement-light-dtr-ehr) and check that the EHR's responses are conformant.
15
+ Inferno will simulate a DTR SMART App that will connect to the DTR Light EHR system under test. The tester will need to launch Inferno using an EHR launch. Once the connection between Inferno's simulated DTR SMART App and the DTR Light EHR under test is established, tests within this suite will make FHIR API requests corresponding to capabilities required by the [Light DTR EHR Capability Statement](https://hl7.org/fhir/us/davinci-dtr/STU2/CapabilityStatement-light-dtr-ehr) and check that the EHR's responses are conformant.
16
16
 
17
17
  ## Running the Tests
18
18
 
19
- If you would like to try out the tests but don't have a DTR Light EHR implementation, you can run these tests against the [public instance of the Inferno Reference Server](https://inferno.healthit.gov/reference-server/r4/) by using the Inferno Reference Server preset in the test suite. In order to get the Inferno Reference Server to do an EHR launch, navigate to https://inferno.healthit.gov/reference-server/app/app-launch and use https://inferno.healthit.gov/suites/custom/smart/launch as the App Launch URL. When using the Inferno Reference Server preset for the DTR Light EHR test suite, note that the sample patient used for testing (`dtr_bundle_patient_pat015.json`) is focused on DTR-specific data and does not have the complete set of US Core data needed to pass all the US Core tests. In addition, this preset does not test the `create` or `update` tests for DTR QuestionnaireResponse resources and PAS Task resources.
19
+ If you would like to try out the tests but don't have a Light DTR EHR implementation, you can run these tests against the [public instance of the Inferno Reference Server](https://inferno.healthit.gov/reference-server/r4/) by using the Inferno Reference Server preset in the test suite. In order to get the Inferno Reference Server to do an EHR launch, navigate to https://inferno.healthit.gov/reference-server/app/app-launch and use https://inferno.healthit.gov/suites/custom/smart/launch as the App Launch URL. When using the Inferno Reference Server preset for the DTR Light EHR test suite, note that the sample patient used for testing (`dtr_bundle_patient_pat015.json`) is focused on DTR-specific data and does not have the complete set of US Core data needed to pass all the US Core tests. In addition, this preset does not test the `create` or `update` tests for DTR QuestionnaireResponse resources and PAS Task resources.
20
+
21
+ In addition, if you would like to try out the DTR-specific SMART Launch tests, meaning the tests that check for DTR `fhirContext` conformance, but do not have a Light DTR EHR implementation, you can run these tests against an instance of Inferno running the DTR Smart App Test Suite as your Light DTR EHR. This process is described in the following steps:
22
+
23
+ 1. In the tab with the Light DTR EHR Test Suite open, click "1 Authorization" test group and click "Run all tests". The FHIR Server Base Url should be `[URL prefix]/custom/dtr_smart_app/fhir` where `[URL prefix]` comes from the URL of the test session which will be of the form `[URL prefix]/dtr_smart_app/[session id]` and the EHR Launch Client ID should be `sample`. Click "Submit". Take note of the launch_uri provided by the following prompt.
24
+ 2. In a separate tab from the DTR Light EHR Test Suite, pull up the Da Vinci DTR SMART App Test Suite and click "Run all tests".
25
+ 3. Start off by launching it with "EHR Launch from Inferno" with a client_id of `sample` and a launch_uri provided by the DTR Light EHR prompt in step 1. Before clicking "Submit", change the SMART App Launch fhirContext input to be an array of strings, rather than the default JSON object since the DTR Light EHR tests use STU2.0 version of SMART Launch. The input should be `["Coverage/cov015","DeviceRequest/devreqe0470"]`. Click "Submit".
26
+ 4. Right click on the link in the resulting popup and click "Open Link in New Window" to complete the Authorization Test Group of the DTR Light EHR Test Suite.
20
27
 
21
28
  ## Limitations
22
29
 
@@ -24,10 +31,6 @@ The DTR IG is a complex specification and these tests currently validate conform
24
31
  a subset of IG requirements. Future versions of the test suite will test further
25
32
  features.
26
33
 
27
- Specific limitations include:
28
- - *SMART Launch `fhirContext`*: Inferno does not currently verify the use of `fhirContext` to convey details
29
- about the DTR SMART App launch.
30
-
31
34
  ## DTR 2.0.1 Corrections
32
35
 
33
36
  The DTR 2.0.1 version of the [Light EHR CapabilityStatement](http://hl7.org/fhir/us/davinci-dtr/CapabilityStatement/light-dtr-ehr) includes two pieces of missing or misleading information that have been corrected:
@@ -1,5 +1,6 @@
1
- require_relative 'client_groups/dinner_static/dtr_full_ehr_questionnaire_workflow_group'
2
- require_relative 'client_groups/dinner_adaptive/dtr_full_ehr_adaptive_dinner_questionnaire_workflow_group'
1
+ require_relative 'client_groups/custom_static/dtr_full_ehr_custom_static_workflow_group'
2
+ require_relative 'client_groups/dinner_static/dtr_full_ehr_static_dinner_workflow_group'
3
+ require_relative 'client_groups/dinner_adaptive/dtr_full_ehr_adaptive_dinner_workflow_group'
3
4
  require_relative 'auth_groups/oauth2_authentication_group'
4
5
  require_relative 'endpoints/cors'
5
6
  require_relative 'endpoints/mock_authorization/simple_token_endpoint'
@@ -15,8 +16,6 @@ module DaVinciDTRTestKit
15
16
  title 'Da Vinci DTR Full EHR Test Suite'
16
17
  description File.read(File.join(__dir__, 'docs', 'dtr_full_ehr_suite_description_v201.md'))
17
18
 
18
- version VERSION
19
-
20
19
  links [
21
20
  {
22
21
  label: 'Report Issue',
@@ -61,7 +60,21 @@ module DaVinciDTRTestKit
61
60
  end
62
61
 
63
62
  group from: :oauth2_authentication
64
- group from: :dtr_full_ehr_static_dinner_questionnaire_workflow
65
- group from: :dtr_full_ehr_adaptive_dinner_questionnaire_workflow
63
+ group do
64
+ id :dtr_full_ehr_basic_workflows
65
+ title 'Basic Workflows'
66
+
67
+ group from: :dtr_full_ehr_custom_static_workflow
68
+ group from: :dtr_full_ehr_adaptive_dinner_workflow
69
+ end
70
+ group do
71
+ id :dtr_full_ehr_questionnaire_functionality
72
+ title 'Questionnaire Functionality Coverage'
73
+ description %(
74
+ Tests in this group validate that the client can complete additional DTR workflows
75
+ covering additional pre-population features of questionnaires.
76
+ )
77
+ group from: :dtr_full_ehr_static_dinner_workflow
78
+ end
66
79
  end
67
80
  end
@@ -12,6 +12,7 @@ require_relative 'profiles/nutrition_order_group'
12
12
  require_relative 'profiles/service_request_group'
13
13
  require_relative 'profiles/task_group'
14
14
  require_relative 'profiles/vision_prescription_group'
15
+ require_relative 'client_groups/light_ehr/dtr_smart_ehr_launch'
15
16
  require 'smart_app_launch/smart_stu1_suite'
16
17
  require 'smart_app_launch/smart_stu2_suite'
17
18
 
@@ -21,8 +22,6 @@ module DaVinciDTRTestKit
21
22
  title 'Da Vinci DTR Light EHR Test Suite'
22
23
  description File.read(File.join(__dir__, 'docs', 'dtr_light_ehr_suite_description_v201.md'))
23
24
 
24
- version VERSION
25
-
26
25
  links [
27
26
  {
28
27
  label: 'Report Issue',
@@ -83,13 +82,18 @@ module DaVinciDTRTestKit
83
82
  end
84
83
  end
85
84
 
86
- group from: :smart_ehr_launch_stu2,
87
- required_suite_options: DTROptions::SMART_2_REQUIREMENT,
88
- run_as_group: true
89
-
90
- group from: :smart_standalone_launch_stu2,
85
+ group from: :dtr_smart_ehr_launch,
91
86
  required_suite_options: DTROptions::SMART_2_REQUIREMENT,
92
- run_as_group: true
87
+ run_as_group: true,
88
+ config: {
89
+ outputs: {
90
+ id_token: { name: :id_token },
91
+ client_id: { name: :client_id },
92
+ requested_scopes: { name: :requested_scopes },
93
+ access_token: { name: :access_token },
94
+ smart_credentials: { name: :smart_credentials }
95
+ }
96
+ }
93
97
  end
94
98
 
95
99
  group do
@@ -102,39 +106,41 @@ module DaVinciDTRTestKit
102
106
  )
103
107
 
104
108
  group from: :'us_core_v311-us_core_v311_fhir_api',
105
- run_as_group: true
106
- end
109
+ run_as_group: true,
110
+ verifies_requirements: ['hl7.fhir.us.davinci-dtr_2.0.1@2', 'hl7.fhir.us.davinci-dtr_2.0.1@281']
107
111
 
108
- group do
109
- title 'DTR Light EHR Profiles'
110
- description %(This test group tests system for their conformance to
111
- the RESTful capabilities by specified Resources/Profiles as defined by
112
- the DaVinci Documentation Templates and Rules (DTR) v2.0,1 Implementation
113
- Guide Light DTR EHR Capability Statement.
112
+ group do
113
+ title 'DTR Light EHR Profiles'
114
+ description %(This test group tests system for their conformance to
115
+ the RESTful capabilities by specified Resources/Profiles as defined by
116
+ the DaVinci Documentation Templates and Rules (DTR) v2.0,1 Implementation
117
+ Guide Light DTR EHR Capability Statement.
114
118
 
115
- )
119
+ )
120
+ run_as_group
116
121
 
117
- input :credentials,
118
- title: 'OAuth Credentials',
119
- type: :oauth_credentials,
120
- optional: true
122
+ input :smart_credentials,
123
+ title: 'OAuth Credentials',
124
+ type: :oauth_credentials,
125
+ optional: true
121
126
 
122
- # All FHIR requests in this suite will use this FHIR client
123
- fhir_client do
124
- url :url
125
- oauth_credentials :credentials
126
- end
127
+ # All FHIR requests in this suite will use this FHIR client
128
+ fhir_client do
129
+ url :url
130
+ oauth_credentials :smart_credentials
131
+ end
127
132
 
128
- group from: :questionnaire_response_group
129
- group from: :coverage_group
130
- group from: :communication_request_group
131
- group from: :device_request_group
132
- group from: :encounter_group
133
- group from: :medication_request_group
134
- group from: :nutrition_order_group
135
- group from: :service_request_group
136
- group from: :task_group
137
- group from: :vision_prescription_group
133
+ group from: :questionnaire_response_group
134
+ group from: :coverage_group
135
+ group from: :communication_request_group
136
+ group from: :device_request_group
137
+ group from: :encounter_group
138
+ group from: :medication_request_group
139
+ group from: :nutrition_order_group
140
+ group from: :service_request_group
141
+ group from: :task_group
142
+ group from: :vision_prescription_group
143
+ end
138
144
  end
139
145
  end
140
146
  end
@@ -15,8 +15,6 @@ module DaVinciDTRTestKit
15
15
  title 'Da Vinci DTR Payer Server Test Suite'
16
16
  description File.read(File.join(__dir__, 'docs', 'dtr_payer_server_suite_description_v201.md'))
17
17
 
18
- version VERSION
19
-
20
18
  links [
21
19
  {
22
20
  label: 'Report Issue',
@@ -1,13 +1,51 @@
1
- # frozen_string_literal: true
2
-
1
+ require_relative 'cql_test'
3
2
  module DaVinciDTRTestKit
4
3
  module DTRQuestionnaireResponseValidation
4
+ include DaVinciDTRTestKit::CQLTest
5
+
5
6
  CQL_EXPRESSION_EXTENSIONS = [
6
7
  'http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-initialExpression',
7
8
  'http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-calculatedExpression',
8
9
  'http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-candidateExpression'
9
10
  ].freeze
10
11
 
12
+ def validate_questionnaire_response_correctness(questionnaire_response_json, custom_response = nil)
13
+ check_is_questionnaire_response(questionnaire_response_json)
14
+ qr = FHIR.from_contents(questionnaire_response_json)
15
+ questionnaire = nil
16
+ expected_overrides = []
17
+ if custom_response.blank?
18
+ questionnaire = Fixtures.questionnaire_for_test(id)
19
+ expected_overrides = ['PBD.2']
20
+ else
21
+ assert_valid_json custom_response, 'Custom response provided is not a valid JSON'
22
+
23
+ # Find the questionnaire that is referenced in the QuestionnaireResponse
24
+ questionnaire = extract_questionnaire_from_questionnaire_package(
25
+ custom_response, qr.questionnaire
26
+ )
27
+
28
+ skip_if questionnaire.blank?,
29
+ "Couldn't find Questionnaire #{qr.questionnaire} in the provided custom questionnaire package
30
+ to validate the QuestionnaireResponse."
31
+
32
+ missing_origin_sources = ['auto', 'manual', 'override'] - extract_origin_sources(qr.item)
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
40
+ end
41
+
42
+ check_origin_sources(questionnaire.item, qr.item, expected_overrides:)
43
+
44
+ required_link_ids = extract_required_link_ids(questionnaire.item)
45
+ check_answer_presence(qr.item, required_link_ids)
46
+ assert(messages.none? { |m| m[:type] == 'error' }, 'QuestionnaireResponse is not correct, see error message(s)')
47
+ end
48
+
11
49
  def check_is_questionnaire_response(questionnaire_response_json)
12
50
  assert_valid_json(questionnaire_response_json)
13
51
  questionnaire_response = begin
@@ -55,6 +93,15 @@ module DaVinciDTRTestKit
55
93
  end
56
94
  end
57
95
 
96
+ def extract_origin_sources(items, origin_sources = [])
97
+ items&.each do |item|
98
+ extract_origin_sources(item&.item, origin_sources)
99
+ origin_sources << find_origin_source(item) if item&.answer&.any?
100
+ end
101
+
102
+ origin_sources
103
+ end
104
+
58
105
  # Ensures that all required questions have been answered.
59
106
  # If required_link_ids not provided, all questions are treated as optional.
60
107
  def check_answer_presence(response_items, required_link_ids = [])
@@ -108,7 +155,6 @@ module DaVinciDTRTestKit
108
155
 
109
156
  def validate_cql_executed(actual_items, questionnaire_cql_expression_link_ids, template_prepopulation_expectations,
110
157
  template_override_expectations)
111
-
112
158
  actual_items&.each do |item_to_validate|
113
159
  link_id = item_to_validate.linkId
114
160
  if questionnaire_cql_expression_link_ids.include?(link_id)
@@ -225,7 +271,7 @@ module DaVinciDTRTestKit
225
271
  end
226
272
 
227
273
  def item_is_cql_expression?(item)
228
- item.extension&.any? { |ext| CQL_EXPRESSION_EXTENSIONS.include?(ext.url) }
274
+ item&.extension&.any? { |ext| CQL_EXPRESSION_EXTENSIONS.include?(ext.url) }
229
275
  end
230
276
 
231
277
  def answer_value_equal?(expected, actual)