davinci_crd_test_kit 0.12.2 → 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 +59 -2
- 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 +308 -101
- data/lib/davinci_crd_test_kit/client_fhir_api_group.rb +0 -785
- data/lib/davinci_crd_test_kit/client_hooks_group.rb +0 -75
- 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 -41
- data/lib/davinci_crd_test_kit/client_tests/client_fhir_api_read_test.rb +0 -39
- 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 -41
- data/lib/davinci_crd_test_kit/client_tests/client_fhir_api_validation_test.rb +0 -60
- 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 -44
- 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 -185
- 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
|
@@ -1,12 +1,12 @@
|
|
|
1
|
+
require_relative 'requests_logical_model_validation'
|
|
2
|
+
require_relative '../server/server_base_urls'
|
|
3
|
+
require_relative 'profiles_and_resource_types'
|
|
4
|
+
|
|
1
5
|
module DaVinciCRDTestKit
|
|
2
6
|
module HookRequestFieldValidation
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
else
|
|
7
|
-
"Request #{@request_number}: "
|
|
8
|
-
end
|
|
9
|
-
end
|
|
7
|
+
include RequestsLogicalModelValidation
|
|
8
|
+
include ServerBaseURLs
|
|
9
|
+
include ProfilesAndResourceTypes
|
|
10
10
|
|
|
11
11
|
def json_parse(json)
|
|
12
12
|
JSON.parse(json)
|
|
@@ -15,6 +15,115 @@ module DaVinciCRDTestKit
|
|
|
15
15
|
false
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
+
def hook_request_required_fields_check(request_body, hook_name, ig_version: 'v201') # rubocop:disable Lint/UnusedMethodArgument
|
|
19
|
+
hook_request_required_fields_check_presence_and_types(request_body)
|
|
20
|
+
|
|
21
|
+
if request_body['hook'] != hook_name
|
|
22
|
+
add_message('error',
|
|
23
|
+
"#{request_number}The `hook` field should be #{hook_name}, but was #{request_body['hook']}")
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
if request_body['fhirAuthorization'].present? && request_body['fhirServer'].blank?
|
|
27
|
+
add_message('error', %(
|
|
28
|
+
#{request_number}Missing `fhirServer` field: If `fhirAuthorization` is provided, this field is
|
|
29
|
+
#REQUIRED.))
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
return unless request_body['hookInstance'].present? && !guid?(request_body['hookInstance'])
|
|
33
|
+
|
|
34
|
+
add_message('error', "#{request_number}`hookInstance` field must be a globally unique UUID.")
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def hook_request_optional_fields_check(request_body, ig_version: 'v201') # rubocop:disable Lint/UnusedMethodArgument
|
|
38
|
+
hook_request_optional_fields_check_type(request_body)
|
|
39
|
+
|
|
40
|
+
defined_fields = hook_required_fields.keys + hook_optional_fields.keys
|
|
41
|
+
request_body.keys.reject { |field| defined_fields.include?(field) }.each do |field|
|
|
42
|
+
if request_body[field].blank?
|
|
43
|
+
add_message('error', "#{request_number}Hook request field `#{field}` cannot be defined but blank.")
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
hook_request_fhir_auth_check(request_body)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def hook_request_context_check(context, hook_name, ig_version: 'v201')
|
|
51
|
+
required_fields =
|
|
52
|
+
if hook_name == 'order-dispatch'
|
|
53
|
+
context_required_order_dispatch_fields[ig_version]
|
|
54
|
+
else
|
|
55
|
+
context_required_fields_by_hook[hook_name]
|
|
56
|
+
end
|
|
57
|
+
required_fields.each do |field, type|
|
|
58
|
+
validate_presence_and_type(context, field, type,
|
|
59
|
+
"#{request_number}#{hook_name} request context")
|
|
60
|
+
end
|
|
61
|
+
context_validate_optional_fields(context, hook_name, ig_version:)
|
|
62
|
+
hook_specific_context_check(context, hook_name, ig_version:)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def hook_request_prefetch_check(advertised_prefetch_fields, received_prefetch, received_context, ig_version: 'v201')
|
|
66
|
+
received_prefetch.each do |received_prefetch_key, received_prefetch_hash|
|
|
67
|
+
unless advertised_prefetch_fields.key?(received_prefetch_key)
|
|
68
|
+
add_message('error', "#{request_number}Client sent non-requested Prefetch field `#{received_prefetch_key}`.")
|
|
69
|
+
next
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
unless received_prefetch_hash.is_a?(Hash)
|
|
73
|
+
add_message('error', "#{request_number}Prefetch field `#{received_prefetch_key}` is not of type `Hash`.")
|
|
74
|
+
next
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
received_prefetch_resource = FHIR.from_contents(received_prefetch[received_prefetch_key].to_json)
|
|
78
|
+
advertised_prefetch_template = advertised_prefetch_fields[received_prefetch_key]
|
|
79
|
+
if advertised_prefetch_template.include?('?')
|
|
80
|
+
advertised_prefetch_fhir_search = advertised_prefetch_template.gsub(/{|}/, '').split('?')
|
|
81
|
+
advertised_prefetch_resource_type = advertised_prefetch_fhir_search.first
|
|
82
|
+
|
|
83
|
+
if advertised_prefetch_resource_type == 'Coverage'
|
|
84
|
+
advertised_coverage_query_params = Rack::Utils.parse_nested_query(advertised_prefetch_fhir_search.last)
|
|
85
|
+
|
|
86
|
+
advertised_patient_token = advertised_coverage_query_params['patient']
|
|
87
|
+
advertised_context_patient_id_key = advertised_patient_token.split('.').last
|
|
88
|
+
received_context_patient_id = received_context[advertised_context_patient_id_key]
|
|
89
|
+
|
|
90
|
+
advertised_status_param = advertised_coverage_query_params['status']
|
|
91
|
+
|
|
92
|
+
validate_prefetch_coverages(received_prefetch_resource, received_prefetch_key, received_context_patient_id,
|
|
93
|
+
advertised_status_param, ig_version:)
|
|
94
|
+
end
|
|
95
|
+
else
|
|
96
|
+
advertised_prefetch_token = advertised_prefetch_template.gsub(/{|}/, '').split('/')
|
|
97
|
+
advertised_context_id = advertised_prefetch_token.last.split('.').last
|
|
98
|
+
|
|
99
|
+
if advertised_prefetch_token.length == 1
|
|
100
|
+
received_context_reference = FHIR::Reference.new(reference: received_context[advertised_context_id])
|
|
101
|
+
received_context_resource_type = received_context_reference.resource_type
|
|
102
|
+
received_context_id = received_context_reference.reference_id
|
|
103
|
+
else
|
|
104
|
+
received_context_id = received_context[advertised_context_id]
|
|
105
|
+
received_context_resource_type = advertised_prefetch_token.first
|
|
106
|
+
end
|
|
107
|
+
validate_prefetch_resource(received_prefetch_resource, received_prefetch_key,
|
|
108
|
+
received_context_resource_type, received_context_id, ig_version:)
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def no_error_validation(message)
|
|
114
|
+
assert messages.none? { |msg| msg[:type] == 'error' }, message
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
private
|
|
118
|
+
|
|
119
|
+
def request_number
|
|
120
|
+
if @request_number.blank?
|
|
121
|
+
''
|
|
122
|
+
else
|
|
123
|
+
"Request #{@request_number}: "
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
18
127
|
def hook_required_fields
|
|
19
128
|
{
|
|
20
129
|
'hook' => String,
|
|
@@ -51,16 +160,28 @@ module DaVinciCRDTestKit
|
|
|
51
160
|
'encounter-start' => common_context_fields.merge('encounterId' => String),
|
|
52
161
|
'encounter-discharge' => common_context_fields.merge('encounterId' => String),
|
|
53
162
|
'order-select' => common_context_fields.merge('selections' => Array, 'draftOrders' => Hash),
|
|
54
|
-
'order-dispatch' => { 'patientId' => String, 'order' => String, 'performer' => String },
|
|
55
163
|
'order-sign' => common_context_fields.merge('draftOrders' => Hash)
|
|
56
164
|
}.freeze
|
|
57
165
|
end
|
|
58
166
|
|
|
167
|
+
def context_required_order_dispatch_fields
|
|
168
|
+
{
|
|
169
|
+
'v201' => { 'patientId' => String, 'order' => String, 'performer' => String },
|
|
170
|
+
'v221' => { 'patientId' => String, 'dispatchedOrders' => Array, 'performer' => String }
|
|
171
|
+
}
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def context_optional_order_dispatch_fields
|
|
175
|
+
{
|
|
176
|
+
'v201' => { 'task' => Hash },
|
|
177
|
+
'v221' => { 'fulfillmentTasks' => Array }
|
|
178
|
+
}
|
|
179
|
+
end
|
|
180
|
+
|
|
59
181
|
def context_optional_fields_by_hook
|
|
60
182
|
{
|
|
61
183
|
'appointment-book' => { 'encounterId' => String },
|
|
62
184
|
'order-select' => { 'encounterId' => String },
|
|
63
|
-
'order-dispatch' => { 'task' => Hash },
|
|
64
185
|
'order-sign' => { 'encounterId' => String }
|
|
65
186
|
}.freeze
|
|
66
187
|
end
|
|
@@ -82,29 +203,7 @@ module DaVinciCRDTestKit
|
|
|
82
203
|
}.freeze
|
|
83
204
|
end
|
|
84
205
|
|
|
85
|
-
def
|
|
86
|
-
{
|
|
87
|
-
'Practitioner' => 'http://hl7.org/fhir/us/davinci-crd/StructureDefinition/profile-practitioner',
|
|
88
|
-
'PractitionerRole' => 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-practitionerrole',
|
|
89
|
-
'Patient' => 'http://hl7.org/fhir/us/davinci-crd/StructureDefinition/profile-patient',
|
|
90
|
-
'Encounter' => 'http://hl7.org/fhir/us/davinci-crd/StructureDefinition/profile-encounter',
|
|
91
|
-
'Appointment' => 'http://hl7.org/fhir/us/davinci-crd/StructureDefinition/profile-appointment',
|
|
92
|
-
'DeviceRequest' => 'http://hl7.org/fhir/us/davinci-crd/StructureDefinition/profile-devicerequest',
|
|
93
|
-
'MedicationRequest' => 'http://hl7.org/fhir/us/davinci-crd/StructureDefinition/profile-medicationrequest',
|
|
94
|
-
'NutritionOrder' => 'http://hl7.org/fhir/us/davinci-crd/StructureDefinition/profile-nutritionorder',
|
|
95
|
-
'ServiceRequest' => 'http://hl7.org/fhir/us/davinci-crd/StructureDefinition/profile-servicerequest',
|
|
96
|
-
'VisionPrescription' => 'http://hl7.org/fhir/us/davinci-crd/StructureDefinition/profile-visionprescription',
|
|
97
|
-
'Medication' => 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-medication',
|
|
98
|
-
'Device' => 'http://hl7.org/fhir/us/davinci-crd/StructureDefinition/profile-device',
|
|
99
|
-
'CommunicationRequest' => 'http://hl7.org/fhir/us/davinci-crd/StructureDefinition/profile-communicationrequest',
|
|
100
|
-
'Task' => 'http://hl7.org/fhir/us/davinci-crd/StructureDefinition/profile-taskquestionnaire',
|
|
101
|
-
'Coverage' => 'http://hl7.org/fhir/us/davinci-crd/StructureDefinition/profile-coverage',
|
|
102
|
-
'Location' => 'http://hl7.org/fhir/us/davinci-crd/StructureDefinition/profile-location',
|
|
103
|
-
'Organization' => 'http://hl7.org/fhir/us/davinci-crd/StructureDefinition/profile-organization'
|
|
104
|
-
}.freeze
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
def hook_request_required_fields_check(request_body, hook_name)
|
|
206
|
+
def hook_request_required_fields_check_presence_and_types(request_body)
|
|
108
207
|
hook_required_fields.each do |field, type|
|
|
109
208
|
if request_body[field].blank?
|
|
110
209
|
add_message('error', "#{request_number}Hook request did not contain required field: `#{field}`")
|
|
@@ -112,22 +211,10 @@ module DaVinciCRDTestKit
|
|
|
112
211
|
end
|
|
113
212
|
|
|
114
213
|
unless request_body[field].is_a?(type)
|
|
115
|
-
add_message('error', "#{request_number}Hook request field
|
|
214
|
+
add_message('error', "#{request_number}Hook request field `#{field}` is not of type #{type}")
|
|
116
215
|
next
|
|
117
216
|
end
|
|
118
217
|
end
|
|
119
|
-
|
|
120
|
-
if request_body['hook'] != hook_name
|
|
121
|
-
add_message('error',
|
|
122
|
-
"#{request_number}The `hook` field should be #{hook_name}, but was #{request_body['hook']}")
|
|
123
|
-
return
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
return unless request_body['fhirAuthorization'].present? && request_body['fhirServer'].blank?
|
|
127
|
-
|
|
128
|
-
add_message('error', %(
|
|
129
|
-
#{request_number}Missing `fhirServer` field: If `fhirAuthorization` is provided, this field is
|
|
130
|
-
#REQUIRED.))
|
|
131
218
|
end
|
|
132
219
|
|
|
133
220
|
def fhir_auth_fields_valid?(fhir_authorization_required_fields, fhir_authorization)
|
|
@@ -138,10 +225,18 @@ module DaVinciCRDTestKit
|
|
|
138
225
|
fhir_auth_valid = false
|
|
139
226
|
end
|
|
140
227
|
unless fhir_authorization[field].is_a?(type)
|
|
141
|
-
add_message('error', "#{request_number}`fhirAuthorization` field
|
|
228
|
+
add_message('error', "#{request_number}`fhirAuthorization` field `#{field}` is not of type #{type}")
|
|
229
|
+
fhir_auth_valid = false
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
fhir_authorization.keys.reject { |field| fhir_authorization_required_fields.key?(field) }.each do |field|
|
|
234
|
+
if fhir_authorization[field].blank?
|
|
235
|
+
add_message('error', "#{request_number}`fhirAuthorization` field `#{field}` cannot be defined but blank.")
|
|
142
236
|
fhir_auth_valid = false
|
|
143
237
|
end
|
|
144
238
|
end
|
|
239
|
+
|
|
145
240
|
fhir_auth_valid
|
|
146
241
|
end
|
|
147
242
|
|
|
@@ -174,20 +269,25 @@ module DaVinciCRDTestKit
|
|
|
174
269
|
{ fhir_server_uri: request_body['fhirServer'], fhir_access_token: access_token }
|
|
175
270
|
end
|
|
176
271
|
|
|
177
|
-
def
|
|
272
|
+
def hook_request_optional_fields_check_type(request_body)
|
|
178
273
|
hook_optional_fields.each do |field, type|
|
|
179
|
-
|
|
274
|
+
if request_body[field].blank?
|
|
275
|
+
if request_body.key?(field)
|
|
276
|
+
add_message('error', "#{request_number}Hook request field `#{field}` cannot be defined but blank.")
|
|
277
|
+
else
|
|
278
|
+
info "#{request_number}Hook request did not contain optional field: `#{field}`"
|
|
279
|
+
end
|
|
280
|
+
end
|
|
180
281
|
|
|
181
282
|
if request_body[field] && !request_body[field].is_a?(type)
|
|
182
|
-
add_message('error', "#{request_number}Hook request field
|
|
283
|
+
add_message('error', "#{request_number}Hook request field `#{field}` is not of type #{type}")
|
|
183
284
|
end
|
|
184
285
|
end
|
|
185
|
-
hook_request_fhir_auth_check(request_body)
|
|
186
286
|
end
|
|
187
287
|
|
|
188
|
-
def validate_presence_and_type(object, field_name, type, description = '')
|
|
288
|
+
def validate_presence_and_type(object, field_name, type, description = '', required: true)
|
|
189
289
|
value = object[field_name]
|
|
190
|
-
|
|
290
|
+
if required && !value
|
|
191
291
|
error_msg = "#{description} does not contain required field `#{field_name}`: #{description} `#{object}`."
|
|
192
292
|
add_message('error', error_msg)
|
|
193
293
|
return
|
|
@@ -197,44 +297,33 @@ module DaVinciCRDTestKit
|
|
|
197
297
|
unless is_valid_type
|
|
198
298
|
error_msg = type == 'URL' ? 'is not a valid URL' : "is not of type `#{type}`"
|
|
199
299
|
add_message('error', "#{description} field `#{field_name}` #{error_msg}: #{description} `#{object}`.")
|
|
200
|
-
return
|
|
201
300
|
end
|
|
202
301
|
|
|
203
|
-
return
|
|
302
|
+
return if value.present?
|
|
204
303
|
|
|
205
304
|
error_msg = "#{description} field `#{field_name}` should not be an empty #{type}: #{description} `#{object}`."
|
|
206
305
|
add_message('error', error_msg)
|
|
207
306
|
end
|
|
208
307
|
|
|
209
|
-
def
|
|
210
|
-
required_fields = context_required_fields_by_hook[hook_name]
|
|
211
|
-
required_fields.each do |field, type|
|
|
212
|
-
validate_presence_and_type(context, field, type,
|
|
213
|
-
"#{request_number}#{hook_name} request context")
|
|
214
|
-
end
|
|
215
|
-
context_validate_optional_fields(context, hook_name)
|
|
216
|
-
hook_specific_context_check(context, hook_name)
|
|
217
|
-
end
|
|
218
|
-
|
|
219
|
-
def hook_specific_context_check(context, hook_name)
|
|
308
|
+
def hook_specific_context_check(context, hook_name, ig_version: 'v201')
|
|
220
309
|
case hook_name
|
|
221
310
|
when 'appointment-book'
|
|
222
|
-
appointment_book_context_check(context)
|
|
311
|
+
appointment_book_context_check(context, ig_version:)
|
|
223
312
|
when 'encounter-start', 'encounter-discharge'
|
|
224
|
-
encounter_start_or_discharge_context_check(context, hook_name)
|
|
313
|
+
encounter_start_or_discharge_context_check(context, hook_name, ig_version:)
|
|
225
314
|
when 'order-select', 'order-sign'
|
|
226
|
-
order_select_or_sign_context_check(context, hook_name)
|
|
315
|
+
order_select_or_sign_context_check(context, hook_name, ig_version:)
|
|
227
316
|
when 'order-dispatch'
|
|
228
|
-
order_dispatch_context_check(context)
|
|
317
|
+
order_dispatch_context_check(context, ig_version:)
|
|
229
318
|
end
|
|
230
319
|
end
|
|
231
320
|
|
|
232
|
-
def hook_user_type_check(context, hook_name)
|
|
321
|
+
def hook_user_type_check(context, hook_name, ig_version: 'v201')
|
|
233
322
|
supported_resource_types = context_user_types_by_hook[hook_name]
|
|
234
|
-
resource_reference_check(context['userId'], 'userId', supported_resource_types:)
|
|
323
|
+
resource_reference_check(context['userId'], 'userId', supported_resource_types:, ig_version:)
|
|
235
324
|
end
|
|
236
325
|
|
|
237
|
-
def resource_reference_check(reference, field_name, supported_resource_types: nil)
|
|
326
|
+
def resource_reference_check(reference, field_name, supported_resource_types: nil, ig_version: 'v201')
|
|
238
327
|
return unless reference.is_a?(String) && valid_reference_format?(reference, field_name)
|
|
239
328
|
|
|
240
329
|
resource_type, resource_id = reference.split('/')
|
|
@@ -248,7 +337,9 @@ module DaVinciCRDTestKit
|
|
|
248
337
|
return
|
|
249
338
|
end
|
|
250
339
|
|
|
251
|
-
|
|
340
|
+
return unless client_test? && !field_name.include?('selections')
|
|
341
|
+
|
|
342
|
+
query_and_validate_id_field(resource_type, resource_id, ig_version:)
|
|
252
343
|
end
|
|
253
344
|
|
|
254
345
|
def valid_reference_format?(reference, field_name)
|
|
@@ -262,14 +353,14 @@ module DaVinciCRDTestKit
|
|
|
262
353
|
false
|
|
263
354
|
end
|
|
264
355
|
|
|
265
|
-
def id_only_fields_check(hook_name, context, id_fields)
|
|
356
|
+
def id_only_fields_check(hook_name, context, id_fields, ig_version: 'v201')
|
|
266
357
|
id_fields.each do |field|
|
|
267
358
|
resource_id = context[field]
|
|
268
359
|
next unless resource_id.is_a?(String) && valid_id_format?(field, hook_name, resource_id)
|
|
269
360
|
|
|
270
361
|
if client_test?
|
|
271
362
|
resource_type = field.split(/(?=[A-Z])/).first.capitalize
|
|
272
|
-
query_and_validate_id_field(resource_type, resource_id)
|
|
363
|
+
query_and_validate_id_field(resource_type, resource_id, ig_version:)
|
|
273
364
|
end
|
|
274
365
|
end
|
|
275
366
|
end
|
|
@@ -285,7 +376,7 @@ module DaVinciCRDTestKit
|
|
|
285
376
|
true
|
|
286
377
|
end
|
|
287
378
|
|
|
288
|
-
def bundle_entries_check(context, context_field_name, bundle, resource_types, status = nil)
|
|
379
|
+
def bundle_entries_check(context, context_field_name, bundle, resource_types, status = nil, ig_version: 'v201') # rubocop:disable Metrics/CyclomaticComplexity
|
|
289
380
|
bundle.entry.each do |entry|
|
|
290
381
|
resource_id = entry.resource.id
|
|
291
382
|
next unless resource_id.blank?
|
|
@@ -305,7 +396,11 @@ module DaVinciCRDTestKit
|
|
|
305
396
|
status_check(context, context_field_name, status, target_resources)
|
|
306
397
|
|
|
307
398
|
target_resources.each do |resource|
|
|
308
|
-
|
|
399
|
+
if resource.resourceType == 'Appointment' && ig_version == 'v221'
|
|
400
|
+
check_appointment_conformance(resource, { 'context' => context, 'fhirServer' => fhir_url }, '', '2.2.1')
|
|
401
|
+
else
|
|
402
|
+
resource_is_valid?(resource:, profile_url: structure_definition_map(ig_version)[resource.resourceType])
|
|
403
|
+
end
|
|
309
404
|
end
|
|
310
405
|
end
|
|
311
406
|
|
|
@@ -334,11 +429,12 @@ module DaVinciCRDTestKit
|
|
|
334
429
|
nil
|
|
335
430
|
end
|
|
336
431
|
|
|
337
|
-
def context_selections_check(context, selections, order_refs, expected_resource_types)
|
|
432
|
+
def context_selections_check(context, selections, order_refs, expected_resource_types, ig_version: 'v201')
|
|
338
433
|
return unless selections.is_a?(Array)
|
|
339
434
|
|
|
340
435
|
selections.each do |reference|
|
|
341
|
-
resource_reference_check(reference, 'selections item', supported_resource_types: expected_resource_types
|
|
436
|
+
resource_reference_check(reference, 'selections item', supported_resource_types: expected_resource_types,
|
|
437
|
+
ig_version:)
|
|
342
438
|
next if order_refs.include?(reference)
|
|
343
439
|
|
|
344
440
|
error_msg = "#{request_number}`selections` field must reference FHIR resources in `draftOrders`. " \
|
|
@@ -347,25 +443,26 @@ module DaVinciCRDTestKit
|
|
|
347
443
|
end
|
|
348
444
|
end
|
|
349
445
|
|
|
350
|
-
def appointment_book_context_check(context)
|
|
351
|
-
hook_user_type_check(context, 'appointment-book')
|
|
352
|
-
id_only_fields_check('appointment-book', context, ['patientId'])
|
|
446
|
+
def appointment_book_context_check(context, ig_version: 'v201')
|
|
447
|
+
hook_user_type_check(context, 'appointment-book', ig_version:)
|
|
448
|
+
id_only_fields_check('appointment-book', context, ['patientId'], ig_version:)
|
|
353
449
|
|
|
354
450
|
appointment_bundle = parse_fhir_bundle_from_context('appointments', context)
|
|
355
451
|
return if appointment_bundle.blank?
|
|
356
452
|
|
|
357
453
|
expected_resource_types = ['Appointment']
|
|
358
|
-
bundle_entries_check(context, 'appointments', appointment_bundle, expected_resource_types, 'proposed'
|
|
454
|
+
bundle_entries_check(context, 'appointments', appointment_bundle, expected_resource_types, 'proposed',
|
|
455
|
+
ig_version:)
|
|
359
456
|
end
|
|
360
457
|
|
|
361
|
-
def encounter_start_or_discharge_context_check(context, hook_name)
|
|
362
|
-
hook_user_type_check(context, hook_name)
|
|
363
|
-
id_only_fields_check(hook_name, context, ['patientId', 'encounterId'])
|
|
458
|
+
def encounter_start_or_discharge_context_check(context, hook_name, ig_version: 'v201')
|
|
459
|
+
hook_user_type_check(context, hook_name, ig_version:)
|
|
460
|
+
id_only_fields_check(hook_name, context, ['patientId', 'encounterId'], ig_version:)
|
|
364
461
|
end
|
|
365
462
|
|
|
366
|
-
def order_select_or_sign_context_check(context, hook_name)
|
|
367
|
-
hook_user_type_check(context, hook_name)
|
|
368
|
-
id_only_fields_check(hook_name, context, ['patientId'])
|
|
463
|
+
def order_select_or_sign_context_check(context, hook_name, ig_version: 'v201')
|
|
464
|
+
hook_user_type_check(context, hook_name, ig_version:)
|
|
465
|
+
id_only_fields_check(hook_name, context, ['patientId'], ig_version:)
|
|
369
466
|
|
|
370
467
|
draft_orders_bundle = parse_fhir_bundle_from_context('draftOrders', context)
|
|
371
468
|
return if draft_orders_bundle.blank?
|
|
@@ -375,28 +472,25 @@ module DaVinciCRDTestKit
|
|
|
375
472
|
'ServiceRequest', 'VisionPrescription'
|
|
376
473
|
]
|
|
377
474
|
|
|
378
|
-
bundle_entries_check(context, 'draftOrders', draft_orders_bundle, expected_resource_types)
|
|
475
|
+
bundle_entries_check(context, 'draftOrders', draft_orders_bundle, expected_resource_types, ig_version:)
|
|
379
476
|
|
|
380
477
|
return unless hook_name == 'order-select'
|
|
381
478
|
|
|
382
479
|
order_refs = draft_orders_bundle.entry.map(&:resource).map do |resource|
|
|
383
480
|
"#{resource.resourceType}/#{resource.id}"
|
|
384
481
|
end
|
|
385
|
-
context_selections_check(context, context['selections'], order_refs, expected_resource_types)
|
|
482
|
+
context_selections_check(context, context['selections'], order_refs, expected_resource_types, ig_version:)
|
|
386
483
|
end
|
|
387
484
|
|
|
388
|
-
def order_dispatch_context_check(context)
|
|
389
|
-
id_only_fields_check('order-dispatch', context, ['patientId'])
|
|
485
|
+
def order_dispatch_context_check(context, ig_version: 'v201')
|
|
486
|
+
id_only_fields_check('order-dispatch', context, ['patientId'], ig_version:)
|
|
390
487
|
order_supported_resource_type = [
|
|
391
488
|
'DeviceRequest', 'MedicationRequest', 'NutritionOrder',
|
|
392
489
|
'ServiceRequest', 'VisionPrescription'
|
|
393
490
|
]
|
|
394
|
-
resource_reference_check(context['order'], 'order', supported_resource_types: order_supported_resource_type
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
def no_error_validation(message)
|
|
399
|
-
assert messages.none? { |msg| msg[:type] == 'error' }, message
|
|
491
|
+
resource_reference_check(context['order'], 'order', supported_resource_types: order_supported_resource_type,
|
|
492
|
+
ig_version:)
|
|
493
|
+
resource_reference_check(context['performer'], 'performer', ig_version:)
|
|
400
494
|
end
|
|
401
495
|
|
|
402
496
|
def valid_url?(url)
|
|
@@ -406,42 +500,55 @@ module DaVinciCRDTestKit
|
|
|
406
500
|
false
|
|
407
501
|
end
|
|
408
502
|
|
|
409
|
-
def
|
|
503
|
+
def guid?(string)
|
|
504
|
+
uuid_regex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i
|
|
505
|
+
uuid_regex.match?(string.to_s)
|
|
506
|
+
end
|
|
507
|
+
|
|
508
|
+
def query_and_validate_id_field(resource_type, resource_id, ig_version: 'v201')
|
|
410
509
|
fhir_read(resource_type, resource_id)
|
|
411
510
|
status = request.response[:status]
|
|
412
511
|
unless status == 200
|
|
413
|
-
add_message('error',
|
|
512
|
+
add_message('error',
|
|
513
|
+
"#{request_number}Unexpected response status when reading '#{resource_type}/#{resource_id}': " \
|
|
514
|
+
"expected 200, but received #{status}")
|
|
414
515
|
return
|
|
415
516
|
end
|
|
416
517
|
unless resource.resourceType == resource_type
|
|
417
|
-
add_message('error',
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
))
|
|
518
|
+
add_message('error',
|
|
519
|
+
"#{request_number}Unexpected resource type when reading '#{resource_type}/#{resource_id}': " \
|
|
520
|
+
"#Expected `#{resource_type}`. Got `#{resource.resourceType}`.")
|
|
421
521
|
return
|
|
422
522
|
end
|
|
423
523
|
unless resource.id == resource_id
|
|
424
|
-
add_message('error',
|
|
425
|
-
|
|
426
|
-
|
|
524
|
+
add_message('error',
|
|
525
|
+
"#{request_number}Unexpected resource id when reading '#{resource_type}/#{resource_id}': " \
|
|
526
|
+
"Expected `#{resource_id}`. Got `#{resource.id}`.")
|
|
427
527
|
return
|
|
428
528
|
end
|
|
429
529
|
|
|
430
|
-
profile_url = hook_name == 'order-dispatch' ? nil : structure_definition_map[resource_type]
|
|
530
|
+
profile_url = hook_name == 'order-dispatch' ? nil : structure_definition_map(ig_version)[resource_type]
|
|
431
531
|
resource_is_valid?(profile_url:)
|
|
432
532
|
end
|
|
433
533
|
|
|
434
|
-
def context_validate_optional_fields(hook_context, hook_name)
|
|
435
|
-
hook_optional_context_fields =
|
|
534
|
+
def context_validate_optional_fields(hook_context, hook_name, ig_version: 'v201')
|
|
535
|
+
hook_optional_context_fields =
|
|
536
|
+
if hook_name == 'order-dispatch'
|
|
537
|
+
context_optional_order_dispatch_fields[ig_version]
|
|
538
|
+
else
|
|
539
|
+
context_optional_fields_by_hook[hook_name]
|
|
540
|
+
end
|
|
436
541
|
return if hook_optional_context_fields.blank?
|
|
437
542
|
|
|
438
543
|
hook_optional_context_fields.each do |field, type|
|
|
439
|
-
|
|
544
|
+
if hook_context.key?(field)
|
|
545
|
+
validate_presence_and_type(hook_context, field, type, "#{hook_name} request context", required: false)
|
|
546
|
+
end
|
|
440
547
|
end
|
|
441
548
|
|
|
442
549
|
optional_field_keys = hook_optional_context_fields.keys
|
|
443
550
|
if optional_field_keys.include?('encounterId') && hook_context['encounterId'].present?
|
|
444
|
-
id_only_fields_check(hook_name, hook_context, ['encounterId'])
|
|
551
|
+
id_only_fields_check(hook_name, hook_context, ['encounterId'], ig_version:)
|
|
445
552
|
end
|
|
446
553
|
|
|
447
554
|
validate_hash_fields(hook_context, optional_field_keys)
|
|
@@ -473,58 +580,11 @@ module DaVinciCRDTestKit
|
|
|
473
580
|
end
|
|
474
581
|
end
|
|
475
582
|
|
|
476
|
-
def
|
|
477
|
-
|
|
478
|
-
next if received_prefetch[advertised_prefetch_key].blank?
|
|
479
|
-
|
|
480
|
-
unless received_prefetch[advertised_prefetch_key].is_a?(Hash)
|
|
481
|
-
add_message('error', "#{request_number}Prefetch field `#{advertised_prefetch_key}` is not of type `Hash`.")
|
|
482
|
-
next
|
|
483
|
-
end
|
|
484
|
-
|
|
485
|
-
received_prefetch_resource = FHIR.from_contents(received_prefetch[advertised_prefetch_key].to_json)
|
|
486
|
-
|
|
487
|
-
if advertised_prefetch_template.include?('?')
|
|
488
|
-
advertised_prefetch_fhir_search = advertised_prefetch_template.gsub(/{|}/, '').split('?')
|
|
489
|
-
advertised_prefetch_resource_type = advertised_prefetch_fhir_search.first
|
|
490
|
-
|
|
491
|
-
if advertised_prefetch_resource_type == 'Coverage'
|
|
492
|
-
advertised_coverage_query_params = Rack::Utils.parse_nested_query(advertised_prefetch_fhir_search.last)
|
|
493
|
-
|
|
494
|
-
advertised_patient_token = advertised_coverage_query_params['patient']
|
|
495
|
-
advertised_context_patient_id_key = advertised_patient_token.split('.').last
|
|
496
|
-
received_context_patient_id = received_context[advertised_context_patient_id_key]
|
|
497
|
-
|
|
498
|
-
advertised_status_param = advertised_coverage_query_params['status']
|
|
499
|
-
|
|
500
|
-
validate_prefetch_coverage(received_prefetch_resource, advertised_prefetch_key, received_context_patient_id,
|
|
501
|
-
advertised_status_param)
|
|
502
|
-
end
|
|
503
|
-
else
|
|
504
|
-
advertised_prefetch_token = advertised_prefetch_template.gsub(/{|}/, '').split('/')
|
|
505
|
-
advertised_context_id = advertised_prefetch_token.last.split('.').last
|
|
506
|
-
|
|
507
|
-
if advertised_prefetch_token.length == 1
|
|
508
|
-
received_context_reference = FHIR::Reference.new(reference: received_context[advertised_context_id])
|
|
509
|
-
received_context_resource_type = received_context_reference.resource_type
|
|
510
|
-
received_context_id = received_context_reference.reference_id
|
|
511
|
-
else
|
|
512
|
-
received_context_id = received_context[advertised_context_id]
|
|
513
|
-
received_context_resource_type = advertised_prefetch_token.first
|
|
514
|
-
end
|
|
515
|
-
validate_prefetch_resource(received_prefetch_resource, advertised_prefetch_key,
|
|
516
|
-
received_context_resource_type, received_context_id)
|
|
517
|
-
end
|
|
518
|
-
end
|
|
519
|
-
end
|
|
520
|
-
|
|
521
|
-
def validate_prefetch_coverage(received_resource, advertised_prefetch_key,
|
|
522
|
-
received_context_patient_id, advertised_status)
|
|
583
|
+
def validate_prefetch_coverages(received_resource, advertised_prefetch_key,
|
|
584
|
+
received_context_patient_id, advertised_status, ig_version: 'v201')
|
|
523
585
|
unless received_resource.resourceType == 'Bundle'
|
|
524
|
-
add_message('error',
|
|
525
|
-
|
|
526
|
-
`#{received_resource.resourceType}`.
|
|
527
|
-
))
|
|
586
|
+
add_message('error', "#{request_number}Unexpected resource type: Expected `Bundle`. Got " \
|
|
587
|
+
"`#{received_resource.resourceType}`.")
|
|
528
588
|
return
|
|
529
589
|
end
|
|
530
590
|
|
|
@@ -533,76 +593,95 @@ module DaVinciCRDTestKit
|
|
|
533
593
|
return
|
|
534
594
|
end
|
|
535
595
|
|
|
536
|
-
|
|
596
|
+
if received_context_patient_id.blank?
|
|
597
|
+
add_message('error',
|
|
598
|
+
"#{request_number}Cannot verify `coverage` patient id because no id provided in the context.")
|
|
599
|
+
end
|
|
600
|
+
|
|
601
|
+
received_resource.entry.each_with_index do |entry, index|
|
|
602
|
+
validate_prefetch_coverage(entry&.resource, advertised_prefetch_key,
|
|
603
|
+
received_context_patient_id, advertised_status, index, ig_version:)
|
|
604
|
+
end
|
|
605
|
+
end
|
|
606
|
+
|
|
607
|
+
def validate_prefetch_coverage(coverage_resource, advertised_prefetch_key,
|
|
608
|
+
received_context_patient_id, advertised_status, entry_index, ig_version: 'v201')
|
|
609
|
+
unless coverage_resource.present?
|
|
610
|
+
add_message('error', "#{request_number}Coverage Bundle entry #{entry_index + 1} had no resource")
|
|
611
|
+
return
|
|
612
|
+
end
|
|
613
|
+
|
|
537
614
|
unless coverage_resource.resourceType == 'Coverage'
|
|
538
|
-
add_message('error',
|
|
539
|
-
|
|
540
|
-
`#{coverage_resource.resourceType}`.
|
|
541
|
-
))
|
|
615
|
+
add_message('error', "#{request_number}Coverage Bundle entry #{entry_index + 1} - Unexpected resource type: " \
|
|
616
|
+
"Expected `Coverage`. Got `#{coverage_resource.resourceType}`.")
|
|
542
617
|
return
|
|
543
618
|
end
|
|
544
619
|
|
|
545
620
|
resource_is_valid?(resource: coverage_resource,
|
|
546
|
-
profile_url: structure_definition_map['Coverage'])
|
|
621
|
+
profile_url: structure_definition_map(ig_version)['Coverage'])
|
|
547
622
|
|
|
548
623
|
coverage_beneficiary_reference = coverage_resource.beneficiary
|
|
549
624
|
coverage_beneficiary_patient_id = coverage_beneficiary_reference.reference_id
|
|
550
625
|
if coverage_beneficiary_patient_id.blank?
|
|
551
|
-
add_message('error',
|
|
552
|
-
|
|
553
|
-
resource
|
|
554
|
-
))
|
|
626
|
+
add_message('error', "#{request_number}Coverage Bundle entry #{entry_index + 1} - Could not get beneficiary " \
|
|
627
|
+
"reference id from `#{advertised_prefetch_key}` field's Coverage resource")
|
|
555
628
|
return
|
|
556
629
|
end
|
|
557
630
|
|
|
558
|
-
if coverage_beneficiary_patient_id != received_context_patient_id
|
|
559
|
-
add_message('error',
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
631
|
+
if received_context_patient_id.present? && coverage_beneficiary_patient_id != received_context_patient_id
|
|
632
|
+
add_message('error', "#{request_number}Coverage Bundle entry #{entry_index + 1} - " \
|
|
633
|
+
"Expected `#{advertised_prefetch_key}` field's Coverage resource to have a " \
|
|
634
|
+
"`beneficiary` reference id of '#{received_context_patient_id}', " \
|
|
635
|
+
"instead was '#{coverage_beneficiary_patient_id}`")
|
|
563
636
|
return
|
|
564
637
|
end
|
|
565
638
|
|
|
566
639
|
coverage_status = coverage_resource.status
|
|
567
640
|
return unless coverage_status != advertised_status
|
|
568
641
|
|
|
569
|
-
add_message('error',
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
))
|
|
642
|
+
add_message('error', "#{request_number}Coverage Bundle entry #{entry_index + 1} - " \
|
|
643
|
+
"Expected `#{advertised_prefetch_key}` field's Coverage resource to have a `status` of " \
|
|
644
|
+
"'#{advertised_status}', instead was '#{coverage_status}'")
|
|
573
645
|
end
|
|
574
646
|
|
|
575
647
|
def validate_prefetch_resource(received_resource, advertised_prefetch_key, context_field_resource_type,
|
|
576
|
-
context_field_id)
|
|
577
|
-
unless received_resource
|
|
578
|
-
|
|
579
|
-
#{request_number}Unexpected resource type: Expected `#{context_field_resource_type}`. Got
|
|
580
|
-
`#{received_resource.resourceType}`.
|
|
581
|
-
))
|
|
582
|
-
return
|
|
583
|
-
end
|
|
648
|
+
context_field_id, ig_version: 'v201')
|
|
649
|
+
return unless prefetch_resource_type_correct?(received_resource, context_field_resource_type,
|
|
650
|
+
"#{request_number}`#{advertised_prefetch_key}` - ")
|
|
584
651
|
|
|
585
652
|
if hook_name == 'order-dispatch'
|
|
586
653
|
resource_is_valid?(resource: received_resource)
|
|
587
654
|
else
|
|
588
655
|
resource_is_valid?(resource: received_resource,
|
|
589
|
-
profile_url: structure_definition_map[context_field_resource_type])
|
|
656
|
+
profile_url: structure_definition_map(ig_version)[context_field_resource_type])
|
|
590
657
|
end
|
|
591
658
|
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
659
|
+
prefetch_resource_id_correct?(received_resource, context_field_id,
|
|
660
|
+
"#{request_number}`#{advertised_prefetch_key}` - ")
|
|
661
|
+
end
|
|
662
|
+
|
|
663
|
+
def prefetch_resource_type_correct?(resource, expected_type, error_prefix)
|
|
664
|
+
if expected_type.present?
|
|
665
|
+
return true if resource.resourceType == expected_type
|
|
666
|
+
|
|
667
|
+
add_message(:error, "#{error_prefix}Prefetched resource has the wrong resource type. " \
|
|
668
|
+
"Expected `#{expected_type}`, got `#{resource.resourceType}`.")
|
|
669
|
+
else
|
|
670
|
+
add_message(:error, "#{error_prefix}No resource type provided to verify prefetched resource against.")
|
|
598
671
|
end
|
|
672
|
+
false
|
|
673
|
+
end
|
|
599
674
|
|
|
600
|
-
|
|
675
|
+
def prefetch_resource_id_correct?(resource, expected_id, error_prefix)
|
|
676
|
+
if expected_id.present?
|
|
677
|
+
return true if resource.id == expected_id
|
|
601
678
|
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
679
|
+
add_message(:error, "#{error_prefix}Prefetched resource has the wrong resource id. " \
|
|
680
|
+
"Expected `#{expected_id}`, got `#{resource.id}`.")
|
|
681
|
+
else
|
|
682
|
+
add_message(:error, "#{error_prefix}No resource id provided to verify prefetched resource against.")
|
|
683
|
+
end
|
|
684
|
+
false
|
|
606
685
|
end
|
|
607
686
|
end
|
|
608
687
|
end
|