davinci_dtr_test_kit 0.17.1 → 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.
- checksums.yaml +4 -4
- data/config/presets/v220_full_ehr_suite_run_against_payer_suite.json.erb +19 -0
- data/config/presets/v220_payer_suite_run_against_full_ehr_suite.json.erb +76 -0
- data/lib/davinci_dtr_test_kit/cross_suite/fhirpath_utils.rb +52 -0
- data/lib/davinci_dtr_test_kit/cross_suite/generated/v2.2.0/dtr_base_questionnaire/metadata.yml +212 -0
- data/lib/davinci_dtr_test_kit/cross_suite/generated/v2.2.0/dtr_q_package_bundle/metadata.yml +39 -0
- data/lib/davinci_dtr_test_kit/cross_suite/generated/v2.2.0/dtr_qpackage_output_parameters/metadata.yml +30 -0
- data/lib/davinci_dtr_test_kit/cross_suite/generated/v2.2.0/dtr_questionnaire_adapt/metadata.yml +17 -0
- data/lib/davinci_dtr_test_kit/cross_suite/generated/v2.2.0/dtr_questionnaire_adapt_search/metadata.yml +91 -0
- data/lib/davinci_dtr_test_kit/cross_suite/generated/v2.2.0/dtr_std_questionnaire/metadata.yml +17 -0
- data/lib/davinci_dtr_test_kit/cross_suite/generated/v2.2.0/metadata.yml +403 -0
- data/lib/davinci_dtr_test_kit/cross_suite/generated_profile_metadata.rb +22 -0
- data/lib/davinci_dtr_test_kit/cross_suite/response_selection_utils.rb +85 -0
- data/lib/davinci_dtr_test_kit/cross_suite/v2.2.0/dtr_conformance_verification.rb +21 -0
- data/lib/davinci_dtr_test_kit/cross_suite/v2.2.0/multi_request_message_helper.rb +35 -0
- data/lib/davinci_dtr_test_kit/cross_suite/v2.2.0/questionnaire_helper.rb +162 -0
- data/lib/davinci_dtr_test_kit/{dtr_client_options.rb → full_ehr/dtr_full_ehr_options.rb} +1 -1
- data/lib/davinci_dtr_test_kit/{endpoints → full_ehr/endpoints}/mock_payer.rb +9 -3
- data/lib/davinci_dtr_test_kit/{endpoints → full_ehr/endpoints}/mock_udap_smart_server/token_endpoint.rb +2 -2
- data/lib/davinci_dtr_test_kit/full_ehr/fixture_loader.rb +37 -0
- data/lib/davinci_dtr_test_kit/full_ehr/fixtures/dinner_adaptive/dinner_order_adaptive_next_question_template.json +243 -0
- data/lib/davinci_dtr_test_kit/full_ehr/fixtures/dinner_adaptive/parameters_questionnaire_dinner_order_adaptive.json +104 -0
- data/lib/davinci_dtr_test_kit/full_ehr/fixtures/dinner_static/parameters_questionnaire_dinner_order_static.json +291 -0
- data/lib/davinci_dtr_test_kit/full_ehr/fixtures/empty_templates/next_question_template_empty.json +1 -0
- data/lib/davinci_dtr_test_kit/full_ehr/fixtures/empty_templates/parameters_questionnaire_package_empty.json +9 -0
- data/lib/davinci_dtr_test_kit/full_ehr/short_circuit_interaction_verification.rb +73 -0
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- data/lib/davinci_dtr_test_kit/{client_groups/adaptive_questionnaire/custom → full_ehr/v2.0.1}/dtr_full_ehr_custom_adaptive_workflow_group.rb +14 -14
- 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
- data/lib/davinci_dtr_test_kit/{client_groups/must_support → full_ehr/v2.0.1}/dtr_full_ehr_questionnaire_must_support_group.rb +6 -6
- 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
- data/lib/davinci_dtr_test_kit/{dtr_full_ehr_suite.rb → full_ehr/v2.0.1/dtr_full_ehr_suite.rb} +19 -20
- 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
- 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
- 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
- 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
- data/lib/davinci_dtr_test_kit/{client_groups → full_ehr/v2.0.1}/must_support/dtr_must_support_attestation_test.rb +1 -1
- data/lib/davinci_dtr_test_kit/{client_groups → full_ehr/v2.0.1}/must_support/dtr_questionnaire_must_support_test.rb +1 -1
- data/lib/davinci_dtr_test_kit/{client_groups → full_ehr/v2.0.1}/payer_registration/configuration_display_smart_test.rb +1 -1
- data/lib/davinci_dtr_test_kit/{client_groups → full_ehr/v2.0.1}/payer_registration/configuration_display_udap_test.rb +1 -1
- data/lib/davinci_dtr_test_kit/{client_groups → full_ehr/v2.0.1}/shared/dtr_custom_questionnaire_expressions_test.rb +1 -1
- data/lib/davinci_dtr_test_kit/{client_groups → full_ehr/v2.0.1}/shared/dtr_custom_questionnaire_extensions_test.rb +1 -1
- data/lib/davinci_dtr_test_kit/{client_groups → full_ehr/v2.0.1}/shared/dtr_custom_questionnaire_libraries_test.rb +1 -1
- data/lib/davinci_dtr_test_kit/{client_groups → full_ehr/v2.0.1}/shared/dtr_custom_questionnaire_package_validation_test.rb +1 -1
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- data/lib/davinci_dtr_test_kit/{client_groups → full_ehr/v2.0.1}/shared/dtr_prepopulation_attestation_test.rb +1 -1
- data/lib/davinci_dtr_test_kit/{client_groups → full_ehr/v2.0.1}/shared/dtr_prepopulation_override_attestation_test.rb +1 -1
- data/lib/davinci_dtr_test_kit/{client_groups → full_ehr/v2.0.1}/shared/dtr_questionnaire_package_request_validation_test.rb +1 -1
- data/lib/davinci_dtr_test_kit/{client_groups → full_ehr/v2.0.1}/shared/dtr_questionnaire_response_basic_conformance_test.rb +2 -2
- data/lib/davinci_dtr_test_kit/{client_groups → full_ehr/v2.0.1}/shared/dtr_questionnaire_response_prepopulation_test.rb +1 -1
- data/lib/davinci_dtr_test_kit/{client_groups → full_ehr/v2.0.1}/shared/dtr_rendering_attestation_test.rb +1 -1
- 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
- data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/dtr_full_ehr_abstract_adaptive_group.rb +87 -0
- data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/dtr_full_ehr_abstract_standard_group.rb +59 -0
- data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/dtr_full_ehr_suite.rb +145 -0
- data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/dtr_full_ehr_suite_description_v220.md +254 -0
- data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/full_ehr_next_question_endpoint.rb +391 -0
- data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/full_ehr_questionnaire_package_endpoint.rb +206 -0
- data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/interaction/adaptive_questionnaires_completed_test.rb +108 -0
- data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/interaction/interaction_wait_test.rb +177 -0
- data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/interaction/ui_display_and_interaction_attestation_test.rb +132 -0
- data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/must_support/dtr_additional_questionnaires_interaction_group.rb +74 -0
- data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/must_support/dtr_questionnaire_adaptive_must_support_test.rb +45 -0
- data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/must_support/dtr_questionnaire_base_must_support_test.rb +43 -0
- data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/must_support/dtr_questionnaire_standard_must_support_test.rb +45 -0
- data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/next_question_template_questionnaires.rb +21 -0
- data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/request/dtr_next_question_request_validation_test.rb +85 -0
- data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/request/dtr_questionnaire_package_request_validation_test.rb +89 -0
- data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/response/dtr_next_question_response_validation_test.rb +85 -0
- data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/response/dtr_questionnaire_package_response_validation_test.rb +77 -0
- data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/workflows/dtr_full_ehr_workflow_adaptive_group.rb +24 -0
- data/lib/davinci_dtr_test_kit/full_ehr/v2.2.0/workflows/dtr_full_ehr_workflow_standard_group.rb +21 -0
- data/lib/davinci_dtr_test_kit/generator/ig_metadata.rb +21 -0
- data/lib/davinci_dtr_test_kit/generator/profile_metadata_extractor.rb +57 -0
- data/lib/davinci_dtr_test_kit/generator.rb +117 -0
- data/lib/davinci_dtr_test_kit/igs/davinci_dtr_2.2.0.tgz +0 -0
- data/lib/davinci_dtr_test_kit/{dtr_options.rb → light_ehr/dtr_light_ehr_options.rb} +1 -1
- data/lib/davinci_dtr_test_kit/{dtr_light_ehr_suite.rb → light_ehr/v2.0.1/dtr_light_ehr_suite.rb} +8 -9
- data/lib/davinci_dtr_test_kit/{client_groups/light_ehr → light_ehr/v2.0.1}/dtr_light_ehr_supported_endpoints_group.rb +5 -5
- data/lib/davinci_dtr_test_kit/{client_groups/light_ehr → light_ehr/v2.0.1}/dtr_smart_ehr_launch.rb +3 -3
- data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/communication_request/communication_request_read.rb +1 -1
- data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/coverage/coverage_read.rb +1 -1
- data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/device_request/device_request_read.rb +1 -1
- data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/encounter/encounter_read.rb +1 -1
- data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/medication_request/medication_request_read.rb +1 -1
- data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/nutrition_order/nutrition_order_read.rb +1 -1
- data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/questionnaire_response/questionnaire_response_create.rb +1 -1
- data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/questionnaire_response/questionnaire_response_update.rb +1 -1
- data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/service_request/service_request_read.rb +1 -1
- data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/task/task_create.rb +1 -1
- data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/task/task_read.rb +1 -1
- data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/task/task_update.rb +1 -1
- data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/vision_prescription/vision_prescription_read.rb +1 -1
- 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 +2 -2
- 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 +1 -1
- 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 +1 -1
- 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 +1 -1
- 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 +2 -2
- data/lib/davinci_dtr_test_kit/metadata.rb +13 -68
- data/lib/davinci_dtr_test_kit/requirements/davinci_dtr_test_kit_requirements.csv +216 -0
- data/lib/davinci_dtr_test_kit/requirements/generated/dtr_full_ehr_requirements_coverage.csv +1 -1
- data/lib/davinci_dtr_test_kit/requirements/generated/dtr_full_ehr_v220_requirements_coverage.csv +1 -0
- data/lib/davinci_dtr_test_kit/requirements/generated/dtr_light_ehr_requirements_coverage.csv +1 -1
- data/lib/davinci_dtr_test_kit/requirements/generated/dtr_payer_server_requirements_coverage.csv +1 -1
- data/lib/davinci_dtr_test_kit/requirements/generated/dtr_payer_server_v220_requirements_coverage.csv +114 -0
- data/lib/davinci_dtr_test_kit/requirements/generated/dtr_smart_app_requirements_coverage.csv +1 -1
- data/lib/davinci_dtr_test_kit/requirements/hl7.fhir.us.davinci-dtr_2.2.0_requirements.xlsx +0 -0
- data/lib/davinci_dtr_test_kit/{endpoints/mock_payer → server/endpoints}/next_question_proxy_endpoint.rb +2 -0
- data/lib/davinci_dtr_test_kit/{endpoints/mock_payer → server/endpoints}/questionnaire_package_proxy_endpoint.rb +2 -0
- data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1/adaptive_forms}/adaptive_form_libraries_test.rb +2 -1
- data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1/adaptive_forms}/adaptive_form_questionnaire_expressions_test.rb +2 -1
- data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1/adaptive_forms}/adaptive_form_questionnaire_extensions_test.rb +2 -1
- data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1/adaptive_forms}/adaptive_next_questionnaire_expressions_test.rb +2 -1
- data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1/adaptive_forms}/adaptive_next_questionnaire_extensions_test.rb +2 -1
- data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1/adaptive_forms}/payer_server_adaptive_request_test.rb +1 -1
- data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1/adaptive_forms}/payer_server_adaptive_request_validation_test.rb +2 -1
- data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1/adaptive_forms}/payer_server_adaptive_response_bundles_validation_test.rb +2 -1
- data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1/adaptive_forms}/payer_server_adaptive_response_search_validation_test.rb +2 -1
- data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1/adaptive_forms}/payer_server_adaptive_response_validation_test.rb +3 -2
- data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1/adaptive_forms}/payer_server_next_request_validation_test.rb +2 -1
- data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1/adaptive_forms}/payer_server_next_response_validation_test.rb +2 -1
- data/lib/davinci_dtr_test_kit/{dtr_payer_server_suite.rb → server/v2.0.1/dtr_payer_server_suite.rb} +9 -10
- data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1}/payer_server_adaptive_group.rb +13 -13
- data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1}/payer_server_static_group.rb +6 -6
- data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1/static_forms}/static_form_libraries_test.rb +2 -1
- data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1/static_forms}/static_form_questionnaire_expressions_test.rb +2 -1
- data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1/static_forms}/static_form_questionnaire_extensions_test.rb +2 -1
- data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1/static_forms}/static_form_request_test.rb +3 -2
- data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1/static_forms}/static_form_request_validation_test.rb +3 -2
- data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1/static_forms}/static_form_response_validation_test.rb +4 -3
- data/lib/davinci_dtr_test_kit/server/v2.2.0/client_simulation.rb +297 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/dtr_payer_server_capability_statement_test.rb +73 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/dtr_payer_server_suite.rb +322 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/dtr_payer_server_suite_description_v220.md +37 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/interaction_test.rb +97 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/log_questionnaire_errors_support_test.rb +57 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/must_support/questionnaire_adaptive_must_support_test.rb +47 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/must_support/questionnaire_adaptive_search_must_support_test.rb +40 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/must_support/questionnaire_base_must_support_test.rb +40 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/must_support/questionnaire_package_bundle_must_support_test.rb +38 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/must_support/questionnaire_package_output_parameters_must_support_test.rb +37 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/must_support/questionnaire_standard_must_support_test.rb +39 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/next_question_request_validation_test.rb +45 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/next_question_support/adaptive_questionnaire_endpoint_test.rb +98 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/next_question_support/invalid_questionnaire_response_test.rb +43 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/next_question_support/next_contained_questionnaire_response_references_test.rb +46 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/next_question_support/next_question_response_references_test.rb +56 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/next_question_support/next_question_response_validation_test.rb +67 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_design/contained_binary_test.rb +58 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_design/contained_binary_validation.rb +128 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_design/cql_library_validation_test.rb +58 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_design/questionnaire_design_support.rb +65 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_design/questionnaire_expression_elm_test.rb +81 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_design/questionnaire_expression_language_test.rb +63 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_design/questionnaire_prepopulation_test.rb +42 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_design/questionnaire_relevance_logic_test.rb +40 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_operation_validation.rb +440 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_package_request_validation_test.rb +42 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_package_support/adaptive_questionnaire_response_contained_questionnaire_test.rb +127 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_package_support/adaptive_questionnaire_response_validation_test.rb +61 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_package_support/contained_questionnaire_response_references_test.rb +42 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_package_support/dtr_server_no_custom_extension_test.rb +184 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_package_support/dtr_server_questionnaire_not_found_test.rb +76 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_package_support/dtr_server_questionnaire_package_contents_test.rb +89 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_package_support/initial_questionnaire_response_test.rb +132 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_package_support/questionnaire_package_input_type_test.rb +110 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_package_support/questionnaire_references_version_specific_test.rb +79 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_package_support/questionnaire_response_questionnaire_canonical_test.rb +89 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_package_support/questionnaire_response_references_test.rb +51 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_package_support/questionnaire_response_validation_test.rb +63 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_package_support/source_data_error_test.rb +43 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_package_support/value_set_validation_test.rb +90 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_response_reference_validation.rb +133 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/value_set_expand_support/small_value_set_expansion_test.rb +120 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/value_set_expand_support/value_set_expansion_test.rb +51 -0
- data/lib/davinci_dtr_test_kit/server/v2.2.0/value_set_expand_support/value_set_expansion_validation.rb +58 -0
- data/lib/davinci_dtr_test_kit/{endpoints → smart_app/endpoints}/mock_authorization/token_endpoint.rb +1 -1
- data/lib/davinci_dtr_test_kit/{endpoints → smart_app/endpoints}/mock_ehr/fhir_get_endpoint.rb +1 -1
- data/lib/davinci_dtr_test_kit/smart_app/endpoints/mock_payer/smart_app_next_question_endpoint.rb +12 -0
- data/lib/davinci_dtr_test_kit/smart_app/endpoints/mock_payer/smart_app_questionnaire_package_endpoint.rb +12 -0
- 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 +12 -12
- 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
- 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
- data/lib/davinci_dtr_test_kit/{auth_groups → smart_app/v2.0.1/auth}/token_request_test.rb +1 -1
- 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
- data/lib/davinci_dtr_test_kit/{client_groups/must_support → smart_app/v2.0.1}/dtr_smart_app_questionnaire_must_support_group.rb +6 -6
- data/lib/davinci_dtr_test_kit/{client_groups/respiratory → smart_app/v2.0.1}/dtr_smart_app_respiratory_workflow_group.rb +3 -3
- 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
- data/lib/davinci_dtr_test_kit/{dtr_smart_app_suite.rb → smart_app/v2.0.1/dtr_smart_app_suite.rb} +21 -21
- 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
- data/lib/davinci_dtr_test_kit/{auth_groups → smart_app/v2.0.1}/oauth2_authentication_group.rb +2 -2
- data/lib/davinci_dtr_test_kit/{client_groups/respiratory → smart_app/v2.0.1/static_respiratory}/dtr_respiratory_questionnaire_package_group.rb +1 -1
- 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
- data/lib/davinci_dtr_test_kit/{client_groups/respiratory → smart_app/v2.0.1/static_respiratory}/dtr_respiratory_questionnaire_response_group.rb +2 -2
- 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
- data/lib/davinci_dtr_test_kit/{client_groups/respiratory → smart_app/v2.0.1/static_respiratory}/dtr_respiratory_rendering_attestation_test.rb +1 -1
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- data/lib/davinci_dtr_test_kit/tags.rb +2 -0
- data/lib/davinci_dtr_test_kit/version.rb +2 -2
- data/lib/davinci_dtr_test_kit.rb +6 -4
- metadata +299 -209
- data/lib/davinci_dtr_test_kit/certs/InfernoCA.key +0 -52
- data/lib/davinci_dtr_test_kit/certs/InfernoCA.pem +0 -35
- data/lib/davinci_dtr_test_kit/certs/TestKit.pem +0 -32
- data/lib/davinci_dtr_test_kit/certs/TestKitPrivateKey.key +0 -28
- data/lib/davinci_dtr_test_kit/endpoints/mock_payer/full_ehr_next_question_endpoint.rb +0 -30
- data/lib/davinci_dtr_test_kit/endpoints/mock_payer/full_ehr_questionnaire_package_endpoint.rb +0 -31
- data/lib/davinci_dtr_test_kit/fixture_loader.rb +0 -21
- /data/lib/davinci_dtr_test_kit/{endpoints → cross_suite}/cors.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{cql_test.rb → cross_suite/v2.0.1/cql_test.rb} +0 -0
- /data/lib/davinci_dtr_test_kit/{dtr_questionnaire_response_validation.rb → cross_suite/v2.0.1/dtr_questionnaire_response_validation.rb} +0 -0
- /data/lib/davinci_dtr_test_kit/{descriptions.rb → full_ehr/descriptions.rb} +0 -0
- /data/lib/davinci_dtr_test_kit/{fixtures → full_ehr/fixtures}/dinner_adaptive/dinner_order_adaptive_next_question_burrito.json +0 -0
- /data/lib/davinci_dtr_test_kit/{fixtures → full_ehr/fixtures}/dinner_adaptive/dinner_order_adaptive_next_question_hamburger.json +0 -0
- /data/lib/davinci_dtr_test_kit/{fixtures → full_ehr/fixtures}/dinner_adaptive/dinner_order_adaptive_next_question_initial.json +0 -0
- /data/lib/davinci_dtr_test_kit/{fixtures → full_ehr/fixtures}/dinner_adaptive/questionnaire_dinner_order_adaptive.json +0 -0
- /data/lib/davinci_dtr_test_kit/{fixtures → full_ehr/fixtures}/dinner_static/questionnaire_dinner_order_static.json +0 -0
- /data/lib/davinci_dtr_test_kit/{fixtures → full_ehr/fixtures}/dinner_static/questionnaire_response_dinner_order_static.json +0 -0
- /data/lib/davinci_dtr_test_kit/{fixtures → full_ehr/fixtures}/respiratory_assist_device/pre_populated_questionnaire_response.json +0 -0
- /data/lib/davinci_dtr_test_kit/{fixtures → full_ehr/fixtures}/respiratory_assist_device/questionnaire_package.json +0 -0
- /data/lib/davinci_dtr_test_kit/{fixtures.rb → full_ehr/fixtures.rb} +0 -0
- /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 +0 -0
- /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
- /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
- /data/lib/davinci_dtr_test_kit/{client_groups/auth → full_ehr/v2.0.1}/dtr_client_payer_auth_smart_group.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{client_groups/auth → full_ehr/v2.0.1}/dtr_client_payer_auth_udap_group.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{docs → full_ehr/v2.0.1}/dtr_full_ehr_suite_description_v201.md +0 -0
- /data/lib/davinci_dtr_test_kit/{client_groups → full_ehr/v2.0.1}/must_support/questionnaire_must_support_elements.rb +0 -0
- /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
- /data/lib/davinci_dtr_test_kit/{create_test.rb → light_ehr/create_test.rb} +0 -0
- /data/lib/davinci_dtr_test_kit/{endpoints/mock_payer → light_ehr/endpoints}/light_ehr_supported_payer_endpoint.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{read_test.rb → light_ehr/read_test.rb} +0 -0
- /data/lib/davinci_dtr_test_kit/{update_test.rb → light_ehr/update_test.rb} +0 -0
- /data/lib/davinci_dtr_test_kit/{docs → light_ehr/v2.0.1}/dtr_light_ehr_suite_description_v201.md +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/communication_request/communication_request_must_support_test.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/communication_request/communication_request_validation.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/communication_request/metadata.yml +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/communication_request_group.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/coverage/coverage_must_support_test.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/coverage/coverage_validation.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/coverage/metadata.yml +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/coverage_group.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/device_request/device_request_must_support_test.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/device_request/device_request_validation.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/device_request/metadata.yml +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/device_request_group.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/encounter/encounter_must_support_test.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/encounter/encounter_validation.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/encounter/metadata.yml +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/encounter_group.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/medication_request/medication_request_must_support_test.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/medication_request/medication_request_validation.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/medication_request/metadata.yml +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/medication_request_group.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/nutrition_order/metadata.yml +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/nutrition_order/nutrition_order_must_support_test.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/nutrition_order/nutrition_order_validation.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/nutrition_order_group.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/questionnaire_response/metadata.yml +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/questionnaire_response/questionnaire_response_context_search.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/questionnaire_response/questionnaire_response_must_support_test.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/questionnaire_response/questionnaire_response_patient_search.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/questionnaire_response/questionnaire_response_read.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/questionnaire_response/questionnaire_response_validation.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/questionnaire_response_group.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/service_request/metadata.yml +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/service_request/service_request_must_support_test.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/service_request/service_request_validation.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/service_request_group.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/task/metadata.yml +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/task/task_must_support_test.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/task/task_validation.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/task_group.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/vision_prescription/metadata.yml +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/vision_prescription/vision_prescription_must_support_test.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/vision_prescription/vision_prescription_validation.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{profiles → light_ehr/v2.0.1/profiles}/vision_prescription_group.rb +0 -0
- /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
- /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
- /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
- /data/lib/davinci_dtr_test_kit/{endpoints/mock_authorization → server/endpoints}/simple_token_endpoint.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{payer_server_groups → server/v2.0.1/adaptive_forms}/payer_server_next_response_complete_test.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{docs → server/v2.0.1}/dtr_payer_server_suite_description_v201.md +0 -0
- /data/lib/davinci_dtr_test_kit/{validation_test.rb → server/validation_test.rb} +0 -0
- /data/lib/davinci_dtr_test_kit/{endpoints → smart_app/endpoints}/mock_authorization/authorize_endpoint.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{endpoints → smart_app/endpoints}/mock_authorization.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{endpoints → smart_app/endpoints}/mock_ehr/questionnaire_response_endpoint.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{endpoints → smart_app/endpoints}/mock_ehr.rb +0 -0
- /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
- /data/lib/davinci_dtr_test_kit/{auth_groups → smart_app/v2.0.1/auth}/token_validation_test.rb +0 -0
- /data/lib/davinci_dtr_test_kit/{docs → smart_app/v2.0.1}/dtr_smart_app_suite_description_v201.md +0 -0
- /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,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'questionnaire_design_support'
|
|
4
|
+
|
|
5
|
+
module DaVinciDTRTestKit
|
|
6
|
+
module DTRPayerServerV220
|
|
7
|
+
class QuestionnaireRelevanceLogicTest < Inferno::Test
|
|
8
|
+
include QuestionnaireDesignSupport
|
|
9
|
+
|
|
10
|
+
ENABLE_WHEN_EXPRESSION_URL =
|
|
11
|
+
'http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-enableWhenExpression'
|
|
12
|
+
|
|
13
|
+
id :dtr_v220_payer_questionnaire_relevance_logic
|
|
14
|
+
title 'Questionnaires include relevance logic'
|
|
15
|
+
description %(
|
|
16
|
+
Inferno verifies that, across all Questionnaires returned by the DTR server, at
|
|
17
|
+
least one demonstrates logic for including only relevant questions and answer
|
|
18
|
+
choices based on answers already provided, using `enableWhen` or
|
|
19
|
+
`enableWhenExpression`.
|
|
20
|
+
)
|
|
21
|
+
verifies_requirements 'hl7.fhir.us.davinci-dtr_2.2.0@spec-17'
|
|
22
|
+
|
|
23
|
+
run do
|
|
24
|
+
questionnaires = returned_questionnaires.map { |details| details[:questionnaire] }
|
|
25
|
+
skip_if questionnaires.blank?, 'No Questionnaire resources were returned'
|
|
26
|
+
|
|
27
|
+
assert questionnaires.any? { |questionnaire| questionnaire_has_relevance_logic?(questionnaire) },
|
|
28
|
+
'No Questionnaire included enableWhen or enableWhenExpression relevance logic.'
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def questionnaire_has_relevance_logic?(questionnaire)
|
|
34
|
+
questionnaire_items(questionnaire).any? do |item|
|
|
35
|
+
item.enableWhen.present? || item.extension.any? { |extension| extension.url == ENABLE_WHEN_EXPRESSION_URL }
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
# NOTE: this was copied from 2.0.1 'cql_test', and is in the process of being updated
|
|
2
|
+
module DaVinciDTRTestKit
|
|
3
|
+
module QuestionnaireOperationValidation
|
|
4
|
+
QUESTIONNAIRE_PACKAGE_BUNDLE_PROFILE = 'http://hl7.org/fhir/us/davinci-dtr/StructureDefinition/DTR-QPackageBundle|2.2.0'.freeze
|
|
5
|
+
QUESTIONNAIRE_PACKAGE_PARAMETER_PROFILE = 'http://hl7.org/fhir/us/davinci-dtr/StructureDefinition/dtr-qpackage-output-parameters|2.2.0'.freeze
|
|
6
|
+
|
|
7
|
+
def extension_presence
|
|
8
|
+
@extension_presence ||= { 'found_min_launch_context' => false, 'found_min_variable' => false,
|
|
9
|
+
'found_min_pop_context' => false, 'found_min_init_expression' => false,
|
|
10
|
+
'found_min_candidate_expression' => false, 'found_min_context_expression' => false,
|
|
11
|
+
'found_min_cqf_lib' => false }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# def cql_presence
|
|
15
|
+
# @cql_presence ||= { 'launch_context' => true, 'variable' => true,
|
|
16
|
+
# 'pop_context' => true, 'init_expression' => true,
|
|
17
|
+
# 'candidate_expression' => true, 'context_expression' => true }
|
|
18
|
+
# end
|
|
19
|
+
|
|
20
|
+
# def cqf_reference_libraries
|
|
21
|
+
# scratch[:cqf_reference_libraries] ||= Set.new
|
|
22
|
+
# end
|
|
23
|
+
|
|
24
|
+
def library_canonicals
|
|
25
|
+
@library_canonicals ||= Set.new
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def library_names
|
|
29
|
+
@library_names ||= Set.new
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def reset_library_tracking
|
|
33
|
+
@library_canonicals = Set.new
|
|
34
|
+
@library_names = Set.new
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# def found_questionnaire
|
|
38
|
+
# @found_questionnaire ||= false
|
|
39
|
+
# end
|
|
40
|
+
|
|
41
|
+
# def found_duplicate_library_name
|
|
42
|
+
# @found_duplicate_library_name ||= false
|
|
43
|
+
# end
|
|
44
|
+
|
|
45
|
+
# def found_non_cql_elm_library
|
|
46
|
+
# @found_non_cql_elm_library ||= false
|
|
47
|
+
# end
|
|
48
|
+
|
|
49
|
+
# def found_non_cql_expression
|
|
50
|
+
# @found_non_cql_expression ||= false
|
|
51
|
+
# end
|
|
52
|
+
|
|
53
|
+
# def verify_questionnaire_extensions(questionnaires)
|
|
54
|
+
# assert questionnaires&.any? && questionnaires.all?(FHIR::Questionnaire), 'No questionnaires found.'
|
|
55
|
+
# questionnaires.each_with_index { |q, q_index| check_questionnaire_extensions(q, q_index) }
|
|
56
|
+
# check_library_references
|
|
57
|
+
# assert extension_presence.value?(true), 'No extensions found. Questionnaire must demonstrate prepopulation.'
|
|
58
|
+
# assert cql_presence['variable'], 'Variable expression logic not written in CQL.'
|
|
59
|
+
# assert cql_presence['launch_context'], 'Launch context expression logic not written in CQL.'
|
|
60
|
+
# assert cql_presence['pop_context'], 'Population context expression logic not written in CQL.'
|
|
61
|
+
# end
|
|
62
|
+
|
|
63
|
+
# def check_questionnaire_extensions(questionnaire, q_index)
|
|
64
|
+
# # are extensions present in this questionnaire?
|
|
65
|
+
# found_launch_context = found_variable = found_pop_context = found_cqf_lib = false
|
|
66
|
+
# cqf_count = total_cqf_libs(questionnaire.extension)
|
|
67
|
+
# misformatted_expressions = []
|
|
68
|
+
# questionnaire.extension.each_with_index do |extension, index|
|
|
69
|
+
# if extension.url == 'http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-launchContext'
|
|
70
|
+
# found_launch_context = true
|
|
71
|
+
# extension_presence['found_min_launch_context'] = true
|
|
72
|
+
# check_for_cql(extension, 'launch_context', index, q_index, extension.url)
|
|
73
|
+
# misformatted_expressions << check_expression_format(extension, index)
|
|
74
|
+
# end
|
|
75
|
+
# if extension.url == 'http://hl7.org/fhir/StructureDefinition/variable'
|
|
76
|
+
# found_variable = true
|
|
77
|
+
# extension_presence['found_min_variable'] = true
|
|
78
|
+
# check_for_cql(extension, 'variable', index, q_index, extension.url)
|
|
79
|
+
# misformatted_expressions << check_expression_format(extension, index)
|
|
80
|
+
# end
|
|
81
|
+
# if extension.url == 'http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-itemPopulationContext'
|
|
82
|
+
# found_pop_context = true
|
|
83
|
+
# extension_presence['found_min_pop_context'] = true
|
|
84
|
+
# check_for_cql(extension, 'pop_context', index, q_index, extension.url)
|
|
85
|
+
# misformatted_expressions << check_expression_format(extension, index)
|
|
86
|
+
# end
|
|
87
|
+
# next unless extension.url == 'http://hl7.org/fhir/StructureDefinition/cqf-library'
|
|
88
|
+
|
|
89
|
+
# cqf_reference_libraries.add(extension.valueCanonical)
|
|
90
|
+
# found_cqf_lib = true
|
|
91
|
+
# extension_presence['found_min_cqf_lib'] = true
|
|
92
|
+
|
|
93
|
+
# check_for_cql(extension, '', index, q_index, extension.url)
|
|
94
|
+
# end
|
|
95
|
+
# add_launch_context_messages(found_launch_context, found_variable, found_pop_context, found_cqf_lib, q_index)
|
|
96
|
+
# return if cqf_count < 1
|
|
97
|
+
|
|
98
|
+
# add_formatting_messages(misformatted_expressions, q_index)
|
|
99
|
+
# assert misformatted_expressions.compact.empty?, 'Expression in questionnaire misformatted.'
|
|
100
|
+
# end
|
|
101
|
+
|
|
102
|
+
# def verify_questionnaire_items(questionnaires, final_cql_test: false)
|
|
103
|
+
# assert questionnaires&.any? && questionnaires.all?(FHIR::Questionnaire), 'No questionnaires found.'
|
|
104
|
+
# questionnaires.each_with_index { |q, q_index| check_questionnaire_items(q, q_index) }
|
|
105
|
+
|
|
106
|
+
# begin
|
|
107
|
+
# assert !found_non_cql_expression, 'Found non-cql expression.'
|
|
108
|
+
# assert extension_presence.value?(true), 'No extensions found. Questionnaire must demonstrate prepopulation.'
|
|
109
|
+
# assert cql_presence['init_expression'], 'Initial expression logic not written in CQL.'
|
|
110
|
+
# assert cql_presence['candidate_expression'], 'Candidate expression logic not written in CQL.'
|
|
111
|
+
# assert cql_presence['context_expression'], 'Context expression logic not written in CQL.'
|
|
112
|
+
# ensure
|
|
113
|
+
# reset_cql_tests if final_cql_test
|
|
114
|
+
# end
|
|
115
|
+
# end
|
|
116
|
+
|
|
117
|
+
# def add_launch_context_messages(found_launch_context, found_variable, found_pop_context, found_cqf_lib, q_index)
|
|
118
|
+
# unless found_launch_context
|
|
119
|
+
# messages << { type: 'info',
|
|
120
|
+
# message: format_markdown("[questionnaire #{q_index + 1}] included no launch context.") }
|
|
121
|
+
# end
|
|
122
|
+
# unless found_variable
|
|
123
|
+
# messages << { type: 'info',
|
|
124
|
+
# message: format_markdown("[questionnaire #{q_index + 1}]
|
|
125
|
+
# included no variable to query for additional data.") }
|
|
126
|
+
# end
|
|
127
|
+
# unless found_pop_context
|
|
128
|
+
# messages << { type: 'info',
|
|
129
|
+
# message: format_markdown("[questionnaire #{q_index + 1}]
|
|
130
|
+
# included no item population context.") }
|
|
131
|
+
# end
|
|
132
|
+
# return if found_cqf_lib
|
|
133
|
+
|
|
134
|
+
# messages << { type: 'info',
|
|
135
|
+
# message: format_markdown("[questionnaire #{q_index + 1}]
|
|
136
|
+
# included no cqf library.") }
|
|
137
|
+
# end
|
|
138
|
+
|
|
139
|
+
# def add_formatting_messages(misformatted_expressions, q_index)
|
|
140
|
+
# misformatted_expressions.compact.each do |idx|
|
|
141
|
+
# messages << { type: 'info',
|
|
142
|
+
# message: format_markdown("[expression #{idx + 1}] in [questionnaire #{q_index + 1}]
|
|
143
|
+
# does not begin with a reference to an included library name.") }
|
|
144
|
+
# end
|
|
145
|
+
# end
|
|
146
|
+
|
|
147
|
+
# def total_cqf_libs(extensions)
|
|
148
|
+
# cqf_count = 0
|
|
149
|
+
# extensions.each do |extension|
|
|
150
|
+
# next unless extension.url == 'http://hl7.org/fhir/StructureDefinition/cqf-library'
|
|
151
|
+
|
|
152
|
+
# cqf_count += 1
|
|
153
|
+
# end
|
|
154
|
+
# cqf_count
|
|
155
|
+
# end
|
|
156
|
+
|
|
157
|
+
# def add_item_messages(found_item_expressions, q_index)
|
|
158
|
+
# unless found_item_expressions['found_candidate_expression']
|
|
159
|
+
# messages << { type: 'info',
|
|
160
|
+
# message: format_markdown("[questionnaire #{q_index + 1}] included no candidate expression.") }
|
|
161
|
+
# end
|
|
162
|
+
# unless found_item_expressions['found_init_expression']
|
|
163
|
+
# messages << { type: 'info',
|
|
164
|
+
# message: format_markdown("[questionnaire #{q_index + 1}] included no initial expression.") }
|
|
165
|
+
# end
|
|
166
|
+
# return if found_item_expressions['found_context_expression']
|
|
167
|
+
|
|
168
|
+
# messages << { type: 'info',
|
|
169
|
+
# message: format_markdown("[questionnaire #{q_index + 1}] included no context expression.") }
|
|
170
|
+
# end
|
|
171
|
+
|
|
172
|
+
# def check_questionnaire_items(questionnaire, q_index)
|
|
173
|
+
# # are expressions present in this questionnaire?
|
|
174
|
+
# found_item_expressions = { 'found_init_expression' => false,
|
|
175
|
+
# 'found_candidate_expression' => false,
|
|
176
|
+
# 'found_context_expression' => false }
|
|
177
|
+
# cqf_count = total_cqf_libs(questionnaire.extension)
|
|
178
|
+
# misformatted_expressions = []
|
|
179
|
+
|
|
180
|
+
# # check questionnaire items
|
|
181
|
+
# questionnaire.item.each_with_index do |item, index|
|
|
182
|
+
# misformatted_expressions.concat(check_nested_items(item, index, q_index, found_item_expressions, item.linkId))
|
|
183
|
+
# # check extensions on items
|
|
184
|
+
# item.extension.each do |item_ext|
|
|
185
|
+
# misformatted_expressions << check_item_extension(item_ext,
|
|
186
|
+
# index, q_index, found_item_expressions, item.linkId)
|
|
187
|
+
# end
|
|
188
|
+
# end
|
|
189
|
+
# add_item_messages(found_item_expressions, q_index)
|
|
190
|
+
# # only care about formatting when there are multiple cqf libs
|
|
191
|
+
# return if cqf_count < 1
|
|
192
|
+
|
|
193
|
+
# misformatted_expressions.compact.to_set.each do |idx|
|
|
194
|
+
# messages << { type: 'info',
|
|
195
|
+
# message: format_markdown("[item #{idx + 1}] in [questionnaire #{q_index + 1}]
|
|
196
|
+
# contains expression that does not begin with a reference to an included library name.") }
|
|
197
|
+
# end
|
|
198
|
+
# assert misformatted_expressions.compact.to_set.empty?, 'Expression in questionnaire misformatted.'
|
|
199
|
+
# end
|
|
200
|
+
|
|
201
|
+
def check_libraries(parameters, request_index)
|
|
202
|
+
questionnaire_bundles = extract_questionnaire_bundles(parameters)
|
|
203
|
+
|
|
204
|
+
questionnaire_bundles.each do |bundle|
|
|
205
|
+
reset_library_tracking
|
|
206
|
+
|
|
207
|
+
libraries = extract_libraries_from_bundles([bundle])
|
|
208
|
+
|
|
209
|
+
questionnaires = extract_questionnaires_from_bundles([bundle])
|
|
210
|
+
|
|
211
|
+
referenced_libraries =
|
|
212
|
+
Set.new(
|
|
213
|
+
questionnaires
|
|
214
|
+
.flat_map { |questionnaire| referenced_library_canonicals(questionnaire) }
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
libraries.each do |library|
|
|
218
|
+
library_canonicals.add(library_canonical(library)) unless library.url.nil?
|
|
219
|
+
|
|
220
|
+
referenced_libraries.merge(depends_on_library_canonicals(library))
|
|
221
|
+
|
|
222
|
+
evaluate_library(library, request_index)
|
|
223
|
+
|
|
224
|
+
next if library_names.add?(library.name)
|
|
225
|
+
|
|
226
|
+
add_message(
|
|
227
|
+
'error',
|
|
228
|
+
"Request #{request_index}: Bundle contains multiple libraries named '#{library.name}'"
|
|
229
|
+
)
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
check_referenced_libraries(referenced_libraries, library_canonicals, request_index)
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
def library_canonical(library)
|
|
237
|
+
library_version_string = library.version.present? ? "|#{library.version}" : ''
|
|
238
|
+
|
|
239
|
+
"#{library.url}#{library_version_string}"
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
def evaluate_library(library, request_index)
|
|
243
|
+
unless library_contains_cql?(library)
|
|
244
|
+
add_message(
|
|
245
|
+
'error',
|
|
246
|
+
"Request #{request_index}: Library `#{library.url}` does not include CQL."
|
|
247
|
+
)
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
unless library_contains_elm?(library) # rubocop:disable Style/GuardClause
|
|
251
|
+
add_message(
|
|
252
|
+
'error',
|
|
253
|
+
"Request #{request_index}: Library `#{library.url}` does not include ELM."
|
|
254
|
+
)
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
def library_contains_cql?(library)
|
|
259
|
+
library
|
|
260
|
+
.content
|
|
261
|
+
.any? { |content| content.data.present? && content.contentType == 'text/cql' }
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
def library_contains_elm?(library)
|
|
265
|
+
library
|
|
266
|
+
.content
|
|
267
|
+
.any? { |content| content.data.present? && content.contentType == 'application/elm+json' }
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
def referenced_library_canonicals(questionnaire)
|
|
271
|
+
questionnaire
|
|
272
|
+
.extension
|
|
273
|
+
.select { |extension| extension.url == 'http://hl7.org/fhir/StructureDefinition/cqf-library' }
|
|
274
|
+
.map(&:valueCanonical)
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
def depends_on_library_canonicals(library)
|
|
278
|
+
library.relatedArtifact.filter_map do |related_artifact|
|
|
279
|
+
related_artifact.resource if related_artifact.type == 'depends-on'
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
def check_referenced_libraries(referenced_libraries, found_libraries, request_index)
|
|
284
|
+
unversioned_library_references = referenced_libraries.select { |library| library.exclude? '|' }
|
|
285
|
+
|
|
286
|
+
if unversioned_library_references.present?
|
|
287
|
+
unversioned_library_string =
|
|
288
|
+
unversioned_library_references
|
|
289
|
+
.map { |reference| "`#{reference}`" }
|
|
290
|
+
.join(', ')
|
|
291
|
+
|
|
292
|
+
add_message(
|
|
293
|
+
'error',
|
|
294
|
+
"The Bundle included the following unversioned library references: #{unversioned_library_string}"
|
|
295
|
+
)
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
referenced_libraries.reject! { |library| library.exclude? '|' }
|
|
299
|
+
|
|
300
|
+
missing_libraries = referenced_libraries - found_libraries
|
|
301
|
+
|
|
302
|
+
return if missing_libraries.blank?
|
|
303
|
+
|
|
304
|
+
missing_library_string = missing_libraries.map { |url| "`#{url}`" }.join(', ')
|
|
305
|
+
|
|
306
|
+
add_message(
|
|
307
|
+
'error',
|
|
308
|
+
"Request #{request_index}: The following libraries are referenced but not included in the Bundle: " \
|
|
309
|
+
"#{missing_library_string}"
|
|
310
|
+
)
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
# def check_item_extension(item_ext, index, q_index, found_item_expressions, link_id)
|
|
314
|
+
# if item_ext.url == 'http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-candidateExpression'
|
|
315
|
+
# found_item_expressions['found_candidate_expression'] = true
|
|
316
|
+
# extension_presence['found_min_candidate_expression'] = true
|
|
317
|
+
# check_for_cql(item_ext, 'candidate_expression', index, q_index, item_ext.url, link_id)
|
|
318
|
+
# return check_expression_format(item_ext, index)
|
|
319
|
+
# end
|
|
320
|
+
# if item_ext.url == 'http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-initialExpression'
|
|
321
|
+
# found_item_expressions['found_init_expression'] = true
|
|
322
|
+
# extension_presence['found_min_init_expression'] = true
|
|
323
|
+
# check_for_cql(item_ext, 'init_expression', index, q_index, item_ext.url, link_id)
|
|
324
|
+
# return check_expression_format(item_ext, index)
|
|
325
|
+
# end
|
|
326
|
+
# if item_ext.url == 'http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-contextExpression'
|
|
327
|
+
# found_item_expressions['found_context_expression'] = true
|
|
328
|
+
# extension_presence['found_min_context_expression'] = true
|
|
329
|
+
# check_for_cql(item_ext, 'context_expression', index, q_index, item_ext.url, link_id)
|
|
330
|
+
# return check_expression_format(item_ext, index)
|
|
331
|
+
# end
|
|
332
|
+
# check_for_cql(item_ext, '', index, q_index, item_ext.url, link_id)
|
|
333
|
+
# end
|
|
334
|
+
|
|
335
|
+
# def check_nested_items(item, index, q_index, found_item_expressions, link_id)
|
|
336
|
+
# misformatted_nested_expressions = []
|
|
337
|
+
# item.item.each do |nested_item|
|
|
338
|
+
# check_nested_items(nested_item, index, q_index, found_item_expressions, nested_item.linkId)
|
|
339
|
+
# nested_item.extension.each do |item_ext|
|
|
340
|
+
# misformatted_nested_expressions << check_item_extension(item_ext, index, q_index, found_item_expressions,
|
|
341
|
+
# link_id)
|
|
342
|
+
# end
|
|
343
|
+
# end
|
|
344
|
+
# misformatted_nested_expressions.compact
|
|
345
|
+
# end
|
|
346
|
+
|
|
347
|
+
# def check_expression_format(item_ext, index)
|
|
348
|
+
# return unless library_names.none?
|
|
349
|
+
|
|
350
|
+
# expression_passes = false
|
|
351
|
+
# library_names.each do |name|
|
|
352
|
+
# if item_ext.valueExpression.expression.start_with? "\"#{name}\""
|
|
353
|
+
# expression_passes = true
|
|
354
|
+
# break
|
|
355
|
+
# end
|
|
356
|
+
# end
|
|
357
|
+
# index unless expression_passes
|
|
358
|
+
# end
|
|
359
|
+
|
|
360
|
+
# def check_for_cql(extension, extension_name, index, q_index, url, link_id = '')
|
|
361
|
+
# return if extension.valueExpression.nil?
|
|
362
|
+
# return if extension.valueExpression.language == 'text/cql'
|
|
363
|
+
|
|
364
|
+
# cql_presence[extension_name] = false unless extension_name.blank?
|
|
365
|
+
# messages << if link_id.blank?
|
|
366
|
+
# { type: 'info',
|
|
367
|
+
# message: format_markdown("[extension #{index + 1}] in [questionnaire #{q_index + 1}]
|
|
368
|
+
# contains expression that does not have content type of cql
|
|
369
|
+
# (URL: #{url}).") }
|
|
370
|
+
# else
|
|
371
|
+
# { type: 'info',
|
|
372
|
+
# message: format_markdown("[item #{index + 1}] in [questionnaire #{q_index + 1}]
|
|
373
|
+
# contains expression that does not have content type of cql
|
|
374
|
+
# (linkId: #{link_id}, URL: #{url}).") }
|
|
375
|
+
# end
|
|
376
|
+
# end
|
|
377
|
+
|
|
378
|
+
# def extract_contained_questionnaires(questionnaire_responses)
|
|
379
|
+
# questionnaire_responses&.filter_map do |qr|
|
|
380
|
+
# qr.contained&.grep(FHIR::Questionnaire)
|
|
381
|
+
# end&.flatten&.compact
|
|
382
|
+
# end
|
|
383
|
+
|
|
384
|
+
def extract_questionnaires_from_bundles(questionnaire_bundles)
|
|
385
|
+
questionnaire_bundles.filter_map do |qb|
|
|
386
|
+
qb.entry.filter_map { |entry| entry.resource if entry.resource.is_a?(FHIR::Questionnaire) }
|
|
387
|
+
end&.flatten&.compact
|
|
388
|
+
end
|
|
389
|
+
|
|
390
|
+
def perform_questionnaire_package_response_validation(resource, index)
|
|
391
|
+
bundles = extract_questionnaire_bundles(resource)
|
|
392
|
+
|
|
393
|
+
resource_is_valid?(
|
|
394
|
+
resource:,
|
|
395
|
+
profile_url: QUESTIONNAIRE_PACKAGE_PARAMETER_PROFILE,
|
|
396
|
+
message_prefix: "Request #{index}: "
|
|
397
|
+
)
|
|
398
|
+
|
|
399
|
+
return if bundles.present?
|
|
400
|
+
|
|
401
|
+
add_message(
|
|
402
|
+
'error',
|
|
403
|
+
"No Questionnaire Bundle found in response #{index}"
|
|
404
|
+
)
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
def extract_questionnaire_bundles(resource)
|
|
408
|
+
case resource&.resourceType
|
|
409
|
+
when 'Bundle'
|
|
410
|
+
[resource]
|
|
411
|
+
when 'Parameters'
|
|
412
|
+
extract_bundles_from_parameter(resource)
|
|
413
|
+
else
|
|
414
|
+
[]
|
|
415
|
+
end
|
|
416
|
+
end
|
|
417
|
+
|
|
418
|
+
def extract_bundles_from_parameter(parameter)
|
|
419
|
+
return [] if parameter.blank?
|
|
420
|
+
|
|
421
|
+
parameter.parameter&.filter_map do |param|
|
|
422
|
+
param.resource if param.resource&.resourceType == 'Bundle'
|
|
423
|
+
end
|
|
424
|
+
end
|
|
425
|
+
|
|
426
|
+
# def extract_questionnaire_from_questionnaire_package(questionnaire_pkg_json, questionnaire_url)
|
|
427
|
+
# resource = FHIR.from_contents(questionnaire_pkg_json)
|
|
428
|
+
# questionnaire_bundles = extract_questionnaire_bundles(resource)
|
|
429
|
+
# questionnaires = extract_questionnaires_from_bundles(questionnaire_bundles)
|
|
430
|
+
|
|
431
|
+
# questionnaires.find { |q| q.url == questionnaire_url }
|
|
432
|
+
# end
|
|
433
|
+
|
|
434
|
+
def extract_libraries_from_bundles(questionnaire_bundles)
|
|
435
|
+
questionnaire_bundles.filter_map do |qb|
|
|
436
|
+
qb.entry.filter_map { |entry| entry.resource if entry&.resource.is_a?(FHIR::Library) }
|
|
437
|
+
end&.flatten&.compact
|
|
438
|
+
end
|
|
439
|
+
end
|
|
440
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
require_relative '../validation_test'
|
|
2
|
+
require_relative '../../tags'
|
|
3
|
+
|
|
4
|
+
module DaVinciDTRTestKit
|
|
5
|
+
module DTRPayerServerV220
|
|
6
|
+
class QuestionnairePackageRequestValidationTest < Inferno::Test
|
|
7
|
+
include DaVinciDTRTestKit::ValidationTest
|
|
8
|
+
|
|
9
|
+
id :dtr_v220_payer_questionnaire_package_request_validation
|
|
10
|
+
title '$questionnaire-package request is valid'
|
|
11
|
+
description %(
|
|
12
|
+
This test validates that each outgoing $questionnaire-package request body
|
|
13
|
+
conforms to the [DTR Questionnaire Package Input Parameters profile](https://hl7.org/fhir/us/davinci-dtr/2.2.0/en/StructureDefinition-dtr-qpackage-input-parameters.html).
|
|
14
|
+
Inferno generates these request bodies from the provided test input.
|
|
15
|
+
)
|
|
16
|
+
simulation_verification
|
|
17
|
+
|
|
18
|
+
run do
|
|
19
|
+
load_tagged_requests(QUESTIONNAIRE_TAG)
|
|
20
|
+
|
|
21
|
+
omit_if requests.empty?, 'No $questionnaire-package requests were made.'
|
|
22
|
+
|
|
23
|
+
requests.each_with_index do |request, index|
|
|
24
|
+
fhir_obj = begin
|
|
25
|
+
FHIR.from_contents(request.request_body)
|
|
26
|
+
rescue StandardError
|
|
27
|
+
nil
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
validate_resource(
|
|
31
|
+
fhir_obj,
|
|
32
|
+
:parameters,
|
|
33
|
+
'http://hl7.org/fhir/us/davinci-dtr/StructureDefinition/dtr-qpackage-input-parameters|2.2.0',
|
|
34
|
+
index
|
|
35
|
+
)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
assert_no_error_messages('Non-conformant $questionnaire-package request. See Messages for details.')
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../questionnaire_operation_validation'
|
|
4
|
+
require_relative '../../../cross_suite/v2.2.0/multi_request_message_helper'
|
|
5
|
+
require_relative '../../../tags'
|
|
6
|
+
|
|
7
|
+
module DaVinciDTRTestKit
|
|
8
|
+
module DTRPayerServerV220
|
|
9
|
+
class AdaptiveQuestionnaireResponseContainedQuestionnaireTest < Inferno::Test
|
|
10
|
+
include QuestionnaireOperationValidation
|
|
11
|
+
include MultiRequestMessageHelper
|
|
12
|
+
|
|
13
|
+
ADAPTIVE_QUESTIONNAIRE_EXTENSION_URL =
|
|
14
|
+
'http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-questionnaireAdaptive'
|
|
15
|
+
|
|
16
|
+
id :dtr_v220_payer_adaptive_questionnaire_response_contained_questionnaire
|
|
17
|
+
title 'Adaptive QuestionnaireResponses reference a contained Questionnaire'
|
|
18
|
+
description %(
|
|
19
|
+
This test verifies that each QuestionnaireResponse accompanying an adaptive
|
|
20
|
+
Questionnaire in a `$questionnaire-package` response references a contained
|
|
21
|
+
Questionnaire. The contained Questionnaire must be derived from the canonical
|
|
22
|
+
URL of the adaptive Questionnaire being completed.
|
|
23
|
+
)
|
|
24
|
+
verifies_requirements 'hl7.fhir.us.davinci-dtr_2.2.0@spec-25'
|
|
25
|
+
|
|
26
|
+
run do
|
|
27
|
+
load_tagged_requests(QUESTIONNAIRE_TAG)
|
|
28
|
+
adaptive_package_found = false
|
|
29
|
+
|
|
30
|
+
requests.each_with_index do |request, request_index|
|
|
31
|
+
resource = parse_fhir_request_entity(request.response_body, 'Response', request_index)
|
|
32
|
+
next unless resource.present?
|
|
33
|
+
|
|
34
|
+
extract_questionnaire_bundles(resource).each do |bundle|
|
|
35
|
+
adaptive_questionnaire = bundle.entry.filter_map(&:resource).find do |entry_resource|
|
|
36
|
+
adaptive_questionnaire?(entry_resource)
|
|
37
|
+
end
|
|
38
|
+
next unless adaptive_questionnaire.present?
|
|
39
|
+
|
|
40
|
+
adaptive_package_found = true
|
|
41
|
+
validate_questionnaire_response(bundle, adaptive_questionnaire, request_index)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
omit_if !adaptive_package_found, 'No adaptive Questionnaire packages were returned.'
|
|
46
|
+
|
|
47
|
+
assert_no_error_messages(
|
|
48
|
+
"#{requests_with_errors_prefix}Adaptive QuestionnaireResponses must reference a contained Questionnaire " \
|
|
49
|
+
'derived from the adaptive Questionnaire canonical. See Messages for details.'
|
|
50
|
+
)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
private
|
|
54
|
+
|
|
55
|
+
def adaptive_questionnaire?(resource)
|
|
56
|
+
resource.is_a?(FHIR::Questionnaire) &&
|
|
57
|
+
resource.extension.any? do |extension|
|
|
58
|
+
extension.url == ADAPTIVE_QUESTIONNAIRE_EXTENSION_URL &&
|
|
59
|
+
(extension.valueBoolean || extension.valueUrl.present?)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def validate_questionnaire_response(bundle, adaptive_questionnaire, request_index)
|
|
64
|
+
questionnaire_response = bundle.entry.filter_map(&:resource).find do |entry_resource|
|
|
65
|
+
entry_resource.is_a?(FHIR::QuestionnaireResponse)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
unless questionnaire_response.present?
|
|
69
|
+
add_request_message(
|
|
70
|
+
'error',
|
|
71
|
+
'Adaptive Questionnaire package contains no QuestionnaireResponse.',
|
|
72
|
+
request_index
|
|
73
|
+
)
|
|
74
|
+
return
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
contained_questionnaire = referenced_contained_questionnaire(questionnaire_response, request_index)
|
|
78
|
+
return unless contained_questionnaire.present?
|
|
79
|
+
|
|
80
|
+
validate_derived_from(contained_questionnaire, adaptive_questionnaire, questionnaire_response, request_index)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def referenced_contained_questionnaire(questionnaire_response, request_index)
|
|
84
|
+
reference = questionnaire_response.questionnaire
|
|
85
|
+
unless reference&.start_with?('#')
|
|
86
|
+
add_request_message(
|
|
87
|
+
'error',
|
|
88
|
+
'QuestionnaireResponse.questionnaire does not reference a contained Questionnaire.',
|
|
89
|
+
request_index
|
|
90
|
+
)
|
|
91
|
+
return
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
contained_questionnaire = questionnaire_response.contained.find do |contained_resource|
|
|
95
|
+
contained_resource.is_a?(FHIR::Questionnaire) && contained_resource.id == reference.delete_prefix('#')
|
|
96
|
+
end
|
|
97
|
+
unless contained_questionnaire.present?
|
|
98
|
+
add_request_message(
|
|
99
|
+
'error',
|
|
100
|
+
"QuestionnaireResponse.questionnaire references `#{reference}`, " \
|
|
101
|
+
'but no contained Questionnaire has that id.',
|
|
102
|
+
request_index
|
|
103
|
+
)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
contained_questionnaire
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def validate_derived_from(contained_questionnaire, adaptive_questionnaire, questionnaire_response, request_index)
|
|
110
|
+
canonical = questionnaire_canonical(adaptive_questionnaire)
|
|
111
|
+
return if canonical.present? && contained_questionnaire.derivedFrom.include?(canonical)
|
|
112
|
+
|
|
113
|
+
add_request_message(
|
|
114
|
+
'error',
|
|
115
|
+
"Contained Questionnaire `#{questionnaire_response.questionnaire}` is not derived from `#{canonical}`.",
|
|
116
|
+
request_index
|
|
117
|
+
)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def questionnaire_canonical(questionnaire)
|
|
121
|
+
return unless questionnaire.url.present?
|
|
122
|
+
|
|
123
|
+
"#{questionnaire.url}#{"|#{questionnaire.version}" if questionnaire.version.present?}"
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|