davinci_crd_test_kit 0.13.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/config/presets/inferno_crd_client_suite.json.erb +20 -14
- data/config/presets/inferno_crd_client_suite_prefetch_subset_v221.json.erb +125 -0
- data/config/presets/inferno_crd_client_suite_v221.json.erb +124 -0
- data/config/presets/inferno_crd_server_suite.json.erb +58 -1
- data/config/presets/inferno_crd_server_suite_v221.json.erb +94 -0
- data/config/presets/ri_crd_request_generator.json_v221.json.erb +13 -0
- data/config/presets/ri_crd_server.json.erb +19 -19
- data/lib/davinci_crd_test_kit/client/client_base_urls.rb +80 -0
- data/lib/davinci_crd_test_kit/{client_hook_request_validation.rb → client/client_hook_request_validation.rb} +1 -1
- data/lib/davinci_crd_test_kit/client/crd_client_options.rb +30 -0
- data/lib/davinci_crd_test_kit/client/endpoints/cds_services_discovery_handler.rb +34 -0
- data/lib/davinci_crd_test_kit/client/endpoints/custom_service_response.rb +342 -0
- data/lib/davinci_crd_test_kit/client/endpoints/gather_response_generation_data.rb +410 -0
- data/lib/davinci_crd_test_kit/client/endpoints/hook_request_endpoint.rb +233 -0
- data/lib/davinci_crd_test_kit/{mock_service_response.rb → client/endpoints/mock_service_response.rb} +165 -59
- data/lib/davinci_crd_test_kit/{card_responses → client/endpoints/mocked_card_responses}/companions_prerequisites.json +1 -0
- data/lib/davinci_crd_test_kit/{card_responses → client/endpoints/mocked_card_responses}/create_update_coverage_information.json +3 -2
- data/lib/davinci_crd_test_kit/{card_responses → client/endpoints/mocked_card_responses}/launch_smart_app.json +8 -1
- data/lib/davinci_crd_test_kit/{card_responses → client/endpoints/mocked_card_responses}/propose_alternate_request.json +1 -0
- data/lib/davinci_crd_test_kit/{card_responses → client/endpoints/mocked_card_responses}/request_form_completion.json +17 -16
- data/lib/davinci_crd_test_kit/client/multi_request_message_helper.rb +35 -0
- data/lib/davinci_crd_test_kit/client/tagged_request_load_helper.rb +38 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/api/client_fhir_api_create_test.rb +43 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/api/client_fhir_api_read_test.rb +43 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/api/client_fhir_api_search_test.rb +234 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/api/client_fhir_api_update_test.rb +43 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/api/client_fhir_api_validation_test.rb +63 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/auth/decode_auth_token_test.rb +65 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/auth/retrieve_jwks_test.rb +109 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/auth/token_header_test.rb +70 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/auth/token_payload_test.rb +85 -0
- data/lib/davinci_crd_test_kit/{routes/cds-services.json → client/v2.0.1/cds-services-v201.json} +1 -1
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_appointment_book_group.rb +108 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_card_must_support_group.rb +31 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_encounter_discharge_group.rb +105 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_encounter_start_group.rb +105 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_fhir_api_group.rb +790 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_hooks_group.rb +74 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_order_dispatch_group.rb +111 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_order_select_group.rb +116 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_order_sign_group.rb +113 -0
- data/lib/davinci_crd_test_kit/{client_registration_group.rb → client/v2.0.1/client_registration_group.rb} +12 -8
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_urls.rb +13 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/crd_client_suite.rb +134 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/invocation/appointment_book_receive_request_test.rb +129 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/invocation/encounter_discharge_receive_request_test.rb +126 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/invocation/encounter_start_receive_request_test.rb +126 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/invocation/order_dispatch_receive_request_test.rb +138 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/invocation/order_select_receive_request_test.rb +134 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/invocation/order_sign_receive_request_test.rb +136 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/must_support/client_card_must_support_coverage_information.rb +93 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/must_support/client_card_must_support_external_reference.rb +62 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/must_support/client_card_must_support_instructions.rb +62 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/registration/client_registration_verification_test.rb +94 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/registration/client_service_registration_attestation_test.rb +40 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_fetched_data_test.rb +86 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_optional_fields_test.rb +63 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_prefetch_equals_queried_test.rb +96 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_required_fields_test.rb +55 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_valid_context_test.rb +70 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_valid_prefetch_test.rb +62 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_response/client_display_cards_attest.rb +83 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_response/inferno_response_validation.rb +79 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/api/client_coverage_info_update_test.rb +212 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/api/client_crd_update_verification_group.rb +18 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/auth/decode_auth_token_test.rb +69 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/auth/retrieve_jwks_test.rb +120 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/auth/token_header_test.rb +92 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/auth/token_payload_test.rb +93 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/cds-services-prefetch-subset-v221.json +198 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/cds-services-v221.json +202 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_appointment_book_group.rb +102 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_cross_hook_group.rb +28 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_encounter_discharge_group.rb +96 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_encounter_start_group.rb +95 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_fhir_api_group.rb +88 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_hooks_group.rb +64 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_long_running_hook_group.rb +32 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_order_dispatch_group.rb +101 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_order_select_group.rb +102 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_order_sign_group.rb +107 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_registration_group.rb +27 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_urls.rb +27 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/crd_client_suite.rb +229 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_card_must_support_coverage_information_test.rb +63 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_fhirpath_collection_as_comma_delimited_string_test.rb +60 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_hook_instances_unique_test.rb +45 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_location_address_propagation_test.rb +135 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_prefetch_complete_and_subset_test.rb +103 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/appointment_book_receive_request_test.rb +156 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/encounter_discharge_receive_request_test.rb +157 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/encounter_start_receive_request_test.rb +157 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/order_dispatch_receive_request_test.rb +165 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/order_select_receive_request_test.rb +165 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/order_sign_receive_request_test.rb +165 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/long_running/client_long_running_receive_request_test.rb +64 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/long_running/client_skip_long_running_attestation_test.rb +49 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/registration/client_registration_verification_test.rb +161 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/registration/client_service_registration_attestation_test.rb +107 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_conformance_test.rb +47 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_coverage_verification_test.rb +152 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_data_fetch_verification_test.rb +55 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_granted_scopes_test.rb +123 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_prefetch_complete_test.rb +127 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_prefetch_profiles_test.rb +55 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_requested_version_test.rb +54 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_secured_transport_test.rb +48 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_response/client_display_cards_attest.rb +74 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_response/hook_response_support_coverage_information_test.rb +30 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_response/inferno_response_validation.rb +77 -0
- data/lib/davinci_crd_test_kit/cross_suite/base_urls.rb +20 -0
- data/lib/davinci_crd_test_kit/cross_suite/cards_identification.rb +312 -0
- data/lib/davinci_crd_test_kit/{cards_validation.rb → cross_suite/cards_validation.rb} +104 -47
- data/lib/davinci_crd_test_kit/cross_suite/coverage-information_stu201_metadata.yml +27 -0
- data/lib/davinci_crd_test_kit/cross_suite/coverage-information_stu221_metadata.yml +60 -0
- data/lib/davinci_crd_test_kit/cross_suite/fhirpath_on_cds_request.rb +177 -0
- data/lib/davinci_crd_test_kit/{hook_request_field_validation.rb → cross_suite/hook_request_field_validation.rb} +282 -203
- data/lib/davinci_crd_test_kit/cross_suite/logical_models_override_helper.rb +220 -0
- data/lib/davinci_crd_test_kit/cross_suite/prefetch_completeness_checker.rb +462 -0
- data/lib/davinci_crd_test_kit/cross_suite/prefetch_contents_validation.rb +81 -0
- data/lib/davinci_crd_test_kit/cross_suite/prefetch_profile_validation.rb +48 -0
- data/lib/davinci_crd_test_kit/cross_suite/profiles_and_resource_types.rb +63 -0
- data/lib/davinci_crd_test_kit/cross_suite/replace_tokens.rb +38 -0
- data/lib/davinci_crd_test_kit/cross_suite/requests_logical_model_validation.rb +202 -0
- data/lib/davinci_crd_test_kit/cross_suite/response_logical_model_validation.rb +274 -0
- data/lib/davinci_crd_test_kit/{suggestion_actions_validation.rb → cross_suite/suggestion_actions_validation.rb} +70 -50
- data/lib/davinci_crd_test_kit/cross_suite/tags.rb +42 -0
- data/lib/davinci_crd_test_kit/metadata.rb +10 -44
- data/lib/davinci_crd_test_kit/requirements/cds-hooks-library_1.0.1_requirements.xlsx +0 -0
- data/lib/davinci_crd_test_kit/requirements/cds-hooks_2.0_requirements.xlsx +0 -0
- data/lib/davinci_crd_test_kit/requirements/cds-hooks_3.0.0-ballot_requirements.xlsx +0 -0
- data/lib/davinci_crd_test_kit/requirements/davinci_crd_test_kit_requirements.csv +742 -65
- data/lib/davinci_crd_test_kit/requirements/generated/crd_client_requirements_coverage.csv +279 -54
- data/lib/davinci_crd_test_kit/requirements/generated/crd_client_v221_requirements_coverage.csv +1430 -0
- data/lib/davinci_crd_test_kit/requirements/generated/crd_server_requirements_coverage.csv +36 -45
- data/lib/davinci_crd_test_kit/requirements/generated/crd_server_v221_requirements_coverage.csv +143 -0
- data/lib/davinci_crd_test_kit/requirements/hl7.fhir.us.davinci-crd_2.0.1_requirements.xlsx +0 -0
- data/lib/davinci_crd_test_kit/requirements/hl7.fhir.us.davinci-crd_2.2.1_requirements.xlsx +0 -0
- data/lib/davinci_crd_test_kit/server/endpoints/jwk_set_endpoint_handler.rb +13 -0
- data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_create_endpoint.rb +23 -0
- data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_delete_endpoint.rb +30 -0
- data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_metadata_endpoint.rb +112 -0
- data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_read_endpoint.rb +21 -0
- data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_request_handler.rb +261 -0
- data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_search_endpoint.rb +561 -0
- data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_update_endpoint.rb +24 -0
- data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/stress-test-Bundle.json +54687 -0
- data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr_endpoints.rb +95 -0
- data/lib/davinci_crd_test_kit/server/jobs/invoke_hook.rb +225 -0
- data/lib/davinci_crd_test_kit/{jwt_helper.rb → server/jwt_helper.rb} +1 -12
- data/lib/davinci_crd_test_kit/server/resource_extractor.rb +68 -0
- data/lib/davinci_crd_test_kit/server/server_abstract_invoke_hook_test.rb +165 -0
- data/lib/davinci_crd_test_kit/server/server_base_urls.rb +30 -0
- data/lib/davinci_crd_test_kit/{server_hook_helper.rb → server/server_hook_helper.rb} +1 -1
- data/lib/davinci_crd_test_kit/{server_hook_request_validation.rb → server/server_hook_request_validation.rb} +1 -1
- data/lib/davinci_crd_test_kit/{test_helper.rb → server/server_test_helper.rb} +7 -3
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Appointment.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/ClaimResponse.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/CommunicationRequest.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Coverage.yml +21 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Device.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/DeviceRequest.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Encounter.yml +7 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Location.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/MedicationRequest.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/NutritionOrder.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Organization.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Patient.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Practitioner.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/PractitionerRole.yml +40 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/ServiceRequest.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Task.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/VisionPrescription.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_server_suite.rb +99 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/discovery/discovery_endpoint_test.rb +90 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/discovery/discovery_services_validation_test.rb +67 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/interaction/server_invoke_hook_test.rb +12 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/must_support/coverage_information_system_action_across_hooks_validation_test.rb +34 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/must_support/external_reference_card_across_hooks_validation_test.rb +30 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/must_support/instructions_card_received_across_hooks_test.rb +27 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_appointment_book_group.rb +191 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_demonstrate_hook_response_group.rb +93 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_discovery_group.rb +62 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_encounter_discharge_group.rb +186 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_encounter_start_group.rb +186 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_hooks_group.rb +73 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_order_dispatch_group.rb +191 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_order_select_group.rb +211 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_order_sign_group.rb +216 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_required_card_response_validation_group.rb +28 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_urls.rb +13 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_request/service_request_context_validation_test.rb +30 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_request/service_request_optional_fields_validation_test.rb +39 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_request/service_request_required_fields_validation_test.rb +40 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/additional_orders_validation_test.rb +59 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/card_optional_fields_validation_test.rb +51 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/coverage_information_system_action_received_test.rb +65 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/coverage_information_system_action_validation_test.rb +120 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/create_or_update_coverage_info_response_validation_test.rb +70 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/external_reference_card_validation_test.rb +37 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/form_completion_response_validation_test.rb +67 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/instructions_card_received_test.rb +30 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/launch_smart_app_card_validation_test.rb +39 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/propose_alternate_request_card_validation_test.rb +46 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/service_response_validation_test.rb +83 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Appointment_withorder.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Appointment_withoutorder.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/CommunicationRequest.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Coverage.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Device.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/DeviceRequest.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Encounter.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Location.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/MedicationRequest.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/NutritionOrder.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Organization.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Patient.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/PractitionerRole.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/ServiceRequest.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/VisionPrescription.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_server_suite.rb +115 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/discovery/discovery_configuration_test.rb +159 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/discovery/discovery_endpoint_test.rb +90 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/discovery/discovery_prefetch_support_test.rb +43 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/discovery/discovery_services_validation_test.rb +121 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/interaction/server_invoke_hook_test.rb +17 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/must_support/coverage_information_must_support_test.rb +71 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/must_support/coverage_information_system_action_across_hooks_validation_test.rb +36 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/must_support/supported_us_core_versions_test.rb +118 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_appointment_book_group.rb +213 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_demonstrate_hook_response_group.rb +93 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_discovery_group.rb +69 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_encounter_discharge_group.rb +194 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_encounter_start_group.rb +194 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_hooks_group.rb +73 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_order_dispatch_group.rb +214 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_order_select_group.rb +219 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_order_sign_group.rb +241 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_required_card_response_validation_group.rb +30 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_urls.rb +13 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_request/service_request_context_validation_test.rb +30 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_request/service_request_no_custom_extensions_test.rb +120 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_request/service_request_optional_fields_validation_test.rb +39 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_request/service_request_required_fields_validation_test.rb +40 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/additional_orders_validation_test.rb +66 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/all_responses_include_coverage_information_test.rb +123 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/card_optional_fields_validation_test.rb +57 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/coverage_info_configuration_test.rb +83 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/coverage_information_system_action_received_test.rb +65 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/coverage_information_system_action_validation_test.rb +184 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/create_or_update_coverage_info_response_validation_test.rb +75 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/external_reference_card_validation_test.rb +47 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/form_completion_response_validation_test.rb +91 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/hook_request_resource_resolution.rb +137 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/instructions_card_received_test.rb +32 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/launch_smart_app_card_validation_test.rb +49 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/order_dispatch_coverage_information_test.rb +38 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/propose_alternate_request_card_validation_test.rb +54 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/service_response_validation_test.rb +97 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/unknown_cds_hooks_elements_test.rb +78 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/unknown_configuration_test.rb +78 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/unknown_context_test.rb +78 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/verify_response_without_billing_options_test.rb +43 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/verify_response_without_configuration_test.rb +44 -0
- data/lib/davinci_crd_test_kit/version.rb +2 -2
- data/lib/davinci_crd_test_kit.rb +4 -2
- metadata +297 -93
- data/lib/davinci_crd_test_kit/client_fhir_api_group.rb +0 -785
- data/lib/davinci_crd_test_kit/client_hooks_group.rb +0 -74
- data/lib/davinci_crd_test_kit/client_tests/appointment_book_receive_request_test.rb +0 -93
- data/lib/davinci_crd_test_kit/client_tests/client_appointment_book_group.rb +0 -75
- data/lib/davinci_crd_test_kit/client_tests/client_display_cards_attest.rb +0 -48
- data/lib/davinci_crd_test_kit/client_tests/client_encounter_discharge_group.rb +0 -73
- data/lib/davinci_crd_test_kit/client_tests/client_encounter_start_group.rb +0 -73
- data/lib/davinci_crd_test_kit/client_tests/client_fhir_api_create_test.rb +0 -42
- data/lib/davinci_crd_test_kit/client_tests/client_fhir_api_read_test.rb +0 -40
- data/lib/davinci_crd_test_kit/client_tests/client_fhir_api_search_test.rb +0 -232
- data/lib/davinci_crd_test_kit/client_tests/client_fhir_api_update_test.rb +0 -42
- data/lib/davinci_crd_test_kit/client_tests/client_fhir_api_validation_test.rb +0 -61
- data/lib/davinci_crd_test_kit/client_tests/client_order_dispatch_group.rb +0 -79
- data/lib/davinci_crd_test_kit/client_tests/client_order_select_group.rb +0 -82
- data/lib/davinci_crd_test_kit/client_tests/client_order_sign_group.rb +0 -81
- data/lib/davinci_crd_test_kit/client_tests/client_registration_verification_test.rb +0 -88
- data/lib/davinci_crd_test_kit/client_tests/decode_auth_token_test.rb +0 -60
- data/lib/davinci_crd_test_kit/client_tests/encounter_discharge_receive_request_test.rb +0 -90
- data/lib/davinci_crd_test_kit/client_tests/encounter_start_receive_request_test.rb +0 -90
- data/lib/davinci_crd_test_kit/client_tests/hook_request_optional_fields_test.rb +0 -57
- data/lib/davinci_crd_test_kit/client_tests/hook_request_required_fields_test.rb +0 -49
- data/lib/davinci_crd_test_kit/client_tests/hook_request_valid_context_test.rb +0 -68
- data/lib/davinci_crd_test_kit/client_tests/hook_request_valid_prefetch_test.rb +0 -69
- data/lib/davinci_crd_test_kit/client_tests/order_dispatch_receive_request_test.rb +0 -102
- data/lib/davinci_crd_test_kit/client_tests/order_select_receive_request_test.rb +0 -98
- data/lib/davinci_crd_test_kit/client_tests/order_sign_receive_request_test.rb +0 -101
- data/lib/davinci_crd_test_kit/client_tests/retrieve_jwks_test.rb +0 -105
- data/lib/davinci_crd_test_kit/client_tests/submitted_response_validation.rb +0 -48
- data/lib/davinci_crd_test_kit/client_tests/token_header_test.rb +0 -65
- data/lib/davinci_crd_test_kit/client_tests/token_payload_test.rb +0 -78
- data/lib/davinci_crd_test_kit/crd_client_suite.rb +0 -193
- data/lib/davinci_crd_test_kit/crd_options.rb +0 -9
- data/lib/davinci_crd_test_kit/crd_server_suite.rb +0 -125
- data/lib/davinci_crd_test_kit/igs/davinci-crd-2.0.1.tgz +0 -0
- data/lib/davinci_crd_test_kit/routes/cds_services_discovery_handler.rb +0 -18
- data/lib/davinci_crd_test_kit/routes/hook_request_endpoint.rb +0 -77
- data/lib/davinci_crd_test_kit/routes/jwk_set_endpoint_handler.rb +0 -15
- data/lib/davinci_crd_test_kit/server_appointment_book_group.rb +0 -176
- data/lib/davinci_crd_test_kit/server_demonstrate_hook_response_group.rb +0 -77
- data/lib/davinci_crd_test_kit/server_discovery_group.rb +0 -60
- data/lib/davinci_crd_test_kit/server_encounter_discharge_group.rb +0 -170
- data/lib/davinci_crd_test_kit/server_encounter_start_group.rb +0 -170
- data/lib/davinci_crd_test_kit/server_hooks_group.rb +0 -71
- data/lib/davinci_crd_test_kit/server_order_dispatch_group.rb +0 -176
- data/lib/davinci_crd_test_kit/server_order_select_group.rb +0 -195
- data/lib/davinci_crd_test_kit/server_order_sign_group.rb +0 -201
- data/lib/davinci_crd_test_kit/server_required_card_response_validation_group.rb +0 -26
- data/lib/davinci_crd_test_kit/server_tests/additional_orders_validation_test.rb +0 -68
- data/lib/davinci_crd_test_kit/server_tests/card_optional_fields_validation_test.rb +0 -47
- data/lib/davinci_crd_test_kit/server_tests/coverage_information_system_action_across_hooks_validation_test.rb +0 -32
- data/lib/davinci_crd_test_kit/server_tests/coverage_information_system_action_received_test.rb +0 -63
- data/lib/davinci_crd_test_kit/server_tests/coverage_information_system_action_validation_test.rb +0 -118
- data/lib/davinci_crd_test_kit/server_tests/create_or_update_coverage_info_response_validation_test.rb +0 -71
- data/lib/davinci_crd_test_kit/server_tests/discovery_endpoint_test.rb +0 -88
- data/lib/davinci_crd_test_kit/server_tests/discovery_services_validation_test.rb +0 -65
- data/lib/davinci_crd_test_kit/server_tests/external_reference_card_across_hooks_validation_test.rb +0 -28
- data/lib/davinci_crd_test_kit/server_tests/external_reference_card_validation_test.rb +0 -36
- data/lib/davinci_crd_test_kit/server_tests/form_completion_response_validation_test.rb +0 -78
- data/lib/davinci_crd_test_kit/server_tests/instructions_card_received_across_hooks_test.rb +0 -25
- data/lib/davinci_crd_test_kit/server_tests/instructions_card_received_test.rb +0 -26
- data/lib/davinci_crd_test_kit/server_tests/launch_smart_app_card_validation_test.rb +0 -38
- data/lib/davinci_crd_test_kit/server_tests/propose_alternate_request_card_validation_test.rb +0 -63
- data/lib/davinci_crd_test_kit/server_tests/service_call_test.rb +0 -101
- data/lib/davinci_crd_test_kit/server_tests/service_request_context_validation_test.rb +0 -28
- data/lib/davinci_crd_test_kit/server_tests/service_request_optional_fields_validation_test.rb +0 -37
- data/lib/davinci_crd_test_kit/server_tests/service_request_required_fields_validation_test.rb +0 -38
- data/lib/davinci_crd_test_kit/server_tests/service_response_validation_test.rb +0 -81
- data/lib/davinci_crd_test_kit/tags.rb +0 -10
- data/lib/davinci_crd_test_kit/urls.rb +0 -52
- /data/lib/davinci_crd_test_kit/{card_responses → client/endpoints/mocked_card_responses}/external_reference.json +0 -0
- /data/lib/davinci_crd_test_kit/{card_responses → client/endpoints/mocked_card_responses}/instructions.json +0 -0
- /data/lib/davinci_crd_test_kit/{crd_jwks.json → server/endpoints/crd_jwks.json} +0 -0
- /data/lib/davinci_crd_test_kit/{jwks.rb → server/endpoints/jwks.rb} +0 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
require_relative '../../../cross_suite/prefetch_contents_validation'
|
|
2
|
+
|
|
3
|
+
module DaVinciCRDTestKit
|
|
4
|
+
module V201
|
|
5
|
+
class HookRequestPrefetchEqualsQueriedTest < Inferno::Test
|
|
6
|
+
include PrefetchContentsValidation
|
|
7
|
+
|
|
8
|
+
id :crd_v201_hook_request_prefetch_equals_queried
|
|
9
|
+
title 'Prefetched data is equivalent to queried data'
|
|
10
|
+
description %(
|
|
11
|
+
This test verifies that each key present in the incoming hook request's `prefetch` field is equivalent to the
|
|
12
|
+
data returned by a query to the fhir server using the parameterized prefetch template.
|
|
13
|
+
|
|
14
|
+
The queries will be performed after the hook response has been returned.
|
|
15
|
+
)
|
|
16
|
+
verifies_requirements 'cds-hooks_2.0@45'
|
|
17
|
+
|
|
18
|
+
input :client_fhir_server,
|
|
19
|
+
optional: true
|
|
20
|
+
input :client_access_token,
|
|
21
|
+
optional: true
|
|
22
|
+
input :override_access_token,
|
|
23
|
+
title: 'Prefetch Validation Override Bearer Token',
|
|
24
|
+
description: %(
|
|
25
|
+
Optionally provide a bearer token to use in place of the one provided in the hook request
|
|
26
|
+
when checking that the prefetched data is equivalent to what can be access via FHIR.
|
|
27
|
+
Use only if the bearer token in the request will not be valid even right after the hook
|
|
28
|
+
request is made. If provided it must have the same scope as the bearer token provided
|
|
29
|
+
in the hook request.
|
|
30
|
+
),
|
|
31
|
+
optional: true
|
|
32
|
+
|
|
33
|
+
fhir_client do
|
|
34
|
+
url :client_fhir_server
|
|
35
|
+
bearer_token access_token
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def access_token
|
|
39
|
+
override_access_token.present? ? override_access_token : client_access_token
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def hook_name
|
|
43
|
+
config.options[:hook_name]
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def crd_test_group
|
|
47
|
+
config.options[:crd_test_group]
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def tags_to_load
|
|
51
|
+
crd_test_group.present? ? [hook_name, crd_test_group] : [hook_name]
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def cds_services_json
|
|
55
|
+
JSON.parse(File.read(File.join(
|
|
56
|
+
__dir__, '..', 'cds-services-v201.json'
|
|
57
|
+
)))['services']
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def advertised_prefetch_fields
|
|
61
|
+
advertised_hook_service = cds_services_json.find { |service| service['hook'] == hook_name }
|
|
62
|
+
advertised_hook_service['prefetch']
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def no_error_validation(message)
|
|
66
|
+
assert messages.none? { |msg| msg[:type] == 'error' }, message
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
run do
|
|
70
|
+
hook_requests = load_tagged_requests(*tags_to_load)
|
|
71
|
+
|
|
72
|
+
skip_if hook_requests.blank?, 'No Hook Requests to verify.'
|
|
73
|
+
|
|
74
|
+
pass_if !prefetched_data?(hook_requests), 'No prefetched data provided.'
|
|
75
|
+
|
|
76
|
+
skip_if client_fhir_server.blank?,
|
|
77
|
+
'No FHIR server provided in the hook request to use to validate the prefetch data.'
|
|
78
|
+
|
|
79
|
+
if override_access_token.present?
|
|
80
|
+
add_message(:warning,
|
|
81
|
+
'Override access token provided. Ensure that it has the same scope as used when ' \
|
|
82
|
+
'prefetching data for the hook request.')
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
hook_requests.each_with_index do |request, index|
|
|
86
|
+
@request_number = index + 1
|
|
87
|
+
check_prefetch_data_against_query(request, advertised_prefetch_fields)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
no_error_validation('Prefetched data does not match the requested queries.')
|
|
91
|
+
|
|
92
|
+
pass 'Prefetched data matches the requested queries.'
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_required_fields_test.rb
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
require_relative '../../client_hook_request_validation'
|
|
2
|
+
require_relative '../client_urls'
|
|
3
|
+
|
|
4
|
+
module DaVinciCRDTestKit
|
|
5
|
+
module V201
|
|
6
|
+
class HookRequestRequiredFieldsTest < Inferno::Test
|
|
7
|
+
include ClientHookRequestValidation
|
|
8
|
+
include ClientURLs
|
|
9
|
+
|
|
10
|
+
id :crd_v201_hook_request_required_fields
|
|
11
|
+
title 'Hook request contains required fields'
|
|
12
|
+
description %(
|
|
13
|
+
Under the [CDS hooks HTTP Request section](https://cds-hooks.hl7.org/2.0/#http-request_1), the specification
|
|
14
|
+
requires that a CDS service request SHALL include a JSON POST body with the following input fields:
|
|
15
|
+
* `hook` - *string*
|
|
16
|
+
* `hookInstance` - *string* containing a globally unique UUID
|
|
17
|
+
* `context` - *object*
|
|
18
|
+
|
|
19
|
+
Additionally, if the optional `fhirAuthorization` field is present, then the `fhirServer` field is required.
|
|
20
|
+
|
|
21
|
+
This test also checks that the `hook` field contains the correct CDS service name that the CDS client
|
|
22
|
+
is sending a request for
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
verifies_requirements 'cds-hooks_2.0@1', 'cds-hooks_2.0@18', 'cds-hooks_2.0@19',
|
|
26
|
+
'cds-hooks_2.0@20', 'cds-hooks_2.0@22', 'cds-hooks_2.0@25'
|
|
27
|
+
|
|
28
|
+
def hook_name
|
|
29
|
+
config.options[:hook_name]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
output :contexts, :prefetches
|
|
33
|
+
|
|
34
|
+
run do
|
|
35
|
+
load_tagged_requests(hook_name)
|
|
36
|
+
skip_if requests.empty?, "No #{hook_name} requests were made in a previous test as expected."
|
|
37
|
+
contexts = []
|
|
38
|
+
prefetches = []
|
|
39
|
+
requests.each_with_index do |request, index|
|
|
40
|
+
@request_number = index + 1
|
|
41
|
+
request_body = json_parse(request.request_body)
|
|
42
|
+
next if request_body.blank?
|
|
43
|
+
|
|
44
|
+
contexts << request_body['context'] if request_body['context'].is_a?(Hash)
|
|
45
|
+
prefetches << request_body['prefetch'] if request_body['prefetch'].is_a?(Hash)
|
|
46
|
+
hook_request_required_fields_check(request_body, hook_name, ig_version: 'v201')
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
output contexts: contexts.to_json,
|
|
50
|
+
prefetches: prefetches.to_json
|
|
51
|
+
no_error_validation('Some service requests made are not valid.')
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
require_relative '../../client_hook_request_validation'
|
|
2
|
+
require_relative '../client_urls'
|
|
3
|
+
|
|
4
|
+
module DaVinciCRDTestKit
|
|
5
|
+
module V201
|
|
6
|
+
class HookRequestValidContextTest < Inferno::Test
|
|
7
|
+
include ClientURLs
|
|
8
|
+
include ClientHookRequestValidation
|
|
9
|
+
|
|
10
|
+
id :crd_v201_hook_request_valid_context
|
|
11
|
+
title 'Hook request contains valid context'
|
|
12
|
+
description %(
|
|
13
|
+
As stated in the [CDS hooks specification](https://cds-hooks.hl7.org/2.0#http-request), a CDS service request's
|
|
14
|
+
`context` field contains hook-specific contextual data that the CDS service will need. The context is
|
|
15
|
+
specified in the hook definition to guide developers on the information available at the point in the
|
|
16
|
+
workflow when the hook is triggered.
|
|
17
|
+
|
|
18
|
+
The `context` requirements for each [hook specified in the CRD IG](https://hl7.org/fhir/us/davinci-crd/STU2/hooks.html)
|
|
19
|
+
can be found below:
|
|
20
|
+
* [appointment-book](https://cds-hooks.hl7.org/hooks/appointment-book/2023SepSTU1Ballot/appointment-book/)
|
|
21
|
+
* [encounter-start](https://cds-hooks.hl7.org/hooks/encounter-start/2023SepSTU1Ballot/encounter-start/)
|
|
22
|
+
* [encounter-discharge](https://cds-hooks.hl7.org/hooks/encounter-discharge/2023SepSTU1Ballot/encounter-discharge/)
|
|
23
|
+
* [order-select](https://cds-hooks.hl7.org/hooks/order-select/2023SepSTU1Ballot/order-select/)
|
|
24
|
+
* [order-dispatch](https://cds-hooks.hl7.org/hooks/order-dispatch/2023SepSTU1Ballot/order-dispatch/)
|
|
25
|
+
* [order-sign](https://cds-hooks.org/hooks/order-sign/)
|
|
26
|
+
|
|
27
|
+
This test performs the following:
|
|
28
|
+
* Verifies that the incoming hook request's `context` field contains the fields required by each hook and
|
|
29
|
+
that they are in the correct format
|
|
30
|
+
* Checks the optional fields and ensures they are in the correct format
|
|
31
|
+
* Validates any resources contained in a `context` field that contains a Bundle or FHIR resource
|
|
32
|
+
* Makes FHIR requests for any `context` fields that contain an id or reference and validates each resource
|
|
33
|
+
response against its corresponding CRD resource profile
|
|
34
|
+
* Check some specific `context` requirements for hooks that have special requirements for certain fields
|
|
35
|
+
|
|
36
|
+
The client must provide its FHIR server URL and access token in the hook request in order to run
|
|
37
|
+
this test.
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
input :contexts, :client_fhir_server
|
|
41
|
+
input :client_access_token,
|
|
42
|
+
optional: true
|
|
43
|
+
|
|
44
|
+
fhir_client do
|
|
45
|
+
url :client_fhir_server
|
|
46
|
+
bearer_token :client_access_token
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def hook_name
|
|
50
|
+
config.options[:hook_name]
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
run do
|
|
54
|
+
hook_contexts = json_parse(contexts)
|
|
55
|
+
if hook_contexts
|
|
56
|
+
skip_if(hook_contexts.none?(&:present?), "No #{hook_name} requests contained the `context` field.")
|
|
57
|
+
hook_contexts.each_with_index do |context, index|
|
|
58
|
+
@request_number = index + 1
|
|
59
|
+
if context.blank?
|
|
60
|
+
add_message('error', "#{request_number}Missing required context field.")
|
|
61
|
+
next
|
|
62
|
+
end
|
|
63
|
+
hook_request_context_check(context, hook_name, ig_version: 'v201')
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
no_error_validation('Context is not valid.')
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_valid_prefetch_test.rb
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
require_relative '../../client_hook_request_validation'
|
|
2
|
+
require_relative '../client_urls'
|
|
3
|
+
|
|
4
|
+
module DaVinciCRDTestKit
|
|
5
|
+
module V201
|
|
6
|
+
class HookRequestValidPrefetchTest < Inferno::Test
|
|
7
|
+
include ClientHookRequestValidation
|
|
8
|
+
include ClientURLs
|
|
9
|
+
|
|
10
|
+
id :crd_v201_hook_request_valid_prefetch
|
|
11
|
+
title 'Hook request contains valid prefetched data'
|
|
12
|
+
description %(
|
|
13
|
+
As stated in the [CDS hooks specification](https://cds-hooks.hl7.org/2.0#http-request), a CDS service request's
|
|
14
|
+
`prefetch` field is an optional field that contains key/value pairs of FHIR queries that the service is
|
|
15
|
+
requesting the CDS client to perform and provide on each service call. The key is a string that describes
|
|
16
|
+
the type of data being requested and the value is a string representing the FHIR query.
|
|
17
|
+
See [Prefetch Template](https://cds-hooks.hl7.org/2.0#prefetch-template)
|
|
18
|
+
for more information about how the `prefetch` formatting works.
|
|
19
|
+
|
|
20
|
+
This test verifies that the incoming hook request's `prefetch` field is in a valid JSON format,
|
|
21
|
+
validates each contained resource against its corresponding CRD resource profile, and checks
|
|
22
|
+
that the data matches what is requested in by the
|
|
23
|
+
[prefetch templates published by Inferno's simulated CRD server](https://github.com/inferno-framework/davinci-crd-test-kit/blob/main/lib/davinci_crd_test_kit/client/v2.0.1/cds-services-v201.json).
|
|
24
|
+
Since prefetch support is not required, this test will pass if `prefetch` is not present or has no entries.
|
|
25
|
+
)
|
|
26
|
+
verifies_requirements 'hl7.fhir.us.davinci-crd_2.0.1@54', 'cds-hooks_2.0@30', 'cds-hooks_2.0@47'
|
|
27
|
+
|
|
28
|
+
input :contexts, :prefetches
|
|
29
|
+
|
|
30
|
+
def hook_name
|
|
31
|
+
config.options[:hook_name]
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def cds_services_json
|
|
35
|
+
JSON.parse(File.read(File.join(
|
|
36
|
+
__dir__, '..', 'cds-services-v201.json'
|
|
37
|
+
)))['services']
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def advertised_prefetch_fields
|
|
41
|
+
advertised_hook_service = cds_services_json.find { |service| service['hook'] == hook_name }
|
|
42
|
+
advertised_hook_service['prefetch']
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
run do
|
|
46
|
+
hook_contexts = json_parse(contexts)
|
|
47
|
+
hook_prefetches = json_parse(prefetches)
|
|
48
|
+
|
|
49
|
+
pass_if hook_prefetches.blank?, 'No prefetched data provided.'
|
|
50
|
+
|
|
51
|
+
hook_prefetches.each_with_index do |prefetch, index|
|
|
52
|
+
next if prefetch.blank?
|
|
53
|
+
|
|
54
|
+
@request_number = index + 1
|
|
55
|
+
context = hook_contexts[index].present? ? hook_contexts[index] : {}
|
|
56
|
+
hook_request_prefetch_check(advertised_prefetch_fields, prefetch, context, ig_version: 'v201')
|
|
57
|
+
end
|
|
58
|
+
no_error_validation('Prefetch is not valid.')
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
require_relative '../client_urls'
|
|
2
|
+
require_relative '../../../cross_suite/cards_identification'
|
|
3
|
+
|
|
4
|
+
module DaVinciCRDTestKit
|
|
5
|
+
module V201
|
|
6
|
+
class ClientCardDisplayAttest < Inferno::Test
|
|
7
|
+
include ClientURLs
|
|
8
|
+
include CardsIdentification
|
|
9
|
+
|
|
10
|
+
id :crd_v201_card_display_attest_test
|
|
11
|
+
title 'Check that returned decision support details are displayed to the user'
|
|
12
|
+
description %(
|
|
13
|
+
Since Inferno has no way to evaluate the client's UI, testers must manually
|
|
14
|
+
verify that the cards and system actions returned by Inferno are presented
|
|
15
|
+
to the user in an appopriate way that allows for consideration and action
|
|
16
|
+
if warranted.
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
def hook_name
|
|
20
|
+
config.options[:hook_name]
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def crd_test_group
|
|
24
|
+
config.options[:crd_test_group]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def tags_to_load
|
|
28
|
+
crd_test_group.present? ? [hook_name, crd_test_group] : [hook_name]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def responded_card_types
|
|
32
|
+
list_card_types_in_requests(requests)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def format_responded_response_types
|
|
36
|
+
responded_card_types
|
|
37
|
+
.map do |response_type|
|
|
38
|
+
response_type_string =
|
|
39
|
+
response_type.split('_')
|
|
40
|
+
.map(&:capitalize)
|
|
41
|
+
.join(' ')
|
|
42
|
+
.prepend('- ')
|
|
43
|
+
.sub('Smart', 'SMART')
|
|
44
|
+
.sub('Create Update', 'Create/Update')
|
|
45
|
+
.sub('Companions Prerequisites', 'Companions/Prerequisites')
|
|
46
|
+
.sub('Card', '(card)')
|
|
47
|
+
.sub('Action', '(systemAction)')
|
|
48
|
+
response_type_string
|
|
49
|
+
end
|
|
50
|
+
.join("\n")
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
output :attest_true_url
|
|
54
|
+
output :attest_false_url
|
|
55
|
+
|
|
56
|
+
run do
|
|
57
|
+
load_tagged_requests(*tags_to_load)
|
|
58
|
+
skip_if responded_card_types.blank?, 'No responses sent to the client.'
|
|
59
|
+
|
|
60
|
+
identifier = SecureRandom.hex(32)
|
|
61
|
+
attest_true_url = "#{resume_pass_url}?token=#{identifier}"
|
|
62
|
+
attest_false_url = "#{resume_fail_url}?token=#{identifier}"
|
|
63
|
+
output(attest_true_url:)
|
|
64
|
+
output(attest_false_url:)
|
|
65
|
+
wait(
|
|
66
|
+
identifier:,
|
|
67
|
+
message: <<~MESSAGE
|
|
68
|
+
**Card Display Attestation**:
|
|
69
|
+
|
|
70
|
+
I attest that the following CDS response types returned were processed by the
|
|
71
|
+
client system and displayed to the user:
|
|
72
|
+
|
|
73
|
+
#{format_responded_response_types}
|
|
74
|
+
|
|
75
|
+
[Click here](#{attest_true_url}) if the above statement is **true**.
|
|
76
|
+
|
|
77
|
+
[Click here](#{attest_false_url}) if the above statement is **false**.
|
|
78
|
+
MESSAGE
|
|
79
|
+
)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
require_relative '../../../cross_suite/cards_validation'
|
|
2
|
+
|
|
3
|
+
module DaVinciCRDTestKit
|
|
4
|
+
module V201
|
|
5
|
+
class InfernoResponseValidationTest < Inferno::Test
|
|
6
|
+
include CardsValidation
|
|
7
|
+
|
|
8
|
+
title 'Inferno CDS Service Response is Conformant'
|
|
9
|
+
description %(
|
|
10
|
+
This test verifies that each service response built by Inferno and returned to the client is conformant.
|
|
11
|
+
These responses must be conformant for the client to demonstrate its ability to accept CDS Service responses.
|
|
12
|
+
|
|
13
|
+
If this test fails when a custom response was provided, adjust the custom response template
|
|
14
|
+
and the submitted requests so that the response built by Inferno is conformant. See
|
|
15
|
+
the documentation for details on how Inferno builds a response from the provided
|
|
16
|
+
custom template.
|
|
17
|
+
|
|
18
|
+
If this test fails when Inferno mocked the response based on selected card types, please
|
|
19
|
+
report this failure to the Inferno team via github issues.
|
|
20
|
+
)
|
|
21
|
+
id :crd_v201_inferno_response_validation
|
|
22
|
+
|
|
23
|
+
input :custom_response_template, optional: true
|
|
24
|
+
|
|
25
|
+
def hook_name
|
|
26
|
+
config.options[:hook_name]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def crd_test_group
|
|
30
|
+
config.options[:crd_test_group]
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def tags_to_load
|
|
34
|
+
crd_test_group.present? ? [hook_name, crd_test_group] : [hook_name]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def response_label(index = nil)
|
|
38
|
+
response_type = (custom_response_template.present? ? 'Custom built' : 'Mocked')
|
|
39
|
+
"#{response_type} response#{" #{index}" if index.present?}"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def valid_cards
|
|
43
|
+
@valid_cards ||= []
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def validate_system_actions(system_actions)
|
|
47
|
+
return if system_actions.nil?
|
|
48
|
+
|
|
49
|
+
system_actions.each do |action|
|
|
50
|
+
action_fields_validation(action, ig_version: 'v201')
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
run do
|
|
55
|
+
load_tagged_requests(*tags_to_load)
|
|
56
|
+
|
|
57
|
+
skip_if request.blank?, "No #{response_label.downcase}s to verify."
|
|
58
|
+
|
|
59
|
+
entity_validated = false
|
|
60
|
+
requests.each_with_index do |request, index|
|
|
61
|
+
response_hash = JSON.parse(request.response_body)
|
|
62
|
+
|
|
63
|
+
next unless response_hash['cards'].present? || response_hash['systemActions'].present?
|
|
64
|
+
|
|
65
|
+
entity_validated = true
|
|
66
|
+
perform_cards_validation(response_hash['cards'], response_hash['systemActions'].present?, 'v201', index)
|
|
67
|
+
validate_system_actions(response_hash['systemActions'])
|
|
68
|
+
rescue JSON::ParserError
|
|
69
|
+
next
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
skip_if !entity_validated,
|
|
73
|
+
"No #{response_label.downcase} cards or system actions to verify returned by Inferno."
|
|
74
|
+
|
|
75
|
+
no_error_validation("Invalid Inferno #{response_label.downcase}(s). Check messages for issues found.")
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
require_relative '../../../cross_suite/cards_identification'
|
|
2
|
+
require_relative '../../tagged_request_load_helper'
|
|
3
|
+
|
|
4
|
+
module DaVinciCRDTestKit
|
|
5
|
+
module V221
|
|
6
|
+
class ClientCoverageInfoUpdateTest < Inferno::Test
|
|
7
|
+
include CardsIdentification
|
|
8
|
+
include TaggedRequestLoadHelper
|
|
9
|
+
|
|
10
|
+
title "Client's FHIR server stores updates from coverage-information responses"
|
|
11
|
+
id :crd_v221_client_coverage_info_update
|
|
12
|
+
description <<~DESCRIPTION
|
|
13
|
+
This test verifies that when the client receives a [Coverage Information response type](https://hl7.org/fhir/us/davinci-crd/2.2.1/en/cards.html#coverage-information-response-type),
|
|
14
|
+
it stores the [coverage-information extension](https://hl7.org/fhir/us/davinci-crd/2.2.1/en/StructureDefinition-ext-coverage-information.html)
|
|
15
|
+
and makes it available when accessing the associated resource.
|
|
16
|
+
|
|
17
|
+
During this test, Inferno will find all [Coverage Information responses](https://hl7.org/fhir/us/davinci-crd/2.2.1/en/cards.html#coverage-information-response-type),
|
|
18
|
+
attempt to read the updated FHIR resource from the client's FHIR server, and verify
|
|
19
|
+
that the [coverage-information extension](https://hl7.org/fhir/us/davinci-crd/2.2.1/en/StructureDefinition-ext-coverage-information.html)
|
|
20
|
+
in the response is now present in the returned resource. When comparing the
|
|
21
|
+
[coverage-information extension](https://hl7.org/fhir/us/davinci-crd/2.2.1/en/StructureDefinition-ext-coverage-information.html)
|
|
22
|
+
in the response with what is returned from the client FHIR server, Inferno
|
|
23
|
+
expects that client stores and exposes the extension without modification, meaning
|
|
24
|
+
that the exact set of sub-extensions in the response and their values are present
|
|
25
|
+
in the stored version.
|
|
26
|
+
|
|
27
|
+
Inferno will not always be able to perform this check. CRD clients are not required
|
|
28
|
+
to expose FHIR read APIs for all request resource types, so resource types for which
|
|
29
|
+
the client's CapabilityStatement does not indicate read interaction support will be omitted.
|
|
30
|
+
Additionally, Inferno will not check complex cases where determining the expected
|
|
31
|
+
stored extensions is difficult. For example, when there are multiple Coverage Information
|
|
32
|
+
responses for a single resource or multiple coverage-information extensions in a
|
|
33
|
+
single Coverage Information response. Implementers are still responsible for storing updates
|
|
34
|
+
in these cases. To pass this test at least one target resource that Inferno can access must be found.
|
|
35
|
+
The stored [coverage-information extension](https://hl7.org/fhir/us/davinci-crd/2.2.1/en/StructureDefinition-ext-coverage-information.html)
|
|
36
|
+
must be correct for all resources checked by Inferno.
|
|
37
|
+
DESCRIPTION
|
|
38
|
+
|
|
39
|
+
verifies_requirements 'hl7.fhir.us.davinci-crd_2.2.1@found-36-B', 'hl7.fhir.us.davinci-crd_2.2.1@resp-46'
|
|
40
|
+
|
|
41
|
+
uses_request :capability_statement
|
|
42
|
+
|
|
43
|
+
run do
|
|
44
|
+
supported_resource_types = extract_supported_resource_types(resource) # extract before loading other requests
|
|
45
|
+
|
|
46
|
+
loaded_requests = requests_to_analyze # all requests for one hook or all requests for all hooks
|
|
47
|
+
skip_if loaded_requests.blank?, 'No hook requests found, run hook tests first.'
|
|
48
|
+
|
|
49
|
+
resources_to_check, unsupported = find_coverage_info_responses(loaded_requests)
|
|
50
|
+
.partition { |request_details| supported_resource_types.include?(request_details[:resource_type]) }
|
|
51
|
+
unsupported.each do |request_details|
|
|
52
|
+
add_message('info', "#{error_prefix(request_details)}Resource type #{request_details[:resource_type]} " \
|
|
53
|
+
'is not supported by the client\'s FHIR API. This resource will not be verified.')
|
|
54
|
+
end
|
|
55
|
+
skip_if resources_to_check.blank?,
|
|
56
|
+
'No coverage-info responses found that Inferno could verify: ' \
|
|
57
|
+
're-run hook tests generating responses that Inferno can verify.'
|
|
58
|
+
|
|
59
|
+
resources_to_check.each do |resource_details|
|
|
60
|
+
check_for_stored_coverage_information_extension(resource_details)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
assert_no_error_messages('Not all coverage-information extensions stored. See Messages for details.')
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# important information to record:
|
|
67
|
+
# - relative resource reference (resource type + id)
|
|
68
|
+
# - coverage-information extension
|
|
69
|
+
# - position (response index + systemAction index)
|
|
70
|
+
def find_coverage_info_responses(requests)
|
|
71
|
+
all_responses = requests.flat_map.with_index do |request, request_index|
|
|
72
|
+
find_coverage_info_actions_in_response(request, request_index)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
all_responses.group_by { |resource_details| [resource_details[:resource_type], resource_details[:target_id]] }
|
|
76
|
+
.filter_map do |(_type, _id), entries|
|
|
77
|
+
if entries.size > 1
|
|
78
|
+
add_message('info',
|
|
79
|
+
"#{error_prefix(entries.first)}Multiple coverage-info responses found. Due to the " \
|
|
80
|
+
'complexity of determining the expected state, this resource will not be verified.')
|
|
81
|
+
next
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
if entries.first[:coverage_information_extensions].size > 1
|
|
85
|
+
add_message('info',
|
|
86
|
+
"#{error_prefix(entries.first)}Multiple coverage-information extensions found. Due to the " \
|
|
87
|
+
'complexity of determining the expected state, this resource will not be verified.')
|
|
88
|
+
next
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
entries.first
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def find_coverage_info_actions_in_response(request, request_index)
|
|
96
|
+
response = JSON.parse(request.response_body)
|
|
97
|
+
return [] unless response.is_a?(Hash) && response.key?('systemActions')
|
|
98
|
+
|
|
99
|
+
response['systemActions'].map.with_index do |action, action_index|
|
|
100
|
+
if coverage_information_response_type?(action)
|
|
101
|
+
extract_coverage_information_details(action, action_index, request_index)
|
|
102
|
+
end
|
|
103
|
+
end.compact
|
|
104
|
+
rescue JSON::ParserError
|
|
105
|
+
[] # no responses to check, error registered elsewhere
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def extract_coverage_information_details(action, action_index, request_index)
|
|
109
|
+
{
|
|
110
|
+
request_index:,
|
|
111
|
+
action_index:,
|
|
112
|
+
resource_type: action.dig('resource', 'resourceType'),
|
|
113
|
+
target_id: action.dig('resource', 'id'),
|
|
114
|
+
coverage_information_extensions: FHIR.from_contents(action['resource'].to_json).extension.select do |ext|
|
|
115
|
+
ext.url == COVERAGE_INFO_EXT_URL
|
|
116
|
+
end
|
|
117
|
+
}
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def extract_supported_resource_types(capability_statement)
|
|
121
|
+
return [] unless capability_statement.rest.is_a?(Array)
|
|
122
|
+
|
|
123
|
+
capability_statement.rest.select { |rest| rest.mode == 'server' }.flat_map do |rest|
|
|
124
|
+
next [] unless rest.resource.is_a?(Array)
|
|
125
|
+
|
|
126
|
+
rest.resource.select do |resource|
|
|
127
|
+
supports_read?(resource)
|
|
128
|
+
end.flat_map(&:type).compact
|
|
129
|
+
end.uniq
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def supports_read?(resource)
|
|
133
|
+
resource.interaction&.any? do |interaction|
|
|
134
|
+
interaction.code == 'read'
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def check_for_stored_coverage_information_extension(resource_details)
|
|
139
|
+
fhir_read resource_details[:resource_type], resource_details[:target_id]
|
|
140
|
+
unless resource.present? && resource.resourceType == resource_details[:resource_type]
|
|
141
|
+
add_message('error', "#{error_prefix(resource_details)}Unable to read target resource.")
|
|
142
|
+
return
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
stored_extensions = resource.extension.select { |ext| ext.url == COVERAGE_INFO_EXT_URL }
|
|
146
|
+
if stored_extensions.blank?
|
|
147
|
+
add_message('error', "#{error_prefix(resource_details)}coverage-information extension(s) not stored.")
|
|
148
|
+
return
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
difference_string = coverage_info_extension_differences(
|
|
152
|
+
resource_details[:coverage_information_extensions],
|
|
153
|
+
stored_extensions
|
|
154
|
+
)
|
|
155
|
+
return unless difference_string.present?
|
|
156
|
+
|
|
157
|
+
add_message('error', "#{error_prefix(resource_details)}#{difference_string}.")
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def coverage_info_extension_differences(expected, actual)
|
|
161
|
+
raise ArgumentError, 'expected must contain exactly one coverage-information extension' if expected.size != 1
|
|
162
|
+
|
|
163
|
+
if expected.size != actual.size
|
|
164
|
+
return "Expected #{expected.size} coverage-information extension(s), found #{actual.size}."
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
differences = compare_coverage_info_sub_extensions(expected[0], actual[0])
|
|
168
|
+
return unless differences.present?
|
|
169
|
+
|
|
170
|
+
"Stored coverage-information extension does not match what was sent by the server: #{differences.join(', ')}"
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def compare_coverage_info_sub_extensions(expected, actual)
|
|
174
|
+
expected_by_url = expected.extension.group_by(&:url)
|
|
175
|
+
actual_by_url = actual.extension.group_by(&:url)
|
|
176
|
+
|
|
177
|
+
(expected_by_url.keys | actual_by_url.keys).filter_map do |url|
|
|
178
|
+
compare_url_sub_extensions(url, expected_by_url, actual_by_url)
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def compare_url_sub_extensions(url, expected_by_url, actual_by_url)
|
|
183
|
+
if !expected_by_url.key?(url)
|
|
184
|
+
"unexpected sub-extension '#{url}' found in stored resource"
|
|
185
|
+
elsif !actual_by_url.key?(url)
|
|
186
|
+
"sub-extension '#{url}' missing from stored resource"
|
|
187
|
+
elsif normalized_extensions(expected_by_url[url]) != normalized_extensions(actual_by_url[url])
|
|
188
|
+
"sub-extension '#{url}' value differs"
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def normalized_extensions(extensions)
|
|
193
|
+
extensions.map { |e| normalize_extension(e.to_hash) }.sort_by(&:to_json)
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# Recursively sort nested arrays so sub-extension order doesn't affect equality.
|
|
197
|
+
def normalize_extension(value)
|
|
198
|
+
case value
|
|
199
|
+
when Hash then value.transform_values { |v| normalize_extension(v) }
|
|
200
|
+
when Array then value.map { |item| normalize_extension(item) }.sort_by(&:to_json)
|
|
201
|
+
else value
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def error_prefix(resource_details)
|
|
206
|
+
"(Request #{resource_details[:request_index] + 1}) " \
|
|
207
|
+
"coverage-info systemAction #{resource_details[:action_index] + 1} " \
|
|
208
|
+
"targeting resource #{resource_details[:resource_type]}/#{resource_details[:target_id]}: "
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require_relative 'client_coverage_info_update_test'
|
|
2
|
+
|
|
3
|
+
module DaVinciCRDTestKit
|
|
4
|
+
module V221
|
|
5
|
+
class ClientCRDUpdateVerificationGroup < Inferno::TestGroup
|
|
6
|
+
id :crd_v221_client_update_verification
|
|
7
|
+
title 'CRD Update Tests'
|
|
8
|
+
description %(
|
|
9
|
+
This CRD-specific group verifies that the client was able to
|
|
10
|
+
persist updates provided by the payer server as a part of
|
|
11
|
+
decision support responses.
|
|
12
|
+
)
|
|
13
|
+
run_as_group
|
|
14
|
+
|
|
15
|
+
test from: :crd_v221_client_coverage_info_update
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|