davinci_crd_test_kit 0.14.0 → 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.
Files changed (166) hide show
  1. checksums.yaml +4 -4
  2. data/config/presets/{inferno_crd_server_suite.json.erb → client_against_inferno_crd_server_suite.json.erb} +0 -33
  3. data/config/presets/{ri_crd_request_generator.json.erb → client_against_ri_crd_request_generator.json.erb} +1 -14
  4. data/config/presets/client_v221_against_inferno_crd_server_suite.json.erb +84 -0
  5. data/config/presets/client_v221_against_ri_br_provider.json.erb +31 -0
  6. data/config/presets/{ri_crd_request_generator.json_v221.json.erb → client_v221_against_ri_crd_request_generator.json.erb} +1 -1
  7. data/config/presets/{inferno_crd_client_suite.json.erb → server_against_inferno_crd_client_suite.json.erb} +0 -43
  8. data/config/presets/{ri_crd_server.json.erb → server_against_ri_crd_server.json.erb} +1 -44
  9. data/config/presets/{inferno_crd_client_suite_v221.json.erb → server_v221_against_inferno_crd_client_suite.json.erb} +48 -45
  10. 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
  11. data/config/presets/server_v221_against_inferno_g31_suite.json.erb +49 -0
  12. data/lib/davinci_crd_test_kit/client/cross_hook_helper.rb +26 -0
  13. data/lib/davinci_crd_test_kit/client/endpoints/custom_service_response.rb +7 -7
  14. data/lib/davinci_crd_test_kit/client/endpoints/gather_response_generation_data.rb +4 -1
  15. data/lib/davinci_crd_test_kit/client/endpoints/hook_request_endpoint.rb +70 -39
  16. data/lib/davinci_crd_test_kit/client/endpoints/mock_service_response.rb +26 -7
  17. data/lib/davinci_crd_test_kit/client/endpoints/mocked_card_responses/external_reference.json +1 -1
  18. data/lib/davinci_crd_test_kit/client/endpoints/mocked_card_responses/launch_smart_app.json +0 -7
  19. data/lib/davinci_crd_test_kit/client/endpoints/scenario_service_response.rb +54 -0
  20. data/lib/davinci_crd_test_kit/client/tagged_request_load_helper.rb +8 -27
  21. data/lib/davinci_crd_test_kit/client/v2.0.1/auth/retrieve_jwks_test.rb +35 -23
  22. data/lib/davinci_crd_test_kit/client/v2.0.1/auth/token_payload_test.rb +34 -21
  23. data/lib/davinci_crd_test_kit/client/v2.0.1/cds-services-v201.json +20 -20
  24. data/lib/davinci_crd_test_kit/client/v2.0.1/client_appointment_book_group.rb +12 -10
  25. data/lib/davinci_crd_test_kit/client/v2.0.1/client_encounter_discharge_group.rb +12 -10
  26. data/lib/davinci_crd_test_kit/client/v2.0.1/client_encounter_start_group.rb +12 -10
  27. data/lib/davinci_crd_test_kit/client/v2.0.1/client_hooks_group.rb +5 -5
  28. data/lib/davinci_crd_test_kit/client/v2.0.1/client_order_dispatch_group.rb +12 -10
  29. data/lib/davinci_crd_test_kit/client/v2.0.1/client_order_select_group.rb +12 -10
  30. data/lib/davinci_crd_test_kit/client/v2.0.1/client_order_sign_group.rb +12 -10
  31. data/lib/davinci_crd_test_kit/client/v2.0.1/must_support/client_card_must_support_coverage_information.rb +3 -36
  32. data/lib/davinci_crd_test_kit/client/v2.0.1/must_support/client_card_must_support_external_reference.rb +3 -36
  33. data/lib/davinci_crd_test_kit/client/v2.0.1/must_support/client_card_must_support_instructions.rb +3 -36
  34. data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_fetched_data_test.rb +4 -13
  35. data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_prefetch_equals_queried_test.rb +3 -13
  36. data/lib/davinci_crd_test_kit/client/v2.0.1/verify_response/client_display_cards_attest.rb +3 -13
  37. data/lib/davinci_crd_test_kit/client/v2.0.1/verify_response/inferno_response_validation.rb +3 -13
  38. data/lib/davinci_crd_test_kit/client/v2.2.1/api/client_coverage_info_update_test.rb +1 -1
  39. data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/attestation_instructions.rb +10 -0
  40. data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_authorized_scope_attestation_test.rb +45 -0
  41. data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_coverage_based_invocation_attestation_test.rb +44 -0
  42. data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_data_element_expectations_attestation_test.rb +44 -0
  43. data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_hook_invocation_logging_attestation_test.rb +43 -0
  44. data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_must_support_exposure_attestation_test.rb +43 -0
  45. data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_must_support_use_attestation_test.rb +41 -0
  46. data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_order_sign_support_attestation_test.rb +42 -0
  47. data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_prefetch_key_omission_attestation_test.rb +42 -0
  48. data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_resource_identifiers_attestation_test.rb +43 -0
  49. data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_response_case_distinction_attestation_test.rb +43 -0
  50. data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_security_and_privacy_attestation_test.rb +43 -0
  51. data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_workflow_integration_attestation_test.rb +44 -0
  52. data/lib/davinci_crd_test_kit/client/v2.2.1/auth/decode_auth_token_test.rb +1 -1
  53. data/lib/davinci_crd_test_kit/client/v2.2.1/auth/retrieve_jwks_test.rb +29 -18
  54. data/lib/davinci_crd_test_kit/client/v2.2.1/auth/token_payload_test.rb +35 -22
  55. data/lib/davinci_crd_test_kit/client/v2.2.1/cds-services-prefetch-subset-v221.json +47 -47
  56. data/lib/davinci_crd_test_kit/client/v2.2.1/cds-services-v221.json +50 -50
  57. data/lib/davinci_crd_test_kit/client/v2.2.1/client_appointment_book_group.rb +24 -15
  58. data/lib/davinci_crd_test_kit/client/v2.2.1/client_attestations_group.rb +49 -0
  59. data/lib/davinci_crd_test_kit/client/v2.2.1/client_cross_hook_group.rb +22 -6
  60. data/lib/davinci_crd_test_kit/client/v2.2.1/client_cross_hook_interaction_group.rb +98 -0
  61. data/lib/davinci_crd_test_kit/client/v2.2.1/client_encounter_discharge_group.rb +19 -11
  62. data/lib/davinci_crd_test_kit/client/v2.2.1/client_encounter_start_group.rb +19 -11
  63. data/lib/davinci_crd_test_kit/client/v2.2.1/client_fhir_api_group.rb +14 -12
  64. data/lib/davinci_crd_test_kit/client/v2.2.1/client_hooks_group.rb +25 -5
  65. data/lib/davinci_crd_test_kit/client/v2.2.1/client_long_running_hook_group.rb +3 -2
  66. data/lib/davinci_crd_test_kit/client/v2.2.1/client_order_dispatch_group.rb +23 -15
  67. data/lib/davinci_crd_test_kit/client/v2.2.1/client_order_select_group.rb +19 -11
  68. data/lib/davinci_crd_test_kit/client/v2.2.1/client_order_sign_group.rb +23 -15
  69. data/lib/davinci_crd_test_kit/client/v2.2.1/client_registration_group.rb +6 -0
  70. data/lib/davinci_crd_test_kit/client/v2.2.1/client_scenarios_group.rb +26 -0
  71. data/lib/davinci_crd_test_kit/client/v2.2.1/client_self_pay_hook_group.rb +36 -0
  72. data/lib/davinci_crd_test_kit/client/v2.2.1/client_unknown_content_hook_group.rb +34 -0
  73. data/lib/davinci_crd_test_kit/client/v2.2.1/crd_client_suite.rb +24 -3
  74. data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_card_must_support_coverage_information_test.rb +1 -1
  75. data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_fhirpath_collection_as_comma_delimited_string_test.rb +4 -11
  76. data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_hook_instances_unique_test.rb +1 -9
  77. data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_location_address_propagation_test.rb +6 -2
  78. data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_prefetch_complete_and_subset_test.rb +3 -12
  79. data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/appointment_book_receive_request_test.rb +8 -89
  80. data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/base_hook_invocation_receive_request_test.rb +163 -0
  81. data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/cross_hooks_receive_request_test.rb +97 -0
  82. data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/encounter_discharge_receive_request_test.rb +8 -90
  83. data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/encounter_start_receive_request_test.rb +8 -90
  84. data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/order_dispatch_receive_request_test.rb +8 -98
  85. data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/order_select_receive_request_test.rb +8 -98
  86. data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/order_sign_receive_request_test.rb +8 -98
  87. data/lib/davinci_crd_test_kit/client/v2.2.1/long_running/client_long_running_receive_request_test.rb +10 -2
  88. data/lib/davinci_crd_test_kit/client/v2.2.1/long_running/client_skip_long_running_attestation_test.rb +11 -6
  89. data/lib/davinci_crd_test_kit/client/v2.2.1/registration/client_service_registration_attestation_test.rb +2 -1
  90. data/lib/davinci_crd_test_kit/client/v2.2.1/self_pay/client_self_pay_no_request_test.rb +30 -0
  91. data/lib/davinci_crd_test_kit/client/v2.2.1/self_pay/client_self_pay_workflow_test.rb +55 -0
  92. data/lib/davinci_crd_test_kit/client/v2.2.1/unknown_content/client_unknown_content_attestation_test.rb +99 -0
  93. data/lib/davinci_crd_test_kit/client/v2.2.1/unknown_content/client_unknown_content_receive_request_test.rb +62 -0
  94. data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_conformance_test.rb +1 -1
  95. data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_coverage_verification_test.rb +10 -2
  96. data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_data_fetch_verification_test.rb +1 -1
  97. data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_granted_scopes_test.rb +1 -1
  98. data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_prefetch_complete_test.rb +7 -1
  99. data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_prefetch_profiles_test.rb +1 -1
  100. data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_requested_version_test.rb +1 -1
  101. data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_secured_transport_test.rb +1 -1
  102. data/lib/davinci_crd_test_kit/client/v2.2.1/verify_response/client_display_cards_attest.rb +54 -21
  103. data/lib/davinci_crd_test_kit/client/v2.2.1/verify_response/hook_response_support_coverage_information_test.rb +1 -1
  104. data/lib/davinci_crd_test_kit/client/v2.2.1/verify_response/inferno_response_validation.rb +6 -3
  105. data/lib/davinci_crd_test_kit/cross_suite/cards_identification.rb +18 -0
  106. data/lib/davinci_crd_test_kit/cross_suite/logical_models_override_helper.rb +30 -13
  107. data/lib/davinci_crd_test_kit/cross_suite/prefetch_completeness_checker.rb +25 -11
  108. data/lib/davinci_crd_test_kit/cross_suite/prefetch_profile_validation.rb +2 -0
  109. data/lib/davinci_crd_test_kit/cross_suite/requests_logical_model_validation.rb +28 -28
  110. data/lib/davinci_crd_test_kit/cross_suite/response_logical_model_validation.rb +211 -43
  111. data/lib/davinci_crd_test_kit/cross_suite/tags.rb +7 -0
  112. data/lib/davinci_crd_test_kit/requirements/cds-hooks_3.0.0-ballot_requirements.xlsx +0 -0
  113. data/lib/davinci_crd_test_kit/requirements/davinci_crd_test_kit_requirements.csv +6 -2
  114. data/lib/davinci_crd_test_kit/requirements/generated/crd_client_requirements_coverage.csv +107 -107
  115. data/lib/davinci_crd_test_kit/requirements/generated/crd_client_v221_requirements_coverage.csv +101 -97
  116. data/lib/davinci_crd_test_kit/requirements/generated/crd_server_requirements_coverage.csv +18 -18
  117. data/lib/davinci_crd_test_kit/requirements/generated/crd_server_v221_requirements_coverage.csv +43 -39
  118. data/lib/davinci_crd_test_kit/requirements/hl7.fhir.us.davinci-crd_2.2.1_requirements.xlsx +0 -0
  119. data/lib/davinci_crd_test_kit/server/jobs/invoke_hook.rb +3 -3
  120. data/lib/davinci_crd_test_kit/server/jobs/invoke_hook_no_special_requests.rb +17 -0
  121. data/lib/davinci_crd_test_kit/server/jobs/invoke_hook_with_bad_auth.rb +14 -0
  122. data/lib/davinci_crd_test_kit/server/server_abstract_invoke_hook_test.rb +24 -6
  123. data/lib/davinci_crd_test_kit/server/server_hook_helper.rb +2 -2
  124. data/lib/davinci_crd_test_kit/server/v2.0.1/crd_server_suite.rb +1 -1
  125. data/lib/davinci_crd_test_kit/server/v2.0.1/server_hooks_group.rb +5 -5
  126. data/lib/davinci_crd_test_kit/server/v2.2.1/crd_server_suite.rb +3 -0
  127. data/lib/davinci_crd_test_kit/server/v2.2.1/discovery/discovery_standard_prefetch_expressions_test.rb +165 -0
  128. data/lib/davinci_crd_test_kit/server/v2.2.1/interaction/server_invoke_hook_single_request_test.rb +22 -0
  129. data/lib/davinci_crd_test_kit/server/v2.2.1/server_appointment_book_group.rb +10 -102
  130. data/lib/davinci_crd_test_kit/server/v2.2.1/server_demonstrate_hook_response_group.rb +3 -2
  131. data/lib/davinci_crd_test_kit/server/v2.2.1/server_discovery_group.rb +2 -0
  132. data/lib/davinci_crd_test_kit/server/v2.2.1/server_encounter_discharge_group.rb +10 -97
  133. data/lib/davinci_crd_test_kit/server/v2.2.1/server_encounter_start_group.rb +10 -97
  134. data/lib/davinci_crd_test_kit/server/v2.2.1/server_hooks_group.rb +5 -5
  135. data/lib/davinci_crd_test_kit/server/v2.2.1/server_order_dispatch_group.rb +10 -103
  136. data/lib/davinci_crd_test_kit/server/v2.2.1/server_order_select_group.rb +12 -116
  137. data/lib/davinci_crd_test_kit/server/v2.2.1/server_order_sign_group.rb +12 -121
  138. data/lib/davinci_crd_test_kit/server/v2.2.1/specific_coverage_response_group.rb +23 -0
  139. data/lib/davinci_crd_test_kit/server/v2.2.1/specific_coverage_responses/coverage_info_reason_test.rb +108 -0
  140. data/lib/davinci_crd_test_kit/server/v2.2.1/specific_coverage_responses/coverage_not_found_group.rb +116 -0
  141. data/lib/davinci_crd_test_kit/server/v2.2.1/specific_coverage_responses/no_active_coverage_group.rb +115 -0
  142. data/lib/davinci_crd_test_kit/server/v2.2.1/specific_coverage_responses/no_member_found_group.rb +117 -0
  143. data/lib/davinci_crd_test_kit/server/v2.2.1/specific_coverage_responses/technical_issues_group.rb +121 -0
  144. data/lib/davinci_crd_test_kit/server/v2.2.1/specific_coverage_responses/technical_issues_invoke_test.rb +22 -0
  145. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_request/service_request_context_validation_test.rb +1 -0
  146. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_request/service_request_optional_fields_validation_test.rb +1 -0
  147. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_request/service_request_required_fields_validation_test.rb +1 -0
  148. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/additional_orders_validation_test.rb +78 -35
  149. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/coverage_information_card_absence_test.rb +76 -0
  150. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/coverage_information_system_action_validation_test.rb +70 -124
  151. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/create_or_update_coverage_info_response_validation_test.rb +83 -39
  152. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/external_reference_card_validation_test.rb +59 -17
  153. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/form_completion_response_validation_test.rb +80 -45
  154. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/hook_request_resource_resolution.rb +37 -0
  155. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/instructions_card_received_test.rb +57 -6
  156. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/launch_smart_app_card_validation_test.rb +56 -17
  157. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/propose_alternate_request_card_validation_test.rb +52 -25
  158. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/service_response_validation_test.rb +17 -51
  159. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/unknown_cds_hooks_elements_test.rb +1 -1
  160. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/unknown_configuration_test.rb +1 -1
  161. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/unknown_context_test.rb +1 -1
  162. data/lib/davinci_crd_test_kit/version.rb +2 -2
  163. metadata +54 -16
  164. data/config/presets/inferno_crd_server_suite_v221.json.erb +0 -94
  165. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/card_optional_fields_validation_test.rb +0 -57
  166. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/coverage_information_system_action_received_test.rb +0 -65
@@ -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
- error_response('No custom template provided for custom Inferno CRD response',
22
- code: 500,
23
- outcome_code: 'processing')
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
- error_response('Invalid template provided for custom Inferno CRD response: invalid JSON',
30
- code: 500,
31
- outcome_code: 'processing')
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
- error_response(
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',
@@ -76,36 +78,40 @@ module DaVinciCRDTestKit
76
78
  end
77
79
 
78
80
  def make_response
79
- if invoked_hook != requested_hook
80
- error_response("#{request.env['PATH_INFO']} serves the #{invoked_hook}, but the client " \
81
- "requested the #{requested_hook} hook.",
82
- code: 400,
83
- outcome_code: 'value')
81
+ if requested_hook.blank?
82
+ hook_error_response("No hook requested - populate the 'hook' element in the request.",
83
+ code: 400,
84
+ outcome_code: 'value')
85
+ elsif invoked_hook != requested_hook
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')
84
90
  elsif wrong_hook_for_test?
85
- error_response("Hook '#{requested_hook}' is not being tested in the current session. " \
86
- "This session is currently testing the '#{tested_hook}' hook.",
87
- code: 422,
88
- outcome_code: 'value')
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')
89
95
  elsif hook_instance_already_used?
90
- error_response(
96
+ hook_error_response(
91
97
  "Invalid Request: Hook instance `#{request_body['hookInstance']}` has already been used in this session.",
92
98
  outcome_code: 'value'
93
99
  )
94
100
  elsif AVAILABLE_HOOKS.include?(requested_hook)
95
101
  process_valid_hook
96
102
  else
97
- error_response("Invalid Request: hook `#{requested_hook}` is not supported by this server.",
98
- outcome_code: 'value')
103
+ hook_error_response("Invalid Request: hook `#{requested_hook}` is not supported by this server.",
104
+ outcome_code: 'value')
99
105
  end
100
106
  rescue StandardError => e
101
- error_response("Inferno failed to generate a response: #{e.message} at #{e.backtrace.first}",
102
- code: 500,
103
- outcome_code: 'exception')
107
+ hook_error_response("Inferno failed to generate a response: #{e.message} at #{e.backtrace.first}",
108
+ code: 500,
109
+ outcome_code: 'exception')
104
110
  end
105
111
 
106
112
  def process_valid_hook
107
113
  if ig_version == 'v201'
108
- send(:"gather_#{requested_hook.gsub('-', '_')}_data")
114
+ send(:"gather_#{requested_hook&.gsub('-', '_')}_data")
109
115
  request_coverage
110
116
  elsif ig_version == 'v221'
111
117
  request_additional_fhir_data
@@ -126,17 +132,21 @@ module DaVinciCRDTestKit
126
132
  end
127
133
 
128
134
  def hook_response
129
- if response_approach == 'custom'
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'
130
140
  build_custom_hook_response
131
141
  else
132
142
  build_mock_hook_response
133
143
  end
134
144
  rescue StandardError => e
135
- error_response("Inferno failed to generate a response: #{e.message} at #{e.backtrace.first}", code: 500)
145
+ hook_error_response("Inferno failed to generate a response: #{e.message} at #{e.backtrace.first}", code: 500)
136
146
  nil
137
147
  end
138
148
 
139
- def apply_hook_configuration(response_body)
149
+ def apply_hook_configuration(response_body) # rubocop:disable Metrics/CyclomaticComplexity
140
150
  return response_body unless response_body.present? && coverage_info_disabled?
141
151
 
142
152
  cards = response_body['cards']
@@ -147,6 +157,8 @@ module DaVinciCRDTestKit
147
157
  response_body['systemActions'] = system_actions.reject { |action| coverage_info_system_action_type?(action) }
148
158
  end
149
159
 
160
+ response_body.delete 'systemActions' if response_body['systemActions'].blank?
161
+
150
162
  response_body
151
163
  end
152
164
 
@@ -159,29 +171,40 @@ module DaVinciCRDTestKit
159
171
  end
160
172
 
161
173
  def tags
162
- return [LONG_RUNNING_GROUP_TAG] if long_running_group?
163
- return [DUPLICATED_HOOK_INSTANCE_TAG] if hook_instance_already_used?
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
164
184
 
165
- return [] if invoked_hook != requested_hook ||
166
- wrong_hook_for_test? ||
167
- !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?
168
187
 
169
- [hook_instance_tag, hook_or_group_tag]
188
+ tags.uniq.compact
170
189
  end
171
190
 
172
191
  def hook_instance_tag
173
192
  TagMethods.hook_instance_tag(request_body['hookInstance'])
174
193
  end
175
194
 
176
- def hook_or_group_tag
177
- if test.config.options[:crd_test_group].present?
178
- test.config.options[:crd_test_group]
179
- else
180
- DaVinciCRDTestKit.const_get(:"#{name.upcase}_TAG")
181
- end
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
182
201
  end
183
202
 
184
- def error_response(error_message, code: 400, outcome_code: 'invalid')
203
+ def cross_hook_tag
204
+ CROSS_HOOK_ANALYSIS_TAG if test.config.options[:include_in_cross_hook_analysis]
205
+ end
206
+
207
+ def hook_error_response(error_message, code: 400, outcome_code: 'invalid')
185
208
  response.status = code
186
209
  response.body = error_operation_outcome(outcome_code, error_message).to_json
187
210
  response.headers.merge!({ 'Content-Type' => 'application/json', 'Access-Control-Allow-Origin' => '*' })
@@ -204,15 +227,23 @@ module DaVinciCRDTestKit
204
227
  end
205
228
 
206
229
  def name
207
- requested_hook.gsub('-', '_')
230
+ requested_hook&.gsub('-', '_')
208
231
  end
209
232
 
210
233
  # -----------------------
211
- # Long Running Group handling
234
+ # Scenario Group handling
212
235
  # -----------------------
213
236
 
214
237
  def long_running_group?
215
- test.config.options[:crd_test_group] == LONG_RUNNING_GROUP_TAG
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
216
247
  end
217
248
 
218
249
  def long_running_pause_time
@@ -221,12 +252,12 @@ module DaVinciCRDTestKit
221
252
  &.dig('value').to_i
222
253
  end
223
254
 
224
- # end the wait immediately after the long-running request returns
225
- # 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
226
257
  def update_result
227
- return unless long_running_group?
258
+ return unless long_running_group? || unknown_content_group? || self_pay_group?
228
259
 
229
- sleep long_running_pause_time
260
+ sleep long_running_pause_time if long_running_group?
230
261
  results_repo.update(result.id, result: 'pass', result_message: '')
231
262
  end
232
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 = Faraday.get(uri, nil, { 'Authorization' => "Bearer #{access_token}" })
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
- prefetch_id = prefetch_key_for_system_actions
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 prefetch_id.present? && request_body['prefetch'] && request_body['prefetch'][prefetch_id]
292
- FHIR.from_contents(request_body['prefetch'][prefetch_id].to_json)
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 prefetch_key_for_system_actions
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
 
@@ -18,4 +18,4 @@
18
18
  "type": "absolute"
19
19
  }
20
20
  ]
21
- }
21
+ }
@@ -11,13 +11,6 @@
11
11
  "display": "Coverage Information"
12
12
  }
13
13
  },
14
- "suggestions": [
15
- {
16
- "label": "Inferno placeholder suggestion",
17
- "uuid": "5abc166b-c50f-4df4-bdb1-2b0b62cb8e55"
18
- }
19
- ],
20
- "selectionBehavior": "any",
21
14
  "links": [
22
15
  {
23
16
  "label": "Inferno",
@@ -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
- ALL_HOOKS = [
4
- APPOINTMENT_BOOK_TAG,
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 crd_test_group
17
- config.options[:crd_test_group]
7
+ def load_interaction_group_requests
8
+ load_tagged_requests(config.options[:crd_interaction_group])
18
9
  end
19
10
 
20
- def tags_to_load(hook = hook_name)
21
- crd_test_group.present? ? [crd_test_group] : [hook]
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 requests_to_analyze
29
- if hook_name.present?
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