davinci_crd_test_kit 0.12.2 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/config/presets/inferno_crd_client_suite.json.erb +20 -14
- data/config/presets/inferno_crd_client_suite_prefetch_subset_v221.json.erb +125 -0
- data/config/presets/inferno_crd_client_suite_v221.json.erb +124 -0
- data/config/presets/inferno_crd_server_suite.json.erb +59 -2
- data/config/presets/inferno_crd_server_suite_v221.json.erb +94 -0
- data/config/presets/ri_crd_request_generator.json_v221.json.erb +13 -0
- data/config/presets/ri_crd_server.json.erb +19 -19
- data/lib/davinci_crd_test_kit/client/client_base_urls.rb +80 -0
- data/lib/davinci_crd_test_kit/{client_hook_request_validation.rb → client/client_hook_request_validation.rb} +1 -1
- data/lib/davinci_crd_test_kit/client/crd_client_options.rb +30 -0
- data/lib/davinci_crd_test_kit/client/endpoints/cds_services_discovery_handler.rb +34 -0
- data/lib/davinci_crd_test_kit/client/endpoints/custom_service_response.rb +342 -0
- data/lib/davinci_crd_test_kit/client/endpoints/gather_response_generation_data.rb +410 -0
- data/lib/davinci_crd_test_kit/client/endpoints/hook_request_endpoint.rb +233 -0
- data/lib/davinci_crd_test_kit/{mock_service_response.rb → client/endpoints/mock_service_response.rb} +165 -59
- data/lib/davinci_crd_test_kit/{card_responses → client/endpoints/mocked_card_responses}/companions_prerequisites.json +1 -0
- data/lib/davinci_crd_test_kit/{card_responses → client/endpoints/mocked_card_responses}/create_update_coverage_information.json +3 -2
- data/lib/davinci_crd_test_kit/{card_responses → client/endpoints/mocked_card_responses}/launch_smart_app.json +8 -1
- data/lib/davinci_crd_test_kit/{card_responses → client/endpoints/mocked_card_responses}/propose_alternate_request.json +1 -0
- data/lib/davinci_crd_test_kit/{card_responses → client/endpoints/mocked_card_responses}/request_form_completion.json +17 -16
- data/lib/davinci_crd_test_kit/client/multi_request_message_helper.rb +35 -0
- data/lib/davinci_crd_test_kit/client/tagged_request_load_helper.rb +38 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/api/client_fhir_api_create_test.rb +43 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/api/client_fhir_api_read_test.rb +43 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/api/client_fhir_api_search_test.rb +234 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/api/client_fhir_api_update_test.rb +43 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/api/client_fhir_api_validation_test.rb +63 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/auth/decode_auth_token_test.rb +65 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/auth/retrieve_jwks_test.rb +109 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/auth/token_header_test.rb +70 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/auth/token_payload_test.rb +85 -0
- data/lib/davinci_crd_test_kit/{routes/cds-services.json → client/v2.0.1/cds-services-v201.json} +1 -1
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_appointment_book_group.rb +108 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_card_must_support_group.rb +31 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_encounter_discharge_group.rb +105 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_encounter_start_group.rb +105 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_fhir_api_group.rb +790 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_hooks_group.rb +74 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_order_dispatch_group.rb +111 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_order_select_group.rb +116 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_order_sign_group.rb +113 -0
- data/lib/davinci_crd_test_kit/{client_registration_group.rb → client/v2.0.1/client_registration_group.rb} +12 -8
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_urls.rb +13 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/crd_client_suite.rb +134 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/invocation/appointment_book_receive_request_test.rb +129 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/invocation/encounter_discharge_receive_request_test.rb +126 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/invocation/encounter_start_receive_request_test.rb +126 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/invocation/order_dispatch_receive_request_test.rb +138 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/invocation/order_select_receive_request_test.rb +134 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/invocation/order_sign_receive_request_test.rb +136 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/must_support/client_card_must_support_coverage_information.rb +93 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/must_support/client_card_must_support_external_reference.rb +62 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/must_support/client_card_must_support_instructions.rb +62 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/registration/client_registration_verification_test.rb +94 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/registration/client_service_registration_attestation_test.rb +40 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_fetched_data_test.rb +86 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_optional_fields_test.rb +63 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_prefetch_equals_queried_test.rb +96 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_required_fields_test.rb +55 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_valid_context_test.rb +70 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_valid_prefetch_test.rb +62 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_response/client_display_cards_attest.rb +83 -0
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_response/inferno_response_validation.rb +79 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/api/client_coverage_info_update_test.rb +212 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/api/client_crd_update_verification_group.rb +18 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/auth/decode_auth_token_test.rb +69 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/auth/retrieve_jwks_test.rb +120 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/auth/token_header_test.rb +92 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/auth/token_payload_test.rb +93 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/cds-services-prefetch-subset-v221.json +198 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/cds-services-v221.json +202 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_appointment_book_group.rb +102 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_cross_hook_group.rb +28 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_encounter_discharge_group.rb +96 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_encounter_start_group.rb +95 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_fhir_api_group.rb +88 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_hooks_group.rb +64 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_long_running_hook_group.rb +32 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_order_dispatch_group.rb +101 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_order_select_group.rb +102 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_order_sign_group.rb +107 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_registration_group.rb +27 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_urls.rb +27 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/crd_client_suite.rb +229 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_card_must_support_coverage_information_test.rb +63 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_fhirpath_collection_as_comma_delimited_string_test.rb +60 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_hook_instances_unique_test.rb +45 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_location_address_propagation_test.rb +135 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_prefetch_complete_and_subset_test.rb +103 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/appointment_book_receive_request_test.rb +156 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/encounter_discharge_receive_request_test.rb +157 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/encounter_start_receive_request_test.rb +157 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/order_dispatch_receive_request_test.rb +165 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/order_select_receive_request_test.rb +165 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/order_sign_receive_request_test.rb +165 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/long_running/client_long_running_receive_request_test.rb +64 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/long_running/client_skip_long_running_attestation_test.rb +49 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/registration/client_registration_verification_test.rb +161 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/registration/client_service_registration_attestation_test.rb +107 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_conformance_test.rb +47 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_coverage_verification_test.rb +152 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_data_fetch_verification_test.rb +55 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_granted_scopes_test.rb +123 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_prefetch_complete_test.rb +127 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_prefetch_profiles_test.rb +55 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_requested_version_test.rb +54 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_secured_transport_test.rb +48 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_response/client_display_cards_attest.rb +74 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_response/hook_response_support_coverage_information_test.rb +30 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_response/inferno_response_validation.rb +77 -0
- data/lib/davinci_crd_test_kit/cross_suite/base_urls.rb +20 -0
- data/lib/davinci_crd_test_kit/cross_suite/cards_identification.rb +312 -0
- data/lib/davinci_crd_test_kit/{cards_validation.rb → cross_suite/cards_validation.rb} +104 -47
- data/lib/davinci_crd_test_kit/cross_suite/coverage-information_stu201_metadata.yml +27 -0
- data/lib/davinci_crd_test_kit/cross_suite/coverage-information_stu221_metadata.yml +60 -0
- data/lib/davinci_crd_test_kit/cross_suite/fhirpath_on_cds_request.rb +177 -0
- data/lib/davinci_crd_test_kit/{hook_request_field_validation.rb → cross_suite/hook_request_field_validation.rb} +282 -203
- data/lib/davinci_crd_test_kit/cross_suite/logical_models_override_helper.rb +220 -0
- data/lib/davinci_crd_test_kit/cross_suite/prefetch_completeness_checker.rb +462 -0
- data/lib/davinci_crd_test_kit/cross_suite/prefetch_contents_validation.rb +81 -0
- data/lib/davinci_crd_test_kit/cross_suite/prefetch_profile_validation.rb +48 -0
- data/lib/davinci_crd_test_kit/cross_suite/profiles_and_resource_types.rb +63 -0
- data/lib/davinci_crd_test_kit/cross_suite/replace_tokens.rb +38 -0
- data/lib/davinci_crd_test_kit/cross_suite/requests_logical_model_validation.rb +202 -0
- data/lib/davinci_crd_test_kit/cross_suite/response_logical_model_validation.rb +274 -0
- data/lib/davinci_crd_test_kit/{suggestion_actions_validation.rb → cross_suite/suggestion_actions_validation.rb} +70 -50
- data/lib/davinci_crd_test_kit/cross_suite/tags.rb +42 -0
- data/lib/davinci_crd_test_kit/metadata.rb +10 -44
- data/lib/davinci_crd_test_kit/requirements/cds-hooks-library_1.0.1_requirements.xlsx +0 -0
- data/lib/davinci_crd_test_kit/requirements/cds-hooks_2.0_requirements.xlsx +0 -0
- data/lib/davinci_crd_test_kit/requirements/cds-hooks_3.0.0-ballot_requirements.xlsx +0 -0
- data/lib/davinci_crd_test_kit/requirements/davinci_crd_test_kit_requirements.csv +742 -65
- data/lib/davinci_crd_test_kit/requirements/generated/crd_client_requirements_coverage.csv +279 -54
- data/lib/davinci_crd_test_kit/requirements/generated/crd_client_v221_requirements_coverage.csv +1430 -0
- data/lib/davinci_crd_test_kit/requirements/generated/crd_server_requirements_coverage.csv +36 -45
- data/lib/davinci_crd_test_kit/requirements/generated/crd_server_v221_requirements_coverage.csv +143 -0
- data/lib/davinci_crd_test_kit/requirements/hl7.fhir.us.davinci-crd_2.0.1_requirements.xlsx +0 -0
- data/lib/davinci_crd_test_kit/requirements/hl7.fhir.us.davinci-crd_2.2.1_requirements.xlsx +0 -0
- data/lib/davinci_crd_test_kit/server/endpoints/jwk_set_endpoint_handler.rb +13 -0
- data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_create_endpoint.rb +23 -0
- data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_delete_endpoint.rb +30 -0
- data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_metadata_endpoint.rb +112 -0
- data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_read_endpoint.rb +21 -0
- data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_request_handler.rb +261 -0
- data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_search_endpoint.rb +561 -0
- data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_update_endpoint.rb +24 -0
- data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/stress-test-Bundle.json +54687 -0
- data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr_endpoints.rb +95 -0
- data/lib/davinci_crd_test_kit/server/jobs/invoke_hook.rb +225 -0
- data/lib/davinci_crd_test_kit/{jwt_helper.rb → server/jwt_helper.rb} +1 -12
- data/lib/davinci_crd_test_kit/server/resource_extractor.rb +68 -0
- data/lib/davinci_crd_test_kit/server/server_abstract_invoke_hook_test.rb +165 -0
- data/lib/davinci_crd_test_kit/server/server_base_urls.rb +30 -0
- data/lib/davinci_crd_test_kit/{server_hook_helper.rb → server/server_hook_helper.rb} +1 -1
- data/lib/davinci_crd_test_kit/{server_hook_request_validation.rb → server/server_hook_request_validation.rb} +1 -1
- data/lib/davinci_crd_test_kit/{test_helper.rb → server/server_test_helper.rb} +7 -3
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Appointment.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/ClaimResponse.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/CommunicationRequest.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Coverage.yml +21 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Device.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/DeviceRequest.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Encounter.yml +7 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Location.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/MedicationRequest.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/NutritionOrder.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Organization.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Patient.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Practitioner.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/PractitionerRole.yml +40 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/ServiceRequest.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Task.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/VisionPrescription.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_server_suite.rb +99 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/discovery/discovery_endpoint_test.rb +90 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/discovery/discovery_services_validation_test.rb +67 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/interaction/server_invoke_hook_test.rb +12 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/must_support/coverage_information_system_action_across_hooks_validation_test.rb +34 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/must_support/external_reference_card_across_hooks_validation_test.rb +30 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/must_support/instructions_card_received_across_hooks_test.rb +27 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_appointment_book_group.rb +191 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_demonstrate_hook_response_group.rb +93 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_discovery_group.rb +62 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_encounter_discharge_group.rb +186 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_encounter_start_group.rb +186 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_hooks_group.rb +73 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_order_dispatch_group.rb +191 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_order_select_group.rb +211 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_order_sign_group.rb +216 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_required_card_response_validation_group.rb +28 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_urls.rb +13 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_request/service_request_context_validation_test.rb +30 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_request/service_request_optional_fields_validation_test.rb +39 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_request/service_request_required_fields_validation_test.rb +40 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/additional_orders_validation_test.rb +59 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/card_optional_fields_validation_test.rb +51 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/coverage_information_system_action_received_test.rb +65 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/coverage_information_system_action_validation_test.rb +120 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/create_or_update_coverage_info_response_validation_test.rb +70 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/external_reference_card_validation_test.rb +37 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/form_completion_response_validation_test.rb +67 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/instructions_card_received_test.rb +30 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/launch_smart_app_card_validation_test.rb +39 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/propose_alternate_request_card_validation_test.rb +46 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/service_response_validation_test.rb +83 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Appointment_withorder.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Appointment_withoutorder.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/CommunicationRequest.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Coverage.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Device.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/DeviceRequest.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Encounter.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Location.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/MedicationRequest.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/NutritionOrder.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Organization.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Patient.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/PractitionerRole.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/ServiceRequest.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/VisionPrescription.yml +5 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/crd_server_suite.rb +115 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/discovery/discovery_configuration_test.rb +159 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/discovery/discovery_endpoint_test.rb +90 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/discovery/discovery_prefetch_support_test.rb +43 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/discovery/discovery_services_validation_test.rb +121 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/interaction/server_invoke_hook_test.rb +17 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/must_support/coverage_information_must_support_test.rb +71 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/must_support/coverage_information_system_action_across_hooks_validation_test.rb +36 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/must_support/supported_us_core_versions_test.rb +118 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_appointment_book_group.rb +213 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_demonstrate_hook_response_group.rb +93 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_discovery_group.rb +69 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_encounter_discharge_group.rb +194 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_encounter_start_group.rb +194 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_hooks_group.rb +73 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_order_dispatch_group.rb +214 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_order_select_group.rb +219 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_order_sign_group.rb +241 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_required_card_response_validation_group.rb +30 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_urls.rb +13 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_request/service_request_context_validation_test.rb +30 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_request/service_request_no_custom_extensions_test.rb +120 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_request/service_request_optional_fields_validation_test.rb +39 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_request/service_request_required_fields_validation_test.rb +40 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/additional_orders_validation_test.rb +66 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/all_responses_include_coverage_information_test.rb +123 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/card_optional_fields_validation_test.rb +57 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/coverage_info_configuration_test.rb +83 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/coverage_information_system_action_received_test.rb +65 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/coverage_information_system_action_validation_test.rb +184 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/create_or_update_coverage_info_response_validation_test.rb +75 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/external_reference_card_validation_test.rb +47 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/form_completion_response_validation_test.rb +91 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/hook_request_resource_resolution.rb +137 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/instructions_card_received_test.rb +32 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/launch_smart_app_card_validation_test.rb +49 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/order_dispatch_coverage_information_test.rb +38 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/propose_alternate_request_card_validation_test.rb +54 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/service_response_validation_test.rb +97 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/unknown_cds_hooks_elements_test.rb +78 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/unknown_configuration_test.rb +78 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/unknown_context_test.rb +78 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/verify_response_without_billing_options_test.rb +43 -0
- data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/verify_response_without_configuration_test.rb +44 -0
- data/lib/davinci_crd_test_kit/version.rb +2 -2
- data/lib/davinci_crd_test_kit.rb +4 -2
- metadata +308 -101
- data/lib/davinci_crd_test_kit/client_fhir_api_group.rb +0 -785
- data/lib/davinci_crd_test_kit/client_hooks_group.rb +0 -75
- data/lib/davinci_crd_test_kit/client_tests/appointment_book_receive_request_test.rb +0 -93
- data/lib/davinci_crd_test_kit/client_tests/client_appointment_book_group.rb +0 -75
- data/lib/davinci_crd_test_kit/client_tests/client_display_cards_attest.rb +0 -48
- data/lib/davinci_crd_test_kit/client_tests/client_encounter_discharge_group.rb +0 -73
- data/lib/davinci_crd_test_kit/client_tests/client_encounter_start_group.rb +0 -73
- data/lib/davinci_crd_test_kit/client_tests/client_fhir_api_create_test.rb +0 -41
- data/lib/davinci_crd_test_kit/client_tests/client_fhir_api_read_test.rb +0 -39
- data/lib/davinci_crd_test_kit/client_tests/client_fhir_api_search_test.rb +0 -232
- data/lib/davinci_crd_test_kit/client_tests/client_fhir_api_update_test.rb +0 -41
- data/lib/davinci_crd_test_kit/client_tests/client_fhir_api_validation_test.rb +0 -60
- data/lib/davinci_crd_test_kit/client_tests/client_order_dispatch_group.rb +0 -79
- data/lib/davinci_crd_test_kit/client_tests/client_order_select_group.rb +0 -82
- data/lib/davinci_crd_test_kit/client_tests/client_order_sign_group.rb +0 -81
- data/lib/davinci_crd_test_kit/client_tests/client_registration_verification_test.rb +0 -88
- data/lib/davinci_crd_test_kit/client_tests/decode_auth_token_test.rb +0 -60
- data/lib/davinci_crd_test_kit/client_tests/encounter_discharge_receive_request_test.rb +0 -90
- data/lib/davinci_crd_test_kit/client_tests/encounter_start_receive_request_test.rb +0 -90
- data/lib/davinci_crd_test_kit/client_tests/hook_request_optional_fields_test.rb +0 -57
- data/lib/davinci_crd_test_kit/client_tests/hook_request_required_fields_test.rb +0 -49
- data/lib/davinci_crd_test_kit/client_tests/hook_request_valid_context_test.rb +0 -68
- data/lib/davinci_crd_test_kit/client_tests/hook_request_valid_prefetch_test.rb +0 -69
- data/lib/davinci_crd_test_kit/client_tests/order_dispatch_receive_request_test.rb +0 -102
- data/lib/davinci_crd_test_kit/client_tests/order_select_receive_request_test.rb +0 -98
- data/lib/davinci_crd_test_kit/client_tests/order_sign_receive_request_test.rb +0 -101
- data/lib/davinci_crd_test_kit/client_tests/retrieve_jwks_test.rb +0 -105
- data/lib/davinci_crd_test_kit/client_tests/submitted_response_validation.rb +0 -44
- data/lib/davinci_crd_test_kit/client_tests/token_header_test.rb +0 -65
- data/lib/davinci_crd_test_kit/client_tests/token_payload_test.rb +0 -78
- data/lib/davinci_crd_test_kit/crd_client_suite.rb +0 -185
- data/lib/davinci_crd_test_kit/crd_options.rb +0 -9
- data/lib/davinci_crd_test_kit/crd_server_suite.rb +0 -125
- data/lib/davinci_crd_test_kit/igs/davinci-crd-2.0.1.tgz +0 -0
- data/lib/davinci_crd_test_kit/routes/cds_services_discovery_handler.rb +0 -18
- data/lib/davinci_crd_test_kit/routes/hook_request_endpoint.rb +0 -77
- data/lib/davinci_crd_test_kit/routes/jwk_set_endpoint_handler.rb +0 -15
- data/lib/davinci_crd_test_kit/server_appointment_book_group.rb +0 -176
- data/lib/davinci_crd_test_kit/server_demonstrate_hook_response_group.rb +0 -77
- data/lib/davinci_crd_test_kit/server_discovery_group.rb +0 -60
- data/lib/davinci_crd_test_kit/server_encounter_discharge_group.rb +0 -170
- data/lib/davinci_crd_test_kit/server_encounter_start_group.rb +0 -170
- data/lib/davinci_crd_test_kit/server_hooks_group.rb +0 -71
- data/lib/davinci_crd_test_kit/server_order_dispatch_group.rb +0 -176
- data/lib/davinci_crd_test_kit/server_order_select_group.rb +0 -195
- data/lib/davinci_crd_test_kit/server_order_sign_group.rb +0 -201
- data/lib/davinci_crd_test_kit/server_required_card_response_validation_group.rb +0 -26
- data/lib/davinci_crd_test_kit/server_tests/additional_orders_validation_test.rb +0 -68
- data/lib/davinci_crd_test_kit/server_tests/card_optional_fields_validation_test.rb +0 -47
- data/lib/davinci_crd_test_kit/server_tests/coverage_information_system_action_across_hooks_validation_test.rb +0 -32
- data/lib/davinci_crd_test_kit/server_tests/coverage_information_system_action_received_test.rb +0 -63
- data/lib/davinci_crd_test_kit/server_tests/coverage_information_system_action_validation_test.rb +0 -118
- data/lib/davinci_crd_test_kit/server_tests/create_or_update_coverage_info_response_validation_test.rb +0 -71
- data/lib/davinci_crd_test_kit/server_tests/discovery_endpoint_test.rb +0 -88
- data/lib/davinci_crd_test_kit/server_tests/discovery_services_validation_test.rb +0 -65
- data/lib/davinci_crd_test_kit/server_tests/external_reference_card_across_hooks_validation_test.rb +0 -28
- data/lib/davinci_crd_test_kit/server_tests/external_reference_card_validation_test.rb +0 -36
- data/lib/davinci_crd_test_kit/server_tests/form_completion_response_validation_test.rb +0 -78
- data/lib/davinci_crd_test_kit/server_tests/instructions_card_received_across_hooks_test.rb +0 -25
- data/lib/davinci_crd_test_kit/server_tests/instructions_card_received_test.rb +0 -26
- data/lib/davinci_crd_test_kit/server_tests/launch_smart_app_card_validation_test.rb +0 -38
- data/lib/davinci_crd_test_kit/server_tests/propose_alternate_request_card_validation_test.rb +0 -63
- data/lib/davinci_crd_test_kit/server_tests/service_call_test.rb +0 -101
- data/lib/davinci_crd_test_kit/server_tests/service_request_context_validation_test.rb +0 -28
- data/lib/davinci_crd_test_kit/server_tests/service_request_optional_fields_validation_test.rb +0 -37
- data/lib/davinci_crd_test_kit/server_tests/service_request_required_fields_validation_test.rb +0 -38
- data/lib/davinci_crd_test_kit/server_tests/service_response_validation_test.rb +0 -81
- data/lib/davinci_crd_test_kit/tags.rb +0 -10
- data/lib/davinci_crd_test_kit/urls.rb +0 -52
- /data/lib/davinci_crd_test_kit/{card_responses → client/endpoints/mocked_card_responses}/external_reference.json +0 -0
- /data/lib/davinci_crd_test_kit/{card_responses → client/endpoints/mocked_card_responses}/instructions.json +0 -0
- /data/lib/davinci_crd_test_kit/{crd_jwks.json → server/endpoints/crd_jwks.json} +0 -0
- /data/lib/davinci_crd_test_kit/{jwks.rb → server/endpoints/jwks.rb} +0 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module DaVinciCRDTestKit
|
|
2
|
+
module V201
|
|
3
|
+
class ClientFHIRApiCreateTest < Inferno::Test
|
|
4
|
+
id :crd_v201_client_fhir_api_create_test
|
|
5
|
+
title 'Create Interaction'
|
|
6
|
+
description %(
|
|
7
|
+
Verify that the CRD client supports the create interaction for the given resource. The capabilities required
|
|
8
|
+
by each resource can be found here: https://hl7.org/fhir/us/davinci-crd/CapabilityStatement-crd-client.html#resourcesSummary1
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
input :create_resources,
|
|
12
|
+
type: 'textarea',
|
|
13
|
+
description: 'Provide a list of resources to create. e.g., [json_resource_1, json_resource_2]',
|
|
14
|
+
optional: true
|
|
15
|
+
|
|
16
|
+
def resource_type
|
|
17
|
+
config.options[:resource_type]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
run do
|
|
21
|
+
skip_if create_resources.blank?, 'Provide a list of resources to create to run this test.'
|
|
22
|
+
assert_valid_json(create_resources)
|
|
23
|
+
create_resources_list = JSON.parse(create_resources)
|
|
24
|
+
skip_if(!create_resources_list.is_a?(Array), 'Resources to create not inputted in list format, skipping test.')
|
|
25
|
+
|
|
26
|
+
valid_create_resources =
|
|
27
|
+
create_resources_list
|
|
28
|
+
.compact_blank
|
|
29
|
+
.map { |resource| FHIR.from_contents(resource.to_json) }
|
|
30
|
+
.select { |resource| resource.resourceType == resource_type }
|
|
31
|
+
.select { |resource| resource_is_valid?(resource:) }
|
|
32
|
+
|
|
33
|
+
skip_if(valid_create_resources.blank?,
|
|
34
|
+
%(No valid #{resource_type} resources were provided to send in Create requests, skipping test.))
|
|
35
|
+
|
|
36
|
+
valid_create_resources.each do |create_resource|
|
|
37
|
+
fhir_create(create_resource)
|
|
38
|
+
assert_response_status(201)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module DaVinciCRDTestKit
|
|
2
|
+
module V201
|
|
3
|
+
class ClientFHIRApiReadTest < Inferno::Test
|
|
4
|
+
id :crd_v201_client_fhir_api_read_test
|
|
5
|
+
title 'Read Interaction'
|
|
6
|
+
description %(
|
|
7
|
+
Verify that the CRD client supports the read interaction for the given resource. The capabilities required by
|
|
8
|
+
each resource can be found here: https://hl7.org/fhir/us/davinci-crd/CapabilityStatement-crd-client.html#resourcesSummary1
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
input :resource_ids,
|
|
12
|
+
optional: true
|
|
13
|
+
|
|
14
|
+
def resource_type
|
|
15
|
+
config.options[:resource_type]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def no_resources_skip_message
|
|
19
|
+
"No #{resource_type} resource ids were provided, skipping test. "
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def bad_resource_id_message(expected_id)
|
|
23
|
+
"Expected resource to have id: `#{expected_id}`, but found `#{resource.id}`"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
run do
|
|
27
|
+
skip_if resource_ids.blank?, no_resources_skip_message
|
|
28
|
+
|
|
29
|
+
resource_id_list = resource_ids.split(',').map(&:strip)
|
|
30
|
+
assert resource_id_list.present?, "No #{resource_type} id provided."
|
|
31
|
+
|
|
32
|
+
resource_id_list.each do |resource_id_to_read|
|
|
33
|
+
fhir_read resource_type, resource_id_to_read, tags: [resource_type, 'read']
|
|
34
|
+
|
|
35
|
+
assert_response_status(200)
|
|
36
|
+
assert_resource_type(resource_type)
|
|
37
|
+
assert resource.id.present? && resource.id == resource_id_to_read,
|
|
38
|
+
bad_resource_id_message(resource_id_to_read)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
module DaVinciCRDTestKit
|
|
2
|
+
module V201
|
|
3
|
+
class ClientFHIRApiSearchTest < Inferno::Test
|
|
4
|
+
id :crd_v201_client_fhir_api_search_test
|
|
5
|
+
title 'Search Interaction'
|
|
6
|
+
description %(
|
|
7
|
+
Verify that the CRD client supports the specified search interaction for the given resource. The capabilities
|
|
8
|
+
required by each resource can be found here: https://hl7.org/fhir/us/davinci-crd/CapabilityStatement-crd-client.html#resourcesSummary1
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
input :search_param_values,
|
|
12
|
+
optional: true
|
|
13
|
+
|
|
14
|
+
attr_accessor :successful_search
|
|
15
|
+
|
|
16
|
+
def resource_type
|
|
17
|
+
config.options[:resource_type]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def search_type
|
|
21
|
+
config.options[:search_type]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def include_searches
|
|
25
|
+
['organization_include', 'practitioner_include', 'location_include']
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def reference_search_parameters
|
|
29
|
+
['organization', 'practitioner', 'patient']
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def bad_resource_id_message(expected_id, actual_id)
|
|
33
|
+
"Expected resource to have id: `#{expected_id}`, but found `#{actual_id}`"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def perform_fhir_search(search_params, tags)
|
|
37
|
+
fhir_search(resource_type, params: search_params, tags:)
|
|
38
|
+
assert_response_status(200)
|
|
39
|
+
assert_resource_type(:bundle)
|
|
40
|
+
resource
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def status_search_result_check(bundle, status)
|
|
44
|
+
return if bundle.entry.empty?
|
|
45
|
+
|
|
46
|
+
self.successful_search = true
|
|
47
|
+
|
|
48
|
+
bundle.entry
|
|
49
|
+
.reject { |entry| entry&.resource&.resourceType == 'OperationOutcome' }
|
|
50
|
+
.map(&:resource)
|
|
51
|
+
.each do |resource|
|
|
52
|
+
assert_resource_type(resource_type, resource:)
|
|
53
|
+
assert(resource.status == status, %(
|
|
54
|
+
Each #{resource_type} resource in search result bundle should have a status of `#{status}`, instead got:
|
|
55
|
+
`#{resource.status}` for resource with id: `#{resource.id}`
|
|
56
|
+
))
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def check_id_search_result_entry(bundle_entry, search_id, entry_resource_type)
|
|
61
|
+
assert_resource_type(entry_resource_type, resource: bundle_entry)
|
|
62
|
+
|
|
63
|
+
assert bundle_entry.id.present?, "Expected id field in returned #{entry_resource_type} resource"
|
|
64
|
+
|
|
65
|
+
assert bundle_entry.id == search_id,
|
|
66
|
+
bad_resource_id_message(search_id, bundle_entry.id)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def id_search_result_check(bundle, search_id)
|
|
70
|
+
warning do
|
|
71
|
+
assert bundle.entry.any?,
|
|
72
|
+
"Search result bundle is empty for #{resource_type} _id search with an id of `#{search_id}`"
|
|
73
|
+
end
|
|
74
|
+
return if bundle.entry.empty?
|
|
75
|
+
|
|
76
|
+
self.successful_search = true
|
|
77
|
+
|
|
78
|
+
bundle.entry
|
|
79
|
+
.reject { |entry| entry&.resource&.resourceType == 'OperationOutcome' }
|
|
80
|
+
.map(&:resource)
|
|
81
|
+
.each do |resource|
|
|
82
|
+
check_id_search_result_entry(resource, search_id, resource_type)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def check_include_reference(base_resource_entry, include_resource_id, include_resource_type)
|
|
87
|
+
base_resource_references = Array.wrap(get_reference_field(include_resource_type, base_resource_entry)).compact
|
|
88
|
+
|
|
89
|
+
assert(base_resource_references.present?, %(
|
|
90
|
+
#{resource_type} resource with id #{base_resource_entry.id} did not include the field that references a
|
|
91
|
+
#{include_resource_type} resource}
|
|
92
|
+
))
|
|
93
|
+
|
|
94
|
+
base_resource_reference_match_found = base_resource_references.any? do |base_resource_reference|
|
|
95
|
+
base_resource_reference.reference_id == include_resource_id
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
assert(base_resource_reference_match_found, %(
|
|
99
|
+
The #{resource_type} resource in search result bundle with id #{base_resource_entry.id} did not have a
|
|
100
|
+
#{include_resource_type} reference with an id of `#{include_resource_id}`.`
|
|
101
|
+
))
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def include_search_result_check(bundle, search_id, included_resource_type) # rubocop:disable Metrics/CyclomaticComplexity
|
|
105
|
+
warning do
|
|
106
|
+
assert bundle.entry.any?,
|
|
107
|
+
"Search result bundle is empty for #{resource_type} _include #{search_type} search with an id
|
|
108
|
+
of `#{search_id}`"
|
|
109
|
+
end
|
|
110
|
+
return if bundle.entry.empty?
|
|
111
|
+
|
|
112
|
+
self.successful_search = true
|
|
113
|
+
|
|
114
|
+
base_resource_entry_list = bundle.entry.select do |entry|
|
|
115
|
+
entry.resource&.resourceType == resource_type
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
assert(base_resource_entry_list.length == 1, %(
|
|
119
|
+
The #{included_resource_type} _include search for #{resource_type} resource with id #{search_id}
|
|
120
|
+
should include exactly 1 #{resource_type} resource, instead got #{base_resource_entry_list.length}.
|
|
121
|
+
))
|
|
122
|
+
|
|
123
|
+
base_resource_entry = base_resource_entry_list.first.resource
|
|
124
|
+
|
|
125
|
+
bundle.entry
|
|
126
|
+
.map(&:resource)
|
|
127
|
+
.each do |resource|
|
|
128
|
+
entry_resource_type = resource.resourceType
|
|
129
|
+
|
|
130
|
+
if entry_resource_type == resource_type
|
|
131
|
+
check_id_search_result_entry(resource, search_id, entry_resource_type)
|
|
132
|
+
elsif entry_resource_type != 'OperationOutcome'
|
|
133
|
+
entry_resource_type = included_resource_type.capitalize
|
|
134
|
+
assert_resource_type(entry_resource_type, resource:)
|
|
135
|
+
|
|
136
|
+
included_resource_id = resource.id
|
|
137
|
+
assert included_resource_id.present?, "Expected id field in returned #{entry_resource_type} resource"
|
|
138
|
+
check_include_reference(base_resource_entry, included_resource_id, included_resource_type)
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def get_reference_field(reference_type, entry)
|
|
144
|
+
case reference_type
|
|
145
|
+
when 'patient'
|
|
146
|
+
entry.beneficiary
|
|
147
|
+
when 'practitioner'
|
|
148
|
+
entry.practitioner
|
|
149
|
+
when 'organization'
|
|
150
|
+
if resource_type == 'Encounter'
|
|
151
|
+
entry.serviceProvider
|
|
152
|
+
else
|
|
153
|
+
entry.organization
|
|
154
|
+
end
|
|
155
|
+
when 'location'
|
|
156
|
+
locations = entry.location
|
|
157
|
+
locations.map(&:location)
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def reference_search_result_check(bundle, reference_id, reference_type)
|
|
162
|
+
warning do
|
|
163
|
+
assert bundle.entry.any?, %(
|
|
164
|
+
Search result bundle is empty for #{resource_type} #{reference_type} search with a #{reference_type} id
|
|
165
|
+
`#{reference_id}`
|
|
166
|
+
)
|
|
167
|
+
end
|
|
168
|
+
return if bundle.entry.empty?
|
|
169
|
+
|
|
170
|
+
self.successful_search = true
|
|
171
|
+
|
|
172
|
+
bundle.entry
|
|
173
|
+
.reject { |entry| entry&.resource&.resourceType == 'OperationOutcome' }
|
|
174
|
+
.map(&:resource)
|
|
175
|
+
.each do |resource|
|
|
176
|
+
assert_resource_type(resource_type, resource:)
|
|
177
|
+
|
|
178
|
+
entry_reference_field = get_reference_field(reference_type, resource)
|
|
179
|
+
assert(
|
|
180
|
+
entry_reference_field.present?,
|
|
181
|
+
%(
|
|
182
|
+
#{resource_type} resource with id #{resource.id} did not include the field that references
|
|
183
|
+
a #{reference_type} resource
|
|
184
|
+
)
|
|
185
|
+
)
|
|
186
|
+
|
|
187
|
+
entry_reference_id = entry_reference_field.reference_id
|
|
188
|
+
assert(
|
|
189
|
+
entry_reference_id == reference_id,
|
|
190
|
+
%(
|
|
191
|
+
The #{resource_type} resource in search result bundle with id #{resource.id} should have a
|
|
192
|
+
#{reference_type} reference with an id of `#{reference_id}`, instead got: `#{entry_reference_id}`
|
|
193
|
+
)
|
|
194
|
+
)
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
run do
|
|
199
|
+
if search_type == 'status'
|
|
200
|
+
coverage_status = ['active', 'cancelled', 'draft', 'entered-in-error']
|
|
201
|
+
coverage_status.each do |status|
|
|
202
|
+
bundle = perform_fhir_search({ status: }, [resource_type, 'status_search'])
|
|
203
|
+
status_search_result_check(bundle, status)
|
|
204
|
+
end
|
|
205
|
+
else
|
|
206
|
+
skip_if search_param_values.blank?, 'No search parameters passed in, skipping test.'
|
|
207
|
+
|
|
208
|
+
search_id_list = search_param_values.split(',').map(&:strip)
|
|
209
|
+
search_id_list.each do |search_id|
|
|
210
|
+
if search_type == '_id'
|
|
211
|
+
bundle = perform_fhir_search({ _id: search_id }, [resource_type, 'id_search'])
|
|
212
|
+
id_search_result_check(bundle, search_id)
|
|
213
|
+
elsif reference_search_parameters.include?(search_type)
|
|
214
|
+
search_params = {}
|
|
215
|
+
search_params[search_type] = "#{search_type.capitalize}/#{search_id}"
|
|
216
|
+
bundle = perform_fhir_search(search_params, [resource_type, "#{search_type}_search"])
|
|
217
|
+
reference_search_result_check(bundle, search_id, search_type)
|
|
218
|
+
elsif include_searches.include?(search_type)
|
|
219
|
+
include_resource_type = search_type.gsub('_include', '')
|
|
220
|
+
bundle = perform_fhir_search({ _id: search_id, _include: "#{resource_type}:#{include_resource_type}" },
|
|
221
|
+
[resource_type, "include_#{include_resource_type}_search"])
|
|
222
|
+
include_search_result_check(bundle, search_id, include_resource_type)
|
|
223
|
+
else
|
|
224
|
+
raise StandardError,
|
|
225
|
+
'Passed in search_type does not match to any of the search types handled by this search test.'
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
skip_if !successful_search,
|
|
230
|
+
'No resources returned in any of the search result bundles.'
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
module DaVinciCRDTestKit
|
|
2
|
+
module V201
|
|
3
|
+
class ClientFHIRApiUpdateTest < Inferno::Test
|
|
4
|
+
id :crd_v201_client_fhir_api_update_test
|
|
5
|
+
title 'Update Interaction'
|
|
6
|
+
description %(
|
|
7
|
+
Verify that the CRD client supports the update interaction for the given resource. The capabilities required by
|
|
8
|
+
each resource can be found here: https://hl7.org/fhir/us/davinci-crd/CapabilityStatement-crd-client.html#resourcesSummary1
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
input :update_resources,
|
|
12
|
+
type: 'textarea',
|
|
13
|
+
description: 'Provide a list of resources to update. e.g., [json_resource_1, json_resource_2]',
|
|
14
|
+
optional: true
|
|
15
|
+
|
|
16
|
+
def resource_type
|
|
17
|
+
config.options[:resource_type]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
run do
|
|
21
|
+
skip_if update_resources.blank?, 'Provide a list of resources to update to run this test.'
|
|
22
|
+
assert_valid_json(update_resources)
|
|
23
|
+
update_resources_list = JSON.parse(update_resources)
|
|
24
|
+
skip_if(!update_resources_list.is_a?(Array), 'Resources to update not inputted in list format, skipping test.')
|
|
25
|
+
|
|
26
|
+
valid_update_resources =
|
|
27
|
+
update_resources_list
|
|
28
|
+
.compact_blank
|
|
29
|
+
.map { |resource| FHIR.from_contents(resource.to_json) }
|
|
30
|
+
.select { |resource| resource.resourceType == resource_type }
|
|
31
|
+
.select { |resource| resource_is_valid?(resource:) }
|
|
32
|
+
|
|
33
|
+
skip_if(valid_update_resources.blank?,
|
|
34
|
+
%(No valid #{resource_type} resources were provided to send in Update requests, skipping test.))
|
|
35
|
+
|
|
36
|
+
valid_update_resources.each do |update_resource|
|
|
37
|
+
fhir_update(update_resource, update_resource.id)
|
|
38
|
+
assert_response_status([200, 201])
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
module DaVinciCRDTestKit
|
|
2
|
+
module V201
|
|
3
|
+
class ClientFHIRApiValidationTest < Inferno::Test
|
|
4
|
+
id :crd_v201_client_fhir_api_validation_test
|
|
5
|
+
title 'FHIR Resource Validation'
|
|
6
|
+
description %(
|
|
7
|
+
Verify that the given resources returned from the previous client API interactions are valid resources. Each
|
|
8
|
+
resource is validated against its corresponding [CRD resource profile](https://hl7.org/fhir/us/davinci-crd/STU2/artifacts.html).
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
def resource_type
|
|
12
|
+
config.options[:resource_type]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def structure_definition_map
|
|
16
|
+
{
|
|
17
|
+
'Practitioner' => 'http://hl7.org/fhir/us/davinci-crd/StructureDefinition/profile-practitioner',
|
|
18
|
+
'PractitionerRole' => 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-practitionerrole',
|
|
19
|
+
'Patient' => 'http://hl7.org/fhir/us/davinci-crd/StructureDefinition/profile-patient',
|
|
20
|
+
'Encounter' => 'http://hl7.org/fhir/us/davinci-crd/StructureDefinition/profile-encounter',
|
|
21
|
+
'Coverage' => 'http://hl7.org/fhir/us/davinci-crd/StructureDefinition/profile-coverage',
|
|
22
|
+
'Device' => 'http://hl7.org/fhir/us/davinci-crd/StructureDefinition/profile-device',
|
|
23
|
+
'Location' => 'http://hl7.org/fhir/us/davinci-crd/StructureDefinition/profile-location',
|
|
24
|
+
'Organization' => 'http://hl7.org/fhir/us/davinci-crd/StructureDefinition/profile-organization'
|
|
25
|
+
}.freeze
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def profile_url
|
|
29
|
+
structure_definition_map[resource_type]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
run do
|
|
33
|
+
load_tagged_requests(resource_type)
|
|
34
|
+
skip_if requests.empty?, 'No FHIR api requests were made'
|
|
35
|
+
|
|
36
|
+
requests.keep_if { |req| req.status == 200 }
|
|
37
|
+
skip_if(requests.blank?,
|
|
38
|
+
'There were no successful FHIR API requests made in previous tests to use in validation.')
|
|
39
|
+
|
|
40
|
+
validated_resources =
|
|
41
|
+
requests
|
|
42
|
+
.map(&:resource)
|
|
43
|
+
.compact
|
|
44
|
+
.flat_map { |resource| resource.is_a?(FHIR::Bundle) ? resource.entry.map(&:resource) : resource }
|
|
45
|
+
.select { |resource| resource.resourceType == resource_type }
|
|
46
|
+
.uniq { |resource| resource.to_reference.reference }
|
|
47
|
+
.map { |resource| resource_is_valid?(resource:, profile_url:) }
|
|
48
|
+
|
|
49
|
+
skip_if(validated_resources.blank?,
|
|
50
|
+
%(No #{resource_type} resources were returned from any of the FHIR API requests made in previous tests
|
|
51
|
+
that could be validated.))
|
|
52
|
+
|
|
53
|
+
validation_error_count = messages.count { |msg| msg[:type] == 'error' }
|
|
54
|
+
invalid_resource_count = validated_resources.reject { |valid| valid }.count
|
|
55
|
+
assert(validation_error_count.zero?,
|
|
56
|
+
%(#{invalid_resource_count}/#{validated_resources.length} #{resource_type} resources returned from
|
|
57
|
+
previous test's FHIR API requests failed validation.))
|
|
58
|
+
|
|
59
|
+
skip_if validated_resources.blank?, 'No FHIR resources were made in previous tests that could be validated.'
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
require_relative '../../client_hook_request_validation'
|
|
2
|
+
|
|
3
|
+
module DaVinciCRDTestKit
|
|
4
|
+
module V201
|
|
5
|
+
class DecodeAuthTokenTest < Inferno::Test
|
|
6
|
+
include ClientHookRequestValidation
|
|
7
|
+
|
|
8
|
+
id :crd_v201_decode_auth_token
|
|
9
|
+
title 'Bearer token can be decoded'
|
|
10
|
+
description %(
|
|
11
|
+
Verify that the Bearer token is a properly constructed JWT. As per the [CDS hooks specification](https://cds-hooks.hl7.org/2.0#trusting-cds-clients),
|
|
12
|
+
each time a CDS client transmits a request to a CDS Service which requires authentication, the request MUST
|
|
13
|
+
include an Authorization header presenting the JWT as a "Bearer" token.
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
verifies_requirements 'cds-hooks_2.0@178'
|
|
17
|
+
|
|
18
|
+
output :auth_tokens, :auth_token_payloads_json, :auth_token_headers_json
|
|
19
|
+
|
|
20
|
+
def hook_name
|
|
21
|
+
config.options[:hook_name]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
run do
|
|
25
|
+
load_tagged_requests(hook_name)
|
|
26
|
+
skip_if requests.empty?, "No #{hook_name} requests were made in a previous test as expected."
|
|
27
|
+
auth_tokens = []
|
|
28
|
+
auth_token_payloads_json = []
|
|
29
|
+
auth_token_headers_json = []
|
|
30
|
+
|
|
31
|
+
requests.each_with_index do |request, index|
|
|
32
|
+
@request_number = index + 1
|
|
33
|
+
|
|
34
|
+
authorization_header = request.request_header('Authorization')&.value
|
|
35
|
+
|
|
36
|
+
unless authorization_header.start_with?('Bearer ')
|
|
37
|
+
add_message('error', "#{request_number}Authorization token must be a JWT presented as a `Bearer` token")
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
auth_token = authorization_header.delete_prefix('Bearer ')
|
|
41
|
+
auth_tokens << auth_token
|
|
42
|
+
|
|
43
|
+
begin
|
|
44
|
+
payload, header =
|
|
45
|
+
JWT.decode(
|
|
46
|
+
auth_token,
|
|
47
|
+
nil,
|
|
48
|
+
false
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
auth_token_payloads_json << payload.to_json
|
|
52
|
+
auth_token_headers_json << header.to_json
|
|
53
|
+
rescue StandardError => e
|
|
54
|
+
add_message('error', "#{request_number}Token is not a properly constructed JWT: #{e.message}")
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
output auth_tokens: auth_tokens.to_json,
|
|
58
|
+
auth_token_payloads_json: auth_token_payloads_json.to_json,
|
|
59
|
+
auth_token_headers_json: auth_token_headers_json.to_json
|
|
60
|
+
|
|
61
|
+
no_error_validation('Decoding Authorization header Bearer tokens failed.')
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
require_relative '../../client_hook_request_validation'
|
|
2
|
+
|
|
3
|
+
module DaVinciCRDTestKit
|
|
4
|
+
module V201
|
|
5
|
+
class RetrieveJWKSTest < Inferno::Test
|
|
6
|
+
include ClientHookRequestValidation
|
|
7
|
+
|
|
8
|
+
id :crd_v201_retrieve_jwks
|
|
9
|
+
title 'JWKS can be retrieved'
|
|
10
|
+
description %(
|
|
11
|
+
Verify that the JWKS can be retrieved from the JWKS uri if it is present in the `jku` field within the JWT token
|
|
12
|
+
header. As per the [CDS hooks specification](https://cds-hooks.hl7.org/2.0#trusting-cds-clients), if the jku
|
|
13
|
+
header field is omitted, the CDS client and CDS service SHALL communicate the JWK Set out-of-band. Therefore,
|
|
14
|
+
if the client does not make their keys publicly available via a uri in the `jku` field, the user must
|
|
15
|
+
submit the jwk_set as an input to the test.
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
verifies_requirements 'cds-hooks_2.0@183', 'cds-hooks_2.0@185', 'cds-hooks_2.0@197', 'cds-hooks_2.0@199'
|
|
19
|
+
|
|
20
|
+
input :auth_token_headers_json
|
|
21
|
+
input :cds_jwk_set,
|
|
22
|
+
title: 'CRD JSON Web Key Set (JWKS)',
|
|
23
|
+
type: 'textarea',
|
|
24
|
+
description: %(
|
|
25
|
+
The client's registered JWK Set containing it's public key, either
|
|
26
|
+
as a publicly accessible url containing the JWKS, or the raw JWKS.
|
|
27
|
+
Run or re-run the **Client Registration** group to set or
|
|
28
|
+
change this value. Used if the `jku` header is not found in the auth token jwt.
|
|
29
|
+
),
|
|
30
|
+
locked: true,
|
|
31
|
+
optional: true
|
|
32
|
+
output :crd_jwks_json, :crd_jwks_keys_json
|
|
33
|
+
|
|
34
|
+
run do
|
|
35
|
+
auth_token_headers = JSON.parse(auth_token_headers_json)
|
|
36
|
+
skip_if auth_token_headers.empty?, 'No Authorization tokens produced from the previous test.'
|
|
37
|
+
|
|
38
|
+
crd_jwks_json = []
|
|
39
|
+
crd_jwks_keys_json = []
|
|
40
|
+
auth_token_headers.each_with_index do |token_header, index|
|
|
41
|
+
@request_number = index + 1
|
|
42
|
+
|
|
43
|
+
jku = JSON.parse(token_header)['jku']
|
|
44
|
+
if jku.present?
|
|
45
|
+
get(jku)
|
|
46
|
+
|
|
47
|
+
if response[:status] != 200
|
|
48
|
+
add_message('error', %(
|
|
49
|
+
#{request_number}Unexpected response status: expected 200, but received
|
|
50
|
+
#{response[:status]}))
|
|
51
|
+
next
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
@request_number = index + 1
|
|
55
|
+
jwks = json_parse(response[:body])
|
|
56
|
+
next if jwks.blank?
|
|
57
|
+
|
|
58
|
+
crd_jwks_json << response[:body]
|
|
59
|
+
|
|
60
|
+
jwks = JSON.parse(response[:body])
|
|
61
|
+
else
|
|
62
|
+
skip_if cds_jwk_set.blank?,
|
|
63
|
+
%(#{request_number}JWK Set must be inputted if the client's JWK Set is not available via a URL
|
|
64
|
+
identified by the jku header field)
|
|
65
|
+
|
|
66
|
+
jwks = JSON.parse(cds_jwk_set)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
keys = jwks['keys']
|
|
70
|
+
unless keys.is_a?(Array)
|
|
71
|
+
add_message('error', "#{request_number}JWKS `keys` field must be an array")
|
|
72
|
+
next
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
if keys.blank?
|
|
76
|
+
add_message('error', "#{request_number}The JWK set returned contains no public keys")
|
|
77
|
+
next
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
keys.each do |jwk|
|
|
81
|
+
JWT::JWK.import(jwk.deep_symbolize_keys)
|
|
82
|
+
rescue StandardError
|
|
83
|
+
add_message('error', "#{request_number}Invalid JWK: #{jwk.to_json}")
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
kid_presence = keys.all? { |key| key['kid'].present? }
|
|
87
|
+
if kid_presence.blank?
|
|
88
|
+
add_message('error',
|
|
89
|
+
"#{request_number}`kid` field must be present in each key if JWKS contains multiple keys")
|
|
90
|
+
next
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
kid_uniqueness = keys.map { |key| key['kid'] }.uniq.length == keys.length
|
|
94
|
+
if kid_uniqueness.blank?
|
|
95
|
+
add_message('error', "#{request_number}`kid` must be unique within the client's JWK Set.")
|
|
96
|
+
next
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
crd_jwks_keys_json << keys.to_json
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
output crd_jwks_json: crd_jwks_json.to_json,
|
|
103
|
+
crd_jwks_keys_json: crd_jwks_keys_json.to_json
|
|
104
|
+
|
|
105
|
+
no_error_validation('Retrieving JWKS failed.')
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
require_relative '../../client_hook_request_validation'
|
|
2
|
+
|
|
3
|
+
module DaVinciCRDTestKit
|
|
4
|
+
module V201
|
|
5
|
+
class TokenHeaderTest < Inferno::Test
|
|
6
|
+
include ClientHookRequestValidation
|
|
7
|
+
|
|
8
|
+
id :crd_v201_token_header
|
|
9
|
+
title 'Authorization token header contains required information'
|
|
10
|
+
description %(
|
|
11
|
+
Verify that the JWT header contains the header fields required by the
|
|
12
|
+
[CDS hooks spec](https://cds-hooks.hl7.org/2.0#trusting-cds-clients).
|
|
13
|
+
The `alg`, `kid`, and `typ` fields are required. This test also verifies that the `typ` field is set to
|
|
14
|
+
`JWT` and that the key used to sign the token can be identified in the JWKS.
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
verifies_requirements 'cds-hooks_2.0@182', 'cds-hooks_2.0@184', 'cds-hooks_2.0@202'
|
|
18
|
+
|
|
19
|
+
input :auth_token_headers_json, :crd_jwks_keys_json
|
|
20
|
+
output :auth_tokens_jwk_json
|
|
21
|
+
|
|
22
|
+
run do
|
|
23
|
+
auth_token_headers = JSON.parse(auth_token_headers_json)
|
|
24
|
+
crd_jwks_keys = JSON.parse(crd_jwks_keys_json)
|
|
25
|
+
skip_if auth_token_headers.empty?, 'No Authorization tokens produced from the previous tests.'
|
|
26
|
+
skip_if crd_jwks_keys.empty?, 'No JWKS keys produced from the previous test.'
|
|
27
|
+
|
|
28
|
+
auth_tokens_jwk_json = []
|
|
29
|
+
auth_token_headers.each_with_index do |token_header, index|
|
|
30
|
+
@request_number = index + 1
|
|
31
|
+
|
|
32
|
+
header = JSON.parse(token_header)
|
|
33
|
+
algorithm = header['alg']
|
|
34
|
+
|
|
35
|
+
add_message('error', "#{request_number}Token header must have the `alg` field") if algorithm.blank?
|
|
36
|
+
|
|
37
|
+
add_message('error', "#{request_number}Token header `alg` field cannot be set to none") if algorithm == 'none'
|
|
38
|
+
|
|
39
|
+
if header['typ'].blank?
|
|
40
|
+
add_message('error', "#{request_number}Token header must have the `typ` field")
|
|
41
|
+
elsif header['typ'] != 'JWT'
|
|
42
|
+
add_message('error', %(
|
|
43
|
+
#{request_number}Token header `typ` field must be set to 'JWT', instead was
|
|
44
|
+
#{header['typ']}))
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
if header['kid'].blank?
|
|
48
|
+
add_message('error', "#{request_number}Token header must have the `kid` field")
|
|
49
|
+
next
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
kid = header['kid']
|
|
53
|
+
keys = JSON.parse(crd_jwks_keys[index])
|
|
54
|
+
|
|
55
|
+
jwk = keys.find { |key| key['kid'] == kid }
|
|
56
|
+
if jwk.blank?
|
|
57
|
+
add_message('error', "#{request_number}JWKS did not contain a public key with an id of `#{kid}`")
|
|
58
|
+
next
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
auth_tokens_jwk_json << jwk.to_json
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
output auth_tokens_jwk_json: auth_tokens_jwk_json.to_json
|
|
65
|
+
|
|
66
|
+
no_error_validation('Token headers missing required information.')
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|