Skip to content
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
6fa88b7
update invoke hook job to send a request with unknown configuration
Jammjammjamm May 15, 2026
34042d3
update invoke hook spec to check for unknown configuration request
Jammjammjamm May 15, 2026
c8c57f3
wip
Jammjammjamm May 15, 2026
8e9d841
add unknown configuration test to hook groups
Jammjammjamm May 15, 2026
fc04930
add spec for unknown configuration test
Jammjammjamm May 15, 2026
0b74d9d
remove unused method
Jammjammjamm May 15, 2026
852197b
add spec for unknown configuration test
Jammjammjamm May 15, 2026
b1e9de2
add request with unknown context to invoke hook job
Jammjammjamm May 15, 2026
e65e160
update invoke hook spec to check for unknown context request
Jammjammjamm May 15, 2026
07ca820
WIP
Jammjammjamm May 15, 2026
41d6669
add test for unknown context
Jammjammjamm May 15, 2026
a29493b
add spec for unknown context test
Jammjammjamm May 15, 2026
6c825a6
update invoke hook to send a request with an unknown cds hooks element
Jammjammjamm May 18, 2026
6e62279
update invoke hook specs to account for unknown cds hooks element call
Jammjammjamm May 18, 2026
398b33c
add test for unknown cds hooks elements
Jammjammjamm May 18, 2026
5a9e250
add spec for known cds hooks elements test
Jammjammjamm May 18, 2026
62e7472
update language in unknown element tests
Jammjammjamm May 18, 2026
a64fb1b
add requirements
Jammjammjamm May 19, 2026
340f21e
update requirements coverage
Jammjammjamm May 19, 2026
19a3495
document expected client test failures
Jammjammjamm May 21, 2026
feeffda
update expected failures docs
Jammjammjamm May 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/Running-Suites-Against-Each-Other.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,5 @@ Some tests will fail, including:
- Client test 2.1.2.01 will fail because the CRD client simulation in the Server suite does not automatically update the Bundle with
resource updates in `systemActions`.
- The server tests will fail as expected because no responses were sent by the client suite.
- Client tests validating that the hook requests conform to the logical model will fail because the server suite sends requests with unexpected fields to verify that the server ignores them.
Comment thread
karlnaden marked this conversation as resolved.
Outdated

3 changes: 3 additions & 0 deletions lib/davinci_crd_test_kit/cross_suite/tags.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ module DaVinciCRDTestKit
LONG_RUNNING_GROUP_TAG = 'long_running_request'.freeze
DUPLICATED_HOOK_INSTANCE_TAG = 'duplicate_hook_instance'.freeze
COVERAGE_INFO_DISABLED_TAG = 'coverage-info-disabled'.freeze
UNKNOWN_CONFIGURATION_TAG = 'unknown-configuration'.freeze
UNKNOWN_CONTEXT_TAG = 'unknown-context'.freeze
UNKNOWN_ELEMENT_TAG = 'unknown-element'.freeze

module TagMethods
def hook_instance_tag(hook_instance)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ hl7.fhir.us.davinci-crd_2.2.1,dev-9,https://hl7.org/fhir/us/davinci-crd/2.2.1/en
hl7.fhir.us.davinci-crd_2.2.1,dev-10,https://hl7.org/fhir/us/davinci-crd/2.2.1/en/deviations.html#ci-c-dev-10,CRD servers providing more than one type of coverage requirement information/guidance **SHOULD** expose configuration options allowing clients to dynamically control what information is returned by the service.,SHOULD,CRD Server,false,,,"",""
hl7.fhir.us.davinci-crd_2.2.1,dev-14,https://hl7.org/fhir/us/davinci-crd/2.2.1/en/deviations.html#ci-c-dev-14,CRD Servers **SHALL** behave in the manner prescribed by any supported configuration information received from the CRD Client.,SHALL,CRD Server,false,,,"",""
hl7.fhir.us.davinci-crd_2.2.1,dev-15,https://hl7.org/fhir/us/davinci-crd/2.2.1/en/deviations.html#ci-c-dev-15,CRD Servers **SHALL NOT** require the inclusion of configuration information in a hook call (i.e. no hook invocation is permitted to fail because configuration information was not included).,SHALL NOT,CRD Server,false,,,"",""
hl7.fhir.us.davinci-crd_2.2.1,dev-17,https://hl7.org/fhir/us/davinci-crd/2.2.1/en/deviations.html#ci-c-dev-17,CRD Servers **SHALL** ignore unsupported configuration information.,SHALL,CRD Server,false,,,"",""
hl7.fhir.us.davinci-crd_2.2.1,dev-17,https://hl7.org/fhir/us/davinci-crd/2.2.1/en/deviations.html#ci-c-dev-17,CRD Servers **SHALL** ignore unsupported configuration information.,SHALL,CRD Server,false,,,"3.1.3.12, 3.2.3.11, 3.3.3.11, 3.4.3.13, 3.5.3.12, 3.6.3.14","crd_server_v221-crd_v221_server_hooks-crd_v221_server_appointment_book-Group03-crd_v221_unknown_configuration, crd_server_v221-crd_v221_server_hooks-crd_v221_server_encounter_start-Group03-crd_v221_unknown_configuration, crd_server_v221-crd_v221_server_hooks-crd_v221_server_encounter_discharge-Group03-crd_v221_unknown_configuration, crd_server_v221-crd_v221_server_hooks-crd_v221_server_order_select-Group03-crd_v221_unknown_configuration, crd_server_v221-crd_v221_server_hooks-crd_v221_server_order_dispatch-Group03-crd_v221_unknown_configuration, crd_server_v221-crd_v221_server_hooks-crd_v221_server_order_sign-Group03-crd_v221_unknown_configuration"
hl7.fhir.us.davinci-crd_2.2.1,dev-19,https://hl7.org/fhir/us/davinci-crd/2.2.1/en/deviations.html#ci-c-dev-19,"When included with a Task, the creation of the Questionnaire needs to be conditional - it **SHOULD** only occur if that specific Questionnaire version does not already exist",SHOULD,CRD Server,false,,,"",""
hl7.fhir.us.davinci-crd_2.2.1,dev-20,https://hl7.org/fhir/us/davinci-crd/2.2.1/en/deviations.html#ci-c-dev-20,the CRD server **SHALL** query to determine if the client has a copy of the Questionnaire before sending the request.,SHALL,CRD Server,false,,,"",""
hl7.fhir.us.davinci-crd_2.2.1,dev-24,https://hl7.org/fhir/us/davinci-crd/2.2.1/en/deviations.html#ci-c-dev-24,"If a hook service is invoked on a collection of resources, all cards returned that are specific to only a subset of the resources passed as context **SHALL** disambiguate in the `detail` element which resources they are associated with in a human-friendly way.",SHALL,CRD Server,true,,,"",""
Expand All @@ -45,7 +45,7 @@ hl7.fhir.us.davinci-crd_2.2.1,found-27,https://hl7.org/fhir/us/davinci-crd/2.2.1
hl7.fhir.us.davinci-crd_2.2.1,found-28,https://hl7.org/fhir/us/davinci-crd/2.2.1/en/foundation.html#ci-c-found-28,"When information is only needed for certain invocations of the hook (e.g., for specific types of medications or services), that information **SHOULD** only be retrieved by query using the provided token, not requested universally via prefetch.",SHOULD,CRD Server,true,,,"",""
hl7.fhir.us.davinci-crd_2.2.1,found-29,https://hl7.org/fhir/us/davinci-crd/2.2.1/en/foundation.html#ci-c-found-29,Servers **SHALL** use prefetch expressions in the manner described below if those data elements are relevant to their coverage determination or other decision support.,SHALL,CRD Server,true,,,"",""
hl7.fhir.us.davinci-crd_2.2.1,found-32,https://hl7.org/fhir/us/davinci-crd/2.2.1/en/foundation.html#ci-c-found-32,HTTP 412 responses **SHALL NOT** be used in situations where the prefetch was provided or the query was successfully performed but the record in question did not have all the data the payer might have needed/desired.,SHALL NOT,CRD Server,false,,,"",""
hl7.fhir.us.davinci-crd_2.2.1,found-33,https://hl7.org/fhir/us/davinci-crd/2.2.1/en/foundation.html#ci-c-found-33,CRD clients and servers **SHALL** ignore unexpected elements when processing instances.,SHALL,"CRD Client,CRD Server",false,,,"",""
hl7.fhir.us.davinci-crd_2.2.1,found-33,https://hl7.org/fhir/us/davinci-crd/2.2.1/en/foundation.html#ci-c-found-33,CRD clients and servers **SHALL** ignore unexpected elements when processing instances.,SHALL,"CRD Client,CRD Server",false,,,"3.1.3.14, 3.2.3.13, 3.3.3.13, 3.4.3.15, 3.5.3.14, 3.6.3.16","crd_server_v221-crd_v221_server_hooks-crd_v221_server_appointment_book-Group03-crd_v221_unknown_cds_hooks_elements, crd_server_v221-crd_v221_server_hooks-crd_v221_server_encounter_start-Group03-crd_v221_unknown_cds_hooks_elements, crd_server_v221-crd_v221_server_hooks-crd_v221_server_encounter_discharge-Group03-crd_v221_unknown_cds_hooks_elements, crd_server_v221-crd_v221_server_hooks-crd_v221_server_order_select-Group03-crd_v221_unknown_cds_hooks_elements, crd_server_v221-crd_v221_server_hooks-crd_v221_server_order_dispatch-Group03-crd_v221_unknown_cds_hooks_elements, crd_server_v221-crd_v221_server_hooks-crd_v221_server_order_sign-Group03-crd_v221_unknown_cds_hooks_elements"
hl7.fhir.us.davinci-crd_2.2.1,found-34,https://hl7.org/fhir/us/davinci-crd/2.2.1/en/foundation.html#ci-c-found-34,CRD servers **SHALL** provide what coverage requirements they can based on the information available.,SHALL,CRD Server,false,,,"",""
hl7.fhir.us.davinci-crd_2.2.1,found-37,https://hl7.org/fhir/us/davinci-crd/2.2.1/en/foundation.html#ci-c-found-37,"Therefore, in addition to any logging performed for security purposes, both CRD clients and CRD servers **SHALL** retain logs of all CRD-related hook invocations and their responses for access in the event of a dispute.",SHALL,"CRD Client,CRD Server",false,,,"",""
hl7.fhir.us.davinci-crd_2.2.1,found-40,https://hl7.org/fhir/us/davinci-crd/2.2.1/en/foundation.html#ci-c-found-40,Conformant systems **SHOULD** omit non-significant whitespace in transmitted instances for performance reasons.,SHOULD,"CRD Client,CRD Server",false,,,"",""
Expand All @@ -59,7 +59,7 @@ hl7.fhir.us.davinci-crd_2.2.1,hook-14,https://hl7.org/fhir/us/davinci-crd/2.2.1/
hl7.fhir.us.davinci-crd_2.2.1,hook-16,https://hl7.org/fhir/us/davinci-crd/2.2.1/en/hooks.html#ci-c-hook-16,"Unless reporting an error or coverage information already exists and there is no new information, CRD Servers **SHALL** include a Coverage Information system action in the response for 'primary' hooks, even if the response indicates that further information is needed or that the level of detail provided is insufficient to determine coverage.",SHALL,CRD Server,false,,,"3.1.3.08, 3.5.3.08, 3.6.3.08","crd_server_v221-crd_v221_server_hooks-crd_v221_server_appointment_book-Group03-crd_v221_all_responses_include_coverage_information, crd_server_v221-crd_v221_server_hooks-crd_v221_server_order_dispatch-Group03-crd_v221_order_dispatch_coverage_information, crd_server_v221-crd_v221_server_hooks-crd_v221_server_order_sign-Group03-crd_v221_all_responses_include_coverage_information"
hl7.fhir.us.davinci-crd_2.2.1,hook-19,https://hl7.org/fhir/us/davinci-crd/2.2.1/en/hooks.html#ci-c-hook-19,"If Coverage Information is returned for these hooks, it **SHALL NOT** include messages indicating a need for [clinical](https://hl7.org/fhir/us/davinci-crd/2.2.1/en/ValueSet-AdditionalDocumentation.html) or [administrative](https://hl7.org/fhir/us/davinci-crd/2.2.1/en/ValueSet-AdditionalDocumentation.html) information, as such information is expected to be made available later in the process and therefore such guidance is not useful.",SHALL NOT,CRD Server,true,,,"",""
hl7.fhir.us.davinci-crd_2.2.1,hook-22,https://hl7.org/fhir/us/davinci-crd/2.2.1/en/hooks.html#ci-c-hook-22,CRD servers **SHALL NOT** depend on data not covered by the identified profiles in order to return valid coverage-information responses.,SHALL NOT,CRD Server,false,,,"",""
hl7.fhir.us.davinci-crd_2.2.1,hook-23,https://hl7.org/fhir/us/davinci-crd/2.2.1/en/hooks.html#ci-c-hook-23,CRD Servers **SHALL** handle unrecognized context elements by ignoring them.,SHALL,CRD Server,false,,,"",""
hl7.fhir.us.davinci-crd_2.2.1,hook-23,https://hl7.org/fhir/us/davinci-crd/2.2.1/en/hooks.html#ci-c-hook-23,CRD Servers **SHALL** handle unrecognized context elements by ignoring them.,SHALL,CRD Server,false,,,"3.1.3.13, 3.2.3.12, 3.3.3.12, 3.4.3.14, 3.5.3.13, 3.6.3.15","crd_server_v221-crd_v221_server_hooks-crd_v221_server_appointment_book-Group03-crd_v221_unknown_context, crd_server_v221-crd_v221_server_hooks-crd_v221_server_encounter_start-Group03-crd_v221_unknown_context, crd_server_v221-crd_v221_server_hooks-crd_v221_server_encounter_discharge-Group03-crd_v221_unknown_context, crd_server_v221-crd_v221_server_hooks-crd_v221_server_order_select-Group03-crd_v221_unknown_context, crd_server_v221-crd_v221_server_hooks-crd_v221_server_order_dispatch-Group03-crd_v221_unknown_context, crd_server_v221-crd_v221_server_hooks-crd_v221_server_order_sign-Group03-crd_v221_unknown_context"
hl7.fhir.us.davinci-crd_2.2.1,hook-25,https://hl7.org/fhir/us/davinci-crd/2.2.1/en/hooks.html#ci-c-hook-25,CRD Servers **MAY** use the appointment-book hook as a basis for associating a patient with a particular practitioner from a payer attribution perspective.,MAY,CRD Server,false,,,"",""
hl7.fhir.us.davinci-crd_2.2.1,hook-26,https://hl7.org/fhir/us/davinci-crd/2.2.1/en/hooks.html#ci-c-hook-26,"CRD clients and servers **SHALL**, at minimum, support returning and processing the [Coverage Information](https://hl7.org/fhir/us/davinci-crd/2.2.1/en/StructureDefinition-ext-coverage-information.html) system action for all invocations of the appointment-book hook.",SHALL,"CRD Client,CRD Server",false,,,3.1.3.08,crd_server_v221-crd_v221_server_hooks-crd_v221_server_appointment_book-Group03-crd_v221_all_responses_include_coverage_information
hl7.fhir.us.davinci-crd_2.2.1,hook-28,https://hl7.org/fhir/us/davinci-crd/2.2.1/en/hooks.html#ci-c-hook-28,CRD Servers **MAY** use the encounter-start hook as a basis for associating a patient with a particular practitioner from a payer attribution perspective.,MAY,CRD Server,false,,,"",""
Expand Down
65 changes: 65 additions & 0 deletions lib/davinci_crd_test_kit/server/jobs/invoke_hook.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,11 @@ def perform_hook_invocations(request_bodies)
request_body = prepare_hook_request(request)
response = send_hook_invocation(request_body.to_json)
send_coverage_info_configuration_invocation(request_body, response)
send_unknown_configuration_invocation(request_body, response)
send_unknown_context_invocation(request_body, response)
send_unknown_cds_hooks_element_invocation(request_body, response)
end

return unless test_waiting?

# end the wait to continue the tests
Expand Down Expand Up @@ -128,6 +132,67 @@ def send_coverage_info_configuration_invocation(request_body, response)
@coverage_info_configuration_invoked = true
end

def send_unknown_configuration_invocation(request_body, response)
return if @unknown_configuration_invoked
return unless response.status == 200
return unless coverage_info_response?(parsed_response_body(response))
return unless test_waiting?

request_body = JSON.parse(request_body.to_json)
prepare_hook_request(request_body)
add_unknown_configuration(request_body)
send_hook_invocation(request_body.to_json, [UNKNOWN_CONFIGURATION_TAG])

@unknown_configuration_invoked = true
end

def send_unknown_context_invocation(request_body, response)
return if @unknown_context_invoked
return unless response.status == 200
return unless coverage_info_response?(parsed_response_body(response))
return unless test_waiting?

request_body = JSON.parse(request_body.to_json)
prepare_hook_request(request_body)
add_unknown_context(request_body)
send_hook_invocation(request_body.to_json, [UNKNOWN_CONTEXT_TAG])

@unknown_context_invoked = true
end

def send_unknown_cds_hooks_element_invocation(request_body, response)
return if @unknown_cds_hooks_element_invoked
return unless response.status == 200
return unless coverage_info_response?(parsed_response_body(response))
return unless test_waiting?

request_body = JSON.parse(request_body.to_json)
prepare_hook_request(request_body)
add_unknown_element(request_body)
send_hook_invocation(request_body.to_json, [UNKNOWN_ELEMENT_TAG])

@unknown_cds_hooks_element_invoked = true
end

def random_key
('a'..'z').to_a.sample(16).join
end

def add_unknown_configuration(request_body)
request_body['extension'] ||= {}
request_body['extension']['davinci-crd.configuration'] ||= {}
request_body['extension']['davinci-crd.configuration'][random_key] = true
end

def add_unknown_context(request_body)
request_body['context'] ||= {}
request_body['context'][random_key] ||= random_key
end

def add_unknown_element(request_body)
request_body[random_key] ||= random_key
end

def parsed_response_body(response)
JSON.parse(response.env.response_body.to_s)
rescue JSON::ParserError, TypeError
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
require_relative 'verify_response/launch_smart_app_card_validation_test'
require_relative 'verify_response/create_or_update_coverage_info_response_validation_test'
require_relative 'verify_response/all_responses_include_coverage_information_test'
require_relative 'verify_response/unknown_configuration_test'
require_relative 'verify_response/unknown_context_test'
require_relative 'verify_response/unknown_cds_hooks_elements_test'

module DaVinciCRDTestKit
module V221
Expand Down Expand Up @@ -200,6 +203,9 @@ class ServerAppointmentBookGroup < Inferno::TestGroup
}
}
test from: :crd_v221_coverage_info_configuration
test from: :crd_v221_unknown_configuration
test from: :crd_v221_unknown_context
test from: :crd_v221_unknown_cds_hooks_elements
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
require_relative 'verify_response/form_completion_response_validation_test'
require_relative 'verify_response/create_or_update_coverage_info_response_validation_test'
require_relative 'verify_response/coverage_info_configuration_test'
require_relative 'verify_response/unknown_configuration_test'
require_relative 'verify_response/unknown_context_test'
require_relative 'verify_response/unknown_cds_hooks_elements_test'

module DaVinciCRDTestKit
module V221
Expand Down Expand Up @@ -182,6 +185,9 @@ class ServerEncounterDischargeGroup < Inferno::TestGroup
}
}
test from: :crd_v221_coverage_info_configuration
test from: :crd_v221_unknown_configuration
test from: :crd_v221_unknown_context
test from: :crd_v221_unknown_cds_hooks_elements
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
require_relative 'verify_response/form_completion_response_validation_test'
require_relative 'verify_response/create_or_update_coverage_info_response_validation_test'
require_relative 'verify_response/coverage_info_configuration_test'
require_relative 'verify_response/unknown_configuration_test'
require_relative 'verify_response/unknown_context_test'
require_relative 'verify_response/unknown_cds_hooks_elements_test'

module DaVinciCRDTestKit
module V221
Expand Down Expand Up @@ -182,6 +185,9 @@ class ServerEncounterStartGroup < Inferno::TestGroup
}
}
test from: :crd_v221_coverage_info_configuration
test from: :crd_v221_unknown_configuration
test from: :crd_v221_unknown_context
test from: :crd_v221_unknown_cds_hooks_elements
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
require_relative 'verify_response/form_completion_response_validation_test'
require_relative 'verify_response/create_or_update_coverage_info_response_validation_test'
require_relative 'verify_response/order_dispatch_coverage_information_test'
require_relative 'verify_response/unknown_configuration_test'
require_relative 'verify_response/unknown_context_test'
require_relative 'verify_response/unknown_cds_hooks_elements_test'

module DaVinciCRDTestKit
module V221
Expand Down Expand Up @@ -201,6 +204,9 @@ class ServerOrderDispatchGroup < Inferno::TestGroup
}
}
test from: :crd_v221_coverage_info_configuration
test from: :crd_v221_unknown_configuration
test from: :crd_v221_unknown_context
test from: :crd_v221_unknown_cds_hooks_elements
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
require_relative 'verify_response/form_completion_response_validation_test'
require_relative 'verify_response/create_or_update_coverage_info_response_validation_test'
require_relative 'verify_response/coverage_info_configuration_test'
require_relative 'verify_response/unknown_configuration_test'
require_relative 'verify_response/unknown_context_test'
require_relative 'verify_response/unknown_cds_hooks_elements_test'

module DaVinciCRDTestKit
module V221
Expand Down Expand Up @@ -207,6 +210,9 @@ class ServerOrderSelectGroup < Inferno::TestGroup
}
}
test from: :crd_v221_coverage_info_configuration
test from: :crd_v221_unknown_configuration
test from: :crd_v221_unknown_context
test from: :crd_v221_unknown_cds_hooks_elements
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
require_relative 'verify_response/form_completion_response_validation_test'
require_relative 'verify_response/create_or_update_coverage_info_response_validation_test'
require_relative 'verify_response/all_responses_include_coverage_information_test'
require_relative 'verify_response/unknown_configuration_test'
require_relative 'verify_response/unknown_context_test'
require_relative 'verify_response/unknown_cds_hooks_elements_test'

module DaVinciCRDTestKit
module V221
Expand Down Expand Up @@ -228,6 +231,9 @@ class ServerOrderSignGroup < Inferno::TestGroup
}
}
test from: :crd_v221_coverage_info_configuration
test from: :crd_v221_unknown_configuration
test from: :crd_v221_unknown_context
test from: :crd_v221_unknown_cds_hooks_elements
end
end
end
Expand Down
Loading