davinci_crd_test_kit 0.14.1 → 0.14.2
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_server_suite.json.erb → client_against_inferno_crd_server_suite.json.erb} +0 -33
- data/config/presets/{ri_crd_request_generator.json.erb → client_against_ri_crd_request_generator.json.erb} +1 -14
- data/config/presets/client_v221_against_inferno_crd_server_suite.json.erb +84 -0
- data/config/presets/client_v221_against_ri_br_provider.json.erb +31 -0
- data/config/presets/{ri_crd_request_generator.json_v221.json.erb → client_v221_against_ri_crd_request_generator.json.erb} +1 -1
- data/config/presets/{inferno_crd_client_suite.json.erb → server_against_inferno_crd_client_suite.json.erb} +0 -43
- data/config/presets/{ri_crd_server.json.erb → server_against_ri_crd_server.json.erb} +1 -44
- data/config/presets/{inferno_crd_client_suite_v221.json.erb → server_v221_against_inferno_crd_client_suite.json.erb} +0 -61
- data/config/presets/{inferno_crd_client_suite_prefetch_subset_v221.json.erb → server_v221_against_inferno_crd_client_suite_prefetch_subset.json.erb} +0 -46
- data/config/presets/server_v221_against_inferno_g31_suite.json.erb +49 -0
- data/lib/davinci_crd_test_kit/client/cross_hook_helper.rb +26 -0
- data/lib/davinci_crd_test_kit/client/endpoints/custom_service_response.rb +7 -7
- data/lib/davinci_crd_test_kit/client/endpoints/gather_response_generation_data.rb +4 -1
- data/lib/davinci_crd_test_kit/client/endpoints/hook_request_endpoint.rb +63 -38
- data/lib/davinci_crd_test_kit/client/endpoints/mock_service_response.rb +26 -7
- data/lib/davinci_crd_test_kit/client/endpoints/scenario_service_response.rb +54 -0
- data/lib/davinci_crd_test_kit/client/tagged_request_load_helper.rb +8 -27
- data/lib/davinci_crd_test_kit/client/v2.0.1/auth/retrieve_jwks_test.rb +35 -23
- data/lib/davinci_crd_test_kit/client/v2.0.1/auth/token_payload_test.rb +34 -21
- data/lib/davinci_crd_test_kit/client/v2.0.1/cds-services-v201.json +20 -20
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_appointment_book_group.rb +12 -10
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_encounter_discharge_group.rb +12 -10
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_encounter_start_group.rb +12 -10
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_hooks_group.rb +5 -5
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_order_dispatch_group.rb +12 -10
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_order_select_group.rb +12 -10
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_order_sign_group.rb +12 -10
- data/lib/davinci_crd_test_kit/client/v2.0.1/must_support/client_card_must_support_coverage_information.rb +3 -36
- data/lib/davinci_crd_test_kit/client/v2.0.1/must_support/client_card_must_support_external_reference.rb +3 -36
- data/lib/davinci_crd_test_kit/client/v2.0.1/must_support/client_card_must_support_instructions.rb +3 -36
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_fetched_data_test.rb +4 -13
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_prefetch_equals_queried_test.rb +3 -13
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_response/client_display_cards_attest.rb +3 -13
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_response/inferno_response_validation.rb +3 -13
- data/lib/davinci_crd_test_kit/client/v2.2.1/api/client_coverage_info_update_test.rb +1 -1
- data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/attestation_instructions.rb +10 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_authorized_scope_attestation_test.rb +45 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_coverage_based_invocation_attestation_test.rb +44 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_data_element_expectations_attestation_test.rb +44 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_hook_invocation_logging_attestation_test.rb +43 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_must_support_exposure_attestation_test.rb +43 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_must_support_use_attestation_test.rb +41 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_order_sign_support_attestation_test.rb +42 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_prefetch_key_omission_attestation_test.rb +42 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_resource_identifiers_attestation_test.rb +43 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_response_case_distinction_attestation_test.rb +43 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_security_and_privacy_attestation_test.rb +43 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_workflow_integration_attestation_test.rb +44 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/auth/decode_auth_token_test.rb +1 -1
- data/lib/davinci_crd_test_kit/client/v2.2.1/auth/retrieve_jwks_test.rb +29 -18
- data/lib/davinci_crd_test_kit/client/v2.2.1/auth/token_payload_test.rb +35 -22
- data/lib/davinci_crd_test_kit/client/v2.2.1/cds-services-prefetch-subset-v221.json +47 -47
- data/lib/davinci_crd_test_kit/client/v2.2.1/cds-services-v221.json +50 -50
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_appointment_book_group.rb +16 -14
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_attestations_group.rb +49 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_cross_hook_group.rb +22 -6
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_cross_hook_interaction_group.rb +98 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_encounter_discharge_group.rb +12 -10
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_encounter_start_group.rb +12 -10
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_fhir_api_group.rb +14 -12
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_hooks_group.rb +9 -9
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_long_running_hook_group.rb +2 -1
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_order_dispatch_group.rb +16 -14
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_order_select_group.rb +12 -10
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_order_sign_group.rb +16 -14
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_scenarios_group.rb +26 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_self_pay_hook_group.rb +36 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_unknown_content_hook_group.rb +34 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/crd_client_suite.rb +19 -3
- data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_card_must_support_coverage_information_test.rb +1 -1
- data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_fhirpath_collection_as_comma_delimited_string_test.rb +4 -11
- data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_hook_instances_unique_test.rb +1 -9
- data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_location_address_propagation_test.rb +6 -2
- data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_prefetch_complete_and_subset_test.rb +3 -12
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/appointment_book_receive_request_test.rb +8 -89
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/base_hook_invocation_receive_request_test.rb +163 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/cross_hooks_receive_request_test.rb +97 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/encounter_discharge_receive_request_test.rb +8 -90
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/encounter_start_receive_request_test.rb +8 -90
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/order_dispatch_receive_request_test.rb +8 -98
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/order_select_receive_request_test.rb +8 -98
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/order_sign_receive_request_test.rb +8 -98
- data/lib/davinci_crd_test_kit/client/v2.2.1/long_running/client_long_running_receive_request_test.rb +10 -2
- data/lib/davinci_crd_test_kit/client/v2.2.1/long_running/client_skip_long_running_attestation_test.rb +1 -1
- data/lib/davinci_crd_test_kit/client/v2.2.1/self_pay/client_self_pay_no_request_test.rb +30 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/self_pay/client_self_pay_workflow_test.rb +55 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/unknown_content/client_unknown_content_attestation_test.rb +99 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/unknown_content/client_unknown_content_receive_request_test.rb +62 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_conformance_test.rb +1 -1
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_coverage_verification_test.rb +10 -2
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_data_fetch_verification_test.rb +1 -1
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_granted_scopes_test.rb +1 -1
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_prefetch_complete_test.rb +1 -1
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_prefetch_profiles_test.rb +1 -1
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_requested_version_test.rb +1 -1
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_secured_transport_test.rb +1 -1
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_response/client_display_cards_attest.rb +52 -20
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_response/hook_response_support_coverage_information_test.rb +1 -1
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_response/inferno_response_validation.rb +6 -3
- data/lib/davinci_crd_test_kit/cross_suite/cards_identification.rb +9 -0
- data/lib/davinci_crd_test_kit/cross_suite/logical_models_override_helper.rb +30 -13
- data/lib/davinci_crd_test_kit/cross_suite/prefetch_profile_validation.rb +2 -0
- data/lib/davinci_crd_test_kit/cross_suite/requests_logical_model_validation.rb +26 -27
- data/lib/davinci_crd_test_kit/cross_suite/response_logical_model_validation.rb +48 -41
- data/lib/davinci_crd_test_kit/cross_suite/tags.rb +3 -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 +6 -2
- data/lib/davinci_crd_test_kit/requirements/generated/crd_client_requirements_coverage.csv +107 -107
- data/lib/davinci_crd_test_kit/requirements/generated/crd_client_v221_requirements_coverage.csv +101 -97
- data/lib/davinci_crd_test_kit/requirements/generated/crd_server_requirements_coverage.csv +18 -18
- data/lib/davinci_crd_test_kit/requirements/generated/crd_server_v221_requirements_coverage.csv +36 -32
- 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/v2.0.1/crd_server_suite.rb +1 -1
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_hooks_group.rb +5 -5
- data/lib/davinci_crd_test_kit/server/v2.2.1/discovery/discovery_standard_prefetch_expressions_test.rb +1 -2
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_demonstrate_hook_response_group.rb +2 -2
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_hooks_group.rb +5 -5
- data/lib/davinci_crd_test_kit/version.rb +2 -2
- metadata +40 -12
- data/config/presets/inferno_crd_server_suite_v221.json.erb +0 -94
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"title": "Run Against the (g)(31) Suite",
|
|
3
|
+
"id": "inferno-crd-server-v221-against-g31-v221",
|
|
4
|
+
"test_suite_id": "crd_server_v221",
|
|
5
|
+
"inputs": [
|
|
6
|
+
{
|
|
7
|
+
"name": "base_url",
|
|
8
|
+
"title": "CRD server base URL",
|
|
9
|
+
"type": "text",
|
|
10
|
+
"value": "<%= Inferno::Application['base_url'] %>/custom/g31_certification/crd_v221"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"name": "authentication_required",
|
|
14
|
+
"title": "Discovery endpoint requires authentication?",
|
|
15
|
+
"type": "radio",
|
|
16
|
+
"value": "no"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"name": "encryption_method",
|
|
20
|
+
"title": "JWT Signing Algorithm",
|
|
21
|
+
"type": "radio",
|
|
22
|
+
"value": "ES384"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"name": "jwks_kid",
|
|
26
|
+
"title": "CDS Services JWKS kid",
|
|
27
|
+
"type": "text",
|
|
28
|
+
"value": ""
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"name": "any_hook_request_body",
|
|
32
|
+
"title": "Request body to use for the \"Demonstrate a Hook Response\" test",
|
|
33
|
+
"type": "textarea",
|
|
34
|
+
"value": "{\n \"hookInstance\": \"d2577c69-dfbe-77ad-ba6d-3e05e953b2ea\",\n \"fhirServer\": \"<%= Inferno::Application['base_url'] %>/custom/crd_server_v221/fhir\",\n \"hook\": \"order-sign\",\n \"fhirAuthorization\": {\n \"access_token\": \"SAMPLE_TOKEN\",\n \"token_type\": \"Bearer\",\n \"expires_in\": 300,\n \"scope\": \"user/AllergyIntolerance.rs user/CarePlan.rs user/CareTeam.rs user/Condition.rs user/Device.rs user/DiagnosticReport.rs user/DocumentReference.rs user/Encounter.rs user/Goal.rs user/Immunization.rs user/Location.rs user/Medication.rs user/MedicationRequest.rs user/Observation.rs user/Organization.rs user/Patient.rs user/Practitioner.rs user/PractitionerRole.rs user/Procedure.rs user/Provenance.rs\",\n \"subject\": \"cds-service4\"\n },\n \"context\": {\n \"userId\": \"Practitioner/crd221-demo-practitioner-orderer\",\n \"patientId\": \"crd221-demo-patient\",\n \"encounterId\": \"crd221-demo-encounter-no-performer\",\n \"draftOrders\": {\n \"resourceType\": \"Bundle\",\n \"type\": \"collection\",\n \"entry\": [\n {\n \"fullUrl\": \"<%= Inferno::Application['base_url'] %>/custom/crd_server_v221/fhir/DeviceRequest/crd221-demo-devicerequest-different-orderer-vs-performer\",\n \"resource\": {\n \"resourceType\": \"DeviceRequest\",\n \"id\": \"crd221-demo-devicerequest-different-orderer-vs-performer\",\n \"identifier\": [\n {\n \"type\": {\n \"coding\": [\n {\n \"system\": \"http://terminology.hl7.org/CodeSystem/v2-0203\",\n \"code\": \"PLAC\"\n }\n ]\n },\n \"value\": \"f105372f-bbef-442c-ad7a-708fee7f8c93\"\n }\n ],\n \"status\": \"draft\",\n \"intent\": \"original-order\",\n \"codeCodeableConcept\": {\n \"coding\": [\n {\n \"system\": \"https://bluebutton.cms.gov/resources/codesystem/hcpcs\",\n \"code\": \"E0250\",\n \"display\": \"Hospital bed fixed height with any type of side rails, mattress\"\n }\n ]\n },\n \"authoredOn\": \"2026-05-14\",\n \"subject\": {\n \"reference\": \"Patient/crd221-demo-patient\"\n },\n \"requester\": {\n \"reference\": \"Practitioner/crd221-demo-practitioner-orderer\"\n },\n \"performer\": {\n \"reference\": \"Practitioner/crd221-demo-practitioner-performer\"\n }\n }\n }\n ]\n }\n },\n \"extension\": {\n \"davinci-crd.configuration\": {\n \"alt-drug\": true\n },\n \"davinci-crd.requestedVersion\": \"2.2\"\n },\n \"prefetch\": {\n \"patient\": {\n \"resourceType\": \"Patient\",\n \"id\": \"crd221-demo-patient\",\n \"gender\": \"male\",\n \"birthDate\": \"2015-02-23\",\n \"address\": [\n {\n \"use\": \"home\",\n \"type\": \"both\",\n \"state\": \"NY\",\n \"city\": \"Buffalo\",\n \"postalCode\": \"14210\",\n \"line\": [\n \"202 Burlington Road\"\n ]\n }\n ],\n \"name\": [\n {\n \"use\": \"official\",\n \"family\": \"Oster\",\n \"given\": [\n \"William\",\n \"Hale\",\n \"Oster\"\n ]\n }\n ],\n \"telecom\": [\n {\n \"system\": \"phone\",\n \"value\": \"(781) 555-5555\",\n \"use\": \"home\",\n \"rank\": 1\n },\n {\n \"system\": \"phone\",\n \"value\": \"(781) 555 5613\",\n \"use\": \"work\",\n \"rank\": 2\n },\n {\n \"system\": \"phone\",\n \"value\": \"(781) 555 8834\",\n \"use\": \"old\",\n \"period\": {\n \"end\": \"2014\"\n }\n }\n ],\n \"identifier\": [\n {\n \"use\": \"usual\",\n \"type\": {\n \"coding\": [\n {\n \"system\": \"http://terminology.hl7.org/CodeSystem/v2-0203\",\n \"code\": \"MR\"\n }\n ],\n \"text\": \"Medical Record Number\"\n },\n \"system\": \"http://hl7.org/fhir/sid/us-medicare\",\n \"value\": \"0M34355006FW\"\n }\n ]\n },\n \"encounter\": {\n \"resourceType\": \"Encounter\",\n \"id\": \"crd221-demo-encounter-no-performer\",\n \"status\": \"in-progress\",\n \"class\": {\n \"system\": \"http://terminology.hl7.org/CodeSystem/v3-ActCode\",\n \"code\": \"AMB\",\n \"display\": \"ambulatory\"\n },\n \"type\": [\n {\n \"coding\": [\n {\n \"system\": \"http://www.ama-assn.org/go/cpt\",\n \"code\": \"99211\"\n }\n ],\n \"text\": \"Office Visit\"\n }\n ],\n \"subject\": {\n \"reference\": \"Patient/crd221-demo-patient\"\n }\n },\n \"coverage\": {\n \"resourceType\": \"Bundle\",\n \"type\": \"searchset\",\n \"total\": 1,\n \"link\": [\n {\n \"relation\": \"self\",\n \"url\": \"<%= Inferno::Application['base_url'] %>/custom/crd_server_v221/fhir/Coverage?patient=crd221-demo-patient\"\n }\n ],\n \"entry\": [\n {\n \"fullUrl\": \"<%= Inferno::Application['base_url'] %>/custom/crd_server_v221/fhir/Coverage/crd221-demo-coverage-complete-prefetch\",\n \"resource\": {\n \"resourceType\": \"Coverage\",\n \"id\": \"crd221-demo-coverage-complete-prefetch\",\n \"subscriberId\": \"10A3D58WH456\",\n \"relationship\": {\n \"coding\": [\n {\n \"system\": \"http://terminology.hl7.org/CodeSystem/subscriber-relationship\",\n \"code\": \"self\"\n }\n ]\n },\n \"beneficiary\": {\n \"reference\": \"Patient/crd221-demo-patient\"\n },\n \"status\": \"active\",\n \"class\": [\n {\n \"type\": {\n \"coding\": [\n {\n \"system\": \"http://terminology.hl7.org/CodeSystem/coverage-class\",\n \"code\": \"plan\"\n }\n ]\n },\n \"value\": \"Medicare Part A\"\n }\n ],\n \"payor\": [\n {\n \"reference\": \"Organization/crd221-demo-payer-complete-prefetch\"\n }\n ]\n },\n \"search\": {\n \"mode\": \"match\"\n }\n }\n ]\n },\n \"devices\": null,\n \"medications\": null,\n \"practitionerRoles\": null,\n \"organizations\": null,\n \"practitioners\": {\n \"resourceType\": \"Bundle\",\n \"type\": \"collection\",\n \"entry\": [\n {\n \"fullUrl\": \"<%= Inferno::Application['base_url'] %>/custom/crd_server_v221/fhir/Practitioner/crd221-demo-practitioner-orderer\",\n \"resource\": {\n \"resourceType\": \"Practitioner\",\n \"id\": \"crd221-demo-practitioner-orderer\",\n \"meta\": {\n \"profile\": [\n \"http://hl7.org/fhir/us/core/StructureDefinition/us-core-practitioner\"\n ]\n },\n \"identifier\": [\n {\n \"system\": \"http://hl7.org/fhir/sid/us-npi\",\n \"value\": \"1122334455\"\n }\n ],\n \"address\": [\n {\n \"use\": \"home\",\n \"type\": \"both\",\n \"state\": \"NY\",\n \"city\": \"Buffalo\",\n \"postalCode\": \"14210\",\n \"line\": [\n \"840 Seneca St\"\n ]\n }\n ],\n \"telecom\": [\n {\n \"system\": \"phone\",\n \"value\": \"716-873-1557\"\n },\n {\n \"system\": \"email\",\n \"value\": \"jane.betty@myhospital.com\"\n }\n ],\n \"name\": [\n {\n \"use\": \"official\",\n \"family\": \"Doe\",\n \"given\": [\n \"Jane\",\n \"Betty\"\n ],\n \"prefix\": [\n \"Dr.\"\n ]\n }\n ],\n \"qualification\": [\n {\n \"code\": {\n \"coding\": [\n {\n \"system\": \"http://terminology.hl7.org/CodeSystem/v2-0360\",\n \"code\": \"MD\",\n \"display\": \"Doctor of Medicine\"\n }\n ],\n \"text\": \"Doctor of Medicine\"\n },\n \"period\": {\n \"start\": \"1995\"\n },\n \"issuer\": {\n \"display\": \"Example University\"\n }\n }\n ]\n }\n },\n {\n \"fullUrl\": \"<%= Inferno::Application['base_url'] %>/custom/crd_server_v221/fhir/Practitioner/crd221-demo-practitioner-performer\",\n \"resource\": {\n \"resourceType\": \"Practitioner\",\n \"id\": \"crd221-demo-practitioner-performer\",\n \"meta\": {\n \"profile\": [\n \"http://hl7.org/fhir/us/core/StructureDefinition/us-core-practitioner\"\n ]\n },\n \"identifier\": [\n {\n \"system\": \"http://hl7.org/fhir/sid/us-npi\",\n \"value\": \"1122334455\"\n }\n ],\n \"name\": [\n {\n \"use\": \"official\",\n \"family\": \"Doe\",\n \"given\": [\n \"Bob\"\n ],\n \"prefix\": [\n \"Dr.\"\n ]\n }\n ],\n \"qualification\": [\n {\n \"code\": {\n \"coding\": [\n {\n \"system\": \"http://terminology.hl7.org/CodeSystem/v2-0360\",\n \"code\": \"MD\",\n \"display\": \"Doctor of Medicine\"\n }\n ],\n \"text\": \"Doctor of Medicine\"\n },\n \"period\": {\n \"start\": \"1995\"\n },\n \"issuer\": {\n \"display\": \"Example University\"\n }\n }\n ]\n }\n }\n ]\n },\n \"locations\": null\n }\n }"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"name": "order_sign_request_bodies",
|
|
38
|
+
"title": "Request body or bodies for invoking the `order-sign` hook",
|
|
39
|
+
"type": "textarea",
|
|
40
|
+
"value": "[\n {\n \"hookInstance\": \"d1577c69-dfbe-77ad-ba6d-3e05e953b2ea\",\n \"fhirServer\": \"<%= Inferno::Application['base_url'] %>/custom/crd_server_v221/fhir\",\n \"hook\": \"order-sign\",\n \"fhirAuthorization\": {\n \"access_token\": \"SAMPLE_TOKEN\",\n \"token_type\": \"Bearer\",\n \"expires_in\": 300,\n \"scope\": \"user/AllergyIntolerance.rs user/CarePlan.rs user/CareTeam.rs user/Condition.rs user/Device.rs user/DiagnosticReport.rs user/DocumentReference.rs user/Encounter.rs user/Goal.rs user/Immunization.rs user/Location.rs user/Medication.rs user/MedicationRequest.rs user/Observation.rs user/Organization.rs user/Patient.rs user/Practitioner.rs user/PractitionerRole.rs user/Procedure.rs user/Provenance.rs\",\n \"subject\": \"cds-service4\"\n },\n \"context\": {\n \"userId\": \"Practitioner/crd221-demo-practitioner-orderer\",\n \"patientId\": \"crd221-demo-patient\",\n \"encounterId\": \"crd221-demo-encounter-no-performer\",\n \"draftOrders\": {\n \"resourceType\": \"Bundle\",\n \"type\": \"collection\",\n \"entry\": [\n {\n \"fullUrl\": \"<%= Inferno::Application['base_url'] %>/custom/crd_server_v221/fhir/DeviceRequest/crd221-demo-devicerequest-different-orderer-vs-performer\",\n \"resource\": {\n \"resourceType\": \"DeviceRequest\",\n \"id\": \"crd221-demo-devicerequest-different-orderer-vs-performer\",\n \"identifier\": [\n {\n \"type\": {\n \"coding\": [\n {\n \"system\": \"http://terminology.hl7.org/CodeSystem/v2-0203\",\n \"code\": \"PLAC\"\n }\n ]\n },\n \"value\": \"f105372f-bbef-442c-ad7a-708fee7f8c93\"\n }\n ],\n \"status\": \"draft\",\n \"intent\": \"original-order\",\n \"codeCodeableConcept\": {\n \"coding\": [\n {\n \"system\": \"https://bluebutton.cms.gov/resources/codesystem/hcpcs\",\n \"code\": \"E0250\",\n \"display\": \"Hospital bed fixed height with any type of side rails, mattress\"\n }\n ]\n },\n \"subject\": {\n \"reference\": \"Patient/crd221-demo-patient\"\n },\n \"authoredOn\": \"2023-01-01T00:00:00Z\",\n \"requester\": {\n \"reference\": \"Practitioner/crd221-demo-practitioner-orderer\"\n },\n \"performer\": {\n \"reference\": \"Practitioner/crd221-demo-practitioner-performer\"\n }\n }\n }\n ]\n }\n },\n \"extension\": {\n \"davinci-crd.configuration\": {\n \"alt-drug\": true\n },\n \"davinci-crd.requestedVersion\": \"2.2\"\n },\n \"prefetch\": {\n \"patient\": {\n \"resourceType\": \"Patient\",\n \"id\": \"crd221-demo-patient\",\n \"gender\": \"male\",\n \"birthDate\": \"2015-02-23\",\n \"address\": [\n {\n \"use\": \"home\",\n \"type\": \"both\",\n \"state\": \"NY\",\n \"city\": \"Buffalo\",\n \"postalCode\": \"14210\",\n \"line\": [\n \"202 Burlington Road\"\n ]\n }\n ],\n \"name\": [\n {\n \"use\": \"official\",\n \"family\": \"Oster\",\n \"given\": [\n \"William\",\n \"Hale\",\n \"Oster\"\n ]\n }\n ],\n \"telecom\": [\n {\n \"system\": \"phone\",\n \"value\": \"(781) 555-5555\",\n \"use\": \"home\",\n \"rank\": 1\n },\n {\n \"system\": \"phone\",\n \"value\": \"(781) 555 5613\",\n \"use\": \"work\",\n \"rank\": 2\n },\n {\n \"system\": \"phone\",\n \"value\": \"(781) 555 8834\",\n \"use\": \"old\",\n \"period\": {\n \"end\": \"2014\"\n }\n }\n ],\n \"identifier\": [\n {\n \"use\": \"usual\",\n \"type\": {\n \"coding\": [\n {\n \"system\": \"http://terminology.hl7.org/CodeSystem/v2-0203\",\n \"code\": \"MR\"\n }\n ],\n \"text\": \"Medical Record Number\"\n },\n \"system\": \"http://hl7.org/fhir/sid/us-medicare\",\n \"value\": \"0M34355006FW\"\n }\n ]\n },\n \"encounter\": {\n \"resourceType\": \"Encounter\",\n \"id\": \"crd221-demo-encounter-no-performer\",\n \"status\": \"in-progress\",\n \"class\": {\n \"system\": \"http://terminology.hl7.org/CodeSystem/v3-ActCode\",\n \"code\": \"AMB\",\n \"display\": \"ambulatory\"\n },\n \"type\": [\n {\n \"coding\": [\n {\n \"system\": \"http://www.ama-assn.org/go/cpt\",\n \"code\": \"99211\"\n }\n ],\n \"text\": \"Office Visit\"\n }\n ],\n \"subject\": {\n \"reference\": \"Patient/crd221-demo-patient\"\n }\n },\n \"coverage\": {\n \"resourceType\": \"Bundle\",\n \"type\": \"searchset\",\n \"total\": 1,\n \"link\": [\n {\n \"relation\": \"self\",\n \"url\": \"<%= Inferno::Application['base_url'] %>/custom/crd_server_v221/fhir/Coverage?patient=crd221-demo-patient\"\n }\n ],\n \"entry\": [\n {\n \"fullUrl\": \"<%= Inferno::Application['base_url'] %>/custom/crd_server_v221/fhir/Coverage/crd221-demo-coverage-complete-prefetch\",\n \"resource\": {\n \"resourceType\": \"Coverage\",\n \"id\": \"crd221-demo-coverage-complete-prefetch\",\n \"subscriberId\": \"10A3D58WH456\",\n \"relationship\": {\n \"coding\": [\n {\n \"system\": \"http://terminology.hl7.org/CodeSystem/subscriber-relationship\",\n \"code\": \"self\"\n }\n ]\n },\n \"beneficiary\": {\n \"reference\": \"Patient/crd221-demo-patient\"\n },\n \"status\": \"active\",\n \"class\": [\n {\n \"type\": {\n \"coding\": [\n {\n \"system\": \"http://terminology.hl7.org/CodeSystem/coverage-class\",\n \"code\": \"plan\"\n }\n ]\n },\n \"value\": \"Medicare Part A\"\n }\n ],\n \"payor\": [\n {\n \"reference\": \"Organization/crd221-demo-payer-complete-prefetch\"\n }\n ]\n },\n \"search\": {\n \"mode\": \"match\"\n }\n }\n ]\n },\n \"devices\": null,\n \"medications\": null,\n \"practitionerRoles\": null,\n \"organizations\": null,\n \"practitioners\": {\n \"resourceType\": \"Bundle\",\n \"type\": \"collection\",\n \"entry\": [\n {\n \"fullUrl\": \"<%= Inferno::Application['base_url'] %>/custom/crd_server_v221/fhir/Practitioner/crd221-demo-practitioner-orderer\",\n \"resource\": {\n \"resourceType\": \"Practitioner\",\n \"id\": \"crd221-demo-practitioner-orderer\",\n \"meta\": {\n \"profile\": [\n \"http://hl7.org/fhir/us/core/StructureDefinition/us-core-practitioner\"\n ]\n },\n \"identifier\": [\n {\n \"system\": \"http://hl7.org/fhir/sid/us-npi\",\n \"value\": \"1122334455\"\n }\n ],\n \"address\": [\n {\n \"use\": \"home\",\n \"type\": \"both\",\n \"state\": \"NY\",\n \"city\": \"Buffalo\",\n \"postalCode\": \"14210\",\n \"line\": [\n \"840 Seneca St\"\n ]\n }\n ],\n \"telecom\": [\n {\n \"system\": \"phone\",\n \"value\": \"716-873-1557\"\n },\n {\n \"system\": \"email\",\n \"value\": \"jane.betty@myhospital.com\"\n }\n ],\n \"name\": [\n {\n \"use\": \"official\",\n \"family\": \"Doe\",\n \"given\": [\n \"Jane\",\n \"Betty\"\n ],\n \"prefix\": [\n \"Dr.\"\n ]\n }\n ],\n \"qualification\": [\n {\n \"code\": {\n \"coding\": [\n {\n \"system\": \"http://terminology.hl7.org/CodeSystem/v2-0360\",\n \"code\": \"MD\",\n \"display\": \"Doctor of Medicine\"\n }\n ],\n \"text\": \"Doctor of Medicine\"\n },\n \"period\": {\n \"start\": \"1995\"\n },\n \"issuer\": {\n \"display\": \"Example University\"\n }\n }\n ]\n }\n },\n {\n \"fullUrl\": \"<%= Inferno::Application['base_url'] %>/custom/crd_server_v221/fhir/Practitioner/crd221-demo-practitioner-performer\",\n \"resource\": {\n \"resourceType\": \"Practitioner\",\n \"id\": \"crd221-demo-practitioner-performer\",\n \"meta\": {\n \"profile\": [\n \"http://hl7.org/fhir/us/core/StructureDefinition/us-core-practitioner\"\n ]\n },\n \"identifier\": [\n {\n \"system\": \"http://hl7.org/fhir/sid/us-npi\",\n \"value\": \"1122334455\"\n }\n ],\n \"name\": [\n {\n \"use\": \"official\",\n \"family\": \"Doe\",\n \"given\": [\n \"Bob\"\n ],\n \"prefix\": [\n \"Dr.\"\n ]\n }\n ],\n \"qualification\": [\n {\n \"code\": {\n \"coding\": [\n {\n \"system\": \"http://terminology.hl7.org/CodeSystem/v2-0360\",\n \"code\": \"MD\",\n \"display\": \"Doctor of Medicine\"\n }\n ],\n \"text\": \"Doctor of Medicine\"\n },\n \"period\": {\n \"start\": \"1995\"\n },\n \"issuer\": {\n \"display\": \"Example University\"\n }\n }\n ]\n }\n }\n ]\n },\n \"locations\": null\n }\n },\n {\n \"hookInstance\": \"d1577c69-dfbe-77a1-ba6d-3e05e953b2ea\",\n \"fhirServer\": \"<%= Inferno::Application['base_url'] %>/custom/crd_server_v221/fhir\",\n \"hook\": \"order-sign\",\n \"fhirAuthorization\": {\n \"access_token\": \"SAMPLE_TOKEN\",\n \"token_type\": \"Bearer\",\n \"expires_in\": 300,\n \"scope\": \"user/AllergyIntolerance.rs user/CarePlan.rs user/CareTeam.rs user/Condition.rs user/Device.rs user/DiagnosticReport.rs user/DocumentReference.rs user/Encounter.rs user/Goal.rs user/Immunization.rs user/Location.rs user/Medication.rs user/MedicationRequest.rs user/Observation.rs user/Organization.rs user/Patient.rs user/Practitioner.rs user/PractitionerRole.rs user/Procedure.rs user/Provenance.rs\",\n \"subject\": \"cds-service4\"\n },\n \"context\": {\n \"userId\": \"Practitioner/crd221-demo-practitioner-orderer\",\n \"patientId\": \"crd221-demo-patient\",\n \"encounterId\": \"crd221-demo-encounter-no-performer\",\n \"draftOrders\": {\n \"resourceType\": \"Bundle\",\n \"type\": \"collection\",\n \"entry\": [\n {\n \"fullUrl\": \"<%= Inferno::Application['base_url'] %>/custom/crd_server_v221/fhir/ServiceRequest/crd221-demo-servicerequest-no-orderer\",\n \"resource\": {\n \"resourceType\": \"ServiceRequest\",\n \"id\": \"crd221-demo-servicerequest-no-orderer\",\n \"identifier\": [\n {\n \"type\": {\n \"coding\": [\n {\n \"system\": \"http://terminology.hl7.org/CodeSystem/v2-0203\",\n \"code\": \"PLAC\"\n }\n ]\n },\n \"value\": \"11ddab7e-1488-4848-b3d5-512d2f1e3f28\"\n }\n ],\n \"status\": \"draft\",\n \"intent\": \"order\",\n \"code\": {\n \"coding\": [\n {\n \"system\": \"https://bluebutton.cms.gov/resources/codesystem/hcpcs\",\n \"code\": \"G0180\",\n \"display\": \"Medicare-covered home health services under a home health plan of care\"\n }\n ]\n },\n \"subject\": {\n \"reference\": \"Patient/crd221-demo-patient\"\n },\n \"authoredOn\": \"2017-10-04\",\n \"requester\": {\n \"display\": \"Smythe Juliette, MD\"\n },\n \"performer\": [\n {\n \"reference\": \"Practitioner/crd221-demo-practitioner-performer\"\n }\n ]\n }\n },\n {\n \"fullUrl\": \"<%= Inferno::Application['base_url'] %>/custom/crd_server_v221/fhir/CommunicationRequest/crd221-demo-communicationrequest\",\n \"resource\": {\n \"resourceType\": \"CommunicationRequest\",\n \"id\": \"crd221-demo-communicationrequest\",\n \"status\": \"draft\",\n \"basedOn\" : [\n {\n \"display\" : \"EligibilityRequest\"\n }\n ],\n \"subject\": {\n \"reference\": \"Patient/crd221-demo-patient\"\n },\n \"payload\": [\n {\n \"extension\": [\n {\n \"url\": \"http://hl7.org/fhir/5.0/StructureDefinition/extension-CommunicationRequest.payload.content\",\n \"valueCodeableConcept\": {\n \"coding\": [\n {\n \"system\": \"http://loinc.org\",\n \"code\": \"65752-8\",\n \"display\": \"Liver Pathology biopsy report\"\n }\n ]\n }\n }\n ],\n \"contentString\": \"Liver pathology biopsy report\"\n }\n ],\n \"authoredOn\": \"2017-10-04\",\n \"requester\": {\n \"reference\": \"Practitioner/crd221-demo-practitioner-orderer\"\n }\n }\n }\n ]\n }\n },\n \"extension\": {\n \"davinci-crd.configuration\": {\n \"alt-drug\": true,\n \"coverage\": true,\n \"dtr-clin\": true,\n \"max-cards\": 10\n },\n \"davinci-crd.requestedVersion\": \"2.2\"\n },\n \"prefetch\": {\n \"patient\": {\n \"resourceType\": \"Patient\",\n \"id\": \"crd221-demo-patient\",\n \"gender\": \"male\",\n \"birthDate\": \"2015-02-23\",\n \"address\": [\n {\n \"use\": \"home\",\n \"type\": \"both\",\n \"state\": \"NY\",\n \"city\": \"Buffalo\",\n \"postalCode\": \"14210\",\n \"line\": [\n \"202 Burlington Road\"\n ]\n }\n ],\n \"name\": [\n {\n \"use\": \"official\",\n \"family\": \"Oster\",\n \"given\": [\n \"William\",\n \"Hale\",\n \"Oster\"\n ]\n }\n ],\n \"telecom\": [\n {\n \"system\": \"phone\",\n \"value\": \"(781) 555-5555\",\n \"use\": \"home\",\n \"rank\": 1\n },\n {\n \"system\": \"phone\",\n \"value\": \"(781) 555 5613\",\n \"use\": \"work\",\n \"rank\": 2\n },\n {\n \"system\": \"phone\",\n \"value\": \"(781) 555 8834\",\n \"use\": \"old\",\n \"period\": {\n \"end\": \"2014\"\n }\n }\n ],\n \"identifier\": [\n {\n \"use\": \"usual\",\n \"type\": {\n \"coding\": [\n {\n \"system\": \"http://terminology.hl7.org/CodeSystem/v2-0203\",\n \"code\": \"MR\"\n }\n ],\n \"text\": \"Medical Record Number\"\n },\n \"system\": \"http://hl7.org/fhir/sid/us-medicare\",\n \"value\": \"0M34355006FW\"\n }\n ]\n },\n \"encounter\": {\n \"resourceType\": \"Encounter\",\n \"id\": \"crd221-demo-encounter-no-performer\",\n \"status\": \"in-progress\",\n \"class\": {\n \"system\": \"http://terminology.hl7.org/CodeSystem/v3-ActCode\",\n \"code\": \"AMB\",\n \"display\": \"ambulatory\"\n },\n \"type\": [\n {\n \"coding\": [\n {\n \"system\": \"http://www.ama-assn.org/go/cpt\",\n \"code\": \"99211\"\n }\n ],\n \"text\": \"Office Visit\"\n }\n ],\n \"subject\": {\n \"reference\": \"Patient/crd221-demo-patient\"\n }\n },\n \"coverage\": {\n \"resourceType\": \"Bundle\",\n \"type\": \"searchset\",\n \"total\": 1,\n \"link\": [\n {\n \"relation\": \"self\",\n \"url\": \"<%= Inferno::Application['base_url'] %>/custom/crd_server_v221/fhir/Coverage?patient=crd221-demo-patient\"\n }\n ],\n \"entry\": [\n {\n \"fullUrl\": \"<%= Inferno::Application['base_url'] %>/custom/crd_server_v221/fhir/Coverage/crd221-demo-coverage-complete-prefetch\",\n \"resource\": {\n \"resourceType\": \"Coverage\",\n \"id\": \"crd221-demo-coverage-complete-prefetch\",\n \"subscriberId\": \"10A3D58WH456\",\n \"relationship\": {\n \"coding\": [\n {\n \"system\": \"http://terminology.hl7.org/CodeSystem/subscriber-relationship\",\n \"code\": \"self\"\n }\n ]\n },\n \"beneficiary\": {\n \"reference\": \"Patient/crd221-demo-patient\"\n },\n \"status\": \"active\",\n \"class\": [\n {\n \"type\": {\n \"coding\": [\n {\n \"system\": \"http://terminology.hl7.org/CodeSystem/coverage-class\",\n \"code\": \"plan\"\n }\n ]\n },\n \"value\": \"Medicare Part A\"\n }\n ],\n \"payor\": [\n {\n \"reference\": \"Organization/crd221-demo-payer-complete-prefetch\"\n }\n ]\n },\n \"search\": {\n \"mode\": \"match\"\n }\n }\n ]\n },\n \"devices\": null,\n \"medications\": null,\n \"practitionerRoles\": null,\n \"organizations\": null,\n \"practitioners\": {\n \"resourceType\": \"Bundle\",\n \"type\": \"collection\",\n \"entry\": [\n {\n \"fullUrl\": \"<%= Inferno::Application['base_url'] %>/custom/crd_server_v221/fhir/Practitioner/crd221-demo-practitioner-orderer\",\n \"resource\": {\n \"resourceType\": \"Practitioner\",\n \"id\": \"crd221-demo-practitioner-orderer\",\n \"meta\": {\n \"profile\": [\n \"http://hl7.org/fhir/us/core/StructureDefinition/us-core-practitioner\"\n ]\n },\n \"identifier\": [\n {\n \"system\": \"http://hl7.org/fhir/sid/us-npi\",\n \"value\": \"1122334455\"\n }\n ],\n \"address\": [\n {\n \"use\": \"home\",\n \"type\": \"both\",\n \"state\": \"NY\",\n \"city\": \"Buffalo\",\n \"postalCode\": \"14210\",\n \"line\": [\n \"840 Seneca St\"\n ]\n }\n ],\n \"telecom\": [\n {\n \"system\": \"phone\",\n \"value\": \"716-873-1557\"\n },\n {\n \"system\": \"email\",\n \"value\": \"jane.betty@myhospital.com\"\n }\n ],\n \"name\": [\n {\n \"use\": \"official\",\n \"family\": \"Doe\",\n \"given\": [\n \"Jane\",\n \"Betty\"\n ],\n \"prefix\": [\n \"Dr.\"\n ]\n }\n ],\n \"qualification\": [\n {\n \"code\": {\n \"coding\": [\n {\n \"system\": \"http://terminology.hl7.org/CodeSystem/v2-0360\",\n \"code\": \"MD\",\n \"display\": \"Doctor of Medicine\"\n }\n ],\n \"text\": \"Doctor of Medicine\"\n },\n \"period\": {\n \"start\": \"1995\"\n },\n \"issuer\": {\n \"display\": \"Example University\"\n }\n }\n ]\n }\n },\n {\n \"fullUrl\": \"<%= Inferno::Application['base_url'] %>/custom/crd_server_v221/fhir/Practitioner/crd221-demo-practitioner-performer\",\n \"resource\": {\n \"resourceType\": \"Practitioner\",\n \"id\": \"crd221-demo-practitioner-performer\",\n \"meta\": {\n \"profile\": [\n \"http://hl7.org/fhir/us/core/StructureDefinition/us-core-practitioner\"\n ]\n },\n \"identifier\": [\n {\n \"system\": \"http://hl7.org/fhir/sid/us-npi\",\n \"value\": \"1122334455\"\n }\n ],\n \"name\": [\n {\n \"use\": \"official\",\n \"family\": \"Doe\",\n \"given\": [\n \"Bob\"\n ],\n \"prefix\": [\n \"Dr.\"\n ]\n }\n ],\n \"qualification\": [\n {\n \"code\": {\n \"coding\": [\n {\n \"system\": \"http://terminology.hl7.org/CodeSystem/v2-0360\",\n \"code\": \"MD\",\n \"display\": \"Doctor of Medicine\"\n }\n ],\n \"text\": \"Doctor of Medicine\"\n },\n \"period\": {\n \"start\": \"1995\"\n },\n \"issuer\": {\n \"display\": \"Example University\"\n }\n }\n ]\n }\n }\n ]\n },\n \"locations\": null\n }\n }\n]"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"name": "mock_ehr_bundle",
|
|
44
|
+
"title": "Mock EHR Data",
|
|
45
|
+
"type": "textarea",
|
|
46
|
+
"value": "{\n \"resourceType\": \"Bundle\",\n \"type\": \"collection\",\n \"entry\": [\n {\n \"resource\": {\n \"resourceType\": \"Organization\",\n \"id\": \"crd221-demo-payer-complete-prefetch\",\n \"identifier\": [\n {\n \"system\": \"http://hl7.org/fhir/sid/us-npi\",\n \"value\": \"1234567893\"\n }\n ],\n \"active\": true,\n \"name\": \"Inferno Simulated Payer (complete standard prefetch)\"\n }\n },\n {\n \"fullUrl\": \"<%= Inferno::Application['base_url'] %>/custom/crd_server_v221/fhir/Location/crd221-demo-location-building\",\n \"resource\": {\n \"resourceType\": \"Location\",\n \"id\": \"crd221-demo-location-building\",\n \"status\": \"active\",\n \"name\": \"Building A\",\n \"address\": {\n \"use\": \"work\",\n \"line\": [\n \"Galapagosweg 91, Building A\"\n ],\n \"city\": \"San Francisco\",\n \"state\": \"CA\",\n \"postalCode\": \"94107\",\n \"country\": \"US\"\n },\n \"physicalType\": {\n \"coding\": [\n {\n \"system\": \"http://terminology.hl7.org/CodeSystem/location-physical-type\",\n \"code\": \"bu\",\n \"display\": \"Building\"\n }\n ]\n },\n \"managingOrganization\": {\n \"reference\": \"Organization/crd221-demo-org-performer\"\n }\n }\n }\n ]\n}"
|
|
47
|
+
}
|
|
48
|
+
]
|
|
49
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module DaVinciCRDTestKit
|
|
2
|
+
module CrossHookHelper
|
|
3
|
+
def find_completeness_tests # rubocop:disable Metrics/CyclomaticComplexity
|
|
4
|
+
# minimal error checking - want it to bomb if this search logic fails
|
|
5
|
+
hooks_group = self.class.parent.parent.parent.groups.find do |group|
|
|
6
|
+
group.id.to_s.include?('crd_v221_client_hooks')
|
|
7
|
+
end
|
|
8
|
+
completeness_tests = hooks_group.groups.map do |group|
|
|
9
|
+
group.groups.flat_map(&:tests).find do |test|
|
|
10
|
+
test.id.to_s.include?('crd_v221_hook_request_prefetch_complete')
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
cross_hooks_interaction_group = self.class.parent.parent.groups.find do |group|
|
|
15
|
+
group.id.to_s.include?('crd_v221_client_cross_hook_interaction')
|
|
16
|
+
end
|
|
17
|
+
cross_hooks_completeness_test =
|
|
18
|
+
cross_hooks_interaction_group.groups.flat_map(&:tests).find do |test|
|
|
19
|
+
test.id.to_s.include?('crd_v221_hook_request_prefetch_complete')
|
|
20
|
+
end
|
|
21
|
+
completeness_tests << cross_hooks_completeness_test
|
|
22
|
+
|
|
23
|
+
completeness_tests.compact
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -18,17 +18,17 @@ module DaVinciCRDTestKit
|
|
|
18
18
|
|
|
19
19
|
def parsed_user_input
|
|
20
20
|
if custom_response_template.blank?
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
hook_error_response('No custom template provided for custom Inferno CRD response',
|
|
22
|
+
code: 500,
|
|
23
|
+
outcome_code: 'processing')
|
|
24
24
|
nil
|
|
25
25
|
else
|
|
26
26
|
JSON.parse(custom_response_template)
|
|
27
27
|
end
|
|
28
28
|
rescue JSON::ParserError
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
hook_error_response('Invalid template provided for custom Inferno CRD response: invalid JSON',
|
|
30
|
+
code: 500,
|
|
31
|
+
outcome_code: 'processing')
|
|
32
32
|
nil
|
|
33
33
|
end
|
|
34
34
|
|
|
@@ -45,7 +45,7 @@ module DaVinciCRDTestKit
|
|
|
45
45
|
|
|
46
46
|
hook_response
|
|
47
47
|
rescue FhirpathServiceError => e
|
|
48
|
-
|
|
48
|
+
hook_error_response(
|
|
49
49
|
'FHIRPath service error while generating custom response. ' \
|
|
50
50
|
'Check the FHIRPath expressions and data in your response template and hook request. ' \
|
|
51
51
|
"Details: #{e.message}",
|
|
@@ -258,7 +258,10 @@ module DaVinciCRDTestKit
|
|
|
258
258
|
request_body['fhirAuthorization'].present? &&
|
|
259
259
|
request_body['fhirAuthorization']['access_token'].present?
|
|
260
260
|
Faraday.new(url: request_body['fhirServer'], request: { open_timeout: 10 },
|
|
261
|
-
headers: data_request_headers)
|
|
261
|
+
headers: data_request_headers) do |f|
|
|
262
|
+
f.request :url_encoded
|
|
263
|
+
f.use FaradayMiddleware::FollowRedirects
|
|
264
|
+
end
|
|
262
265
|
end
|
|
263
266
|
end
|
|
264
267
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
require_relative 'gather_response_generation_data'
|
|
2
2
|
require_relative 'mock_service_response'
|
|
3
3
|
require_relative 'custom_service_response'
|
|
4
|
+
require_relative 'scenario_service_response'
|
|
4
5
|
require_relative '../../cross_suite/cards_identification'
|
|
5
6
|
require_relative '../../cross_suite/tags'
|
|
6
7
|
|
|
@@ -10,6 +11,7 @@ module DaVinciCRDTestKit
|
|
|
10
11
|
include DaVinciCRDTestKit::GatherResponseGenerationData
|
|
11
12
|
include DaVinciCRDTestKit::CustomServiceResponse
|
|
12
13
|
include DaVinciCRDTestKit::CardsIdentification
|
|
14
|
+
include DaVinciCRDTestKit::ScenarioServiceResponse
|
|
13
15
|
|
|
14
16
|
AVAILABLE_HOOKS = [
|
|
15
17
|
'appointment-book',
|
|
@@ -77,34 +79,34 @@ module DaVinciCRDTestKit
|
|
|
77
79
|
|
|
78
80
|
def make_response
|
|
79
81
|
if requested_hook.blank?
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
82
|
+
hook_error_response("No hook requested - populate the 'hook' element in the request.",
|
|
83
|
+
code: 400,
|
|
84
|
+
outcome_code: 'value')
|
|
83
85
|
elsif invoked_hook != requested_hook
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
86
|
+
hook_error_response("#{request.env['PATH_INFO']} serves the #{invoked_hook}, but the client " \
|
|
87
|
+
"requested the #{requested_hook} hook.",
|
|
88
|
+
code: 400,
|
|
89
|
+
outcome_code: 'value')
|
|
88
90
|
elsif wrong_hook_for_test?
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
91
|
+
hook_error_response("Hook '#{requested_hook}' is not being tested in the current session. " \
|
|
92
|
+
"This session is currently testing the '#{tested_hook}' hook.",
|
|
93
|
+
code: 422,
|
|
94
|
+
outcome_code: 'value')
|
|
93
95
|
elsif hook_instance_already_used?
|
|
94
|
-
|
|
96
|
+
hook_error_response(
|
|
95
97
|
"Invalid Request: Hook instance `#{request_body['hookInstance']}` has already been used in this session.",
|
|
96
98
|
outcome_code: 'value'
|
|
97
99
|
)
|
|
98
100
|
elsif AVAILABLE_HOOKS.include?(requested_hook)
|
|
99
101
|
process_valid_hook
|
|
100
102
|
else
|
|
101
|
-
|
|
102
|
-
|
|
103
|
+
hook_error_response("Invalid Request: hook `#{requested_hook}` is not supported by this server.",
|
|
104
|
+
outcome_code: 'value')
|
|
103
105
|
end
|
|
104
106
|
rescue StandardError => e
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
107
|
+
hook_error_response("Inferno failed to generate a response: #{e.message} at #{e.backtrace.first}",
|
|
108
|
+
code: 500,
|
|
109
|
+
outcome_code: 'exception')
|
|
108
110
|
end
|
|
109
111
|
|
|
110
112
|
def process_valid_hook
|
|
@@ -130,13 +132,17 @@ module DaVinciCRDTestKit
|
|
|
130
132
|
end
|
|
131
133
|
|
|
132
134
|
def hook_response
|
|
133
|
-
if
|
|
135
|
+
if unknown_content_group?
|
|
136
|
+
build_unknown_content_hook_response
|
|
137
|
+
elsif self_pay_group? || long_running_group?
|
|
138
|
+
build_coverage_information_hook_response
|
|
139
|
+
elsif response_approach == 'custom'
|
|
134
140
|
build_custom_hook_response
|
|
135
141
|
else
|
|
136
142
|
build_mock_hook_response
|
|
137
143
|
end
|
|
138
144
|
rescue StandardError => e
|
|
139
|
-
|
|
145
|
+
hook_error_response("Inferno failed to generate a response: #{e.message} at #{e.backtrace.first}", code: 500)
|
|
140
146
|
nil
|
|
141
147
|
end
|
|
142
148
|
|
|
@@ -165,29 +171,40 @@ module DaVinciCRDTestKit
|
|
|
165
171
|
end
|
|
166
172
|
|
|
167
173
|
def tags
|
|
168
|
-
|
|
169
|
-
|
|
174
|
+
tags =
|
|
175
|
+
if hook_instance_already_used?
|
|
176
|
+
[DUPLICATED_HOOK_INSTANCE_TAG]
|
|
177
|
+
elsif invoked_hook != requested_hook ||
|
|
178
|
+
wrong_hook_for_test? ||
|
|
179
|
+
!AVAILABLE_HOOKS.include?(requested_hook)
|
|
180
|
+
[]
|
|
181
|
+
else
|
|
182
|
+
[hook_instance_tag, hook_tag, interaction_group_tag, cross_hook_tag]
|
|
183
|
+
end
|
|
170
184
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
!AVAILABLE_HOOKS.include?(requested_hook)
|
|
185
|
+
# the self-pay scenario checks for the absence of requests, so even invalid requests must carry the group tag
|
|
186
|
+
tags << interaction_group_tag if self_pay_group?
|
|
174
187
|
|
|
175
|
-
|
|
188
|
+
tags.uniq.compact
|
|
176
189
|
end
|
|
177
190
|
|
|
178
191
|
def hook_instance_tag
|
|
179
192
|
TagMethods.hook_instance_tag(request_body['hookInstance'])
|
|
180
193
|
end
|
|
181
194
|
|
|
182
|
-
def
|
|
183
|
-
if
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
195
|
+
def hook_tag
|
|
196
|
+
DaVinciCRDTestKit.const_get(:"#{name.upcase}_TAG") if name.present?
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def interaction_group_tag
|
|
200
|
+
test.config.options[:crd_interaction_group].presence
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
def cross_hook_tag
|
|
204
|
+
CROSS_HOOK_ANALYSIS_TAG if test.config.options[:include_in_cross_hook_analysis]
|
|
188
205
|
end
|
|
189
206
|
|
|
190
|
-
def
|
|
207
|
+
def hook_error_response(error_message, code: 400, outcome_code: 'invalid')
|
|
191
208
|
response.status = code
|
|
192
209
|
response.body = error_operation_outcome(outcome_code, error_message).to_json
|
|
193
210
|
response.headers.merge!({ 'Content-Type' => 'application/json', 'Access-Control-Allow-Origin' => '*' })
|
|
@@ -214,11 +231,19 @@ module DaVinciCRDTestKit
|
|
|
214
231
|
end
|
|
215
232
|
|
|
216
233
|
# -----------------------
|
|
217
|
-
#
|
|
234
|
+
# Scenario Group handling
|
|
218
235
|
# -----------------------
|
|
219
236
|
|
|
220
237
|
def long_running_group?
|
|
221
|
-
test.config.options[:
|
|
238
|
+
test.config.options[:crd_interaction_group] == LONG_RUNNING_GROUP_TAG
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
def unknown_content_group?
|
|
242
|
+
test.config.options[:crd_interaction_group] == UNKNOWN_CONTENT_GROUP_TAG
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
def self_pay_group?
|
|
246
|
+
test.config.options[:crd_interaction_group] == SELF_PAY_GROUP_TAG
|
|
222
247
|
end
|
|
223
248
|
|
|
224
249
|
def long_running_pause_time
|
|
@@ -227,12 +252,12 @@ module DaVinciCRDTestKit
|
|
|
227
252
|
&.dig('value').to_i
|
|
228
253
|
end
|
|
229
254
|
|
|
230
|
-
# end the wait immediately after the
|
|
231
|
-
# pause here because update_result runs before response generation
|
|
255
|
+
# end the wait immediately after the scenario request returns
|
|
256
|
+
# pause for long-running requests here because update_result runs before response generation
|
|
232
257
|
def update_result
|
|
233
|
-
return unless long_running_group?
|
|
258
|
+
return unless long_running_group? || unknown_content_group? || self_pay_group?
|
|
234
259
|
|
|
235
|
-
sleep long_running_pause_time
|
|
260
|
+
sleep long_running_pause_time if long_running_group?
|
|
236
261
|
results_repo.update(result.id, result: 'pass', result_message: '')
|
|
237
262
|
end
|
|
238
263
|
end
|
|
@@ -156,8 +156,16 @@ module DaVinciCRDTestKit
|
|
|
156
156
|
}[requested_hook]
|
|
157
157
|
end
|
|
158
158
|
|
|
159
|
+
# @private
|
|
160
|
+
def connection
|
|
161
|
+
@connection ||= Faraday.new do |f|
|
|
162
|
+
f.request :url_encoded
|
|
163
|
+
f.use FaradayMiddleware::FollowRedirects
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
159
167
|
def make_resource_request(uri, access_token)
|
|
160
|
-
response =
|
|
168
|
+
response = connection.get(uri, nil, { 'Authorization' => "Bearer #{access_token}" })
|
|
161
169
|
return unless response.status == 200
|
|
162
170
|
|
|
163
171
|
resource = FHIR.from_contents(response.body)
|
|
@@ -284,22 +292,33 @@ module DaVinciCRDTestKit
|
|
|
284
292
|
|
|
285
293
|
def identify_resources_for_system_actions
|
|
286
294
|
update_resource = context[resource_to_update_field_name]
|
|
287
|
-
|
|
295
|
+
prefetch_id_options = prefetch_key_options_for_system_actions
|
|
296
|
+
prefetched_resource = find_prefetched_resource(request_body, prefetch_id_options)
|
|
288
297
|
|
|
289
298
|
if update_resource.is_a? Hash
|
|
290
299
|
FHIR.from_contents(update_resource.to_json)
|
|
291
|
-
elsif
|
|
292
|
-
FHIR.from_contents(
|
|
300
|
+
elsif prefetched_resource.present?
|
|
301
|
+
FHIR.from_contents(prefetched_resource.to_json)
|
|
293
302
|
elsif update_resource.present?
|
|
294
303
|
get_context_resource(update_resource)
|
|
295
304
|
end
|
|
296
305
|
end
|
|
297
306
|
|
|
298
|
-
def
|
|
307
|
+
def find_prefetched_resource(request_body, key_options)
|
|
308
|
+
prefetch = request_body['prefetch']
|
|
309
|
+
return if prefetch.blank?
|
|
310
|
+
|
|
311
|
+
found_key = key_options&.find { |key| prefetch[key].present? }
|
|
312
|
+
return unless found_key.present?
|
|
313
|
+
|
|
314
|
+
prefetch[found_key]
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
def prefetch_key_options_for_system_actions
|
|
299
318
|
if requested_hook.starts_with?('encounter')
|
|
300
|
-
'encounter'
|
|
319
|
+
['encounter', 'enc'] # handle subset service
|
|
301
320
|
elsif requested_hook == 'order-dispatch'
|
|
302
|
-
'order'
|
|
321
|
+
['order'] # v2.2.1 order-dispatch handled elsewhere
|
|
303
322
|
end
|
|
304
323
|
end
|
|
305
324
|
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
module DaVinciCRDTestKit
|
|
2
|
+
# Serve fixed coverage information responses for hook requests made during scenario groups
|
|
3
|
+
module ScenarioServiceResponse
|
|
4
|
+
# coverage information carrying content that clients are not expected to recognize
|
|
5
|
+
def build_unknown_content_hook_response
|
|
6
|
+
response_body = build_coverage_information_hook_response
|
|
7
|
+
add_unknown_action_element(response_body) if response_body['systemActions'].present?
|
|
8
|
+
add_unknown_extension(response_body)
|
|
9
|
+
response_body
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def build_coverage_information_hook_response
|
|
13
|
+
response_body = { 'cards' => [] }
|
|
14
|
+
system_actions = coverage_information_system_actions
|
|
15
|
+
|
|
16
|
+
if system_actions.present?
|
|
17
|
+
response_body['systemActions'] = system_actions
|
|
18
|
+
else
|
|
19
|
+
create_missing_coverage_information_message
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
response_body
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def coverage_information_system_actions
|
|
26
|
+
return if context.blank? || patient_coverage.blank?
|
|
27
|
+
|
|
28
|
+
create_coverage_extension_system_actions(patient_coverage.id)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def random_element_name
|
|
32
|
+
('a'..'z').to_a.sample(16).join
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# an element that is not part of the CDS Hooks action definition
|
|
36
|
+
def add_unknown_action_element(response_body)
|
|
37
|
+
element_name = random_element_name
|
|
38
|
+
response_body['systemActions'].each { |action| action[element_name] = random_element_name }
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# a CDS Hooks extension whose key is not defined by CRD or CDS Hooks
|
|
42
|
+
def add_unknown_extension(response_body)
|
|
43
|
+
response_body['extension'] = { random_element_name => random_element_name }
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def create_missing_coverage_information_message
|
|
47
|
+
Inferno::Repositories::Messages.new.create(
|
|
48
|
+
result_id: result.id,
|
|
49
|
+
type: 'warning',
|
|
50
|
+
message: %(Unable to return a coverage information system action for the #{requested_hook} hook)
|
|
51
|
+
)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -1,38 +1,19 @@
|
|
|
1
1
|
module DaVinciCRDTestKit
|
|
2
2
|
module TaggedRequestLoadHelper
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
ENCOUNTER_START_TAG,
|
|
6
|
-
ENCOUNTER_DISCHARGE_TAG,
|
|
7
|
-
ORDER_DISPATCH_TAG,
|
|
8
|
-
ORDER_SELECT_TAG,
|
|
9
|
-
ORDER_SIGN_TAG
|
|
10
|
-
].freeze
|
|
11
|
-
|
|
12
|
-
def hook_name
|
|
13
|
-
config.options[:hook_name]
|
|
3
|
+
def load_requests_for_cross_hook_analysis
|
|
4
|
+
load_tagged_requests(CROSS_HOOK_ANALYSIS_TAG)
|
|
14
5
|
end
|
|
15
6
|
|
|
16
|
-
def
|
|
17
|
-
config.options[:
|
|
7
|
+
def load_interaction_group_requests
|
|
8
|
+
load_tagged_requests(config.options[:crd_interaction_group])
|
|
18
9
|
end
|
|
19
10
|
|
|
20
|
-
def
|
|
21
|
-
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def load_hook_requests
|
|
25
|
-
load_tagged_requests(*tags_to_load)
|
|
11
|
+
def hook_name
|
|
12
|
+
config.options[:hook_name]
|
|
26
13
|
end
|
|
27
14
|
|
|
28
|
-
def
|
|
29
|
-
|
|
30
|
-
load_tagged_requests(*tags_to_load)
|
|
31
|
-
else
|
|
32
|
-
ALL_HOOKS.each_with_object([]) do |hook, request_list|
|
|
33
|
-
request_list.concat(load_tagged_requests(*tags_to_load(hook)))
|
|
34
|
-
end
|
|
35
|
-
end
|
|
15
|
+
def crd_interaction_group
|
|
16
|
+
config.options[:crd_interaction_group]
|
|
36
17
|
end
|
|
37
18
|
end
|
|
38
19
|
end
|
|
@@ -41,30 +41,17 @@ module DaVinciCRDTestKit
|
|
|
41
41
|
@request_number = index + 1
|
|
42
42
|
|
|
43
43
|
jku = JSON.parse(token_header)['jku']
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
44
|
+
jwks =
|
|
45
|
+
if jku.present?
|
|
46
|
+
fetch_jwks(jku, crd_jwks_json)
|
|
47
|
+
else
|
|
48
|
+
skip_if cds_jwk_set.blank?,
|
|
49
|
+
%(#{request_number}JWK Set must be inputted if the client's JWK Set is not available via a URL
|
|
50
|
+
identified by the jku header field)
|
|
51
|
+
|
|
52
|
+
parse_or_fetch_jwks(cds_jwk_set, crd_jwks_json)
|
|
52
53
|
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
|
|
54
|
+
next if jwks.blank?
|
|
68
55
|
|
|
69
56
|
keys = jwks['keys']
|
|
70
57
|
unless keys.is_a?(Array)
|
|
@@ -104,6 +91,31 @@ module DaVinciCRDTestKit
|
|
|
104
91
|
|
|
105
92
|
no_error_validation('Retrieving JWKS failed.')
|
|
106
93
|
end
|
|
94
|
+
|
|
95
|
+
def fetch_jwks(uri, crd_jwks_json)
|
|
96
|
+
get(uri)
|
|
97
|
+
|
|
98
|
+
if response[:status] != 200
|
|
99
|
+
add_message('error', %(
|
|
100
|
+
#{request_number}Unexpected response status: expected 200, but received
|
|
101
|
+
#{response[:status]}))
|
|
102
|
+
return false
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
jwks = json_parse(response[:body])
|
|
106
|
+
return false if jwks.blank?
|
|
107
|
+
|
|
108
|
+
crd_jwks_json << response[:body]
|
|
109
|
+
jwks
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def parse_or_fetch_jwks(jwk_set_input, crd_jwks_json)
|
|
113
|
+
if jwk_set_input.match?(%r{\Ahttps?://})
|
|
114
|
+
fetch_jwks(jwk_set_input, crd_jwks_json)
|
|
115
|
+
else
|
|
116
|
+
json_parse(jwk_set_input)
|
|
117
|
+
end
|
|
118
|
+
end
|
|
107
119
|
end
|
|
108
120
|
end
|
|
109
121
|
end
|