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,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../questionnaire_response_reference_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 NextQuestionContainedResponseReferencesTest < Inferno::Test
|
|
10
|
+
include QuestionnaireResponseReferenceValidation
|
|
11
|
+
include MultiRequestMessageHelper
|
|
12
|
+
|
|
13
|
+
id :dtr_v220_payer_next_question_contained_response_references
|
|
14
|
+
title 'Contained $next-question QuestionnaireResponse references occur only in answer values'
|
|
15
|
+
description %(
|
|
16
|
+
This test verifies that a QuestionnaireResponse returned by `$next-question` uses
|
|
17
|
+
contained resource references only as
|
|
18
|
+
`QuestionnaireResponse.item.answer.valueReference` values.
|
|
19
|
+
)
|
|
20
|
+
verifies_requirements 'hl7.fhir.us.davinci-dtr_2.2.0@spec-140',
|
|
21
|
+
'hl7.fhir.us.davinci-dtr_2.2.0@spec-141'
|
|
22
|
+
|
|
23
|
+
run do
|
|
24
|
+
load_tagged_requests(NEXT_TAG)
|
|
25
|
+
|
|
26
|
+
omit_if requests.blank?, 'No $next-question requests were made.'
|
|
27
|
+
|
|
28
|
+
responses_by_request = requests.map { |request| questionnaire_responses_from_request(request) }
|
|
29
|
+
|
|
30
|
+
skip_if responses_by_request.all?(&:empty?), 'No QuestionnaireResponse resources were returned.'
|
|
31
|
+
|
|
32
|
+
responses_by_request.each_with_index do |questionnaire_responses, request_index|
|
|
33
|
+
questionnaire_responses.each do |questionnaire_response|
|
|
34
|
+
invalid_contained_reference_locations(questionnaire_response).each do |reference|
|
|
35
|
+
add_request_message('error', reference, request_index)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
message = "#{requests_with_errors_prefix}" \
|
|
41
|
+
'Contained resource references are permitted only in item.answer valueReference '
|
|
42
|
+
assert_no_error_messages("#{message}elements. See Messages for details.")
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../questionnaire_response_reference_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 NextQuestionResponseReferencesTest < Inferno::Test
|
|
10
|
+
include QuestionnaireResponseReferenceValidation
|
|
11
|
+
include MultiRequestMessageHelper
|
|
12
|
+
|
|
13
|
+
id :dtr_v220_payer_next_question_response_references
|
|
14
|
+
title '$next-question QuestionnaireResponse references only target contained or client FHIR resources'
|
|
15
|
+
description %(
|
|
16
|
+
This test verifies that every reference in each QuestionnaireResponse returned by
|
|
17
|
+
`$next-question` points to either a resource contained in that QuestionnaireResponse
|
|
18
|
+
or a resource on the DTR client's FHIR endpoint. Relative references are interpreted
|
|
19
|
+
relative to the DTR client's FHIR endpoint. To validate absolute references, provide
|
|
20
|
+
the DTR Client FHIR Endpoint input.
|
|
21
|
+
)
|
|
22
|
+
verifies_requirements 'hl7.fhir.us.davinci-dtr_2.2.0@spec-139'
|
|
23
|
+
|
|
24
|
+
input :client_fhir_endpoint, optional: true
|
|
25
|
+
|
|
26
|
+
run do
|
|
27
|
+
load_tagged_requests(NEXT_TAG)
|
|
28
|
+
|
|
29
|
+
omit_if requests.blank?, 'No $next-question requests were made.'
|
|
30
|
+
|
|
31
|
+
responses_by_request = requests.map { |request| questionnaire_responses_from_request(request) }
|
|
32
|
+
|
|
33
|
+
skip_if responses_by_request.all?(&:empty?), 'No QuestionnaireResponse resources were returned.'
|
|
34
|
+
|
|
35
|
+
absolute_references_returned = responses_by_request.flatten.any? do |response|
|
|
36
|
+
questionnaire_response_has_absolute_reference?(response)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
responses_by_request.each_with_index do |questionnaire_responses, request_index|
|
|
40
|
+
questionnaire_responses.each do |questionnaire_response|
|
|
41
|
+
invalid_questionnaire_response_references(questionnaire_response, client_fhir_endpoint).each do |reference|
|
|
42
|
+
add_request_message('error', reference, request_index)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
message = "#{requests_with_errors_prefix}" \
|
|
48
|
+
"References must target contained resources or the DTR client's FHIR endpoint. "
|
|
49
|
+
assert_no_error_messages("#{message}See Messages for details.")
|
|
50
|
+
|
|
51
|
+
skip_if client_fhir_endpoint.blank? && absolute_references_returned,
|
|
52
|
+
'Absolute QuestionnaireResponse references were returned, but no DTR Client FHIR Endpoint was provided.'
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../../../tags'
|
|
4
|
+
|
|
5
|
+
module DaVinciDTRTestKit
|
|
6
|
+
module DTRPayerServerV220
|
|
7
|
+
class NextQuestionResponseValidationTest < Inferno::Test
|
|
8
|
+
NEXT_QUESTION_OUTPUT_PARAMETERS_PROFILE =
|
|
9
|
+
'http://hl7.org/fhir/us/davinci-dtr/StructureDefinition/dtr-next-question-output-parameters|2.2.0'
|
|
10
|
+
ADAPTIVE_QUESTIONNAIRE_RESPONSE_PROFILE =
|
|
11
|
+
'http://hl7.org/fhir/us/davinci-dtr/StructureDefinition/dtr-questionnaireresponse-adapt|2.2.0'
|
|
12
|
+
|
|
13
|
+
id :dtr_v220_payer_next_question_response_validation
|
|
14
|
+
title 'Verify that the $next-question response conforms to the DTR Next Question Output Parameters profile'
|
|
15
|
+
description %(
|
|
16
|
+
Inferno verifies that each payer server response to the `$next-question`
|
|
17
|
+
operation conforms to the [DTR Next Question Output Parameters profile](https://hl7.org/fhir/us/davinci-dtr/2.2.0/en/StructureDefinition-dtr-next-question-output-parameters.html)
|
|
18
|
+
when it is a Parameters resource, or to the [DTR Questionnaire Response
|
|
19
|
+
for adaptive form profile](https://hl7.org/fhir/us/davinci-dtr/2.2.0/en/StructureDefinition-dtr-questionnaireresponse-adapt.html)
|
|
20
|
+
when it is a plain QuestionnaireResponse resource.
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
run do
|
|
24
|
+
load_tagged_requests(NEXT_TAG)
|
|
25
|
+
|
|
26
|
+
omit_if requests.blank?, 'No $next-question requests were made.'
|
|
27
|
+
|
|
28
|
+
requests.each_with_index do |request, index|
|
|
29
|
+
add_message('error', "Request #{index + 1} was unsuccessful.") unless [200, 201].include? request.status
|
|
30
|
+
|
|
31
|
+
JSON.parse(request.response_body)
|
|
32
|
+
resource = FHIR.from_contents(request.response_body)
|
|
33
|
+
|
|
34
|
+
if resource.nil?
|
|
35
|
+
add_message('error', "Response #{index + 1} did not contain FHIR resources.")
|
|
36
|
+
next
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
perform_next_question_response_validation(resource, index)
|
|
40
|
+
rescue JSON::ParserError
|
|
41
|
+
add_message('error', "Response #{index + 1} contained invalid JSON.")
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
assert_no_error_messages('Not all responses were valid. See messages for details.')
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def perform_next_question_response_validation(resource, index)
|
|
48
|
+
case resource
|
|
49
|
+
when FHIR::Parameters
|
|
50
|
+
resource_is_valid?(
|
|
51
|
+
resource:,
|
|
52
|
+
profile_url: NEXT_QUESTION_OUTPUT_PARAMETERS_PROFILE,
|
|
53
|
+
message_prefix: "Response #{index + 1}: "
|
|
54
|
+
)
|
|
55
|
+
when FHIR::QuestionnaireResponse
|
|
56
|
+
resource_is_valid?(
|
|
57
|
+
resource:,
|
|
58
|
+
profile_url: ADAPTIVE_QUESTIONNAIRE_RESPONSE_PROFILE,
|
|
59
|
+
message_prefix: "Response #{index + 1}: "
|
|
60
|
+
)
|
|
61
|
+
else
|
|
62
|
+
add_message('error', "Response #{index + 1} was not a Parameters or QuestionnaireResponse resource.")
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require_relative '../../../tags'
|
|
2
|
+
require_relative '../questionnaire_response_reference_validation'
|
|
3
|
+
require_relative 'contained_binary_validation'
|
|
4
|
+
require_relative '../../../cross_suite/v2.2.0/multi_request_message_helper'
|
|
5
|
+
|
|
6
|
+
module DaVinciDTRTestKit
|
|
7
|
+
module DTRPayerServerV220
|
|
8
|
+
class ContainedBinaryTest < Inferno::Test
|
|
9
|
+
include ContainedBinaryValidation
|
|
10
|
+
include MultiRequestMessageHelper
|
|
11
|
+
include QuestionnaireResponseReferenceValidation
|
|
12
|
+
|
|
13
|
+
id :dtr_v220_payer_contained_binary
|
|
14
|
+
title 'Contained Binary resources are PDFs or safe XHTML'
|
|
15
|
+
description %(
|
|
16
|
+
This test verifies that Binary resources contained in QuestionnaireResponses
|
|
17
|
+
returned from the `$questionnaire-package` or `$next-question` operations are
|
|
18
|
+
either PDFs or XHTML fragments that follow the FHIR R4 Narrative safety rules.
|
|
19
|
+
XHTML must be a non-empty `<div>` fragment in the XHTML namespace and must not
|
|
20
|
+
contain active content, scripts, external stylesheets, deprecated elements, or
|
|
21
|
+
event-related attributes.
|
|
22
|
+
)
|
|
23
|
+
verifies_requirements 'hl7.fhir.us.davinci-dtr_2.2.0@spec-160'
|
|
24
|
+
|
|
25
|
+
run do
|
|
26
|
+
load_tagged_requests(QUESTIONNAIRE_TAG)
|
|
27
|
+
load_tagged_requests(NEXT_TAG)
|
|
28
|
+
omit_if requests.blank?,
|
|
29
|
+
'No $questionnaire-package or $next-question requests were made'
|
|
30
|
+
|
|
31
|
+
binary_found = false
|
|
32
|
+
requests.each_with_index do |request, request_index|
|
|
33
|
+
questionnaire_responses_from_request(request).each do |questionnaire_response|
|
|
34
|
+
contained_binaries([questionnaire_response]).each do |binary|
|
|
35
|
+
binary_found = true
|
|
36
|
+
next if contained_binary_is_safe?(binary)
|
|
37
|
+
|
|
38
|
+
add_request_message(
|
|
39
|
+
'error',
|
|
40
|
+
"#{binary_description(binary)} is not a PDF or safe XHTML fragment.",
|
|
41
|
+
request_index
|
|
42
|
+
)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
omit_if !binary_found, 'No Binary resources were contained in QuestionnaireResponses'
|
|
48
|
+
message = "#{requests_with_errors_prefix}" \
|
|
49
|
+
'Contained Binary resources must be PDFs or safe XHTML fragments. See Messages for details.'
|
|
50
|
+
assert_no_error_messages(message)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def binary_description(binary)
|
|
54
|
+
binary.id.present? ? "Binary `#{binary.id}`" : 'contained Binary without an id'
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_design/contained_binary_validation.rb
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
require 'base64'
|
|
2
|
+
require 'nokogiri'
|
|
3
|
+
|
|
4
|
+
module DaVinciDTRTestKit
|
|
5
|
+
module DTRPayerServerV220
|
|
6
|
+
module ContainedBinaryValidation
|
|
7
|
+
PDF_CONTENT_TYPE = 'application/pdf'.freeze
|
|
8
|
+
XHTML_CONTENT_TYPE = 'application/xhtml+xml'.freeze
|
|
9
|
+
XHTML_NAMESPACE = 'http://www.w3.org/1999/xhtml'.freeze
|
|
10
|
+
|
|
11
|
+
# TODO: Review the FHIR-referenced HTML 4.0 chapters in detail and determine
|
|
12
|
+
# whether this validator needs additional allowed-element or allowed-attribute handling.
|
|
13
|
+
#
|
|
14
|
+
# This validator interprets Binary XHTML according to the FHIR R4 Narrative
|
|
15
|
+
# fragment rules. It enforces the explicitly prohibited elements and
|
|
16
|
+
# attributes, but does not yet attempt a comprehensive HTML allowlist.
|
|
17
|
+
# https://hl7.org/fhir/R4/narrative.html#security
|
|
18
|
+
#
|
|
19
|
+
# "The XHTML content SHALL NOT contain a head, a body element,
|
|
20
|
+
# external stylesheet references, deprecated elements, scripts,
|
|
21
|
+
# forms, base/link/xlink, frames, iframes, objects or
|
|
22
|
+
# event related attributes (e.g. onClick)."
|
|
23
|
+
PROHIBITED_ELEMENTS = %w[
|
|
24
|
+
base body form frame frameset head iframe input link object script style
|
|
25
|
+
].freeze
|
|
26
|
+
# HTML 4.0 deprecated elements: https://www.w3.org/TR/REC-html40-971218/appendix/changes.html#h-A.1.2
|
|
27
|
+
DEPRECATED_ELEMENTS = %w[applet basefont center dir font isindex menu s strike u].freeze
|
|
28
|
+
EXECUTABLE_URL_SCHEMES = %w[javascript vbscript].freeze
|
|
29
|
+
|
|
30
|
+
def contained_binaries(questionnaire_responses)
|
|
31
|
+
questionnaire_responses.flat_map do |questionnaire_response|
|
|
32
|
+
questionnaire_response.contained&.grep(FHIR::Binary) || []
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def contained_binary_is_safe?(binary)
|
|
37
|
+
return true if binary.contentType == PDF_CONTENT_TYPE
|
|
38
|
+
return false unless binary.contentType == XHTML_CONTENT_TYPE
|
|
39
|
+
|
|
40
|
+
safe_xhtml?(Base64.strict_decode64(binary.data.to_s))
|
|
41
|
+
rescue ArgumentError
|
|
42
|
+
false
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def safe_xhtml?(xhtml)
|
|
46
|
+
document = parse_xhtml(xhtml)
|
|
47
|
+
|
|
48
|
+
narrative_fragment?(document) &&
|
|
49
|
+
document.errors.empty? &&
|
|
50
|
+
narrative_has_content?(document) &&
|
|
51
|
+
document_has_no_unsafe_content?(document)
|
|
52
|
+
rescue Nokogiri::XML::SyntaxError
|
|
53
|
+
false
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
private
|
|
57
|
+
|
|
58
|
+
def parse_xhtml(xhtml)
|
|
59
|
+
# Strict parsing rejects malformed XHTML. `nonet` prevents XML from
|
|
60
|
+
# loading any network resources while it is being parsed.
|
|
61
|
+
Nokogiri::XML::Document.parse(xhtml) { |config| config.strict.nonet }
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def document_has_no_unsafe_content?(document)
|
|
65
|
+
# Inspect every nested XHTML element, including elements in the default
|
|
66
|
+
# XHTML namespace which a non-namespaced XPath would not reliably select.
|
|
67
|
+
document.root.traverse do |node|
|
|
68
|
+
return false if node.element? && unsafe_xhtml_element?(node)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
true
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def narrative_fragment?(document)
|
|
75
|
+
# FHIR Narrative XHTML is represented as a div fragment in the XHTML namespace,
|
|
76
|
+
# rather than as a complete HTML document.
|
|
77
|
+
document.root&.name == 'div' && document.root.namespace&.href == XHTML_NAMESPACE
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def narrative_has_content?(document)
|
|
81
|
+
# FHIR Narrative requires non-whitespace text or an image in the div fragment.
|
|
82
|
+
!document.root.text.strip.empty? ||
|
|
83
|
+
!document.root.at_xpath('.//xhtml:img', xhtml: XHTML_NAMESPACE).nil?
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def unsafe_xhtml_element?(element)
|
|
87
|
+
prohibited_element?(element) ||
|
|
88
|
+
deprecated_element?(element) ||
|
|
89
|
+
xlink_node?(element) ||
|
|
90
|
+
element.attribute_nodes.any? { |attribute| unsafe_xhtml_attribute?(attribute) }
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def prohibited_element?(element)
|
|
94
|
+
PROHIBITED_ELEMENTS.include?(element.name.downcase)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def deprecated_element?(element)
|
|
98
|
+
DEPRECATED_ELEMENTS.include?(element.name.downcase)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def xlink_node?(node)
|
|
102
|
+
# xlink is an XML namespace, so it can qualify either an element or an
|
|
103
|
+
# attribute (for example, xlink:href) rather than appearing as an HTML element.
|
|
104
|
+
node.namespace&.prefix == 'xlink'
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def unsafe_xhtml_attribute?(attribute)
|
|
108
|
+
# In XHTML, event handlers are attributes beginning with `on`, such as
|
|
109
|
+
# `onclick`. They run JavaScript when the corresponding browser event occurs.
|
|
110
|
+
return true if attribute.name.match?(/\Aon/i)
|
|
111
|
+
|
|
112
|
+
return true if xlink_node?(attribute)
|
|
113
|
+
|
|
114
|
+
# `href` and `src` are the XHTML attributes that direct a browser to
|
|
115
|
+
# navigate to or load a URL. Other attributes cannot invoke a URL scheme.
|
|
116
|
+
return false unless %w[href src].include?(attribute.name.downcase)
|
|
117
|
+
|
|
118
|
+
# `javascript:` and `vbscript:` URLs execute code when followed instead
|
|
119
|
+
# of loading a document or image.
|
|
120
|
+
EXECUTABLE_URL_SCHEMES.include?(url_scheme(attribute.value))
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def url_scheme(url)
|
|
124
|
+
url.to_s.strip.partition(':').first.downcase
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
end
|
data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_design/cql_library_validation_test.rb
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require_relative '../../../tags'
|
|
2
|
+
require_relative '../questionnaire_operation_validation'
|
|
3
|
+
|
|
4
|
+
module DaVinciDTRTestKit
|
|
5
|
+
module DTRPayerServerV220
|
|
6
|
+
class CQLLibraryValidationTest < Inferno::Test
|
|
7
|
+
include QuestionnaireOperationValidation
|
|
8
|
+
|
|
9
|
+
id :dtr_v220_payer_cql_library_validation
|
|
10
|
+
|
|
11
|
+
title 'All referenced CQL Libraries are included'
|
|
12
|
+
description %(
|
|
13
|
+
Inferno will verify that the payer server's response to the
|
|
14
|
+
questionnaire-package operation includes all CQL Libraries referenced in
|
|
15
|
+
the returned Questionnaires.
|
|
16
|
+
)
|
|
17
|
+
verifies_requirements 'hl7.fhir.us.davinci-dtr_2.2.0@spec-87',
|
|
18
|
+
'hl7.fhir.us.davinci-dtr_2.2.0@spec-95',
|
|
19
|
+
'hl7.fhir.us.davinci-dtr_2.2.0@spec-98',
|
|
20
|
+
'hl7.fhir.us.davinci-dtr_2.2.0@spec-99',
|
|
21
|
+
'hl7.fhir.us.davinci-dtr_2.2.0@oper-13',
|
|
22
|
+
'hl7.fhir.us.davinci-dtr_2.2.0@oper-16'
|
|
23
|
+
|
|
24
|
+
run do
|
|
25
|
+
load_tagged_requests(QUESTIONNAIRE_TAG)
|
|
26
|
+
|
|
27
|
+
successful_requests = requests.select { |request| [200, 201].include? request.response[:status] }
|
|
28
|
+
|
|
29
|
+
skip_if successful_requests.blank?, 'No successful $questionnaire-package requests were made'
|
|
30
|
+
|
|
31
|
+
library_count = 0
|
|
32
|
+
|
|
33
|
+
successful_requests.each_with_index do |request, index|
|
|
34
|
+
JSON.parse(request.response_body)
|
|
35
|
+
|
|
36
|
+
resource = FHIR.from_contents(request.response_body)
|
|
37
|
+
|
|
38
|
+
next if resource.nil?
|
|
39
|
+
|
|
40
|
+
questionnaire_bundles = extract_questionnaire_bundles(resource)
|
|
41
|
+
libraries = extract_libraries_from_bundles(questionnaire_bundles)
|
|
42
|
+
|
|
43
|
+
next if libraries.blank?
|
|
44
|
+
|
|
45
|
+
check_libraries(resource, index)
|
|
46
|
+
|
|
47
|
+
library_count += libraries.length
|
|
48
|
+
rescue JSON::ParserError
|
|
49
|
+
next
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
assert_no_error_messages('Not all responses contained all necessary valid CQL Libraries.')
|
|
53
|
+
|
|
54
|
+
omit_if library_count.zero?, 'No CQL libraries were found.'
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_design/questionnaire_design_support.rb
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../../../tags'
|
|
4
|
+
|
|
5
|
+
module DaVinciDTRTestKit
|
|
6
|
+
module DTRPayerServerV220
|
|
7
|
+
module QuestionnaireDesignSupport
|
|
8
|
+
CQL_MEDIA_TYPES = [
|
|
9
|
+
'text/cql',
|
|
10
|
+
'text/cql-expression',
|
|
11
|
+
'text/cql-identifier'
|
|
12
|
+
].freeze
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
# Returns a Hash for each Questionnaire returned in a tagged response:
|
|
17
|
+
# { questionnaire:, operation:, request_index: }
|
|
18
|
+
# request_index is scoped independently to each operation.
|
|
19
|
+
def returned_questionnaires
|
|
20
|
+
questionnaires_from_requests(load_tagged_requests(QUESTIONNAIRE_TAG), '$questionnaire-package') +
|
|
21
|
+
questionnaires_from_requests(load_tagged_requests(NEXT_TAG), '$next-question')
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def questionnaires_from_requests(requests, operation)
|
|
25
|
+
requests.each_with_index.flat_map do |request, request_index|
|
|
26
|
+
next [] if request.response_body.blank?
|
|
27
|
+
|
|
28
|
+
resource = FHIR.from_contents(request.response_body)
|
|
29
|
+
questionnaires_from_resource(resource).map do |questionnaire|
|
|
30
|
+
{ questionnaire:, operation:, request_index: }
|
|
31
|
+
end
|
|
32
|
+
rescue JSON::ParserError, FHIR::ClientException
|
|
33
|
+
[]
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def questionnaires_from_resource(resource)
|
|
38
|
+
case resource.resourceType
|
|
39
|
+
when 'Questionnaire'
|
|
40
|
+
[resource]
|
|
41
|
+
when 'QuestionnaireResponse'
|
|
42
|
+
resource.contained.grep(FHIR::Questionnaire)
|
|
43
|
+
when 'Bundle'
|
|
44
|
+
questionnaires_from_resources(resource.entry.map(&:resource))
|
|
45
|
+
when 'Parameters'
|
|
46
|
+
questionnaires_from_resources(resource.parameter.map(&:resource))
|
|
47
|
+
else
|
|
48
|
+
[]
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def questionnaires_from_resources(resources)
|
|
53
|
+
resources.compact.flat_map { |resource| questionnaires_from_resource(resource) }
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def questionnaire_items(questionnaire)
|
|
57
|
+
questionnaire.item.flat_map { |item| [item] + questionnaire_items(item) }
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def cql_expression?(expression)
|
|
61
|
+
CQL_MEDIA_TYPES.include?(expression.language.to_s.split(';').first.strip)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'questionnaire_design_support'
|
|
4
|
+
|
|
5
|
+
module DaVinciDTRTestKit
|
|
6
|
+
module DTRPayerServerV220
|
|
7
|
+
class QuestionnaireExpressionElmTest < Inferno::Test
|
|
8
|
+
include QuestionnaireDesignSupport
|
|
9
|
+
|
|
10
|
+
ALTERNATIVE_EXPRESSION_URL = 'http://hl7.org/fhir/us/davinci-dtr/StructureDefinition/alternativeExpression'
|
|
11
|
+
|
|
12
|
+
id :dtr_v220_payer_questionnaire_expression_elm
|
|
13
|
+
title 'Questionnaire expressions include compiled JSON ELM'
|
|
14
|
+
description %(
|
|
15
|
+
Inferno verifies that each Expression in the returned Questionnaires has
|
|
16
|
+
an Alternative Expression extension containing compiled JSON ELM.
|
|
17
|
+
)
|
|
18
|
+
verifies_requirements 'hl7.fhir.us.davinci-dtr_2.2.0@spec-96'
|
|
19
|
+
|
|
20
|
+
run do
|
|
21
|
+
questionnaire_details = returned_questionnaires
|
|
22
|
+
skip_if questionnaire_details.blank?, 'No Questionnaire resources were returned'
|
|
23
|
+
|
|
24
|
+
cql_expressions = questionnaire_details.flat_map { |details| cql_questionnaire_expressions(details) }
|
|
25
|
+
omit_if cql_expressions.blank?, 'No CQL expressions were found'
|
|
26
|
+
|
|
27
|
+
expressions_without_elm = cql_expressions.reject do |details|
|
|
28
|
+
alternative_expression_present?(details[:expression])
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
expressions_without_elm.each do |details|
|
|
32
|
+
add_message(
|
|
33
|
+
'error',
|
|
34
|
+
"#{details[:location]} does not include an Alternative Expression extension with compiled JSON ELM."
|
|
35
|
+
)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
assert expressions_without_elm.blank?,
|
|
39
|
+
'One or more CQL expressions did not include compiled JSON ELM. See messages for details.'
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
def cql_questionnaire_expressions(details)
|
|
45
|
+
questionnaire = details[:questionnaire]
|
|
46
|
+
cql_expressions_from_extensions(questionnaire.extension, details, 'Questionnaire-level extension') +
|
|
47
|
+
questionnaire_items(questionnaire).flat_map do |item|
|
|
48
|
+
cql_expressions_from_extensions(item.extension, details, "linkId `#{item.linkId}`")
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def cql_expressions_from_extensions(extensions, details, location)
|
|
53
|
+
extensions.flat_map do |extension|
|
|
54
|
+
expressions = []
|
|
55
|
+
if extension.valueExpression.present? && cql_expression?(extension.valueExpression)
|
|
56
|
+
expressions << {
|
|
57
|
+
expression: extension.valueExpression,
|
|
58
|
+
location: "#{request_location(details)}, #{location}"
|
|
59
|
+
}
|
|
60
|
+
end
|
|
61
|
+
expressions.concat(cql_expressions_from_extensions(extension.extension, details, location))
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def request_location(details)
|
|
66
|
+
"#{details[:operation]} request #{details[:request_index] + 1}"
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def alternative_expression_present?(expression)
|
|
70
|
+
expression.extension.any? do |extension|
|
|
71
|
+
extension.url == ALTERNATIVE_EXPRESSION_URL && expression_contains_elm?(extension.valueExpression)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def expression_contains_elm?(expression)
|
|
76
|
+
expression&.language == 'application/elm+json' &&
|
|
77
|
+
(expression&.expression.present? || extension.valueExpression&.reference.present?)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'questionnaire_design_support'
|
|
4
|
+
|
|
5
|
+
module DaVinciDTRTestKit
|
|
6
|
+
module DTRPayerServerV220
|
|
7
|
+
class QuestionnaireExpressionLanguageTest < Inferno::Test
|
|
8
|
+
include QuestionnaireDesignSupport
|
|
9
|
+
|
|
10
|
+
id :dtr_v220_payer_questionnaire_expression_language
|
|
11
|
+
title 'Questionnaire flow and rendering expressions use CQL'
|
|
12
|
+
description %(
|
|
13
|
+
Inferno verifies that Expression-valued Questionnaire item extensions are
|
|
14
|
+
written in CQL. This requirement is conditional and is omitted when no
|
|
15
|
+
such expressions are present.
|
|
16
|
+
)
|
|
17
|
+
verifies_requirements 'hl7.fhir.us.davinci-dtr_2.2.0@spec-18'
|
|
18
|
+
|
|
19
|
+
run do
|
|
20
|
+
questionnaire_details = returned_questionnaires
|
|
21
|
+
skip_if questionnaire_details.blank?, 'No Questionnaire resources were returned'
|
|
22
|
+
|
|
23
|
+
expressions = questionnaire_details.flat_map { |details| questionnaire_item_expressions(details) }
|
|
24
|
+
omit_if expressions.blank?, 'No flow or rendering expressions were found'
|
|
25
|
+
|
|
26
|
+
non_cql_expressions = expressions.reject do |details|
|
|
27
|
+
cql_expression?(details[:expression])
|
|
28
|
+
end
|
|
29
|
+
non_cql_details = non_cql_expressions.map do |details|
|
|
30
|
+
language = details[:expression].language.presence || 'missing'
|
|
31
|
+
"#{request_location(details[:request_details])} linkId `#{details[:link_id]}` (language `#{language}`)"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
assert non_cql_expressions.blank?,
|
|
35
|
+
"The following flow or rendering expressions were not written in CQL: #{non_cql_details.join(', ')}"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
def questionnaire_item_expressions(details)
|
|
41
|
+
questionnaire = details[:questionnaire]
|
|
42
|
+
questionnaire_items(questionnaire).flat_map do |item|
|
|
43
|
+
item.extension.flat_map do |extension|
|
|
44
|
+
expressions_from_extension(extension).map do |expression|
|
|
45
|
+
{ expression:, link_id: item.linkId, request_details: details }
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def expressions_from_extension(extension)
|
|
52
|
+
[
|
|
53
|
+
extension.valueExpression,
|
|
54
|
+
*extension.extension.flat_map { |nested_extension| expressions_from_extension(nested_extension) }
|
|
55
|
+
].compact
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def request_location(details)
|
|
59
|
+
"#{details[:operation]} request #{details[:request_index] + 1}"
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
data/lib/davinci_dtr_test_kit/server/v2.2.0/questionnaire_design/questionnaire_prepopulation_test.rb
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'questionnaire_design_support'
|
|
4
|
+
|
|
5
|
+
module DaVinciDTRTestKit
|
|
6
|
+
module DTRPayerServerV220
|
|
7
|
+
class QuestionnairePrepopulationTest < Inferno::Test
|
|
8
|
+
include QuestionnaireDesignSupport
|
|
9
|
+
|
|
10
|
+
POPULATION_EXPRESSION_URLS = [
|
|
11
|
+
'http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-initialExpression',
|
|
12
|
+
'http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-candidateExpression',
|
|
13
|
+
'http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-contextExpression'
|
|
14
|
+
].freeze
|
|
15
|
+
|
|
16
|
+
id :dtr_v220_payer_questionnaire_prepopulation
|
|
17
|
+
title 'Questionnaires support EHR prepopulation'
|
|
18
|
+
description %(
|
|
19
|
+
Inferno verifies that, across all Questionnaires returned by the DTR server,
|
|
20
|
+
at least one includes an extension indicating support for population from
|
|
21
|
+
EHR data.
|
|
22
|
+
)
|
|
23
|
+
verifies_requirements 'hl7.fhir.us.davinci-dtr_2.2.0@spec-54'
|
|
24
|
+
|
|
25
|
+
run do
|
|
26
|
+
questionnaires = returned_questionnaires.map { |details| details[:questionnaire] }
|
|
27
|
+
skip_if questionnaires.blank?, 'No Questionnaire resources were returned'
|
|
28
|
+
|
|
29
|
+
assert questionnaires.any? { |questionnaire| questionnaire_has_prepopulation_logic?(questionnaire) },
|
|
30
|
+
'No Questionnaire included logic supporting population from the EHR.'
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def questionnaire_has_prepopulation_logic?(questionnaire)
|
|
36
|
+
questionnaire_items(questionnaire).any? do |item|
|
|
37
|
+
item.extension.any? { |extension| POPULATION_EXPRESSION_URLS.include?(extension.url) }
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|