davinci_dtr_test_kit 0.17.0 → 0.18.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 (311) hide show
  1. checksums.yaml +4 -4
  2. data/config/presets/v220_full_ehr_suite_run_against_payer_suite.json.erb +19 -0
  3. data/config/presets/v220_payer_suite_run_against_full_ehr_suite.json.erb +76 -0
  4. data/lib/davinci_dtr_test_kit/cross_suite/fhirpath_utils.rb +52 -0
  5. data/lib/davinci_dtr_test_kit/cross_suite/generated/v2.2.0/dtr_base_questionnaire/metadata.yml +212 -0
  6. data/lib/davinci_dtr_test_kit/cross_suite/generated/v2.2.0/dtr_q_package_bundle/metadata.yml +39 -0
  7. data/lib/davinci_dtr_test_kit/cross_suite/generated/v2.2.0/dtr_qpackage_output_parameters/metadata.yml +30 -0
  8. data/lib/davinci_dtr_test_kit/cross_suite/generated/v2.2.0/dtr_questionnaire_adapt/metadata.yml +17 -0
  9. data/lib/davinci_dtr_test_kit/cross_suite/generated/v2.2.0/dtr_questionnaire_adapt_search/metadata.yml +91 -0
  10. data/lib/davinci_dtr_test_kit/cross_suite/generated/v2.2.0/dtr_std_questionnaire/metadata.yml +17 -0
  11. data/lib/davinci_dtr_test_kit/cross_suite/generated/v2.2.0/metadata.yml +403 -0
  12. data/lib/davinci_dtr_test_kit/cross_suite/generated_profile_metadata.rb +22 -0
  13. data/lib/davinci_dtr_test_kit/cross_suite/response_selection_utils.rb +85 -0
  14. data/lib/davinci_dtr_test_kit/{cql_test.rb → cross_suite/v2.0.1/cql_test.rb} +3 -3
  15. data/lib/davinci_dtr_test_kit/cross_suite/v2.2.0/dtr_conformance_verification.rb +21 -0
  16. data/lib/davinci_dtr_test_kit/cross_suite/v2.2.0/multi_request_message_helper.rb +35 -0
  17. data/lib/davinci_dtr_test_kit/cross_suite/v2.2.0/questionnaire_helper.rb +162 -0
  18. data/lib/davinci_dtr_test_kit/{dtr_client_options.rb → full_ehr/dtr_full_ehr_options.rb} +1 -1
  19. data/lib/davinci_dtr_test_kit/{endpoints → full_ehr/endpoints}/mock_payer.rb +9 -3
  20. data/lib/davinci_dtr_test_kit/{endpoints → full_ehr/endpoints}/mock_udap_smart_server/token_endpoint.rb +2 -2
  21. data/lib/davinci_dtr_test_kit/full_ehr/fixture_loader.rb +37 -0
  22. data/lib/davinci_dtr_test_kit/full_ehr/fixtures/dinner_adaptive/dinner_order_adaptive_next_question_template.json +243 -0
  23. data/lib/davinci_dtr_test_kit/full_ehr/fixtures/dinner_adaptive/parameters_questionnaire_dinner_order_adaptive.json +104 -0
  24. data/lib/davinci_dtr_test_kit/full_ehr/fixtures/dinner_static/parameters_questionnaire_dinner_order_static.json +291 -0
  25. data/lib/davinci_dtr_test_kit/full_ehr/fixtures/empty_templates/next_question_template_empty.json +1 -0
  26. data/lib/davinci_dtr_test_kit/full_ehr/fixtures/empty_templates/parameters_questionnaire_package_empty.json +9 -0
  27. data/lib/davinci_dtr_test_kit/full_ehr/short_circuit_interaction_verification.rb +73 -0
  28. data/lib/davinci_dtr_test_kit/{client_groups/adaptive_questionnaire/custom → full_ehr/v2.0.1/adaptive_custom}/dtr_custom_next_question_response_validation_test.rb +2 -1
  29. data/lib/davinci_dtr_test_kit/{client_groups/adaptive_questionnaire/custom → full_ehr/v2.0.1/adaptive_custom}/dtr_full_ehr_custom_adaptive_request_test.rb +1 -1
  30. data/lib/davinci_dtr_test_kit/{client_groups/adaptive_questionnaire/dinner_order → full_ehr/v2.0.1/adaptive_dinner}/dtr_adaptive_next_question_retrieval_group.rb +3 -3
  31. data/lib/davinci_dtr_test_kit/{client_groups/adaptive_questionnaire/dinner_order → full_ehr/v2.0.1/adaptive_dinner}/dtr_full_ehr_adaptive_initial_retrieval_group.rb +5 -5
  32. data/lib/davinci_dtr_test_kit/{client_groups/adaptive_questionnaire → full_ehr/v2.0.1/adaptive_interaction}/dtr_adaptive_next_question_request_test.rb +1 -1
  33. data/lib/davinci_dtr_test_kit/{client_groups/adaptive_questionnaire → full_ehr/v2.0.1/adaptive_interaction}/dtr_adaptive_next_question_request_validation_test.rb +1 -1
  34. data/lib/davinci_dtr_test_kit/{client_groups/adaptive_questionnaire → full_ehr/v2.0.1/adaptive_interaction}/dtr_adaptive_response_validation_test.rb +2 -2
  35. data/lib/davinci_dtr_test_kit/{client_groups/adaptive_questionnaire/dinner_order → full_ehr/v2.0.1}/dtr_full_ehr_adaptive_dinner_workflow_group.rb +7 -7
  36. data/lib/davinci_dtr_test_kit/{client_groups/adaptive_questionnaire/custom → full_ehr/v2.0.1}/dtr_full_ehr_custom_adaptive_workflow_group.rb +18 -16
  37. data/lib/davinci_dtr_test_kit/{client_groups/custom_static → full_ehr/v2.0.1}/dtr_full_ehr_custom_static_workflow_group.rb +11 -11
  38. data/lib/davinci_dtr_test_kit/{client_groups/must_support → full_ehr/v2.0.1}/dtr_full_ehr_questionnaire_must_support_group.rb +8 -7
  39. data/lib/davinci_dtr_test_kit/{client_groups/dinner_static → full_ehr/v2.0.1}/dtr_full_ehr_static_dinner_workflow_group.rb +7 -7
  40. data/lib/davinci_dtr_test_kit/{dtr_full_ehr_suite.rb → full_ehr/v2.0.1/dtr_full_ehr_suite.rb} +23 -20
  41. data/lib/davinci_dtr_test_kit/{client_groups/payer_registration/dtr_client_registration_group.rb → full_ehr/v2.0.1/dtr_payer_registration_group.rb} +8 -8
  42. data/lib/davinci_dtr_test_kit/{endpoints/mock_payer/next_question_endpoint.rb → full_ehr/v2.0.1/full_ehr_next_question_endpoint.rb} +18 -7
  43. data/lib/davinci_dtr_test_kit/{endpoints/mock_payer/questionnaire_package_endpoint.rb → full_ehr/v2.0.1/full_ehr_questionnaire_package_endpoint.rb} +22 -7
  44. data/lib/davinci_dtr_test_kit/{client_groups → full_ehr/v2.0.1}/must_support/dtr_full_ehr_ms_questionnaire_package_request_test.rb +1 -1
  45. data/lib/davinci_dtr_test_kit/{client_groups → full_ehr/v2.0.1}/must_support/dtr_must_support_attestation_test.rb +2 -1
  46. data/lib/davinci_dtr_test_kit/{client_groups → full_ehr/v2.0.1}/must_support/dtr_questionnaire_must_support_test.rb +3 -2
  47. data/lib/davinci_dtr_test_kit/{client_groups → full_ehr/v2.0.1}/payer_registration/configuration_display_smart_test.rb +1 -1
  48. data/lib/davinci_dtr_test_kit/{client_groups → full_ehr/v2.0.1}/payer_registration/configuration_display_udap_test.rb +1 -1
  49. data/lib/davinci_dtr_test_kit/{client_groups → full_ehr/v2.0.1}/shared/dtr_custom_questionnaire_expressions_test.rb +3 -2
  50. data/lib/davinci_dtr_test_kit/{client_groups → full_ehr/v2.0.1}/shared/dtr_custom_questionnaire_extensions_test.rb +3 -2
  51. data/lib/davinci_dtr_test_kit/{client_groups → full_ehr/v2.0.1}/shared/dtr_custom_questionnaire_libraries_test.rb +3 -2
  52. data/lib/davinci_dtr_test_kit/{client_groups → full_ehr/v2.0.1}/shared/dtr_custom_questionnaire_package_validation_test.rb +3 -2
  53. data/lib/davinci_dtr_test_kit/{client_groups/full_ehr → full_ehr/v2.0.1/shared}/dtr_full_ehr_adaptive_request_test.rb +1 -1
  54. data/lib/davinci_dtr_test_kit/{client_groups/full_ehr → full_ehr/v2.0.1/shared}/dtr_full_ehr_launch_attestation_test.rb +1 -1
  55. data/lib/davinci_dtr_test_kit/{client_groups/full_ehr → full_ehr/v2.0.1/shared}/dtr_full_ehr_prepopulation_attestation_test.rb +1 -1
  56. data/lib/davinci_dtr_test_kit/{client_groups/full_ehr → full_ehr/v2.0.1/shared}/dtr_full_ehr_prepopulation_override_attestation_test.rb +1 -1
  57. data/lib/davinci_dtr_test_kit/{client_groups/full_ehr → full_ehr/v2.0.1/shared}/dtr_full_ehr_questionnaire_package_request_test.rb +1 -1
  58. data/lib/davinci_dtr_test_kit/{client_groups/full_ehr → full_ehr/v2.0.1/shared}/dtr_full_ehr_questionnaire_response_conformance_test.rb +1 -1
  59. data/lib/davinci_dtr_test_kit/{client_groups/full_ehr → full_ehr/v2.0.1/shared}/dtr_full_ehr_questionnaire_response_correctness_test.rb +1 -1
  60. data/lib/davinci_dtr_test_kit/{client_groups/full_ehr → full_ehr/v2.0.1/shared}/dtr_full_ehr_store_attestation_test.rb +1 -1
  61. data/lib/davinci_dtr_test_kit/{client_groups → full_ehr/v2.0.1}/shared/dtr_prepopulation_attestation_test.rb +1 -1
  62. data/lib/davinci_dtr_test_kit/{client_groups → full_ehr/v2.0.1}/shared/dtr_prepopulation_override_attestation_test.rb +1 -1
  63. data/lib/davinci_dtr_test_kit/{client_groups → full_ehr/v2.0.1}/shared/dtr_questionnaire_package_request_validation_test.rb +1 -1
  64. data/lib/davinci_dtr_test_kit/{client_groups → full_ehr/v2.0.1}/shared/dtr_questionnaire_response_basic_conformance_test.rb +2 -2
  65. data/lib/davinci_dtr_test_kit/{client_groups → full_ehr/v2.0.1}/shared/dtr_questionnaire_response_prepopulation_test.rb +1 -1
  66. data/lib/davinci_dtr_test_kit/{client_groups → full_ehr/v2.0.1}/shared/dtr_rendering_attestation_test.rb +1 -1
  67. data/lib/davinci_dtr_test_kit/{client_groups/dinner_static → full_ehr/v2.0.1/static_dinner}/dtr_static_dinner_enabled_questions_attestation_test.rb +1 -1
  68. data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/dtr_full_ehr_abstract_adaptive_group.rb +87 -0
  69. data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/dtr_full_ehr_abstract_standard_group.rb +59 -0
  70. data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/dtr_full_ehr_suite.rb +145 -0
  71. data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/dtr_full_ehr_suite_description_v220.md +254 -0
  72. data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/full_ehr_next_question_endpoint.rb +391 -0
  73. data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/full_ehr_questionnaire_package_endpoint.rb +206 -0
  74. data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/interaction/adaptive_questionnaires_completed_test.rb +108 -0
  75. data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/interaction/interaction_wait_test.rb +177 -0
  76. data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/interaction/ui_display_and_interaction_attestation_test.rb +132 -0
  77. data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/must_support/dtr_additional_questionnaires_interaction_group.rb +74 -0
  78. data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/must_support/dtr_questionnaire_adaptive_must_support_test.rb +45 -0
  79. data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/must_support/dtr_questionnaire_base_must_support_test.rb +43 -0
  80. data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/must_support/dtr_questionnaire_standard_must_support_test.rb +45 -0
  81. data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/next_question_template_questionnaires.rb +21 -0
  82. data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/request/dtr_next_question_request_validation_test.rb +85 -0
  83. data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/request/dtr_questionnaire_package_request_validation_test.rb +89 -0
  84. data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/response/dtr_next_question_response_validation_test.rb +85 -0
  85. data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/response/dtr_questionnaire_package_response_validation_test.rb +77 -0
  86. data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/workflows/dtr_full_ehr_workflow_adaptive_group.rb +24 -0
  87. data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/workflows/dtr_full_ehr_workflow_standard_group.rb +21 -0
  88. data/lib/davinci_dtr_test_kit/generator/ig_metadata.rb +21 -0
  89. data/lib/davinci_dtr_test_kit/generator/profile_metadata_extractor.rb +57 -0
  90. data/lib/davinci_dtr_test_kit/generator.rb +117 -0
  91. data/lib/davinci_dtr_test_kit/igs/davinci_dtr_2.2.0.tgz +0 -0
  92. data/lib/davinci_dtr_test_kit/{dtr_options.rb → light_ehr/dtr_light_ehr_options.rb} +1 -1
  93. data/lib/davinci_dtr_test_kit/{dtr_light_ehr_suite.rb → light_ehr/v2.0.1/dtr_light_ehr_suite.rb} +21 -10
  94. data/lib/davinci_dtr_test_kit/{client_groups/light_ehr → light_ehr/v2.0.1}/dtr_light_ehr_supported_endpoints_group.rb +5 -5
  95. data/lib/davinci_dtr_test_kit/{client_groups/light_ehr → light_ehr/v2.0.1}/dtr_smart_ehr_launch.rb +3 -3
  96. data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/communication_request/communication_request_read.rb +1 -1
  97. data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/coverage/coverage_read.rb +1 -1
  98. data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/device_request/device_request_read.rb +1 -1
  99. data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/encounter/encounter_read.rb +1 -1
  100. data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/medication_request/medication_request_read.rb +1 -1
  101. data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/nutrition_order/nutrition_order_read.rb +1 -1
  102. data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/questionnaire_response/questionnaire_response_create.rb +1 -1
  103. data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/questionnaire_response/questionnaire_response_update.rb +1 -1
  104. data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/service_request/service_request_read.rb +1 -1
  105. data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/task/task_create.rb +1 -1
  106. data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/task/task_read.rb +1 -1
  107. data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/task/task_update.rb +1 -1
  108. data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/vision_prescription/vision_prescription_read.rb +1 -1
  109. data/lib/davinci_dtr_test_kit/{client_groups/light_ehr → light_ehr/v2.0.1/supported_endpoints}/dtr_light_ehr_supported_payers_accept_header_test.rb +3 -2
  110. data/lib/davinci_dtr_test_kit/{client_groups/light_ehr → light_ehr/v2.0.1/supported_endpoints}/dtr_light_ehr_supported_payers_config_test.rb +2 -1
  111. data/lib/davinci_dtr_test_kit/{client_groups/light_ehr → light_ehr/v2.0.1/supported_endpoints}/dtr_light_ehr_supported_payers_endpoint_test.rb +2 -1
  112. data/lib/davinci_dtr_test_kit/{client_groups/light_ehr → light_ehr/v2.0.1/supported_endpoints}/dtr_light_ehr_supported_payers_use_test.rb +2 -1
  113. data/lib/davinci_dtr_test_kit/{client_groups/light_ehr → light_ehr/v2.0.1/supported_endpoints}/dtr_light_ehr_supported_payers_user_response_test.rb +5 -3
  114. data/lib/davinci_dtr_test_kit/metadata.rb +13 -68
  115. data/lib/davinci_dtr_test_kit/requirements/davinci_dtr_test_kit_requirements.csv +216 -0
  116. data/lib/davinci_dtr_test_kit/requirements/generated/dtr_full_ehr_requirements_coverage.csv +1 -1
  117. data/lib/davinci_dtr_test_kit/requirements/generated/dtr_full_ehr_v220_requirements_coverage.csv +1 -0
  118. data/lib/davinci_dtr_test_kit/requirements/generated/dtr_light_ehr_requirements_coverage.csv +1 -1
  119. data/lib/davinci_dtr_test_kit/requirements/generated/dtr_payer_server_requirements_coverage.csv +1 -1
  120. data/lib/davinci_dtr_test_kit/requirements/generated/dtr_payer_server_v220_requirements_coverage.csv +114 -0
  121. data/lib/davinci_dtr_test_kit/requirements/generated/dtr_smart_app_requirements_coverage.csv +1 -1
  122. data/lib/davinci_dtr_test_kit/requirements/hl7.fhir.us.davinci-dtr_2.2.0_requirements.xlsx +0 -0
  123. data/lib/davinci_dtr_test_kit/{endpoints/mock_payer → server/endpoints}/next_question_proxy_endpoint.rb +2 -0
  124. data/lib/davinci_dtr_test_kit/{endpoints/mock_payer → server/endpoints}/questionnaire_package_proxy_endpoint.rb +2 -0
  125. data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1/adaptive_forms}/adaptive_form_libraries_test.rb +2 -1
  126. data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1/adaptive_forms}/adaptive_form_questionnaire_expressions_test.rb +2 -1
  127. data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1/adaptive_forms}/adaptive_form_questionnaire_extensions_test.rb +2 -1
  128. data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1/adaptive_forms}/adaptive_next_questionnaire_expressions_test.rb +2 -1
  129. data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1/adaptive_forms}/adaptive_next_questionnaire_extensions_test.rb +2 -1
  130. data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1/adaptive_forms}/payer_server_adaptive_request_test.rb +2 -1
  131. data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1/adaptive_forms}/payer_server_adaptive_request_validation_test.rb +3 -1
  132. data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1/adaptive_forms}/payer_server_adaptive_response_bundles_validation_test.rb +3 -1
  133. data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1/adaptive_forms}/payer_server_adaptive_response_search_validation_test.rb +3 -1
  134. data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1/adaptive_forms}/payer_server_adaptive_response_validation_test.rb +4 -2
  135. data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1/adaptive_forms}/payer_server_next_request_validation_test.rb +3 -1
  136. data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1/adaptive_forms}/payer_server_next_response_validation_test.rb +3 -1
  137. data/lib/davinci_dtr_test_kit/{dtr_payer_server_suite.rb → server/v2.0.1/dtr_payer_server_suite.rb} +13 -10
  138. data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1}/payer_server_adaptive_group.rb +13 -13
  139. data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1}/payer_server_static_group.rb +6 -6
  140. data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1/static_forms}/static_form_libraries_test.rb +2 -1
  141. data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1/static_forms}/static_form_questionnaire_expressions_test.rb +2 -1
  142. data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1/static_forms}/static_form_questionnaire_extensions_test.rb +2 -1
  143. data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1/static_forms}/static_form_request_test.rb +4 -2
  144. data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1/static_forms}/static_form_request_validation_test.rb +3 -2
  145. data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1/static_forms}/static_form_response_validation_test.rb +5 -3
  146. data/lib/davinci_dtr_test_kit/server/v2.2.0/client_simulation.rb +297 -0
  147. data/lib/davinci_dtr_test_kit/server/v2.2.0/dtr_payer_server_capability_statement_test.rb +73 -0
  148. data/lib/davinci_dtr_test_kit/server/v2.2.0/dtr_payer_server_suite.rb +322 -0
  149. data/lib/davinci_dtr_test_kit/server/v2.2.0/dtr_payer_server_suite_description_v220.md +37 -0
  150. data/lib/davinci_dtr_test_kit/server/v2.2.0/interaction_test.rb +97 -0
  151. data/lib/davinci_dtr_test_kit/server/v2.2.0/log_questionnaire_errors_support_test.rb +57 -0
  152. data/lib/davinci_dtr_test_kit/server/v2.2.0/must_support/questionnaire_adaptive_must_support_test.rb +47 -0
  153. data/lib/davinci_dtr_test_kit/server/v2.2.0/must_support/questionnaire_adaptive_search_must_support_test.rb +40 -0
  154. data/lib/davinci_dtr_test_kit/server/v2.2.0/must_support/questionnaire_base_must_support_test.rb +40 -0
  155. data/lib/davinci_dtr_test_kit/server/v2.2.0/must_support/questionnaire_package_bundle_must_support_test.rb +38 -0
  156. data/lib/davinci_dtr_test_kit/server/v2.2.0/must_support/questionnaire_package_output_parameters_must_support_test.rb +37 -0
  157. data/lib/davinci_dtr_test_kit/server/v2.2.0/must_support/questionnaire_standard_must_support_test.rb +39 -0
  158. data/lib/davinci_dtr_test_kit/server/v2.2.0/next_question_request_validation_test.rb +45 -0
  159. data/lib/davinci_dtr_test_kit/server/v2.2.0/next_question_support/adaptive_questionnaire_endpoint_test.rb +98 -0
  160. data/lib/davinci_dtr_test_kit/server/v2.2.0/next_question_support/invalid_questionnaire_response_test.rb +43 -0
  161. data/lib/davinci_dtr_test_kit/server/v2.2.0/next_question_support/next_contained_questionnaire_response_references_test.rb +46 -0
  162. data/lib/davinci_dtr_test_kit/server/v2.2.0/next_question_support/next_question_response_references_test.rb +56 -0
  163. data/lib/davinci_dtr_test_kit/server/v2.2.0/next_question_support/next_question_response_validation_test.rb +67 -0
  164. data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_design/contained_binary_test.rb +58 -0
  165. data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_design/contained_binary_validation.rb +128 -0
  166. data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_design/cql_library_validation_test.rb +58 -0
  167. data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_design/questionnaire_design_support.rb +65 -0
  168. data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_design/questionnaire_expression_elm_test.rb +81 -0
  169. data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_design/questionnaire_expression_language_test.rb +63 -0
  170. data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_design/questionnaire_prepopulation_test.rb +42 -0
  171. data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_design/questionnaire_relevance_logic_test.rb +40 -0
  172. data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_operation_validation.rb +440 -0
  173. data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_package_request_validation_test.rb +42 -0
  174. data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_package_support/adaptive_questionnaire_response_contained_questionnaire_test.rb +127 -0
  175. data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_package_support/adaptive_questionnaire_response_validation_test.rb +61 -0
  176. data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_package_support/contained_questionnaire_response_references_test.rb +42 -0
  177. data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_package_support/dtr_server_no_custom_extension_test.rb +184 -0
  178. data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_package_support/dtr_server_questionnaire_not_found_test.rb +76 -0
  179. data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_package_support/dtr_server_questionnaire_package_contents_test.rb +89 -0
  180. data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_package_support/initial_questionnaire_response_test.rb +132 -0
  181. data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_package_support/questionnaire_package_input_type_test.rb +110 -0
  182. data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_package_support/questionnaire_references_version_specific_test.rb +79 -0
  183. data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_package_support/questionnaire_response_questionnaire_canonical_test.rb +89 -0
  184. data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_package_support/questionnaire_response_references_test.rb +51 -0
  185. data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_package_support/questionnaire_response_validation_test.rb +63 -0
  186. data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_package_support/source_data_error_test.rb +43 -0
  187. data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_package_support/value_set_validation_test.rb +90 -0
  188. data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_response_reference_validation.rb +133 -0
  189. data/lib/davinci_dtr_test_kit/server/v2.2.0/value_set_expand_support/small_value_set_expansion_test.rb +120 -0
  190. data/lib/davinci_dtr_test_kit/server/v2.2.0/value_set_expand_support/value_set_expansion_test.rb +51 -0
  191. data/lib/davinci_dtr_test_kit/server/v2.2.0/value_set_expand_support/value_set_expansion_validation.rb +58 -0
  192. data/lib/davinci_dtr_test_kit/{endpoints → smart_app/endpoints}/mock_authorization/token_endpoint.rb +1 -1
  193. data/lib/davinci_dtr_test_kit/{endpoints → smart_app/endpoints}/mock_ehr/fhir_get_endpoint.rb +1 -1
  194. data/lib/davinci_dtr_test_kit/smart_app/endpoints/mock_payer/smart_app_next_question_endpoint.rb +12 -0
  195. data/lib/davinci_dtr_test_kit/smart_app/endpoints/mock_payer/smart_app_questionnaire_package_endpoint.rb +12 -0
  196. data/lib/davinci_dtr_test_kit/{client_groups/adaptive_questionnaire/custom → smart_app/v2.0.1/adaptive_custom}/dtr_smart_app_custom_adaptive_workflow_group.rb +17 -15
  197. data/lib/davinci_dtr_test_kit/{client_groups/adaptive_questionnaire/dinner_order → smart_app/v2.0.1/adaptive_dinner}/dtr_smart_app_adaptive_dinner_workflow_group.rb +5 -5
  198. data/lib/davinci_dtr_test_kit/{client_groups/adaptive_questionnaire/dinner_order → smart_app/v2.0.1/adaptive_dinner}/dtr_smart_app_adaptive_initial_retrieval_group.rb +4 -4
  199. data/lib/davinci_dtr_test_kit/{auth_groups → smart_app/v2.0.1/auth}/token_request_test.rb +1 -1
  200. data/lib/davinci_dtr_test_kit/{client_groups/custom_static → smart_app/v2.0.1}/dtr_smart_app_custom_static_workflow_group.rb +11 -11
  201. data/lib/davinci_dtr_test_kit/{client_groups/must_support → smart_app/v2.0.1}/dtr_smart_app_questionnaire_must_support_group.rb +8 -7
  202. data/lib/davinci_dtr_test_kit/{client_groups/respiratory → smart_app/v2.0.1}/dtr_smart_app_respiratory_workflow_group.rb +3 -3
  203. data/lib/davinci_dtr_test_kit/{client_groups/dinner_static → smart_app/v2.0.1}/dtr_smart_app_static_dinner_workflow_group.rb +7 -7
  204. data/lib/davinci_dtr_test_kit/{dtr_smart_app_suite.rb → smart_app/v2.0.1/dtr_smart_app_suite.rb} +25 -21
  205. data/lib/davinci_dtr_test_kit/{docs → smart_app/v2.0.1}/dtr_smart_app_suite_description_v201.md +8 -0
  206. data/lib/davinci_dtr_test_kit/{client_groups → smart_app/v2.0.1}/must_support/dtr_smart_app_ms_questionnaire_package_request_test.rb +2 -2
  207. data/lib/davinci_dtr_test_kit/{auth_groups → smart_app/v2.0.1}/oauth2_authentication_group.rb +2 -2
  208. data/lib/davinci_dtr_test_kit/{client_groups/respiratory → smart_app/v2.0.1/static_respiratory}/dtr_respiratory_questionnaire_package_group.rb +1 -1
  209. data/lib/davinci_dtr_test_kit/{client_groups/respiratory → smart_app/v2.0.1/static_respiratory}/dtr_respiratory_questionnaire_package_request_test.rb +1 -1
  210. data/lib/davinci_dtr_test_kit/{client_groups/respiratory → smart_app/v2.0.1/static_respiratory}/dtr_respiratory_questionnaire_response_group.rb +2 -2
  211. data/lib/davinci_dtr_test_kit/{client_groups/respiratory → smart_app/v2.0.1/static_respiratory}/dtr_respiratory_questionnaire_response_save_test.rb +1 -1
  212. data/lib/davinci_dtr_test_kit/{client_groups/respiratory → smart_app/v2.0.1/static_respiratory}/dtr_respiratory_rendering_attestation_test.rb +1 -1
  213. data/lib/davinci_dtr_test_kit/{client_groups/smart_app → smart_app/v2.0.1/tests}/dtr_smart_app_adaptive_request_test.rb +1 -1
  214. data/lib/davinci_dtr_test_kit/{client_groups/smart_app → smart_app/v2.0.1/tests}/dtr_smart_app_prepopulation_attestation_test.rb +1 -1
  215. data/lib/davinci_dtr_test_kit/{client_groups/smart_app → smart_app/v2.0.1/tests}/dtr_smart_app_prepopulation_override_attestation_test.rb +1 -1
  216. data/lib/davinci_dtr_test_kit/{client_groups/smart_app → smart_app/v2.0.1/tests}/dtr_smart_app_questionnaire_package_request_test.rb +1 -1
  217. data/lib/davinci_dtr_test_kit/{client_groups/smart_app → smart_app/v2.0.1/tests}/dtr_smart_app_questionnaire_response_correctness_test.rb +1 -1
  218. data/lib/davinci_dtr_test_kit/{client_groups/smart_app → smart_app/v2.0.1/tests}/dtr_smart_app_questionnaire_response_save_test.rb +1 -1
  219. data/lib/davinci_dtr_test_kit/{client_groups/smart_app → smart_app/v2.0.1/tests}/dtr_smart_app_saving_questionnaire_response_group.rb +1 -1
  220. data/lib/davinci_dtr_test_kit/tags.rb +2 -0
  221. data/lib/davinci_dtr_test_kit/version.rb +2 -2
  222. data/lib/davinci_dtr_test_kit.rb +6 -4
  223. metadata +329 -215
  224. data/lib/davinci_dtr_test_kit/certs/InfernoCA.key +0 -52
  225. data/lib/davinci_dtr_test_kit/certs/InfernoCA.pem +0 -35
  226. data/lib/davinci_dtr_test_kit/certs/TestKit.pem +0 -32
  227. data/lib/davinci_dtr_test_kit/certs/TestKitPrivateKey.key +0 -28
  228. data/lib/davinci_dtr_test_kit/endpoints/mock_payer/full_ehr_next_question_endpoint.rb +0 -30
  229. data/lib/davinci_dtr_test_kit/endpoints/mock_payer/full_ehr_questionnaire_package_endpoint.rb +0 -31
  230. data/lib/davinci_dtr_test_kit/fixture_loader.rb +0 -21
  231. /data/lib/davinci_dtr_test_kit/{endpoints → cross_suite}/cors.rb +0 -0
  232. /data/lib/davinci_dtr_test_kit/{dtr_questionnaire_response_validation.rb → cross_suite/v2.0.1/dtr_questionnaire_response_validation.rb} +0 -0
  233. /data/lib/davinci_dtr_test_kit/{descriptions.rb → full_ehr/descriptions.rb} +0 -0
  234. /data/lib/davinci_dtr_test_kit/{fixtures → full_ehr/fixtures}/dinner_adaptive/dinner_order_adaptive_next_question_burrito.json +0 -0
  235. /data/lib/davinci_dtr_test_kit/{fixtures → full_ehr/fixtures}/dinner_adaptive/dinner_order_adaptive_next_question_hamburger.json +0 -0
  236. /data/lib/davinci_dtr_test_kit/{fixtures → full_ehr/fixtures}/dinner_adaptive/dinner_order_adaptive_next_question_initial.json +0 -0
  237. /data/lib/davinci_dtr_test_kit/{fixtures → full_ehr/fixtures}/dinner_adaptive/questionnaire_dinner_order_adaptive.json +0 -0
  238. /data/lib/davinci_dtr_test_kit/{fixtures → full_ehr/fixtures}/dinner_static/questionnaire_dinner_order_static.json +0 -0
  239. /data/lib/davinci_dtr_test_kit/{fixtures → full_ehr/fixtures}/dinner_static/questionnaire_response_dinner_order_static.json +0 -0
  240. /data/lib/davinci_dtr_test_kit/{fixtures → full_ehr/fixtures}/respiratory_assist_device/pre_populated_questionnaire_response.json +0 -0
  241. /data/lib/davinci_dtr_test_kit/{fixtures → full_ehr/fixtures}/respiratory_assist_device/questionnaire_package.json +0 -0
  242. /data/lib/davinci_dtr_test_kit/{fixtures.rb → full_ehr/fixtures.rb} +0 -0
  243. /data/lib/davinci_dtr_test_kit/{client_groups/adaptive_questionnaire/dinner_order → full_ehr/v2.0.1/adaptive_dinner}/dtr_adaptive_completion_group.rb +0 -0
  244. /data/lib/davinci_dtr_test_kit/{client_groups/adaptive_questionnaire/dinner_order → full_ehr/v2.0.1/adaptive_dinner}/dtr_adaptive_followup_questions_group.rb +0 -0
  245. /data/lib/davinci_dtr_test_kit/{client_groups/auth → full_ehr/v2.0.1}/dtr_client_payer_auth_smart_group.rb +0 -0
  246. /data/lib/davinci_dtr_test_kit/{client_groups/auth → full_ehr/v2.0.1}/dtr_client_payer_auth_udap_group.rb +0 -0
  247. /data/lib/davinci_dtr_test_kit/{docs → full_ehr/v2.0.1}/dtr_full_ehr_suite_description_v201.md +0 -0
  248. /data/lib/davinci_dtr_test_kit/{client_groups → full_ehr/v2.0.1}/must_support/questionnaire_must_support_elements.rb +0 -0
  249. /data/lib/davinci_dtr_test_kit/{client_groups/full_ehr → full_ehr/v2.0.1/shared}/dtr_full_ehr_saving_questionnaire_response_group.rb +0 -0
  250. /data/lib/davinci_dtr_test_kit/{create_test.rb → light_ehr/create_test.rb} +0 -0
  251. /data/lib/davinci_dtr_test_kit/{endpoints/mock_payer → light_ehr/endpoints}/light_ehr_supported_payer_endpoint.rb +0 -0
  252. /data/lib/davinci_dtr_test_kit/{read_test.rb → light_ehr/read_test.rb} +0 -0
  253. /data/lib/davinci_dtr_test_kit/{update_test.rb → light_ehr/update_test.rb} +0 -0
  254. /data/lib/davinci_dtr_test_kit/{docs → light_ehr/v2.0.1}/dtr_light_ehr_suite_description_v201.md +0 -0
  255. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/communication_request/communication_request_must_support_test.rb +0 -0
  256. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/communication_request/communication_request_validation.rb +0 -0
  257. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/communication_request/metadata.yml +0 -0
  258. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/communication_request_group.rb +0 -0
  259. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/coverage/coverage_must_support_test.rb +0 -0
  260. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/coverage/coverage_validation.rb +0 -0
  261. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/coverage/metadata.yml +0 -0
  262. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/coverage_group.rb +0 -0
  263. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/device_request/device_request_must_support_test.rb +0 -0
  264. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/device_request/device_request_validation.rb +0 -0
  265. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/device_request/metadata.yml +0 -0
  266. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/device_request_group.rb +0 -0
  267. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/encounter/encounter_must_support_test.rb +0 -0
  268. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/encounter/encounter_validation.rb +0 -0
  269. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/encounter/metadata.yml +0 -0
  270. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/encounter_group.rb +0 -0
  271. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/medication_request/medication_request_must_support_test.rb +0 -0
  272. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/medication_request/medication_request_validation.rb +0 -0
  273. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/medication_request/metadata.yml +0 -0
  274. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/medication_request_group.rb +0 -0
  275. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/nutrition_order/metadata.yml +0 -0
  276. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/nutrition_order/nutrition_order_must_support_test.rb +0 -0
  277. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/nutrition_order/nutrition_order_validation.rb +0 -0
  278. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/nutrition_order_group.rb +0 -0
  279. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/questionnaire_response/metadata.yml +0 -0
  280. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/questionnaire_response/questionnaire_response_context_search.rb +0 -0
  281. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/questionnaire_response/questionnaire_response_must_support_test.rb +0 -0
  282. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/questionnaire_response/questionnaire_response_patient_search.rb +0 -0
  283. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/questionnaire_response/questionnaire_response_read.rb +0 -0
  284. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/questionnaire_response/questionnaire_response_validation.rb +0 -0
  285. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/questionnaire_response_group.rb +0 -0
  286. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/service_request/metadata.yml +0 -0
  287. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/service_request/service_request_must_support_test.rb +0 -0
  288. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/service_request/service_request_validation.rb +0 -0
  289. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/service_request_group.rb +0 -0
  290. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/task/metadata.yml +0 -0
  291. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/task/task_must_support_test.rb +0 -0
  292. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/task/task_validation.rb +0 -0
  293. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/task_group.rb +0 -0
  294. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/vision_prescription/metadata.yml +0 -0
  295. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/vision_prescription/vision_prescription_must_support_test.rb +0 -0
  296. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/vision_prescription/vision_prescription_validation.rb +0 -0
  297. /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/vision_prescription_group.rb +0 -0
  298. /data/lib/davinci_dtr_test_kit/{client_groups/light_ehr → light_ehr/v2.0.1/smart_ehr_launch}/fhir_context_coverage_test.rb +0 -0
  299. /data/lib/davinci_dtr_test_kit/{client_groups/light_ehr → light_ehr/v2.0.1/smart_ehr_launch}/fhir_context_references_test.rb +0 -0
  300. /data/lib/davinci_dtr_test_kit/{client_groups/light_ehr → light_ehr/v2.0.1/smart_ehr_launch}/fhir_launch_context_test.rb +0 -0
  301. /data/lib/davinci_dtr_test_kit/{endpoints/mock_authorization → server/endpoints}/simple_token_endpoint.rb +0 -0
  302. /data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1/adaptive_forms}/payer_server_next_response_complete_test.rb +0 -0
  303. /data/lib/davinci_dtr_test_kit/{docs → server/v2.0.1}/dtr_payer_server_suite_description_v201.md +0 -0
  304. /data/lib/davinci_dtr_test_kit/{validation_test.rb → server/validation_test.rb} +0 -0
  305. /data/lib/davinci_dtr_test_kit/{endpoints → smart_app/endpoints}/mock_authorization/authorize_endpoint.rb +0 -0
  306. /data/lib/davinci_dtr_test_kit/{endpoints → smart_app/endpoints}/mock_authorization.rb +0 -0
  307. /data/lib/davinci_dtr_test_kit/{endpoints → smart_app/endpoints}/mock_ehr/questionnaire_response_endpoint.rb +0 -0
  308. /data/lib/davinci_dtr_test_kit/{endpoints → smart_app/endpoints}/mock_ehr.rb +0 -0
  309. /data/lib/davinci_dtr_test_kit/{client_groups/adaptive_questionnaire/custom → smart_app/v2.0.1/adaptive_custom}/dtr_smart_app_custom_adaptive_request_test.rb +0 -0
  310. /data/lib/davinci_dtr_test_kit/{auth_groups → smart_app/v2.0.1/auth}/token_validation_test.rb +0 -0
  311. /data/lib/davinci_dtr_test_kit/{client_groups/respiratory → smart_app/v2.0.1/static_respiratory}/dtr_respiratory_rendering_group.rb +0 -0
@@ -0,0 +1,391 @@
1
+ require 'udap_security_test_kit'
2
+ require_relative '../endpoints/mock_payer'
3
+ require_relative '../../cross_suite/fhirpath_utils'
4
+ require_relative '../../cross_suite/response_selection_utils'
5
+ require_relative '../fixture_loader'
6
+ require_relative '../../tags'
7
+ require_relative 'next_question_template_questionnaires'
8
+ require_relative '../../cross_suite/v2.2.0/questionnaire_helper'
9
+
10
+ module DaVinciDTRTestKit
11
+ module MockPayer
12
+ class FullEHRV220NextQuestionEndpoint < Inferno::DSL::SuiteEndpoint
13
+ include MockPayer
14
+ include DaVinciDTRTestKit::FhirpathUtils
15
+ include DaVinciDTRTestKit::ResponseSelectionUtils
16
+ include DaVinciDTRTestKit::NextQuestionTemplateQuestionnaires
17
+ include DaVinciDTRTestKit::QuestionnaireHelper
18
+
19
+ def test_run_identifier
20
+ return request.params[:session_path] if request.params[:session_path].present?
21
+
22
+ UDAPSecurityTestKit::MockUDAPServer.issued_token_to_client_id(
23
+ request.headers['authorization']&.delete_prefix('Bearer ')
24
+ )
25
+ end
26
+
27
+ def tags
28
+ tags = [CLIENT_NEXT_TAG]
29
+ tags << test.config.options[:dtr_workflow_tag] if test.config.options[:dtr_workflow_tag].present?
30
+ unless test.config.options[:dtr_exclude_from_questionnaire_must_support]
31
+ tags << CLIENT_QUESTIONNAIRE_MUST_SUPPORT
32
+ end
33
+
34
+ tags
35
+ end
36
+
37
+ def make_response
38
+ response.headers['Access-Control-Allow-Origin'] = '*'
39
+ return if response.status == 401 # response set in update_result (expired token handling there)
40
+
41
+ response.format = 'application/fhir+json'
42
+ response.body = response_body.to_json
43
+ response.status = if response_body.is_a?(FHIR::OperationOutcome)
44
+ 400
45
+ else
46
+ 200
47
+ end
48
+ rescue StandardError => e
49
+ Inferno::Application['logger'].error("Error responding to $next-question:\n#{e.full_message}")
50
+ response.body =
51
+ operation_outcome(
52
+ 'fatal',
53
+ 'processing',
54
+ e.message
55
+ ).to_json
56
+ response.status = 500
57
+ end
58
+
59
+ def update_result
60
+ return unless UDAPSecurityTestKit::MockUDAPServer.request_has_expired_token?(request)
61
+
62
+ UDAPSecurityTestKit::MockUDAPServer.update_response_for_expired_token(response, 'Bearer token')
63
+ end
64
+
65
+ private
66
+
67
+ # ***********************************************************************
68
+ # Response Body
69
+ # ***********************************************************************
70
+
71
+ def response_body
72
+ @response_body ||= build_response_body
73
+ end
74
+
75
+ def build_response_body
76
+ error_outcome = check_request_questionnaire_response_validity
77
+ if error_outcome.is_a?(FHIR::OperationOutcome)
78
+ error_outcome
79
+ elsif questionnaire_template.is_a?(FHIR::OperationOutcome)
80
+ questionnaire_template
81
+ else
82
+ update_response
83
+ end
84
+ rescue MockPayer::ParseError => e
85
+ operation_outcome('error', 'invalid', e.message)
86
+ end
87
+
88
+ # ***********************************************************************
89
+ # Request Details
90
+ # ***********************************************************************
91
+
92
+ def request_questionnaire_response
93
+ @request_questionnaire_response ||= extract_questionnaire_response
94
+ end
95
+
96
+ def extract_questionnaire_response
97
+ parsed_request_body = parse_fhir_object(request.body.string)
98
+ if parsed_request_body.is_a?(FHIR::Parameters)
99
+ questionnaire_response_param = find_questionnaire_response(parsed_request_body)
100
+ return questionnaire_response_param if questionnaire_response_param.is_a?(FHIR::OperationOutcome)
101
+
102
+ questionnaire_response = questionnaire_response_param.resource
103
+ unless questionnaire_response.is_a?(FHIR::QuestionnaireResponse)
104
+ return operation_outcome(
105
+ 'error',
106
+ 'business-rule',
107
+ 'Input `parameter:questionnaire-response.resource` is not a QuestionnaireResponse.'
108
+ )
109
+ end
110
+
111
+ questionnaire_response
112
+ elsif parsed_request_body.is_a?(FHIR::QuestionnaireResponse)
113
+ parsed_request_body
114
+ else
115
+ operation_outcome('error', 'invalid',
116
+ 'Wrong resource type submitted for $next-question request: ' \
117
+ "expected Parameters or QuestionnaireResponse, got #{parsed_request_body.resourceType}")
118
+ end
119
+ rescue MockPayer::ParseError => e
120
+ operation_outcome('error', 'invalid', e.message)
121
+ end
122
+
123
+ def request_questionnaire
124
+ @request_questionnaire ||= extract_contained_questionnaire
125
+ end
126
+
127
+ def extract_contained_questionnaire
128
+ contained_questionnaire = contained_questionnaire_from_questionnaire_response(request_questionnaire_response)
129
+
130
+ unless contained_questionnaire.present?
131
+ return operation_outcome('error', 'invalid',
132
+ 'Invalid QuestionnaireResponse for $next-question request: ' \
133
+ 'no contained Questionnaire resource.')
134
+ end
135
+ unless contained_questionnaire.url.present?
136
+ return operation_outcome('error', 'invalid',
137
+ 'Invalid QuestionnaireResponse for $next-question request: ' \
138
+ 'contained Questionnaire must have a url.')
139
+ end
140
+
141
+ contained_questionnaire
142
+ end
143
+
144
+ # ***********************************************************************
145
+ # Verify Request
146
+ # ***********************************************************************
147
+
148
+ def check_request_questionnaire_response_validity
149
+ return request_questionnaire_response if request_questionnaire_response.is_a?(FHIR::OperationOutcome)
150
+ return request_questionnaire if request_questionnaire.is_a?(FHIR::OperationOutcome)
151
+
152
+ target_questionnaire_canonical = questionnaire_canonical_url(request_questionnaire)
153
+ packaged_questionnaire = requested_questionnaire(target_questionnaire_canonical)
154
+ unless packaged_questionnaire.present?
155
+ return operation_outcome('error', 'invalid',
156
+ 'Invalid QuestionnaireResponse for $next-question request: ' \
157
+ "questionnaire #{target_questionnaire_canonical} not returned " \
158
+ 'by $questionnaire-package during this wait test.')
159
+ end
160
+ unless adaptive_questionnaire?(packaged_questionnaire)
161
+ return operation_outcome('error', 'invalid',
162
+ 'Invalid QuestionnaireResponse for $next-question request: ' \
163
+ "questionnaire #{target_questionnaire_canonical} is not adaptive.")
164
+ end
165
+
166
+ nil
167
+ end
168
+
169
+ def requested_questionnaire(questionnaire_canonical)
170
+ successful_questionnaire_package_requests.each do |qp_request|
171
+ response_parameters = FHIR.from_contents(qp_request.response_body)
172
+ next unless response_parameters.present?
173
+
174
+ response_parameters.parameter.select { |param| param.name == 'packagebundle' }.map(&:resource)
175
+ .each do |bundle|
176
+ target_questionnaire = extract_target_questionnaire(bundle, questionnaire_canonical)
177
+ return target_questionnaire if target_questionnaire.present?
178
+ end
179
+ end
180
+ nil
181
+ end
182
+
183
+ def successful_questionnaire_package_requests
184
+ requests_repo = Inferno::Repositories::Requests.new
185
+ previous_requests = requests_repo.requests_for_result(result.id)
186
+ previous_requests.select { |req| req.url.include?('$questionnaire-package') && req.status == 200 }
187
+ .map { |req| requests_repo.find_full_request(req.id) }
188
+ end
189
+
190
+ def extract_target_questionnaire(bundle, target_questionnaire_canonical)
191
+ bundle.entry.each do |entry|
192
+ next unless entry.resource.is_a?(FHIR::Questionnaire) &&
193
+ questionnaire_canonical_url(entry.resource) == target_questionnaire_canonical
194
+
195
+ return entry.resource
196
+ end
197
+ nil
198
+ end
199
+
200
+ # ***********************************************************************
201
+ # Response Template
202
+ # ***********************************************************************
203
+
204
+ def questionnaire_template
205
+ @questionnaire_template ||=
206
+ if template_from_fixture?
207
+ questionnaire_template_from_fixture
208
+ elsif template_from_input?
209
+ questionnaire_template_from_input
210
+ else
211
+ raise Inferno::Exceptions::TestSuiteImplementationException.new(
212
+ 'dtr $next-question response template',
213
+ 'No response template source indicated by the test implementer, please file a bug report.'
214
+ )
215
+ end
216
+ end
217
+
218
+ def template_from_fixture?
219
+ test.config.options[:nq_questionnaire_template_fixture].present?
220
+ end
221
+
222
+ def template_from_input?
223
+ !template_from_fixture? && test.config.options[:nq_questionnaire_template_input].present?
224
+ end
225
+
226
+ def questionnaire_template_from_fixture
227
+ fixture = FixtureLoader.instance[test.config.options[:nq_questionnaire_template_fixture]]
228
+ unless fixture.is_a?(FHIR::Questionnaire)
229
+ raise Inferno::Exceptions::TestSuiteImplementationException.new(
230
+ 'dtr $next-question response template fixture',
231
+ 'Invalid $next-question response template fixture: ' \
232
+ "Expected Questionnaire, got '#{fixture.resourceType}'."
233
+ )
234
+ end
235
+ fixture
236
+ end
237
+
238
+ def questionnaire_template_from_input
239
+ input_name = test.config.options[:nq_questionnaire_template_input]
240
+ value = JSON.parse(result.input_json)
241
+ .find { |input| input['name'] == input_name }
242
+ &.dig('value')
243
+
244
+ title = input_title(input_name)
245
+ unless value.present?
246
+ return operation_outcome('error', 'invalid',
247
+ "No response template provided by the user in input '#{title}'.")
248
+ end
249
+
250
+ parse_questionnaire_response_input_template(value, title)
251
+ end
252
+
253
+ def parse_questionnaire_response_input_template(value, title)
254
+ parsed_json = JSON.parse(value)
255
+ if parsed_json.is_a?(Array)
256
+ matching_questionnaire_template(questionnaires_from_template_value(value), title)
257
+ else
258
+ parse_single_questionnaire_template(value, title)
259
+ end
260
+ rescue JSON::ParserError
261
+ operation_outcome('error', 'invalid', "Input #{title} does not contain valid JSON.")
262
+ end
263
+
264
+ def parse_single_questionnaire_template(value, title)
265
+ parsed = parse_fhir_object(value, entity: "Input #{title}")
266
+ unless parsed.is_a?(FHIR::Questionnaire)
267
+ return operation_outcome('error', 'invalid',
268
+ 'Invalid input response template for $next-question: ' \
269
+ "Expected Questionnaire, got '#{parsed.resourceType}'.")
270
+ end
271
+ parsed
272
+ rescue MockPayer::ParseError => e
273
+ operation_outcome('error', 'invalid', e.message)
274
+ end
275
+
276
+ def matching_questionnaire_template(questionnaires, title)
277
+ matching = questionnaires.find { |questionnaire| questionnaire_template_matches_request?(questionnaire) }
278
+ return matching if matching.present?
279
+
280
+ operation_outcome('error', 'invalid',
281
+ 'Invalid input response template for $next-question: ' \
282
+ "No Questionnaire in input '#{title}' matches " \
283
+ "#{questionnaire_canonical_url(request_questionnaire)}.")
284
+ end
285
+
286
+ # test.config.options input references are stored as input names; testers only see the
287
+ # input's title in the Inferno UI, so client-facing messages should use that instead.
288
+ def input_title(input_name)
289
+ test.config.input(input_name.to_sym)&.title || input_name
290
+ end
291
+
292
+ def questionnaire_template_matches_request?(questionnaire)
293
+ return false unless questionnaire.url == request_questionnaire.url
294
+
295
+ request_questionnaire.version.blank? || questionnaire.version == request_questionnaire.version
296
+ end
297
+
298
+ # ***********************************************************************
299
+ # Replace {{fhirpath}} tokens in template
300
+ # ***********************************************************************
301
+
302
+ def replace_tokens_in_item(item)
303
+ instantiated_json = replace_tokens_in_string(item.to_json, request_questionnaire_response)
304
+ FHIR::Questionnaire::Item.new(JSON.parse(instantiated_json))
305
+ rescue JSON::ParserError => e
306
+ if template_from_fixture?
307
+ raise Inferno::Exceptions::TestSuiteImplementationException.new('dtr response template tokens', e.message)
308
+ end
309
+
310
+ raise MockPayer::ParseError, e.message
311
+ end
312
+
313
+ # ***********************************************************************
314
+ # Update Response
315
+ # ***********************************************************************
316
+
317
+ def update_response
318
+ @new_questions_added = false
319
+ add_questions_from_questionnaire_template
320
+ complete_questionnaire_response if !@new_questions_added && questionnaire_response_completed?
321
+ request_questionnaire_response
322
+ rescue FhirpathServiceError => e
323
+ raise if template_from_fixture?
324
+
325
+ operation_outcome('error', 'invalid', e.message)
326
+ end
327
+
328
+ # ***********************************************************************
329
+ # Add Question Items from Template
330
+ # ***********************************************************************
331
+
332
+ def add_questions_from_questionnaire_template
333
+ questionnaire_template.item.each do |template_item|
334
+ add_new_item_if_needed(template_item, request_questionnaire.item)
335
+ end
336
+ end
337
+
338
+ def add_new_item_if_needed(item, target_list)
339
+ existing = target_list.find { |target_item| item.linkId == target_item.linkId }
340
+ return add_children_if_needed(item, existing) if existing
341
+ return unless add_missing_item_to_response?(item)
342
+
343
+ new_item = replace_tokens_in_item(item)
344
+ strip_inferno_extensions(new_item)
345
+ new_item.item = []
346
+ target_list << new_item
347
+ @new_questions_added = true
348
+ add_children_if_needed(item, new_item)
349
+ end
350
+
351
+ def add_children_if_needed(template_item, form_item)
352
+ return unless template_item.item.present?
353
+
354
+ template_item.item.each { |child| add_new_item_if_needed(child, form_item.item) }
355
+ end
356
+
357
+ def add_missing_item_to_response?(item)
358
+ return false if item.linkId.blank?
359
+
360
+ include_entity?(item, request_questionnaire_response, '$next-question')
361
+ end
362
+
363
+ # ***********************************************************************
364
+ # Complete QuestionnaireResponse
365
+ # ***********************************************************************
366
+
367
+ def questionnaire_response_completed?
368
+ request_questionnaire.item.all? do |item|
369
+ item_not_required_or_completed?(item, request_questionnaire_response.item)
370
+ end
371
+ end
372
+
373
+ def item_not_required_or_completed?(item, response_item_list)
374
+ required = (item.required == true)
375
+ response_item = response_item_list.find { |response_item| response_item.linkId == item.linkId }
376
+ not_required_or_completed = !required || answer_completed_and_valid?(item, response_item)
377
+ return false unless not_required_or_completed
378
+
379
+ item.item.all? { |sub_item| item_not_required_or_completed?(sub_item, response_item&.item || []) }
380
+ end
381
+
382
+ def answer_completed_and_valid?(_item, response_item)
383
+ response_item&.answer&.any? { |answer| !answer&.value.nil? }
384
+ end
385
+
386
+ def complete_questionnaire_response
387
+ request_questionnaire_response.status = 'completed'
388
+ end
389
+ end
390
+ end
391
+ end
@@ -0,0 +1,206 @@
1
+ require 'udap_security_test_kit'
2
+ require_relative '../endpoints/mock_payer'
3
+ require_relative '../../cross_suite/fhirpath_utils'
4
+ require_relative '../../cross_suite/response_selection_utils'
5
+ require_relative '../fixture_loader'
6
+ require_relative '../../tags'
7
+
8
+ module DaVinciDTRTestKit
9
+ module MockPayer
10
+ class FullEHRV220QuestionnairePackageEndpoint < Inferno::DSL::SuiteEndpoint
11
+ include MockPayer
12
+ include DaVinciDTRTestKit::FhirpathUtils
13
+ include DaVinciDTRTestKit::ResponseSelectionUtils
14
+
15
+ def test_run_identifier
16
+ return request.params[:session_path] if request.params[:session_path].present?
17
+
18
+ UDAPSecurityTestKit::MockUDAPServer.issued_token_to_client_id(
19
+ request.headers['authorization']&.delete_prefix('Bearer ')
20
+ )
21
+ end
22
+
23
+ def tags
24
+ tags = [QUESTIONNAIRE_PACKAGE_TAG]
25
+ tags << test.config.options[:dtr_workflow_tag] if test.config.options[:dtr_workflow_tag].present?
26
+ unless test.config.options[:dtr_exclude_from_questionnaire_must_support]
27
+ tags << CLIENT_QUESTIONNAIRE_MUST_SUPPORT
28
+ end
29
+
30
+ tags
31
+ end
32
+
33
+ def make_response
34
+ response.headers['Access-Control-Allow-Origin'] = '*'
35
+ return if response.status == 401 # response set in update_result (expired token handling there)
36
+
37
+ response.format = 'application/fhir+json'
38
+ response.body = response_body.to_json
39
+ response.status = if response_body.is_a?(FHIR::OperationOutcome)
40
+ 400
41
+ else
42
+ 200
43
+ end
44
+ rescue StandardError => e
45
+ Inferno::Application['logger'].error("Error responding to $questionnaire-package:\n#{e.full_message}")
46
+ response.body =
47
+ operation_outcome(
48
+ 'fatal',
49
+ 'processing',
50
+ e.message
51
+ ).to_json
52
+ response.status = 500
53
+ end
54
+
55
+ def update_result
56
+ return unless UDAPSecurityTestKit::MockUDAPServer.request_has_expired_token?(request)
57
+
58
+ UDAPSecurityTestKit::MockUDAPServer.update_response_for_expired_token(response, 'Bearer token')
59
+ end
60
+
61
+ private
62
+
63
+ # ***********************************************************************
64
+ # Response Body
65
+ # ***********************************************************************
66
+
67
+ def response_body
68
+ @response_body ||= build_response_body
69
+ end
70
+
71
+ def build_response_body
72
+ if !request_parameters.is_a?(FHIR::Parameters)
73
+ operation_outcome('error', 'invalid', 'Request body must be a FHIR Parameters resource.')
74
+ elsif response_template.is_a?(FHIR::OperationOutcome)
75
+ response_template
76
+ elsif single_use_limit_exceeded?
77
+ operation_outcome('error', 'business-rule',
78
+ '$questionnaire-package is configured to respond successfully only once.')
79
+ else
80
+ instantiate_template
81
+ end
82
+ rescue MockPayer::ParseError => e
83
+ operation_outcome('error', 'invalid', e.message)
84
+ end
85
+
86
+ def single_use_limit_exceeded?
87
+ test.config.options[:qp_single_use] &&
88
+ count_previous_successful_requests('$questionnaire-package') >= 1
89
+ end
90
+
91
+ # ***********************************************************************
92
+ # Template Instantiation
93
+ # ***********************************************************************
94
+
95
+ def instantiate_template
96
+ result = replace_tokens(
97
+ FHIR::Parameters.new(
98
+ parameter: response_template.parameter.select do |param|
99
+ include_entity?(param, request_parameters, '$questionnaire-package')
100
+ end
101
+ )
102
+ )
103
+ result.parameter.each { |param| strip_inferno_extensions(param) } if result.is_a?(FHIR::Parameters)
104
+ result
105
+ rescue FhirpathServiceError => e
106
+ raise if template_from_fixture?
107
+
108
+ operation_outcome('error', 'invalid', e.message)
109
+ end
110
+
111
+ # ***********************************************************************
112
+ # Replace {{fhirpath}} tokens in template
113
+ # ***********************************************************************
114
+
115
+ def replace_tokens(parameters_resource)
116
+ instantiated_json = replace_tokens_in_string(parameters_resource.to_json, request_parameters)
117
+ FHIR.from_contents(instantiated_json)
118
+ rescue JSON::ParserError => e
119
+ if template_from_fixture?
120
+ raise Inferno::Exceptions::TestSuiteImplementationException.new('dtr response template tokens', e.message)
121
+ end
122
+
123
+ operation_outcome('error', 'invalid', e.message)
124
+ end
125
+
126
+ # ***********************************************************************
127
+ # Request Contents
128
+ # ***********************************************************************
129
+
130
+ def request_parameters
131
+ @request_parameters ||= parse_fhir_object(request.body.string)
132
+ end
133
+
134
+ # ***********************************************************************
135
+ # Response Template
136
+ # ***********************************************************************
137
+
138
+ def response_template
139
+ @response_template ||=
140
+ if template_from_fixture?
141
+ parameters_template_from_fixture
142
+ elsif template_from_input?
143
+ parameters_template_from_input
144
+ else
145
+ raise Inferno::Exceptions::TestSuiteImplementationException.new(
146
+ 'dtr $questionnaire-package response template',
147
+ 'No response template source indicated by the test implementer, please file a bug report.'
148
+ )
149
+ end
150
+ end
151
+
152
+ def template_from_fixture?
153
+ test.config.options[:qp_response_template_fixture].present?
154
+ end
155
+
156
+ def template_from_input?
157
+ !template_from_fixture? && test.config.options[:qp_response_template_input].present?
158
+ end
159
+
160
+ def parameters_template_from_fixture
161
+ fixture = FixtureLoader.instance[test.config.options[:qp_response_template_fixture]]
162
+ unless fixture.is_a?(FHIR::Parameters)
163
+ raise Inferno::Exceptions::TestSuiteImplementationException.new(
164
+ 'dtr $questionnaire-package response template fixture',
165
+ 'Invalid $questionnaire-package response template fixture: ' \
166
+ "Expected Parameters, got '#{fixture.resourceType}'."
167
+ )
168
+ end
169
+ fixture
170
+ end
171
+
172
+ def parameters_template_from_input
173
+ input_name = test.config.options[:qp_response_template_input]
174
+ value = JSON.parse(result.input_json)
175
+ .find { |input| input['name'] == input_name }
176
+ &.dig('value')
177
+
178
+ title = input_title(input_name)
179
+ unless value.present?
180
+ return operation_outcome('error', 'invalid',
181
+ "No response template provided by the user in input '#{title}'.")
182
+ end
183
+
184
+ parse_parameters_input_template(value, title)
185
+ end
186
+
187
+ def parse_parameters_input_template(value, title)
188
+ parsed = parse_fhir_object(value, entity: "Input #{title}")
189
+ unless parsed.is_a?(FHIR::Parameters)
190
+ return operation_outcome('error', 'invalid',
191
+ 'Invalid input response template for $questionnaire-package: ' \
192
+ "Expected Parameters, got '#{parsed.resourceType}'.")
193
+ end
194
+ parsed
195
+ rescue MockPayer::ParseError => e
196
+ operation_outcome('error', 'invalid', e.message)
197
+ end
198
+
199
+ # test.config.options input references are stored as input names; testers only see the
200
+ # input's title in the Inferno UI, so client-facing messages should use that instead.
201
+ def input_title(input_name)
202
+ test.config.input(input_name.to_sym)&.title || input_name
203
+ end
204
+ end
205
+ end
206
+ end