davinci_crd_test_kit 0.13.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/config/presets/inferno_crd_client_suite.json.erb +20 -14
- data/config/presets/inferno_crd_client_suite_prefetch_subset_v221.json.erb +125 -0
- data/config/presets/inferno_crd_client_suite_v221.json.erb +124 -0
- data/config/presets/inferno_crd_server_suite.json.erb +58 -1
- data/config/presets/inferno_crd_server_suite_v221.json.erb +94 -0
- data/config/presets/ri_crd_request_generator.json_v221.json.erb +13 -0
- data/config/presets/ri_crd_server.json.erb +19 -19
- data/lib/davinci_crd_test_kit/client/client_base_urls.rb +80 -0
- data/lib/davinci_crd_test_kit/{client_hook_request_validation.rb → client/client_hook_request_validation.rb} +1 -1
- data/lib/davinci_crd_test_kit/client/crd_client_options.rb +30 -0
- data/lib/davinci_crd_test_kit/client/endpoints/cds_services_discovery_handler.rb +34 -0
- data/lib/davinci_crd_test_kit/client/endpoints/custom_service_response.rb +342 -0
- data/lib/davinci_crd_test_kit/client/endpoints/gather_response_generation_data.rb +410 -0
- data/lib/davinci_crd_test_kit/client/endpoints/hook_request_endpoint.rb +233 -0
- data/lib/davinci_crd_test_kit/{mock_service_response.rb → client/endpoints/mock_service_response.rb} +165 -59
- data/lib/davinci_crd_test_kit/{card_responses → client/endpoints/mocked_card_responses}/companions_prerequisites.json +1 -0
- data/lib/davinci_crd_test_kit/{card_responses → client/endpoints/mocked_card_responses}/create_update_coverage_information.json +3 -2
- data/lib/davinci_crd_test_kit/{card_responses → client/endpoints/mocked_card_responses}/launch_smart_app.json +8 -1
- data/lib/davinci_crd_test_kit/{card_responses → client/endpoints/mocked_card_responses}/propose_alternate_request.json +1 -0
- data/lib/davinci_crd_test_kit/{card_responses → client/endpoints/mocked_card_responses}/request_form_completion.json +17 -16
- data/lib/davinci_crd_test_kit/client/multi_request_message_helper.rb +35 -0
- data/lib/davinci_crd_test_kit/client/tagged_request_load_helper.rb +38 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/api/client_fhir_api_create_test.rb +43 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/api/client_fhir_api_read_test.rb +43 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/api/client_fhir_api_search_test.rb +234 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/api/client_fhir_api_update_test.rb +43 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/api/client_fhir_api_validation_test.rb +63 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/auth/decode_auth_token_test.rb +65 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/auth/retrieve_jwks_test.rb +109 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/auth/token_header_test.rb +70 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/auth/token_payload_test.rb +85 -0
- data/lib/davinci_crd_test_kit/{routes/cds-services.json → client/v2.0.1/cds-services-v201.json} +1 -1
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_appointment_book_group.rb +108 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_card_must_support_group.rb +31 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_encounter_discharge_group.rb +105 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_encounter_start_group.rb +105 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_fhir_api_group.rb +790 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_hooks_group.rb +74 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_order_dispatch_group.rb +111 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_order_select_group.rb +116 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_order_sign_group.rb +113 -0
- data/lib/davinci_crd_test_kit/{client_registration_group.rb → client/v2.0.1/client_registration_group.rb} +12 -8
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_urls.rb +13 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/crd_client_suite.rb +134 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/invocation/appointment_book_receive_request_test.rb +129 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/invocation/encounter_discharge_receive_request_test.rb +126 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/invocation/encounter_start_receive_request_test.rb +126 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/invocation/order_dispatch_receive_request_test.rb +138 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/invocation/order_select_receive_request_test.rb +134 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/invocation/order_sign_receive_request_test.rb +136 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/must_support/client_card_must_support_coverage_information.rb +93 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/must_support/client_card_must_support_external_reference.rb +62 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/must_support/client_card_must_support_instructions.rb +62 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/registration/client_registration_verification_test.rb +94 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/registration/client_service_registration_attestation_test.rb +40 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_fetched_data_test.rb +86 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_optional_fields_test.rb +63 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_prefetch_equals_queried_test.rb +96 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_required_fields_test.rb +55 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_valid_context_test.rb +70 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_valid_prefetch_test.rb +62 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_response/client_display_cards_attest.rb +83 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_response/inferno_response_validation.rb +79 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/api/client_coverage_info_update_test.rb +212 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/api/client_crd_update_verification_group.rb +18 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/auth/decode_auth_token_test.rb +69 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/auth/retrieve_jwks_test.rb +120 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/auth/token_header_test.rb +92 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/auth/token_payload_test.rb +93 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/cds-services-prefetch-subset-v221.json +198 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/cds-services-v221.json +202 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_appointment_book_group.rb +102 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_cross_hook_group.rb +28 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_encounter_discharge_group.rb +96 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_encounter_start_group.rb +95 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_fhir_api_group.rb +88 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_hooks_group.rb +64 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_long_running_hook_group.rb +32 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_order_dispatch_group.rb +101 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_order_select_group.rb +102 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_order_sign_group.rb +107 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_registration_group.rb +27 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_urls.rb +27 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/crd_client_suite.rb +229 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_card_must_support_coverage_information_test.rb +63 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_fhirpath_collection_as_comma_delimited_string_test.rb +60 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_hook_instances_unique_test.rb +45 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_location_address_propagation_test.rb +135 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_prefetch_complete_and_subset_test.rb +103 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/appointment_book_receive_request_test.rb +156 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/encounter_discharge_receive_request_test.rb +157 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/encounter_start_receive_request_test.rb +157 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/order_dispatch_receive_request_test.rb +165 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/order_select_receive_request_test.rb +165 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/order_sign_receive_request_test.rb +165 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/long_running/client_long_running_receive_request_test.rb +64 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/long_running/client_skip_long_running_attestation_test.rb +49 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/registration/client_registration_verification_test.rb +161 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/registration/client_service_registration_attestation_test.rb +107 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_conformance_test.rb +47 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_coverage_verification_test.rb +152 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_data_fetch_verification_test.rb +55 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_granted_scopes_test.rb +123 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_prefetch_complete_test.rb +127 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_prefetch_profiles_test.rb +55 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_requested_version_test.rb +54 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_secured_transport_test.rb +48 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_response/client_display_cards_attest.rb +74 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_response/hook_response_support_coverage_information_test.rb +30 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_response/inferno_response_validation.rb +77 -0
- data/lib/davinci_crd_test_kit/cross_suite/base_urls.rb +20 -0
- data/lib/davinci_crd_test_kit/cross_suite/cards_identification.rb +312 -0
- data/lib/davinci_crd_test_kit/{cards_validation.rb → cross_suite/cards_validation.rb} +104 -47
- data/lib/davinci_crd_test_kit/cross_suite/coverage-information_stu201_metadata.yml +27 -0
- data/lib/davinci_crd_test_kit/cross_suite/coverage-information_stu221_metadata.yml +60 -0
- data/lib/davinci_crd_test_kit/cross_suite/fhirpath_on_cds_request.rb +177 -0
- data/lib/davinci_crd_test_kit/{hook_request_field_validation.rb → cross_suite/hook_request_field_validation.rb} +282 -203
- data/lib/davinci_crd_test_kit/cross_suite/logical_models_override_helper.rb +220 -0
- data/lib/davinci_crd_test_kit/cross_suite/prefetch_completeness_checker.rb +462 -0
- data/lib/davinci_crd_test_kit/cross_suite/prefetch_contents_validation.rb +81 -0
- data/lib/davinci_crd_test_kit/cross_suite/prefetch_profile_validation.rb +48 -0
- data/lib/davinci_crd_test_kit/cross_suite/profiles_and_resource_types.rb +63 -0
- data/lib/davinci_crd_test_kit/cross_suite/replace_tokens.rb +38 -0
- data/lib/davinci_crd_test_kit/cross_suite/requests_logical_model_validation.rb +202 -0
- data/lib/davinci_crd_test_kit/cross_suite/response_logical_model_validation.rb +274 -0
- data/lib/davinci_crd_test_kit/{suggestion_actions_validation.rb → cross_suite/suggestion_actions_validation.rb} +70 -50
- data/lib/davinci_crd_test_kit/cross_suite/tags.rb +42 -0
- data/lib/davinci_crd_test_kit/metadata.rb +10 -44
- data/lib/davinci_crd_test_kit/requirements/cds-hooks-library_1.0.1_requirements.xlsx +0 -0
- data/lib/davinci_crd_test_kit/requirements/cds-hooks_2.0_requirements.xlsx +0 -0
- data/lib/davinci_crd_test_kit/requirements/cds-hooks_3.0.0-ballot_requirements.xlsx +0 -0
- data/lib/davinci_crd_test_kit/requirements/davinci_crd_test_kit_requirements.csv +742 -65
- data/lib/davinci_crd_test_kit/requirements/generated/crd_client_requirements_coverage.csv +279 -54
- data/lib/davinci_crd_test_kit/requirements/generated/crd_client_v221_requirements_coverage.csv +1430 -0
- data/lib/davinci_crd_test_kit/requirements/generated/crd_server_requirements_coverage.csv +36 -45
- data/lib/davinci_crd_test_kit/requirements/generated/crd_server_v221_requirements_coverage.csv +143 -0
- data/lib/davinci_crd_test_kit/requirements/hl7.fhir.us.davinci-crd_2.0.1_requirements.xlsx +0 -0
- data/lib/davinci_crd_test_kit/requirements/hl7.fhir.us.davinci-crd_2.2.1_requirements.xlsx +0 -0
- data/lib/davinci_crd_test_kit/server/endpoints/jwk_set_endpoint_handler.rb +13 -0
- data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_create_endpoint.rb +23 -0
- data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_delete_endpoint.rb +30 -0
- data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_metadata_endpoint.rb +112 -0
- data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_read_endpoint.rb +21 -0
- data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_request_handler.rb +261 -0
- data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_search_endpoint.rb +561 -0
- data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_update_endpoint.rb +24 -0
- data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/stress-test-Bundle.json +54687 -0
- data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr_endpoints.rb +95 -0
- data/lib/davinci_crd_test_kit/server/jobs/invoke_hook.rb +225 -0
- data/lib/davinci_crd_test_kit/{jwt_helper.rb → server/jwt_helper.rb} +1 -12
- data/lib/davinci_crd_test_kit/server/resource_extractor.rb +68 -0
- data/lib/davinci_crd_test_kit/server/server_abstract_invoke_hook_test.rb +165 -0
- data/lib/davinci_crd_test_kit/server/server_base_urls.rb +30 -0
- data/lib/davinci_crd_test_kit/{server_hook_helper.rb → server/server_hook_helper.rb} +1 -1
- data/lib/davinci_crd_test_kit/{server_hook_request_validation.rb → server/server_hook_request_validation.rb} +1 -1
- data/lib/davinci_crd_test_kit/{test_helper.rb → server/server_test_helper.rb} +7 -3
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Appointment.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/ClaimResponse.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/CommunicationRequest.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Coverage.yml +21 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Device.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/DeviceRequest.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Encounter.yml +7 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Location.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/MedicationRequest.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/NutritionOrder.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Organization.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Patient.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Practitioner.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/PractitionerRole.yml +40 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/ServiceRequest.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Task.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/VisionPrescription.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_server_suite.rb +99 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/discovery/discovery_endpoint_test.rb +90 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/discovery/discovery_services_validation_test.rb +67 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/interaction/server_invoke_hook_test.rb +12 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/must_support/coverage_information_system_action_across_hooks_validation_test.rb +34 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/must_support/external_reference_card_across_hooks_validation_test.rb +30 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/must_support/instructions_card_received_across_hooks_test.rb +27 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_appointment_book_group.rb +191 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_demonstrate_hook_response_group.rb +93 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_discovery_group.rb +62 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_encounter_discharge_group.rb +186 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_encounter_start_group.rb +186 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_hooks_group.rb +73 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_order_dispatch_group.rb +191 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_order_select_group.rb +211 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_order_sign_group.rb +216 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_required_card_response_validation_group.rb +28 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_urls.rb +13 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_request/service_request_context_validation_test.rb +30 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_request/service_request_optional_fields_validation_test.rb +39 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_request/service_request_required_fields_validation_test.rb +40 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/additional_orders_validation_test.rb +59 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/card_optional_fields_validation_test.rb +51 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/coverage_information_system_action_received_test.rb +65 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/coverage_information_system_action_validation_test.rb +120 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/create_or_update_coverage_info_response_validation_test.rb +70 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/external_reference_card_validation_test.rb +37 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/form_completion_response_validation_test.rb +67 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/instructions_card_received_test.rb +30 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/launch_smart_app_card_validation_test.rb +39 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/propose_alternate_request_card_validation_test.rb +46 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/service_response_validation_test.rb +83 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Appointment_withorder.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Appointment_withoutorder.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/CommunicationRequest.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Coverage.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Device.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/DeviceRequest.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Encounter.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Location.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/MedicationRequest.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/NutritionOrder.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Organization.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Patient.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/PractitionerRole.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/ServiceRequest.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/VisionPrescription.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_server_suite.rb +115 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/discovery/discovery_configuration_test.rb +159 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/discovery/discovery_endpoint_test.rb +90 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/discovery/discovery_prefetch_support_test.rb +43 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/discovery/discovery_services_validation_test.rb +121 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/interaction/server_invoke_hook_test.rb +17 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/must_support/coverage_information_must_support_test.rb +71 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/must_support/coverage_information_system_action_across_hooks_validation_test.rb +36 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/must_support/supported_us_core_versions_test.rb +118 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_appointment_book_group.rb +213 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_demonstrate_hook_response_group.rb +93 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_discovery_group.rb +69 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_encounter_discharge_group.rb +194 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_encounter_start_group.rb +194 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_hooks_group.rb +73 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_order_dispatch_group.rb +214 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_order_select_group.rb +219 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_order_sign_group.rb +241 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_required_card_response_validation_group.rb +30 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_urls.rb +13 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_request/service_request_context_validation_test.rb +30 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_request/service_request_no_custom_extensions_test.rb +120 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_request/service_request_optional_fields_validation_test.rb +39 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_request/service_request_required_fields_validation_test.rb +40 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/additional_orders_validation_test.rb +66 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/all_responses_include_coverage_information_test.rb +123 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/card_optional_fields_validation_test.rb +57 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/coverage_info_configuration_test.rb +83 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/coverage_information_system_action_received_test.rb +65 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/coverage_information_system_action_validation_test.rb +184 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/create_or_update_coverage_info_response_validation_test.rb +75 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/external_reference_card_validation_test.rb +47 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/form_completion_response_validation_test.rb +91 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/hook_request_resource_resolution.rb +137 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/instructions_card_received_test.rb +32 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/launch_smart_app_card_validation_test.rb +49 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/order_dispatch_coverage_information_test.rb +38 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/propose_alternate_request_card_validation_test.rb +54 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/service_response_validation_test.rb +97 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/unknown_cds_hooks_elements_test.rb +78 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/unknown_configuration_test.rb +78 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/unknown_context_test.rb +78 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/verify_response_without_billing_options_test.rb +43 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/verify_response_without_configuration_test.rb +44 -0
- data/lib/davinci_crd_test_kit/version.rb +2 -2
- data/lib/davinci_crd_test_kit.rb +4 -2
- metadata +297 -93
- data/lib/davinci_crd_test_kit/client_fhir_api_group.rb +0 -785
- data/lib/davinci_crd_test_kit/client_hooks_group.rb +0 -74
- data/lib/davinci_crd_test_kit/client_tests/appointment_book_receive_request_test.rb +0 -93
- data/lib/davinci_crd_test_kit/client_tests/client_appointment_book_group.rb +0 -75
- data/lib/davinci_crd_test_kit/client_tests/client_display_cards_attest.rb +0 -48
- data/lib/davinci_crd_test_kit/client_tests/client_encounter_discharge_group.rb +0 -73
- data/lib/davinci_crd_test_kit/client_tests/client_encounter_start_group.rb +0 -73
- data/lib/davinci_crd_test_kit/client_tests/client_fhir_api_create_test.rb +0 -42
- data/lib/davinci_crd_test_kit/client_tests/client_fhir_api_read_test.rb +0 -40
- data/lib/davinci_crd_test_kit/client_tests/client_fhir_api_search_test.rb +0 -232
- data/lib/davinci_crd_test_kit/client_tests/client_fhir_api_update_test.rb +0 -42
- data/lib/davinci_crd_test_kit/client_tests/client_fhir_api_validation_test.rb +0 -61
- data/lib/davinci_crd_test_kit/client_tests/client_order_dispatch_group.rb +0 -79
- data/lib/davinci_crd_test_kit/client_tests/client_order_select_group.rb +0 -82
- data/lib/davinci_crd_test_kit/client_tests/client_order_sign_group.rb +0 -81
- data/lib/davinci_crd_test_kit/client_tests/client_registration_verification_test.rb +0 -88
- data/lib/davinci_crd_test_kit/client_tests/decode_auth_token_test.rb +0 -60
- data/lib/davinci_crd_test_kit/client_tests/encounter_discharge_receive_request_test.rb +0 -90
- data/lib/davinci_crd_test_kit/client_tests/encounter_start_receive_request_test.rb +0 -90
- data/lib/davinci_crd_test_kit/client_tests/hook_request_optional_fields_test.rb +0 -57
- data/lib/davinci_crd_test_kit/client_tests/hook_request_required_fields_test.rb +0 -49
- data/lib/davinci_crd_test_kit/client_tests/hook_request_valid_context_test.rb +0 -68
- data/lib/davinci_crd_test_kit/client_tests/hook_request_valid_prefetch_test.rb +0 -69
- data/lib/davinci_crd_test_kit/client_tests/order_dispatch_receive_request_test.rb +0 -102
- data/lib/davinci_crd_test_kit/client_tests/order_select_receive_request_test.rb +0 -98
- data/lib/davinci_crd_test_kit/client_tests/order_sign_receive_request_test.rb +0 -101
- data/lib/davinci_crd_test_kit/client_tests/retrieve_jwks_test.rb +0 -105
- data/lib/davinci_crd_test_kit/client_tests/submitted_response_validation.rb +0 -48
- data/lib/davinci_crd_test_kit/client_tests/token_header_test.rb +0 -65
- data/lib/davinci_crd_test_kit/client_tests/token_payload_test.rb +0 -78
- data/lib/davinci_crd_test_kit/crd_client_suite.rb +0 -193
- data/lib/davinci_crd_test_kit/crd_options.rb +0 -9
- data/lib/davinci_crd_test_kit/crd_server_suite.rb +0 -125
- data/lib/davinci_crd_test_kit/igs/davinci-crd-2.0.1.tgz +0 -0
- data/lib/davinci_crd_test_kit/routes/cds_services_discovery_handler.rb +0 -18
- data/lib/davinci_crd_test_kit/routes/hook_request_endpoint.rb +0 -77
- data/lib/davinci_crd_test_kit/routes/jwk_set_endpoint_handler.rb +0 -15
- data/lib/davinci_crd_test_kit/server_appointment_book_group.rb +0 -176
- data/lib/davinci_crd_test_kit/server_demonstrate_hook_response_group.rb +0 -77
- data/lib/davinci_crd_test_kit/server_discovery_group.rb +0 -60
- data/lib/davinci_crd_test_kit/server_encounter_discharge_group.rb +0 -170
- data/lib/davinci_crd_test_kit/server_encounter_start_group.rb +0 -170
- data/lib/davinci_crd_test_kit/server_hooks_group.rb +0 -71
- data/lib/davinci_crd_test_kit/server_order_dispatch_group.rb +0 -176
- data/lib/davinci_crd_test_kit/server_order_select_group.rb +0 -195
- data/lib/davinci_crd_test_kit/server_order_sign_group.rb +0 -201
- data/lib/davinci_crd_test_kit/server_required_card_response_validation_group.rb +0 -26
- data/lib/davinci_crd_test_kit/server_tests/additional_orders_validation_test.rb +0 -68
- data/lib/davinci_crd_test_kit/server_tests/card_optional_fields_validation_test.rb +0 -47
- data/lib/davinci_crd_test_kit/server_tests/coverage_information_system_action_across_hooks_validation_test.rb +0 -32
- data/lib/davinci_crd_test_kit/server_tests/coverage_information_system_action_received_test.rb +0 -63
- data/lib/davinci_crd_test_kit/server_tests/coverage_information_system_action_validation_test.rb +0 -118
- data/lib/davinci_crd_test_kit/server_tests/create_or_update_coverage_info_response_validation_test.rb +0 -71
- data/lib/davinci_crd_test_kit/server_tests/discovery_endpoint_test.rb +0 -88
- data/lib/davinci_crd_test_kit/server_tests/discovery_services_validation_test.rb +0 -65
- data/lib/davinci_crd_test_kit/server_tests/external_reference_card_across_hooks_validation_test.rb +0 -28
- data/lib/davinci_crd_test_kit/server_tests/external_reference_card_validation_test.rb +0 -36
- data/lib/davinci_crd_test_kit/server_tests/form_completion_response_validation_test.rb +0 -78
- data/lib/davinci_crd_test_kit/server_tests/instructions_card_received_across_hooks_test.rb +0 -25
- data/lib/davinci_crd_test_kit/server_tests/instructions_card_received_test.rb +0 -26
- data/lib/davinci_crd_test_kit/server_tests/launch_smart_app_card_validation_test.rb +0 -38
- data/lib/davinci_crd_test_kit/server_tests/propose_alternate_request_card_validation_test.rb +0 -63
- data/lib/davinci_crd_test_kit/server_tests/service_call_test.rb +0 -101
- data/lib/davinci_crd_test_kit/server_tests/service_request_context_validation_test.rb +0 -28
- data/lib/davinci_crd_test_kit/server_tests/service_request_optional_fields_validation_test.rb +0 -37
- data/lib/davinci_crd_test_kit/server_tests/service_request_required_fields_validation_test.rb +0 -38
- data/lib/davinci_crd_test_kit/server_tests/service_response_validation_test.rb +0 -81
- data/lib/davinci_crd_test_kit/tags.rb +0 -10
- data/lib/davinci_crd_test_kit/urls.rb +0 -52
- /data/lib/davinci_crd_test_kit/{card_responses → client/endpoints/mocked_card_responses}/external_reference.json +0 -0
- /data/lib/davinci_crd_test_kit/{card_responses → client/endpoints/mocked_card_responses}/instructions.json +0 -0
- /data/lib/davinci_crd_test_kit/{crd_jwks.json → server/endpoints/crd_jwks.json} +0 -0
- /data/lib/davinci_crd_test_kit/{jwks.rb → server/endpoints/jwks.rb} +0 -0
data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_requested_version_test.rb
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require_relative '../../multi_request_message_helper'
|
|
2
|
+
require_relative '../../tagged_request_load_helper'
|
|
3
|
+
|
|
4
|
+
module DaVinciCRDTestKit
|
|
5
|
+
module V221
|
|
6
|
+
class HookRequestRequestedVersionTest < Inferno::Test
|
|
7
|
+
include DaVinciCRDTestKit::MultiRequestMessageHelper
|
|
8
|
+
include DaVinciCRDTestKit::TaggedRequestLoadHelper
|
|
9
|
+
|
|
10
|
+
id :crd_v221_hook_request_requested_version
|
|
11
|
+
title 'Hook requests contains the CRD version extension'
|
|
12
|
+
description %(
|
|
13
|
+
Inferno's CRD service supports multiple versions of CRD, so [clients are required](https://hl7.org/fhir/us/davinci-crd/2.2.1/en/conformancedetails.html#ci-c-dev-3)
|
|
14
|
+
to specify the requested version using the `davinci-crd.requestedVersion` extension on each request.
|
|
15
|
+
|
|
16
|
+
During this test, Inferno will verify that the body of each hook request contains
|
|
17
|
+
the `davinci-crd.requestedVersion` extension with the correct value: "2.2".
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
verifies_requirements 'cds-hooks_3.0.0-ballot@214', 'hl7.fhir.us.davinci-crd_2.2.1@dev-3-A',
|
|
21
|
+
'hl7.fhir.us.davinci-crd_2.2.1@dev-12'
|
|
22
|
+
|
|
23
|
+
run do
|
|
24
|
+
hook_requests = load_hook_requests
|
|
25
|
+
|
|
26
|
+
skip_if hook_requests.blank?, "No #{hook_name} hook requests received."
|
|
27
|
+
|
|
28
|
+
hook_requests.each_with_index do |request, request_index|
|
|
29
|
+
request_body = parse_json_request_entity(request.request_body, 'Request body', request_index)
|
|
30
|
+
next unless request_body.present?
|
|
31
|
+
|
|
32
|
+
requested_version = request_body.dig('extension', 'davinci-crd.requestedVersion')
|
|
33
|
+
if requested_version.blank?
|
|
34
|
+
add_request_message('error', "Required extension 'davinci-crd.requestedVersion' is not present.",
|
|
35
|
+
request_index)
|
|
36
|
+
elsif !requested_version.is_a?(String)
|
|
37
|
+
add_request_message('error',
|
|
38
|
+
"For extension 'davinci-crd.requestedVersion' expected a String, " \
|
|
39
|
+
"got #{requested_version.class}",
|
|
40
|
+
request_index)
|
|
41
|
+
elsif requested_version != '2.2'
|
|
42
|
+
add_request_message('error',
|
|
43
|
+
"For extension 'davinci-crd.requestedVersion' expected '2.2', " \
|
|
44
|
+
"got '#{requested_version}'",
|
|
45
|
+
request_index)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
assert_no_error_messages("#{requests_with_errors_prefix}Requested version extension not populated properly. " \
|
|
50
|
+
'See Messages for details.')
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_secured_transport_test.rb
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
require_relative '../../multi_request_message_helper'
|
|
2
|
+
require_relative '../../tagged_request_load_helper'
|
|
3
|
+
|
|
4
|
+
module DaVinciCRDTestKit
|
|
5
|
+
module V221
|
|
6
|
+
class HookRequestSecuredTransportTest < Inferno::Test
|
|
7
|
+
include DaVinciCRDTestKit::MultiRequestMessageHelper
|
|
8
|
+
include DaVinciCRDTestKit::TaggedRequestLoadHelper
|
|
9
|
+
|
|
10
|
+
id :crd_v221_hook_request_secured_transport
|
|
11
|
+
title 'Hook request interactions use TLS'
|
|
12
|
+
description %(
|
|
13
|
+
During this test, Inferno will verify that
|
|
14
|
+
requests made by both the client and Inferno's simulated CRD servers are made against
|
|
15
|
+
TLS-secured endpoints using the `https` protocol.
|
|
16
|
+
)
|
|
17
|
+
verifies_requirements 'cds-hooks_3.0.0-ballot@2', 'cds-hooks_3.0.0-ballot@168', 'cds-hooks_3.0.0-ballot@172',
|
|
18
|
+
'hl7.fhir.us.davinci-crd_2.2.1@sec-2'
|
|
19
|
+
|
|
20
|
+
run do
|
|
21
|
+
hook_requests = load_hook_requests
|
|
22
|
+
|
|
23
|
+
skip_if hook_requests.blank?, "No #{hook_name} hook requests received."
|
|
24
|
+
|
|
25
|
+
hook_requests.each_with_index do |request, request_index|
|
|
26
|
+
unless request.url.starts_with?('https')
|
|
27
|
+
add_request_message('error',
|
|
28
|
+
"Inferno's simulated CRD server must use the https " \
|
|
29
|
+
'protocol (TLS). Run this suite on a host that uses TLS.',
|
|
30
|
+
request_index)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# check that the fhirServer endpoint uses https
|
|
34
|
+
request_body = parse_json_request_entity(request.request_body, 'Request body', request_index)
|
|
35
|
+
next unless request_body.present?
|
|
36
|
+
next unless request_body['fhirServer'].present? && !request_body['fhirServer'].starts_with?('https')
|
|
37
|
+
|
|
38
|
+
add_request_message('error',
|
|
39
|
+
'The `fhirServer` provided in the request must use the https protocol (TLS).',
|
|
40
|
+
request_index)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
assert_no_error_messages("#{requests_with_errors_prefix}Interactions not secured using TLS. " \
|
|
44
|
+
'See Messages for details.')
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
require_relative '../client_urls'
|
|
2
|
+
require_relative '../../../cross_suite/cards_identification'
|
|
3
|
+
require_relative '../../tagged_request_load_helper'
|
|
4
|
+
|
|
5
|
+
module DaVinciCRDTestKit
|
|
6
|
+
module V221
|
|
7
|
+
class ClientCardDisplayAttest < Inferno::Test
|
|
8
|
+
include ClientURLs
|
|
9
|
+
include CardsIdentification
|
|
10
|
+
include DaVinciCRDTestKit::TaggedRequestLoadHelper
|
|
11
|
+
|
|
12
|
+
id :crd_v221_card_display_attest_test
|
|
13
|
+
title 'Client displays returned decision support details to the user (Attestation)'
|
|
14
|
+
description %(
|
|
15
|
+
During this test, the tester will confirm that the received cards and actions in the
|
|
16
|
+
hook responses have been displayed or otherwise made available to users of the client system
|
|
17
|
+
in an appopriate way that allows for consideration and action if warranted.
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
def responded_card_types
|
|
21
|
+
list_card_types_in_requests(requests)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def format_responded_response_types
|
|
25
|
+
responded_card_types
|
|
26
|
+
.map do |response_type|
|
|
27
|
+
response_type_string =
|
|
28
|
+
response_type.split('_')
|
|
29
|
+
.map(&:capitalize)
|
|
30
|
+
.join(' ')
|
|
31
|
+
.prepend('- ')
|
|
32
|
+
.sub('Smart', 'SMART')
|
|
33
|
+
.sub('Create Update', 'Create/Update')
|
|
34
|
+
.sub('Companions Prerequisites', 'Companions/Prerequisites')
|
|
35
|
+
.sub('Card', '(card)')
|
|
36
|
+
.sub('Action', '(systemAction)')
|
|
37
|
+
response_type_string
|
|
38
|
+
end
|
|
39
|
+
.join("\n")
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
output :attest_true_url
|
|
43
|
+
output :attest_false_url
|
|
44
|
+
|
|
45
|
+
run do
|
|
46
|
+
load_hook_requests
|
|
47
|
+
skip_if responded_card_types.blank?, 'No responses sent to the client.'
|
|
48
|
+
|
|
49
|
+
identifier = SecureRandom.hex(32)
|
|
50
|
+
attest_true_url = "#{resume_pass_url}?token=#{identifier}"
|
|
51
|
+
attest_false_url = "#{resume_fail_url}?token=#{identifier}"
|
|
52
|
+
output(attest_true_url:)
|
|
53
|
+
output(attest_false_url:)
|
|
54
|
+
wait(
|
|
55
|
+
identifier:,
|
|
56
|
+
message: <<~MESSAGE
|
|
57
|
+
**Card Display Attestation**:
|
|
58
|
+
|
|
59
|
+
I attest that the following CRD response types returned by Inferno's simulated
|
|
60
|
+
CRD servers were processed by the client system and displayed or otherwise made
|
|
61
|
+
available to users of the client system in an appropriate way that allows for
|
|
62
|
+
consideration and action if warranted:
|
|
63
|
+
|
|
64
|
+
#{format_responded_response_types}
|
|
65
|
+
|
|
66
|
+
[Click here](#{attest_true_url}) if the above statement is **true**.
|
|
67
|
+
|
|
68
|
+
[Click here](#{attest_false_url}) if the above statement is **false**.
|
|
69
|
+
MESSAGE
|
|
70
|
+
)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require_relative '../../../cross_suite/cards_identification'
|
|
2
|
+
require_relative '../../tagged_request_load_helper'
|
|
3
|
+
|
|
4
|
+
module DaVinciCRDTestKit
|
|
5
|
+
module V221
|
|
6
|
+
class ClientHookResponseSupportCoverageInformationTest < Inferno::Test
|
|
7
|
+
include CardsIdentification
|
|
8
|
+
include TaggedRequestLoadHelper
|
|
9
|
+
|
|
10
|
+
title 'Client supports the Coverage Information response type on this hook'
|
|
11
|
+
id :crd_v221_client_hook_response_support_coverage_information
|
|
12
|
+
description <<~DESCRIPTION
|
|
13
|
+
During this test, Inferno will verify that the client demonstrated support for the [Coverage Information](https://hl7.org/fhir/us/davinci-crd/2.2.1/en/cards.html#coverage-information)
|
|
14
|
+
response type. At least one hook invocation performed during this group must have returned a Coverage Information action.
|
|
15
|
+
|
|
16
|
+
If this test fails, adjust the [cards returned by Inferno's simulated CRD server](https://github.com/inferno-framework/davinci-crd-test-kit/wiki/Controlling-Simulated-Responses)
|
|
17
|
+
and/or the hook requests made by the client during this group such that a Coverage Information action is returned.
|
|
18
|
+
DESCRIPTION
|
|
19
|
+
|
|
20
|
+
run do
|
|
21
|
+
hook_requests = load_hook_requests
|
|
22
|
+
skip_if hook_requests.blank?, "No #{hook_name} hook requests received."
|
|
23
|
+
|
|
24
|
+
sorted_cards = sorted_cards_from_requests(hook_requests)
|
|
25
|
+
assert sorted_cards['actions'][COVERAGE_INFORMATION_RESPONSE_TYPE].present?,
|
|
26
|
+
"Support for the Coverage Information response type not demonstrated for the #{hook_name} hook."
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
require_relative '../../../cross_suite/cards_validation'
|
|
2
|
+
require_relative '../../../cross_suite/response_logical_model_validation'
|
|
3
|
+
require_relative '../../tagged_request_load_helper'
|
|
4
|
+
|
|
5
|
+
module DaVinciCRDTestKit
|
|
6
|
+
module V221
|
|
7
|
+
class InfernoResponseValidationTest < Inferno::Test
|
|
8
|
+
include CardsValidation
|
|
9
|
+
include ResponseLogicalModelValidation
|
|
10
|
+
include DaVinciCRDTestKit::TaggedRequestLoadHelper
|
|
11
|
+
|
|
12
|
+
title 'Hook responses have the correct structure and content'
|
|
13
|
+
description %(
|
|
14
|
+
During this test, Inferno will verify that each hook response built by Inferno's simulated CRD servers
|
|
15
|
+
and returned to the client conforms to CDS Hooks and CRD requirements. These responses must be conformant
|
|
16
|
+
for the client to demonstrate its ability to accept and process valid CRD responses.
|
|
17
|
+
|
|
18
|
+
If this test fails when the tester provided a custom response template, adjust the
|
|
19
|
+
provided template and the submitted requests so that the response built by Inferno
|
|
20
|
+
is conformant. If this test fails when Inferno mocked the response based on selected
|
|
21
|
+
card types, first ensure that the client's request is conformant. If the request is conformant
|
|
22
|
+
but Inferno's response(s) are still not conformant, please report this failure to the
|
|
23
|
+
Inferno team via [GitHub Issues](https://github.com/inferno-framework/davinci-crd-test-kit/issues).
|
|
24
|
+
For more details on how Inferno builds responses, see the
|
|
25
|
+
[Controlling Simulated Responses](https://github.com/inferno-framework/davinci-crd-test-kit/wiki/Controlling-Simulated-Responses)
|
|
26
|
+
section of the [CRD Test Kit Wiki](https://github.com/inferno-framework/davinci-crd-test-kit/wiki).
|
|
27
|
+
)
|
|
28
|
+
id :crd_v221_inferno_response_validation
|
|
29
|
+
simulation_verification
|
|
30
|
+
|
|
31
|
+
verifies_requirements 'cds-hooks_3.0.0-ballot@3', 'cds-hooks_3.0.0-ballot@222', 'cds-hooks_3.0.0-ballot@223',
|
|
32
|
+
'cds-hooks_3.0.0-ballot@224'
|
|
33
|
+
|
|
34
|
+
input :custom_response_template, optional: true
|
|
35
|
+
|
|
36
|
+
def response_label(index = nil)
|
|
37
|
+
response_type = (custom_response_template.present? ? 'Custom built' : 'Mocked')
|
|
38
|
+
"#{response_type} response#{" #{index}" if index.present?}"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def validate_card_summaries(cards)
|
|
42
|
+
return unless cards.is_a?(Array)
|
|
43
|
+
|
|
44
|
+
cards.each { |card| card_summary_check(card) if card.is_a?(Hash) }
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
run do
|
|
48
|
+
load_hook_requests
|
|
49
|
+
|
|
50
|
+
skip_if request.blank?, "No #{response_label.downcase}s to verify."
|
|
51
|
+
|
|
52
|
+
entity_validated = false
|
|
53
|
+
requests.each_with_index do |request, index|
|
|
54
|
+
response_hash = JSON.parse(request.response_body)
|
|
55
|
+
request_hash = JSON.parse(request.request_body)
|
|
56
|
+
|
|
57
|
+
next unless response_hash['cards'].present? || response_hash['systemActions'].present?
|
|
58
|
+
|
|
59
|
+
entity_validated = true
|
|
60
|
+
validate_card_summaries(response_hash['cards'])
|
|
61
|
+
perform_response_logical_model_validation(response_hash['cards'],
|
|
62
|
+
response_hash['systemActions'],
|
|
63
|
+
request_hash,
|
|
64
|
+
index,
|
|
65
|
+
'2.2.1')
|
|
66
|
+
rescue JSON::ParserError
|
|
67
|
+
next
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
skip_if !entity_validated,
|
|
71
|
+
"No #{response_label.downcase} cards or system actions to verify returned by Inferno."
|
|
72
|
+
|
|
73
|
+
no_error_validation("Invalid Inferno #{response_label.downcase}(s). See Messages for details.")
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module DaVinciCRDTestKit
|
|
2
|
+
RESUME_PASS_PATH = '/resume_pass'.freeze
|
|
3
|
+
RESUME_FAIL_PATH = '/resume_fail'.freeze
|
|
4
|
+
|
|
5
|
+
# base url, plus other shared ones such as resume urls
|
|
6
|
+
# suite_id must be defined
|
|
7
|
+
module BaseURLs
|
|
8
|
+
def inferno_base_url
|
|
9
|
+
@inferno_base_url ||= "#{Inferno::Application['base_url']}/custom/#{suite_id}"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def resume_pass_url
|
|
13
|
+
@resume_pass_url ||= inferno_base_url + RESUME_PASS_PATH
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def resume_fail_url
|
|
17
|
+
@resume_fail_url ||= inferno_base_url + RESUME_FAIL_PATH
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
require_relative 'hook_request_field_validation'
|
|
2
|
+
require_relative 'suggestion_actions_validation'
|
|
3
|
+
|
|
4
|
+
module DaVinciCRDTestKit
|
|
5
|
+
module CardsIdentification
|
|
6
|
+
include DaVinciCRDTestKit::SuggestionActionsValidation
|
|
7
|
+
include DaVinciCRDTestKit::HookRequestFieldValidation
|
|
8
|
+
|
|
9
|
+
COVERAGE_INFO_EXT_URL = 'http://hl7.org/fhir/us/davinci-crd/StructureDefinition/ext-coverage-information'.freeze
|
|
10
|
+
|
|
11
|
+
ADDITIONAL_ORDERS_RESPONSE_TYPE = 'companions_prerequisites'.freeze
|
|
12
|
+
COVERAGE_INFORMATION_RESPONSE_TYPE = 'coverage_information'.freeze
|
|
13
|
+
CREATE_OR_UPDATE_COVERAGE_RESPONSE_TYPE = 'create_update_coverage_info'.freeze
|
|
14
|
+
EXTERNAL_REFERENCE_RESPONSE_TYPE = 'external_reference'.freeze
|
|
15
|
+
FORM_COMPLETION_RESPONSE_TYPE = 'request_form_completion'.freeze
|
|
16
|
+
INSTRUCTIONS_RESPONSE_TYPE = 'instructions'.freeze
|
|
17
|
+
LAUNCH_SMART_APP_RESPONSE_TYPE = 'launch_smart_app'.freeze
|
|
18
|
+
PROPOSE_ALTERNATIVE_REQUEST_RESPONSE_TYPE = 'propose_alternate_request'.freeze
|
|
19
|
+
COVERAGE_INFO_CONFIGURATION_CODE = 'coverage-info'.freeze
|
|
20
|
+
|
|
21
|
+
ADDITIONAL_ORDERS_EXPECTED_RESOURCE_TYPES = %w[
|
|
22
|
+
CommunicationRequest Device DeviceRequest Medication
|
|
23
|
+
MedicationRequest NutritionOrder ServiceRequest
|
|
24
|
+
VisionPrescription
|
|
25
|
+
].freeze
|
|
26
|
+
|
|
27
|
+
PROPOSE_ALTERNATIVE_REQUEST_EXPECTED_RESOURCE_TYPES = %w[
|
|
28
|
+
CommunicationRequest Device DeviceRequest Encounter Medication
|
|
29
|
+
MedicationRequest NutritionOrder ServiceRequest
|
|
30
|
+
VisionPrescription
|
|
31
|
+
].freeze
|
|
32
|
+
|
|
33
|
+
COVERAGE_INFO_EXPECTED_RESOURCE_TYPES = %w[
|
|
34
|
+
Appointment CommunicationRequest DeviceRequest Encounter MedicationRequest
|
|
35
|
+
NutritionOrder ServiceRequest VisionPrescription
|
|
36
|
+
].freeze
|
|
37
|
+
|
|
38
|
+
def identify_card_type(card) # rubocop:disable Metrics/CyclomaticComplexity
|
|
39
|
+
return nil if card['type'].present? # action, not a card
|
|
40
|
+
return ADDITIONAL_ORDERS_RESPONSE_TYPE if additional_orders_response_type?(card)
|
|
41
|
+
return CREATE_OR_UPDATE_COVERAGE_RESPONSE_TYPE if create_or_update_coverage_card_response_type?(card)
|
|
42
|
+
return EXTERNAL_REFERENCE_RESPONSE_TYPE if external_reference_response_type?(card)
|
|
43
|
+
return FORM_COMPLETION_RESPONSE_TYPE if form_completion_card_response_type?(card)
|
|
44
|
+
return INSTRUCTIONS_RESPONSE_TYPE if instructions_response_type?(card)
|
|
45
|
+
return LAUNCH_SMART_APP_RESPONSE_TYPE if launch_smart_app_response_type?(card)
|
|
46
|
+
return PROPOSE_ALTERNATIVE_REQUEST_RESPONSE_TYPE if propose_alternative_request_response_type?(card)
|
|
47
|
+
|
|
48
|
+
nil
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def identify_action_type(action)
|
|
52
|
+
return nil unless action['type'].present? # card, not an action
|
|
53
|
+
return COVERAGE_INFORMATION_RESPONSE_TYPE if coverage_information_response_type?(action)
|
|
54
|
+
return CREATE_OR_UPDATE_COVERAGE_RESPONSE_TYPE if create_or_update_coverage_action_response_type?(action)
|
|
55
|
+
return FORM_COMPLETION_RESPONSE_TYPE if form_completion_action_response_type?(action)
|
|
56
|
+
|
|
57
|
+
nil
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def coverage_info_card_type?(card)
|
|
61
|
+
return false unless card.respond_to?(:dig)
|
|
62
|
+
|
|
63
|
+
card.dig('source', 'topic', 'code') == COVERAGE_INFO_CONFIGURATION_CODE
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def coverage_info_system_action_type?(action)
|
|
67
|
+
return false unless action.respond_to?(:[])
|
|
68
|
+
|
|
69
|
+
[COVERAGE_INFORMATION_RESPONSE_TYPE, FORM_COMPLETION_RESPONSE_TYPE].include?(identify_action_type(action))
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def coverage_info_content(response_body)
|
|
73
|
+
return [[], []] unless response_body.is_a?(Hash)
|
|
74
|
+
|
|
75
|
+
cards =
|
|
76
|
+
if response_body['cards'].is_a?(Array)
|
|
77
|
+
response_body['cards'].select { |card| coverage_info_card_type?(card) }
|
|
78
|
+
else
|
|
79
|
+
[]
|
|
80
|
+
end
|
|
81
|
+
actions =
|
|
82
|
+
if response_body['systemActions'].is_a?(Array)
|
|
83
|
+
response_body['systemActions'].select { |action| coverage_info_system_action_type?(action) }
|
|
84
|
+
else
|
|
85
|
+
[]
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
[cards, actions]
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def coverage_info_response?(response_body)
|
|
92
|
+
cards, actions = coverage_info_content(response_body)
|
|
93
|
+
|
|
94
|
+
cards.present? || actions.present?
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def coverage_info_configuration_disabled?(request_body)
|
|
98
|
+
request_body.is_a?(Hash) &&
|
|
99
|
+
request_body.dig('extension', 'davinci-crd.configuration', COVERAGE_INFO_CONFIGURATION_CODE) == false
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def disable_coverage_info_configuration!(request_body)
|
|
103
|
+
request_body['extension'] = {} unless request_body['extension'].is_a?(Hash)
|
|
104
|
+
unless request_body['extension']['davinci-crd.configuration'].is_a?(Hash)
|
|
105
|
+
request_body['extension']['davinci-crd.configuration'] = {}
|
|
106
|
+
end
|
|
107
|
+
request_body['extension']['davinci-crd.configuration'][COVERAGE_INFO_CONFIGURATION_CODE] = false
|
|
108
|
+
|
|
109
|
+
request_body
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def additional_orders_response_type?(card, expected_resource_types: ADDITIONAL_ORDERS_EXPECTED_RESOURCE_TYPES)
|
|
113
|
+
return false if card['suggestions'].blank?
|
|
114
|
+
|
|
115
|
+
card['suggestions'].all? do |suggestion|
|
|
116
|
+
actions = suggestion['actions']
|
|
117
|
+
actions&.all? do |action|
|
|
118
|
+
action['type'] == 'create' &&
|
|
119
|
+
(expected_resource_types.blank? || action_resource_type_check(action, expected_resource_types))
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def coverage_information_response_type?(action) # rubocop:disable Metrics/CyclomaticComplexity
|
|
125
|
+
return false unless action.respond_to?(:[])
|
|
126
|
+
|
|
127
|
+
resource = action['resource']&.to_hash
|
|
128
|
+
return false unless COVERAGE_INFO_EXPECTED_RESOURCE_TYPES.include? resource&.dig('resourceType')
|
|
129
|
+
|
|
130
|
+
unless resource&.dig('extension')&.any? { |extension| extension_url(extension) == COVERAGE_INFO_EXT_URL }
|
|
131
|
+
return false
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
true
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def extension_url(extension)
|
|
138
|
+
return extension.url if extension.respond_to?(:url)
|
|
139
|
+
return extension['url'] if extension.respond_to?(:[])
|
|
140
|
+
|
|
141
|
+
nil
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def create_or_update_coverage_card_response_type?(card)
|
|
145
|
+
card['suggestions']&.one? && card['suggestions'].first['actions']&.one? do |action|
|
|
146
|
+
create_or_update_coverage_action_response_type?(action)
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def create_or_update_coverage_action_response_type?(action)
|
|
151
|
+
['create', 'update'].include?(action['type']) && action_resource_type_check(action, ['Coverage'])
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def create_questionnaire_action_response_type?(action)
|
|
155
|
+
action['type'] == 'create' && action_resource_type_check(action, ['Questionnaire'])
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def external_reference_response_type?(card)
|
|
159
|
+
links = card['links']
|
|
160
|
+
return false if links.blank?
|
|
161
|
+
|
|
162
|
+
links.all? { |link| link['type'] == 'absolute' }
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def form_completion_card_response_type?(card)
|
|
166
|
+
card['suggestions']&.all? do |suggestion|
|
|
167
|
+
suggestion['actions']&.one? { |action| form_completion_action_response_type?(action) }
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def form_completion_action_response_type?(action)
|
|
172
|
+
action['type'] == 'create' &&
|
|
173
|
+
action_resource_type_check(action, ['Task']) &&
|
|
174
|
+
form_completion_task_questionnaire?(action['resource'])
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def form_completion_task_questionnaire?(task_action)
|
|
178
|
+
task_action.dig('code', 'coding')&.any? { |code| code['code'] == 'complete-questionnaire' } &&
|
|
179
|
+
task_action['input']&.any? do |input|
|
|
180
|
+
input.dig('type', 'text') == 'questionnaire' && valid_url?(input['valueCanonical'])
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def instructions_response_type?(card)
|
|
185
|
+
card['links'].blank? && card['suggestions'].blank?
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def launch_smart_app_response_type?(card)
|
|
189
|
+
links = card['links']
|
|
190
|
+
return false if links.blank?
|
|
191
|
+
|
|
192
|
+
links.all? { |link| link['type'] == 'smart' }
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def propose_alternative_request_response_type?(
|
|
196
|
+
card,
|
|
197
|
+
expected_resource_types: PROPOSE_ALTERNATIVE_REQUEST_EXPECTED_RESOURCE_TYPES
|
|
198
|
+
)
|
|
199
|
+
card['suggestions']&.any? do |suggestion|
|
|
200
|
+
actions = suggestion['actions']
|
|
201
|
+
has_update = check_action_type(actions, 'update', expected_resource_types)
|
|
202
|
+
has_delete = check_action_type(actions, 'delete', expected_resource_types)
|
|
203
|
+
has_create = check_action_type(actions, 'create', expected_resource_types)
|
|
204
|
+
|
|
205
|
+
has_update || (has_delete && has_create)
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
def check_action_type(actions, action_type, expected_resource_types)
|
|
210
|
+
actions&.any? do |action|
|
|
211
|
+
action['type'] == action_type &&
|
|
212
|
+
(expected_resource_types.blank? || action_resource_type_check(action, expected_resource_types))
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
def list_card_types_in_requests(hooks_requests)
|
|
217
|
+
sorted_cards = sorted_cards_from_requests(hooks_requests)
|
|
218
|
+
|
|
219
|
+
present_card_types = sorted_cards['cards'].select { |key, value| key.present? && value.present? }.keys
|
|
220
|
+
present_action_types = sorted_cards['actions'].select { |key, value| key.present? && value.present? }.keys
|
|
221
|
+
|
|
222
|
+
present_card_types.map { |type| "#{type}_card" } + present_action_types.map { |type| "#{type}_action" }
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
def sorted_cards_from_requests(hooks_requests)
|
|
226
|
+
return sorted_cards_from_cache if sorted_cards_cached?(hooks_requests)
|
|
227
|
+
|
|
228
|
+
sorted_cards = initialize_sorted_cards_hash
|
|
229
|
+
|
|
230
|
+
hooks_requests.each do |request|
|
|
231
|
+
sort_card_types_from_request(request, sorted_cards)
|
|
232
|
+
rescue JSON::ParserError
|
|
233
|
+
next
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
cache_sorted_cards(hooks_requests, sorted_cards)
|
|
237
|
+
sorted_cards
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def sort_card_types_from_request(request, sorted_cards)
|
|
241
|
+
response_body = JSON.parse(request.response_body)
|
|
242
|
+
response_body['cards']&.each do |card|
|
|
243
|
+
sorted_cards['cards'][identify_card_type(card)] << card
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
response_body['systemActions']&.each do |action|
|
|
247
|
+
sorted_cards['actions'][identify_action_type(action)] << action
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
def initialize_sorted_cards_hash
|
|
252
|
+
{
|
|
253
|
+
'cards' => {
|
|
254
|
+
ADDITIONAL_ORDERS_RESPONSE_TYPE => [],
|
|
255
|
+
CREATE_OR_UPDATE_COVERAGE_RESPONSE_TYPE => [],
|
|
256
|
+
EXTERNAL_REFERENCE_RESPONSE_TYPE => [],
|
|
257
|
+
FORM_COMPLETION_RESPONSE_TYPE => [],
|
|
258
|
+
INSTRUCTIONS_RESPONSE_TYPE => [],
|
|
259
|
+
LAUNCH_SMART_APP_RESPONSE_TYPE => [],
|
|
260
|
+
PROPOSE_ALTERNATIVE_REQUEST_RESPONSE_TYPE => [],
|
|
261
|
+
nil => [] # unknown type
|
|
262
|
+
},
|
|
263
|
+
'actions' => {
|
|
264
|
+
COVERAGE_INFORMATION_RESPONSE_TYPE => [],
|
|
265
|
+
CREATE_OR_UPDATE_COVERAGE_RESPONSE_TYPE => [],
|
|
266
|
+
FORM_COMPLETION_RESPONSE_TYPE => [],
|
|
267
|
+
nil => [] # unknown type
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
def extract_coverage_information_extensions(sorted_cards)
|
|
273
|
+
coverage_information_extensions = []
|
|
274
|
+
|
|
275
|
+
sorted_cards['actions'][COVERAGE_INFORMATION_RESPONSE_TYPE].each do |coverage_information_action|
|
|
276
|
+
coverage_information_action['resource']['extension'].each do |extension|
|
|
277
|
+
coverage_information_extensions << extension if extension['url'] == COVERAGE_INFO_EXT_URL
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
coverage_information_extensions.map { |ext| FHIR::Extension.new(ext) }
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
def sorted_cards_cached?(requests)
|
|
285
|
+
return false unless scratch['sorted_cards'].present?
|
|
286
|
+
return false unless scratch['sorted_cards']['hook_instances'].length == requests.length
|
|
287
|
+
|
|
288
|
+
requests.all? do |request|
|
|
289
|
+
scratch['sorted_cards']['hook_instances'].include?(JSON.parse(request.request_body)&.dig('hookInstance'))
|
|
290
|
+
rescue JSON::ParserError
|
|
291
|
+
false
|
|
292
|
+
end
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
def cache_sorted_cards(requests, sorted_cards)
|
|
296
|
+
scratch['sorted_cards'] = {
|
|
297
|
+
'hook_instances' => hook_instances_from_requests(requests),
|
|
298
|
+
'data' => sorted_cards
|
|
299
|
+
}
|
|
300
|
+
rescue JSON::ParserError
|
|
301
|
+
nil
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
def sorted_cards_from_cache
|
|
305
|
+
scratch['sorted_cards']['data']
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
def hook_instances_from_requests(requests)
|
|
309
|
+
requests.map { |request| JSON.parse(request.request_body)&.dig('hookInstance') }.compact
|
|
310
|
+
end
|
|
311
|
+
end
|
|
312
|
+
end
|