davinci_pas_test_kit 0.12.0 → 0.12.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/lib/davinci_pas_test_kit/client_suite.rb +24 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_approval_submit_test.rb +32 -1
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_denial_submit_test.rb +30 -4
- data/lib/davinci_pas_test_kit/{generated/v2.0.1/client_tests/client_pended_pas_inquiry_request_bundle_validation_test.rb → custom_groups/v2.0.1/client_tests/pas_client_inquire_request_bundle_validation_test.rb} +26 -20
- data/lib/davinci_pas_test_kit/{generated/v2.0.1/client_tests/client_denial_pas_response_bundle_validation_test.rb → custom_groups/v2.0.1/client_tests/pas_client_inquire_response_bundle_validation_test.rb} +34 -21
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_pended_submit_test.rb +130 -5
- data/lib/davinci_pas_test_kit/{generated/v2.0.1/client_tests/client_pas_request_bundle_validation_test.rb → custom_groups/v2.0.1/client_tests/pas_client_request_bundle_validation_test.rb} +28 -20
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/{pas_client_approval_submit_response_attest.rb → pas_client_response_attest.rb} +26 -9
- data/lib/davinci_pas_test_kit/{generated/v2.0.1/client_tests/client_pended_pas_response_bundle_validation_test.rb → custom_groups/v2.0.1/client_tests/pas_client_response_bundle_validation_test.rb} +44 -20
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_submit_must_support_test.rb +3 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_subscription_create_test.rb +52 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_subscription_pas_conformance_test.rb +49 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/error_tests/pas_submission_error_test.rb +1 -0
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_approval_group.rb +21 -9
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_authentication_group.rb +2 -2
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_denial_group.rb +21 -22
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/pas_client_pended_group.rb +97 -31
- data/lib/davinci_pas_test_kit/docs/client_suite_description_v201.md +213 -72
- data/lib/davinci_pas_test_kit/endpoints/claim_endpoint.rb +85 -134
- data/lib/davinci_pas_test_kit/endpoints/subscription_create_endpoint.rb +96 -0
- data/lib/davinci_pas_test_kit/endpoints/subscription_status_endpoint.rb +90 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/claim/claim_operation_test.rb +1 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/claiminquiryresponse/server_inquire_response_claiminquiryresponse_must_support_test.rb +1 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/claimresponse/server_submit_response_claimresponse_must_support_test.rb +1 -0
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_inquiry_request_bundle/metadata.yml +0 -2
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_inquiry_request_bundle/server_pas_inquiry_request_bundle_validation_test.rb +3 -1
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_inquiry_response_bundle/server_pas_inquiry_response_bundle_validation_test.rb +2 -1
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_request_bundle/metadata.yml +0 -2
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_request_bundle/server_pas_request_bundle_validation_test.rb +3 -1
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_response_bundle/metadata.yml +0 -4
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_response_bundle/server_pas_response_bundle_validation_test.rb +2 -1
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_server_denial_use_case_group.rb +1 -1
- data/lib/davinci_pas_test_kit/generated/v2.0.1/pas_server_pended_use_case_group.rb +6 -5
- data/lib/davinci_pas_test_kit/generated/v2.0.1/server_suite.rb +1 -0
- data/lib/davinci_pas_test_kit/generator/group_generator.rb +9 -8
- data/lib/davinci_pas_test_kit/generator/group_metadata_extractor.rb +7 -3
- data/lib/davinci_pas_test_kit/generator/templates/suite.rb.erb +1 -0
- data/lib/davinci_pas_test_kit/generator/validation_test_generator.rb +19 -56
- data/lib/davinci_pas_test_kit/generator/value_extractor.rb +4 -1
- data/lib/davinci_pas_test_kit/generator.rb +1 -1
- data/lib/davinci_pas_test_kit/jobs/send_pas_subscription_notification.rb +136 -0
- data/lib/davinci_pas_test_kit/jobs/send_subscription_handshake.rb +139 -0
- data/lib/davinci_pas_test_kit/pas_bundle_validation.rb +12 -11
- data/lib/davinci_pas_test_kit/requirements/davinci-pas-test-kit_out_of_scope_requirements.csv +11 -0
- data/lib/davinci_pas_test_kit/requirements/davinci-pas-test-kit_requirements.csv +214 -0
- data/lib/davinci_pas_test_kit/requirements/generated/davinci-pas-test-kit_requirements_coverage.csv +214 -0
- data/lib/davinci_pas_test_kit/response_generator.rb +397 -0
- data/lib/davinci_pas_test_kit/tags.rb +9 -0
- data/lib/davinci_pas_test_kit/urls.rb +8 -0
- data/lib/davinci_pas_test_kit/user_input_response.rb +11 -8
- data/lib/davinci_pas_test_kit/validation_test.rb +0 -1
- data/lib/davinci_pas_test_kit/version.rb +2 -2
- data/lib/davinci_pas_test_kit.rb +1 -0
- data/lib/inferno_requirements_tools/ext/inferno_core/runnable.rb +22 -0
- data/lib/inferno_requirements_tools/tasks/requirements_coverage.rb +284 -0
- data/lib/requirements_config.yaml +17 -0
- metadata +36 -14
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_denial_submit_response_attest.rb +0 -38
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_pended_inquire_response_attest.rb +0 -39
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_pended_inquire_test.rb +0 -35
- data/lib/davinci_pas_test_kit/custom_groups/v2.0.1/client_tests/pas_client_pended_submit_response_attest.rb +0 -39
- data/lib/davinci_pas_test_kit/generator/templates/validation_client.rb.erb +0 -50
@@ -0,0 +1,136 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../tags'
|
4
|
+
require_relative '../urls'
|
5
|
+
require 'subscriptions_test_kit'
|
6
|
+
|
7
|
+
module DaVinciPASTestKit
|
8
|
+
module Jobs
|
9
|
+
class SendPASSubscriptionNotification
|
10
|
+
include Sidekiq::Job
|
11
|
+
include SubscriptionsTestKit::SubscriptionsR5BackportR4Client::SubscriptionSimulationUtils
|
12
|
+
include URLs
|
13
|
+
|
14
|
+
# override the one from URLs
|
15
|
+
def suite_id
|
16
|
+
@notification_suite_id
|
17
|
+
end
|
18
|
+
|
19
|
+
sidekiq_options retry: false
|
20
|
+
|
21
|
+
def perform(test_run_id, test_session_id, result_id, notification_bearer_token, notification_json, resume_token,
|
22
|
+
notification_suite_id)
|
23
|
+
@test_run_id = test_run_id
|
24
|
+
@test_session_id = test_session_id
|
25
|
+
@result_id = result_id
|
26
|
+
@notification_bearer_token = notification_bearer_token
|
27
|
+
@notification_json = notification_json
|
28
|
+
@resume_token = resume_token
|
29
|
+
@notification_suite_id = notification_suite_id
|
30
|
+
|
31
|
+
await_subscription_creation # NOTE: currently must exist - see PASClientPendedSubmitTest
|
32
|
+
sleep 1
|
33
|
+
return unless test_still_waiting?
|
34
|
+
|
35
|
+
sleep rand(5..10)
|
36
|
+
return unless test_still_waiting?
|
37
|
+
|
38
|
+
send_event_notification
|
39
|
+
end
|
40
|
+
|
41
|
+
def requests_repo
|
42
|
+
@requests_repo ||= Inferno::Repositories::Requests.new
|
43
|
+
end
|
44
|
+
|
45
|
+
def results_repo
|
46
|
+
@results_repo ||= Inferno::Repositories::Results.new
|
47
|
+
end
|
48
|
+
|
49
|
+
def subscription
|
50
|
+
@subscription ||= find_subscription(@test_session_id)
|
51
|
+
end
|
52
|
+
|
53
|
+
def subscription_notification_endpoint
|
54
|
+
subscription&.channel&.endpoint
|
55
|
+
end
|
56
|
+
|
57
|
+
def headers
|
58
|
+
@headers ||= subscription_headers.merge(content_type_header).merge(authorization_header)
|
59
|
+
end
|
60
|
+
|
61
|
+
def rest_hook_connection
|
62
|
+
@rest_hook_connection ||= Faraday.new(url: subscription_notification_endpoint, request: { open_timeout: 30 },
|
63
|
+
headers:)
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_suite_connection
|
67
|
+
@test_suite_connection ||= Faraday.new(base_url)
|
68
|
+
end
|
69
|
+
|
70
|
+
def content_type_header
|
71
|
+
@content_type_header ||= { 'Content-Type' => actual_mime_type(subscription) }
|
72
|
+
end
|
73
|
+
|
74
|
+
def subscription_headers
|
75
|
+
@subscription_headers ||= subscription.channel&.header&.each_with_object({}) do |header, hash|
|
76
|
+
header_name, header_value = header.split(': ', 2)
|
77
|
+
hash[header_name] = header_value
|
78
|
+
end || {}
|
79
|
+
end
|
80
|
+
|
81
|
+
def authorization_header
|
82
|
+
@authorization_header ||=
|
83
|
+
@notification_bearer_token.present? ? { 'Authorization' => "Bearer #{@notification_bearer_token}" } : {}
|
84
|
+
end
|
85
|
+
|
86
|
+
def subscription_topic
|
87
|
+
@subscription_topic ||= subscription&.criteria
|
88
|
+
end
|
89
|
+
|
90
|
+
def subscription_full_url
|
91
|
+
@subscription_full_url ||= "#{fhir_subscription_url}/#{subscription.id}"
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_still_waiting?
|
95
|
+
results_repo.find_waiting_result(test_run_id: @test_run_id)
|
96
|
+
end
|
97
|
+
|
98
|
+
def await_subscription_creation
|
99
|
+
sleep 0.5 until subscription.present? || !test_still_waiting?
|
100
|
+
end
|
101
|
+
|
102
|
+
def send_event_notification
|
103
|
+
event_json = derive_event_notification(@notification_json, subscription_full_url, subscription_topic, 1).to_json
|
104
|
+
response = send_notification(event_json)
|
105
|
+
persist_notification_request(response, [REST_HOOK_EVENT_NOTIFICATION_TAG])
|
106
|
+
end
|
107
|
+
|
108
|
+
def send_notification(request_body)
|
109
|
+
rest_hook_connection.post('', request_body)
|
110
|
+
rescue Faraday::Error => e
|
111
|
+
# Warning: This is a hack. If there is an error with the request such that we never get a response, we have
|
112
|
+
# no clean way to persist that information for the Inferno test to check later. The solution here
|
113
|
+
# is to persist the request anyway with a status of nil, using the error message as response body
|
114
|
+
Faraday::Response.new(response_body: e.message, url: rest_hook_connection.url_prefix.to_s)
|
115
|
+
end
|
116
|
+
|
117
|
+
def persist_notification_request(response, tags)
|
118
|
+
inferno_request_headers = headers.map { |name, value| { name:, value: } }
|
119
|
+
inferno_response_headers = response.headers&.map { |name, value| { name:, value: } }
|
120
|
+
requests_repo.create(
|
121
|
+
verb: 'POST',
|
122
|
+
url: response.env.url.to_s,
|
123
|
+
direction: 'outgoing',
|
124
|
+
status: response.status,
|
125
|
+
request_body: response.env.request_body,
|
126
|
+
response_body: response.env.response_body,
|
127
|
+
test_session_id: @test_session_id,
|
128
|
+
result_id: @result_id,
|
129
|
+
request_headers: inferno_request_headers,
|
130
|
+
response_headers: inferno_response_headers,
|
131
|
+
tags:
|
132
|
+
)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../tags'
|
4
|
+
require 'subscriptions_test_kit'
|
5
|
+
|
6
|
+
module DaVinciPASTestKit
|
7
|
+
module Jobs
|
8
|
+
class SendSubscriptionHandshake
|
9
|
+
include Sidekiq::Job
|
10
|
+
include SubscriptionsTestKit::SubscriptionsR5BackportR4Client::SubscriptionSimulationUtils
|
11
|
+
|
12
|
+
sidekiq_options retry: false
|
13
|
+
|
14
|
+
def perform(test_run_id, test_session_id, result_id, subscription_id, subscription_url, client_endpoint,
|
15
|
+
bearer_token, notification_json, test_run_identifier, test_suite_base_url)
|
16
|
+
@test_run_id = test_run_id
|
17
|
+
@test_session_id = test_session_id
|
18
|
+
@result_id = result_id
|
19
|
+
@subscription_id = subscription_id
|
20
|
+
@subscription_url = subscription_url
|
21
|
+
@client_endpoint = client_endpoint
|
22
|
+
@bearer_token = bearer_token
|
23
|
+
@notification_json = notification_json.present? ? notification_json : default_notification_base_json
|
24
|
+
@test_run_identifier = test_run_identifier
|
25
|
+
@test_suite_base_url = test_suite_base_url
|
26
|
+
|
27
|
+
await_subscription_creation
|
28
|
+
sleep 1
|
29
|
+
return unless test_still_waiting?
|
30
|
+
|
31
|
+
send_handshake_notification
|
32
|
+
test_suite_connection.get(RESUME_PASS_PATH.delete_prefix('/'), { token: @test_run_identifier })
|
33
|
+
end
|
34
|
+
|
35
|
+
def default_notification_base_json
|
36
|
+
FHIR::Bundle.new(
|
37
|
+
timestamp: Time.now.utc.iso8601,
|
38
|
+
type: 'history',
|
39
|
+
entry: [
|
40
|
+
FHIR::Bundle::Entry.new(fullUrl: "urn:uuid:#{SecureRandom.uuid}",
|
41
|
+
resource: FHIR.from_contents(default_handshake_parameters_base_json))
|
42
|
+
]
|
43
|
+
).to_json
|
44
|
+
end
|
45
|
+
|
46
|
+
def default_handshake_parameters_base_json
|
47
|
+
'{ "parameter": [ { "name": "subscription", "valueReference": { "reference": "replace_with_subscription_ref" } }, { "name": "topic", "valueCanonical": "replace_with_topic_canonical" }, { "name": "status", "valueCode": "requested" }, { "name": "type", "valueCode": "handshake" }, { "name": "events-since-subscription-start", "valueString": "0" } ], "resourceType": "Parameters" }' # rubocop:disable Layout/LineLength
|
48
|
+
end
|
49
|
+
|
50
|
+
def requests_repo
|
51
|
+
@requests_repo ||= Inferno::Repositories::Requests.new
|
52
|
+
end
|
53
|
+
|
54
|
+
def results_repo
|
55
|
+
@results_repo ||= Inferno::Repositories::Results.new
|
56
|
+
end
|
57
|
+
|
58
|
+
def subscription
|
59
|
+
@subscription ||= find_subscription(@test_session_id)
|
60
|
+
end
|
61
|
+
|
62
|
+
def headers
|
63
|
+
@headers ||= subscription_headers.merge(content_type_header).merge(authorization_header)
|
64
|
+
end
|
65
|
+
|
66
|
+
def rest_hook_connection
|
67
|
+
@rest_hook_connection ||= Faraday.new(url: @client_endpoint, request: { open_timeout: 30 }, headers:)
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_suite_connection
|
71
|
+
@test_suite_connection ||= Faraday.new(@test_suite_base_url)
|
72
|
+
end
|
73
|
+
|
74
|
+
def content_type_header
|
75
|
+
@content_type_header ||= { 'Content-Type' => actual_mime_type(subscription) }
|
76
|
+
end
|
77
|
+
|
78
|
+
def subscription_headers
|
79
|
+
return {} unless subscription.present?
|
80
|
+
|
81
|
+
@subscription_headers ||= subscription.channel&.header&.each_with_object({}) do |header, hash|
|
82
|
+
header_name, header_value = header.split(': ', 2)
|
83
|
+
hash[header_name] = header_value
|
84
|
+
end || {}
|
85
|
+
end
|
86
|
+
|
87
|
+
def subscription_topic
|
88
|
+
@subscription_topic ||= subscription&.criteria
|
89
|
+
end
|
90
|
+
|
91
|
+
def authorization_header
|
92
|
+
@authorization_header ||= @bearer_token.present? ? { 'Authorization' => "Bearer #{@bearer_token}" } : {}
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_still_waiting?
|
96
|
+
results_repo.find_waiting_result(test_run_id: @test_run_id)
|
97
|
+
end
|
98
|
+
|
99
|
+
def await_subscription_creation
|
100
|
+
sleep 0.5 until subscription.present?
|
101
|
+
end
|
102
|
+
|
103
|
+
def send_handshake_notification
|
104
|
+
handshake_json = derive_handshake_notification(@notification_json, @subscription_url,
|
105
|
+
subscription_topic).to_json
|
106
|
+
response = send_notification(handshake_json)
|
107
|
+
persist_notification_request(response, [REST_HOOK_HANDSHAKE_NOTIFICATION_TAG])
|
108
|
+
response
|
109
|
+
end
|
110
|
+
|
111
|
+
def send_notification(request_body)
|
112
|
+
rest_hook_connection.post('', request_body)
|
113
|
+
rescue Faraday::Error => e
|
114
|
+
# Warning: This is a hack. If there is an error with the request such that we never get a response, we have
|
115
|
+
# no clean way to persist that information for the Inferno test to check later. The solution here
|
116
|
+
# is to persist the request anyway with a status of nil, using the error message as response body
|
117
|
+
Faraday::Response.new(response_body: e.message, url: rest_hook_connection.url_prefix.to_s)
|
118
|
+
end
|
119
|
+
|
120
|
+
def persist_notification_request(response, tags)
|
121
|
+
inferno_request_headers = headers.map { |name, value| { name:, value: } }
|
122
|
+
inferno_response_headers = response.headers&.map { |name, value| { name:, value: } }
|
123
|
+
requests_repo.create(
|
124
|
+
verb: 'POST',
|
125
|
+
url: response.env.url.to_s,
|
126
|
+
direction: 'outgoing',
|
127
|
+
status: response.status,
|
128
|
+
request_body: response.env.request_body,
|
129
|
+
response_body: response.env.response_body,
|
130
|
+
test_session_id: @test_session_id,
|
131
|
+
result_id: @result_id,
|
132
|
+
request_headers: inferno_request_headers,
|
133
|
+
response_headers: inferno_response_headers,
|
134
|
+
tags:
|
135
|
+
)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
@@ -70,7 +70,7 @@ module DaVinciPASTestKit
|
|
70
70
|
# referenced in the Claim resource are included in the bundle. It ensures that the first
|
71
71
|
# entry in the Bundle is a Claim resource and additional entries are populated
|
72
72
|
# with referenced resources, following the traversal of references.
|
73
|
-
# Duplicate resources are handled as required(
|
73
|
+
# Duplicate resources are handled as required (appearing only once
|
74
74
|
# in the bundle entry).
|
75
75
|
def validate_pa_request_payload_structure(bundle, request_type)
|
76
76
|
bundle_entry_resources = bundle.entry.map(&:resource)
|
@@ -171,7 +171,7 @@ module DaVinciPASTestKit
|
|
171
171
|
bundle_entry = bundle.entry
|
172
172
|
|
173
173
|
root_entry = bundle_entry.find do |entry|
|
174
|
-
|
174
|
+
['Claim', 'ClaimResponse'].include?(entry.resource.resourceType)
|
175
175
|
end
|
176
176
|
|
177
177
|
if root_entry.present?
|
@@ -299,7 +299,7 @@ module DaVinciPASTestKit
|
|
299
299
|
# Processes the profiles associated with a given instance in a FHIR bundle.
|
300
300
|
# It adds the instance's profiles to the resource target profile map and handles recursive profile extraction.
|
301
301
|
# The profiles collected here are possible profiles the given instance may conform to.
|
302
|
-
# The conformance validation will ensure that the resource is
|
302
|
+
# The conformance validation will ensure that the resource is conformant to at least one of the target profiles.
|
303
303
|
# @param instance [Object] The instance whose profiles are to be processed.
|
304
304
|
# @param bundle_entry [Array] The bundle.entry contents.
|
305
305
|
# @param reference_element [Hash] The reference element related to the instance.
|
@@ -331,7 +331,9 @@ module DaVinciPASTestKit
|
|
331
331
|
# @param bundle_entry [Array] The bundle.entry contents.
|
332
332
|
# @param version [String] The IG version.
|
333
333
|
def add_declared_profiles(instance, bundle_entry, version)
|
334
|
-
instance.resource
|
334
|
+
return unless instance.resource.present?
|
335
|
+
|
336
|
+
instance.resource.meta&.profile&.each do |url|
|
335
337
|
next if bundle_resources_target_profile_map[instance.fullUrl][:profile_urls].include?(url)
|
336
338
|
|
337
339
|
bundle_resources_target_profile_map[instance.fullUrl][:profile_urls] << url
|
@@ -340,7 +342,7 @@ module DaVinciPASTestKit
|
|
340
342
|
end
|
341
343
|
|
342
344
|
# Adds a specific profile URL to an instance in the resource target profile map.
|
343
|
-
# It recursively processes the instance for further
|
345
|
+
# It recursively processes the instance for further profile extraction.
|
344
346
|
# @param instance [Object] The instance to which the profile URL is added.
|
345
347
|
# @param profile_url [String] The profile URL to be added.
|
346
348
|
# @param bundle_entry [Array] The bundle.entry contents.
|
@@ -453,7 +455,7 @@ module DaVinciPASTestKit
|
|
453
455
|
# as required by the PAS IG.
|
454
456
|
# @param target_resource [FHIR::Model] The FHIR resource to traverse and validate.
|
455
457
|
# @param base_url [String] The server base url.
|
456
|
-
# @param resources_to_match [Array<FHIR:
|
458
|
+
# @param resources_to_match [Array<FHIR:Bundle:Entry] The list of FHIR bundle entries to match references against.
|
457
459
|
def check_presence_of_referenced_resources(target_resource, base_url, resources_to_match)
|
458
460
|
return if target_resource.blank?
|
459
461
|
|
@@ -462,11 +464,10 @@ module DaVinciPASTestKit
|
|
462
464
|
return if ref.blank?
|
463
465
|
|
464
466
|
absolute_ref = absolute_url(ref, base_url)
|
465
|
-
resource_type, resource_id = ref.split('/')
|
466
467
|
matching_resources = resources_to_match.find_all { |res| res.fullUrl == absolute_ref }
|
467
468
|
|
468
469
|
if matching_resources.length != 1
|
469
|
-
validation_error_messages << resource_shall_appear_once_message(
|
470
|
+
validation_error_messages << resource_shall_appear_once_message(absolute_ref,
|
470
471
|
matching_resources.length)
|
471
472
|
end
|
472
473
|
|
@@ -525,10 +526,10 @@ module DaVinciPASTestKit
|
|
525
526
|
#
|
526
527
|
# This method generates an error message when a referenced resource appears more than once
|
527
528
|
# in a FHIR bundle, which is not allowed.
|
528
|
-
def resource_shall_appear_once_message(
|
529
|
+
def resource_shall_appear_once_message(absolute_ref, total_matches)
|
529
530
|
"
|
530
|
-
The referenced #{
|
531
|
-
SHALL
|
531
|
+
The referenced #{absolute_ref} resource
|
532
|
+
SHALL appear exactly once in the Bundle, but found #{total_matches}.
|
532
533
|
"
|
533
534
|
end
|
534
535
|
|
@@ -0,0 +1,11 @@
|
|
1
|
+
Req Set,ID,Reason,Details
|
2
|
+
hl7.fhir.us.davinci-pas_2.0.1,12,Not Tested,Details of X12 messages will not be tested by Inferno.
|
3
|
+
hl7.fhir.us.davinci-pas_2.0.1,13,Not Tested,Details of X12 messages will not be tested by Inferno.
|
4
|
+
hl7.fhir.us.davinci-pas_2.0.1,14,Not Tested,Details of X12 messages will not be tested by Inferno.
|
5
|
+
hl7.fhir.us.davinci-pas_2.0.1,15,Not Tested,Details of X12 messages will not be tested by Inferno.
|
6
|
+
hl7.fhir.us.davinci-pas_2.0.1,96,Not Tested,Details of X12 messages will not be tested by Inferno.
|
7
|
+
hl7.fhir.us.davinci-pas_2.0.1,108,Not Verifiable,The specification does not provide clear details on the indicated responses (unclear diagram)
|
8
|
+
hl7.fhir.us.davinci-pas_2.0.1,109,Not Verifiable,The specification does not provide clear details on the indicated responses (unclear diagram)
|
9
|
+
hl7.fhir.us.davinci-pas_2.0.1,124,Not Tested,The rules for determining matching claims are specified in a proprietary X12 specification.
|
10
|
+
hl7.fhir.us.davinci-pas_2.0.1,132,Not Tested,How to request a subset of information is not detailed in the specification and lives in priopietary X12 specifications and mappings.
|
11
|
+
hl7.fhir.us.davinci-pas_2.0.1,191,Not Tested,Details of payer business rules will not be tested by Inferno.
|