davinci_crd_test_kit 0.9.0 → 0.9.1
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_crd_test_kit/card_responses/propose_alternate_request.json +2 -52
- data/lib/davinci_crd_test_kit/card_responses/request_form_completion.json +46 -31
- data/lib/davinci_crd_test_kit/cards_validation.rb +8 -4
- data/lib/davinci_crd_test_kit/client_hooks_group.rb +22 -660
- data/lib/davinci_crd_test_kit/client_tests/appointment_book_receive_request_test.rb +17 -6
- data/lib/davinci_crd_test_kit/client_tests/client_appointment_book_group.rb +70 -0
- data/lib/davinci_crd_test_kit/client_tests/client_encounter_discharge_group.rb +71 -0
- data/lib/davinci_crd_test_kit/client_tests/client_encounter_start_group.rb +70 -0
- data/lib/davinci_crd_test_kit/client_tests/client_order_dispatch_group.rb +70 -0
- data/lib/davinci_crd_test_kit/client_tests/client_order_select_group.rb +72 -0
- data/lib/davinci_crd_test_kit/client_tests/client_order_sign_group.rb +71 -0
- data/lib/davinci_crd_test_kit/client_tests/decode_auth_token_test.rb +43 -23
- data/lib/davinci_crd_test_kit/client_tests/encounter_discharge_receive_request_test.rb +19 -6
- data/lib/davinci_crd_test_kit/client_tests/encounter_start_receive_request_test.rb +18 -6
- data/lib/davinci_crd_test_kit/client_tests/hook_request_optional_fields_test.rb +26 -10
- data/lib/davinci_crd_test_kit/client_tests/hook_request_required_fields_test.rb +20 -11
- data/lib/davinci_crd_test_kit/client_tests/hook_request_valid_context_test.rb +14 -10
- data/lib/davinci_crd_test_kit/client_tests/hook_request_valid_prefetch_test.rb +27 -110
- data/lib/davinci_crd_test_kit/client_tests/order_dispatch_receive_request_test.rb +18 -6
- data/lib/davinci_crd_test_kit/client_tests/order_select_receive_request_test.rb +18 -6
- data/lib/davinci_crd_test_kit/client_tests/order_sign_receive_request_test.rb +18 -6
- data/lib/davinci_crd_test_kit/client_tests/retrieve_jwks_test.rb +66 -29
- data/lib/davinci_crd_test_kit/client_tests/submitted_response_validation.rb +44 -0
- data/lib/davinci_crd_test_kit/client_tests/token_header_test.rb +45 -14
- data/lib/davinci_crd_test_kit/client_tests/token_payload_test.rb +43 -26
- data/lib/davinci_crd_test_kit/crd_client_suite.rb +0 -4
- data/lib/davinci_crd_test_kit/hook_request_field_validation.rb +240 -50
- data/lib/davinci_crd_test_kit/mock_service_response.rb +134 -120
- data/lib/davinci_crd_test_kit/routes/hook_request_endpoint.rb +26 -42
- data/lib/davinci_crd_test_kit/server_encounter_discharge_group.rb +24 -0
- data/lib/davinci_crd_test_kit/server_encounter_start_group.rb +24 -0
- data/lib/davinci_crd_test_kit/server_order_select_group.rb +24 -0
- data/lib/davinci_crd_test_kit/server_tests/coverage_information_system_action_received_test.rb +4 -1
- data/lib/davinci_crd_test_kit/server_tests/service_request_optional_fields_validation_test.rb +8 -10
- data/lib/davinci_crd_test_kit/server_tests/service_request_required_fields_validation_test.rb +5 -10
- data/lib/davinci_crd_test_kit/tags.rb +6 -6
- data/lib/davinci_crd_test_kit/version.rb +1 -1
- metadata +9 -2
@@ -1,5 +1,20 @@
|
|
1
1
|
module DaVinciCRDTestKit
|
2
2
|
module HookRequestFieldValidation
|
3
|
+
def request_number
|
4
|
+
if @request_number.blank?
|
5
|
+
''
|
6
|
+
else
|
7
|
+
"Request #{@request_number}: "
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def json_parse(json)
|
12
|
+
JSON.parse(json)
|
13
|
+
rescue JSON::ParserError
|
14
|
+
add_message('error', "#{request_number}Invalid JSON.")
|
15
|
+
false
|
16
|
+
end
|
17
|
+
|
3
18
|
def hook_required_fields
|
4
19
|
{
|
5
20
|
'hook' => String,
|
@@ -82,23 +97,61 @@ module DaVinciCRDTestKit
|
|
82
97
|
'Medication' => 'http://hl7.org/fhir/us/core/StructureDefinition/us-core-medication',
|
83
98
|
'Device' => 'http://hl7.org/fhir/us/davinci-crd/StructureDefinition/profile-device',
|
84
99
|
'CommunicationRequest' => 'http://hl7.org/fhir/us/davinci-crd/StructureDefinition/profile-communicationrequest',
|
85
|
-
'Task' => 'http://hl7.org/fhir/us/davinci-crd/StructureDefinition/profile-taskquestionnaire'
|
100
|
+
'Task' => 'http://hl7.org/fhir/us/davinci-crd/StructureDefinition/profile-taskquestionnaire',
|
101
|
+
'Coverage' => 'http://hl7.org/fhir/us/davinci-crd/StructureDefinition/profile-coverage',
|
102
|
+
'Location' => 'http://hl7.org/fhir/us/davinci-crd/StructureDefinition/profile-location',
|
103
|
+
'Organization' => 'http://hl7.org/fhir/us/davinci-crd/StructureDefinition/profile-organization'
|
86
104
|
}.freeze
|
87
105
|
end
|
88
106
|
|
89
107
|
def hook_request_required_fields_check(request_body, hook_name)
|
90
108
|
hook_required_fields.each do |field, type|
|
91
|
-
|
92
|
-
|
109
|
+
if request_body[field].blank?
|
110
|
+
add_message('error', "#{request_number}Hook request did not contain required field: `#{field}`")
|
111
|
+
next
|
112
|
+
end
|
113
|
+
|
114
|
+
unless request_body[field].is_a?(type)
|
115
|
+
add_message('error', "#{request_number}Hook request field #{field} is not of type #{type}")
|
116
|
+
next
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
if request_body['hook'] != hook_name
|
121
|
+
add_message('error',
|
122
|
+
"#{request_number}The `hook` field should be #{hook_name}, but was #{request_body['hook']}")
|
123
|
+
return
|
93
124
|
end
|
94
125
|
|
95
|
-
|
96
|
-
"The `hook` field should be #{hook_name}, but was #{request_body['hook']}")
|
126
|
+
return unless request_body['fhirAuthorization'].present? && request_body['fhirServer'].blank?
|
97
127
|
|
98
|
-
|
128
|
+
add_message('error', %(
|
129
|
+
#{request_number}Missing `fhirServer` field: If `fhirAuthorization` is provided, this field is
|
130
|
+
#REQUIRED.))
|
131
|
+
end
|
132
|
+
|
133
|
+
def fhir_auth_fields_valid?(fhir_authorization_required_fields, fhir_authorization)
|
134
|
+
fhir_auth_valid = true
|
135
|
+
fhir_authorization_required_fields.each do |field, type|
|
136
|
+
if fhir_authorization[field].blank?
|
137
|
+
add_message('error', "#{request_number}`fhirAuthorization` did not contain required field: `#{field}`")
|
138
|
+
fhir_auth_valid = false
|
139
|
+
end
|
140
|
+
unless fhir_authorization[field].is_a?(type)
|
141
|
+
add_message('error', "#{request_number}`fhirAuthorization` field #{field} is not of type #{type}")
|
142
|
+
fhir_auth_valid = false
|
143
|
+
end
|
144
|
+
end
|
145
|
+
fhir_auth_valid
|
146
|
+
end
|
99
147
|
|
100
|
-
|
101
|
-
|
148
|
+
def check_patient_scope_requirement(scopes, fhir_authorization)
|
149
|
+
if scopes.any? { |scope| scope.start_with?('patient/') } &&
|
150
|
+
!(fhir_authorization['patient'] && fhir_authorization['patient'].is_a?(String))
|
151
|
+
info %(
|
152
|
+
#{request_number}The `patient` field for request SHOULD be populated to identify the FHIR id of that
|
153
|
+
patient when the granted SMART scopes include patient scopes)
|
154
|
+
end
|
102
155
|
end
|
103
156
|
|
104
157
|
def hook_request_fhir_auth_check(request_body)
|
@@ -106,36 +159,27 @@ module DaVinciCRDTestKit
|
|
106
159
|
|
107
160
|
fhir_authorization = request_body['fhirAuthorization']
|
108
161
|
|
109
|
-
|
110
|
-
assert(fhir_authorization[field], "`fhirAuthorization` did not contain required field: `#{field}`")
|
111
|
-
assert(fhir_authorization[field].is_a?(type), "`fhirAuthorization` field #{field} is not of type #{type}")
|
112
|
-
end
|
162
|
+
return unless fhir_auth_fields_valid?(fhir_authorization_required_fields, fhir_authorization)
|
113
163
|
|
114
|
-
|
115
|
-
|
164
|
+
if fhir_authorization['token_type'] != 'Bearer'
|
165
|
+
add_message('error', "#{request_number}`fhirAuthorization` `token_type` field is not set to 'Bearer'")
|
166
|
+
end
|
116
167
|
|
117
168
|
access_token = fhir_authorization['access_token']
|
118
169
|
|
119
170
|
scopes = fhir_authorization['scope'].split
|
120
171
|
|
121
|
-
|
122
|
-
info do
|
123
|
-
assert(fhir_authorization['patient'] && fhir_authorization['patient'].is_a?(String),
|
124
|
-
%(The `patient` field SHOULD be populated to identify the FHIR id of that patient when the granted
|
125
|
-
SMART scopes include patient scopes))
|
126
|
-
end
|
127
|
-
end
|
172
|
+
check_patient_scope_requirement(scopes, fhir_authorization)
|
128
173
|
end
|
129
174
|
{ fhir_server_uri: request_body['fhirServer'], fhir_access_token: access_token }
|
130
175
|
end
|
131
176
|
|
132
177
|
def hook_request_optional_fields_check(request_body)
|
133
178
|
hook_optional_fields.each do |field, type|
|
134
|
-
info
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
assert(request_body[field].is_a?(type), "Hook request field #{field} is not of type #{type}")
|
179
|
+
info "#{request_number}Hook request did not contain optional field: `#{field}`" if request_body[field].blank?
|
180
|
+
|
181
|
+
if request_body[field] && !request_body[field].is_a?(type)
|
182
|
+
add_message('error', "#{request_number}Hook request field #{field} is not of type #{type}")
|
139
183
|
end
|
140
184
|
end
|
141
185
|
hook_request_fhir_auth_check(request_body)
|
@@ -165,7 +209,8 @@ module DaVinciCRDTestKit
|
|
165
209
|
def hook_request_context_check(context, hook_name)
|
166
210
|
required_fields = context_required_fields_by_hook[hook_name]
|
167
211
|
required_fields.each do |field, type|
|
168
|
-
validate_presence_and_type(context, field, type,
|
212
|
+
validate_presence_and_type(context, field, type,
|
213
|
+
"#{request_number}#{hook_name} request context")
|
169
214
|
end
|
170
215
|
context_validate_optional_fields(context, hook_name)
|
171
216
|
hook_specific_context_check(context, hook_name)
|
@@ -195,7 +240,7 @@ module DaVinciCRDTestKit
|
|
195
240
|
resource_type, resource_id = reference.split('/')
|
196
241
|
|
197
242
|
if supported_resource_types && !supported_resource_types.include?(resource_type)
|
198
|
-
error_msg = "Unsupported resource type: `#{field_name}` type should be one " \
|
243
|
+
error_msg = "#{request_number}Unsupported resource type: `#{field_name}` type should be one " \
|
199
244
|
"of the following: #{supported_resource_types.to_sentence}, but " \
|
200
245
|
"received #{resource_type}."
|
201
246
|
|
@@ -210,7 +255,10 @@ module DaVinciCRDTestKit
|
|
210
255
|
resource_type, resource_id = reference.split('/')
|
211
256
|
return true if resource_type.present? && resource_id.present?
|
212
257
|
|
213
|
-
add_message('error',
|
258
|
+
add_message('error', %(
|
259
|
+
#{request_number}Invalid `#{field_name}` format. Expected `{resourceType}/{id}`,
|
260
|
+
received `#{reference}`.
|
261
|
+
))
|
214
262
|
false
|
215
263
|
end
|
216
264
|
|
@@ -228,7 +276,9 @@ module DaVinciCRDTestKit
|
|
228
276
|
|
229
277
|
def valid_id_format?(field, hook_name, resource_id)
|
230
278
|
if resource_id.include?('/')
|
231
|
-
error_msg =
|
279
|
+
error_msg = %(
|
280
|
+
#{request_number}`#{field}` in #{hook_name} context should be a plain ID, not a reference.
|
281
|
+
Got: `#{resource_id}`.)
|
232
282
|
add_message('error', error_msg)
|
233
283
|
false
|
234
284
|
end
|
@@ -237,9 +287,9 @@ module DaVinciCRDTestKit
|
|
237
287
|
|
238
288
|
def bundle_entries_check(context, context_field_name, bundle, resource_types, status = nil)
|
239
289
|
target_resources = bundle.entry.map(&:resource).select { |r| resource_types.include?(r.resourceType) }
|
240
|
-
|
241
|
-
error_msg = "`#{context_field_name}` bundle must contain at least one of the
|
242
|
-
"#{resource_types.to_sentence}. In Context `#{context}`"
|
290
|
+
if target_resources.blank?
|
291
|
+
error_msg = "#{request_number}`#{context_field_name}` bundle must contain at least one of the " \
|
292
|
+
"expected resource types: #{resource_types.to_sentence}. In Context `#{context}`"
|
243
293
|
add_message('error', error_msg)
|
244
294
|
return
|
245
295
|
end
|
@@ -254,24 +304,24 @@ module DaVinciCRDTestKit
|
|
254
304
|
def status_check(context, context_field_name, status, resources)
|
255
305
|
return unless status && !resources.all? { |resource| resource.status == status }
|
256
306
|
|
257
|
-
error_msg = "All #{resources.map(&:resourceType).uniq.to_sentence} resources in
|
258
|
-
"bundle must have a `#{status}` status. In Context `#{context}`"
|
307
|
+
error_msg = "#{request_number}All #{resources.map(&:resourceType).uniq.to_sentence} resources in " \
|
308
|
+
"`#{context_field_name}` bundle must have a `#{status}` status. In Context `#{context}`"
|
259
309
|
add_message('error', error_msg)
|
260
310
|
end
|
261
311
|
|
262
312
|
def parse_fhir_bundle_from_context(context_field_name, context)
|
263
313
|
fhir_bundle = FHIR.from_contents(context[context_field_name].to_json)
|
264
|
-
|
265
|
-
error_msg = "`#{context_field_name}` field is not a FHIR resource:
|
266
|
-
"In Context `#{context}`"
|
314
|
+
if fhir_bundle.blank?
|
315
|
+
error_msg = "#{request_number}`#{context_field_name}` field is not a FHIR resource: " \
|
316
|
+
"`#{context[context_field_name]}`. In Context `#{context}`"
|
267
317
|
add_message('error', error_msg)
|
268
318
|
return
|
269
319
|
end
|
270
320
|
|
271
321
|
return fhir_bundle if fhir_bundle.is_a?(FHIR::Bundle)
|
272
322
|
|
273
|
-
error_msg = "Wrong context resource type: Expected `Bundle`, got
|
274
|
-
"In Context `#{context}`"
|
323
|
+
error_msg = "#{request_number}Wrong context resource type: Expected `Bundle`, got " \
|
324
|
+
"`#{fhir_bundle.resourceType}`. In Context `#{context}`"
|
275
325
|
add_message('error', error_msg)
|
276
326
|
nil
|
277
327
|
end
|
@@ -283,7 +333,7 @@ module DaVinciCRDTestKit
|
|
283
333
|
resource_reference_check(reference, 'selections item', supported_resource_types: expected_resource_types)
|
284
334
|
next if order_refs.include?(reference)
|
285
335
|
|
286
|
-
error_msg =
|
336
|
+
error_msg = "#{request_number}`selections` field must reference FHIR resources in `draftOrders`. " \
|
287
337
|
"#{reference} is not in `draftOrders`. In Context `#{context}`"
|
288
338
|
add_message('error', error_msg)
|
289
339
|
end
|
@@ -294,7 +344,7 @@ module DaVinciCRDTestKit
|
|
294
344
|
id_only_fields_check('appointment-book', context, ['patientId'])
|
295
345
|
|
296
346
|
appointment_bundle = parse_fhir_bundle_from_context('appointments', context)
|
297
|
-
return
|
347
|
+
return if appointment_bundle.blank?
|
298
348
|
|
299
349
|
expected_resource_types = ['Appointment']
|
300
350
|
bundle_entries_check(context, 'appointments', appointment_bundle, expected_resource_types, 'proposed')
|
@@ -310,7 +360,7 @@ module DaVinciCRDTestKit
|
|
310
360
|
id_only_fields_check(hook_name, context, ['patientId'])
|
311
361
|
|
312
362
|
draft_orders_bundle = parse_fhir_bundle_from_context('draftOrders', context)
|
313
|
-
return
|
363
|
+
return if draft_orders_bundle.blank?
|
314
364
|
|
315
365
|
expected_resource_types = [
|
316
366
|
'DeviceRequest', 'MedicationRequest', 'NutritionOrder',
|
@@ -352,15 +402,20 @@ module DaVinciCRDTestKit
|
|
352
402
|
fhir_read(resource_type, resource_id)
|
353
403
|
status = request.response[:status]
|
354
404
|
unless status == 200
|
355
|
-
add_message('error', "Unexpected response status: expected 200, but received #{status}")
|
405
|
+
add_message('error', "#{request_number}Unexpected response status: expected 200, but received #{status}")
|
356
406
|
return
|
357
407
|
end
|
358
408
|
unless resource.resourceType == resource_type
|
359
|
-
add_message('error',
|
409
|
+
add_message('error', %(
|
410
|
+
#{request_number}Unexpected resource type: Expected `#{resource_type}`. Got
|
411
|
+
`#{resource.resourceType}`.
|
412
|
+
))
|
360
413
|
return
|
361
414
|
end
|
362
415
|
unless resource.id == resource_id
|
363
|
-
add_message('error',
|
416
|
+
add_message('error', %(
|
417
|
+
#{request_number}Requested resource with id #{resource_id}, received resource with id #{resource.id}
|
418
|
+
))
|
364
419
|
return
|
365
420
|
end
|
366
421
|
|
@@ -370,7 +425,7 @@ module DaVinciCRDTestKit
|
|
370
425
|
|
371
426
|
def context_validate_optional_fields(hook_context, hook_name)
|
372
427
|
hook_optional_context_fields = context_optional_fields_by_hook[hook_name]
|
373
|
-
return
|
428
|
+
return if hook_optional_context_fields.blank?
|
374
429
|
|
375
430
|
hook_optional_context_fields.each do |field, type|
|
376
431
|
validate_presence_and_type(hook_context, field, type, "#{hook_name} request context") if hook_context[field]
|
@@ -394,17 +449,152 @@ module DaVinciCRDTestKit
|
|
394
449
|
hash_context_fields.each do |field, entry|
|
395
450
|
resource_json = entry.to_json
|
396
451
|
fhir_resource = FHIR.from_contents(resource_json)
|
397
|
-
|
398
|
-
add_message('error', "Field `#{field}` is not a FHIR resource.")
|
452
|
+
if fhir_resource.blank?
|
453
|
+
add_message('error', "#{request_number}Field `#{field}` is not a FHIR resource.")
|
399
454
|
next
|
400
455
|
end
|
401
456
|
resource_type = optional_field_resource_types[field]
|
402
457
|
unless fhir_resource.resourceType == resource_type
|
403
|
-
add_message('error',
|
458
|
+
add_message('error', %(
|
459
|
+
#{request_number}Field `#{field}` must be a `#{resource_type}`. Got
|
460
|
+
`#{fhir_resource.resourceType}`.
|
461
|
+
))
|
404
462
|
next
|
405
463
|
end
|
406
464
|
resource_is_valid?(resource: fhir_resource)
|
407
465
|
end
|
408
466
|
end
|
467
|
+
|
468
|
+
def hook_request_prefetch_check(advertised_prefetch_fields, received_prefetch, received_context)
|
469
|
+
advertised_prefetch_fields.each do |advertised_prefetch_key, advertised_prefetch_template|
|
470
|
+
next if received_prefetch[advertised_prefetch_key].blank?
|
471
|
+
|
472
|
+
unless received_prefetch[advertised_prefetch_key].is_a?(Hash)
|
473
|
+
add_message('error', "#{request_number}Prefetch field `#{advertised_prefetch_key}` is not of type `Hash`.")
|
474
|
+
next
|
475
|
+
end
|
476
|
+
|
477
|
+
received_prefetch_resource = FHIR.from_contents(received_prefetch[advertised_prefetch_key].to_json)
|
478
|
+
|
479
|
+
if advertised_prefetch_template.include?('?')
|
480
|
+
advertised_prefetch_fhir_search = advertised_prefetch_template.gsub(/{|}/, '').split('?')
|
481
|
+
advertised_prefetch_resource_type = advertised_prefetch_fhir_search.first
|
482
|
+
|
483
|
+
if advertised_prefetch_resource_type == 'Coverage'
|
484
|
+
advertised_coverage_query_params = Rack::Utils.parse_nested_query(advertised_prefetch_fhir_search.last)
|
485
|
+
|
486
|
+
advertised_patient_token = advertised_coverage_query_params['patient']
|
487
|
+
advertised_context_patient_id_key = advertised_patient_token.split('.').last
|
488
|
+
received_context_patient_id = received_context[advertised_context_patient_id_key]
|
489
|
+
|
490
|
+
advertised_status_param = advertised_coverage_query_params['status']
|
491
|
+
|
492
|
+
validate_prefetch_coverage(received_prefetch_resource, advertised_prefetch_key, received_context_patient_id,
|
493
|
+
advertised_status_param)
|
494
|
+
end
|
495
|
+
else
|
496
|
+
advertised_prefetch_token = advertised_prefetch_template.gsub(/{|}/, '').split('/')
|
497
|
+
advertised_context_id = advertised_prefetch_token.last.split('.').last
|
498
|
+
|
499
|
+
if advertised_prefetch_token.length == 1
|
500
|
+
received_context_reference = FHIR::Reference.new(reference: received_context[advertised_context_id])
|
501
|
+
received_context_resource_type = received_context_reference.resource_type
|
502
|
+
received_context_id = received_context_reference.reference_id
|
503
|
+
else
|
504
|
+
received_context_id = received_context[advertised_context_id]
|
505
|
+
received_context_resource_type = advertised_prefetch_token.first
|
506
|
+
end
|
507
|
+
validate_prefetch_resource(received_prefetch_resource, advertised_prefetch_key,
|
508
|
+
received_context_resource_type, received_context_id)
|
509
|
+
end
|
510
|
+
end
|
511
|
+
end
|
512
|
+
|
513
|
+
def validate_prefetch_coverage(received_resource, advertised_prefetch_key,
|
514
|
+
received_context_patient_id, advertised_status)
|
515
|
+
unless received_resource.resourceType == 'Bundle'
|
516
|
+
add_message('error', %(
|
517
|
+
#{request_number}Unexpected resource type: Expected `Bundle`. Got
|
518
|
+
`#{received_resource.resourceType}`.
|
519
|
+
))
|
520
|
+
return
|
521
|
+
end
|
522
|
+
|
523
|
+
if received_resource.entry.empty?
|
524
|
+
add_message('error', "#{request_number}Bundle of coverage resources received from prefetch is empty")
|
525
|
+
return
|
526
|
+
end
|
527
|
+
|
528
|
+
coverage_resource = received_resource.entry.first.resource
|
529
|
+
unless coverage_resource.resourceType == 'Coverage'
|
530
|
+
add_message('error', %(
|
531
|
+
#{request_number}Unexpected resource type: Expected `Coverage`. Got
|
532
|
+
`#{coverage_resource.resourceType}`.
|
533
|
+
))
|
534
|
+
return
|
535
|
+
end
|
536
|
+
|
537
|
+
resource_is_valid?(resource: coverage_resource,
|
538
|
+
profile_url: structure_definition_map['Coverage'])
|
539
|
+
|
540
|
+
coverage_beneficiary_reference = coverage_resource.beneficiary
|
541
|
+
coverage_beneficiary_patient_id = coverage_beneficiary_reference.reference_id
|
542
|
+
if coverage_beneficiary_patient_id.blank?
|
543
|
+
add_message('error', %(
|
544
|
+
#{request_number}Could not get beneficiary reference id from `#{advertised_prefetch_key}` field's Coverage
|
545
|
+
resource
|
546
|
+
))
|
547
|
+
return
|
548
|
+
end
|
549
|
+
|
550
|
+
if coverage_beneficiary_patient_id != received_context_patient_id
|
551
|
+
add_message('error', %(
|
552
|
+
#{request_number}Expected `#{advertised_prefetch_key}` field's Coverage resource to have a `beneficiary`
|
553
|
+
reference id of '#{received_context_patient_id}', instead was '#{coverage_beneficiary_patient_id}'
|
554
|
+
))
|
555
|
+
return
|
556
|
+
end
|
557
|
+
|
558
|
+
coverage_status = coverage_resource.status
|
559
|
+
return unless coverage_status != advertised_status
|
560
|
+
|
561
|
+
add_message('error', %(
|
562
|
+
#{request_number}Expected `#{advertised_prefetch_key}` field's Coverage resource to have a `status` of
|
563
|
+
'#{advertised_status}', instead was '#{coverage_status}'
|
564
|
+
))
|
565
|
+
end
|
566
|
+
|
567
|
+
def validate_prefetch_resource(received_resource, advertised_prefetch_key, context_field_resource_type,
|
568
|
+
context_field_id)
|
569
|
+
unless received_resource.resourceType == context_field_resource_type
|
570
|
+
add_message('error', %(
|
571
|
+
#{request_number}Unexpected resource type: Expected `#{context_field_resource_type}`. Got
|
572
|
+
`#{received_resource.resourceType}`.
|
573
|
+
))
|
574
|
+
return
|
575
|
+
end
|
576
|
+
|
577
|
+
if hook_name == 'order-dispatch'
|
578
|
+
resource_is_valid?(resource: received_resource)
|
579
|
+
else
|
580
|
+
resource_is_valid?(resource: received_resource,
|
581
|
+
profile_url: structure_definition_map[context_field_resource_type])
|
582
|
+
end
|
583
|
+
|
584
|
+
received_prefetch_resource_id = received_resource.id
|
585
|
+
if received_prefetch_resource_id.blank?
|
586
|
+
add_message('error', %(
|
587
|
+
#{request_number}#{advertised_prefetch_key}` field's FHIR resource does not contain the `id` field
|
588
|
+
))
|
589
|
+
return
|
590
|
+
end
|
591
|
+
|
592
|
+
return unless received_prefetch_resource_id != context_field_id
|
593
|
+
|
594
|
+
add_message('error', %(
|
595
|
+
#{request_number}Expected `#{advertised_prefetch_key}` field's FHIR resource to have an `id` of
|
596
|
+
'#{context_field_id}', instead was '#{received_prefetch_resource_id}'
|
597
|
+
))
|
598
|
+
end
|
409
599
|
end
|
410
600
|
end
|