davinci_crd_test_kit 0.13.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (341) hide show
  1. checksums.yaml +4 -4
  2. data/config/presets/inferno_crd_client_suite.json.erb +20 -14
  3. data/config/presets/inferno_crd_client_suite_prefetch_subset_v221.json.erb +125 -0
  4. data/config/presets/inferno_crd_client_suite_v221.json.erb +124 -0
  5. data/config/presets/inferno_crd_server_suite.json.erb +58 -1
  6. data/config/presets/inferno_crd_server_suite_v221.json.erb +94 -0
  7. data/config/presets/ri_crd_request_generator.json_v221.json.erb +13 -0
  8. data/config/presets/ri_crd_server.json.erb +19 -19
  9. data/lib/davinci_crd_test_kit/client/client_base_urls.rb +80 -0
  10. data/lib/davinci_crd_test_kit/{client_hook_request_validation.rb → client/client_hook_request_validation.rb} +1 -1
  11. data/lib/davinci_crd_test_kit/client/crd_client_options.rb +30 -0
  12. data/lib/davinci_crd_test_kit/client/endpoints/cds_services_discovery_handler.rb +34 -0
  13. data/lib/davinci_crd_test_kit/client/endpoints/custom_service_response.rb +342 -0
  14. data/lib/davinci_crd_test_kit/client/endpoints/gather_response_generation_data.rb +410 -0
  15. data/lib/davinci_crd_test_kit/client/endpoints/hook_request_endpoint.rb +233 -0
  16. data/lib/davinci_crd_test_kit/{mock_service_response.rb → client/endpoints/mock_service_response.rb} +165 -59
  17. data/lib/davinci_crd_test_kit/{card_responses → client/endpoints/mocked_card_responses}/companions_prerequisites.json +1 -0
  18. data/lib/davinci_crd_test_kit/{card_responses → client/endpoints/mocked_card_responses}/create_update_coverage_information.json +3 -2
  19. data/lib/davinci_crd_test_kit/{card_responses → client/endpoints/mocked_card_responses}/launch_smart_app.json +8 -1
  20. data/lib/davinci_crd_test_kit/{card_responses → client/endpoints/mocked_card_responses}/propose_alternate_request.json +1 -0
  21. data/lib/davinci_crd_test_kit/{card_responses → client/endpoints/mocked_card_responses}/request_form_completion.json +17 -16
  22. data/lib/davinci_crd_test_kit/client/multi_request_message_helper.rb +35 -0
  23. data/lib/davinci_crd_test_kit/client/tagged_request_load_helper.rb +38 -0
  24. data/lib/davinci_crd_test_kit/client/v2.0.1/api/client_fhir_api_create_test.rb +43 -0
  25. data/lib/davinci_crd_test_kit/client/v2.0.1/api/client_fhir_api_read_test.rb +43 -0
  26. data/lib/davinci_crd_test_kit/client/v2.0.1/api/client_fhir_api_search_test.rb +234 -0
  27. data/lib/davinci_crd_test_kit/client/v2.0.1/api/client_fhir_api_update_test.rb +43 -0
  28. data/lib/davinci_crd_test_kit/client/v2.0.1/api/client_fhir_api_validation_test.rb +63 -0
  29. data/lib/davinci_crd_test_kit/client/v2.0.1/auth/decode_auth_token_test.rb +65 -0
  30. data/lib/davinci_crd_test_kit/client/v2.0.1/auth/retrieve_jwks_test.rb +109 -0
  31. data/lib/davinci_crd_test_kit/client/v2.0.1/auth/token_header_test.rb +70 -0
  32. data/lib/davinci_crd_test_kit/client/v2.0.1/auth/token_payload_test.rb +85 -0
  33. data/lib/davinci_crd_test_kit/{routes/cds-services.json → client/v2.0.1/cds-services-v201.json} +1 -1
  34. data/lib/davinci_crd_test_kit/client/v2.0.1/client_appointment_book_group.rb +108 -0
  35. data/lib/davinci_crd_test_kit/client/v2.0.1/client_card_must_support_group.rb +31 -0
  36. data/lib/davinci_crd_test_kit/client/v2.0.1/client_encounter_discharge_group.rb +105 -0
  37. data/lib/davinci_crd_test_kit/client/v2.0.1/client_encounter_start_group.rb +105 -0
  38. data/lib/davinci_crd_test_kit/client/v2.0.1/client_fhir_api_group.rb +790 -0
  39. data/lib/davinci_crd_test_kit/client/v2.0.1/client_hooks_group.rb +74 -0
  40. data/lib/davinci_crd_test_kit/client/v2.0.1/client_order_dispatch_group.rb +111 -0
  41. data/lib/davinci_crd_test_kit/client/v2.0.1/client_order_select_group.rb +116 -0
  42. data/lib/davinci_crd_test_kit/client/v2.0.1/client_order_sign_group.rb +113 -0
  43. data/lib/davinci_crd_test_kit/{client_registration_group.rb → client/v2.0.1/client_registration_group.rb} +12 -8
  44. data/lib/davinci_crd_test_kit/client/v2.0.1/client_urls.rb +13 -0
  45. data/lib/davinci_crd_test_kit/client/v2.0.1/crd_client_suite.rb +134 -0
  46. data/lib/davinci_crd_test_kit/client/v2.0.1/invocation/appointment_book_receive_request_test.rb +129 -0
  47. data/lib/davinci_crd_test_kit/client/v2.0.1/invocation/encounter_discharge_receive_request_test.rb +126 -0
  48. data/lib/davinci_crd_test_kit/client/v2.0.1/invocation/encounter_start_receive_request_test.rb +126 -0
  49. data/lib/davinci_crd_test_kit/client/v2.0.1/invocation/order_dispatch_receive_request_test.rb +138 -0
  50. data/lib/davinci_crd_test_kit/client/v2.0.1/invocation/order_select_receive_request_test.rb +134 -0
  51. data/lib/davinci_crd_test_kit/client/v2.0.1/invocation/order_sign_receive_request_test.rb +136 -0
  52. data/lib/davinci_crd_test_kit/client/v2.0.1/must_support/client_card_must_support_coverage_information.rb +93 -0
  53. data/lib/davinci_crd_test_kit/client/v2.0.1/must_support/client_card_must_support_external_reference.rb +62 -0
  54. data/lib/davinci_crd_test_kit/client/v2.0.1/must_support/client_card_must_support_instructions.rb +62 -0
  55. data/lib/davinci_crd_test_kit/client/v2.0.1/registration/client_registration_verification_test.rb +94 -0
  56. data/lib/davinci_crd_test_kit/client/v2.0.1/registration/client_service_registration_attestation_test.rb +40 -0
  57. data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_fetched_data_test.rb +86 -0
  58. data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_optional_fields_test.rb +63 -0
  59. data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_prefetch_equals_queried_test.rb +96 -0
  60. data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_required_fields_test.rb +55 -0
  61. data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_valid_context_test.rb +70 -0
  62. data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_valid_prefetch_test.rb +62 -0
  63. data/lib/davinci_crd_test_kit/client/v2.0.1/verify_response/client_display_cards_attest.rb +83 -0
  64. data/lib/davinci_crd_test_kit/client/v2.0.1/verify_response/inferno_response_validation.rb +79 -0
  65. data/lib/davinci_crd_test_kit/client/v2.2.1/api/client_coverage_info_update_test.rb +212 -0
  66. data/lib/davinci_crd_test_kit/client/v2.2.1/api/client_crd_update_verification_group.rb +18 -0
  67. data/lib/davinci_crd_test_kit/client/v2.2.1/auth/decode_auth_token_test.rb +69 -0
  68. data/lib/davinci_crd_test_kit/client/v2.2.1/auth/retrieve_jwks_test.rb +120 -0
  69. data/lib/davinci_crd_test_kit/client/v2.2.1/auth/token_header_test.rb +92 -0
  70. data/lib/davinci_crd_test_kit/client/v2.2.1/auth/token_payload_test.rb +93 -0
  71. data/lib/davinci_crd_test_kit/client/v2.2.1/cds-services-prefetch-subset-v221.json +198 -0
  72. data/lib/davinci_crd_test_kit/client/v2.2.1/cds-services-v221.json +202 -0
  73. data/lib/davinci_crd_test_kit/client/v2.2.1/client_appointment_book_group.rb +102 -0
  74. data/lib/davinci_crd_test_kit/client/v2.2.1/client_cross_hook_group.rb +28 -0
  75. data/lib/davinci_crd_test_kit/client/v2.2.1/client_encounter_discharge_group.rb +96 -0
  76. data/lib/davinci_crd_test_kit/client/v2.2.1/client_encounter_start_group.rb +95 -0
  77. data/lib/davinci_crd_test_kit/client/v2.2.1/client_fhir_api_group.rb +88 -0
  78. data/lib/davinci_crd_test_kit/client/v2.2.1/client_hooks_group.rb +64 -0
  79. data/lib/davinci_crd_test_kit/client/v2.2.1/client_long_running_hook_group.rb +32 -0
  80. data/lib/davinci_crd_test_kit/client/v2.2.1/client_order_dispatch_group.rb +101 -0
  81. data/lib/davinci_crd_test_kit/client/v2.2.1/client_order_select_group.rb +102 -0
  82. data/lib/davinci_crd_test_kit/client/v2.2.1/client_order_sign_group.rb +107 -0
  83. data/lib/davinci_crd_test_kit/client/v2.2.1/client_registration_group.rb +27 -0
  84. data/lib/davinci_crd_test_kit/client/v2.2.1/client_urls.rb +27 -0
  85. data/lib/davinci_crd_test_kit/client/v2.2.1/crd_client_suite.rb +229 -0
  86. data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_card_must_support_coverage_information_test.rb +63 -0
  87. data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_fhirpath_collection_as_comma_delimited_string_test.rb +60 -0
  88. data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_hook_instances_unique_test.rb +45 -0
  89. data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_location_address_propagation_test.rb +135 -0
  90. data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_prefetch_complete_and_subset_test.rb +103 -0
  91. data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/appointment_book_receive_request_test.rb +156 -0
  92. data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/encounter_discharge_receive_request_test.rb +157 -0
  93. data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/encounter_start_receive_request_test.rb +157 -0
  94. data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/order_dispatch_receive_request_test.rb +165 -0
  95. data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/order_select_receive_request_test.rb +165 -0
  96. data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/order_sign_receive_request_test.rb +165 -0
  97. data/lib/davinci_crd_test_kit/client/v2.2.1/long_running/client_long_running_receive_request_test.rb +64 -0
  98. data/lib/davinci_crd_test_kit/client/v2.2.1/long_running/client_skip_long_running_attestation_test.rb +49 -0
  99. data/lib/davinci_crd_test_kit/client/v2.2.1/registration/client_registration_verification_test.rb +161 -0
  100. data/lib/davinci_crd_test_kit/client/v2.2.1/registration/client_service_registration_attestation_test.rb +107 -0
  101. data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_conformance_test.rb +47 -0
  102. data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_coverage_verification_test.rb +152 -0
  103. data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_data_fetch_verification_test.rb +55 -0
  104. data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_granted_scopes_test.rb +123 -0
  105. data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_prefetch_complete_test.rb +127 -0
  106. data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_prefetch_profiles_test.rb +55 -0
  107. data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_requested_version_test.rb +54 -0
  108. data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_secured_transport_test.rb +48 -0
  109. data/lib/davinci_crd_test_kit/client/v2.2.1/verify_response/client_display_cards_attest.rb +74 -0
  110. data/lib/davinci_crd_test_kit/client/v2.2.1/verify_response/hook_response_support_coverage_information_test.rb +30 -0
  111. data/lib/davinci_crd_test_kit/client/v2.2.1/verify_response/inferno_response_validation.rb +77 -0
  112. data/lib/davinci_crd_test_kit/cross_suite/base_urls.rb +20 -0
  113. data/lib/davinci_crd_test_kit/cross_suite/cards_identification.rb +312 -0
  114. data/lib/davinci_crd_test_kit/{cards_validation.rb → cross_suite/cards_validation.rb} +104 -47
  115. data/lib/davinci_crd_test_kit/cross_suite/coverage-information_stu201_metadata.yml +27 -0
  116. data/lib/davinci_crd_test_kit/cross_suite/coverage-information_stu221_metadata.yml +60 -0
  117. data/lib/davinci_crd_test_kit/cross_suite/fhirpath_on_cds_request.rb +177 -0
  118. data/lib/davinci_crd_test_kit/{hook_request_field_validation.rb → cross_suite/hook_request_field_validation.rb} +282 -203
  119. data/lib/davinci_crd_test_kit/cross_suite/logical_models_override_helper.rb +220 -0
  120. data/lib/davinci_crd_test_kit/cross_suite/prefetch_completeness_checker.rb +462 -0
  121. data/lib/davinci_crd_test_kit/cross_suite/prefetch_contents_validation.rb +81 -0
  122. data/lib/davinci_crd_test_kit/cross_suite/prefetch_profile_validation.rb +48 -0
  123. data/lib/davinci_crd_test_kit/cross_suite/profiles_and_resource_types.rb +63 -0
  124. data/lib/davinci_crd_test_kit/cross_suite/replace_tokens.rb +38 -0
  125. data/lib/davinci_crd_test_kit/cross_suite/requests_logical_model_validation.rb +202 -0
  126. data/lib/davinci_crd_test_kit/cross_suite/response_logical_model_validation.rb +274 -0
  127. data/lib/davinci_crd_test_kit/{suggestion_actions_validation.rb → cross_suite/suggestion_actions_validation.rb} +70 -50
  128. data/lib/davinci_crd_test_kit/cross_suite/tags.rb +42 -0
  129. data/lib/davinci_crd_test_kit/metadata.rb +10 -44
  130. data/lib/davinci_crd_test_kit/requirements/cds-hooks-library_1.0.1_requirements.xlsx +0 -0
  131. data/lib/davinci_crd_test_kit/requirements/cds-hooks_2.0_requirements.xlsx +0 -0
  132. data/lib/davinci_crd_test_kit/requirements/cds-hooks_3.0.0-ballot_requirements.xlsx +0 -0
  133. data/lib/davinci_crd_test_kit/requirements/davinci_crd_test_kit_requirements.csv +742 -65
  134. data/lib/davinci_crd_test_kit/requirements/generated/crd_client_requirements_coverage.csv +279 -54
  135. data/lib/davinci_crd_test_kit/requirements/generated/crd_client_v221_requirements_coverage.csv +1430 -0
  136. data/lib/davinci_crd_test_kit/requirements/generated/crd_server_requirements_coverage.csv +36 -45
  137. data/lib/davinci_crd_test_kit/requirements/generated/crd_server_v221_requirements_coverage.csv +143 -0
  138. data/lib/davinci_crd_test_kit/requirements/hl7.fhir.us.davinci-crd_2.0.1_requirements.xlsx +0 -0
  139. data/lib/davinci_crd_test_kit/requirements/hl7.fhir.us.davinci-crd_2.2.1_requirements.xlsx +0 -0
  140. data/lib/davinci_crd_test_kit/server/endpoints/jwk_set_endpoint_handler.rb +13 -0
  141. data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_create_endpoint.rb +23 -0
  142. data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_delete_endpoint.rb +30 -0
  143. data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_metadata_endpoint.rb +112 -0
  144. data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_read_endpoint.rb +21 -0
  145. data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_request_handler.rb +261 -0
  146. data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_search_endpoint.rb +561 -0
  147. data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/fhir_update_endpoint.rb +24 -0
  148. data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr/stress-test-Bundle.json +54687 -0
  149. data/lib/davinci_crd_test_kit/server/endpoints/mock_ehr_endpoints.rb +95 -0
  150. data/lib/davinci_crd_test_kit/server/jobs/invoke_hook.rb +225 -0
  151. data/lib/davinci_crd_test_kit/{jwt_helper.rb → server/jwt_helper.rb} +1 -12
  152. data/lib/davinci_crd_test_kit/server/resource_extractor.rb +68 -0
  153. data/lib/davinci_crd_test_kit/server/server_abstract_invoke_hook_test.rb +165 -0
  154. data/lib/davinci_crd_test_kit/server/server_base_urls.rb +30 -0
  155. data/lib/davinci_crd_test_kit/{server_hook_helper.rb → server/server_hook_helper.rb} +1 -1
  156. data/lib/davinci_crd_test_kit/{server_hook_request_validation.rb → server/server_hook_request_validation.rb} +1 -1
  157. data/lib/davinci_crd_test_kit/{test_helper.rb → server/server_test_helper.rb} +7 -3
  158. data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Appointment.yml +5 -0
  159. data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/ClaimResponse.yml +5 -0
  160. data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/CommunicationRequest.yml +5 -0
  161. data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Coverage.yml +21 -0
  162. data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Device.yml +5 -0
  163. data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/DeviceRequest.yml +5 -0
  164. data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Encounter.yml +7 -0
  165. data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Location.yml +5 -0
  166. data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/MedicationRequest.yml +5 -0
  167. data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/NutritionOrder.yml +5 -0
  168. data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Organization.yml +5 -0
  169. data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Patient.yml +5 -0
  170. data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Practitioner.yml +5 -0
  171. data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/PractitionerRole.yml +40 -0
  172. data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/ServiceRequest.yml +5 -0
  173. data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/Task.yml +5 -0
  174. data/lib/davinci_crd_test_kit/server/v2.0.1/crd_metadata/VisionPrescription.yml +5 -0
  175. data/lib/davinci_crd_test_kit/server/v2.0.1/crd_server_suite.rb +99 -0
  176. data/lib/davinci_crd_test_kit/server/v2.0.1/discovery/discovery_endpoint_test.rb +90 -0
  177. data/lib/davinci_crd_test_kit/server/v2.0.1/discovery/discovery_services_validation_test.rb +67 -0
  178. data/lib/davinci_crd_test_kit/server/v2.0.1/interaction/server_invoke_hook_test.rb +12 -0
  179. data/lib/davinci_crd_test_kit/server/v2.0.1/must_support/coverage_information_system_action_across_hooks_validation_test.rb +34 -0
  180. data/lib/davinci_crd_test_kit/server/v2.0.1/must_support/external_reference_card_across_hooks_validation_test.rb +30 -0
  181. data/lib/davinci_crd_test_kit/server/v2.0.1/must_support/instructions_card_received_across_hooks_test.rb +27 -0
  182. data/lib/davinci_crd_test_kit/server/v2.0.1/server_appointment_book_group.rb +191 -0
  183. data/lib/davinci_crd_test_kit/server/v2.0.1/server_demonstrate_hook_response_group.rb +93 -0
  184. data/lib/davinci_crd_test_kit/server/v2.0.1/server_discovery_group.rb +62 -0
  185. data/lib/davinci_crd_test_kit/server/v2.0.1/server_encounter_discharge_group.rb +186 -0
  186. data/lib/davinci_crd_test_kit/server/v2.0.1/server_encounter_start_group.rb +186 -0
  187. data/lib/davinci_crd_test_kit/server/v2.0.1/server_hooks_group.rb +73 -0
  188. data/lib/davinci_crd_test_kit/server/v2.0.1/server_order_dispatch_group.rb +191 -0
  189. data/lib/davinci_crd_test_kit/server/v2.0.1/server_order_select_group.rb +211 -0
  190. data/lib/davinci_crd_test_kit/server/v2.0.1/server_order_sign_group.rb +216 -0
  191. data/lib/davinci_crd_test_kit/server/v2.0.1/server_required_card_response_validation_group.rb +28 -0
  192. data/lib/davinci_crd_test_kit/server/v2.0.1/server_urls.rb +13 -0
  193. data/lib/davinci_crd_test_kit/server/v2.0.1/verify_request/service_request_context_validation_test.rb +30 -0
  194. data/lib/davinci_crd_test_kit/server/v2.0.1/verify_request/service_request_optional_fields_validation_test.rb +39 -0
  195. data/lib/davinci_crd_test_kit/server/v2.0.1/verify_request/service_request_required_fields_validation_test.rb +40 -0
  196. data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/additional_orders_validation_test.rb +59 -0
  197. data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/card_optional_fields_validation_test.rb +51 -0
  198. data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/coverage_information_system_action_received_test.rb +65 -0
  199. data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/coverage_information_system_action_validation_test.rb +120 -0
  200. data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/create_or_update_coverage_info_response_validation_test.rb +70 -0
  201. data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/external_reference_card_validation_test.rb +37 -0
  202. data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/form_completion_response_validation_test.rb +67 -0
  203. data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/instructions_card_received_test.rb +30 -0
  204. data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/launch_smart_app_card_validation_test.rb +39 -0
  205. data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/propose_alternate_request_card_validation_test.rb +46 -0
  206. data/lib/davinci_crd_test_kit/server/v2.0.1/verify_response/service_response_validation_test.rb +83 -0
  207. data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Appointment_withorder.yml +5 -0
  208. data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Appointment_withoutorder.yml +5 -0
  209. data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/CommunicationRequest.yml +5 -0
  210. data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Coverage.yml +5 -0
  211. data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Device.yml +5 -0
  212. data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/DeviceRequest.yml +5 -0
  213. data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Encounter.yml +5 -0
  214. data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Location.yml +5 -0
  215. data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/MedicationRequest.yml +5 -0
  216. data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/NutritionOrder.yml +5 -0
  217. data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Organization.yml +5 -0
  218. data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/Patient.yml +5 -0
  219. data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/PractitionerRole.yml +5 -0
  220. data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/ServiceRequest.yml +5 -0
  221. data/lib/davinci_crd_test_kit/server/v2.2.1/crd_metadata/VisionPrescription.yml +5 -0
  222. data/lib/davinci_crd_test_kit/server/v2.2.1/crd_server_suite.rb +115 -0
  223. data/lib/davinci_crd_test_kit/server/v2.2.1/discovery/discovery_configuration_test.rb +159 -0
  224. data/lib/davinci_crd_test_kit/server/v2.2.1/discovery/discovery_endpoint_test.rb +90 -0
  225. data/lib/davinci_crd_test_kit/server/v2.2.1/discovery/discovery_prefetch_support_test.rb +43 -0
  226. data/lib/davinci_crd_test_kit/server/v2.2.1/discovery/discovery_services_validation_test.rb +121 -0
  227. data/lib/davinci_crd_test_kit/server/v2.2.1/interaction/server_invoke_hook_test.rb +17 -0
  228. data/lib/davinci_crd_test_kit/server/v2.2.1/must_support/coverage_information_must_support_test.rb +71 -0
  229. data/lib/davinci_crd_test_kit/server/v2.2.1/must_support/coverage_information_system_action_across_hooks_validation_test.rb +36 -0
  230. data/lib/davinci_crd_test_kit/server/v2.2.1/must_support/supported_us_core_versions_test.rb +118 -0
  231. data/lib/davinci_crd_test_kit/server/v2.2.1/server_appointment_book_group.rb +213 -0
  232. data/lib/davinci_crd_test_kit/server/v2.2.1/server_demonstrate_hook_response_group.rb +93 -0
  233. data/lib/davinci_crd_test_kit/server/v2.2.1/server_discovery_group.rb +69 -0
  234. data/lib/davinci_crd_test_kit/server/v2.2.1/server_encounter_discharge_group.rb +194 -0
  235. data/lib/davinci_crd_test_kit/server/v2.2.1/server_encounter_start_group.rb +194 -0
  236. data/lib/davinci_crd_test_kit/server/v2.2.1/server_hooks_group.rb +73 -0
  237. data/lib/davinci_crd_test_kit/server/v2.2.1/server_order_dispatch_group.rb +214 -0
  238. data/lib/davinci_crd_test_kit/server/v2.2.1/server_order_select_group.rb +219 -0
  239. data/lib/davinci_crd_test_kit/server/v2.2.1/server_order_sign_group.rb +241 -0
  240. data/lib/davinci_crd_test_kit/server/v2.2.1/server_required_card_response_validation_group.rb +30 -0
  241. data/lib/davinci_crd_test_kit/server/v2.2.1/server_urls.rb +13 -0
  242. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_request/service_request_context_validation_test.rb +30 -0
  243. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_request/service_request_no_custom_extensions_test.rb +120 -0
  244. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_request/service_request_optional_fields_validation_test.rb +39 -0
  245. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_request/service_request_required_fields_validation_test.rb +40 -0
  246. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/additional_orders_validation_test.rb +66 -0
  247. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/all_responses_include_coverage_information_test.rb +123 -0
  248. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/card_optional_fields_validation_test.rb +57 -0
  249. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/coverage_info_configuration_test.rb +83 -0
  250. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/coverage_information_system_action_received_test.rb +65 -0
  251. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/coverage_information_system_action_validation_test.rb +184 -0
  252. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/create_or_update_coverage_info_response_validation_test.rb +75 -0
  253. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/external_reference_card_validation_test.rb +47 -0
  254. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/form_completion_response_validation_test.rb +91 -0
  255. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/hook_request_resource_resolution.rb +137 -0
  256. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/instructions_card_received_test.rb +32 -0
  257. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/launch_smart_app_card_validation_test.rb +49 -0
  258. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/order_dispatch_coverage_information_test.rb +38 -0
  259. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/propose_alternate_request_card_validation_test.rb +54 -0
  260. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/service_response_validation_test.rb +97 -0
  261. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/unknown_cds_hooks_elements_test.rb +78 -0
  262. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/unknown_configuration_test.rb +78 -0
  263. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/unknown_context_test.rb +78 -0
  264. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/verify_response_without_billing_options_test.rb +43 -0
  265. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/verify_response_without_configuration_test.rb +44 -0
  266. data/lib/davinci_crd_test_kit/version.rb +2 -2
  267. data/lib/davinci_crd_test_kit.rb +4 -2
  268. metadata +297 -93
  269. data/lib/davinci_crd_test_kit/client_fhir_api_group.rb +0 -785
  270. data/lib/davinci_crd_test_kit/client_hooks_group.rb +0 -74
  271. data/lib/davinci_crd_test_kit/client_tests/appointment_book_receive_request_test.rb +0 -93
  272. data/lib/davinci_crd_test_kit/client_tests/client_appointment_book_group.rb +0 -75
  273. data/lib/davinci_crd_test_kit/client_tests/client_display_cards_attest.rb +0 -48
  274. data/lib/davinci_crd_test_kit/client_tests/client_encounter_discharge_group.rb +0 -73
  275. data/lib/davinci_crd_test_kit/client_tests/client_encounter_start_group.rb +0 -73
  276. data/lib/davinci_crd_test_kit/client_tests/client_fhir_api_create_test.rb +0 -42
  277. data/lib/davinci_crd_test_kit/client_tests/client_fhir_api_read_test.rb +0 -40
  278. data/lib/davinci_crd_test_kit/client_tests/client_fhir_api_search_test.rb +0 -232
  279. data/lib/davinci_crd_test_kit/client_tests/client_fhir_api_update_test.rb +0 -42
  280. data/lib/davinci_crd_test_kit/client_tests/client_fhir_api_validation_test.rb +0 -61
  281. data/lib/davinci_crd_test_kit/client_tests/client_order_dispatch_group.rb +0 -79
  282. data/lib/davinci_crd_test_kit/client_tests/client_order_select_group.rb +0 -82
  283. data/lib/davinci_crd_test_kit/client_tests/client_order_sign_group.rb +0 -81
  284. data/lib/davinci_crd_test_kit/client_tests/client_registration_verification_test.rb +0 -88
  285. data/lib/davinci_crd_test_kit/client_tests/decode_auth_token_test.rb +0 -60
  286. data/lib/davinci_crd_test_kit/client_tests/encounter_discharge_receive_request_test.rb +0 -90
  287. data/lib/davinci_crd_test_kit/client_tests/encounter_start_receive_request_test.rb +0 -90
  288. data/lib/davinci_crd_test_kit/client_tests/hook_request_optional_fields_test.rb +0 -57
  289. data/lib/davinci_crd_test_kit/client_tests/hook_request_required_fields_test.rb +0 -49
  290. data/lib/davinci_crd_test_kit/client_tests/hook_request_valid_context_test.rb +0 -68
  291. data/lib/davinci_crd_test_kit/client_tests/hook_request_valid_prefetch_test.rb +0 -69
  292. data/lib/davinci_crd_test_kit/client_tests/order_dispatch_receive_request_test.rb +0 -102
  293. data/lib/davinci_crd_test_kit/client_tests/order_select_receive_request_test.rb +0 -98
  294. data/lib/davinci_crd_test_kit/client_tests/order_sign_receive_request_test.rb +0 -101
  295. data/lib/davinci_crd_test_kit/client_tests/retrieve_jwks_test.rb +0 -105
  296. data/lib/davinci_crd_test_kit/client_tests/submitted_response_validation.rb +0 -48
  297. data/lib/davinci_crd_test_kit/client_tests/token_header_test.rb +0 -65
  298. data/lib/davinci_crd_test_kit/client_tests/token_payload_test.rb +0 -78
  299. data/lib/davinci_crd_test_kit/crd_client_suite.rb +0 -193
  300. data/lib/davinci_crd_test_kit/crd_options.rb +0 -9
  301. data/lib/davinci_crd_test_kit/crd_server_suite.rb +0 -125
  302. data/lib/davinci_crd_test_kit/igs/davinci-crd-2.0.1.tgz +0 -0
  303. data/lib/davinci_crd_test_kit/routes/cds_services_discovery_handler.rb +0 -18
  304. data/lib/davinci_crd_test_kit/routes/hook_request_endpoint.rb +0 -77
  305. data/lib/davinci_crd_test_kit/routes/jwk_set_endpoint_handler.rb +0 -15
  306. data/lib/davinci_crd_test_kit/server_appointment_book_group.rb +0 -176
  307. data/lib/davinci_crd_test_kit/server_demonstrate_hook_response_group.rb +0 -77
  308. data/lib/davinci_crd_test_kit/server_discovery_group.rb +0 -60
  309. data/lib/davinci_crd_test_kit/server_encounter_discharge_group.rb +0 -170
  310. data/lib/davinci_crd_test_kit/server_encounter_start_group.rb +0 -170
  311. data/lib/davinci_crd_test_kit/server_hooks_group.rb +0 -71
  312. data/lib/davinci_crd_test_kit/server_order_dispatch_group.rb +0 -176
  313. data/lib/davinci_crd_test_kit/server_order_select_group.rb +0 -195
  314. data/lib/davinci_crd_test_kit/server_order_sign_group.rb +0 -201
  315. data/lib/davinci_crd_test_kit/server_required_card_response_validation_group.rb +0 -26
  316. data/lib/davinci_crd_test_kit/server_tests/additional_orders_validation_test.rb +0 -68
  317. data/lib/davinci_crd_test_kit/server_tests/card_optional_fields_validation_test.rb +0 -47
  318. data/lib/davinci_crd_test_kit/server_tests/coverage_information_system_action_across_hooks_validation_test.rb +0 -32
  319. data/lib/davinci_crd_test_kit/server_tests/coverage_information_system_action_received_test.rb +0 -63
  320. data/lib/davinci_crd_test_kit/server_tests/coverage_information_system_action_validation_test.rb +0 -118
  321. data/lib/davinci_crd_test_kit/server_tests/create_or_update_coverage_info_response_validation_test.rb +0 -71
  322. data/lib/davinci_crd_test_kit/server_tests/discovery_endpoint_test.rb +0 -88
  323. data/lib/davinci_crd_test_kit/server_tests/discovery_services_validation_test.rb +0 -65
  324. data/lib/davinci_crd_test_kit/server_tests/external_reference_card_across_hooks_validation_test.rb +0 -28
  325. data/lib/davinci_crd_test_kit/server_tests/external_reference_card_validation_test.rb +0 -36
  326. data/lib/davinci_crd_test_kit/server_tests/form_completion_response_validation_test.rb +0 -78
  327. data/lib/davinci_crd_test_kit/server_tests/instructions_card_received_across_hooks_test.rb +0 -25
  328. data/lib/davinci_crd_test_kit/server_tests/instructions_card_received_test.rb +0 -26
  329. data/lib/davinci_crd_test_kit/server_tests/launch_smart_app_card_validation_test.rb +0 -38
  330. data/lib/davinci_crd_test_kit/server_tests/propose_alternate_request_card_validation_test.rb +0 -63
  331. data/lib/davinci_crd_test_kit/server_tests/service_call_test.rb +0 -101
  332. data/lib/davinci_crd_test_kit/server_tests/service_request_context_validation_test.rb +0 -28
  333. data/lib/davinci_crd_test_kit/server_tests/service_request_optional_fields_validation_test.rb +0 -37
  334. data/lib/davinci_crd_test_kit/server_tests/service_request_required_fields_validation_test.rb +0 -38
  335. data/lib/davinci_crd_test_kit/server_tests/service_response_validation_test.rb +0 -81
  336. data/lib/davinci_crd_test_kit/tags.rb +0 -10
  337. data/lib/davinci_crd_test_kit/urls.rb +0 -52
  338. /data/lib/davinci_crd_test_kit/{card_responses → client/endpoints/mocked_card_responses}/external_reference.json +0 -0
  339. /data/lib/davinci_crd_test_kit/{card_responses → client/endpoints/mocked_card_responses}/instructions.json +0 -0
  340. /data/lib/davinci_crd_test_kit/{crd_jwks.json → server/endpoints/crd_jwks.json} +0 -0
  341. /data/lib/davinci_crd_test_kit/{jwks.rb → server/endpoints/jwks.rb} +0 -0
@@ -0,0 +1,39 @@
1
+ require_relative '../../server_hook_request_validation'
2
+ require_relative '../../server_hook_helper'
3
+
4
+ module DaVinciCRDTestKit
5
+ module V221
6
+ class ServiceRequestOptionalFieldsValidationTest < Inferno::Test
7
+ include DaVinciCRDTestKit::ServerHookRequestValidation
8
+ include DaVinciCRDTestKit::ServerHookHelper
9
+
10
+ title 'Service request optional fields are valid'
11
+ id :crd_v221_service_request_optional_fields_validation
12
+ description %(
13
+ This optional test reviews the user-submitted CRD service requests for the presence of optional fields:
14
+ `fhirAuthorization` and `prefetch`.
15
+
16
+ The test will not fail if these optional fields are missing from a service request; instead, it generates an
17
+ informational message.
18
+ )
19
+ optional
20
+
21
+ run do
22
+ load_tagged_requests(tested_hook_name)
23
+ skip_if requests.empty?, "No #{tested_hook_name} request was made in a previous test as expected."
24
+
25
+ requests.each_with_index do |request, index|
26
+ @request_number = index + 1
27
+ request_body = json_parse(request.request_body)
28
+ if request_body.blank?
29
+ add_message('error', "#{request_number}Hook request body cannot be empty.")
30
+ next
31
+ end
32
+
33
+ hook_request_optional_fields_check(request_body, ig_version: 'v221')
34
+ end
35
+ no_error_validation('Some service requests have invalid optional fields.')
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,40 @@
1
+ require_relative '../../server_hook_request_validation'
2
+ require_relative '../../server_hook_helper'
3
+
4
+ module DaVinciCRDTestKit
5
+ module V221
6
+ class ServiceRequestRequiredFieldsValidationTest < Inferno::Test
7
+ include DaVinciCRDTestKit::ServerHookRequestValidation
8
+ include DaVinciCRDTestKit::ServerHookHelper
9
+
10
+ title 'Service requests contain required fields'
11
+ id :crd_v221_service_request_required_fields_validation
12
+ description %(
13
+ This test validates all CRD service requests provided by the user, ensuring each includes all required fields
14
+ specified in the [CDS Hooks spec section on Calling a CDS Service](https://cds-hooks.hl7.org/2.0/#calling-a-cds-service):
15
+ `hook`, `hookInstance`, and `context`. Furthermore, the test checks for the conditional presence of the
16
+ `fhirServer` field if `fhirAuthorization` is included.
17
+ )
18
+ input :invoked_hook
19
+ output :contexts
20
+
21
+ run do
22
+ load_tagged_requests(tested_hook_name)
23
+ skip_if requests.empty?, "No #{tested_hook_name} request was made in a previous test as expected."
24
+ contexts = []
25
+ requests.each_with_index do |request, index|
26
+ @request_number = index + 1
27
+ request_body = json_parse(request.request_body)
28
+ next if request_body.blank?
29
+
30
+ contexts << request_body['context'] if request_body['context'].is_a?(Hash)
31
+ hook_request_required_fields_check(request_body, invoked_hook, ig_version: 'v221')
32
+ end
33
+
34
+ output contexts: contexts.to_json
35
+
36
+ no_error_validation('Some service requests made are not valid.')
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,66 @@
1
+ require_relative '../../server_test_helper'
2
+ require_relative '../../server_hook_helper'
3
+ require_relative '../../../cross_suite/suggestion_actions_validation'
4
+ require_relative '../../../cross_suite/cards_identification'
5
+ require_relative '../../../cross_suite/cards_validation'
6
+
7
+ module DaVinciCRDTestKit
8
+ module V221
9
+ class AdditionalOrdersValidationTest < Inferno::Test
10
+ include DaVinciCRDTestKit::ServerTestHelper
11
+ include DaVinciCRDTestKit::SuggestionActionsValidation
12
+ include DaVinciCRDTestKit::ServerHookHelper
13
+ include DaVinciCRDTestKit::CardsIdentification
14
+ include DaVinciCRDTestKit::CardsValidation
15
+
16
+ title 'Additional Orders cards are valid'
17
+ id :crd_v221_additional_orders_card_validation
18
+ description %(
19
+ This test validates that an [Additional Orders as companions/prerequisites](https://hl7.org/fhir/us/davinci-crd/STU2/cards.html#identify-additional-orders-as-companionsprerequisites-for-current-order)
20
+ card was received. It does so by:
21
+ - Filtering cards with the following criteria:
22
+ - For each suggestion in the card's suggestions array, all actions have a type of 'create'
23
+ and the action's resource type is one of the expected types: CommunicationRequest, Device,
24
+ DeviceRequest, Medication, MedicationRequest, NutritionOrder, ServiceRequest, or VisionPrescription.
25
+ - Then, for each valid Additional Orders card retrieved, verifying that each action within the
26
+ card's suggestions complies with their respective profiles as specified in the
27
+ [CRD IG section on Additional Orders as companions/prerequisites](https://hl7.org/fhir/us/davinci-crd/STU2/cards.html#identify-additional-orders-as-companionsprerequisites-for-current-order):
28
+ - [crd-profile-communicationrequest](https://hl7.org/fhir/us/davinci-crd/STU2/StructureDefinition-profile-communicationrequest.html)
29
+ - [crd-profile-device](https://hl7.org/fhir/us/davinci-crd/STU2/StructureDefinition-profile-device.html)
30
+ - [crd-profile-deviceRequest](https://hl7.org/fhir/us/davinci-crd/STU2/StructureDefinition-profile-devicerequest.html)
31
+ - [us-core-medication](http://hl7.org/fhir/us/core/STU3.1.1/StructureDefinition-us-core-medication.html)
32
+ - [crd-profile-medicationRequest](https://hl7.org/fhir/us/davinci-crd/STU2/StructureDefinition-profile-medicationrequest.html)
33
+ - [crd-profile-nutritionOrder](https://hl7.org/fhir/us/davinci-crd/STU2/StructureDefinition-profile-nutritionorder.html)
34
+ - [crd-profile-serviceRequest](https://hl7.org/fhir/us/davinci-crd/STU2/StructureDefinition-profile-servicerequest.html)
35
+ - [crd-profile-visionPrescription](https://hl7.org/fhir/us/davinci-crd/STU2/StructureDefinition-profile-visionprescription.html).
36
+
37
+ The test will skip if no Additional Orders cards are found.
38
+ )
39
+
40
+ verifies_requirements 'hl7.fhir.us.davinci-crd_2.2.1@resp-57',
41
+ 'hl7.fhir.us.davinci-crd_2.2.1@resp-58'
42
+
43
+ optional
44
+ input :valid_cards_with_suggestions
45
+
46
+ run do
47
+ parsed_cards = parse_json(valid_cards_with_suggestions)
48
+ additional_orders_cards = parsed_cards.filter do |card|
49
+ additional_orders_response_type?(card)
50
+ end
51
+ skip_if additional_orders_cards.blank?,
52
+ "#{tested_hook_name} hook response does not include Additional Orders as companion/prerequisite cards."
53
+
54
+ additional_orders_cards.each do |card|
55
+ card['suggestions'].each do |suggestion|
56
+ actions_check(suggestion['actions'], ig_version: 'v221')
57
+ end
58
+
59
+ additional_orders_check(card)
60
+ end
61
+
62
+ no_error_validation('Some Additional Order cards are not valid. See messages for more information.')
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,123 @@
1
+ require_relative '../../server_test_helper'
2
+ require_relative '../../server_hook_helper'
3
+ require_relative '../../../cross_suite/cards_identification'
4
+ require_relative '../../../cross_suite/profiles_and_resource_types'
5
+
6
+ module DaVinciCRDTestKit
7
+ module V221
8
+ class AllResponsesIncludeCoverageInformationTest < Inferno::Test
9
+ include DaVinciCRDTestKit::ServerTestHelper
10
+ include DaVinciCRDTestKit::ServerHookHelper
11
+ include DaVinciCRDTestKit::CardsIdentification
12
+
13
+ title 'Hook responses include Coverage Information system actions'
14
+ id :crd_v221_all_responses_include_coverage_information
15
+ description %(
16
+ This test validates that a [Coverage
17
+ Information](https://hl7.org/fhir/us/davinci-crd/2.2.1/en/cards.html#coverage-information-response-type)
18
+ system action was returned for every hook call, unless the resource
19
+ which is the focus of the hook call already includes a
20
+ [coverage-information
21
+ extension](https://hl7.org/fhir/us/davinci-crd/2.2.1/en/StructureDefinition-ext-coverage-information.html).
22
+ It does so by:
23
+ - First checking for the presence of actions with a `resource` element
24
+ of the following types:
25
+ - For `appointment-book`: Appointment
26
+ - For `order-sign` or `order-dispatch`: CommunicationRequest,
27
+ DeviceRequest, MedicationRequest, NutritionOrder, ServiceRequest, or
28
+ VisionPrescription
29
+ - Then, checking whether each resource contains the coverage-information extension
30
+ - Finally verifying that the response to each hook call where the
31
+ resource did not contain a coverage-information extension includes
32
+ coverage information system action
33
+ )
34
+
35
+ verifies_requirements 'hl7.fhir.us.davinci-crd_2.2.1@hook-16',
36
+ 'hl7.fhir.us.davinci-crd_2.2.1@resp-28'
37
+
38
+ input :invoked_hook
39
+
40
+ def target_resources
41
+ {
42
+ 'appointment-book' => ['Appointment'],
43
+ 'order-sign' => ProfilesAndResourceTypes::ORDER_RESOURCE_TYPES,
44
+ 'order-dispatch' => ProfilesAndResourceTypes::ORDER_RESOURCE_TYPES,
45
+ 'order-select' => ProfilesAndResourceTypes::ORDER_RESOURCE_TYPES,
46
+ 'encounter-start' => ['Encounter'],
47
+ 'encounter-discharge' => ['Encounter']
48
+ }[tested_hook_name]
49
+ end
50
+
51
+ def hook_bundle_field_name
52
+ {
53
+ 'appointment-book' => 'appointments',
54
+ 'order-sign' => 'draftOrders'
55
+ }[tested_hook_name]
56
+ end
57
+
58
+ def resources_contain_coverage_information_extension?(resources)
59
+ resources.all? do |resource|
60
+ resource.extension&.any? do |extension|
61
+ extension.url == 'http://hl7.org/fhir/us/davinci-crd/StructureDefinition/ext-coverage-information'
62
+ end
63
+ end
64
+ end
65
+
66
+ def order_resources(hook_call_body)
67
+ bundle = FHIR::Bundle.new(hook_call_body.dig('context', hook_bundle_field_name))
68
+ bundle.entry.map(&:resource).select { |resource| target_resources.include? resource.resourceType }
69
+ end
70
+
71
+ run do
72
+ successful_hook_calls_without_coverage_information = 0
73
+ coverage_information_system_actions_received = 0
74
+
75
+ load_tagged_requests(tested_hook_name)
76
+
77
+ requests.each do |request|
78
+ next if request.status != 200
79
+
80
+ hook_call_body = JSON.parse(request.request_body)
81
+
82
+ # TODO: handle when default value for coverage-info is false
83
+ next if hook_call_body.dig('extension', 'davinci-crd.configuration', 'coverage-info') == false
84
+
85
+ resources = order_resources(hook_call_body)
86
+
87
+ next if resources_contain_coverage_information_extension?(resources)
88
+
89
+ successful_hook_calls_without_coverage_information += 1
90
+
91
+ hook_call_response = JSON.parse(request.response_body)
92
+
93
+ system_actions = hook_call_response['systemActions']
94
+
95
+ next if system_actions.blank?
96
+
97
+ system_actions_resources =
98
+ system_actions
99
+ .select { |action| action['type'] == 'update' }
100
+ .select { |action| target_resources.include? action['resource']['resourceType'] }
101
+ .map { |action| FHIR.from_contents(action['resource'].to_json) }
102
+
103
+ next unless resources_contain_coverage_information_extension?(system_actions_resources)
104
+
105
+ coverage_information_system_actions_received += 1
106
+ rescue JSON::ParserError => e
107
+ warning(e.message)
108
+ next
109
+ end
110
+
111
+ skip_if successful_hook_calls_without_coverage_information.zero?,
112
+ 'No successful hook calls were made with resources which did not already ' \
113
+ 'contain a coverage-information extension.'
114
+
115
+ assert successful_hook_calls_without_coverage_information == coverage_information_system_actions_received,
116
+ "#{successful_hook_calls_without_coverage_information} successful hook calls " \
117
+ 'without a coverage-information extension were made, but only ' \
118
+ "#{coverage_information_system_actions_received} of the responses contained " \
119
+ 'a coverage information system action.'
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,57 @@
1
+ require_relative '../../server_test_helper'
2
+ require_relative '../../server_hook_request_validation'
3
+ require_relative '../../../cross_suite/cards_validation'
4
+
5
+ module DaVinciCRDTestKit
6
+ module V221
7
+ class CardOptionalFieldsValidationTest < Inferno::Test
8
+ include DaVinciCRDTestKit::ServerTestHelper
9
+ include DaVinciCRDTestKit::ServerHookRequestValidation
10
+ include DaVinciCRDTestKit::CardsValidation
11
+
12
+ title 'Cards contain valid optional fields'
13
+ id :crd_v221_card_optional_fields_validation
14
+ description %(
15
+ This test checks for the presence and validity of optional fields in a card,
16
+ but only if the card's required fields are valid. As specified in the
17
+ [CDS Hooks specification section on Card Attributes](https://cds-hooks.hl7.org/2.0/#card-attributes),
18
+ the optional fields include `uuid`, `detail`, `suggestions`, `overrideReasons`, and `links`.
19
+
20
+ Additionally, the test validates the presence of the conditional field `selectionBehavior`
21
+ only if the `suggestions` field is present.
22
+ )
23
+ optional
24
+ input :valid_cards
25
+ output :valid_cards_with_links, :valid_cards_with_suggestions
26
+
27
+ verifies_requirements 'hl7.fhir.us.davinci-crd_2.2.1@resp-3',
28
+ 'hl7.fhir.us.davinci-crd_2.2.1@resp-13',
29
+ 'hl7.fhir.us.davinci-crd_2.2.1@resp-18',
30
+ 'hl7.fhir.us.davinci-crd_2.2.1@resp-19',
31
+ 'hl7.fhir.us.davinci-crd_2.2.1@resp-22'
32
+
33
+ def cards_with_suggestions
34
+ @cards_with_suggestions ||= []
35
+ end
36
+
37
+ def cards_with_links
38
+ @cards_with_links ||= []
39
+ end
40
+
41
+ run do
42
+ parsed_cards = parse_json(valid_cards)
43
+ parsed_cards.each do |card|
44
+ if valid_card_with_optionals?(card, 'v221')
45
+ cards_with_links << card if card['links']
46
+ cards_with_suggestions << card if card['suggestions']
47
+ end
48
+ end
49
+
50
+ output valid_cards_with_links: cards_with_links.to_json
51
+ output valid_cards_with_suggestions: cards_with_suggestions.to_json
52
+
53
+ no_error_validation('Some cards with valid required fields have invalid optional fields.')
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,83 @@
1
+ require_relative '../../../cross_suite/cards_identification'
2
+ require_relative '../../server_hook_helper'
3
+ require_relative '../server_urls'
4
+
5
+ module DaVinciCRDTestKit
6
+ module V221
7
+ class CoverageInfoConfigurationTest < Inferno::Test
8
+ include DaVinciCRDTestKit::CardsIdentification
9
+ include DaVinciCRDTestKit::ServerHookHelper
10
+ include DaVinciCRDTestKit::V221::ServerURLs
11
+
12
+ title 'Coverage Information configuration option suppresses coverage-info responses'
13
+ id :crd_v221_coverage_info_configuration
14
+ description %(
15
+ This test checks follow-up hook requests made with
16
+ `extension.davinci-crd.configuration.coverage-info` set to `false` after prior successful hook requests
17
+ returned coverage-info content.
18
+
19
+ CRD Servers SHALL behave in the manner prescribed by supported configuration information received from
20
+ the CRD Client. When `coverage-info` is `false`, responses must not include coverage-info cards or
21
+ coverage-information/form-completion system actions.
22
+ )
23
+
24
+ verifies_requirements 'hl7.fhir.us.davinci-crd_2.2.1@dev-14',
25
+ 'hl7.fhir.us.davinci-crd_2.2.1@resp-28'
26
+
27
+ def coverage_info_message(cards, actions)
28
+ card_summaries = cards.map { |card| card['summary'] }.compact
29
+ action_descriptions = actions.map { |action| action['description'] }.compact
30
+
31
+ 'Coverage-info disabled server response included coverage-info content despite ' \
32
+ "`#{COVERAGE_INFO_CONFIGURATION_CODE}` being set to `false`. " \
33
+ "Cards: #{card_summaries.join(', ')}. System actions: #{action_descriptions.join(', ')}."
34
+ end
35
+
36
+ def primary_hook?
37
+ ['appointment-book', 'order-sign', 'order-dispatch'].include? tested_hook_name
38
+ end
39
+
40
+ def parsed_body(json)
41
+ JSON.parse(json)
42
+ rescue JSON::ParserError
43
+ nil
44
+ end
45
+
46
+ run do
47
+ load_tagged_requests(tested_hook_name, COVERAGE_INFO_DISABLED_TAG)
48
+
49
+ if requests.empty?
50
+ message = "No successful #{tested_hook_name} response contained coverage-info content to suppress."
51
+ if primary_hook?
52
+ skip message
53
+ else
54
+ omit message
55
+ end
56
+ end
57
+
58
+ requests.each do |request|
59
+ unless request.status == 200
60
+ add_message(
61
+ 'error',
62
+ "Coverage-info disabled server request returned HTTP #{request.status}; expected HTTP 200."
63
+ )
64
+ next
65
+ end
66
+
67
+ response_body = parsed_body(request.response_body)
68
+ unless response_body.is_a?(Hash)
69
+ add_message('error', 'Coverage-info disabled server response was not valid JSON.')
70
+ next
71
+ end
72
+
73
+ cards, actions = coverage_info_content(response_body)
74
+ next if cards.empty? && actions.empty?
75
+
76
+ add_message('error', coverage_info_message(cards, actions))
77
+ end
78
+
79
+ assert_no_error_messages('Coverage-info configuration responses were not valid. Check messages for details.')
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,65 @@
1
+ require_relative '../../server_test_helper'
2
+ require_relative '../../server_hook_helper'
3
+ require_relative '../../../cross_suite/cards_identification'
4
+
5
+ module DaVinciCRDTestKit
6
+ module V221
7
+ class CoverageInformationSystemActionReceivedTest < Inferno::Test
8
+ include DaVinciCRDTestKit::ServerTestHelper
9
+ include DaVinciCRDTestKit::ServerHookHelper
10
+ include DaVinciCRDTestKit::CardsIdentification
11
+
12
+ title 'Server returns a Coverage Information system action'
13
+ id :crd_v221_coverage_info_system_action_received
14
+ description %(
15
+ This test validates that a [Coverage Information](https://hl7.org/fhir/us/davinci-crd/STU2/cards.html#coverage-information)
16
+ system action was returned. It does so by:
17
+ - First checking for the presence of actions with a `resource` element of the following types:
18
+ - For `appointment-book`: Appointment
19
+ - For `order-sign` or `order-dispatch`: DeviceRequest, MedicationRequest, NutritionOrder,
20
+ ServiceRequest, or VisionPrescription
21
+ - Then, among the target actions, checking if their resource has the [coverage-information extension](http://hl7.org/fhir/us/davinci-crd/StructureDefinition/ext-coverage-information).
22
+ )
23
+ # verifies_requirements 'hl7.fhir.us.davinci-crd_2.0.1@272', 'hl7.fhir.us.davinci-crd_2.0.1@273',
24
+ # 'hl7.fhir.us.davinci-crd_2.0.1@274', 'hl7.fhir.us.davinci-crd_2.0.1@275',
25
+ # 'hl7.fhir.us.davinci-crd_2.0.1@276', 'hl7.fhir.us.davinci-crd_2.0.1@277'
26
+
27
+ input :valid_system_actions, :invoked_hook
28
+ output :coverage_info
29
+
30
+ def resources_by_hook
31
+ shared_resources = [
32
+ 'DeviceRequest', 'MedicationRequest', 'NutritionOrder',
33
+ 'ServiceRequest', 'VisionPrescription'
34
+ ]
35
+ {
36
+ 'appointment-book' => ['Appointment'],
37
+ 'order-sign' => shared_resources,
38
+ 'order-dispatch' => shared_resources,
39
+ 'order-select' => shared_resources,
40
+ 'encounter-start' => ['Encounter'],
41
+ 'encounter-discharge' => ['Encounter']
42
+ }
43
+ end
44
+
45
+ run do
46
+ parsed_actions = parse_json(valid_system_actions)
47
+ target_resources = resources_by_hook[invoked_hook]
48
+
49
+ target_actions = parsed_actions.select do |action|
50
+ resource = FHIR.from_contents(action['resource'].to_json)
51
+ target_resources.include?(resource&.resourceType)
52
+ end
53
+
54
+ coverage_info_system_actions = target_actions.select do |action|
55
+ coverage_information_response_type?(action)
56
+ end
57
+
58
+ assert coverage_info_system_actions.present?,
59
+ "Coverage Information system action was not returned in the #{tested_hook_name} hook response."
60
+
61
+ output coverage_info: coverage_info_system_actions.to_json
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,184 @@
1
+ require_relative '../../server_hook_request_validation'
2
+ require_relative '../../server_test_helper'
3
+ require_relative '../../server_hook_helper'
4
+ require_relative 'hook_request_resource_resolution'
5
+
6
+ module DaVinciCRDTestKit
7
+ module V221
8
+ class CoverageInformationSystemActionValidationTest < Inferno::Test
9
+ include DaVinciCRDTestKit::ServerHookRequestValidation
10
+ include DaVinciCRDTestKit::ServerTestHelper
11
+ include DaVinciCRDTestKit::ServerHookHelper
12
+ include HookRequestResourceResolution
13
+
14
+ COVERAGE_INFO_EXT_URL = 'http://hl7.org/fhir/us/davinci-crd/StructureDefinition/ext-coverage-information'.freeze
15
+
16
+ title 'Coverage Information system actions are valid'
17
+ id :crd_v221_coverage_info_system_action_validation
18
+ description %(
19
+ This test validates all [Coverage Information](https://hl7.org/fhir/us/davinci-crd/STU2/cards.html#coverage-information)
20
+ system actions received. It verifies the following for each action:
21
+ - The action type is `update`.
22
+ - The resource within the action conforms its respective FHIR profile.
23
+ - The resource does not change any data elements other than adding or modifying
24
+ the `coverage-information` extension.
25
+
26
+ Additionally, the test examines the `coverage-info` extensions within the resource to ensure that:
27
+ - Entries referencing differing coverage have distinct `coverage-assertion-ids` and `satisfied-pa-ids`
28
+ (if present).
29
+ - Entries referencing the same coverage have the same `coverage-assertion-ids` and `satisfied-pa-ids`
30
+ (if present).
31
+ )
32
+
33
+ verifies_requirements 'hl7.fhir.us.davinci-crd_2.2.1@resp-32',
34
+ 'hl7.fhir.us.davinci-crd_2.2.1@resp-37',
35
+ 'hl7.fhir.us.davinci-crd_2.2.1@resp-47',
36
+ 'hl7.fhir.us.davinci-crd_2.2.1@resp-48',
37
+ 'hl7.fhir.us.davinci-crd_2.2.1@resp-52'
38
+
39
+ input :coverage_info
40
+ input :mock_ehr_bundle, optional: true
41
+
42
+ def find_extension_value(extension, url, *properties)
43
+ found_extension = extension.extension.find { |ext| ext.url == url }
44
+ return nil unless found_extension
45
+
46
+ properties.reduce(found_extension) do |current, prop|
47
+ return current unless current.respond_to?(prop)
48
+
49
+ current.send(prop)
50
+ end
51
+ end
52
+
53
+ def extract_and_group_coverage_info(resource)
54
+ resource.extension.each_with_object({}) do |extension, grouped_extensions|
55
+ next unless extension.url == COVERAGE_INFO_EXT_URL
56
+
57
+ coverage_key = find_extension_value(extension, 'coverage', 'valueReference', 'reference')
58
+ grouped_extensions[coverage_key] ||= []
59
+ grouped_extensions[coverage_key] << extension
60
+ end
61
+ end
62
+
63
+ # For the same coverage, ensure coverage-assertion-ids and satisfied-pa-ids are the same.
64
+ # For different coverages, ensure coverage-assertion-ids and satisfied-pa-ids are distinct.
65
+ def multiple_extensions_conformance_check(grouped_coverage_info, resource)
66
+ resource_ref = "#{resource.resourceType}/#{resource.id}"
67
+ assertion_ids_across_coverages = Set.new
68
+ pa_ids_across_coverages = Set.new
69
+
70
+ grouped_coverage_info.each do |coverage, extensions|
71
+ coverage_assertion_ids = collect_extensions_id(extensions, 'coverage-assertion-id', 'valueString').uniq
72
+ satisfied_pa_ids = collect_extensions_id(extensions, 'satisfied-pa-id', 'valueString').uniq.compact
73
+ assert coverage_assertion_ids.length == 1,
74
+ same_coverage_conformance_error_msg(resource_ref, coverage, 'coverage-assertion-ids')
75
+
76
+ assert satisfied_pa_ids.length <= 1,
77
+ same_coverage_conformance_error_msg(resource_ref, coverage, 'satisfied-pa-ids')
78
+
79
+ assertion_id = coverage_assertion_ids.first
80
+ assert !assertion_ids_across_coverages.include?(assertion_id),
81
+ different_coverage_conformance_error_msg(resource_ref, 'coverage-assertion-ids')
82
+ assertion_ids_across_coverages.add(assertion_id)
83
+ pa_id = satisfied_pa_ids.first
84
+ next unless pa_id
85
+
86
+ assert !pa_ids_across_coverages.include?(pa_id),
87
+ different_coverage_conformance_error_msg(resource_ref, 'satisfied-pa-ids')
88
+ pa_ids_across_coverages.add(pa_id)
89
+ end
90
+ end
91
+
92
+ def collect_extensions_id(extensions, url, *properties)
93
+ extensions.map do |extension|
94
+ find_extension_value(extension, url, *properties)
95
+ end
96
+ end
97
+
98
+ def same_coverage_conformance_error_msg(resource_ref, coverage, id_name)
99
+ "#{resource_ref}: extension has multiple repetitions of coverage `#{coverage}` with different #{id_name}."
100
+ end
101
+
102
+ def different_coverage_conformance_error_msg(resource_ref, id_name)
103
+ "#{resource_ref}: extensions referencing differing coverage SHALL have distinct #{id_name}."
104
+ end
105
+
106
+ def normalize_value(value)
107
+ case value
108
+ when Hash
109
+ value.transform_values { |child| normalize_value(child) }
110
+ when Array
111
+ value.map { |child| normalize_value(child) }.sort_by(&:to_json)
112
+ else
113
+ value
114
+ end
115
+ end
116
+
117
+ def strip_coverage_info_extensions(resource_hash)
118
+ normalized_hash = resource_hash.deep_dup
119
+ return normalized_hash unless normalized_hash['extension'].is_a?(Array)
120
+
121
+ normalized_hash['extension'] = normalized_hash['extension'].reject do |extension|
122
+ extension['url'] == COVERAGE_INFO_EXT_URL
123
+ end
124
+ normalized_hash.delete('extension') if normalized_hash['extension'].empty?
125
+ normalized_hash
126
+ end
127
+
128
+ def verify_only_coverage_info_changed(action)
129
+ request = matching_request_for_action(action)
130
+ source_resource = find_action_source_resource(action, request)
131
+ updated_resource_hash = action['resource']
132
+ resource_ref = "#{updated_resource_hash['resourceType']}/#{updated_resource_hash['id']}"
133
+ unless source_resource
134
+ messages << {
135
+ type: 'warning',
136
+ message: 'Inferno could not resolve the original source resource for Coverage Information systemAction ' \
137
+ "targeting #{resource_ref}, so it could not verify that only coverage-information extensions " \
138
+ 'were changed.'
139
+ }
140
+ return
141
+ end
142
+
143
+ source_resource_hash = source_resource.to_hash
144
+
145
+ source_without_coverage_info = normalize_value(strip_coverage_info_extensions(source_resource_hash))
146
+ updated_without_coverage_info = normalize_value(strip_coverage_info_extensions(updated_resource_hash))
147
+
148
+ assert source_without_coverage_info == updated_without_coverage_info,
149
+ "#{resource_ref}: resource content changed outside the coverage-information extension."
150
+ end
151
+
152
+ def coverage_info_system_action_check(coverage_info_system_action)
153
+ type = coverage_info_system_action['type']
154
+ assert type, '`type` field is missing.'
155
+ assert type == 'update', "`type` must be `update`, but was `#{type}`"
156
+
157
+ resource = FHIR.from_contents(coverage_info_system_action['resource'].to_json)
158
+ profile_url = structure_definition_map('v221')[resource.resourceType]
159
+ resource_is_valid?(resource:, profile_url:)
160
+
161
+ grouped_coverage_info = extract_and_group_coverage_info(resource)
162
+ multiple_extensions_conformance_check(grouped_coverage_info, resource)
163
+ verify_only_coverage_info_changed(coverage_info_system_action)
164
+ end
165
+
166
+ run do
167
+ load_tagged_requests(tested_hook_name)
168
+ parsed_coverage_info = parse_json(coverage_info)
169
+ error_messages = []
170
+ parsed_coverage_info.each do |action|
171
+ coverage_info_system_action_check(action)
172
+ rescue Inferno::Exceptions::AssertionException => e
173
+ error_messages << "Coverage Info system action `#{action}`: #{e.message}"
174
+ end
175
+
176
+ error_messages.each do |msg|
177
+ messages << { type: 'error', message: msg }
178
+ end
179
+
180
+ assert_no_error_messages 'Some Coverage Info system actions are not valid.'
181
+ end
182
+ end
183
+ end
184
+ end