davinci_crd_test_kit 0.12.2 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 +59 -2
  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 +308 -101
  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 -75
  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 -41
  277. data/lib/davinci_crd_test_kit/client_tests/client_fhir_api_read_test.rb +0 -39
  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 -41
  280. data/lib/davinci_crd_test_kit/client_tests/client_fhir_api_validation_test.rb +0 -60
  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 -44
  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 -185
  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
@@ -1,9 +1,9 @@
1
- require_relative 'server_hook_request_validation'
1
+ require_relative 'hook_request_field_validation'
2
2
  require_relative 'suggestion_actions_validation'
3
3
 
4
4
  module DaVinciCRDTestKit
5
5
  module CardsValidation
6
- include DaVinciCRDTestKit::ServerHookRequestValidation
6
+ include DaVinciCRDTestKit::HookRequestFieldValidation
7
7
  include DaVinciCRDTestKit::SuggestionActionsValidation
8
8
 
9
9
  HOOKS = [
@@ -12,7 +12,18 @@ module DaVinciCRDTestKit
12
12
  ].freeze
13
13
 
14
14
  def card_required_fields
15
- { 'summary' => String, 'indicator' => String, 'source' => Hash }
15
+ {
16
+ 'v221' => {
17
+ 'uuid' => String,
18
+ 'summary' => String,
19
+ 'source' => Hash
20
+ },
21
+ 'v201' => {
22
+ 'indicator' => String,
23
+ 'summary' => String,
24
+ 'source' => Hash
25
+ }
26
+ }
16
27
  end
17
28
 
18
29
  def source_required_fields
@@ -25,11 +36,22 @@ module DaVinciCRDTestKit
25
36
 
26
37
  def card_optional_fields
27
38
  {
28
- 'uuid' => String,
29
- 'detail' => String,
30
- 'suggestions' => Array,
31
- 'overrideReasons' => Array,
32
- 'links' => Array
39
+ 'v221' => {
40
+ 'detail' => String,
41
+ 'indicator' => String,
42
+ 'suggestions' => Array,
43
+ 'selectionBehavior' => String,
44
+ 'overrideReasons' => Array,
45
+ 'links' => Array
46
+ },
47
+ 'v201' => {
48
+ 'detail' => String,
49
+ 'uuid' => String,
50
+ 'suggestions' => Array,
51
+ 'selectionBehavior' => String,
52
+ 'overrideReasons' => Array,
53
+ 'links' => Array
54
+ }
33
55
  }
34
56
  end
35
57
 
@@ -41,12 +63,12 @@ module DaVinciCRDTestKit
41
63
  { 'label' => String, 'type' => String, 'url' => 'URL' }
42
64
  end
43
65
 
44
- def valid_card_with_optionals?(card)
66
+ def valid_card_with_optionals?(card, version)
45
67
  current_error_count = messages.count { |msg| msg[:type] == 'error' }
46
- card_optional_fields.each do |field, type|
68
+ card_optional_fields[version].each do |field, type|
47
69
  next unless card[field]
48
70
 
49
- validate_presence_and_type(card, field, type, 'Card')
71
+ validate_presence_and_type(card, field, type, 'Card', required: false)
50
72
  end
51
73
 
52
74
  card_selection_behavior_check(card)
@@ -84,32 +106,83 @@ module DaVinciCRDTestKit
84
106
  end
85
107
  end
86
108
 
87
- def card_links_check(card)
109
+ def card_links_check(card) # rubocop:disable Metrics/CyclomaticComplexity
88
110
  return unless card['links'].is_a?(Array) && card['links'].present?
89
111
 
90
112
  card['links'].each do |link|
91
113
  link_required_fields.each do |field, type|
92
114
  validate_presence_and_type(link, field, type, 'Link')
93
115
  end
116
+ end
94
117
 
95
- card_link_type_check(card, link)
118
+ if card['links'].all? { |link| link['type'] == 'absolute' }
119
+ external_reference_card_check(card)
120
+ elsif card['links'].all? { |link| link['type'] == 'smart' }
121
+ smart_app_card_check(card)
122
+ else
123
+ add_message(
124
+ 'error',
125
+ "All links must either be `absolute` or `smart` in card: #{card}"
126
+ )
96
127
  end
97
128
  end
98
129
 
99
- def card_link_type_check(card, link)
100
- return unless link['type']
130
+ def external_reference_card_check(card)
131
+ if card['suggestions'].present?
132
+ add_message(
133
+ 'error',
134
+ "Cards with `absolute` links must not contain suggestions. In card `#{card}`"
135
+ )
136
+ end
101
137
 
102
- unless ['absolute', 'smart'].include?(link['type'])
103
- add_message('error',
104
- "`Link.type` must be `absolute` or `smart`. Got `#{link['type']}`: `#{link}`. In Card `#{card}`")
105
- return
138
+ card['links'].each do |link|
139
+ next if link['appContext'].blank?
140
+
141
+ add_message(
142
+ 'error',
143
+ '`appContext` field must not be present if the link type is absolute: ' \
144
+ "`#{link}`. In Card `#{card}`"
145
+ )
106
146
  end
147
+ end
107
148
 
108
- return unless link['type'] == 'absolute' && link['appContext'].present?
149
+ def smart_app_card_check(card)
150
+ if card['suggestions'].blank?
151
+ add_message(
152
+ 'error',
153
+ "Cards with `smart` links must contain at least one suggestion. In card `#{card}`"
154
+ )
155
+ elsif card['suggestions'].any? { |suggestion| suggestion['actions'].present? }
156
+ add_message(
157
+ 'error',
158
+ "Cards with `smart` links must not contain any suggestion actions. In card `#{card}`"
159
+ )
160
+ end
161
+ end
109
162
 
110
- msg = '`appContext` field should only be valued if the link type is smart and is not valid for absolute links: ' \
111
- "`#{link}`. In Card `#{card}`"
112
- add_message('error', msg)
163
+ def no_links_check(card, card_type)
164
+ return unless card['links'].present?
165
+
166
+ add_message(
167
+ 'error',
168
+ "#{card_type} response must not contain links. In card: `#{card}`"
169
+ )
170
+ end
171
+
172
+ def additional_orders_check(card)
173
+ no_links_check(card, 'Additional Orders')
174
+ end
175
+
176
+ def create_or_update_coverage_check(card)
177
+ no_links_check(card, 'Update Coverage Records')
178
+ end
179
+
180
+ def form_completion_check(card)
181
+ no_links_check(card, 'Form Completion')
182
+ end
183
+
184
+ def propose_alternate_request_check(card)
185
+ no_links_check(card, 'Propose Alternate Request')
113
186
  end
114
187
 
115
188
  def card_suggestions_check(card)
@@ -122,6 +195,7 @@ module DaVinciCRDTestKit
122
195
 
123
196
  def process_suggestion(card, suggestion)
124
197
  validate_presence_and_type(suggestion, 'label', String, 'Suggestion')
198
+ validate_presence_and_type(suggestion, 'uuid', String, 'Suggestion')
125
199
  return unless suggestion['actions']
126
200
 
127
201
  validate_and_process_actions(card, suggestion)
@@ -166,7 +240,7 @@ module DaVinciCRDTestKit
166
240
  def card_summary_check(card)
167
241
  return if !card['summary'].is_a?(String) || card['summary'].length < 140
168
242
 
169
- add_message('error', "`summary` is over the 140-character limit: `#{card}`")
243
+ add_message('error', "`summary` is over the 140-character limit: `#{card['summary']}`")
170
244
  end
171
245
 
172
246
  def card_indicator_check(card)
@@ -176,10 +250,10 @@ module DaVinciCRDTestKit
176
250
  add_message('error', msg)
177
251
  end
178
252
 
179
- def cards_check(cards)
253
+ def cards_check(cards, version = 'v221')
180
254
  cards.each do |card|
181
255
  current_error_count = messages.count { |msg| msg[:type] == 'error' }
182
- card_required_fields.each do |field, type|
256
+ card_required_fields[version].each do |field, type|
183
257
  validate_presence_and_type(card, field, type, 'Card')
184
258
  end
185
259
 
@@ -195,7 +269,7 @@ module DaVinciCRDTestKit
195
269
  "Server response #{index}"
196
270
  end
197
271
 
198
- def perform_cards_validation(cards, response_index = 0)
272
+ def perform_cards_validation(cards, response_has_system_actions, version, response_index)
199
273
  unless cards
200
274
  add_message('error', "#{response_label(response_index + 1)} did not have the `cards` field.")
201
275
  return
@@ -205,9 +279,10 @@ module DaVinciCRDTestKit
205
279
  return
206
280
  end
207
281
  warning do
208
- assert cards.present?, "#{response_label(response_index + 1)} has no decision support."
282
+ assert cards.present? || response_has_system_actions,
283
+ "#{response_label(response_index + 1)} has no decision support."
209
284
  end
210
- cards_check(cards)
285
+ cards_check(cards, version)
211
286
  end
212
287
 
213
288
  def all_requests
@@ -216,23 +291,5 @@ module DaVinciCRDTestKit
216
291
  reqs.concat(requests)
217
292
  end
218
293
  end
219
-
220
- def extract_all_valid_cards_from_hooks_responses
221
- all_requests.keep_if { |request| request.status == 200 }
222
- all_requests.each_with_index do |request, index|
223
- service_response = JSON.parse(request.response_body)
224
- perform_cards_validation(service_response['cards'], index)
225
- rescue JSON::ParserError
226
- add_message('error', "Invalid JSON: #{response_label(response_index + 1).downcase} is not a valid JSON.")
227
- end
228
- end
229
-
230
- def extract_valid_cards_with_links_from_hooks_responses
231
- extract_all_valid_cards_from_hooks_responses
232
-
233
- valid_cards.each do |card|
234
- valid_cards_with_links << card if valid_card_with_optionals?(card) && (card['links'])
235
- end
236
- end
237
294
  end
238
295
  end
@@ -0,0 +1,27 @@
1
+ ---
2
+ :name: coverage_information
3
+ :version: v2.0.1
4
+ :reformatted_version: v201
5
+ :profile_url: http://hl7.org/fhir/us/davinci-crd/StructureDefinition/ext-coverage-information
6
+ :profile_name: "Extension: Coverage Information"
7
+ :profile_version: 2.0.1
8
+ :title: Coverage Information
9
+ :must_supports:
10
+ :extensions:
11
+ - :id: Extension.extension:coverage
12
+ :path: extension
13
+ :url: coverage
14
+ - :id: Extension.extension:covered
15
+ :path: extension
16
+ :url: covered
17
+ - :id: Extension.extension:doc-needed
18
+ :path: extension
19
+ :url: doc-needed
20
+ - :id: Extension.extension:doc-purpose
21
+ :path: extension
22
+ :url: doc-purpose
23
+ - :id: Extension.extension:info-needed
24
+ :path: extension
25
+ :url: info-needed
26
+ :slices:
27
+ :elements:
@@ -0,0 +1,60 @@
1
+ ---
2
+ :name: coverage_information
3
+ :version: v2.2.1
4
+ :reformatted_version: v221
5
+ :profile_url: http://hl7.org/fhir/us/davinci-crd/StructureDefinition/ext-coverage-information
6
+ :profile_name: "Extension: Coverage Information"
7
+ :profile_version: 2.2.1
8
+ :title: Coverage Information
9
+ :must_supports:
10
+ :extensions:
11
+ - :id: Extension.extension:coverage
12
+ :path: extension
13
+ :url: coverage
14
+ - :id: Extension.extension:covered
15
+ :path: extension
16
+ :url: covered
17
+ - :id: Extension.extension:pa-needed
18
+ :path: extension
19
+ :url: pa-needed
20
+ - :id: Extension.extension:doc-needed
21
+ :path: extension
22
+ :url: doc-needed
23
+ - :id: Extension.extension:doc-purpose
24
+ :path: extension
25
+ :url: doc-purpose
26
+ - :id: Extension.extension:info-needed
27
+ :path: extension
28
+ :url: info-needed
29
+ - :id: Extension.extension:billingCode
30
+ :path: extension
31
+ :url: billingCode
32
+ - :id: Extension.extension:reason
33
+ :path: extension
34
+ :url: reason
35
+ - :id: Extension.extension:detail
36
+ :path: extension
37
+ :url: detail
38
+ - :id: Extension.extension:dependency
39
+ :path: extension
40
+ :url: dependency
41
+ - :id: Extension.extension:questionnaire
42
+ :path: extension
43
+ :url: questionnaire
44
+ - :id: Extension.extension:date
45
+ :path: extension
46
+ :url: date
47
+ - :id: Extension.extension:coverage-assertion-id
48
+ :path: extension
49
+ :url: coverage-assertion-id
50
+ - :id: Extension.extension:satisfied-pa-id
51
+ :path: extension
52
+ :url: satisfied-pa-id
53
+ - :id: Extension.extension:contact
54
+ :path: extension
55
+ :url: contact
56
+ - :id: Extension.extension:expiry-date
57
+ :path: extension
58
+ :url: expiry-date
59
+ :slices:
60
+ :elements:
@@ -0,0 +1,177 @@
1
+ require 'date'
2
+ require 'uri'
3
+
4
+ module DaVinciCRDTestKit
5
+ class FhirpathServiceError < StandardError; end
6
+
7
+ # Methods for executing simple fhirpath queries on cds request objects, e.g., to resolve
8
+ # prefetch tokens.
9
+ #
10
+ # If resolve() calls are in scope (CRD 2.2.1 and beyond), then an implementation of the
11
+ # `resolve(target)` method must be provided, where `target` is
12
+ module FhirpathOnCDSRequest
13
+ SUPPORTED_POST_RESOLVE_FUNCTIONS = %w[ofType today resolve].freeze
14
+ TODAY_EXPRESSION_PATTERN = /\Atoday\(\)\s*(?:([+-])\s*(\d+)\s+days)?\z/
15
+
16
+ # fhirpath services doesn't handle the following, which are handled manually
17
+ # - non-fhir objects
18
+ # - resolve()
19
+ # - Bundle.entry.resource when resolve() appears in the remaining query (to track entry.fullUrl per entry)
20
+ # - standalone today() expressions (today(), today()-N, today()+N)
21
+ def execute_fhirpath_on_cds_request(hook_request, fhirpath_query)
22
+ today_result = execute_today_expression(fhirpath_query)
23
+ return today_result if today_result
24
+
25
+ cds_component, remaining_query = identify_cds_component(fhirpath_query)
26
+ execution_targets = cds_component.present? ? get_cds_field(hook_request, cds_component) : hook_request
27
+
28
+ execution_targets.map do |execution_target|
29
+ @current_base_fhir_server = hook_request['fhirServer']
30
+ execute(execution_target, remaining_query)
31
+ end.flatten.compact
32
+ ensure
33
+ # clean-up identity
34
+ @current_base_fhir_server = nil
35
+ end
36
+
37
+ private
38
+
39
+ # -------------------------------------------------------------------------
40
+ # today() handling
41
+ # -------------------------------------------------------------------------
42
+
43
+ def execute_today_expression(fhirpath_query)
44
+ match = fhirpath_query.strip.match(TODAY_EXPRESSION_PATTERN)
45
+ return nil unless match
46
+
47
+ date = Date.today
48
+ if match[1]
49
+ days = match[2].to_i
50
+ date = match[1] == '+' ? date + days : date - days
51
+ end
52
+ [date.to_s]
53
+ end
54
+
55
+ # -------------------------------------------------------------------------
56
+ # resolve() handling
57
+ # -------------------------------------------------------------------------
58
+
59
+ # input is either
60
+ # - string representing a FHIR reference, absolute or relative
61
+ # - a FHIR Reference object with an absolute or relative reference in the `reference` element
62
+ # Default implementation does not perform any resolution
63
+ def resolve(_reference)
64
+ nil
65
+ end
66
+
67
+ # -------------------------------------------------------------------------
68
+ # CDS Request Handling
69
+ # -------------------------------------------------------------------------
70
+
71
+ # returns a pair of [cds component, remaining query]
72
+ def identify_cds_component(fhirpath_query)
73
+ if fhirpath_query.starts_with?('context.')
74
+ context_field, remaining_query = fhirpath_query[8..].split('.', 2)
75
+ ["context.#{context_field}", remaining_query]
76
+ elsif fhirpath_query.starts_with?('%')
77
+ prefetch_key, remaining_query = fhirpath_query[1..].split('.', 2)
78
+ ["prefetch.#{prefetch_key}", remaining_query]
79
+ else
80
+ # everything is in the cds request
81
+ [fhirpath_query, nil]
82
+ end
83
+ end
84
+
85
+ def get_cds_field(request, cds_path)
86
+ value = cds_path.split('.').reduce(request) { |hash, path| hash.present? ? hash[path] : nil }
87
+
88
+ value.is_a?(Array) ? value : [value]
89
+ end
90
+
91
+ # -------------------------------------------------------------------------
92
+ # Main execution loop
93
+ # -------------------------------------------------------------------------
94
+
95
+ def execute(execution_target, fhirpath_query)
96
+ return execution_target unless fhirpath_query.present? && execution_target.present?
97
+
98
+ if fhirpath_query.starts_with?('resolve()')
99
+ execute_resolve(execution_target, fhirpath_query)
100
+ elsif fhirpath_query.starts_with?('entry.resource.') && fhirpath_query.include?('resolve()')
101
+ execute_entry_resource_step(execution_target, fhirpath_query)
102
+ else
103
+ execute_fhirpath_step(execution_target, fhirpath_query)
104
+ end
105
+ end
106
+
107
+ def execute_fhirpath_step(execution_target, fhirpath_query)
108
+ path_to_execute, query_after_next_resolve = fhirpath_query.split('.resolve()', 2)
109
+ remaining_query = "#{'resolve()' if fhirpath_query.include?('resolve()')}#{query_after_next_resolve}"
110
+ delegate_execution_to_fhirpath_engine(execution_target, path_to_execute).compact.map do |result|
111
+ execute(result, remaining_query)
112
+ end.flatten.compact
113
+ end
114
+
115
+ def execute_resolve(execution_target, fhirpath_query)
116
+ referenced = resolve(execution_target)
117
+ return nil unless referenced.present?
118
+
119
+ execute(referenced, fhirpath_query[10..])
120
+ end
121
+
122
+ def execute_entry_resource_step(execution_target, fhirpath_query)
123
+ validate_entry_resource_query!(fhirpath_query)
124
+ return nil unless execution_target['entry'].present?
125
+
126
+ Array.wrap(execution_target['entry']).map do |entry|
127
+ @current_base_fhir_server = base_fhir_server_for_identity(entry['fullUrl'])
128
+ execute(entry['resource'], fhirpath_query[15..])
129
+ end.flatten.compact
130
+ end
131
+
132
+ def validate_entry_resource_query!(fhirpath_query)
133
+ _, post_resolve = fhirpath_query.split('.resolve()', 2)
134
+ return unless post_resolve.present?
135
+
136
+ unsupported = post_resolve.scan(/[a-zA-Z_]\w*(?=\()/).uniq - SUPPORTED_POST_RESOLVE_FUNCTIONS
137
+ return if unsupported.empty?
138
+
139
+ raise FhirpathServiceError,
140
+ "Unsupported function(s) after resolve() in '#{fhirpath_query}': #{unsupported.join(', ')}. " \
141
+ "Supported: #{SUPPORTED_POST_RESOLVE_FUNCTIONS.join(', ')}."
142
+ end
143
+
144
+ def base_fhir_server_for_identity(current_resource_identity)
145
+ return nil unless current_resource_identity.present?
146
+
147
+ parsed_identity = URI.parse(current_resource_identity)
148
+ return nil unless ['http', 'https'].include?(parsed_identity.scheme)
149
+
150
+ current_resource_identity.split('/')[0..-3].join('/')
151
+ rescue URI::InvalidURIError
152
+ nil
153
+ end
154
+
155
+ # -------------------------------------------------------------------------
156
+ # fhirpath delegation
157
+ # -------------------------------------------------------------------------
158
+
159
+ def fhirpath_evaluator
160
+ @fhirpath_evaluator ||= Inferno::DSL::FhirpathEvaluation::Evaluator.new
161
+ end
162
+
163
+ def delegate_execution_to_fhirpath_engine(hash, fhirpath_query)
164
+ return [hash] unless fhirpath_query.present?
165
+ return [] unless hash.present?
166
+
167
+ result = fhirpath_evaluator.call_fhirpath_service(hash, fhirpath_query)
168
+ unless result.status.to_s.starts_with?('2')
169
+ raise FhirpathServiceError,
170
+ "FHIRPath service returned #{result.status} for query '#{fhirpath_query}' " \
171
+ "on resource #{hash.to_json}: #{result.body}"
172
+ end
173
+
174
+ JSON.parse(result.body).map { |entry| entry['element'] }
175
+ end
176
+ end
177
+ end