davinci_crd_test_kit 0.9.0 → 0.9.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|