davinci_crd_test_kit 0.13.0 → 0.14.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/inferno_crd_client_suite.json.erb +20 -14
- data/config/presets/inferno_crd_client_suite_prefetch_subset_v221.json.erb +125 -0
- data/config/presets/inferno_crd_client_suite_v221.json.erb +124 -0
- data/config/presets/inferno_crd_server_suite.json.erb +58 -1
- data/config/presets/inferno_crd_server_suite_v221.json.erb +94 -0
- data/config/presets/ri_crd_request_generator.json_v221.json.erb +13 -0
- data/config/presets/ri_crd_server.json.erb +19 -19
- data/lib/davinci_crd_test_kit/client/client_base_urls.rb +80 -0
- data/lib/davinci_crd_test_kit/{client_hook_request_validation.rb → client/client_hook_request_validation.rb} +1 -1
- data/lib/davinci_crd_test_kit/client/crd_client_options.rb +30 -0
- data/lib/davinci_crd_test_kit/client/endpoints/cds_services_discovery_handler.rb +34 -0
- data/lib/davinci_crd_test_kit/client/endpoints/custom_service_response.rb +342 -0
- data/lib/davinci_crd_test_kit/client/endpoints/gather_response_generation_data.rb +410 -0
- data/lib/davinci_crd_test_kit/client/endpoints/hook_request_endpoint.rb +233 -0
- data/lib/davinci_crd_test_kit/{mock_service_response.rb → client/endpoints/mock_service_response.rb} +165 -59
- data/lib/davinci_crd_test_kit/{card_responses → client/endpoints/mocked_card_responses}/companions_prerequisites.json +1 -0
- data/lib/davinci_crd_test_kit/{card_responses → client/endpoints/mocked_card_responses}/create_update_coverage_information.json +3 -2
- data/lib/davinci_crd_test_kit/{card_responses → client/endpoints/mocked_card_responses}/launch_smart_app.json +8 -1
- data/lib/davinci_crd_test_kit/{card_responses → client/endpoints/mocked_card_responses}/propose_alternate_request.json +1 -0
- data/lib/davinci_crd_test_kit/{card_responses → client/endpoints/mocked_card_responses}/request_form_completion.json +17 -16
- data/lib/davinci_crd_test_kit/client/multi_request_message_helper.rb +35 -0
- data/lib/davinci_crd_test_kit/client/tagged_request_load_helper.rb +38 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/api/client_fhir_api_create_test.rb +43 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/api/client_fhir_api_read_test.rb +43 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/api/client_fhir_api_search_test.rb +234 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/api/client_fhir_api_update_test.rb +43 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/api/client_fhir_api_validation_test.rb +63 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/auth/decode_auth_token_test.rb +65 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/auth/retrieve_jwks_test.rb +109 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/auth/token_header_test.rb +70 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/auth/token_payload_test.rb +85 -0
- data/lib/davinci_crd_test_kit/{routes/cds-services.json → client/v2.0.1/cds-services-v201.json} +1 -1
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_appointment_book_group.rb +108 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_card_must_support_group.rb +31 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_encounter_discharge_group.rb +105 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_encounter_start_group.rb +105 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_fhir_api_group.rb +790 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_hooks_group.rb +74 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_order_dispatch_group.rb +111 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_order_select_group.rb +116 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_order_sign_group.rb +113 -0
- data/lib/davinci_crd_test_kit/{client_registration_group.rb → client/v2.0.1/client_registration_group.rb} +12 -8
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_urls.rb +13 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/crd_client_suite.rb +134 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/invocation/appointment_book_receive_request_test.rb +129 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/invocation/encounter_discharge_receive_request_test.rb +126 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/invocation/encounter_start_receive_request_test.rb +126 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/invocation/order_dispatch_receive_request_test.rb +138 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/invocation/order_select_receive_request_test.rb +134 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/invocation/order_sign_receive_request_test.rb +136 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/must_support/client_card_must_support_coverage_information.rb +93 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/must_support/client_card_must_support_external_reference.rb +62 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/must_support/client_card_must_support_instructions.rb +62 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/registration/client_registration_verification_test.rb +94 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/registration/client_service_registration_attestation_test.rb +40 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_fetched_data_test.rb +86 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_optional_fields_test.rb +63 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_prefetch_equals_queried_test.rb +96 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_required_fields_test.rb +55 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_valid_context_test.rb +70 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_valid_prefetch_test.rb +62 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_response/client_display_cards_attest.rb +83 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_response/inferno_response_validation.rb +79 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/api/client_coverage_info_update_test.rb +212 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/api/client_crd_update_verification_group.rb +18 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/auth/decode_auth_token_test.rb +69 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/auth/retrieve_jwks_test.rb +120 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/auth/token_header_test.rb +92 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/auth/token_payload_test.rb +93 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/cds-services-prefetch-subset-v221.json +198 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/cds-services-v221.json +202 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_appointment_book_group.rb +102 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_cross_hook_group.rb +28 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_encounter_discharge_group.rb +96 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_encounter_start_group.rb +95 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_fhir_api_group.rb +88 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_hooks_group.rb +64 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_long_running_hook_group.rb +32 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_order_dispatch_group.rb +101 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_order_select_group.rb +102 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_order_sign_group.rb +107 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_registration_group.rb +27 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_urls.rb +27 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/crd_client_suite.rb +229 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_card_must_support_coverage_information_test.rb +63 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_fhirpath_collection_as_comma_delimited_string_test.rb +60 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_hook_instances_unique_test.rb +45 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_location_address_propagation_test.rb +135 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_prefetch_complete_and_subset_test.rb +103 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/appointment_book_receive_request_test.rb +156 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/encounter_discharge_receive_request_test.rb +157 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/encounter_start_receive_request_test.rb +157 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/order_dispatch_receive_request_test.rb +165 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/order_select_receive_request_test.rb +165 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/order_sign_receive_request_test.rb +165 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/long_running/client_long_running_receive_request_test.rb +64 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/long_running/client_skip_long_running_attestation_test.rb +49 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/registration/client_registration_verification_test.rb +161 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/registration/client_service_registration_attestation_test.rb +107 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_conformance_test.rb +47 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_coverage_verification_test.rb +152 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_data_fetch_verification_test.rb +55 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_granted_scopes_test.rb +123 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_prefetch_complete_test.rb +127 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_prefetch_profiles_test.rb +55 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_requested_version_test.rb +54 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_secured_transport_test.rb +48 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_response/client_display_cards_attest.rb +74 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_response/hook_response_support_coverage_information_test.rb +30 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_response/inferno_response_validation.rb +77 -0
- data/lib/davinci_crd_test_kit/cross_suite/base_urls.rb +20 -0
- data/lib/davinci_crd_test_kit/cross_suite/cards_identification.rb +312 -0
- data/lib/davinci_crd_test_kit/{cards_validation.rb → cross_suite/cards_validation.rb} +104 -47
- data/lib/davinci_crd_test_kit/cross_suite/coverage-information_stu201_metadata.yml +27 -0
- data/lib/davinci_crd_test_kit/cross_suite/coverage-information_stu221_metadata.yml +60 -0
- data/lib/davinci_crd_test_kit/cross_suite/fhirpath_on_cds_request.rb +177 -0
- data/lib/davinci_crd_test_kit/{hook_request_field_validation.rb → cross_suite/hook_request_field_validation.rb} +282 -203
- data/lib/davinci_crd_test_kit/cross_suite/logical_models_override_helper.rb +220 -0
- data/lib/davinci_crd_test_kit/cross_suite/prefetch_completeness_checker.rb +462 -0
- data/lib/davinci_crd_test_kit/cross_suite/prefetch_contents_validation.rb +81 -0
- data/lib/davinci_crd_test_kit/cross_suite/prefetch_profile_validation.rb +48 -0
- data/lib/davinci_crd_test_kit/cross_suite/profiles_and_resource_types.rb +63 -0
- data/lib/davinci_crd_test_kit/cross_suite/replace_tokens.rb +38 -0
- data/lib/davinci_crd_test_kit/cross_suite/requests_logical_model_validation.rb +202 -0
- data/lib/davinci_crd_test_kit/cross_suite/response_logical_model_validation.rb +274 -0
- data/lib/davinci_crd_test_kit/{suggestion_actions_validation.rb → cross_suite/suggestion_actions_validation.rb} +70 -50
- data/lib/davinci_crd_test_kit/cross_suite/tags.rb +42 -0
- data/lib/davinci_crd_test_kit/metadata.rb +10 -44
- data/lib/davinci_crd_test_kit/requirements/cds-hooks-library_1.0.1_requirements.xlsx +0 -0
- data/lib/davinci_crd_test_kit/requirements/cds-hooks_2.0_requirements.xlsx +0 -0
- data/lib/davinci_crd_test_kit/requirements/cds-hooks_3.0.0-ballot_requirements.xlsx +0 -0
- data/lib/davinci_crd_test_kit/requirements/davinci_crd_test_kit_requirements.csv +742 -65
- data/lib/davinci_crd_test_kit/requirements/generated/crd_client_requirements_coverage.csv +279 -54
- data/lib/davinci_crd_test_kit/requirements/generated/crd_client_v221_requirements_coverage.csv +1430 -0
- data/lib/davinci_crd_test_kit/requirements/generated/crd_server_requirements_coverage.csv +36 -45
- data/lib/davinci_crd_test_kit/requirements/generated/crd_server_v221_requirements_coverage.csv +143 -0
- data/lib/davinci_crd_test_kit/requirements/hl7.fhir.us.davinci-crd_2.0.1_requirements.xlsx +0 -0
- data/lib/davinci_crd_test_kit/requirements/hl7.fhir.us.davinci-crd_2.2.1_requirements.xlsx +0 -0
- data/lib/davinci_crd_test_kit/server/endpoints/jwk_set_endpoint_handler.rb +13 -0
- data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_create_endpoint.rb +23 -0
- data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_delete_endpoint.rb +30 -0
- data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_metadata_endpoint.rb +112 -0
- data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_read_endpoint.rb +21 -0
- data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_request_handler.rb +261 -0
- data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_search_endpoint.rb +561 -0
- data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_update_endpoint.rb +24 -0
- data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/stress-test-Bundle.json +54687 -0
- data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr_endpoints.rb +95 -0
- data/lib/davinci_crd_test_kit/server/jobs/invoke_hook.rb +225 -0
- data/lib/davinci_crd_test_kit/{jwt_helper.rb → server/jwt_helper.rb} +1 -12
- data/lib/davinci_crd_test_kit/server/resource_extractor.rb +68 -0
- data/lib/davinci_crd_test_kit/server/server_abstract_invoke_hook_test.rb +165 -0
- data/lib/davinci_crd_test_kit/server/server_base_urls.rb +30 -0
- data/lib/davinci_crd_test_kit/{server_hook_helper.rb → server/server_hook_helper.rb} +1 -1
- data/lib/davinci_crd_test_kit/{server_hook_request_validation.rb → server/server_hook_request_validation.rb} +1 -1
- data/lib/davinci_crd_test_kit/{test_helper.rb → server/server_test_helper.rb} +7 -3
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Appointment.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/ClaimResponse.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/CommunicationRequest.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Coverage.yml +21 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Device.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/DeviceRequest.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Encounter.yml +7 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Location.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/MedicationRequest.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/NutritionOrder.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Organization.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Patient.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Practitioner.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/PractitionerRole.yml +40 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/ServiceRequest.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Task.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/VisionPrescription.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_server_suite.rb +99 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/discovery/discovery_endpoint_test.rb +90 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/discovery/discovery_services_validation_test.rb +67 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/interaction/server_invoke_hook_test.rb +12 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/must_support/coverage_information_system_action_across_hooks_validation_test.rb +34 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/must_support/external_reference_card_across_hooks_validation_test.rb +30 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/must_support/instructions_card_received_across_hooks_test.rb +27 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_appointment_book_group.rb +191 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_demonstrate_hook_response_group.rb +93 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_discovery_group.rb +62 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_encounter_discharge_group.rb +186 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_encounter_start_group.rb +186 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_hooks_group.rb +73 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_order_dispatch_group.rb +191 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_order_select_group.rb +211 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_order_sign_group.rb +216 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_required_card_response_validation_group.rb +28 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_urls.rb +13 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_request/service_request_context_validation_test.rb +30 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_request/service_request_optional_fields_validation_test.rb +39 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_request/service_request_required_fields_validation_test.rb +40 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/additional_orders_validation_test.rb +59 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/card_optional_fields_validation_test.rb +51 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/coverage_information_system_action_received_test.rb +65 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/coverage_information_system_action_validation_test.rb +120 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/create_or_update_coverage_info_response_validation_test.rb +70 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/external_reference_card_validation_test.rb +37 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/form_completion_response_validation_test.rb +67 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/instructions_card_received_test.rb +30 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/launch_smart_app_card_validation_test.rb +39 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/propose_alternate_request_card_validation_test.rb +46 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/service_response_validation_test.rb +83 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Appointment_withorder.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Appointment_withoutorder.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/CommunicationRequest.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Coverage.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Device.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/DeviceRequest.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Encounter.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Location.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/MedicationRequest.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/NutritionOrder.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Organization.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Patient.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/PractitionerRole.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/ServiceRequest.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/VisionPrescription.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_server_suite.rb +115 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/discovery/discovery_configuration_test.rb +159 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/discovery/discovery_endpoint_test.rb +90 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/discovery/discovery_prefetch_support_test.rb +43 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/discovery/discovery_services_validation_test.rb +121 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/interaction/server_invoke_hook_test.rb +17 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/must_support/coverage_information_must_support_test.rb +71 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/must_support/coverage_information_system_action_across_hooks_validation_test.rb +36 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/must_support/supported_us_core_versions_test.rb +118 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_appointment_book_group.rb +213 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_demonstrate_hook_response_group.rb +93 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_discovery_group.rb +69 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_encounter_discharge_group.rb +194 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_encounter_start_group.rb +194 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_hooks_group.rb +73 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_order_dispatch_group.rb +214 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_order_select_group.rb +219 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_order_sign_group.rb +241 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_required_card_response_validation_group.rb +30 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_urls.rb +13 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_request/service_request_context_validation_test.rb +30 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_request/service_request_no_custom_extensions_test.rb +120 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_request/service_request_optional_fields_validation_test.rb +39 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_request/service_request_required_fields_validation_test.rb +40 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/additional_orders_validation_test.rb +66 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/all_responses_include_coverage_information_test.rb +123 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/card_optional_fields_validation_test.rb +57 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/coverage_info_configuration_test.rb +83 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/coverage_information_system_action_received_test.rb +65 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/coverage_information_system_action_validation_test.rb +184 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/create_or_update_coverage_info_response_validation_test.rb +75 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/external_reference_card_validation_test.rb +47 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/form_completion_response_validation_test.rb +91 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/hook_request_resource_resolution.rb +137 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/instructions_card_received_test.rb +32 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/launch_smart_app_card_validation_test.rb +49 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/order_dispatch_coverage_information_test.rb +38 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/propose_alternate_request_card_validation_test.rb +54 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/service_response_validation_test.rb +97 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/unknown_cds_hooks_elements_test.rb +78 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/unknown_configuration_test.rb +78 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/unknown_context_test.rb +78 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/verify_response_without_billing_options_test.rb +43 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/verify_response_without_configuration_test.rb +44 -0
- data/lib/davinci_crd_test_kit/version.rb +2 -2
- data/lib/davinci_crd_test_kit.rb +4 -2
- metadata +297 -93
- data/lib/davinci_crd_test_kit/client_fhir_api_group.rb +0 -785
- data/lib/davinci_crd_test_kit/client_hooks_group.rb +0 -74
- data/lib/davinci_crd_test_kit/client_tests/appointment_book_receive_request_test.rb +0 -93
- data/lib/davinci_crd_test_kit/client_tests/client_appointment_book_group.rb +0 -75
- data/lib/davinci_crd_test_kit/client_tests/client_display_cards_attest.rb +0 -48
- data/lib/davinci_crd_test_kit/client_tests/client_encounter_discharge_group.rb +0 -73
- data/lib/davinci_crd_test_kit/client_tests/client_encounter_start_group.rb +0 -73
- data/lib/davinci_crd_test_kit/client_tests/client_fhir_api_create_test.rb +0 -42
- data/lib/davinci_crd_test_kit/client_tests/client_fhir_api_read_test.rb +0 -40
- data/lib/davinci_crd_test_kit/client_tests/client_fhir_api_search_test.rb +0 -232
- data/lib/davinci_crd_test_kit/client_tests/client_fhir_api_update_test.rb +0 -42
- data/lib/davinci_crd_test_kit/client_tests/client_fhir_api_validation_test.rb +0 -61
- data/lib/davinci_crd_test_kit/client_tests/client_order_dispatch_group.rb +0 -79
- data/lib/davinci_crd_test_kit/client_tests/client_order_select_group.rb +0 -82
- data/lib/davinci_crd_test_kit/client_tests/client_order_sign_group.rb +0 -81
- data/lib/davinci_crd_test_kit/client_tests/client_registration_verification_test.rb +0 -88
- data/lib/davinci_crd_test_kit/client_tests/decode_auth_token_test.rb +0 -60
- data/lib/davinci_crd_test_kit/client_tests/encounter_discharge_receive_request_test.rb +0 -90
- data/lib/davinci_crd_test_kit/client_tests/encounter_start_receive_request_test.rb +0 -90
- data/lib/davinci_crd_test_kit/client_tests/hook_request_optional_fields_test.rb +0 -57
- data/lib/davinci_crd_test_kit/client_tests/hook_request_required_fields_test.rb +0 -49
- data/lib/davinci_crd_test_kit/client_tests/hook_request_valid_context_test.rb +0 -68
- data/lib/davinci_crd_test_kit/client_tests/hook_request_valid_prefetch_test.rb +0 -69
- data/lib/davinci_crd_test_kit/client_tests/order_dispatch_receive_request_test.rb +0 -102
- data/lib/davinci_crd_test_kit/client_tests/order_select_receive_request_test.rb +0 -98
- data/lib/davinci_crd_test_kit/client_tests/order_sign_receive_request_test.rb +0 -101
- data/lib/davinci_crd_test_kit/client_tests/retrieve_jwks_test.rb +0 -105
- data/lib/davinci_crd_test_kit/client_tests/submitted_response_validation.rb +0 -48
- data/lib/davinci_crd_test_kit/client_tests/token_header_test.rb +0 -65
- data/lib/davinci_crd_test_kit/client_tests/token_payload_test.rb +0 -78
- data/lib/davinci_crd_test_kit/crd_client_suite.rb +0 -193
- data/lib/davinci_crd_test_kit/crd_options.rb +0 -9
- data/lib/davinci_crd_test_kit/crd_server_suite.rb +0 -125
- data/lib/davinci_crd_test_kit/igs/davinci-crd-2.0.1.tgz +0 -0
- data/lib/davinci_crd_test_kit/routes/cds_services_discovery_handler.rb +0 -18
- data/lib/davinci_crd_test_kit/routes/hook_request_endpoint.rb +0 -77
- data/lib/davinci_crd_test_kit/routes/jwk_set_endpoint_handler.rb +0 -15
- data/lib/davinci_crd_test_kit/server_appointment_book_group.rb +0 -176
- data/lib/davinci_crd_test_kit/server_demonstrate_hook_response_group.rb +0 -77
- data/lib/davinci_crd_test_kit/server_discovery_group.rb +0 -60
- data/lib/davinci_crd_test_kit/server_encounter_discharge_group.rb +0 -170
- data/lib/davinci_crd_test_kit/server_encounter_start_group.rb +0 -170
- data/lib/davinci_crd_test_kit/server_hooks_group.rb +0 -71
- data/lib/davinci_crd_test_kit/server_order_dispatch_group.rb +0 -176
- data/lib/davinci_crd_test_kit/server_order_select_group.rb +0 -195
- data/lib/davinci_crd_test_kit/server_order_sign_group.rb +0 -201
- data/lib/davinci_crd_test_kit/server_required_card_response_validation_group.rb +0 -26
- data/lib/davinci_crd_test_kit/server_tests/additional_orders_validation_test.rb +0 -68
- data/lib/davinci_crd_test_kit/server_tests/card_optional_fields_validation_test.rb +0 -47
- data/lib/davinci_crd_test_kit/server_tests/coverage_information_system_action_across_hooks_validation_test.rb +0 -32
- data/lib/davinci_crd_test_kit/server_tests/coverage_information_system_action_received_test.rb +0 -63
- data/lib/davinci_crd_test_kit/server_tests/coverage_information_system_action_validation_test.rb +0 -118
- data/lib/davinci_crd_test_kit/server_tests/create_or_update_coverage_info_response_validation_test.rb +0 -71
- data/lib/davinci_crd_test_kit/server_tests/discovery_endpoint_test.rb +0 -88
- data/lib/davinci_crd_test_kit/server_tests/discovery_services_validation_test.rb +0 -65
- data/lib/davinci_crd_test_kit/server_tests/external_reference_card_across_hooks_validation_test.rb +0 -28
- data/lib/davinci_crd_test_kit/server_tests/external_reference_card_validation_test.rb +0 -36
- data/lib/davinci_crd_test_kit/server_tests/form_completion_response_validation_test.rb +0 -78
- data/lib/davinci_crd_test_kit/server_tests/instructions_card_received_across_hooks_test.rb +0 -25
- data/lib/davinci_crd_test_kit/server_tests/instructions_card_received_test.rb +0 -26
- data/lib/davinci_crd_test_kit/server_tests/launch_smart_app_card_validation_test.rb +0 -38
- data/lib/davinci_crd_test_kit/server_tests/propose_alternate_request_card_validation_test.rb +0 -63
- data/lib/davinci_crd_test_kit/server_tests/service_call_test.rb +0 -101
- data/lib/davinci_crd_test_kit/server_tests/service_request_context_validation_test.rb +0 -28
- data/lib/davinci_crd_test_kit/server_tests/service_request_optional_fields_validation_test.rb +0 -37
- data/lib/davinci_crd_test_kit/server_tests/service_request_required_fields_validation_test.rb +0 -38
- data/lib/davinci_crd_test_kit/server_tests/service_response_validation_test.rb +0 -81
- data/lib/davinci_crd_test_kit/tags.rb +0 -10
- data/lib/davinci_crd_test_kit/urls.rb +0 -52
- /data/lib/davinci_crd_test_kit/{card_responses → client/endpoints/mocked_card_responses}/external_reference.json +0 -0
- /data/lib/davinci_crd_test_kit/{card_responses → client/endpoints/mocked_card_responses}/instructions.json +0 -0
- /data/lib/davinci_crd_test_kit/{crd_jwks.json → server/endpoints/crd_jwks.json} +0 -0
- /data/lib/davinci_crd_test_kit/{jwks.rb → server/endpoints/jwks.rb} +0 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
module DaVinciCRDTestKit
|
|
2
|
+
module V221
|
|
3
|
+
class CRDClientServiceRegistrationAttestation < Inferno::Test
|
|
4
|
+
include ClientURLs
|
|
5
|
+
|
|
6
|
+
id :crd_v221_client_service_registration_attestation
|
|
7
|
+
title 'CRD client registers Inferno (Attestation)'
|
|
8
|
+
description %(
|
|
9
|
+
Inferno simulates two CRD servers which can be discovered at the following endpoints:
|
|
10
|
+
- Complete Prefetch Service Discovery Endpoint: #{ClientURLs.discovery_url}
|
|
11
|
+
- Subset Prefetch Service Discovery Endpoint: #{ClientURLs.prefetch_subset_discovery_url}
|
|
12
|
+
|
|
13
|
+
During this test, the tester will confirm that these two endpoints
|
|
14
|
+
have been registered by the client as trusted CRD servers that can access the CRD client's
|
|
15
|
+
FHIR server and that they have each been
|
|
16
|
+
- Associated with a particular payer organization (used to check that the
|
|
17
|
+
hook requests are sent by the client system to the appropriate payers based on
|
|
18
|
+
the Patient's coverage).
|
|
19
|
+
- Granted patient- or user-level read and search access to all US Core resource
|
|
20
|
+
types in the selected US Core version (required to verify the client's support
|
|
21
|
+
of the US Core FHIR API and used to verify the `fhirAuthorization.scope`
|
|
22
|
+
hook request field).
|
|
23
|
+
)
|
|
24
|
+
verifies_requirements 'cds-hooks_3.0.0-ballot@174'
|
|
25
|
+
|
|
26
|
+
input :complete_prefetch_service_organization_id,
|
|
27
|
+
title: 'Complete Prefetch Service Organization id',
|
|
28
|
+
description: %(
|
|
29
|
+
The FHIR Organization id associated with Inferno's simulated
|
|
30
|
+
complete prefetch CRD server. This Organization must be referenced as the
|
|
31
|
+
payer on Coverages in hook requests made to services described by the
|
|
32
|
+
`#{ClientURLs.discovery_url}` discovery endpoint.
|
|
33
|
+
The client suite may be run without this input, but it is required
|
|
34
|
+
for the tests to pass.
|
|
35
|
+
),
|
|
36
|
+
type: 'text',
|
|
37
|
+
optional: true
|
|
38
|
+
input :subset_prefetch_service_organization_id,
|
|
39
|
+
title: 'Subset Prefetch Service Organization id',
|
|
40
|
+
description: %(
|
|
41
|
+
The FHIR Organization id associated with Inferno's simulated
|
|
42
|
+
subset prefetch CRD server. This Organization must be referenced
|
|
43
|
+
payer on Coverages in hook requests made to services described by the
|
|
44
|
+
`#{ClientURLs.prefetch_subset_discovery_url}` discovery endpoint.
|
|
45
|
+
The client suite may be run without this input, but it is required
|
|
46
|
+
for the tests to pass.
|
|
47
|
+
),
|
|
48
|
+
type: 'text',
|
|
49
|
+
optional: true
|
|
50
|
+
output :attest_true_url
|
|
51
|
+
output :attest_false_url
|
|
52
|
+
|
|
53
|
+
def us_core_version
|
|
54
|
+
case suite_options[:us_core_version]
|
|
55
|
+
when CRDClientOptions::US_CORE_3
|
|
56
|
+
'v3.1.1'
|
|
57
|
+
when CRDClientOptions::US_CORE_6
|
|
58
|
+
'v6.1.0'
|
|
59
|
+
when CRDClientOptions::US_CORE_7
|
|
60
|
+
'v7.0.0'
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def us_core_version_resource_types
|
|
65
|
+
case suite_options[:us_core_version]
|
|
66
|
+
when CRDClientOptions::US_CORE_3
|
|
67
|
+
CRDClientOptions::US_CORE_3_RESOURCE_TYPES
|
|
68
|
+
when CRDClientOptions::US_CORE_6, CRDClientOptions::US_CORE_7
|
|
69
|
+
CRDClientOptions::US_CORE_6_7_RESOURCE_TYPES
|
|
70
|
+
end.join('`, `')
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
run do
|
|
74
|
+
identifier = SecureRandom.hex(32)
|
|
75
|
+
attest_true_url = "#{resume_pass_url}?token=#{identifier}"
|
|
76
|
+
attest_false_url = "#{resume_fail_url}?token=#{identifier}"
|
|
77
|
+
output(attest_true_url:)
|
|
78
|
+
output(attest_false_url:)
|
|
79
|
+
wait(
|
|
80
|
+
identifier:,
|
|
81
|
+
message: <<~MESSAGE
|
|
82
|
+
**Registration of Inferno as a trusted CRD server**:
|
|
83
|
+
|
|
84
|
+
I attest that the following Inferno CRD servers have been registered as trusted
|
|
85
|
+
within the client system:
|
|
86
|
+
|
|
87
|
+
- Complete Prefetch Service Discovery Endpoint: `#{discovery_url}`
|
|
88
|
+
- Services on this CRD server will be invoked for patients with a primary coverage issued by the payer
|
|
89
|
+
represented by the Organization resource with id `#{complete_prefetch_service_organization_id}`.
|
|
90
|
+
- The CRD server has been granted patient- or user-level read and search access scopes for
|
|
91
|
+
all US Core #{us_core_version} profiled resource types (`#{us_core_version_resource_types}`).
|
|
92
|
+
|
|
93
|
+
- Subset Prefetch Service Discovery Endpoint: `#{prefetch_subset_discovery_url}`
|
|
94
|
+
- Services on this CRD server will be invoked for patients with a primary coverage issued by the payer
|
|
95
|
+
represented by the Organization resource with id `#{subset_prefetch_service_organization_id}`.
|
|
96
|
+
- The CRD server has been granted patient- or user-level read and search access scopes for
|
|
97
|
+
all US Core #{us_core_version} profiled resource types (`#{us_core_version_resource_types}`).
|
|
98
|
+
|
|
99
|
+
[Click here](#{attest_true_url}) if the above statement is **true**.
|
|
100
|
+
|
|
101
|
+
[Click here](#{attest_false_url}) if the above statement is **false**.
|
|
102
|
+
MESSAGE
|
|
103
|
+
)
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require_relative '../../../cross_suite/requests_logical_model_validation'
|
|
2
|
+
require_relative '../../tagged_request_load_helper'
|
|
3
|
+
require_relative '../../multi_request_message_helper'
|
|
4
|
+
|
|
5
|
+
module DaVinciCRDTestKit
|
|
6
|
+
module V221
|
|
7
|
+
class HookRequestConformanceTest < Inferno::Test
|
|
8
|
+
include RequestsLogicalModelValidation
|
|
9
|
+
include DaVinciCRDTestKit::TaggedRequestLoadHelper
|
|
10
|
+
include DaVinciCRDTestKit::MultiRequestMessageHelper
|
|
11
|
+
|
|
12
|
+
id :crd_v221_hook_request_conformance
|
|
13
|
+
title 'Hook requests have the correct structure and contents'
|
|
14
|
+
description %(
|
|
15
|
+
During this test, Inferno will check each request body against the structural and content
|
|
16
|
+
requirements for the invoked hook.
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
output :url, :smart_auth_info
|
|
20
|
+
|
|
21
|
+
verifies_requirements 'cds-hooks_3.0.0-ballot@3', 'cds-hooks_3.0.0-ballot@222', 'cds-hooks_3.0.0-ballot@223',
|
|
22
|
+
'cds-hooks_3.0.0-ballot@224',
|
|
23
|
+
'hl7.fhir.us.davinci-crd_2.2.1@billopt-1', 'hl7.fhir.us.davinci-crd_2.2.1@found-36-A',
|
|
24
|
+
'hl7.fhir.us.davinci-crd_2.2.1@hook-20', 'hl7.fhir.us.davinci-crd_2.2.1@hook-21'
|
|
25
|
+
|
|
26
|
+
run do
|
|
27
|
+
hook_requests = load_hook_requests
|
|
28
|
+
|
|
29
|
+
skip_if hook_requests.blank?, "No #{hook_name} hook requests received."
|
|
30
|
+
|
|
31
|
+
hook_requests.each_with_index do |request, request_index|
|
|
32
|
+
request_body = parse_json_request_entity(request.request_body, 'Request body', request_index)
|
|
33
|
+
next unless request_body.present?
|
|
34
|
+
|
|
35
|
+
validate_request_against_logical_model(request_body, request_index, '2.2.1')
|
|
36
|
+
|
|
37
|
+
output url: request_body['fhirServer'] if request_body['fhirServer'].present?
|
|
38
|
+
if request_body.dig('fhirAuthorization', 'access_token').present?
|
|
39
|
+
output smart_auth_info: { access_token: request_body['fhirAuthorization']['access_token'] }.to_json
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
assert_no_error_messages("#{requests_with_errors_prefix}Non-conformant hook request. See Messages for details.")
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
require_relative '../../../cross_suite/tags'
|
|
2
|
+
require_relative '../../multi_request_message_helper'
|
|
3
|
+
require_relative '../../tagged_request_load_helper'
|
|
4
|
+
require_relative '../client_urls'
|
|
5
|
+
|
|
6
|
+
module DaVinciCRDTestKit
|
|
7
|
+
module V221
|
|
8
|
+
class HookRequestCoverageVerificationTest < Inferno::Test
|
|
9
|
+
include DaVinciCRDTestKit::MultiRequestMessageHelper
|
|
10
|
+
include DaVinciCRDTestKit::TaggedRequestLoadHelper
|
|
11
|
+
include ClientURLs
|
|
12
|
+
|
|
13
|
+
id :crd_v221_hook_request_coverage_verification
|
|
14
|
+
title 'Prefetched coverages are valid'
|
|
15
|
+
description %(
|
|
16
|
+
During this test, Inferno will verify that the issuing payer Organization id from the `payor` element
|
|
17
|
+
of each hook request's prefetched coverage matches the Organization id associated with the
|
|
18
|
+
invoked simulated CRD server provided by the tester during the "Registration" group.
|
|
19
|
+
Inferno also checks that the Organization resources conform to the
|
|
20
|
+
[CRD Organization](https://hl7.org/fhir/us/davinci-crd/2.2.1/en/StructureDefinition-profile-organization.html)
|
|
21
|
+
profile.
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
verifies_requirements 'hl7.fhir.us.davinci-crd_2.2.1@dev-29-A', 'hl7.fhir.us.davinci-crd_2.2.1@hook-1'
|
|
25
|
+
|
|
26
|
+
input :complete_prefetch_service_organization_id,
|
|
27
|
+
title: 'Complete Prefetch Service Organization id',
|
|
28
|
+
description: %(
|
|
29
|
+
The FHIR Organization id associated with Inferno's simulated
|
|
30
|
+
complete prefetch CRD server. This Organization must be referenced as the
|
|
31
|
+
payer on Coverages in hook requests made to services described by the `#{ClientURLs.discovery_url}`
|
|
32
|
+
discovery endpoint. The client suite may be run without this input, but it is required
|
|
33
|
+
for the tests to pass.
|
|
34
|
+
Re-run the "Registration" group to provide this detail.
|
|
35
|
+
),
|
|
36
|
+
type: 'text',
|
|
37
|
+
optional: true,
|
|
38
|
+
locked: true
|
|
39
|
+
input :subset_prefetch_service_organization_id,
|
|
40
|
+
title: 'Subset Prefetch Service Organization id',
|
|
41
|
+
description: %(
|
|
42
|
+
The FHIR Organization id associated with Inferno's simulated
|
|
43
|
+
subset prefetch CRD server. This Organization must be referenced
|
|
44
|
+
payer on Coverages in hook requests made to services described by the
|
|
45
|
+
`#{ClientURLs.prefetch_subset_discovery_url}` discovery endpoint.
|
|
46
|
+
The client suite may be run without this input, but it is required
|
|
47
|
+
for the tests to pass.
|
|
48
|
+
Re-run the "Registration" group to provide this detail.
|
|
49
|
+
),
|
|
50
|
+
type: 'text',
|
|
51
|
+
optional: true,
|
|
52
|
+
locked: true
|
|
53
|
+
|
|
54
|
+
def prefetch_target(request)
|
|
55
|
+
if request.url.include?(PREFETCH_SUBSET_PREFIX)
|
|
56
|
+
:subset
|
|
57
|
+
else
|
|
58
|
+
:complete
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def payer_org_id_for_request(request)
|
|
63
|
+
if prefetch_target(request) == :subset
|
|
64
|
+
subset_prefetch_service_organization_id
|
|
65
|
+
else
|
|
66
|
+
complete_prefetch_service_organization_id
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def load_payer_request_for_hook_request(request_body)
|
|
71
|
+
hook_data_fetch_tag = TagMethods.hook_instance_data_fetch_tag(request_body['hookInstance'])
|
|
72
|
+
load_tagged_requests(PAYER_ORG_FETCH_TAG, hook_data_fetch_tag, DATA_FETCH_TAG).first
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def check_payer_request(request_body, request_index, expected_payer_org_id)
|
|
76
|
+
payer_request = load_payer_request_for_hook_request(request_body)
|
|
77
|
+
unless payer_request.present? && payer_request.status.to_s.starts_with?('2')
|
|
78
|
+
add_request_message('error',
|
|
79
|
+
"Inferno failed to retrieve the Coverage's payer during hook processing.",
|
|
80
|
+
request_index)
|
|
81
|
+
return
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
payer_resource = FHIR.from_contents(payer_request.response_body)
|
|
85
|
+
unless payer_resource.present?
|
|
86
|
+
add_request_message('error', 'Request for payer resource returned invalid FHIR data.', request_index)
|
|
87
|
+
return
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
if payer_resource.resourceType != 'Organization'
|
|
91
|
+
add_request_message('error', 'Payer for the Coverage is not an Organization: ' \
|
|
92
|
+
"got '#{payer_resource.resourceType}'", request_index)
|
|
93
|
+
end
|
|
94
|
+
if payer_resource.id != expected_payer_org_id
|
|
95
|
+
add_request_message('error', 'Payer for the Coverage has the wrong id: ' \
|
|
96
|
+
"expected '#{expected_payer_org_id}', got '#{payer_resource.id}'.",
|
|
97
|
+
request_index)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
validator_response_details = []
|
|
101
|
+
resource_is_valid?(resource: payer_resource, profile_url: 'http://hl7.org/fhir/us/davinci-crd/StructureDefinition/profile-organization|2.2.1',
|
|
102
|
+
add_messages_to_runnable: false, validator_response_details:)
|
|
103
|
+
|
|
104
|
+
validator_response_details.each { |issue| add_request_message(issue.severity, issue.message, request_index) }
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
run do
|
|
108
|
+
hook_requests = load_hook_requests
|
|
109
|
+
|
|
110
|
+
skip_if hook_requests.blank?, "No #{hook_name} hook requests received."
|
|
111
|
+
|
|
112
|
+
hook_requests.each_with_index do |request, request_index|
|
|
113
|
+
request_body = parse_json_request_entity(request.request_body, 'Request body', request_index)
|
|
114
|
+
next unless request_body.present?
|
|
115
|
+
|
|
116
|
+
expected_payer_org_id = payer_org_id_for_request(request)
|
|
117
|
+
if expected_payer_org_id.blank?
|
|
118
|
+
add_request_message(
|
|
119
|
+
'error',
|
|
120
|
+
'No Inferno Payer Organization id configured for this endpoint; skipping required coverage check.',
|
|
121
|
+
request_index
|
|
122
|
+
)
|
|
123
|
+
next
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
coverage = prefetched_coverage(request_body)
|
|
127
|
+
unless coverage.present?
|
|
128
|
+
add_request_message('warning', 'Request has no coverage.', request_index)
|
|
129
|
+
next
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
payer_organization_reference = coverage.dig('payor', 0, 'reference')
|
|
133
|
+
if payer_organization_reference.blank?
|
|
134
|
+
add_request_message('error', 'Coverage has no payer reference.', request_index)
|
|
135
|
+
next
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
check_payer_request(request_body, request_index, expected_payer_org_id)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
assert_no_error_messages("#{requests_with_errors_prefix}Invalid coverage. " \
|
|
142
|
+
'See Messages for details.')
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def prefetched_coverage(request_body)
|
|
146
|
+
coverage = request_body.dig('prefetch', 'coverage', 'entry', 0, 'resource')
|
|
147
|
+
coverage = request_body.dig('prefetch', 'cov', 'entry', 0, 'resource') unless coverage.present?
|
|
148
|
+
coverage
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
require_relative '../../../cross_suite/tags'
|
|
2
|
+
require_relative '../../tagged_request_load_helper'
|
|
3
|
+
|
|
4
|
+
module DaVinciCRDTestKit
|
|
5
|
+
module V221
|
|
6
|
+
class HookRequestDataFetchVerificationTest < Inferno::Test
|
|
7
|
+
include DaVinciCRDTestKit::TaggedRequestLoadHelper
|
|
8
|
+
|
|
9
|
+
id :crd_v221_hook_data_fetch_verification
|
|
10
|
+
title 'Client made additional FHIR data available during hook request processing'
|
|
11
|
+
description %(
|
|
12
|
+
During this test, Inferno will verify that for at least one hook request it was successfully
|
|
13
|
+
able to use the FHIR API and access token indicated in that hook request to gather additional data during
|
|
14
|
+
hook invocation. For this test to pass, at least one additional data request across
|
|
15
|
+
all hook invocations must succeed and return a FHIR resource.
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
verifies_requirements 'hl7.fhir.us.davinci-crd_2.2.1@found-20'
|
|
19
|
+
|
|
20
|
+
def fhir_data_returned?(request)
|
|
21
|
+
return false unless request.status.to_s.starts_with?('2')
|
|
22
|
+
|
|
23
|
+
fhir_response = FHIR.from_contents(request.response_body)
|
|
24
|
+
return false unless fhir_response.present?
|
|
25
|
+
|
|
26
|
+
if fhir_response.is_a?(FHIR::Bundle)
|
|
27
|
+
fhir_response.entry.any? { |entry| entry.resource.present? }
|
|
28
|
+
else
|
|
29
|
+
true
|
|
30
|
+
end
|
|
31
|
+
rescue JSON::ParserError
|
|
32
|
+
false
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
run do
|
|
36
|
+
hook_requests = load_hook_requests
|
|
37
|
+
|
|
38
|
+
skip_if hook_requests.blank?, "No #{hook_name} hook requests received."
|
|
39
|
+
|
|
40
|
+
data_returned = hook_requests.any? do |request|
|
|
41
|
+
request_body = JSON.parse(request.request_body)
|
|
42
|
+
additional_data_requests =
|
|
43
|
+
load_tagged_requests(TagMethods.hook_instance_data_fetch_tag(request_body['hookInstance']), DATA_FETCH_TAG)
|
|
44
|
+
|
|
45
|
+
additional_data_requests.any? { |data_request| fhir_data_returned?(data_request) }
|
|
46
|
+
rescue JSON::ParserError
|
|
47
|
+
false
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
assert data_returned,
|
|
51
|
+
'Inferno was never able to successfully obtain additional FHIR data during hook processing.'
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_granted_scopes_test.rb
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
require_relative '../../multi_request_message_helper'
|
|
2
|
+
require_relative '../../crd_client_options'
|
|
3
|
+
require_relative '../../tagged_request_load_helper'
|
|
4
|
+
|
|
5
|
+
module DaVinciCRDTestKit
|
|
6
|
+
module V221
|
|
7
|
+
class HookRequestGrantedScopesTest < Inferno::Test
|
|
8
|
+
include DaVinciCRDTestKit::MultiRequestMessageHelper
|
|
9
|
+
include DaVinciCRDTestKit::TaggedRequestLoadHelper
|
|
10
|
+
|
|
11
|
+
id :crd_v221_hook_request_granted_scopes
|
|
12
|
+
title 'Hook requests grant the requested scopes'
|
|
13
|
+
description %(
|
|
14
|
+
As a part of registration, CRD clients and servers agree on a set of scopes that the server needs
|
|
15
|
+
to obtain all data that goes into creating hook responses. For the purposes of simulating a
|
|
16
|
+
payer CRD server acting as a part of these tests that evaluate conformance to the CRD specification,
|
|
17
|
+
Inferno requires access to all US Core resource types. While in a real exchange scenario, a CRD client
|
|
18
|
+
organization might well reject such a set of scopes as too large, for the purposes of testing, the client
|
|
19
|
+
must grant these scopes in order for Inferno to verify its conformance.
|
|
20
|
+
|
|
21
|
+
During this test, Inferno will verify that the requested scopes covering all resource types profiled in
|
|
22
|
+
the selected version of the US Core IG are granted and no more. Clients may choose to grant either user scopes
|
|
23
|
+
or patient scopes. If choosing patient scopes, note that the token is used by default for complete testing
|
|
24
|
+
of the client's US Core FHIR API, so either that single patient would need to
|
|
25
|
+
demonstrate all US Core resources and must support elements or another access token would need
|
|
26
|
+
to be provided when testing the client's FHIR API.
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
verifies_requirements 'hl7.fhir.us.davinci-crd_2.2.1@found-21'
|
|
30
|
+
|
|
31
|
+
run do
|
|
32
|
+
hook_requests = load_hook_requests
|
|
33
|
+
|
|
34
|
+
skip_if hook_requests.blank?, "No #{hook_name} hook requests received."
|
|
35
|
+
|
|
36
|
+
hook_requests.each_with_index do |request, request_index|
|
|
37
|
+
request_body = parse_json_request_entity(request.request_body, 'Request body', request_index)
|
|
38
|
+
next unless request_body.present?
|
|
39
|
+
|
|
40
|
+
# check that the resource scopes match what Inferno requested
|
|
41
|
+
granted_resource_scopes = granted_resource_scopes(request_body)
|
|
42
|
+
check_granted_resources(granted_resource_scopes, request_index)
|
|
43
|
+
check_granted_scopes_level(granted_resource_scopes, request_index)
|
|
44
|
+
check_granted_interactions(granted_resource_scopes, request_index)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
assert_no_error_messages("#{requests_with_errors_prefix}Granted scopes do not match the requested scopes. " \
|
|
48
|
+
'See Messages for details.')
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def requested_scope_resources
|
|
52
|
+
case suite_options[:us_core_version]
|
|
53
|
+
when CRDClientOptions::US_CORE_3
|
|
54
|
+
CRDClientOptions::US_CORE_3_RESOURCE_TYPES
|
|
55
|
+
when CRDClientOptions::US_CORE_6, CRDClientOptions::US_CORE_7
|
|
56
|
+
CRDClientOptions::US_CORE_6_7_RESOURCE_TYPES
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def granted_resource_scopes(request_body)
|
|
61
|
+
granted_scopes = request_body.dig('fhirAuthorization', 'scope')
|
|
62
|
+
return [] unless granted_scopes.present?
|
|
63
|
+
|
|
64
|
+
granted_scopes.split(' ').grep(%r{\A\S+/\S+\.\S+\z}) # rubocop:disable Style/RedundantArgument
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def check_granted_resources(granted_resource_scopes, request_index)
|
|
68
|
+
granted_scope_resources = granted_resource_scopes.map { |scope| scope.split('/').last.split('.').first }
|
|
69
|
+
|
|
70
|
+
missing_resources = requested_scope_resources - granted_scope_resources
|
|
71
|
+
extra_resources = granted_scope_resources - requested_scope_resources
|
|
72
|
+
if missing_resources.present?
|
|
73
|
+
add_request_message('error', 'Granted scopes missing the following ' \
|
|
74
|
+
"requested resource types: #{missing_resources.join(', ')}", request_index)
|
|
75
|
+
end
|
|
76
|
+
return unless extra_resources.present?
|
|
77
|
+
|
|
78
|
+
add_request_message('error', 'Granted scopes included the following resource types ' \
|
|
79
|
+
"beyond what was requested: #{extra_resources.join(', ')}", request_index)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def check_granted_interactions(granted_resource_scopes, request_index)
|
|
83
|
+
return if granted_resource_scopes.all? { |scope| scope.split('.').last == 'rs' }
|
|
84
|
+
|
|
85
|
+
if granted_resource_scopes.all? { |scope| scope.split('.').last == 'read' }
|
|
86
|
+
add_request_message('warning',
|
|
87
|
+
'SMART v1 `read` scope used. Use of SMART v2 `rs` scope recommended.',
|
|
88
|
+
request_index)
|
|
89
|
+
return
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
add_request_message('error', 'Some granted resource scopes do not provide ' \
|
|
93
|
+
"requested 'rs' (read and search) interactions.", request_index)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def check_granted_scopes_level(granted_resource_scopes, request_index)
|
|
97
|
+
level = scopes_level(granted_resource_scopes)
|
|
98
|
+
if level.blank?
|
|
99
|
+
add_request_message('error',
|
|
100
|
+
'Requested scopes did not use a consistent level of scope (patient or user).',
|
|
101
|
+
request_index)
|
|
102
|
+
return
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
return if ['user', 'patient'].include?(level)
|
|
106
|
+
|
|
107
|
+
add_request_message('error',
|
|
108
|
+
"Unexpected level for granted scopes: expected 'user' or 'patient', got '#{level}'.",
|
|
109
|
+
request_index)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def scopes_level(granted_resource_scopes)
|
|
113
|
+
return nil unless granted_resource_scopes.present? && all_scopes_same_level?(granted_resource_scopes)
|
|
114
|
+
|
|
115
|
+
granted_resource_scopes.first.split('/').first
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def all_scopes_same_level?(granted_resource_scopes)
|
|
119
|
+
granted_resource_scopes.map { |s| s.split('/').first }.uniq.size <= 1
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_prefetch_complete_test.rb
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
require_relative '../../../cross_suite/prefetch_completeness_checker'
|
|
2
|
+
require_relative '../../tagged_request_load_helper'
|
|
3
|
+
require_relative '../../multi_request_message_helper'
|
|
4
|
+
require_relative '../client_urls'
|
|
5
|
+
|
|
6
|
+
module DaVinciCRDTestKit
|
|
7
|
+
module V221
|
|
8
|
+
class HookRequestPrefetchCompleteTest < Inferno::Test
|
|
9
|
+
include DaVinciCRDTestKit::TaggedRequestLoadHelper
|
|
10
|
+
include DaVinciCRDTestKit::MultiRequestMessageHelper
|
|
11
|
+
|
|
12
|
+
id :crd_v221_hook_request_prefetch_complete
|
|
13
|
+
title 'Hook requests include the requested prefetch data'
|
|
14
|
+
description %(
|
|
15
|
+
The [CDS service discovery response `prefetch` field](https://cds-hooks.hl7.org/2026Jan/en/#response)
|
|
16
|
+
contains key/value pairs describing additional information needed to render a response. Each key is a
|
|
17
|
+
string that describes the type of data being requested and the corresponding
|
|
18
|
+
value is a FHIR query (read or search) that will return the desired scope.
|
|
19
|
+
See the [Prefetch Template](https://cds-hooks.hl7.org/2026Jan/en/#prefetch-template)
|
|
20
|
+
section for more information about the format of `prefetch` templates.
|
|
21
|
+
|
|
22
|
+
[The CRD IG requires client support for prefetch](https://hl7.org/fhir/us/davinci-crd/2.2.1/en/foundation.html#prefetch)
|
|
23
|
+
including the ability to provide all data in and subsets of the [standard prefetch templates](https://hl7.org/fhir/us/davinci-crd/2.2.1/en/foundation.html#standard-prefetch),
|
|
24
|
+
when they are requested by the invoked CRD server. Inferno simulates two CRD servers,
|
|
25
|
+
one at `#{ClientURLs.discovery_url}` requiring the [complete set of standard prefetches](https://github.com/inferno-framework/davinci-crd-test-kit/blob/main/lib/davinci_crd_test_kit/client/v2.2.1/cds-services-v221.json)
|
|
26
|
+
and the other at `#{ClientURLs.prefetch_subset_discovery_url}`
|
|
27
|
+
[requesting a subset of the standard prefetch data set](https://github.com/inferno-framework/davinci-crd-test-kit/blob/main/lib/davinci_crd_test_kit/client/v2.2.1/cds-services-prefetch-subset-v221.json).
|
|
28
|
+
|
|
29
|
+
During this test, Inferno will verify that each hook request body includes a `prefetch` field populated with
|
|
30
|
+
valid JSON that contains exactly the requested prefetch keys and data sets described in the service description
|
|
31
|
+
for the invoked service as calculated by Inferno based on the resources provided in the request.
|
|
32
|
+
)
|
|
33
|
+
verifies_requirements 'cds-hooks_3.0.0-ballot@30', 'cds-hooks_3.0.0-ballot@231', 'cds-hooks_3.0.0-ballot@45',
|
|
34
|
+
'cds-hooks_3.0.0-ballot@46', 'cds-hooks_3.0.0-ballot@47', 'cds-hooks_3.0.0-ballot@232',
|
|
35
|
+
'cds-hooks_3.0.0-ballot@53', 'cds-hooks_3.0.0-ballot@240',
|
|
36
|
+
'hl7.fhir.us.davinci-crd_2.2.1@dev-29-A', 'hl7.fhir.us.davinci-crd_2.2.1@found-23',
|
|
37
|
+
'hl7.fhir.us.davinci-crd_2.2.1@found-24', 'hl7.fhir.us.davinci-crd_2.2.1@found-25-A',
|
|
38
|
+
'hl7.fhir.us.davinci-crd_2.2.1@found-25-B', 'hl7.fhir.us.davinci-crd_2.2.1@found-31'
|
|
39
|
+
|
|
40
|
+
# output emitted only if the behavior is detected
|
|
41
|
+
output :demonstrates_fhirpath_collection_as_comma_delimited_string,
|
|
42
|
+
:demonstrates_prefetch_subset_distinct_from_complete,
|
|
43
|
+
:demonstrates_prefetch_complete_distinct_from_subset
|
|
44
|
+
|
|
45
|
+
SERVICE_FILENAMES = {
|
|
46
|
+
complete: 'cds-services-v221.json',
|
|
47
|
+
subset: 'cds-services-prefetch-subset-v221.json'
|
|
48
|
+
}.freeze
|
|
49
|
+
|
|
50
|
+
def service_path_for_target(target)
|
|
51
|
+
File.join(__dir__, '..', SERVICE_FILENAMES[target])
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def service_path_for_opposite(target)
|
|
55
|
+
opposite = target == :complete ? :subset : :complete
|
|
56
|
+
service_path_for_target(opposite)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
PREFETCH_KEY_COMPARISON_MAP = {
|
|
60
|
+
'patient' => 'pat',
|
|
61
|
+
'encounter' => 'enc',
|
|
62
|
+
'coverage' => 'cov',
|
|
63
|
+
'communicationRequests' => 'comReqs',
|
|
64
|
+
'deviceRequests' => 'devReqs',
|
|
65
|
+
'medicationRequests' => 'medReqs',
|
|
66
|
+
'nutritionOrders' => 'nutOrds',
|
|
67
|
+
'serviceRequests' => 'servReqs',
|
|
68
|
+
'visionPrescriptions' => 'visRxs',
|
|
69
|
+
'devices' => 'devs',
|
|
70
|
+
'medications' => 'meds',
|
|
71
|
+
'practitionerRoles' => 'roles',
|
|
72
|
+
'practitioners' => 'pracs',
|
|
73
|
+
'organizations' => 'orgs',
|
|
74
|
+
'locations' => 'locs'
|
|
75
|
+
}.freeze
|
|
76
|
+
|
|
77
|
+
def key_comparison_map_for_target(target)
|
|
78
|
+
if target == :complete
|
|
79
|
+
PREFETCH_KEY_COMPARISON_MAP.invert
|
|
80
|
+
else
|
|
81
|
+
PREFETCH_KEY_COMPARISON_MAP
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
run do
|
|
86
|
+
hook_requests = load_hook_requests
|
|
87
|
+
|
|
88
|
+
skip_if hook_requests.blank?, "No #{hook_name} hook requests received."
|
|
89
|
+
|
|
90
|
+
hook_requests.each_with_index do |request, request_index|
|
|
91
|
+
hook_request = parse_json_request_entity(request.request_body, 'Request body', request_index)
|
|
92
|
+
next unless hook_request.present?
|
|
93
|
+
|
|
94
|
+
prefetch_target = if request.url.include?(PREFETCH_SUBSET_PREFIX)
|
|
95
|
+
:subset
|
|
96
|
+
else
|
|
97
|
+
:complete
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
services_path = service_path_for_target(prefetch_target)
|
|
101
|
+
checker = PrefetchCompletenessChecker.new(hook_request, request_index, services_path)
|
|
102
|
+
completeness_errors = checker.check_prefetched_data
|
|
103
|
+
completeness_errors.each do |error|
|
|
104
|
+
add_message('error', error) # NOTE: PrefetchCompletenessChecker adds the (Request #) prefix
|
|
105
|
+
end
|
|
106
|
+
if checker.observed_fhirpath_collection_as_comma_delimited_string
|
|
107
|
+
output demonstrates_fhirpath_collection_as_comma_delimited_string: true
|
|
108
|
+
end
|
|
109
|
+
if completeness_errors.blank? &&
|
|
110
|
+
checker.data_set_different_with_alternate_service?(
|
|
111
|
+
service_path_for_opposite(prefetch_target),
|
|
112
|
+
key_comparison_map_for_target(prefetch_target)
|
|
113
|
+
)
|
|
114
|
+
if prefetch_target == :subset
|
|
115
|
+
output demonstrates_prefetch_subset_distinct_from_complete: true
|
|
116
|
+
else
|
|
117
|
+
output demonstrates_prefetch_complete_distinct_from_subset: true
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
assert_no_error_messages("#{requests_with_errors_prefix}Incomplete or invalid prefetched data. " \
|
|
123
|
+
'See Messages for details.')
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_prefetch_profiles_test.rb
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
require_relative '../../../cross_suite/prefetch_profile_validation'
|
|
2
|
+
require_relative '../../tagged_request_load_helper'
|
|
3
|
+
require_relative '../../multi_request_message_helper'
|
|
4
|
+
|
|
5
|
+
module DaVinciCRDTestKit
|
|
6
|
+
module V221
|
|
7
|
+
class HookRequestPrefetchProfilesTest < Inferno::Test
|
|
8
|
+
include PrefetchProfileValidation
|
|
9
|
+
include DaVinciCRDTestKit::TaggedRequestLoadHelper
|
|
10
|
+
include DaVinciCRDTestKit::MultiRequestMessageHelper
|
|
11
|
+
|
|
12
|
+
id :crd_v221_hook_request_prefetch_profiles
|
|
13
|
+
title 'Prefetched resources conform to the required CRD profiles'
|
|
14
|
+
description %(
|
|
15
|
+
The [CDS service discovery response `prefetch` field](https://cds-hooks.hl7.org/2026Jan/en/#response)
|
|
16
|
+
contains key/value pairs describing additional information needed to render a response. Each key is a
|
|
17
|
+
string that describes the type of data being requested and the corresponding
|
|
18
|
+
value is a FHIR query (read or search) that will return the desired scope.
|
|
19
|
+
See the [Prefetch Template](https://cds-hooks.hl7.org/2026Jan/en/#prefetch-template)
|
|
20
|
+
section for more information about the format of `prefetch` templates.
|
|
21
|
+
|
|
22
|
+
[The CRD IG requires client support for prefetch](https://hl7.org/fhir/us/davinci-crd/2.2.1/en/foundation.html#prefetch)
|
|
23
|
+
including that the provided resources, which are part of the data included in the hook invocation,
|
|
24
|
+
[conform to the appropriate CRD profile](https://hl7.org/fhir/us/davinci-crd/2.2.1/en/hooks.html#ci-c-hook-21).
|
|
25
|
+
|
|
26
|
+
During this test, Inferno will verify that each FHIR resources found under the `prefetch`
|
|
27
|
+
field of each request body conforms to the appropriate CRD profile.
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
verifies_requirements 'hl7.fhir.us.davinci-crd_2.2.1@hook-21', 'hl7.fhir.us.davinci-crd_2.2.1@prof-3',
|
|
31
|
+
'hl7.fhir.us.davinci-crd_2.2.1@prof-4', 'hl7.fhir.us.davinci-crd_2.2.1@prof-5',
|
|
32
|
+
'hl7.fhir.us.davinci-crd_2.2.1@prof-6', 'hl7.fhir.us.davinci-crd_2.2.1@prof-7',
|
|
33
|
+
'hl7.fhir.us.davinci-crd_2.2.1@prof-8', 'hl7.fhir.us.davinci-crd_2.2.1@prof-9',
|
|
34
|
+
'hl7.fhir.us.davinci-crd_2.2.1@prof-10', 'hl7.fhir.us.davinci-crd_2.2.1@prof-11',
|
|
35
|
+
'hl7.fhir.us.davinci-crd_2.2.1@prof-12'
|
|
36
|
+
run do
|
|
37
|
+
hook_requests = load_hook_requests
|
|
38
|
+
|
|
39
|
+
skip_if hook_requests.blank?, "No #{hook_name} hook requests received."
|
|
40
|
+
|
|
41
|
+
hook_requests.each_with_index do |request, request_index|
|
|
42
|
+
hook_request = parse_json_request_entity(request.request_body, 'Request body',
|
|
43
|
+
request_index)
|
|
44
|
+
next unless hook_request.present?
|
|
45
|
+
next unless hook_request.key?('prefetch')
|
|
46
|
+
|
|
47
|
+
check_prefetch_profiles(hook_request['prefetch'], request_index)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
assert_no_error_messages("#{requests_with_errors_prefix}Prefetched data not conformant to CRD profiles. " \
|
|
51
|
+
'See Messages for details.')
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|