davinci_crd_test_kit 0.13.0 → 0.14.1
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 +188 -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 +239 -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}/external_reference.json +1 -1
- data/lib/davinci_crd_test_kit/{card_responses → client/endpoints/mocked_card_responses}/launch_smart_app.json +1 -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 +109 -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 +102 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_encounter_start_group.rb +101 -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 +84 -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 +107 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_order_select_group.rb +108 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_order_sign_group.rb +113 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_registration_group.rb +33 -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 +234 -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 +54 -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 +108 -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 +133 -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 +75 -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 +321 -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 +476 -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 +203 -0
- data/lib/davinci_crd_test_kit/cross_suite/response_logical_model_validation.rb +435 -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 +46 -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/server/jobs/invoke_hook_no_special_requests.rb +17 -0
- data/lib/davinci_crd_test_kit/server/jobs/invoke_hook_with_bad_auth.rb +14 -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 +183 -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} +3 -3
- 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 +118 -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/discovery/discovery_standard_prefetch_expressions_test.rb +166 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/interaction/server_invoke_hook_single_request_test.rb +22 -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 +121 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_demonstrate_hook_response_group.rb +94 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_discovery_group.rb +71 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_encounter_discharge_group.rb +107 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_encounter_start_group.rb +107 -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 +121 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_order_select_group.rb +115 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_order_sign_group.rb +132 -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/specific_coverage_response_group.rb +23 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/specific_coverage_responses/coverage_info_reason_test.rb +108 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/specific_coverage_responses/coverage_not_found_group.rb +116 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/specific_coverage_responses/no_active_coverage_group.rb +115 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/specific_coverage_responses/no_member_found_group.rb +117 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/specific_coverage_responses/technical_issues_group.rb +121 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/specific_coverage_responses/technical_issues_invoke_test.rb +22 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_request/service_request_context_validation_test.rb +31 -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 +40 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_request/service_request_required_fields_validation_test.rb +41 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/additional_orders_validation_test.rb +109 -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/coverage_info_configuration_test.rb +83 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/coverage_information_card_absence_test.rb +76 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/coverage_information_system_action_validation_test.rb +130 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/create_or_update_coverage_info_response_validation_test.rb +119 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/external_reference_card_validation_test.rb +89 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/form_completion_response_validation_test.rb +126 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/hook_request_resource_resolution.rb +174 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/instructions_card_received_test.rb +83 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/launch_smart_app_card_validation_test.rb +88 -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 +81 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/service_response_validation_test.rb +63 -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 +307 -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}/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,130 @@
|
|
|
1
|
+
require_relative '../../server_hook_request_validation'
|
|
2
|
+
require_relative '../../server_test_helper'
|
|
3
|
+
require_relative '../../server_hook_helper'
|
|
4
|
+
require_relative '../../../cross_suite/cards_identification'
|
|
5
|
+
require_relative '../../../cross_suite/response_logical_model_validation'
|
|
6
|
+
require_relative 'hook_request_resource_resolution'
|
|
7
|
+
|
|
8
|
+
module DaVinciCRDTestKit
|
|
9
|
+
module V221
|
|
10
|
+
class CoverageInformationSystemActionValidationTest < Inferno::Test
|
|
11
|
+
include DaVinciCRDTestKit::ServerHookRequestValidation
|
|
12
|
+
include DaVinciCRDTestKit::ServerTestHelper
|
|
13
|
+
include DaVinciCRDTestKit::ServerHookHelper
|
|
14
|
+
include HookRequestResourceResolution
|
|
15
|
+
include DaVinciCRDTestKit::CardsIdentification
|
|
16
|
+
include DaVinciCRDTestKit::ResponseLogicalModelValidation
|
|
17
|
+
|
|
18
|
+
COVERAGE_INFO_EXT_URL = 'http://hl7.org/fhir/us/davinci-crd/StructureDefinition/ext-coverage-information'.freeze
|
|
19
|
+
|
|
20
|
+
title 'Coverage Information system actions are valid'
|
|
21
|
+
id :crd_v221_coverage_info_system_action_validation
|
|
22
|
+
description %(
|
|
23
|
+
This test validates all [Coverage
|
|
24
|
+
Information](https://hl7.org/fhir/us/davinci-crd/2.2.1/en/cards.html#coverage-information-response-type)
|
|
25
|
+
system actions received. It verifies the following for each action:
|
|
26
|
+
- The action type is `update`.
|
|
27
|
+
- The resource within the action conforms its respective FHIR profile.
|
|
28
|
+
- The resource does not change any data elements other than adding or
|
|
29
|
+
modifying the `coverage-information` extension.
|
|
30
|
+
|
|
31
|
+
Additionally, the test examines the `coverage-info` extensions within
|
|
32
|
+
the resource to ensure that:
|
|
33
|
+
- Entries referencing differing coverage have distinct
|
|
34
|
+
`coverage-assertion-ids` and `satisfied-pa-ids` (if present).
|
|
35
|
+
- Entries referencing the same coverage have the same
|
|
36
|
+
`coverage-assertion-ids` and `satisfied-pa-ids` (if present).
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
verifies_requirements 'hl7.fhir.us.davinci-crd_2.2.1@resp-26',
|
|
40
|
+
'hl7.fhir.us.davinci-crd_2.2.1@resp-32',
|
|
41
|
+
'hl7.fhir.us.davinci-crd_2.2.1@resp-37',
|
|
42
|
+
'hl7.fhir.us.davinci-crd_2.2.1@resp-47',
|
|
43
|
+
'hl7.fhir.us.davinci-crd_2.2.1@resp-48',
|
|
44
|
+
'hl7.fhir.us.davinci-crd_2.2.1@resp-52'
|
|
45
|
+
|
|
46
|
+
input :invoked_hook
|
|
47
|
+
input :mock_ehr_bundle, optional: true
|
|
48
|
+
output :coverage_info
|
|
49
|
+
|
|
50
|
+
def verify_only_coverage_info_changed(action, request)
|
|
51
|
+
source_resource = find_action_source_resource(action, request)
|
|
52
|
+
updated_resource_hash = action['resource']
|
|
53
|
+
resource_ref = "#{updated_resource_hash['resourceType']}/#{updated_resource_hash['id']}"
|
|
54
|
+
unless source_resource
|
|
55
|
+
messages << {
|
|
56
|
+
type: 'warning',
|
|
57
|
+
message: 'Inferno could not resolve the original source resource for Coverage Information systemAction ' \
|
|
58
|
+
"targeting #{resource_ref}, so it could not verify that only coverage-information extensions " \
|
|
59
|
+
'were changed.'
|
|
60
|
+
}
|
|
61
|
+
return
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
return if only_coverage_information_changed?(source_resource.to_hash, updated_resource_hash)
|
|
65
|
+
|
|
66
|
+
add_message(
|
|
67
|
+
'error',
|
|
68
|
+
"#{resource_ref}: resource content changed outside the coverage-information extension."
|
|
69
|
+
)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def body_has_no_system_actions?(body)
|
|
73
|
+
!body.is_a?(Hash) ||
|
|
74
|
+
body['systemActions'].blank? ||
|
|
75
|
+
!body['systemActions'].is_a?(Array) ||
|
|
76
|
+
!body['systemActions'].all?(Hash)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def coverage_info_actions(request)
|
|
80
|
+
return [] if request.status != 200
|
|
81
|
+
|
|
82
|
+
response_body = JSON.parse(request.response_body)
|
|
83
|
+
|
|
84
|
+
return [] if body_has_no_system_actions?(response_body)
|
|
85
|
+
|
|
86
|
+
response_body['systemActions'].select { |action| coverage_information_response_type? action }
|
|
87
|
+
rescue JSON::ParserError
|
|
88
|
+
[]
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
run do
|
|
92
|
+
load_tagged_requests(tested_hook_name)
|
|
93
|
+
|
|
94
|
+
all_coverage_info_actions = []
|
|
95
|
+
coverage_info_count = 0
|
|
96
|
+
|
|
97
|
+
successful_requests = requests.select { |request| request.status == 200 }
|
|
98
|
+
|
|
99
|
+
skip_if successful_requests.blank?,
|
|
100
|
+
'No successful hook responses were received'
|
|
101
|
+
|
|
102
|
+
requests.each_with_index do |request, index|
|
|
103
|
+
actions = coverage_info_actions(request)
|
|
104
|
+
|
|
105
|
+
coverage_info_count += actions.length
|
|
106
|
+
|
|
107
|
+
perform_response_logical_model_validation(
|
|
108
|
+
nil,
|
|
109
|
+
actions,
|
|
110
|
+
request.request_body,
|
|
111
|
+
index,
|
|
112
|
+
'2.2.1'
|
|
113
|
+
)
|
|
114
|
+
actions.each { |action| verify_only_coverage_info_changed(action, request) }
|
|
115
|
+
|
|
116
|
+
all_coverage_info_actions.concat(actions)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
skip_if coverage_info_count.zero?,
|
|
120
|
+
"#{tested_hook_name} hook responses do not contain any Coverage Information system actions."
|
|
121
|
+
|
|
122
|
+
output coverage_info: all_coverage_info_actions.to_json
|
|
123
|
+
|
|
124
|
+
no_error_validation(
|
|
125
|
+
'Not all Coverage Information system actions were valid. See messages for more information.'
|
|
126
|
+
)
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
end
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
require_relative '../../server_test_helper'
|
|
2
|
+
require_relative '../../server_hook_helper'
|
|
3
|
+
require_relative '../../../cross_suite/cards_identification'
|
|
4
|
+
require_relative '../../../cross_suite/response_logical_model_validation'
|
|
5
|
+
|
|
6
|
+
module DaVinciCRDTestKit
|
|
7
|
+
module V221
|
|
8
|
+
class CreateOrUpdateCoverageInfoResponseValidationTest < Inferno::Test
|
|
9
|
+
include DaVinciCRDTestKit::ServerTestHelper
|
|
10
|
+
include DaVinciCRDTestKit::ServerHookHelper
|
|
11
|
+
include DaVinciCRDTestKit::CardsIdentification
|
|
12
|
+
include DaVinciCRDTestKit::ResponseLogicalModelValidation
|
|
13
|
+
|
|
14
|
+
title 'Create or Update Coverage Information cards and system actions are valid'
|
|
15
|
+
id :crd_v221_create_or_update_coverage_info_response_validation
|
|
16
|
+
description %(
|
|
17
|
+
This test validates the Create or Update Coverage Information cards or
|
|
18
|
+
system actions received from the CRD service, as per the specifications
|
|
19
|
+
outlined in the [Da Vinci CRD Implementation
|
|
20
|
+
Guide](https://hl7.org/fhir/us/davinci-crd/2.2.1/en/cards.html#update-coverage-records-response-type).
|
|
21
|
+
|
|
22
|
+
- **Checking for Presence:**
|
|
23
|
+
The test first checks if any Create or Update Coverage Information
|
|
24
|
+
cards or system actions are present in the returned valid cards or
|
|
25
|
+
valid system actions.
|
|
26
|
+
- **For cards**: it ensures there are cards with a `suggestions` array
|
|
27
|
+
containing a single suggestion, and the `actions` array of that
|
|
28
|
+
suggestion has one `create` or `update` action for the `Coverage`
|
|
29
|
+
resource.
|
|
30
|
+
- **For system actions**: it checks for the presence of `create` or
|
|
31
|
+
`update` actions for the `Coverage` resource.
|
|
32
|
+
|
|
33
|
+
- **Validating:**
|
|
34
|
+
If any Create or Update Coverage Information cards or system actions
|
|
35
|
+
are found, each `Coverage` resource is validated against the base FHIR
|
|
36
|
+
Coverage resource.
|
|
37
|
+
|
|
38
|
+
If no Create or Update Coverage Information cards or system actions
|
|
39
|
+
are received, the test is skipped.
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
verifies_requirements 'hl7.fhir.us.davinci-crd_2.2.1@resp-3',
|
|
43
|
+
'hl7.fhir.us.davinci-crd_2.2.1@resp-71'
|
|
44
|
+
|
|
45
|
+
input :invoked_hook
|
|
46
|
+
|
|
47
|
+
optional
|
|
48
|
+
|
|
49
|
+
def body_has_no_cards?(body)
|
|
50
|
+
!body.is_a?(Hash) ||
|
|
51
|
+
body['cards'].blank? ||
|
|
52
|
+
!body['cards'].is_a?(Array) ||
|
|
53
|
+
!body['cards'].all?(Hash)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def update_coverage_cards(request)
|
|
57
|
+
return [] if request.status != 200
|
|
58
|
+
|
|
59
|
+
response_body = JSON.parse(request.response_body)
|
|
60
|
+
|
|
61
|
+
return [] if body_has_no_cards?(response_body)
|
|
62
|
+
|
|
63
|
+
response_body['cards'].select { |card| create_or_update_coverage_card_response_type? card }
|
|
64
|
+
rescue JSON::ParserError
|
|
65
|
+
[]
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def body_has_no_system_actions?(body)
|
|
69
|
+
!body.is_a?(Hash) ||
|
|
70
|
+
body['systemActions'].blank? ||
|
|
71
|
+
!body['systemActions'].is_a?(Array) ||
|
|
72
|
+
!body['systemActions'].all?(Hash)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def update_coverage_actions(request)
|
|
76
|
+
return [] if request.status != 200
|
|
77
|
+
|
|
78
|
+
response_body = JSON.parse(request.response_body)
|
|
79
|
+
|
|
80
|
+
return [] if body_has_no_system_actions?(response_body)
|
|
81
|
+
|
|
82
|
+
response_body['systemActions'].select { |action| create_or_update_coverage_action_response_type? action }
|
|
83
|
+
rescue JSON::ParserError
|
|
84
|
+
[]
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
run do
|
|
88
|
+
load_tagged_requests(tested_hook_name)
|
|
89
|
+
|
|
90
|
+
update_coverage_count = 0
|
|
91
|
+
|
|
92
|
+
successful_requests = requests.select { |request| request.status == 200 }
|
|
93
|
+
|
|
94
|
+
skip_if successful_requests.blank?,
|
|
95
|
+
'No successful hook responses were received'
|
|
96
|
+
|
|
97
|
+
requests.each_with_index do |request, index|
|
|
98
|
+
cards = update_coverage_cards(request)
|
|
99
|
+
actions = update_coverage_actions(request)
|
|
100
|
+
|
|
101
|
+
update_coverage_count += cards.length + actions.length
|
|
102
|
+
|
|
103
|
+
perform_response_logical_model_validation(
|
|
104
|
+
cards,
|
|
105
|
+
actions,
|
|
106
|
+
request.request_body,
|
|
107
|
+
index,
|
|
108
|
+
'2.2.1'
|
|
109
|
+
)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
skip_if update_coverage_count.zero?,
|
|
113
|
+
"#{tested_hook_name} hook responses do not contain any Update Coverage Records cards or system actions."
|
|
114
|
+
|
|
115
|
+
no_error_validation('Not all Update Coverage Records responses were valid. See messages for more information.')
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
require_relative '../../server_test_helper'
|
|
2
|
+
require_relative '../../server_hook_helper'
|
|
3
|
+
require_relative '../../../cross_suite/cards_identification'
|
|
4
|
+
require_relative '../../../cross_suite/response_logical_model_validation'
|
|
5
|
+
|
|
6
|
+
module DaVinciCRDTestKit
|
|
7
|
+
module V221
|
|
8
|
+
class ExternalReferenceCardValidationTest < Inferno::Test
|
|
9
|
+
include DaVinciCRDTestKit::ServerTestHelper
|
|
10
|
+
include DaVinciCRDTestKit::ServerHookHelper
|
|
11
|
+
include DaVinciCRDTestKit::CardsIdentification
|
|
12
|
+
include DaVinciCRDTestKit::ResponseLogicalModelValidation
|
|
13
|
+
|
|
14
|
+
title 'External Reference cards are valid'
|
|
15
|
+
id :crd_v221_external_reference_card_validation
|
|
16
|
+
description %(
|
|
17
|
+
This test verifies the presence of valid External Reference cards within
|
|
18
|
+
the CRD service responses.
|
|
19
|
+
|
|
20
|
+
As per the [Da Vinci CRD Implementation
|
|
21
|
+
Guide](https://hl7.org/fhir/us/davinci-crd/2.2.1/en/cards.html#external-reference-response-type),
|
|
22
|
+
External Reference cards must contain links with the type set to
|
|
23
|
+
`absolute`. This test checks for the presence of any External Reference
|
|
24
|
+
cards by verifying:
|
|
25
|
+
- The presence of a `links` array within each card.
|
|
26
|
+
- That every link in the `links` array of a card is of type `absolute`.
|
|
27
|
+
|
|
28
|
+
The test will be skipped if no External Reference cards are found within
|
|
29
|
+
the returned valid cards.
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
verifies_requirements 'hl7.fhir.us.davinci-crd_2.2.1@resp-19',
|
|
33
|
+
'hl7.fhir.us.davinci-crd_2.2.1@resp-22'
|
|
34
|
+
|
|
35
|
+
input :invoked_hook
|
|
36
|
+
|
|
37
|
+
optional
|
|
38
|
+
|
|
39
|
+
def body_has_no_cards?(body)
|
|
40
|
+
!body.is_a?(Hash) ||
|
|
41
|
+
body['cards'].blank? ||
|
|
42
|
+
!body['cards'].is_a?(Array) ||
|
|
43
|
+
!body['cards'].all?(Hash)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def external_reference_cards(request)
|
|
47
|
+
return [] if request.status != 200
|
|
48
|
+
|
|
49
|
+
response_body = JSON.parse(request.response_body)
|
|
50
|
+
|
|
51
|
+
return [] if body_has_no_cards?(response_body)
|
|
52
|
+
|
|
53
|
+
response_body['cards'].select { |card| external_reference_response_type? card }
|
|
54
|
+
rescue JSON::ParserError
|
|
55
|
+
[]
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
run do
|
|
59
|
+
load_tagged_requests(tested_hook_name)
|
|
60
|
+
|
|
61
|
+
external_reference_count = 0
|
|
62
|
+
|
|
63
|
+
successful_requests = requests.select { |request| request.status == 200 }
|
|
64
|
+
|
|
65
|
+
skip_if successful_requests.blank?,
|
|
66
|
+
'No successful hook responses were received'
|
|
67
|
+
|
|
68
|
+
requests.each_with_index do |request, index|
|
|
69
|
+
cards = external_reference_cards(request)
|
|
70
|
+
|
|
71
|
+
external_reference_count += cards.length
|
|
72
|
+
|
|
73
|
+
perform_response_logical_model_validation(
|
|
74
|
+
cards,
|
|
75
|
+
nil,
|
|
76
|
+
request.request_body,
|
|
77
|
+
index,
|
|
78
|
+
'2.2.1'
|
|
79
|
+
)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
skip_if external_reference_count.zero?,
|
|
83
|
+
"#{tested_hook_name} hook responses do not contain any External Reference cards."
|
|
84
|
+
|
|
85
|
+
no_error_validation('Not all External Reference cards were valid. See messages for more information.')
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
require_relative '../../server_test_helper'
|
|
2
|
+
require_relative '../../server_hook_helper'
|
|
3
|
+
require_relative '../../../cross_suite/cards_identification'
|
|
4
|
+
require_relative '../../../cross_suite/response_logical_model_validation'
|
|
5
|
+
|
|
6
|
+
module DaVinciCRDTestKit
|
|
7
|
+
module V221
|
|
8
|
+
class FormCompletionResponseValidationTest < Inferno::Test
|
|
9
|
+
include DaVinciCRDTestKit::ServerTestHelper
|
|
10
|
+
include DaVinciCRDTestKit::ServerHookHelper
|
|
11
|
+
include DaVinciCRDTestKit::CardsIdentification
|
|
12
|
+
include DaVinciCRDTestKit::ResponseLogicalModelValidation
|
|
13
|
+
|
|
14
|
+
title 'Request Form Completion cards and system actions are valid'
|
|
15
|
+
id :crd_v221_request_form_completion_response_validation
|
|
16
|
+
description %(
|
|
17
|
+
This test validates the Request Form Completion cards or system actions
|
|
18
|
+
received from the CRD service, as per the specifications outlined in the
|
|
19
|
+
[Da Vinci CRD Implementation
|
|
20
|
+
Guide](https://hl7.org/fhir/us/davinci-crd/2.2.1/en/cards.html#request-form-completion-response-type).
|
|
21
|
+
|
|
22
|
+
- **Checking for Presence:**
|
|
23
|
+
The test begins by verifying whether any Request Form Completion cards
|
|
24
|
+
or system actions are present.
|
|
25
|
+
- **For cards:** It ensures that there are cards with `suggestions`
|
|
26
|
+
containing `create` actions for the `Task` resource, specifically:
|
|
27
|
+
- The `Task` must have a `code` of `complete-questionnaire`.
|
|
28
|
+
- The `Task` should include an input of type `text`
|
|
29
|
+
(`Task.input.type.text`) labeled as `questionnaire` and associated
|
|
30
|
+
with a valid canonical URL (`Task.input.valueCanonical`).
|
|
31
|
+
- **For system actions:** It checks for the presence of `create`
|
|
32
|
+
actions for the `Task` resource with the characteristics described
|
|
33
|
+
above.
|
|
34
|
+
|
|
35
|
+
- **Validating:**
|
|
36
|
+
If any Request Form Completion cards or system actions are found, the
|
|
37
|
+
test proceeds to validate them. Each `Task` resource is validated
|
|
38
|
+
against the [CRD Questionnaire Task
|
|
39
|
+
profile](https://hl7.org/fhir/us/davinci-crd/2.2.1/en/StructureDefinition-profile-taskquestionnaire.html).
|
|
40
|
+
Additionally, if any actions for the creation of a `Questionnaire` are
|
|
41
|
+
found, the test verifies that they include the
|
|
42
|
+
`davinci-crd.if-none-exist` extension.
|
|
43
|
+
|
|
44
|
+
If no Request Form Completion cards or system actions are received, the test is skipped.
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
verifies_requirements 'hl7.fhir.us.davinci-crd_2.2.1@dev-20',
|
|
48
|
+
'hl7.fhir.us.davinci-crd_2.2.1@resp-3',
|
|
49
|
+
'hl7.fhir.us.davinci-crd_2.2.1@resp-62',
|
|
50
|
+
'hl7.fhir.us.davinci-crd_2.2.1@resp-65'
|
|
51
|
+
|
|
52
|
+
input :invoked_hook
|
|
53
|
+
|
|
54
|
+
optional
|
|
55
|
+
|
|
56
|
+
def body_has_no_cards?(body)
|
|
57
|
+
!body.is_a?(Hash) ||
|
|
58
|
+
body['cards'].blank? ||
|
|
59
|
+
!body['cards'].is_a?(Array) ||
|
|
60
|
+
!body['cards'].all?(Hash)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def form_completion_cards(request)
|
|
64
|
+
return [] if request.status != 200
|
|
65
|
+
|
|
66
|
+
response_body = JSON.parse(request.response_body)
|
|
67
|
+
|
|
68
|
+
return [] if body_has_no_cards?(response_body)
|
|
69
|
+
|
|
70
|
+
response_body['cards'].select { |card| form_completion_card_response_type? card }
|
|
71
|
+
rescue JSON::ParserError
|
|
72
|
+
[]
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def body_has_no_system_actions?(body)
|
|
76
|
+
!body.is_a?(Hash) ||
|
|
77
|
+
body['systemActions'].blank? ||
|
|
78
|
+
!body['systemActions'].is_a?(Array) ||
|
|
79
|
+
!body['systemActions'].all?(Hash)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def form_completion_actions(request)
|
|
83
|
+
return [] if request.status != 200
|
|
84
|
+
|
|
85
|
+
response_body = JSON.parse(request.response_body)
|
|
86
|
+
|
|
87
|
+
return [] if body_has_no_system_actions?(response_body)
|
|
88
|
+
|
|
89
|
+
response_body['systemActions'].select { |action| form_completion_action_response_type? action }
|
|
90
|
+
rescue JSON::ParserError
|
|
91
|
+
[]
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
run do
|
|
95
|
+
load_tagged_requests(tested_hook_name)
|
|
96
|
+
|
|
97
|
+
form_completion_count = 0
|
|
98
|
+
|
|
99
|
+
successful_requests = requests.select { |request| request.status == 200 }
|
|
100
|
+
|
|
101
|
+
skip_if successful_requests.blank?,
|
|
102
|
+
'No successful hook responses were received'
|
|
103
|
+
|
|
104
|
+
requests.each_with_index do |request, index|
|
|
105
|
+
cards = form_completion_cards(request)
|
|
106
|
+
actions = form_completion_actions(request)
|
|
107
|
+
|
|
108
|
+
form_completion_count += cards.length + actions.length
|
|
109
|
+
|
|
110
|
+
perform_response_logical_model_validation(
|
|
111
|
+
cards,
|
|
112
|
+
actions,
|
|
113
|
+
request.request_body,
|
|
114
|
+
index,
|
|
115
|
+
'2.2.1'
|
|
116
|
+
)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
skip_if form_completion_count.zero?,
|
|
120
|
+
"#{tested_hook_name} hook responses do not contain any Request Form Completion cards or system actions."
|
|
121
|
+
|
|
122
|
+
no_error_validation('Not all Request Form Completion responses were valid. See messages for more information.')
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/hook_request_resource_resolution.rb
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
module DaVinciCRDTestKit
|
|
2
|
+
module V221
|
|
3
|
+
module HookRequestResourceResolution
|
|
4
|
+
def mock_ehr_bundle_resource
|
|
5
|
+
@mock_ehr_bundle_resource ||= JSON.parse(mock_ehr_bundle) if mock_ehr_bundle.present?
|
|
6
|
+
rescue JSON::ParserError
|
|
7
|
+
nil
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def matching_request_for_action(action)
|
|
11
|
+
requests.find do |request|
|
|
12
|
+
response = JSON.parse(request.response_body)
|
|
13
|
+
request.status == 200 && Array(response['systemActions']).any? { |candidate| candidate == action }
|
|
14
|
+
rescue JSON::ParserError
|
|
15
|
+
false
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Resolve the original resource being updated by a systemAction.
|
|
20
|
+
# - appointment-book: look in context.appointments; if the action targets a ServiceRequest,
|
|
21
|
+
# follow the Appointment basedOn reference and resolve that from prefetch or mock EHR data
|
|
22
|
+
# - order-sign/order-select: look in context.draftOrders
|
|
23
|
+
# - other hooks: resolve from prefetch or mock EHR data because context may carry only ids/references
|
|
24
|
+
def find_action_source_resource(action, request)
|
|
25
|
+
action_resource = action['resource']
|
|
26
|
+
return unless action_resource.is_a?(Hash)
|
|
27
|
+
|
|
28
|
+
target_type = action_resource['resourceType']
|
|
29
|
+
target_id = action_resource['id']
|
|
30
|
+
request_body = parse_request_body(request)
|
|
31
|
+
return unless target_type.present? && target_id.present? && request_body
|
|
32
|
+
|
|
33
|
+
hook_context_resource(request_body, target_type, target_id) ||
|
|
34
|
+
fallback_source_resource(request_body, target_type, target_id)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def only_coverage_information_changed?(source_resource_hash, updated_resource_hash)
|
|
38
|
+
return true if coverage_information_extension_only_payload?(updated_resource_hash)
|
|
39
|
+
|
|
40
|
+
source_without_coverage_info = normalize_value(strip_coverage_info_extensions(source_resource_hash))
|
|
41
|
+
updated_without_coverage_info = normalize_value(strip_coverage_info_extensions(updated_resource_hash))
|
|
42
|
+
|
|
43
|
+
source_without_coverage_info == updated_without_coverage_info
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def coverage_information_extension_only_payload?(resource_hash)
|
|
47
|
+
return false unless resource_hash.is_a?(Hash)
|
|
48
|
+
|
|
49
|
+
strip_coverage_info_extensions(resource_hash).keys.all? { |key| ['resourceType', 'id', 'meta'].include?(key) }
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def strip_coverage_info_extensions(resource_hash)
|
|
53
|
+
normalized_hash = resource_hash.deep_dup
|
|
54
|
+
return normalized_hash unless normalized_hash['extension'].is_a?(Array)
|
|
55
|
+
|
|
56
|
+
normalized_hash['extension'] = normalized_hash['extension'].reject do |extension|
|
|
57
|
+
extension['url'] == DaVinciCRDTestKit::CardsIdentification::COVERAGE_INFO_EXT_URL
|
|
58
|
+
end
|
|
59
|
+
normalized_hash.delete('extension') if normalized_hash['extension'].empty?
|
|
60
|
+
normalized_hash
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def normalize_value(value)
|
|
64
|
+
case value
|
|
65
|
+
when Hash
|
|
66
|
+
value.transform_values { |child| normalize_value(child) }
|
|
67
|
+
when Array
|
|
68
|
+
value.map { |child| normalize_value(child) }.sort_by(&:to_json)
|
|
69
|
+
else
|
|
70
|
+
value
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def find_appointment_book_resource(request_body, target_type, target_id)
|
|
75
|
+
appointments_bundle = request_body.dig('context', 'appointments')
|
|
76
|
+
find_resource_in_bundle(appointments_bundle, target_type, target_id) ||
|
|
77
|
+
appointment_book_service_request(request_body, appointments_bundle, target_id)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def find_draft_orders_resource(request_body, target_type, target_id)
|
|
81
|
+
draft_orders_bundle = request_body.dig('context', 'draftOrders')
|
|
82
|
+
find_resource_in_bundle(draft_orders_bundle, target_type, target_id)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def fallback_source_resource(request_body, target_type, target_id)
|
|
86
|
+
find_resource_in_prefetch(request_body, target_type, target_id) ||
|
|
87
|
+
find_resource_in_bundle(mock_ehr_bundle_resource, target_type, target_id)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def hook_context_resource(request_body, target_type, target_id)
|
|
91
|
+
case tested_hook_name
|
|
92
|
+
when 'appointment-book'
|
|
93
|
+
find_appointment_book_resource(request_body, target_type, target_id)
|
|
94
|
+
when 'order-sign', 'order-select'
|
|
95
|
+
find_draft_orders_resource(request_body, target_type, target_id)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def appointment_book_service_request(request_body, appointments_bundle_hash, target_id)
|
|
100
|
+
target_type = 'ServiceRequest'
|
|
101
|
+
appointments_bundle = parse_bundle(appointments_bundle_hash)
|
|
102
|
+
appointment = (appointments_bundle&.entry || [])
|
|
103
|
+
.filter_map(&:resource)
|
|
104
|
+
.find { |candidate| appointment_based_on_matches_target?(candidate, target_type, target_id) }
|
|
105
|
+
return unless appointment
|
|
106
|
+
|
|
107
|
+
find_resource_in_prefetch(request_body, target_type, target_id) ||
|
|
108
|
+
find_resource_in_bundle(mock_ehr_bundle_resource, target_type, target_id)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def appointment_based_on_matches_target?(appointment, target_type, target_id)
|
|
112
|
+
Array(appointment.basedOn).any? do |reference|
|
|
113
|
+
reference_parts(reference.reference) == [target_type, target_id]
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def find_resource_in_prefetch(request_body, target_type, target_id)
|
|
118
|
+
Array(request_body['prefetch']&.values).each do |prefetched_value|
|
|
119
|
+
if prefetched_value.is_a?(Hash) &&
|
|
120
|
+
prefetched_value['resourceType'] == target_type &&
|
|
121
|
+
prefetched_value['id'] == target_id
|
|
122
|
+
return FHIR.from_contents(prefetched_value.to_json)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
resource = find_resource_in_bundle(prefetched_value, target_type, target_id)
|
|
126
|
+
return resource if resource
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
nil
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def find_resource_by_reference(request_body, reference)
|
|
133
|
+
target_type, target_id = reference_parts(reference)
|
|
134
|
+
return unless target_type.present? && target_id.present?
|
|
135
|
+
|
|
136
|
+
find_resource_in_prefetch(request_body, target_type, target_id) ||
|
|
137
|
+
find_resource_in_bundle(mock_ehr_bundle_resource, target_type, target_id)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def find_resource_in_bundle(bundle_hash, target_type, target_id)
|
|
141
|
+
bundle = parse_bundle(bundle_hash)
|
|
142
|
+
return unless bundle&.entry
|
|
143
|
+
|
|
144
|
+
bundle.entry
|
|
145
|
+
.filter_map(&:resource)
|
|
146
|
+
.find { |resource| resource.resourceType == target_type && resource.id == target_id }
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def reference_parts(reference)
|
|
150
|
+
return if reference.blank?
|
|
151
|
+
|
|
152
|
+
parts = reference.split('/')
|
|
153
|
+
return unless parts.length >= 2
|
|
154
|
+
|
|
155
|
+
[parts[-2], parts[-1]]
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def parse_bundle(bundle_hash)
|
|
159
|
+
bundle = FHIR.from_contents(bundle_hash.to_json)
|
|
160
|
+
bundle if bundle.is_a?(FHIR::Bundle)
|
|
161
|
+
rescue StandardError
|
|
162
|
+
nil
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def parse_request_body(request)
|
|
166
|
+
return unless request&.request_body.present?
|
|
167
|
+
|
|
168
|
+
JSON.parse(request.request_body)
|
|
169
|
+
rescue JSON::ParserError
|
|
170
|
+
nil
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
end
|