davinci_crd_test_kit 0.14.0 → 0.14.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. checksums.yaml +4 -4
  2. data/config/presets/{inferno_crd_server_suite.json.erb → client_against_inferno_crd_server_suite.json.erb} +0 -33
  3. data/config/presets/{ri_crd_request_generator.json.erb → client_against_ri_crd_request_generator.json.erb} +1 -14
  4. data/config/presets/client_v221_against_inferno_crd_server_suite.json.erb +84 -0
  5. data/config/presets/client_v221_against_ri_br_provider.json.erb +31 -0
  6. data/config/presets/{ri_crd_request_generator.json_v221.json.erb → client_v221_against_ri_crd_request_generator.json.erb} +1 -1
  7. data/config/presets/{inferno_crd_client_suite.json.erb → server_against_inferno_crd_client_suite.json.erb} +0 -43
  8. data/config/presets/{ri_crd_server.json.erb → server_against_ri_crd_server.json.erb} +1 -44
  9. data/config/presets/{inferno_crd_client_suite_v221.json.erb → server_v221_against_inferno_crd_client_suite.json.erb} +48 -45
  10. data/config/presets/{inferno_crd_client_suite_prefetch_subset_v221.json.erb → server_v221_against_inferno_crd_client_suite_prefetch_subset.json.erb} +0 -46
  11. data/config/presets/server_v221_against_inferno_g31_suite.json.erb +49 -0
  12. data/lib/davinci_crd_test_kit/client/cross_hook_helper.rb +26 -0
  13. data/lib/davinci_crd_test_kit/client/endpoints/custom_service_response.rb +7 -7
  14. data/lib/davinci_crd_test_kit/client/endpoints/gather_response_generation_data.rb +4 -1
  15. data/lib/davinci_crd_test_kit/client/endpoints/hook_request_endpoint.rb +70 -39
  16. data/lib/davinci_crd_test_kit/client/endpoints/mock_service_response.rb +26 -7
  17. data/lib/davinci_crd_test_kit/client/endpoints/mocked_card_responses/external_reference.json +1 -1
  18. data/lib/davinci_crd_test_kit/client/endpoints/mocked_card_responses/launch_smart_app.json +0 -7
  19. data/lib/davinci_crd_test_kit/client/endpoints/scenario_service_response.rb +54 -0
  20. data/lib/davinci_crd_test_kit/client/tagged_request_load_helper.rb +8 -27
  21. data/lib/davinci_crd_test_kit/client/v2.0.1/auth/retrieve_jwks_test.rb +35 -23
  22. data/lib/davinci_crd_test_kit/client/v2.0.1/auth/token_payload_test.rb +34 -21
  23. data/lib/davinci_crd_test_kit/client/v2.0.1/cds-services-v201.json +20 -20
  24. data/lib/davinci_crd_test_kit/client/v2.0.1/client_appointment_book_group.rb +12 -10
  25. data/lib/davinci_crd_test_kit/client/v2.0.1/client_encounter_discharge_group.rb +12 -10
  26. data/lib/davinci_crd_test_kit/client/v2.0.1/client_encounter_start_group.rb +12 -10
  27. data/lib/davinci_crd_test_kit/client/v2.0.1/client_hooks_group.rb +5 -5
  28. data/lib/davinci_crd_test_kit/client/v2.0.1/client_order_dispatch_group.rb +12 -10
  29. data/lib/davinci_crd_test_kit/client/v2.0.1/client_order_select_group.rb +12 -10
  30. data/lib/davinci_crd_test_kit/client/v2.0.1/client_order_sign_group.rb +12 -10
  31. data/lib/davinci_crd_test_kit/client/v2.0.1/must_support/client_card_must_support_coverage_information.rb +3 -36
  32. data/lib/davinci_crd_test_kit/client/v2.0.1/must_support/client_card_must_support_external_reference.rb +3 -36
  33. data/lib/davinci_crd_test_kit/client/v2.0.1/must_support/client_card_must_support_instructions.rb +3 -36
  34. data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_fetched_data_test.rb +4 -13
  35. data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_prefetch_equals_queried_test.rb +3 -13
  36. data/lib/davinci_crd_test_kit/client/v2.0.1/verify_response/client_display_cards_attest.rb +3 -13
  37. data/lib/davinci_crd_test_kit/client/v2.0.1/verify_response/inferno_response_validation.rb +3 -13
  38. data/lib/davinci_crd_test_kit/client/v2.2.1/api/client_coverage_info_update_test.rb +1 -1
  39. data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/attestation_instructions.rb +10 -0
  40. data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_authorized_scope_attestation_test.rb +45 -0
  41. data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_coverage_based_invocation_attestation_test.rb +44 -0
  42. data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_data_element_expectations_attestation_test.rb +44 -0
  43. data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_hook_invocation_logging_attestation_test.rb +43 -0
  44. data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_must_support_exposure_attestation_test.rb +43 -0
  45. data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_must_support_use_attestation_test.rb +41 -0
  46. data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_order_sign_support_attestation_test.rb +42 -0
  47. data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_prefetch_key_omission_attestation_test.rb +42 -0
  48. data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_resource_identifiers_attestation_test.rb +43 -0
  49. data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_response_case_distinction_attestation_test.rb +43 -0
  50. data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_security_and_privacy_attestation_test.rb +43 -0
  51. data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_workflow_integration_attestation_test.rb +44 -0
  52. data/lib/davinci_crd_test_kit/client/v2.2.1/auth/decode_auth_token_test.rb +1 -1
  53. data/lib/davinci_crd_test_kit/client/v2.2.1/auth/retrieve_jwks_test.rb +29 -18
  54. data/lib/davinci_crd_test_kit/client/v2.2.1/auth/token_payload_test.rb +35 -22
  55. data/lib/davinci_crd_test_kit/client/v2.2.1/cds-services-prefetch-subset-v221.json +47 -47
  56. data/lib/davinci_crd_test_kit/client/v2.2.1/cds-services-v221.json +50 -50
  57. data/lib/davinci_crd_test_kit/client/v2.2.1/client_appointment_book_group.rb +24 -15
  58. data/lib/davinci_crd_test_kit/client/v2.2.1/client_attestations_group.rb +49 -0
  59. data/lib/davinci_crd_test_kit/client/v2.2.1/client_cross_hook_group.rb +22 -6
  60. data/lib/davinci_crd_test_kit/client/v2.2.1/client_cross_hook_interaction_group.rb +98 -0
  61. data/lib/davinci_crd_test_kit/client/v2.2.1/client_encounter_discharge_group.rb +19 -11
  62. data/lib/davinci_crd_test_kit/client/v2.2.1/client_encounter_start_group.rb +19 -11
  63. data/lib/davinci_crd_test_kit/client/v2.2.1/client_fhir_api_group.rb +14 -12
  64. data/lib/davinci_crd_test_kit/client/v2.2.1/client_hooks_group.rb +25 -5
  65. data/lib/davinci_crd_test_kit/client/v2.2.1/client_long_running_hook_group.rb +3 -2
  66. data/lib/davinci_crd_test_kit/client/v2.2.1/client_order_dispatch_group.rb +23 -15
  67. data/lib/davinci_crd_test_kit/client/v2.2.1/client_order_select_group.rb +19 -11
  68. data/lib/davinci_crd_test_kit/client/v2.2.1/client_order_sign_group.rb +23 -15
  69. data/lib/davinci_crd_test_kit/client/v2.2.1/client_registration_group.rb +6 -0
  70. data/lib/davinci_crd_test_kit/client/v2.2.1/client_scenarios_group.rb +26 -0
  71. data/lib/davinci_crd_test_kit/client/v2.2.1/client_self_pay_hook_group.rb +36 -0
  72. data/lib/davinci_crd_test_kit/client/v2.2.1/client_unknown_content_hook_group.rb +34 -0
  73. data/lib/davinci_crd_test_kit/client/v2.2.1/crd_client_suite.rb +24 -3
  74. data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_card_must_support_coverage_information_test.rb +1 -1
  75. data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_fhirpath_collection_as_comma_delimited_string_test.rb +4 -11
  76. data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_hook_instances_unique_test.rb +1 -9
  77. data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_location_address_propagation_test.rb +6 -2
  78. data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_prefetch_complete_and_subset_test.rb +3 -12
  79. data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/appointment_book_receive_request_test.rb +8 -89
  80. data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/base_hook_invocation_receive_request_test.rb +163 -0
  81. data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/cross_hooks_receive_request_test.rb +97 -0
  82. data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/encounter_discharge_receive_request_test.rb +8 -90
  83. data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/encounter_start_receive_request_test.rb +8 -90
  84. data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/order_dispatch_receive_request_test.rb +8 -98
  85. data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/order_select_receive_request_test.rb +8 -98
  86. data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/order_sign_receive_request_test.rb +8 -98
  87. data/lib/davinci_crd_test_kit/client/v2.2.1/long_running/client_long_running_receive_request_test.rb +10 -2
  88. data/lib/davinci_crd_test_kit/client/v2.2.1/long_running/client_skip_long_running_attestation_test.rb +11 -6
  89. data/lib/davinci_crd_test_kit/client/v2.2.1/registration/client_service_registration_attestation_test.rb +2 -1
  90. data/lib/davinci_crd_test_kit/client/v2.2.1/self_pay/client_self_pay_no_request_test.rb +30 -0
  91. data/lib/davinci_crd_test_kit/client/v2.2.1/self_pay/client_self_pay_workflow_test.rb +55 -0
  92. data/lib/davinci_crd_test_kit/client/v2.2.1/unknown_content/client_unknown_content_attestation_test.rb +99 -0
  93. data/lib/davinci_crd_test_kit/client/v2.2.1/unknown_content/client_unknown_content_receive_request_test.rb +62 -0
  94. data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_conformance_test.rb +1 -1
  95. data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_coverage_verification_test.rb +10 -2
  96. data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_data_fetch_verification_test.rb +1 -1
  97. data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_granted_scopes_test.rb +1 -1
  98. data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_prefetch_complete_test.rb +7 -1
  99. data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_prefetch_profiles_test.rb +1 -1
  100. data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_requested_version_test.rb +1 -1
  101. data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_secured_transport_test.rb +1 -1
  102. data/lib/davinci_crd_test_kit/client/v2.2.1/verify_response/client_display_cards_attest.rb +54 -21
  103. data/lib/davinci_crd_test_kit/client/v2.2.1/verify_response/hook_response_support_coverage_information_test.rb +1 -1
  104. data/lib/davinci_crd_test_kit/client/v2.2.1/verify_response/inferno_response_validation.rb +6 -3
  105. data/lib/davinci_crd_test_kit/cross_suite/cards_identification.rb +18 -0
  106. data/lib/davinci_crd_test_kit/cross_suite/logical_models_override_helper.rb +30 -13
  107. data/lib/davinci_crd_test_kit/cross_suite/prefetch_completeness_checker.rb +25 -11
  108. data/lib/davinci_crd_test_kit/cross_suite/prefetch_profile_validation.rb +2 -0
  109. data/lib/davinci_crd_test_kit/cross_suite/requests_logical_model_validation.rb +28 -28
  110. data/lib/davinci_crd_test_kit/cross_suite/response_logical_model_validation.rb +211 -43
  111. data/lib/davinci_crd_test_kit/cross_suite/tags.rb +7 -0
  112. data/lib/davinci_crd_test_kit/requirements/cds-hooks_3.0.0-ballot_requirements.xlsx +0 -0
  113. data/lib/davinci_crd_test_kit/requirements/davinci_crd_test_kit_requirements.csv +6 -2
  114. data/lib/davinci_crd_test_kit/requirements/generated/crd_client_requirements_coverage.csv +107 -107
  115. data/lib/davinci_crd_test_kit/requirements/generated/crd_client_v221_requirements_coverage.csv +101 -97
  116. data/lib/davinci_crd_test_kit/requirements/generated/crd_server_requirements_coverage.csv +18 -18
  117. data/lib/davinci_crd_test_kit/requirements/generated/crd_server_v221_requirements_coverage.csv +43 -39
  118. data/lib/davinci_crd_test_kit/requirements/hl7.fhir.us.davinci-crd_2.2.1_requirements.xlsx +0 -0
  119. data/lib/davinci_crd_test_kit/server/jobs/invoke_hook.rb +3 -3
  120. data/lib/davinci_crd_test_kit/server/jobs/invoke_hook_no_special_requests.rb +17 -0
  121. data/lib/davinci_crd_test_kit/server/jobs/invoke_hook_with_bad_auth.rb +14 -0
  122. data/lib/davinci_crd_test_kit/server/server_abstract_invoke_hook_test.rb +24 -6
  123. data/lib/davinci_crd_test_kit/server/server_hook_helper.rb +2 -2
  124. data/lib/davinci_crd_test_kit/server/v2.0.1/crd_server_suite.rb +1 -1
  125. data/lib/davinci_crd_test_kit/server/v2.0.1/server_hooks_group.rb +5 -5
  126. data/lib/davinci_crd_test_kit/server/v2.2.1/crd_server_suite.rb +3 -0
  127. data/lib/davinci_crd_test_kit/server/v2.2.1/discovery/discovery_standard_prefetch_expressions_test.rb +165 -0
  128. data/lib/davinci_crd_test_kit/server/v2.2.1/interaction/server_invoke_hook_single_request_test.rb +22 -0
  129. data/lib/davinci_crd_test_kit/server/v2.2.1/server_appointment_book_group.rb +10 -102
  130. data/lib/davinci_crd_test_kit/server/v2.2.1/server_demonstrate_hook_response_group.rb +3 -2
  131. data/lib/davinci_crd_test_kit/server/v2.2.1/server_discovery_group.rb +2 -0
  132. data/lib/davinci_crd_test_kit/server/v2.2.1/server_encounter_discharge_group.rb +10 -97
  133. data/lib/davinci_crd_test_kit/server/v2.2.1/server_encounter_start_group.rb +10 -97
  134. data/lib/davinci_crd_test_kit/server/v2.2.1/server_hooks_group.rb +5 -5
  135. data/lib/davinci_crd_test_kit/server/v2.2.1/server_order_dispatch_group.rb +10 -103
  136. data/lib/davinci_crd_test_kit/server/v2.2.1/server_order_select_group.rb +12 -116
  137. data/lib/davinci_crd_test_kit/server/v2.2.1/server_order_sign_group.rb +12 -121
  138. data/lib/davinci_crd_test_kit/server/v2.2.1/specific_coverage_response_group.rb +23 -0
  139. data/lib/davinci_crd_test_kit/server/v2.2.1/specific_coverage_responses/coverage_info_reason_test.rb +108 -0
  140. data/lib/davinci_crd_test_kit/server/v2.2.1/specific_coverage_responses/coverage_not_found_group.rb +116 -0
  141. data/lib/davinci_crd_test_kit/server/v2.2.1/specific_coverage_responses/no_active_coverage_group.rb +115 -0
  142. data/lib/davinci_crd_test_kit/server/v2.2.1/specific_coverage_responses/no_member_found_group.rb +117 -0
  143. data/lib/davinci_crd_test_kit/server/v2.2.1/specific_coverage_responses/technical_issues_group.rb +121 -0
  144. data/lib/davinci_crd_test_kit/server/v2.2.1/specific_coverage_responses/technical_issues_invoke_test.rb +22 -0
  145. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_request/service_request_context_validation_test.rb +1 -0
  146. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_request/service_request_optional_fields_validation_test.rb +1 -0
  147. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_request/service_request_required_fields_validation_test.rb +1 -0
  148. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/additional_orders_validation_test.rb +78 -35
  149. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/coverage_information_card_absence_test.rb +76 -0
  150. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/coverage_information_system_action_validation_test.rb +70 -124
  151. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/create_or_update_coverage_info_response_validation_test.rb +83 -39
  152. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/external_reference_card_validation_test.rb +59 -17
  153. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/form_completion_response_validation_test.rb +80 -45
  154. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/hook_request_resource_resolution.rb +37 -0
  155. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/instructions_card_received_test.rb +57 -6
  156. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/launch_smart_app_card_validation_test.rb +56 -17
  157. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/propose_alternate_request_card_validation_test.rb +52 -25
  158. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/service_response_validation_test.rb +17 -51
  159. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/unknown_cds_hooks_elements_test.rb +1 -1
  160. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/unknown_configuration_test.rb +1 -1
  161. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/unknown_context_test.rb +1 -1
  162. data/lib/davinci_crd_test_kit/version.rb +2 -2
  163. metadata +54 -16
  164. data/config/presets/inferno_crd_server_suite_v221.json.erb +0 -94
  165. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/card_optional_fields_validation_test.rb +0 -57
  166. data/lib/davinci_crd_test_kit/server/v2.2.1/verify_response/coverage_information_system_action_received_test.rb +0 -65
@@ -1,74 +1,118 @@
1
1
  require_relative '../../server_test_helper'
2
- require_relative '../../../cross_suite/suggestion_actions_validation'
3
2
  require_relative '../../server_hook_helper'
4
3
  require_relative '../../../cross_suite/cards_identification'
5
- require_relative '../../../cross_suite/cards_validation'
4
+ require_relative '../../../cross_suite/response_logical_model_validation'
6
5
 
7
6
  module DaVinciCRDTestKit
8
7
  module V221
9
8
  class CreateOrUpdateCoverageInfoResponseValidationTest < Inferno::Test
10
9
  include DaVinciCRDTestKit::ServerTestHelper
11
- include DaVinciCRDTestKit::SuggestionActionsValidation
12
10
  include DaVinciCRDTestKit::ServerHookHelper
13
11
  include DaVinciCRDTestKit::CardsIdentification
14
- include DaVinciCRDTestKit::CardsValidation
12
+ include DaVinciCRDTestKit::ResponseLogicalModelValidation
15
13
 
16
14
  title 'Create or Update Coverage Information cards and system actions are valid'
17
15
  id :crd_v221_create_or_update_coverage_info_response_validation
18
16
  description %(
19
- This test validates the Create or Update Coverage Information cards or system actions received from the
20
- CRD service, as per the specifications outlined in the [Da Vinci CRD Implementation Guide](https://hl7.org/fhir/us/davinci-crd/STU2/cards.html#create-or-update-coverage-information).
17
+ This test validates the Create or Update Coverage Information cards or
18
+ system actions received from the CRD service, as per the specifications
19
+ outlined in the [Da Vinci CRD Implementation
20
+ Guide](https://hl7.org/fhir/us/davinci-crd/2.2.1/en/cards.html#update-coverage-records-response-type).
21
21
 
22
22
  - **Checking for Presence:**
23
- The test first checks if any Create or Update Coverage Information cards or system actions are present in
24
- the returned valid cards or valid system actions.
25
- - **For cards**: it ensures there are cards with a `suggestions` array containing a single suggestion,
26
- and the `actions` array of that suggestion has one `create` or `update` action for the `Coverage` resource.
27
- - **For system actions**: it checks for the presence of `create` or `update` actions for the `Coverage`
28
- resource.
23
+ The test first checks if any Create or Update Coverage Information
24
+ cards or system actions are present in the returned valid cards or
25
+ valid system actions.
26
+ - **For cards**: it ensures there are cards with a `suggestions` array
27
+ containing a single suggestion, and the `actions` array of that
28
+ suggestion has one `create` or `update` action for the `Coverage`
29
+ resource.
30
+ - **For system actions**: it checks for the presence of `create` or
31
+ `update` actions for the `Coverage` resource.
29
32
 
30
33
  - **Validating:**
31
- If any Create or Update Coverage Information cards or system actions are found, each `Coverage` resource is
32
- validated against the base FHIR Coverage resource.
34
+ If any Create or Update Coverage Information cards or system actions
35
+ are found, each `Coverage` resource is validated against the base FHIR
36
+ Coverage resource.
33
37
 
34
- If no Create or Update Coverage Information cards or system actions are received, the test is skipped.
38
+ If no Create or Update Coverage Information cards or system actions
39
+ are received, the test is skipped.
35
40
  )
36
41
 
37
- verifies_requirements 'hl7.fhir.us.davinci-crd_2.2.1@resp-71'
42
+ verifies_requirements 'hl7.fhir.us.davinci-crd_2.2.1@resp-3',
43
+ 'hl7.fhir.us.davinci-crd_2.2.1@resp-71'
44
+
45
+ input :invoked_hook
38
46
 
39
47
  optional
40
- input :valid_cards_with_suggestions, :valid_system_actions
48
+
49
+ def body_has_no_cards?(body)
50
+ !body.is_a?(Hash) ||
51
+ body['cards'].blank? ||
52
+ !body['cards'].is_a?(Array) ||
53
+ !body['cards'].all?(Hash)
54
+ end
55
+
56
+ def update_coverage_cards(request)
57
+ return [] if request.status != 200
58
+
59
+ response_body = JSON.parse(request.response_body)
60
+
61
+ return [] if body_has_no_cards?(response_body)
62
+
63
+ response_body['cards'].select { |card| create_or_update_coverage_card_response_type? card }
64
+ rescue JSON::ParserError
65
+ []
66
+ end
67
+
68
+ def body_has_no_system_actions?(body)
69
+ !body.is_a?(Hash) ||
70
+ body['systemActions'].blank? ||
71
+ !body['systemActions'].is_a?(Array) ||
72
+ !body['systemActions'].all?(Hash)
73
+ end
74
+
75
+ def update_coverage_actions(request)
76
+ return [] if request.status != 200
77
+
78
+ response_body = JSON.parse(request.response_body)
79
+
80
+ return [] if body_has_no_system_actions?(response_body)
81
+
82
+ response_body['systemActions'].select { |action| create_or_update_coverage_action_response_type? action }
83
+ rescue JSON::ParserError
84
+ []
85
+ end
41
86
 
42
87
  run do
43
- parsed_cards = parse_json(valid_cards_with_suggestions)
44
- parsed_actions = parse_json(valid_system_actions)
88
+ load_tagged_requests(tested_hook_name)
45
89
 
46
- create_or_update_coverage_info_cards = parsed_cards.select do |card|
47
- create_or_update_coverage_card_response_type?(card)
48
- end
49
- create_or_update_coverage_info_actions = parsed_actions.select do |action|
50
- create_or_update_coverage_action_response_type?(action)
51
- end
90
+ update_coverage_count = 0
52
91
 
53
- skip_msg = "#{tested_hook_name} hook response does not contain any Create or Update Coverage Information " \
54
- 'cards or system actions.'
55
- skip_if create_or_update_coverage_info_cards.blank? && create_or_update_coverage_info_actions.blank?, skip_msg
92
+ successful_requests = requests.select { |request| request.status == 200 }
56
93
 
57
- if create_or_update_coverage_info_actions.present?
58
- actions_check(create_or_update_coverage_info_actions, ig_version: 'v221')
59
- end
94
+ skip_if successful_requests.blank?,
95
+ 'No successful hook responses were received'
60
96
 
61
- if create_or_update_coverage_info_cards.present?
62
- create_or_update_coverage_info_cards.each do |card|
63
- actions_check(card['suggestions'].first['actions'].select do |action|
64
- create_or_update_coverage_action_response_type?(action)
65
- end, ig_version: 'v221')
97
+ requests.each_with_index do |request, index|
98
+ cards = update_coverage_cards(request)
99
+ actions = update_coverage_actions(request)
66
100
 
67
- create_or_update_coverage_check(card)
68
- end
101
+ update_coverage_count += cards.length + actions.length
102
+
103
+ perform_response_logical_model_validation(
104
+ cards,
105
+ actions,
106
+ request.request_body,
107
+ index,
108
+ '2.2.1'
109
+ )
69
110
  end
70
111
 
71
- no_error_validation('Some Create or Update Coverage Information received are not valid.')
112
+ skip_if update_coverage_count.zero?,
113
+ "#{tested_hook_name} hook responses do not contain any Update Coverage Records cards or system actions."
114
+
115
+ no_error_validation('Not all Update Coverage Records responses were valid. See messages for more information.')
72
116
  end
73
117
  end
74
118
  end
@@ -1,7 +1,7 @@
1
1
  require_relative '../../server_test_helper'
2
2
  require_relative '../../server_hook_helper'
3
3
  require_relative '../../../cross_suite/cards_identification'
4
- require_relative '../../../cross_suite/cards_validation'
4
+ require_relative '../../../cross_suite/response_logical_model_validation'
5
5
 
6
6
  module DaVinciCRDTestKit
7
7
  module V221
@@ -9,38 +9,80 @@ module DaVinciCRDTestKit
9
9
  include DaVinciCRDTestKit::ServerTestHelper
10
10
  include DaVinciCRDTestKit::ServerHookHelper
11
11
  include DaVinciCRDTestKit::CardsIdentification
12
- include DaVinciCRDTestKit::CardsValidation
12
+ include DaVinciCRDTestKit::ResponseLogicalModelValidation
13
13
 
14
14
  title 'External Reference cards are valid'
15
15
  id :crd_v221_external_reference_card_validation
16
16
  description %(
17
- This test verifies the presence of valid External Reference cards within the list of valid cards
18
- returned by the CRD service.
19
- As per the [Da Vinci CRD Implementation Guide](https://hl7.org/fhir/us/davinci-crd/STU2/cards.html#external-reference),
20
- External Reference cards must contain links with the type set to `absolute`.
21
- This test checks for the presence of any External Reference cards by verifying:
17
+ This test verifies the presence of valid External Reference cards within
18
+ the CRD service responses.
19
+
20
+ As per the [Da Vinci CRD Implementation
21
+ Guide](https://hl7.org/fhir/us/davinci-crd/2.2.1/en/cards.html#external-reference-response-type),
22
+ External Reference cards must contain links with the type set to
23
+ `absolute`. This test checks for the presence of any External Reference
24
+ cards by verifying:
22
25
  - The presence of a `links` array within each card.
23
26
  - That every link in the `links` array of a card is of type `absolute`.
27
+
28
+ The test will be skipped if no External Reference cards are found within
29
+ the returned valid cards.
24
30
  )
25
31
 
26
- verifies_requirements 'hl7.fhir.us.davinci-crd_2.2.1@resp-22'
32
+ verifies_requirements 'hl7.fhir.us.davinci-crd_2.2.1@resp-19',
33
+ 'hl7.fhir.us.davinci-crd_2.2.1@resp-22'
34
+
35
+ input :invoked_hook
27
36
 
28
- input :valid_cards_with_links
29
37
  optional
30
38
 
39
+ def body_has_no_cards?(body)
40
+ !body.is_a?(Hash) ||
41
+ body['cards'].blank? ||
42
+ !body['cards'].is_a?(Array) ||
43
+ !body['cards'].all?(Hash)
44
+ end
45
+
46
+ def external_reference_cards(request)
47
+ return [] if request.status != 200
48
+
49
+ response_body = JSON.parse(request.response_body)
50
+
51
+ return [] if body_has_no_cards?(response_body)
52
+
53
+ response_body['cards'].select { |card| external_reference_response_type? card }
54
+ rescue JSON::ParserError
55
+ []
56
+ end
57
+
31
58
  run do
32
- parsed_cards = parse_json(valid_cards_with_links)
33
- external_reference_cards = parsed_cards.select { |card| external_reference_response_type?(card) }
59
+ load_tagged_requests(tested_hook_name)
60
+
61
+ external_reference_count = 0
62
+
63
+ successful_requests = requests.select { |request| request.status == 200 }
34
64
 
35
- skip_if external_reference_cards.blank?,
36
- "#{tested_hook_name} hook response does not contain any External Reference cards."
65
+ skip_if successful_requests.blank?,
66
+ 'No successful hook responses were received'
37
67
 
38
- external_reference_cards.each do |card|
39
- external_reference_card_check(card)
68
+ requests.each_with_index do |request, index|
69
+ cards = external_reference_cards(request)
70
+
71
+ external_reference_count += cards.length
72
+
73
+ perform_response_logical_model_validation(
74
+ cards,
75
+ nil,
76
+ request.request_body,
77
+ index,
78
+ '2.2.1'
79
+ )
40
80
  end
41
81
 
42
- assert messages.blank?,
43
- 'Not all External Reference cards were valid. See messages for more information.'
82
+ skip_if external_reference_count.zero?,
83
+ "#{tested_hook_name} hook responses do not contain any External Reference cards."
84
+
85
+ no_error_validation('Not all External Reference cards were valid. See messages for more information.')
44
86
  end
45
87
  end
46
88
  end
@@ -1,38 +1,42 @@
1
1
  require_relative '../../server_test_helper'
2
- require_relative '../../../cross_suite/suggestion_actions_validation'
3
2
  require_relative '../../server_hook_helper'
4
3
  require_relative '../../../cross_suite/cards_identification'
5
- require_relative '../../../cross_suite/cards_validation'
4
+ require_relative '../../../cross_suite/response_logical_model_validation'
6
5
 
7
6
  module DaVinciCRDTestKit
8
7
  module V221
9
8
  class FormCompletionResponseValidationTest < Inferno::Test
10
9
  include DaVinciCRDTestKit::ServerTestHelper
11
- include DaVinciCRDTestKit::SuggestionActionsValidation
12
10
  include DaVinciCRDTestKit::ServerHookHelper
13
11
  include DaVinciCRDTestKit::CardsIdentification
14
- include DaVinciCRDTestKit::CardsValidation
12
+ include DaVinciCRDTestKit::ResponseLogicalModelValidation
15
13
 
16
14
  title 'Request Form Completion cards and system actions are valid'
17
15
  id :crd_v221_request_form_completion_response_validation
18
16
  description %(
19
- This test validates the Request Form Completion cards or system actions received from the CRD service,
20
- as per the specifications outlined in the [Da Vinci CRD Implementation Guide](https://hl7.org/fhir/us/davinci-crd/STU2/cards.html#request-form-completion).
17
+ This test validates the Request Form Completion cards or system actions
18
+ received from the CRD service, as per the specifications outlined in the
19
+ [Da Vinci CRD Implementation
20
+ Guide](https://hl7.org/fhir/us/davinci-crd/2.2.1/en/cards.html#request-form-completion-response-type).
21
21
 
22
22
  - **Checking for Presence:**
23
- The test begins by verifying whether any Request Form Completion cards or system actions are present.
24
- - **For cards:** It ensures that there are cards with `suggestions` containing `create` actions
25
- for the `Task` resource, specifically:
23
+ The test begins by verifying whether any Request Form Completion cards
24
+ or system actions are present.
25
+ - **For cards:** It ensures that there are cards with `suggestions`
26
+ containing `create` actions for the `Task` resource, specifically:
26
27
  - The `Task` must have a `code` of `complete-questionnaire`.
27
- - The `Task` should include an input of type `text` (`Task.input.type.text`) labeled as `questionnaire`
28
- and associated with a valid canonical URL (`Task.input.valueCanonical`).
29
- - **For system actions:** It checks for the presence of `create` actions for the `Task` resource with
30
- the characteristics described above.
28
+ - The `Task` should include an input of type `text`
29
+ (`Task.input.type.text`) labeled as `questionnaire` and associated
30
+ with a valid canonical URL (`Task.input.valueCanonical`).
31
+ - **For system actions:** It checks for the presence of `create`
32
+ actions for the `Task` resource with the characteristics described
33
+ above.
31
34
 
32
35
  - **Validating:**
33
- If any Request Form Completion cards or system actions are found, the test proceeds to validate them.
34
- Each `Task` resource is validated against the [CRD Questionnaire Task
35
- profile](http://hl7.org/fhir/us/davinci-crd/StructureDefinition/profile-taskquestionnaire).
36
+ If any Request Form Completion cards or system actions are found, the
37
+ test proceeds to validate them. Each `Task` resource is validated
38
+ against the [CRD Questionnaire Task
39
+ profile](https://hl7.org/fhir/us/davinci-crd/2.2.1/en/StructureDefinition-profile-taskquestionnaire.html).
36
40
  Additionally, if any actions for the creation of a `Questionnaire` are
37
41
  found, the test verifies that they include the
38
42
  `davinci-crd.if-none-exist` extension.
@@ -41,50 +45,81 @@ module DaVinciCRDTestKit
41
45
  )
42
46
 
43
47
  verifies_requirements 'hl7.fhir.us.davinci-crd_2.2.1@dev-20',
48
+ 'hl7.fhir.us.davinci-crd_2.2.1@resp-3',
44
49
  'hl7.fhir.us.davinci-crd_2.2.1@resp-62',
45
50
  'hl7.fhir.us.davinci-crd_2.2.1@resp-65'
46
51
 
52
+ input :invoked_hook
53
+
47
54
  optional
48
- input :valid_cards_with_suggestions, :valid_system_actions
55
+
56
+ def body_has_no_cards?(body)
57
+ !body.is_a?(Hash) ||
58
+ body['cards'].blank? ||
59
+ !body['cards'].is_a?(Array) ||
60
+ !body['cards'].all?(Hash)
61
+ end
62
+
63
+ def form_completion_cards(request)
64
+ return [] if request.status != 200
65
+
66
+ response_body = JSON.parse(request.response_body)
67
+
68
+ return [] if body_has_no_cards?(response_body)
69
+
70
+ response_body['cards'].select { |card| form_completion_card_response_type? card }
71
+ rescue JSON::ParserError
72
+ []
73
+ end
74
+
75
+ def body_has_no_system_actions?(body)
76
+ !body.is_a?(Hash) ||
77
+ body['systemActions'].blank? ||
78
+ !body['systemActions'].is_a?(Array) ||
79
+ !body['systemActions'].all?(Hash)
80
+ end
81
+
82
+ def form_completion_actions(request)
83
+ return [] if request.status != 200
84
+
85
+ response_body = JSON.parse(request.response_body)
86
+
87
+ return [] if body_has_no_system_actions?(response_body)
88
+
89
+ response_body['systemActions'].select { |action| form_completion_action_response_type? action }
90
+ rescue JSON::ParserError
91
+ []
92
+ end
49
93
 
50
94
  run do
51
- parsed_cards = parse_json(valid_cards_with_suggestions)
52
- parsed_actions = parse_json(valid_system_actions)
95
+ load_tagged_requests(tested_hook_name)
53
96
 
54
- form_completion_cards = parsed_cards.select { |card| form_completion_card_response_type?(card) }
55
- form_completion_actions = parsed_actions.select { |action| form_completion_action_response_type?(action) }
97
+ form_completion_count = 0
56
98
 
57
- skip_if form_completion_cards.blank? && form_completion_actions.blank?,
58
- "#{tested_hook_name} hook response does not contain any Request Form Completion cards " \
59
- 'or system actions.'
99
+ successful_requests = requests.select { |request| request.status == 200 }
60
100
 
61
- actions_check(form_completion_actions, ig_version: 'v221') if form_completion_actions.present?
101
+ skip_if successful_requests.blank?,
102
+ 'No successful hook responses were received'
62
103
 
63
- if form_completion_cards.present?
64
- form_completion_cards.each do |card|
65
- actions =
66
- card['suggestions']
67
- .flat_map { |suggestion| suggestion['actions'] }
68
- .compact
69
- .select { |action| form_completion_action_response_type? action }
104
+ requests.each_with_index do |request, index|
105
+ cards = form_completion_cards(request)
106
+ actions = form_completion_actions(request)
70
107
 
71
- actions_check(actions, ig_version: 'v221')
108
+ form_completion_count += cards.length + actions.length
72
109
 
73
- form_completion_check(card)
74
- end
110
+ perform_response_logical_model_validation(
111
+ cards,
112
+ actions,
113
+ request.request_body,
114
+ index,
115
+ '2.2.1'
116
+ )
75
117
  end
76
118
 
77
- questionnaire_create_actions =
78
- parsed_actions.select { |action| create_questionnaire_action_response_type?(action) } +
79
- form_completion_cards
80
- .flat_map { |card| card['suggestions'] }
81
- .flat_map { |suggestion| suggestion['actions'] }
82
- .compact
83
- .select { |action| create_questionnaire_action_response_type?(action) }
84
-
85
- questionnaire_create_actions.each { |action| questionnaire_creation_check(action) }
119
+ skip_if form_completion_count.zero?,
120
+ "#{tested_hook_name} hook responses do not contain any Request Form Completion cards or system actions."
86
121
 
87
- no_error_validation('Some Request Form Completion received are not valid.')
122
+ no_error_validation('Not all Request Form Completion responses were valid. See messages for more information.')
88
123
  end
89
124
  end
90
125
  end
@@ -34,6 +34,43 @@ module DaVinciCRDTestKit
34
34
  fallback_source_resource(request_body, target_type, target_id)
35
35
  end
36
36
 
37
+ def only_coverage_information_changed?(source_resource_hash, updated_resource_hash)
38
+ return true if coverage_information_extension_only_payload?(updated_resource_hash)
39
+
40
+ source_without_coverage_info = normalize_value(strip_coverage_info_extensions(source_resource_hash))
41
+ updated_without_coverage_info = normalize_value(strip_coverage_info_extensions(updated_resource_hash))
42
+
43
+ source_without_coverage_info == updated_without_coverage_info
44
+ end
45
+
46
+ def coverage_information_extension_only_payload?(resource_hash)
47
+ return false unless resource_hash.is_a?(Hash)
48
+
49
+ strip_coverage_info_extensions(resource_hash).keys.all? { |key| ['resourceType', 'id', 'meta'].include?(key) }
50
+ end
51
+
52
+ def strip_coverage_info_extensions(resource_hash)
53
+ normalized_hash = resource_hash.deep_dup
54
+ return normalized_hash unless normalized_hash['extension'].is_a?(Array)
55
+
56
+ normalized_hash['extension'] = normalized_hash['extension'].reject do |extension|
57
+ extension['url'] == DaVinciCRDTestKit::CardsIdentification::COVERAGE_INFO_EXT_URL
58
+ end
59
+ normalized_hash.delete('extension') if normalized_hash['extension'].empty?
60
+ normalized_hash
61
+ end
62
+
63
+ def normalize_value(value)
64
+ case value
65
+ when Hash
66
+ value.transform_values { |child| normalize_value(child) }
67
+ when Array
68
+ value.map { |child| normalize_value(child) }.sort_by(&:to_json)
69
+ else
70
+ value
71
+ end
72
+ end
73
+
37
74
  def find_appointment_book_resource(request_body, target_type, target_id)
38
75
  appointments_bundle = request_body.dig('context', 'appointments')
39
76
  find_resource_in_bundle(appointments_bundle, target_type, target_id) ||
@@ -1,6 +1,7 @@
1
1
  require_relative '../../server_test_helper'
2
2
  require_relative '../../server_hook_helper'
3
3
  require_relative '../../../cross_suite/cards_identification'
4
+ require_relative '../../../cross_suite/response_logical_model_validation'
4
5
 
5
6
  module DaVinciCRDTestKit
6
7
  module V221
@@ -8,24 +9,74 @@ module DaVinciCRDTestKit
8
9
  include DaVinciCRDTestKit::ServerTestHelper
9
10
  include DaVinciCRDTestKit::ServerHookHelper
10
11
  include DaVinciCRDTestKit::CardsIdentification
12
+ include DaVinciCRDTestKit::ResponseLogicalModelValidation
11
13
 
12
14
  title 'Instructions cards are valid'
13
15
  id :crd_v221_valid_instructions_card_received
14
16
  description %(
15
- This test validates that an [Instructions](https://hl7.org/fhir/us/davinci-crd/STU2/cards.html#instructions)
17
+ This test validates that an
18
+ [Instructions](https://hl7.org/fhir/us/davinci-crd/2.2.1/en/cards.html#instructions-response-type)
16
19
  card was received. It does so by:
17
- - Checking for the presence of a valid card that does not contain the `links` field and the `suggestions` field.
20
+ - Checking for the presence of a valid card that does not contain the
21
+ `links` field and the `suggestions` field.
22
+
23
+ The test will be skipped if no Instructions cards are found within the
24
+ returned valid cards.
18
25
  )
19
26
 
20
27
  verifies_requirements 'hl7.fhir.us.davinci-crd_2.2.1@resp-24'
21
28
 
22
- input :valid_cards
29
+ input :invoked_hook
30
+
23
31
  optional
24
32
 
33
+ def body_has_no_cards?(body)
34
+ !body.is_a?(Hash) ||
35
+ body['cards'].blank? ||
36
+ !body['cards'].is_a?(Array) ||
37
+ !body['cards'].all?(Hash)
38
+ end
39
+
40
+ def instructions_cards(request)
41
+ return [] if request.status != 200
42
+
43
+ response_body = JSON.parse(request.response_body)
44
+
45
+ return [] if body_has_no_cards?(response_body)
46
+
47
+ response_body['cards'].select { |card| instructions_response_type? card }
48
+ rescue JSON::ParserError
49
+ []
50
+ end
51
+
25
52
  run do
26
- parsed_cards = parse_json(valid_cards)
27
- instructions_card = parsed_cards.find { |card| instructions_response_type?(card) }
28
- assert instructions_card, "#{tested_hook_name} hook response did not contain an Instructions card."
53
+ load_tagged_requests(tested_hook_name)
54
+
55
+ instructions_count = 0
56
+
57
+ successful_requests = requests.select { |request| request.status == 200 }
58
+
59
+ skip_if successful_requests.blank?,
60
+ 'No successful hook responses were received'
61
+
62
+ requests.each_with_index do |request, index|
63
+ cards = instructions_cards(request)
64
+
65
+ instructions_count += cards.length
66
+
67
+ perform_response_logical_model_validation(
68
+ cards,
69
+ nil,
70
+ request.request_body,
71
+ index,
72
+ '2.2.1'
73
+ )
74
+ end
75
+
76
+ skip_if instructions_count.zero?,
77
+ "#{tested_hook_name} hook responses do not contain any Instructions cards."
78
+
79
+ no_error_validation('Not all Instructions cards were valid. See messages for more information.')
29
80
  end
30
81
  end
31
82
  end