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,274 @@
1
+ require_relative 'cards_identification'
2
+ require_relative 'logical_models_override_helper'
3
+
4
+ module DaVinciCRDTestKit
5
+ module ResponseLogicalModelValidation
6
+ include DaVinciCRDTestKit::CardsIdentification
7
+ include LogicalModelsOverrideHelper
8
+
9
+ CRD_LOGICAL_MODEL_BASE = 'http://hl7.org/fhir/us/davinci-crd/StructureDefinition'.freeze
10
+ CRD_RESPONSE_BASE_LOGICAL_MODEL = 'CRDHooksResponseBase'.freeze
11
+
12
+ CARD_TYPE_TO_LOGICAL_MODEL = {
13
+ DaVinciCRDTestKit::CardsIdentification::ADDITIONAL_ORDERS_RESPONSE_TYPE =>
14
+ 'CRDHooksResponse-additionalOrders',
15
+ DaVinciCRDTestKit::CardsIdentification::CREATE_OR_UPDATE_COVERAGE_RESPONSE_TYPE =>
16
+ 'CRDHooksResponse-adjustCoverage',
17
+ DaVinciCRDTestKit::CardsIdentification::EXTERNAL_REFERENCE_RESPONSE_TYPE =>
18
+ 'CRDHooksResponse-externalReference',
19
+ DaVinciCRDTestKit::CardsIdentification::FORM_COMPLETION_RESPONSE_TYPE =>
20
+ 'CRDHooksResponse-formCompletion',
21
+ DaVinciCRDTestKit::CardsIdentification::INSTRUCTIONS_RESPONSE_TYPE =>
22
+ 'CRDHooksResponse-instructions',
23
+ DaVinciCRDTestKit::CardsIdentification::LAUNCH_SMART_APP_RESPONSE_TYPE =>
24
+ 'CRDHooksResponse-launchSMART',
25
+ DaVinciCRDTestKit::CardsIdentification::PROPOSE_ALTERNATIVE_REQUEST_RESPONSE_TYPE =>
26
+ 'CRDHooksResponse-alternateRequest'
27
+ }.freeze
28
+
29
+ ACTION_TYPE_TO_LOGICAL_MODEL = {
30
+ DaVinciCRDTestKit::CardsIdentification::COVERAGE_INFORMATION_RESPONSE_TYPE =>
31
+ 'CRDHooksResponse-coverageInformation',
32
+ DaVinciCRDTestKit::CardsIdentification::CREATE_OR_UPDATE_COVERAGE_RESPONSE_TYPE =>
33
+ 'CRDHooksResponse-adjustCoverage',
34
+ DaVinciCRDTestKit::CardsIdentification::FORM_COMPLETION_RESPONSE_TYPE =>
35
+ 'CRDHooksResponse-formCompletion'
36
+ }.freeze
37
+
38
+ def logical_model_url(profile_name)
39
+ "#{CRD_LOGICAL_MODEL_BASE}/#{profile_name}"
40
+ end
41
+
42
+ def perform_response_logical_model_validation(cards, system_actions, request_body, response_index, ig_semver)
43
+ if cards.is_a?(Array)
44
+ cards.each_with_index do |card, card_index|
45
+ validate_card_against_logical_model(card, response_index, request_body, card_index, ig_semver)
46
+ end
47
+ end
48
+
49
+ return unless system_actions.is_a?(Array)
50
+
51
+ system_actions.each_with_index do |action, action_index|
52
+ validate_system_action_against_logical_model(action, response_index, request_body, action_index, ig_semver)
53
+ end
54
+ end
55
+
56
+ def validate_card_against_logical_model(card, response_index, request_body, card_index, ig_semver)
57
+ label = logical_model_entity_label(response_index, card_index, 'card')
58
+ unless card.is_a?(Hash)
59
+ add_message('error', "#{label} is not a JSON object; skipping logical model validation.")
60
+ return
61
+ end
62
+
63
+ card_type = identify_card_type(card)
64
+ profile_name = CARD_TYPE_TO_LOGICAL_MODEL[card_type]
65
+ unless profile_name
66
+ add_message('warning',
67
+ "#{label} could not be categorized as a known CRD response type; " \
68
+ 'validating against the base CRD response logical model.')
69
+ profile_name = CRD_RESPONSE_BASE_LOGICAL_MODEL
70
+ end
71
+
72
+ validation_issues = []
73
+ conforms_to_logical_model?({ 'cards' => [card] }, logical_model_url(profile_name),
74
+ add_messages_to_runnable: false, validator_response_details: validation_issues)
75
+
76
+ error_prefix = "#{label} (#{card_type || 'uncategorized'}): "
77
+ filtered_issues = manually_check_card_specific_errors(card, validation_issues, card_type,
78
+ request_body, error_prefix, ig_semver)
79
+ add_messages_not_excluded(filtered_issues, error_prefix)
80
+ end
81
+
82
+ def validate_system_action_against_logical_model(action, response_index, request_body, action_index, ig_semver)
83
+ label = logical_model_entity_label(response_index, action_index, 'systemAction')
84
+ unless action.is_a?(Hash)
85
+ add_message('error', "#{label} is not a JSON object; skipping logical model validation.")
86
+ return
87
+ end
88
+
89
+ action_type = identify_action_type(action)
90
+ profile_name = ACTION_TYPE_TO_LOGICAL_MODEL[action_type]
91
+ unless profile_name
92
+ add_message('warning',
93
+ "#{label} could not be categorized as a known CRD response type; " \
94
+ 'validating against the base CRD response logical model.')
95
+ profile_name = CRD_RESPONSE_BASE_LOGICAL_MODEL
96
+ end
97
+ if [DaVinciCRDTestKit::CardsIdentification::CREATE_OR_UPDATE_COVERAGE_RESPONSE_TYPE,
98
+ DaVinciCRDTestKit::CardsIdentification::FORM_COMPLETION_RESPONSE_TYPE]
99
+ .include?(action_type)
100
+ profile_name = CRD_RESPONSE_BASE_LOGICAL_MODEL
101
+ end
102
+
103
+ validation_issues = []
104
+ conforms_to_logical_model?({ 'systemActions' => [action] }, logical_model_url(profile_name),
105
+ add_messages_to_runnable: false, validator_response_details: validation_issues)
106
+
107
+ error_prefix = "#{label} (#{action_type || 'uncategorized'}): "
108
+ filtered_issues = manually_check_action_specific_errors(action, validation_issues, action_type,
109
+ request_body, error_prefix, ig_semver)
110
+ add_messages_not_excluded(filtered_issues, error_prefix)
111
+ end
112
+
113
+ def add_messages_not_excluded(issues, error_prefix)
114
+ issues.each do |issue|
115
+ next if issue.filtered || logical_model_extension_issue?(issue)
116
+
117
+ add_message(issue.severity, "#{error_prefix}#{issue.message}")
118
+ end
119
+ end
120
+
121
+ def logical_model_entity_label(response_index, entity_index, kind)
122
+ "Server response #{response_index + 1}, #{kind} #{entity_index + 1}"
123
+ end
124
+
125
+ # -------------------------------------------------------------------------
126
+ # Validator Filtering and Manual Checks Depending on the Card Type
127
+ # -------------------------------------------------------------------------
128
+
129
+ def logical_model_extension_issue?(issue)
130
+ issue.message.match(/\.extension: Unrecognized property/).present?
131
+ end
132
+
133
+ def manually_check_card_specific_errors(card, validation_issues, card_type, request_body, error_prefix,
134
+ ig_semver)
135
+ case card_type
136
+ when DaVinciCRDTestKit::CardsIdentification::FORM_COMPLETION_RESPONSE_TYPE
137
+ manually_check_form_completion_errors(card, validation_issues, error_prefix)
138
+ when DaVinciCRDTestKit::CardsIdentification::PROPOSE_ALTERNATIVE_REQUEST_RESPONSE_TYPE
139
+ manually_check_propose_alternative_errors(card, validation_issues, request_body,
140
+ error_prefix, ig_semver)
141
+ when DaVinciCRDTestKit::CardsIdentification::ADDITIONAL_ORDERS_RESPONSE_TYPE
142
+ manually_check_additional_orders_errors(card, validation_issues, request_body,
143
+ error_prefix, ig_semver)
144
+ else
145
+ validation_issues
146
+ end
147
+ end
148
+
149
+ def manually_check_action_specific_errors(action, validation_issues, action_type, request_body,
150
+ error_prefix, ig_semver)
151
+ case action_type
152
+ when DaVinciCRDTestKit::CardsIdentification::COVERAGE_INFORMATION_RESPONSE_TYPE
153
+ manually_check_coverage_information_errors(action, validation_issues, request_body,
154
+ error_prefix, ig_semver)
155
+ when DaVinciCRDTestKit::CardsIdentification::CREATE_OR_UPDATE_COVERAGE_RESPONSE_TYPE
156
+ manually_check_update_coverage_action_errors(action, validation_issues,
157
+ error_prefix, ig_semver)
158
+ when DaVinciCRDTestKit::CardsIdentification::FORM_COMPLETION_RESPONSE_TYPE
159
+ manually_check_form_completion_action_errors(action, validation_issues,
160
+ error_prefix, ig_semver)
161
+ else
162
+ validation_issues
163
+ end
164
+ end
165
+
166
+ def manually_check_form_completion_errors(card, validation_issues, error_prefix)
167
+ validation_issues.reject do |issue|
168
+ if issue.message.match?(/The type 'Questionnaire' is not valid - must be Task/)
169
+ check_questionnaire_actions(card, issue.message, error_prefix)
170
+ true
171
+ else
172
+ false
173
+ end
174
+ end
175
+ end
176
+
177
+ def check_questionnaire_actions(card, error_message, error_prefix)
178
+ extracted_indexes =
179
+ error_message.match(/CDSHooksResponse\.cards\[0\]\.suggestions\[(\d+)\]\.actions\[(\d+)\]\.resource/)
180
+ unless extracted_indexes
181
+ raise 'Unexpected validator error message format in check_questionnaire_actions: ' \
182
+ "'#{error_message}'. This indicates an implementation problem in the test kit — please log a ticket."
183
+ end
184
+
185
+ suggestion_index = extracted_indexes[1].to_i
186
+ action_index = extracted_indexes[2].to_i
187
+
188
+ message_prefix = "#{error_prefix} suggestion #{suggestion_index + 1}, action #{action_index + 1} - "
189
+ resource = FHIR.from_contents(card['suggestions'][suggestion_index]['actions'][action_index]['resource'].to_json)
190
+ resource_is_valid?(resource:, message_prefix:) # no questionnaire profile applied per CRD
191
+
192
+ return if resource.id.present?
193
+
194
+ add_message('error', "#{message_prefix}Questionnaire must have an id.")
195
+ end
196
+
197
+ def manually_check_propose_alternative_errors(card, validation_issues, request_body,
198
+ error_prefix, ig_semver)
199
+ no_resource_issues = manually_check_action_resources_for_order_profile_conformance(card,
200
+ validation_issues,
201
+ request_body,
202
+ error_prefix,
203
+ ig_semver)
204
+ no_resource_issues.reject do |issue|
205
+ issue.message.match?(/but is fixed to 'create' in the profile/)
206
+ end
207
+ end
208
+
209
+ def manually_check_additional_orders_errors(card, validation_issues, request_body,
210
+ error_prefix, ig_semver)
211
+ manually_check_action_resources_for_order_profile_conformance(card,
212
+ validation_issues,
213
+ request_body,
214
+ error_prefix,
215
+ ig_semver)
216
+ end
217
+
218
+ def manually_check_action_resources_for_order_profile_conformance(card, validation_issues, request_body,
219
+ error_prefix, ig_semver)
220
+ if card['suggestions'].present?
221
+ card['suggestions'].each_with_index do |suggestion, suggestion_index|
222
+ next unless suggestion['actions'].present?
223
+
224
+ suggestion['actions'].each_with_index do |action, action_index|
225
+ action_error_prefix = "#{error_prefix}suggestion #{suggestion_index + 1}, action #{action_index + 1} - "
226
+ check_action_target(action, request_body, action_error_prefix, ig_semver)
227
+ end
228
+ end
229
+ end
230
+
231
+ reject_resource_issues(validation_issues)
232
+ end
233
+
234
+ def check_action_target(action, request_body, error_prefix, ig_semver)
235
+ local_reference?(action['resourceId'], error_prefix) if action['resourceId'].present?
236
+ return unless action['resource'].present?
237
+
238
+ check_resource_conformance_to_order_profile(action['resource'], request_body, error_prefix, ig_semver)
239
+ end
240
+
241
+ def manually_check_coverage_information_errors(action, validation_issues, request_body,
242
+ error_prefix, ig_semver)
243
+ if action['resource'].present?
244
+ check_resource_conformance_to_order_or_encounter_profile(action['resource'], request_body,
245
+ error_prefix, ig_semver)
246
+ end
247
+ reject_resource_issues(validation_issues)
248
+ end
249
+
250
+ def manually_check_update_coverage_action_errors(action, validation_issues,
251
+ error_prefix, ig_semver)
252
+ check_required_action_type(action, 'update', error_prefix, 'coverage update action response type')
253
+ if action['resource'].present?
254
+ check_resource_conformance_to_coverage_profile(action['resource'], error_prefix, ig_semver)
255
+ end
256
+ reject_resource_issues(validation_issues)
257
+ end
258
+
259
+ def manually_check_form_completion_action_errors(action, validation_issues,
260
+ error_prefix, ig_semver)
261
+ check_required_action_type(action, 'create', error_prefix, 'form completion action response type')
262
+ if action['resource'].present?
263
+ check_resource_conformance_to_questionnaire_task_profile(action['resource'], error_prefix, ig_semver)
264
+ end
265
+ reject_resource_issues(validation_issues)
266
+ end
267
+
268
+ def check_required_action_type(action, required_type, error_prefix, description)
269
+ return if action['type'] == required_type
270
+
271
+ add_message('error', "#{error_prefix}action type must be '#{required_type}' for a #{description}.")
272
+ end
273
+ end
274
+ end
@@ -1,21 +1,46 @@
1
- require_relative 'server_hook_request_validation'
1
+ require_relative 'hook_request_field_validation'
2
+
2
3
  module DaVinciCRDTestKit
3
4
  module SuggestionActionsValidation
4
- include DaVinciCRDTestKit::ServerHookRequestValidation
5
-
6
- def action_required_fields
7
- { 'type' => String, 'description' => String }
8
- end
5
+ include HookRequestFieldValidation
9
6
 
10
- def action_fields_validation(action)
7
+ def action_fields_validation(action, ig_version: 'v201')
11
8
  action_required_fields.each do |field, type|
12
9
  validate_presence_and_type(action, field, type, 'Action')
13
10
  end
14
11
 
15
- action_type_field_validation(action)
12
+ action_type_field_validation(action, ig_version:)
13
+ end
14
+
15
+ def actions_check(actions, contexts = nil, ig_version: 'v201')
16
+ create_actions_resource_types = extract_resource_types_by_action(actions, 'create')
17
+
18
+ actions.each do |action|
19
+ case action['type']
20
+ when 'create', 'update'
21
+ create_or_update_action_check(action, contexts, ig_version:)
22
+ when 'delete'
23
+ delete_action_check(action, create_actions_resource_types, contexts)
24
+ end
25
+ end
26
+ end
27
+
28
+ def action_resource_type_check(action, expected_resource_types) # rubocop:disable Naming/PredicateMethod
29
+ resource_type = if ['create', 'update'].include?(action['type'])
30
+ FHIR.from_contents(action['resource'].to_json)&.resourceType
31
+ else
32
+ action['resourceId']&.split('/')&.first
33
+ end
34
+ expected_resource_types.include?(resource_type)
16
35
  end
17
36
 
18
- def action_type_field_validation(action)
37
+ private
38
+
39
+ def action_required_fields
40
+ { 'type' => String, 'description' => String }
41
+ end
42
+
43
+ def action_type_field_validation(action, ig_version: 'v201')
19
44
  return unless action['type']
20
45
 
21
46
  allowed_types = ['create', 'update', 'delete']
@@ -30,7 +55,7 @@ module DaVinciCRDTestKit
30
55
  if ['create', 'update'].include?(type)
31
56
  action_resource_field_validation(action, type)
32
57
  else
33
- action_resource_id_field_validation(action)
58
+ action_resource_id_field_validation(action, ig_version:)
34
59
  end
35
60
  end
36
61
 
@@ -46,13 +71,9 @@ module DaVinciCRDTestKit
46
71
  add_message('error', "`Action.resource` must be a FHIR resource: `#{action}`.")
47
72
  end
48
73
 
49
- def action_resource_id_field_validation(action)
50
- validate_presence_and_type(action, 'resourceId', Array, '`delete` Action')
51
- return unless action['resourceId'].is_a?(Array)
52
-
53
- action['resourceId'].each do |ref|
54
- resource_reference_check(ref, 'Action.resourceId item')
55
- end
74
+ def action_resource_id_field_validation(action, ig_version: 'v201')
75
+ validate_presence_and_type(action, 'resourceId', String, '`delete` Action')
76
+ resource_reference_check(action['resourceId'], 'Action.resourceId', ig_version:)
56
77
  end
57
78
 
58
79
  def draft_orders_bundle_entry_refs(contexts)
@@ -62,37 +83,23 @@ module DaVinciCRDTestKit
62
83
  end
63
84
  end
64
85
 
65
- def action_resource_type_check(action, expected_resource_types)
66
- resource_types = if ['create', 'update'].include?(action['type'])
67
- [FHIR.from_contents(action['resource'].to_json).resourceType]
68
- else
69
- action['resourceId'].map { |ref| ref.split('/').first }
70
- end
71
- resource_types.all? { |resource_type| expected_resource_types.include?(resource_type) }
72
- end
73
-
74
86
  def extract_resource_types_by_action(actions, action_type)
75
87
  actions.each_with_object([]) do |act, resource_types|
76
88
  resource_types << act['resource']['resourceType'] if act['type'] == action_type
77
89
  end
78
90
  end
79
91
 
80
- def actions_check(actions, contexts = nil)
81
- create_actions_resource_types = extract_resource_types_by_action(actions, 'create')
92
+ def create_or_update_action_check(action, contexts, ig_version: 'v201')
93
+ resource = FHIR.from_contents(action['resource'].to_json)
94
+ resource_is_valid?(resource:, profile_url: structure_definition_map(ig_version)[resource.resourceType])
82
95
 
83
- actions.each do |action|
84
- case action['type']
85
- when 'create', 'update'
86
- create_or_update_action_check(action, contexts)
87
- when 'delete'
88
- delete_action_check(action, create_actions_resource_types, contexts)
89
- end
96
+ if action['resourceId'].present?
97
+ add_message(
98
+ 'error',
99
+ "`resourceId` should not be populated for create and update actions. In Action `#{action}`"
100
+ )
90
101
  end
91
- end
92
102
 
93
- def create_or_update_action_check(action, contexts)
94
- resource = FHIR.from_contents(action['resource'].to_json)
95
- resource_is_valid?(resource:, profile_url: structure_definition_map[resource.resourceType])
96
103
  return unless action['type'] == 'update' && contexts
97
104
 
98
105
  ref = "#{resource.resourceType}/#{resource.id}"
@@ -103,21 +110,34 @@ module DaVinciCRDTestKit
103
110
  add_message('error', error_msg)
104
111
  end
105
112
 
106
- def delete_action_check(action, create_actions_resource_types, contexts)
107
- action['resourceId'].each do |ref|
108
- unless draft_orders_bundle_entry_refs(contexts).include?(ref)
109
- error_msg = '`Action.resourceId` must reference FHIR resource from the `draftOrders` entry. ' \
110
- "#{ref} is not in `draftOrders`. In Action `#{action}`"
111
- add_message('error', error_msg)
112
- next
113
- end
113
+ def questionnaire_creation_check(action)
114
+ return unless action.dig('resource', 'resourceType') == 'Questionnaire'
114
115
 
115
- resource_type = ref.split('/').first
116
- next if create_actions_resource_types.include?(resource_type)
116
+ extension_value = action.dig('extension', 'davinci-crd.if-none-exist')
117
+
118
+ if extension_value.nil?
119
+ add_message('error', '`davinci-crd.if-none-exist` extension is not present.')
120
+ elsif !extension_value.is_a? String
121
+ add_message('error', '`davinci-crd.if-none-exist` extension is not a string.')
122
+ elsif extension_value.blank?
123
+ add_message('error', '`davinci-crd.if-none-exist` extension is an empty string.')
124
+ end
125
+ end
117
126
 
118
- error_msg = "There's no `create` action for the proposed order being deleted: `#{ref}`. In Action `#{action}`"
127
+ def delete_action_check(action, create_actions_resource_types, contexts)
128
+ ref = action['resourceId']
129
+ unless draft_orders_bundle_entry_refs(contexts).include?(ref)
130
+ error_msg = '`Action.resourceId` must reference FHIR resource from the `draftOrders` entry. ' \
131
+ "#{ref} is not in `draftOrders`. In Action `#{action}`"
119
132
  add_message('error', error_msg)
133
+ return
120
134
  end
135
+
136
+ resource_type = ref.split('/').first
137
+ return if create_actions_resource_types.include?(resource_type)
138
+
139
+ error_msg = "There's no `create` action for the proposed order being deleted: `#{ref}`. In Action `#{action}`"
140
+ add_message('error', error_msg)
121
141
  end
122
142
  end
123
143
  end
@@ -0,0 +1,42 @@
1
+ module DaVinciCRDTestKit
2
+ APPOINTMENT_BOOK_TAG = 'appointment-book'.freeze
3
+ ENCOUNTER_START_TAG = 'encounter-start'.freeze
4
+ ENCOUNTER_DISCHARGE_TAG = 'encounter-discharge'.freeze
5
+ ORDER_DISPATCH_TAG = 'order-dispatch'.freeze
6
+ ORDER_SELECT_TAG = 'order-select'.freeze
7
+ ORDER_SIGN_TAG = 'order-sign'.freeze
8
+ DISCOVERY_TAG = 'cds_discovery'.freeze
9
+ ANY_HOOK_TAG = 'any_hook'.freeze
10
+ DATA_FETCH_TAG = 'data_fetch'.freeze
11
+ PAYER_ORG_FETCH_TAG = 'payer_org'.freeze
12
+ PARENT_LOCATION_FETCH_TAG = 'parent_location'.freeze
13
+ HOOK_INSTANCE_TAG_PREFIX = 'hi_'.freeze
14
+ HOOK_INSTANCE_DATA_FETCH_TAG_PREFIX = 'hi_data_fetch_'.freeze
15
+ LONG_RUNNING_GROUP_TAG = 'long_running_request'.freeze
16
+ DUPLICATED_HOOK_INSTANCE_TAG = 'duplicate_hook_instance'.freeze
17
+ COVERAGE_INFO_DISABLED_TAG = 'coverage-info-disabled'.freeze
18
+ UNKNOWN_CONFIGURATION_TAG = 'unknown-configuration'.freeze
19
+ UNKNOWN_CONTEXT_TAG = 'unknown-context'.freeze
20
+ UNKNOWN_ELEMENT_TAG = 'unknown-element'.freeze
21
+
22
+ ALL_HOOK_TAGS = [
23
+ APPOINTMENT_BOOK_TAG,
24
+ ENCOUNTER_START_TAG,
25
+ ENCOUNTER_DISCHARGE_TAG,
26
+ ORDER_DISPATCH_TAG,
27
+ ORDER_SELECT_TAG,
28
+ ORDER_SIGN_TAG
29
+ ].freeze
30
+
31
+ module TagMethods
32
+ def hook_instance_tag(hook_instance)
33
+ "#{HOOK_INSTANCE_TAG_PREFIX}#{hook_instance}"
34
+ end
35
+
36
+ def hook_instance_data_fetch_tag(hook_instance)
37
+ "#{HOOK_INSTANCE_DATA_FETCH_TAG_PREFIX}#{hook_instance}"
38
+ end
39
+
40
+ module_function :hook_instance_tag, :hook_instance_data_fetch_tag
41
+ end
42
+ end
@@ -6,9 +6,10 @@ module DaVinciCRDTestKit
6
6
  title 'Da Vinci Coverage Requirements Discovery (CRD) Test Kit'
7
7
  description <<~DESCRIPTION
8
8
  The Da Vinci Coverage Requirements Discovery (CRD) Test Kit tests the
9
- conformance of client and server systems to [version 2.0.1 of the Da Vinci
10
- Coverage Requirements Discovery (CRD) Implementation
11
- Guide](https://hl7.org/fhir/us/davinci-crd/STU2).
9
+ conformance of client and server systems to versions of the
10
+ Da Vinci Coverage Requirements Discovery (CRD) FHIR Implementation Guide (IG), including
11
+ - [Da Vinci Coverage Requirements Discovery (CRD) STU 2.0.1](https://hl7.org/fhir/us/davinci-crd/STU2), and
12
+ - [Da Vinci Coverage Requirements Discovery (CRD) STU 2.2.1](https://hl7.org/fhir/us/davinci-crd/2.2.1)
12
13
 
13
14
  <!-- break -->
14
15
 
@@ -20,51 +21,16 @@ module DaVinciCRDTestKit
20
21
  requirements and may change how these are tested.
21
22
 
22
23
  Additional details on the IG requirements that underlie this test kit can be
23
- found in this [CRD testing note](https://github.com/inferno-framework/davinci-crd-test-kit/blob/main/docs/crd-testing-notes.md). The document
24
- includes the requirements extracted from the IG and specified the ones that are
25
- not testable.
24
+ found in the [Specification Requirements display within the testing UI](https://inferno-framework.github.io/docs/user-interface.html#specification-requirements)
25
+ and other artifacts of Inferno's [requirements tracking tools](https://inferno-framework.github.io/docs/advanced-test-features/requirements.html).
26
26
 
27
- ## Test Scope and Limitations
27
+ ## Additional Details
28
28
 
29
- Documentation of the current tests and their limitations can be found in each
30
- suite's (client and server) description when the tests are run.
29
+ Additional details about design, scope, and limitations of the suites within this
30
+ test kit can be found on the [CRD Test Kit Wiki](https://github.com/inferno-framework/davinci-crd-test-kit/wiki)
31
31
 
32
- ### Test Scope
33
-
34
- At a high-level, the tests check:
35
-
36
- - **Client Suite**:
37
- - The ability of a CRD client to initiate CDS Hooks calls.
38
- - The ability of a CRD client to support the FHIR interactions defined in the
39
- implementation guide.
40
- - **Server Suite**:
41
- - The ability of a CRD server to return a valid response when invoking its
42
- discovery endpoint.
43
- - The ability of a CRD server to return a valid response when invoking a
44
- supported hook, including producing the required response types across all
45
- hooks invoked.
46
-
47
- ### Limitations
48
-
49
- - **Client Suite**:
50
- - This suite does not implement any payer business logic, so the responses to
51
- hook calls are simple hard-coded responses.
52
- - The tests cannot verify that a client is able to consume the received
53
- decision support. Testers should consider this requirement to be verified
54
- through attestation and should not represent their systems as having passed
55
- these tests if this requirement is not met.
56
- - Hook configuration is not tested.
57
- - **Server Suite**:
58
- - Inferno is unable to determine what requests will result in specific kinds
59
- of responses from the server under test (e.g., what will result in
60
- Instructions being returned vs. Coverage Information). As a result, the
61
- tester must supply the request bodies that will cause the system under test
62
- to return the desired response types.
63
- - The ability of a CRD server to request additional FHIR resources is not
64
- tested.
65
- - Hook configuration is not tested.
66
32
  DESCRIPTION
67
- suite_ids [:crd_client, :crd_server]
33
+ suite_ids [:crd_client, :crd_client_v221, :crd_server, :crd_server_v221]
68
34
  tags ['Da Vinci', 'CRD']
69
35
  last_updated LAST_UPDATED
70
36
  version VERSION