Module: DaVinciCRDTestKit::CardsValidation
- Includes:
- HookRequestFieldValidation, SuggestionActionsValidation
- Included in:
- V201::CardOptionalFieldsValidationTest, V201::InfernoResponseValidationTest, V201::ServiceResponseValidationTest, V221::AdditionalOrdersValidationTest, V221::CardOptionalFieldsValidationTest, V221::CreateOrUpdateCoverageInfoResponseValidationTest, V221::ExternalReferenceCardValidationTest, V221::FormCompletionResponseValidationTest, V221::InfernoResponseValidationTest, V221::LaunchSmartAppCardValidationTest, V221::ProposeAlternateRequestCardValidationTest, V221::ServiceResponseValidationTest
- Defined in:
- lib/davinci_crd_test_kit/cross_suite/cards_validation.rb
Constant Summary
collapse
- HOOKS =
[
'appointment-book', 'encounter-discharge', 'encounter-start',
'order-dispatch', 'order-select', 'order-sign'
].freeze
ProfilesAndResourceTypes::ORDER_OR_ENCOUNTER_RESOURCE_CLASSES, ProfilesAndResourceTypes::ORDER_RESOURCE_CLASSES, ProfilesAndResourceTypes::ORDER_RESOURCE_TYPES
RequestsLogicalModelValidation::CRD_CDS_HOOK_REQUEST_MODEL_URL, RequestsLogicalModelValidation::PERFORMER_ALLOWED_RESOURCE_TYPES, RequestsLogicalModelValidation::USER_ID_ALLOWED_RESOURCE_TYPES
Instance Method Summary
collapse
#action_fields_validation, #action_resource_type_check, #actions_check
#hook_request_context_check, #hook_request_optional_fields_check, #hook_request_prefetch_check, #hook_request_required_fields_check, #json_parse, #no_error_validation
#structure_definition_map, #structure_definition_map_v201, #structure_definition_map_v221
#client_fhir_base_url, #fhir_url, #instance_url, #search_url
Methods included from BaseURLs
#inferno_base_url, #resume_fail_url, #resume_pass_url
#validate_request_against_logical_model
#allowed_resource_type?, #check_appointment_conformance, #check_order_like_resource_conformance, #check_resource_conformance_to_coverage_profile, #check_resource_conformance_to_order_or_encounter_profile, #check_resource_conformance_to_order_profile, #check_resource_conformance_to_questionnaire_task_profile, #check_resource_type_and_validate, #local_reference?, #manually_check_appointment_validation_errors, #parse_action_resource, #primary_performer_type?, #referenced_resource_present_in_bundle?, #reject_resource_issues, #resolved_participant_patient_slice_issue?, #resolved_participant_primary_performer_slice_issue?
Instance Method Details
#additional_orders_check(card) ⇒ Object
172
173
174
|
# File 'lib/davinci_crd_test_kit/cross_suite/cards_validation.rb', line 172
def additional_orders_check(card)
no_links_check(card, 'Additional Orders')
end
|
#all_requests ⇒ Object
288
289
290
291
292
293
|
# File 'lib/davinci_crd_test_kit/cross_suite/cards_validation.rb', line 288
def all_requests
@all_requests ||= HOOKS.each_with_object([]) do |hook, reqs|
load_tagged_requests(hook)
reqs.concat(requests)
end
end
|
#card_indicator_check(card) ⇒ Object
246
247
248
249
250
251
|
# File 'lib/davinci_crd_test_kit/cross_suite/cards_validation.rb', line 246
def card_indicator_check(card)
return if !card['indicator'].is_a?(String) || ['info', 'warning', 'critical'].include?(card['indicator'])
msg = "`indicator` is `#{card['indicator']}`. Allowed values are `info`, `warning`, `critical`: `#{card}`"
add_message('error', msg)
end
|
#card_links_check(card) ⇒ Object
rubocop:disable Metrics/CyclomaticComplexity
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
# File 'lib/davinci_crd_test_kit/cross_suite/cards_validation.rb', line 109
def card_links_check(card) return unless card['links'].is_a?(Array) && card['links'].present?
card['links'].each do |link|
link_required_fields.each do |field, type|
validate_presence_and_type(link, field, type, 'Link')
end
end
if card['links'].all? { |link| link['type'] == 'absolute' }
external_reference_card_check(card)
elsif card['links'].all? { |link| link['type'] == 'smart' }
smart_app_card_check(card)
else
add_message(
'error',
"All links must either be `absolute` or `smart` in card: #{card}"
)
end
end
|
#card_optional_fields ⇒ Object
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
# File 'lib/davinci_crd_test_kit/cross_suite/cards_validation.rb', line 37
def card_optional_fields
{
'v221' => {
'detail' => String,
'indicator' => String,
'suggestions' => Array,
'selectionBehavior' => String,
'overrideReasons' => Array,
'links' => Array
},
'v201' => {
'detail' => String,
'uuid' => String,
'suggestions' => Array,
'selectionBehavior' => String,
'overrideReasons' => Array,
'links' => Array
}
}
end
|
#card_override_reasons_check(card) ⇒ Object
99
100
101
102
103
104
105
106
107
|
# File 'lib/davinci_crd_test_kit/cross_suite/cards_validation.rb', line 99
def card_override_reasons_check(card)
return unless card['overrideReasons'].is_a?(Array)
card['overrideReasons'].each do |reason|
override_reasons_required_fields.each do |field, type|
validate_presence_and_type(reason, field, type, 'OverrideReason Coding')
end
end
end
|
#card_required_fields ⇒ Object
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
# File 'lib/davinci_crd_test_kit/cross_suite/cards_validation.rb', line 14
def card_required_fields
{
'v221' => {
'uuid' => String,
'summary' => String,
'source' => Hash
},
'v201' => {
'indicator' => String,
'summary' => String,
'source' => Hash
}
}
end
|
#card_selection_behavior_check(card) ⇒ Object
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
# File 'lib/davinci_crd_test_kit/cross_suite/cards_validation.rb', line 82
def card_selection_behavior_check(card)
return unless card['suggestions'].present?
selection_behavior = card['selectionBehavior']
unless selection_behavior
add_message('error', "`Card.selectionBehavior` must be provided if suggestions are present. In Card `#{card}`")
return
end
allowed_values = ['at-most-one', 'any']
return if allowed_values.include?(selection_behavior)
error_msg = "`selectionBehavior` #{selection_behavior} not allowed. " \
"Allowed values: #{allowed_values.to_sentence}. In Card `#{card}`"
add_message('error', error_msg)
end
|
#card_source_check(card) ⇒ Object
220
221
222
223
224
225
226
227
228
229
230
|
# File 'lib/davinci_crd_test_kit/cross_suite/cards_validation.rb', line 220
def card_source_check(card)
source = card['source']
return unless source.is_a?(Hash)
source_required_fields.each do |field, type|
validate_presence_and_type(source, field, type, 'Source')
end
card_source_topic_check(source['topic'])
end
|
#card_source_topic_check(topic) ⇒ Object
232
233
234
235
236
237
238
|
# File 'lib/davinci_crd_test_kit/cross_suite/cards_validation.rb', line 232
def card_source_topic_check(topic)
return unless topic.is_a?(Hash)
source_topic_required_fields.each do |field, type|
validate_presence_and_type(topic, field, type, 'Source topic')
end
end
|
#card_suggestions_check(card) ⇒ Object
188
189
190
191
192
193
194
|
# File 'lib/davinci_crd_test_kit/cross_suite/cards_validation.rb', line 188
def card_suggestions_check(card)
return unless card['suggestions'].is_a?(Array) && card['suggestions'].present?
card['suggestions'].each do |suggestion|
process_suggestion(card, suggestion)
end
end
|
#card_summary_check(card) ⇒ Object
240
241
242
243
244
|
# File 'lib/davinci_crd_test_kit/cross_suite/cards_validation.rb', line 240
def card_summary_check(card)
return if !card['summary'].is_a?(String) || card['summary'].length < 140
add_message('error', "`summary` is over the 140-character limit: `#{card['summary']}`")
end
|
#cards_check(cards, version = 'v221') ⇒ Object
253
254
255
256
257
258
259
260
261
262
263
264
265
266
|
# File 'lib/davinci_crd_test_kit/cross_suite/cards_validation.rb', line 253
def cards_check(cards, version = 'v221')
cards.each do |card|
current_error_count = messages.count { |msg| msg[:type] == 'error' }
card_required_fields[version].each do |field, type|
validate_presence_and_type(card, field, type, 'Card')
end
card_summary_check(card)
card_indicator_check(card)
card_source_check(card)
valid_cards << card if current_error_count == messages.count { |msg| msg[:type] == 'error' }
end
end
|
#create_or_update_coverage_check(card) ⇒ Object
176
177
178
|
# File 'lib/davinci_crd_test_kit/cross_suite/cards_validation.rb', line 176
def create_or_update_coverage_check(card)
no_links_check(card, 'Update Coverage Records')
end
|
#external_reference_card_check(card) ⇒ Object
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
# File 'lib/davinci_crd_test_kit/cross_suite/cards_validation.rb', line 130
def external_reference_card_check(card)
if card['suggestions'].present?
add_message(
'error',
"Cards with `absolute` links must not contain suggestions. In card `#{card}`"
)
end
card['links'].each do |link|
next if link['appContext'].blank?
add_message(
'error',
'`appContext` field must not be present if the link type is absolute: ' \
"`#{link}`. In Card `#{card}`"
)
end
end
|
180
181
182
|
# File 'lib/davinci_crd_test_kit/cross_suite/cards_validation.rb', line 180
def form_completion_check(card)
no_links_check(card, 'Form Completion')
end
|
#link_required_fields ⇒ Object
62
63
64
|
# File 'lib/davinci_crd_test_kit/cross_suite/cards_validation.rb', line 62
def link_required_fields
{ 'label' => String, 'type' => String, 'url' => 'URL' }
end
|
#no_links_check(card, card_type) ⇒ Object
163
164
165
166
167
168
169
170
|
# File 'lib/davinci_crd_test_kit/cross_suite/cards_validation.rb', line 163
def no_links_check(card, card_type)
return unless card['links'].present?
add_message(
'error',
"#{card_type} response must not contain links. In card: `#{card}`"
)
end
|
#override_reasons_required_fields ⇒ Object
58
59
60
|
# File 'lib/davinci_crd_test_kit/cross_suite/cards_validation.rb', line 58
def override_reasons_required_fields
{ 'code' => String, 'system' => String, 'display' => String }
end
|
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
|
# File 'lib/davinci_crd_test_kit/cross_suite/cards_validation.rb', line 272
def perform_cards_validation(cards, response_has_system_actions, version, response_index)
unless cards
add_message('error', "#{response_label(response_index + 1)} did not have the `cards` field.")
return
end
unless cards.is_a?(Array)
add_message('error', "`cards` field of #{response_label(response_index + 1).downcase} is not an array.")
return
end
warning do
assert cards.present? || response_has_system_actions,
"#{response_label(response_index + 1)} has no decision support."
end
cards_check(cards, version)
end
|
#process_suggestion(card, suggestion) ⇒ Object
196
197
198
199
200
201
202
|
# File 'lib/davinci_crd_test_kit/cross_suite/cards_validation.rb', line 196
def process_suggestion(card, suggestion)
validate_presence_and_type(suggestion, 'label', String, 'Suggestion')
validate_presence_and_type(suggestion, 'uuid', String, 'Suggestion')
return unless suggestion['actions']
validate_and_process_actions(card, suggestion)
end
|
#propose_alternate_request_check(card) ⇒ Object
184
185
186
|
# File 'lib/davinci_crd_test_kit/cross_suite/cards_validation.rb', line 184
def propose_alternate_request_check(card)
no_links_check(card, 'Propose Alternate Request')
end
|
#response_label(index = nil) ⇒ Object
268
269
270
|
# File 'lib/davinci_crd_test_kit/cross_suite/cards_validation.rb', line 268
def response_label(index = nil)
"Server response #{index}"
end
|
#smart_app_card_check(card) ⇒ Object
149
150
151
152
153
154
155
156
157
158
159
160
161
|
# File 'lib/davinci_crd_test_kit/cross_suite/cards_validation.rb', line 149
def smart_app_card_check(card)
if card['suggestions'].blank?
add_message(
'error',
"Cards with `smart` links must contain at least one suggestion. In card `#{card}`"
)
elsif card['suggestions'].any? { |suggestion| suggestion['actions'].present? }
add_message(
'error',
"Cards with `smart` links must not contain any suggestion actions. In card `#{card}`"
)
end
end
|
#source_required_fields ⇒ Object
29
30
31
|
# File 'lib/davinci_crd_test_kit/cross_suite/cards_validation.rb', line 29
def source_required_fields
{ 'label' => String, 'topic' => Hash }
end
|
#source_topic_required_fields ⇒ Object
33
34
35
|
# File 'lib/davinci_crd_test_kit/cross_suite/cards_validation.rb', line 33
def source_topic_required_fields
{ 'code' => String, 'system' => String }
end
|
#valid_card_with_optionals?(card, version) ⇒ Boolean
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
# File 'lib/davinci_crd_test_kit/cross_suite/cards_validation.rb', line 66
def valid_card_with_optionals?(card, version)
current_error_count = messages.count { |msg| msg[:type] == 'error' }
card_optional_fields[version].each do |field, type|
next unless card[field]
validate_presence_and_type(card, field, type, 'Card', required: false)
end
card_selection_behavior_check(card)
card_override_reasons_check(card)
card_links_check(card)
card_suggestions_check(card)
current_error_count == messages.count { |msg| msg[:type] == 'error' }
end
|
#validate_and_process_actions(card, suggestion) ⇒ Object
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
|
# File 'lib/davinci_crd_test_kit/cross_suite/cards_validation.rb', line 204
def validate_and_process_actions(card, suggestion)
actions = suggestion['actions']
if !actions.is_a?(Array)
add_message('error', "Suggestion `actions` field is not of type Array: `#{suggestion}`. In Card `#{card}`")
return
elsif actions.empty?
add_message('error',
"Suggestion `actions` field should not be an empty Array: `#{suggestion}`. In Card `#{card}`")
return
end
actions.each do |action|
action_fields_validation(action)
end
end
|