davinci_crd_test_kit 0.14.1 → 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.
- checksums.yaml +4 -4
- data/config/presets/{inferno_crd_server_suite.json.erb → client_against_inferno_crd_server_suite.json.erb} +0 -33
- data/config/presets/{ri_crd_request_generator.json.erb → client_against_ri_crd_request_generator.json.erb} +1 -14
- data/config/presets/client_v221_against_inferno_crd_server_suite.json.erb +84 -0
- data/config/presets/client_v221_against_ri_br_provider.json.erb +31 -0
- data/config/presets/{ri_crd_request_generator.json_v221.json.erb → client_v221_against_ri_crd_request_generator.json.erb} +1 -1
- data/config/presets/{inferno_crd_client_suite.json.erb → server_against_inferno_crd_client_suite.json.erb} +0 -43
- data/config/presets/{ri_crd_server.json.erb → server_against_ri_crd_server.json.erb} +1 -44
- data/config/presets/{inferno_crd_client_suite_v221.json.erb → server_v221_against_inferno_crd_client_suite.json.erb} +0 -61
- 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
- data/config/presets/server_v221_against_inferno_g31_suite.json.erb +49 -0
- data/lib/davinci_crd_test_kit/client/cross_hook_helper.rb +26 -0
- data/lib/davinci_crd_test_kit/client/endpoints/custom_service_response.rb +7 -7
- data/lib/davinci_crd_test_kit/client/endpoints/gather_response_generation_data.rb +4 -1
- data/lib/davinci_crd_test_kit/client/endpoints/hook_request_endpoint.rb +63 -38
- data/lib/davinci_crd_test_kit/client/endpoints/mock_service_response.rb +26 -7
- data/lib/davinci_crd_test_kit/client/endpoints/scenario_service_response.rb +54 -0
- data/lib/davinci_crd_test_kit/client/tagged_request_load_helper.rb +8 -27
- data/lib/davinci_crd_test_kit/client/v2.0.1/auth/retrieve_jwks_test.rb +35 -23
- data/lib/davinci_crd_test_kit/client/v2.0.1/auth/token_payload_test.rb +34 -21
- data/lib/davinci_crd_test_kit/client/v2.0.1/cds-services-v201.json +20 -20
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_appointment_book_group.rb +12 -10
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_encounter_discharge_group.rb +12 -10
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_encounter_start_group.rb +12 -10
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_hooks_group.rb +5 -5
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_order_dispatch_group.rb +12 -10
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_order_select_group.rb +12 -10
- data/lib/davinci_crd_test_kit/client/v2.0.1/client_order_sign_group.rb +12 -10
- data/lib/davinci_crd_test_kit/client/v2.0.1/must_support/client_card_must_support_coverage_information.rb +3 -36
- data/lib/davinci_crd_test_kit/client/v2.0.1/must_support/client_card_must_support_external_reference.rb +3 -36
- data/lib/davinci_crd_test_kit/client/v2.0.1/must_support/client_card_must_support_instructions.rb +3 -36
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_fetched_data_test.rb +4 -13
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_request/hook_request_prefetch_equals_queried_test.rb +3 -13
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_response/client_display_cards_attest.rb +3 -13
- data/lib/davinci_crd_test_kit/client/v2.0.1/verify_response/inferno_response_validation.rb +3 -13
- data/lib/davinci_crd_test_kit/client/v2.2.1/api/client_coverage_info_update_test.rb +1 -1
- data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/attestation_instructions.rb +10 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_authorized_scope_attestation_test.rb +45 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_coverage_based_invocation_attestation_test.rb +44 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_data_element_expectations_attestation_test.rb +44 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_hook_invocation_logging_attestation_test.rb +43 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_must_support_exposure_attestation_test.rb +43 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_must_support_use_attestation_test.rb +41 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_order_sign_support_attestation_test.rb +42 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_prefetch_key_omission_attestation_test.rb +42 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_resource_identifiers_attestation_test.rb +43 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_response_case_distinction_attestation_test.rb +43 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_security_and_privacy_attestation_test.rb +43 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/attestations/client_workflow_integration_attestation_test.rb +44 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/auth/decode_auth_token_test.rb +1 -1
- data/lib/davinci_crd_test_kit/client/v2.2.1/auth/retrieve_jwks_test.rb +29 -18
- data/lib/davinci_crd_test_kit/client/v2.2.1/auth/token_payload_test.rb +35 -22
- data/lib/davinci_crd_test_kit/client/v2.2.1/cds-services-prefetch-subset-v221.json +47 -47
- data/lib/davinci_crd_test_kit/client/v2.2.1/cds-services-v221.json +50 -50
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_appointment_book_group.rb +16 -14
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_attestations_group.rb +49 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_cross_hook_group.rb +22 -6
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_cross_hook_interaction_group.rb +98 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_encounter_discharge_group.rb +12 -10
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_encounter_start_group.rb +12 -10
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_fhir_api_group.rb +14 -12
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_hooks_group.rb +9 -9
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_long_running_hook_group.rb +2 -1
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_order_dispatch_group.rb +16 -14
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_order_select_group.rb +12 -10
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_order_sign_group.rb +16 -14
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_scenarios_group.rb +26 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_self_pay_hook_group.rb +36 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/client_unknown_content_hook_group.rb +34 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/crd_client_suite.rb +19 -3
- data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_card_must_support_coverage_information_test.rb +1 -1
- data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_fhirpath_collection_as_comma_delimited_string_test.rb +4 -11
- data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_hook_instances_unique_test.rb +1 -9
- data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_location_address_propagation_test.rb +6 -2
- data/lib/davinci_crd_test_kit/client/v2.2.1/cross_hook/client_prefetch_complete_and_subset_test.rb +3 -12
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/appointment_book_receive_request_test.rb +8 -89
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/base_hook_invocation_receive_request_test.rb +163 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/cross_hooks_receive_request_test.rb +97 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/encounter_discharge_receive_request_test.rb +8 -90
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/encounter_start_receive_request_test.rb +8 -90
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/order_dispatch_receive_request_test.rb +8 -98
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/order_select_receive_request_test.rb +8 -98
- data/lib/davinci_crd_test_kit/client/v2.2.1/invocation/order_sign_receive_request_test.rb +8 -98
- data/lib/davinci_crd_test_kit/client/v2.2.1/long_running/client_long_running_receive_request_test.rb +10 -2
- data/lib/davinci_crd_test_kit/client/v2.2.1/long_running/client_skip_long_running_attestation_test.rb +1 -1
- data/lib/davinci_crd_test_kit/client/v2.2.1/self_pay/client_self_pay_no_request_test.rb +30 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/self_pay/client_self_pay_workflow_test.rb +55 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/unknown_content/client_unknown_content_attestation_test.rb +99 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/unknown_content/client_unknown_content_receive_request_test.rb +62 -0
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_conformance_test.rb +1 -1
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_coverage_verification_test.rb +10 -2
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_data_fetch_verification_test.rb +1 -1
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_granted_scopes_test.rb +1 -1
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_prefetch_complete_test.rb +1 -1
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_prefetch_profiles_test.rb +1 -1
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_requested_version_test.rb +1 -1
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_secured_transport_test.rb +1 -1
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_response/client_display_cards_attest.rb +52 -20
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_response/hook_response_support_coverage_information_test.rb +1 -1
- data/lib/davinci_crd_test_kit/client/v2.2.1/verify_response/inferno_response_validation.rb +6 -3
- data/lib/davinci_crd_test_kit/cross_suite/cards_identification.rb +9 -0
- data/lib/davinci_crd_test_kit/cross_suite/logical_models_override_helper.rb +30 -13
- data/lib/davinci_crd_test_kit/cross_suite/prefetch_profile_validation.rb +2 -0
- data/lib/davinci_crd_test_kit/cross_suite/requests_logical_model_validation.rb +26 -27
- data/lib/davinci_crd_test_kit/cross_suite/response_logical_model_validation.rb +48 -41
- data/lib/davinci_crd_test_kit/cross_suite/tags.rb +3 -0
- data/lib/davinci_crd_test_kit/requirements/cds-hooks_3.0.0-ballot_requirements.xlsx +0 -0
- data/lib/davinci_crd_test_kit/requirements/davinci_crd_test_kit_requirements.csv +6 -2
- data/lib/davinci_crd_test_kit/requirements/generated/crd_client_requirements_coverage.csv +107 -107
- data/lib/davinci_crd_test_kit/requirements/generated/crd_client_v221_requirements_coverage.csv +101 -97
- data/lib/davinci_crd_test_kit/requirements/generated/crd_server_requirements_coverage.csv +18 -18
- data/lib/davinci_crd_test_kit/requirements/generated/crd_server_v221_requirements_coverage.csv +36 -32
- data/lib/davinci_crd_test_kit/requirements/hl7.fhir.us.davinci-crd_2.2.1_requirements.xlsx +0 -0
- data/lib/davinci_crd_test_kit/server/v2.0.1/crd_server_suite.rb +1 -1
- data/lib/davinci_crd_test_kit/server/v2.0.1/server_hooks_group.rb +5 -5
- data/lib/davinci_crd_test_kit/server/v2.2.1/discovery/discovery_standard_prefetch_expressions_test.rb +1 -2
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_demonstrate_hook_response_group.rb +2 -2
- data/lib/davinci_crd_test_kit/server/v2.2.1/server_hooks_group.rb +5 -5
- data/lib/davinci_crd_test_kit/version.rb +2 -2
- metadata +40 -12
- data/config/presets/inferno_crd_server_suite_v221.json.erb +0 -94
data/lib/davinci_crd_test_kit/client/v2.2.1/long_running/client_long_running_receive_request_test.rb
CHANGED
|
@@ -44,8 +44,16 @@ module DaVinciCRDTestKit
|
|
|
44
44
|
message: %(
|
|
45
45
|
**Long Running Hook Request Test**:
|
|
46
46
|
|
|
47
|
-
Invoke any supported hook
|
|
48
|
-
|
|
47
|
+
Invoke any supported hook on one of the two Inferno simulated
|
|
48
|
+
CRD servers discoverable at the following endpoints:
|
|
49
|
+
|
|
50
|
+
- Complete Prefetch: `#{discovery_url}`
|
|
51
|
+
- Subset Prefetch: `#{prefetch_subset_discovery_url}`
|
|
52
|
+
|
|
53
|
+
For Inferno to recognize these requests and associate them with this session,
|
|
54
|
+
the authentication JWT sent as a Bearer token in the Authorization header
|
|
55
|
+
must have `#{cds_jwt_iss}` as the `iss` claim in the JWT payload. This test
|
|
56
|
+
will automatically continue once Inferno has received a request, paused
|
|
49
57
|
for #{long_running_pause_time.to_i} seconds, and returned a response.
|
|
50
58
|
|
|
51
59
|
Users must have the option to continue
|
|
@@ -26,7 +26,7 @@ module DaVinciCRDTestKit
|
|
|
26
26
|
output :attest_false_url
|
|
27
27
|
|
|
28
28
|
run do
|
|
29
|
-
long_running_requests =
|
|
29
|
+
long_running_requests = load_interaction_group_requests
|
|
30
30
|
skip_if long_running_requests.blank?, 'Long-running requests not demonstrated: ' \
|
|
31
31
|
'no hook requests sent during the previous wait.'
|
|
32
32
|
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require_relative '../../tagged_request_load_helper'
|
|
2
|
+
|
|
3
|
+
module DaVinciCRDTestKit
|
|
4
|
+
module V221
|
|
5
|
+
class ClientSelfPayNoRequestTest < Inferno::Test
|
|
6
|
+
include DaVinciCRDTestKit::TaggedRequestLoadHelper
|
|
7
|
+
|
|
8
|
+
id :crd_v221_client_self_pay_no_request
|
|
9
|
+
title 'Client does not invoke hooks during self-pay workflows'
|
|
10
|
+
description %(
|
|
11
|
+
The CRD IG [requires](https://hl7.org/fhir/us/davinci-crd/2.2.1/en/deviations.html#ci-c-dev-26)
|
|
12
|
+
that client systems only invoke hooks on payer services where the patient record indicates
|
|
13
|
+
active coverage with the payer associated with the service and where there is no recorded
|
|
14
|
+
indication the patient intends to bypass insurance coverage, i.e., the service or product
|
|
15
|
+
is not flagged as 'self-pay'. During this test, Inferno verifies that the client did not
|
|
16
|
+
make any hook requests when the tester performed a self-pay workflow during the
|
|
17
|
+
previous test.
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
verifies_requirements 'hl7.fhir.us.davinci-crd_2.2.1@dev-26'
|
|
21
|
+
|
|
22
|
+
run do
|
|
23
|
+
self_pay_requests = load_interaction_group_requests
|
|
24
|
+
|
|
25
|
+
assert self_pay_requests.blank?,
|
|
26
|
+
'Inferno incorrectly received a hook request for a service marked as self-pay.'
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
require_relative '../client_urls'
|
|
2
|
+
|
|
3
|
+
module DaVinciCRDTestKit
|
|
4
|
+
module V221
|
|
5
|
+
class ClientSelfPayWorkflowTest < Inferno::Test
|
|
6
|
+
include ClientURLs
|
|
7
|
+
|
|
8
|
+
id :crd_v221_client_self_pay_workflow
|
|
9
|
+
title 'Client performs a self-pay workflow'
|
|
10
|
+
description %(
|
|
11
|
+
During this test, the tester will perform a self-pay scenario in which a patient has indicated
|
|
12
|
+
that they will pay for a service instead of asking their insurance to cover it. Because there
|
|
13
|
+
is a recorded indication that the patient intends to bypass insurance coverage, the client
|
|
14
|
+
is required to not invoke any hooks that would send details of the service to the payer.
|
|
15
|
+
The scenario must include an action related to the service that would normally trigger a
|
|
16
|
+
hook request and Inferno will verify that no hook requests are received.
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
input :cds_jwt_iss,
|
|
20
|
+
title: 'CRD JWT Issuer',
|
|
21
|
+
description: %(
|
|
22
|
+
Value of the `iss` claim that must be present in the JWT used to authorize the client's hook
|
|
23
|
+
request sent as the Bearer token in the `Authorization` header.
|
|
24
|
+
Run or re-run the "Registration" group to set or change this value.
|
|
25
|
+
),
|
|
26
|
+
locked: true
|
|
27
|
+
output :continuation_url
|
|
28
|
+
|
|
29
|
+
run do
|
|
30
|
+
identifier = cds_jwt_iss
|
|
31
|
+
continuation_url = "#{resume_pass_url}?token=#{identifier}"
|
|
32
|
+
output(continuation_url:)
|
|
33
|
+
|
|
34
|
+
wait(
|
|
35
|
+
identifier:,
|
|
36
|
+
message: %(
|
|
37
|
+
**Self-Pay Workflow Test**:
|
|
38
|
+
|
|
39
|
+
Perform a workflow that would normally trigger a hook request, such as one
|
|
40
|
+
performed during previous tests, but for a service or product where the patient
|
|
41
|
+
record contains an indication that the patient intends to self-pay. The client must
|
|
42
|
+
not send any hook requests to Inferno during the workflow.
|
|
43
|
+
|
|
44
|
+
By [clicking here](#{continuation_url}) I attest that a user completed a workflow
|
|
45
|
+
in the client system that would normally trigger a hook request for a service that
|
|
46
|
+
has been marked as self-pay.
|
|
47
|
+
|
|
48
|
+
If Inferno receives a hook request, this test will automatically continue
|
|
49
|
+
and the next test will fail.
|
|
50
|
+
)
|
|
51
|
+
)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
require_relative '../client_urls'
|
|
2
|
+
require_relative '../../../cross_suite/cards_identification'
|
|
3
|
+
require_relative '../../tagged_request_load_helper'
|
|
4
|
+
|
|
5
|
+
module DaVinciCRDTestKit
|
|
6
|
+
module V221
|
|
7
|
+
class ClientUnknownContentAttestationTest < Inferno::Test
|
|
8
|
+
include ClientURLs
|
|
9
|
+
include CardsIdentification
|
|
10
|
+
include DaVinciCRDTestKit::TaggedRequestLoadHelper
|
|
11
|
+
|
|
12
|
+
KNOWN_ACTION_ELEMENTS = ['type', 'description', 'resource', 'resourceId', 'extension'].freeze
|
|
13
|
+
|
|
14
|
+
id :crd_v221_client_unknown_content_attestation_test
|
|
15
|
+
title 'Client processes coverage information returned with unknown content'
|
|
16
|
+
description %(
|
|
17
|
+
The CRD IG [requires](https://hl7.org/fhir/us/davinci-crd/2.2.1/en/foundation.html#ci-c-found-33)
|
|
18
|
+
that client systems ignore unexpected elements within CDS Hooks structures when processing
|
|
19
|
+
instances. During this test, the tester will confirm that the unknown element and custom extension
|
|
20
|
+
included in the CDS section of the previous response did not prevent the client system from
|
|
21
|
+
processing the returned coverage information and making it available to the user.
|
|
22
|
+
)
|
|
23
|
+
attestation
|
|
24
|
+
|
|
25
|
+
verifies_requirements 'hl7.fhir.us.davinci-crd_2.2.1@found-33'
|
|
26
|
+
|
|
27
|
+
output :attest_true_url
|
|
28
|
+
output :attest_false_url
|
|
29
|
+
|
|
30
|
+
def response_bodies(hook_requests)
|
|
31
|
+
hook_requests.filter_map do |request|
|
|
32
|
+
body = JSON.parse(request.response_body)
|
|
33
|
+
body if body.is_a?(Hash)
|
|
34
|
+
rescue JSON::ParserError
|
|
35
|
+
nil
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def unknown_action_elements(bodies)
|
|
40
|
+
bodies.flat_map do |body|
|
|
41
|
+
body['systemActions'].to_a.flat_map { |action| action.keys - KNOWN_ACTION_ELEMENTS }
|
|
42
|
+
end.uniq
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def unknown_extensions(bodies)
|
|
46
|
+
bodies.flat_map { |body| body['extension'].is_a?(Hash) ? body['extension'].keys : [] }.uniq
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def format_unknown_content(bodies)
|
|
50
|
+
[
|
|
51
|
+
format_unknown_names('System action element name', unknown_action_elements(bodies)),
|
|
52
|
+
format_unknown_names('Response extension name', unknown_extensions(bodies))
|
|
53
|
+
].compact.join("\n")
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def format_unknown_names(label, names)
|
|
57
|
+
return if names.blank?
|
|
58
|
+
|
|
59
|
+
"- #{label}: #{names.map { |name| "`#{name}`" }.join(', ')}"
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
run do
|
|
63
|
+
hook_requests = load_interaction_group_requests
|
|
64
|
+
skip_if hook_requests.blank?, 'Unknown response content not demonstrated: ' \
|
|
65
|
+
'no hook requests sent during the previous wait.'
|
|
66
|
+
|
|
67
|
+
bodies = response_bodies(hook_requests)
|
|
68
|
+
skip_if bodies.none? { |body| coverage_info_system_action_response?(body) },
|
|
69
|
+
'Unknown response content not demonstrated: ' \
|
|
70
|
+
'no coverage information system action was returned.'
|
|
71
|
+
|
|
72
|
+
identifier = SecureRandom.hex(32)
|
|
73
|
+
attest_true_url = "#{resume_pass_url}?token=#{identifier}"
|
|
74
|
+
attest_false_url = "#{resume_fail_url}?token=#{identifier}"
|
|
75
|
+
output(attest_true_url:)
|
|
76
|
+
output(attest_false_url:)
|
|
77
|
+
wait(
|
|
78
|
+
identifier:,
|
|
79
|
+
message: <<~MESSAGE
|
|
80
|
+
**Unknown Response Content Attestation**:
|
|
81
|
+
|
|
82
|
+
Inferno returned coverage information along with the following content that is
|
|
83
|
+
not defined by CRD or CDS Hooks:
|
|
84
|
+
|
|
85
|
+
#{format_unknown_content(bodies)}
|
|
86
|
+
|
|
87
|
+
I attest that this unexpected content did not prevent the client system from
|
|
88
|
+
processing the coverage information returned in the same response and that the
|
|
89
|
+
coverage information was displayed or otherwise made available to the user:
|
|
90
|
+
|
|
91
|
+
[Click here](#{attest_true_url}) if the above statement is **true**.
|
|
92
|
+
|
|
93
|
+
[Click here](#{attest_false_url}) if the above statement is **false**.
|
|
94
|
+
MESSAGE
|
|
95
|
+
)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
require_relative '../client_urls'
|
|
2
|
+
|
|
3
|
+
module DaVinciCRDTestKit
|
|
4
|
+
module V221
|
|
5
|
+
class ClientUnknownContentReceiveRequestTest < Inferno::Test
|
|
6
|
+
include ClientURLs
|
|
7
|
+
|
|
8
|
+
id :crd_v221_client_unknown_content_receive_request
|
|
9
|
+
title 'Client invokes any hook'
|
|
10
|
+
description %(
|
|
11
|
+
During this test, Inferno will wait while the client makes a single hook request of any type.
|
|
12
|
+
Inferno will return a fixed [mocked response](https://github.com/inferno-framework/davinci-crd-test-kit/wiki/Controlling-Simulated-Responses#mocked-responses)
|
|
13
|
+
containing a coverage information system action along with content that the client is not
|
|
14
|
+
expected to recognize: an element added to the system action and a custom extension added to
|
|
15
|
+
the response, both with randomly generated names. This content is added at the CRD response
|
|
16
|
+
level rather than within the FHIR resources carried in the response, and testers cannot change
|
|
17
|
+
the response that is returned. The details of the request and its response do not matter for
|
|
18
|
+
the purposes of this test and they will not be evaluated, checked for conformance, or included
|
|
19
|
+
in cross-hook evaluations. The test will automatically continue after Inferno receives a hook
|
|
20
|
+
request and returns a response.
|
|
21
|
+
)
|
|
22
|
+
config options: { accepts_multiple_requests: true }
|
|
23
|
+
|
|
24
|
+
input :cds_jwt_iss,
|
|
25
|
+
title: 'CRD JWT Issuer',
|
|
26
|
+
description: %(
|
|
27
|
+
Value of the `iss` claim that must be present in the JWT used to authorize the client's hook
|
|
28
|
+
request sent as the Bearer token in the `Authorization` header.
|
|
29
|
+
Run or re-run the "Registration" group to set or change this value.
|
|
30
|
+
),
|
|
31
|
+
locked: true
|
|
32
|
+
|
|
33
|
+
run do
|
|
34
|
+
identifier = cds_jwt_iss
|
|
35
|
+
wait(
|
|
36
|
+
identifier:,
|
|
37
|
+
message: %(
|
|
38
|
+
**Unknown Response Content Test**:
|
|
39
|
+
|
|
40
|
+
Invoke any supported hook on one of the two Inferno simulated
|
|
41
|
+
CRD servers discoverable at the following endpoints:
|
|
42
|
+
|
|
43
|
+
- Complete Prefetch: `#{discovery_url}`
|
|
44
|
+
- Subset Prefetch: `#{prefetch_subset_discovery_url}`
|
|
45
|
+
|
|
46
|
+
For Inferno to recognize these requests and associate them with this session,
|
|
47
|
+
the authentication JWT sent as a Bearer token in the Authorization header
|
|
48
|
+
must have `#{cds_jwt_iss}` as the `iss` claim in the JWT payload. The test
|
|
49
|
+
will automatically continue once Inferno has received a request and returned
|
|
50
|
+
a response.
|
|
51
|
+
|
|
52
|
+
The response will include coverage information alongside an element and a
|
|
53
|
+
custom extension whose names are not defined by CRD or CDS Hooks. Clients
|
|
54
|
+
must ignore the content they do not recognize and process the coverage
|
|
55
|
+
information as usual. Testers will be asked to attest that this was
|
|
56
|
+
demonstrated in the next test.
|
|
57
|
+
)
|
|
58
|
+
)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -24,7 +24,7 @@ module DaVinciCRDTestKit
|
|
|
24
24
|
'hl7.fhir.us.davinci-crd_2.2.1@hook-20', 'hl7.fhir.us.davinci-crd_2.2.1@hook-21'
|
|
25
25
|
|
|
26
26
|
run do
|
|
27
|
-
hook_requests =
|
|
27
|
+
hook_requests = load_interaction_group_requests
|
|
28
28
|
|
|
29
29
|
skip_if hook_requests.blank?, "No #{hook_name} hook requests received."
|
|
30
30
|
|
|
@@ -97,15 +97,23 @@ module DaVinciCRDTestKit
|
|
|
97
97
|
request_index)
|
|
98
98
|
end
|
|
99
99
|
|
|
100
|
+
check_payer_resource_conformance(payer_resource, request_index)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def check_payer_resource_conformance(payer_resource, request_index)
|
|
100
104
|
validator_response_details = []
|
|
101
105
|
resource_is_valid?(resource: payer_resource, profile_url: 'http://hl7.org/fhir/us/davinci-crd/StructureDefinition/profile-organization|2.2.1',
|
|
102
106
|
add_messages_to_runnable: false, validator_response_details:)
|
|
103
107
|
|
|
104
|
-
validator_response_details.each
|
|
108
|
+
validator_response_details.each do |issue|
|
|
109
|
+
next if issue.filtered
|
|
110
|
+
|
|
111
|
+
add_request_message(issue.severity, issue.message, request_index)
|
|
112
|
+
end
|
|
105
113
|
end
|
|
106
114
|
|
|
107
115
|
run do
|
|
108
|
-
hook_requests =
|
|
116
|
+
hook_requests = load_interaction_group_requests
|
|
109
117
|
|
|
110
118
|
skip_if hook_requests.blank?, "No #{hook_name} hook requests received."
|
|
111
119
|
|
data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_granted_scopes_test.rb
CHANGED
|
@@ -29,7 +29,7 @@ module DaVinciCRDTestKit
|
|
|
29
29
|
verifies_requirements 'hl7.fhir.us.davinci-crd_2.2.1@found-21'
|
|
30
30
|
|
|
31
31
|
run do
|
|
32
|
-
hook_requests =
|
|
32
|
+
hook_requests = load_interaction_group_requests
|
|
33
33
|
|
|
34
34
|
skip_if hook_requests.blank?, "No #{hook_name} hook requests received."
|
|
35
35
|
|
data/lib/davinci_crd_test_kit/client/v2.2.1/verify_request/hook_request_prefetch_profiles_test.rb
CHANGED
|
@@ -34,7 +34,7 @@ module DaVinciCRDTestKit
|
|
|
34
34
|
'hl7.fhir.us.davinci-crd_2.2.1@prof-10', 'hl7.fhir.us.davinci-crd_2.2.1@prof-11',
|
|
35
35
|
'hl7.fhir.us.davinci-crd_2.2.1@prof-12'
|
|
36
36
|
run do
|
|
37
|
-
hook_requests =
|
|
37
|
+
hook_requests = load_interaction_group_requests
|
|
38
38
|
|
|
39
39
|
skip_if hook_requests.blank?, "No #{hook_name} hook requests received."
|
|
40
40
|
|
|
@@ -18,33 +18,65 @@ module DaVinciCRDTestKit
|
|
|
18
18
|
)
|
|
19
19
|
attestation
|
|
20
20
|
|
|
21
|
+
verifies_requirements 'hl7.fhir.us.davinci-crd_2.2.1@resp-49'
|
|
22
|
+
|
|
21
23
|
def responded_card_types
|
|
22
|
-
list_card_types_in_requests(requests)
|
|
24
|
+
@responded_card_types ||= list_card_types_in_requests(requests)
|
|
23
25
|
end
|
|
24
26
|
|
|
25
|
-
def format_responded_response_types
|
|
26
|
-
|
|
27
|
+
def format_responded_response_types(response_types = responded_card_types)
|
|
28
|
+
response_types
|
|
27
29
|
.map do |response_type|
|
|
28
|
-
|
|
29
|
-
response_type.split('_')
|
|
30
|
-
.map(&:capitalize)
|
|
31
|
-
.join(' ')
|
|
30
|
+
DaVinciCRDTestKit::CardsIdentification.humanize_response_type(response_type)
|
|
32
31
|
.prepend('- ')
|
|
33
|
-
.sub('
|
|
34
|
-
.sub('
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
32
|
+
.sub(' Card', '')
|
|
33
|
+
.sub(' Action', '')
|
|
34
|
+
end.join("\n")
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def format_responded_card_types
|
|
38
|
+
@format_responded_card_types ||=
|
|
39
|
+
format_responded_response_types(responded_card_types.select do |type|
|
|
40
|
+
type.end_with?('_card')
|
|
41
|
+
end)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def format_responded_system_action_types
|
|
45
|
+
@format_responded_system_action_types ||=
|
|
46
|
+
format_responded_response_types(responded_card_types.select do |type|
|
|
47
|
+
type.end_with?('_action')
|
|
48
|
+
end)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
CARD_AND_SYSTEM_ACTION_DISPLAY_PREFIX = "\n\n By attesting true, ".freeze
|
|
52
|
+
CARD_AND_SYSTEM_ACTION_DISPLAY_CLAUSE_PREFIX = 'you confirm that the following '.freeze
|
|
53
|
+
CARD_AND_SYSTEM_ACTION_DISPLAY_CLAUSE_CONNECTOR = "\n\n Additionally, ".freeze
|
|
54
|
+
CARD_AND_SYSTEM_ACTION_DISPLAY_CARD_CLAUSE =
|
|
55
|
+
'card types observed in Inferno\'s responses were displayed to users:'.freeze
|
|
56
|
+
CARD_AND_SYSTEM_ACTION_DISPLAY_SYSTEM_ACTION_CLAUSE =
|
|
57
|
+
'system action types observed in Inferno\'s responses were displayed to users ' \
|
|
58
|
+
'through standard card display, icons, flyovers, or another alternate mechanism:'.freeze
|
|
59
|
+
|
|
60
|
+
def card_and_system_action_details_display
|
|
61
|
+
if format_responded_card_types.present? && format_responded_system_action_types.present?
|
|
62
|
+
"#{CARD_AND_SYSTEM_ACTION_DISPLAY_PREFIX}#{CARD_AND_SYSTEM_ACTION_DISPLAY_CLAUSE_PREFIX}" \
|
|
63
|
+
"#{CARD_AND_SYSTEM_ACTION_DISPLAY_CARD_CLAUSE}\n#{format_responded_card_types}" \
|
|
64
|
+
"#{CARD_AND_SYSTEM_ACTION_DISPLAY_CLAUSE_CONNECTOR}#{CARD_AND_SYSTEM_ACTION_DISPLAY_CLAUSE_PREFIX}" \
|
|
65
|
+
"#{CARD_AND_SYSTEM_ACTION_DISPLAY_SYSTEM_ACTION_CLAUSE}\n#{format_responded_system_action_types}"
|
|
66
|
+
elsif format_responded_card_types.present?
|
|
67
|
+
"#{CARD_AND_SYSTEM_ACTION_DISPLAY_PREFIX}#{CARD_AND_SYSTEM_ACTION_DISPLAY_CLAUSE_PREFIX}" \
|
|
68
|
+
"#{CARD_AND_SYSTEM_ACTION_DISPLAY_CARD_CLAUSE}\n#{format_responded_card_types}"
|
|
69
|
+
else
|
|
70
|
+
"#{CARD_AND_SYSTEM_ACTION_DISPLAY_PREFIX}#{CARD_AND_SYSTEM_ACTION_DISPLAY_CLAUSE_PREFIX}" \
|
|
71
|
+
"#{CARD_AND_SYSTEM_ACTION_DISPLAY_SYSTEM_ACTION_CLAUSE}\n#{format_responded_system_action_types}"
|
|
39
72
|
end
|
|
40
|
-
.join("\n")
|
|
41
73
|
end
|
|
42
74
|
|
|
43
75
|
output :attest_true_url
|
|
44
76
|
output :attest_false_url
|
|
45
77
|
|
|
46
78
|
run do
|
|
47
|
-
|
|
79
|
+
load_interaction_group_requests
|
|
48
80
|
skip_if responded_card_types.blank?, 'No responses sent to the client.'
|
|
49
81
|
|
|
50
82
|
identifier = SecureRandom.hex(32)
|
|
@@ -57,12 +89,12 @@ module DaVinciCRDTestKit
|
|
|
57
89
|
message: <<~MESSAGE
|
|
58
90
|
**Card Display Attestation**:
|
|
59
91
|
|
|
60
|
-
I attest that the
|
|
61
|
-
|
|
62
|
-
available to users of the
|
|
63
|
-
|
|
92
|
+
I attest that the simulated CRD responses returned by Inferno during this
|
|
93
|
+
group were successfully processed by the client system and that they were
|
|
94
|
+
made available to users of the system in an appropriate way that allowed for
|
|
95
|
+
user review and action if warranted.
|
|
64
96
|
|
|
65
|
-
#{
|
|
97
|
+
#{card_and_system_action_details_display}
|
|
66
98
|
|
|
67
99
|
[Click here](#{attest_true_url}) if the above statement is **true**.
|
|
68
100
|
|
|
@@ -18,7 +18,7 @@ module DaVinciCRDTestKit
|
|
|
18
18
|
DESCRIPTION
|
|
19
19
|
|
|
20
20
|
run do
|
|
21
|
-
hook_requests =
|
|
21
|
+
hook_requests = load_interaction_group_requests
|
|
22
22
|
skip_if hook_requests.blank?, "No #{hook_name} hook requests received."
|
|
23
23
|
|
|
24
24
|
sorted_cards = sorted_cards_from_requests(hook_requests)
|
|
@@ -14,6 +14,8 @@ module DaVinciCRDTestKit
|
|
|
14
14
|
During this test, Inferno will verify that each hook response built by Inferno's simulated CRD servers
|
|
15
15
|
and returned to the client conforms to CDS Hooks and CRD requirements. These responses must be conformant
|
|
16
16
|
for the client to demonstrate its ability to accept and process valid CRD responses.
|
|
17
|
+
To prevent the injection of non-standard information into Inferno responses, these validations will
|
|
18
|
+
strictly check that all extensions are allowed at the locations they appear by the CRD specification.
|
|
17
19
|
|
|
18
20
|
If this test fails when the tester provided a custom response template, adjust the
|
|
19
21
|
provided template and the submitted requests so that the response built by Inferno
|
|
@@ -29,7 +31,7 @@ module DaVinciCRDTestKit
|
|
|
29
31
|
simulation_verification
|
|
30
32
|
|
|
31
33
|
verifies_requirements 'cds-hooks_3.0.0-ballot@3', 'cds-hooks_3.0.0-ballot@222', 'cds-hooks_3.0.0-ballot@223',
|
|
32
|
-
'cds-hooks_3.0.0-ballot@224'
|
|
34
|
+
'cds-hooks_3.0.0-ballot@224', 'hl7.fhir.us.davinci-crd_2.2.1@conf-10'
|
|
33
35
|
|
|
34
36
|
input :custom_response_template, optional: true
|
|
35
37
|
|
|
@@ -45,7 +47,7 @@ module DaVinciCRDTestKit
|
|
|
45
47
|
end
|
|
46
48
|
|
|
47
49
|
run do
|
|
48
|
-
|
|
50
|
+
load_interaction_group_requests
|
|
49
51
|
|
|
50
52
|
skip_if request.blank?, "No #{response_label.downcase}s to verify."
|
|
51
53
|
|
|
@@ -62,7 +64,8 @@ module DaVinciCRDTestKit
|
|
|
62
64
|
response_hash['systemActions'],
|
|
63
65
|
request_hash,
|
|
64
66
|
index,
|
|
65
|
-
'2.2.1'
|
|
67
|
+
'2.2.1',
|
|
68
|
+
validator: :no_custom_extensions)
|
|
66
69
|
rescue JSON::ParserError
|
|
67
70
|
next
|
|
68
71
|
end
|
|
@@ -35,6 +35,15 @@ module DaVinciCRDTestKit
|
|
|
35
35
|
NutritionOrder ServiceRequest VisionPrescription
|
|
36
36
|
].freeze
|
|
37
37
|
|
|
38
|
+
def self.humanize_response_type(response_type)
|
|
39
|
+
response_type.split('_')
|
|
40
|
+
.map(&:capitalize)
|
|
41
|
+
.join(' ')
|
|
42
|
+
.sub('Smart', 'SMART')
|
|
43
|
+
.sub('Create Update', 'Create/Update')
|
|
44
|
+
.sub('Companions Prerequisites', 'Companions/Prerequisites')
|
|
45
|
+
end
|
|
46
|
+
|
|
38
47
|
def identify_card_type(card) # rubocop:disable Metrics/CyclomaticComplexity
|
|
39
48
|
return nil if card['type'].present? # action, not a card
|
|
40
49
|
return ADDITIONAL_ORDERS_RESPONSE_TYPE if additional_orders_response_type?(card)
|
|
@@ -13,27 +13,44 @@ module DaVinciCRDTestKit
|
|
|
13
13
|
end
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
+
def filter_logical_model_extension_issues(issues, validator)
|
|
17
|
+
return if validator == :no_custom_extensions
|
|
18
|
+
|
|
19
|
+
issues.each { |issue| issue.filtered = issue.filtered || logical_model_extension_issue?(issue) }
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Logical models validation doesn't currently respect the `"extensions": ["any"]`
|
|
23
|
+
# validator flag
|
|
24
|
+
def logical_model_extension_issue?(issue)
|
|
25
|
+
issue.message.match(/\.extension: Unrecognized property/).present?
|
|
26
|
+
end
|
|
27
|
+
|
|
16
28
|
# -------------------------------------------------------------------------
|
|
17
29
|
# Check resource conformance outside the logical models
|
|
18
30
|
# -------------------------------------------------------------------------
|
|
19
31
|
|
|
20
|
-
def check_resource_conformance_to_coverage_profile(resource_hash, error_prefix, ig_semver)
|
|
21
|
-
check_resource_type_and_validate(resource_hash, error_prefix, ig_semver, FHIR::Coverage)
|
|
32
|
+
def check_resource_conformance_to_coverage_profile(resource_hash, error_prefix, ig_semver, validator: :default)
|
|
33
|
+
check_resource_type_and_validate(resource_hash, error_prefix, ig_semver, FHIR::Coverage, validator:)
|
|
22
34
|
end
|
|
23
35
|
|
|
24
|
-
def check_resource_conformance_to_questionnaire_task_profile(resource_hash, error_prefix, ig_semver
|
|
25
|
-
|
|
36
|
+
def check_resource_conformance_to_questionnaire_task_profile(resource_hash, error_prefix, ig_semver,
|
|
37
|
+
validator: :default)
|
|
38
|
+
check_resource_type_and_validate(resource_hash, error_prefix, ig_semver, FHIR::Task, validator:)
|
|
26
39
|
end
|
|
27
40
|
|
|
28
|
-
def check_resource_conformance_to_order_or_encounter_profile(resource_hash, request_body, error_prefix, ig_semver
|
|
41
|
+
def check_resource_conformance_to_order_or_encounter_profile(resource_hash, request_body, error_prefix, ig_semver,
|
|
42
|
+
validator: :default)
|
|
29
43
|
check_order_like_resource_conformance(resource_hash, request_body, error_prefix, ig_semver,
|
|
44
|
+
validator:,
|
|
30
45
|
allowed_types: ProfilesAndResourceTypes::ORDER_OR_ENCOUNTER_RESOURCE_CLASSES,
|
|
31
46
|
disallowed_message: 'is not allowed as a target ' \
|
|
32
47
|
'for a coverage-information action')
|
|
33
48
|
end
|
|
34
49
|
|
|
35
|
-
def check_resource_conformance_to_order_profile(resource_hash, request_body, error_prefix, ig_semver
|
|
50
|
+
def check_resource_conformance_to_order_profile(resource_hash, request_body, error_prefix, ig_semver,
|
|
51
|
+
validator: :default)
|
|
36
52
|
check_order_like_resource_conformance(resource_hash, request_body, error_prefix, ig_semver,
|
|
53
|
+
validator:,
|
|
37
54
|
allowed_types: ProfilesAndResourceTypes::ORDER_RESOURCE_CLASSES,
|
|
38
55
|
disallowed_message: 'is not allowed for CRD orders')
|
|
39
56
|
end
|
|
@@ -51,11 +68,11 @@ module DaVinciCRDTestKit
|
|
|
51
68
|
yield resource
|
|
52
69
|
end
|
|
53
70
|
|
|
54
|
-
def check_resource_type_and_validate(resource_hash, error_prefix, ig_semver, expected_class)
|
|
71
|
+
def check_resource_type_and_validate(resource_hash, error_prefix, ig_semver, expected_class, validator: :default)
|
|
55
72
|
parse_action_resource(resource_hash, error_prefix) do |resource|
|
|
56
73
|
if resource.is_a?(expected_class)
|
|
57
74
|
resource_is_valid?(resource:, profile_url: structure_definition_map(ig_semver)[resource.resourceType],
|
|
58
|
-
message_prefix: error_prefix)
|
|
75
|
+
message_prefix: error_prefix, validator:)
|
|
59
76
|
else
|
|
60
77
|
add_message('error', "#{error_prefix}found resource type '#{resource.resourceType}' " \
|
|
61
78
|
"expected '#{expected_class.name.split('::').last}'.")
|
|
@@ -64,14 +81,14 @@ module DaVinciCRDTestKit
|
|
|
64
81
|
end
|
|
65
82
|
|
|
66
83
|
def check_order_like_resource_conformance(resource_hash, request_body, error_prefix, ig_semver,
|
|
67
|
-
allowed_types:, disallowed_message:)
|
|
84
|
+
allowed_types:, disallowed_message:, validator: :default)
|
|
68
85
|
parse_action_resource(resource_hash, error_prefix) do |resource|
|
|
69
86
|
case resource
|
|
70
87
|
when FHIR::Appointment
|
|
71
|
-
check_appointment_conformance(resource, request_body, error_prefix, ig_semver)
|
|
88
|
+
check_appointment_conformance(resource, request_body, error_prefix, ig_semver, validator:)
|
|
72
89
|
when *allowed_types
|
|
73
90
|
resource_is_valid?(resource:, profile_url: structure_definition_map(ig_semver)[resource.resourceType],
|
|
74
|
-
message_prefix: error_prefix)
|
|
91
|
+
message_prefix: error_prefix, validator:)
|
|
75
92
|
else
|
|
76
93
|
add_message('error', "#{error_prefix}resource type '#{resource.resourceType}' #{disallowed_message}.")
|
|
77
94
|
end
|
|
@@ -82,7 +99,7 @@ module DaVinciCRDTestKit
|
|
|
82
99
|
# Appointment conformance (requires extra help to decide profile and check profile-based slicing)
|
|
83
100
|
# -------------------------------------------------------------------------
|
|
84
101
|
|
|
85
|
-
def check_appointment_conformance(appointment, request_body, error_prefix, ig_semver)
|
|
102
|
+
def check_appointment_conformance(appointment, request_body, error_prefix, ig_semver, validator: :default)
|
|
86
103
|
target_appointment_profile =
|
|
87
104
|
if appointment.basedOn.present?
|
|
88
105
|
'http://hl7.org/fhir/us/davinci-crd/StructureDefinition/profile-appointment-with-order'
|
|
@@ -92,7 +109,7 @@ module DaVinciCRDTestKit
|
|
|
92
109
|
|
|
93
110
|
validation_issues = []
|
|
94
111
|
resource_is_valid?(resource: appointment, profile_url: "#{target_appointment_profile}|#{ig_semver}",
|
|
95
|
-
add_messages_to_runnable: false, validator_response_details: validation_issues)
|
|
112
|
+
add_messages_to_runnable: false, validator_response_details: validation_issues, validator:)
|
|
96
113
|
|
|
97
114
|
manually_check_appointment_validation_errors(validation_issues, appointment, request_body)
|
|
98
115
|
.each do |issue|
|
|
@@ -34,6 +34,8 @@ module DaVinciCRDTestKit
|
|
|
34
34
|
profile_url: target_crd_profile,
|
|
35
35
|
validator_response_details: validation_details, add_messages_to_runnable: false)
|
|
36
36
|
validation_details.each do |issue|
|
|
37
|
+
next if issue.filtered
|
|
38
|
+
|
|
37
39
|
prefix = prefetch_profile_error_prefix(request_index, bundle_entry_index)
|
|
38
40
|
add_message(issue.severity, "#{prefix}#{issue.message}")
|
|
39
41
|
end
|