Module: DaVinciCRDTestKit::SuggestionActionsValidation

Instance Method Summary collapse

Methods included from ServerHookRequestValidation

#client_test?, #server_test?

Methods included from HookRequestFieldValidation

#appointment_book_context_check, #bundle_entries_check, #check_patient_scope_requirement, #common_context_fields, #context_optional_fields_by_hook, #context_required_fields_by_hook, #context_selections_check, #context_user_types_by_hook, #context_validate_optional_fields, #encounter_start_or_discharge_context_check, #fhir_auth_fields_valid?, #fhir_authorization_required_fields, #hook_optional_fields, #hook_request_context_check, #hook_request_fhir_auth_check, #hook_request_optional_fields_check, #hook_request_prefetch_check, #hook_request_required_fields_check, #hook_required_fields, #hook_specific_context_check, #hook_user_type_check, #id_only_fields_check, #json_parse, #no_error_validation, #optional_field_resource_types, #order_dispatch_context_check, #order_select_or_sign_context_check, #parse_fhir_bundle_from_context, #query_and_validate_id_field, #request_number, #resource_reference_check, #status_check, #structure_definition_map, #valid_id_format?, #valid_reference_format?, #valid_url?, #validate_hash_fields, #validate_prefetch_coverage, #validate_prefetch_resource, #validate_presence_and_type

Instance Method Details

#action_fields_validation(action) ⇒ Object



10
11
12
13
14
15
16
# File 'lib/davinci_crd_test_kit/suggestion_actions_validation.rb', line 10

def action_fields_validation(action)
  action_required_fields.each do |field, type|
    validate_presence_and_type(action, field, type, 'Action')
  end

  action_type_field_validation(action)
end

#action_required_fieldsObject



6
7
8
# File 'lib/davinci_crd_test_kit/suggestion_actions_validation.rb', line 6

def action_required_fields
  { 'type' => String, 'description' => String }
end

#action_resource_field_validation(action, type) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
# File 'lib/davinci_crd_test_kit/suggestion_actions_validation.rb', line 37

def action_resource_field_validation(action, type)
  unless action['resource']
    add_message('error', "`Action.resource` must be present for `#{type}` actions: `#{action}`.")
    return
  end

  resource = FHIR.from_contents(action['resource'].to_json)
  return if resource

  add_message('error', "`Action.resource` must be a FHIR resource: `#{action}`.")
end

#action_resource_id_field_validation(action) ⇒ Object



49
50
51
52
53
54
55
56
# File 'lib/davinci_crd_test_kit/suggestion_actions_validation.rb', line 49

def action_resource_id_field_validation(action)
  validate_presence_and_type(action, 'resourceId', Array, '`delete` Action')
  return unless action['resourceId'].is_a?(Array)

  action['resourceId'].each do |ref|
    resource_reference_check(ref, 'Action.resourceId item')
  end
end

#action_resource_type_check(action, expected_resource_types) ⇒ Object



65
66
67
68
69
70
71
72
# File 'lib/davinci_crd_test_kit/suggestion_actions_validation.rb', line 65

def action_resource_type_check(action, expected_resource_types)
  resource_types = if ['create', 'update'].include?(action['type'])
                     [FHIR.from_contents(action['resource'].to_json).resourceType]
                   else
                     action['resourceId'].map { |ref| ref.split('/').first }
                   end
  resource_types.all? { |resource_type| expected_resource_types.include?(resource_type) }
end

#action_type_field_validation(action) ⇒ Object



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/davinci_crd_test_kit/suggestion_actions_validation.rb', line 18

def action_type_field_validation(action)
  return unless action['type']

  allowed_types = ['create', 'update', 'delete']
  type = action['type']
  unless allowed_types.include?(type)
    error_msg = "Action type value `#{type}` is not allowed. Allowed values: #{allowed_types.to_sentence}. " \
                "In Action `#{action}`"
    add_message('error', error_msg)
    return
  end

  if ['create', 'update'].include?(type)
    action_resource_field_validation(action, type)
  else
    action_resource_id_field_validation(action)
  end
end

#actions_check(actions, contexts = nil) ⇒ Object



80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/davinci_crd_test_kit/suggestion_actions_validation.rb', line 80

def actions_check(actions, contexts = nil)
  create_actions_resource_types = extract_resource_types_by_action(actions, 'create')

  actions.each do |action|
    case action['type']
    when 'create', 'update'
      create_or_update_action_check(action, contexts)
    when 'delete'
      delete_action_check(action, create_actions_resource_types, contexts)
    end
  end
end

#create_or_update_action_check(action, contexts) ⇒ Object



93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/davinci_crd_test_kit/suggestion_actions_validation.rb', line 93

def create_or_update_action_check(action, contexts)
  resource = FHIR.from_contents(action['resource'].to_json)
  resource_is_valid?(resource:, profile_url: structure_definition_map[resource.resourceType])
  return unless action['type'] == 'update' && contexts

  ref = "#{resource.resourceType}/#{resource.id}"
  return if draft_orders_bundle_entry_refs(contexts).include?(ref)

  error_msg = "Resource being updated must be from the `draftOrders` entry. #{ref} is not in the " \
              "`context.drafOrders` of the submitted requests. In Action `#{action}`"
  add_message('error', error_msg)
end

#delete_action_check(action, create_actions_resource_types, contexts) ⇒ Object



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/davinci_crd_test_kit/suggestion_actions_validation.rb', line 106

def delete_action_check(action, create_actions_resource_types, contexts)
  action['resourceId'].each do |ref|
    unless draft_orders_bundle_entry_refs(contexts).include?(ref)
      error_msg = '`Action.resourceId` must reference FHIR resource from the `draftOrders` entry. ' \
                  "#{ref} is not in `draftOrders`. In Action `#{action}`"
      add_message('error', error_msg)
      next
    end

    resource_type = ref.split('/').first
    next if create_actions_resource_types.include?(resource_type)

    error_msg = "There's no `create` action for the proposed order being deleted: `#{ref}`. In Action `#{action}`"
    add_message('error', error_msg)
  end
end

#draft_orders_bundle_entry_refs(contexts) ⇒ Object



58
59
60
61
62
63
# File 'lib/davinci_crd_test_kit/suggestion_actions_validation.rb', line 58

def draft_orders_bundle_entry_refs(contexts)
  @draft_orders_bundle_entry_refs ||= contexts.flat_map do |context|
    draft_orders_bundle = parse_fhir_bundle_from_context('draftOrders', context)
    draft_orders_bundle.entry.map { |entry| "#{entry.resource.resourceType}/#{entry.resource.id}" }
  end
end

#extract_resource_types_by_action(actions, action_type) ⇒ Object



74
75
76
77
78
# File 'lib/davinci_crd_test_kit/suggestion_actions_validation.rb', line 74

def extract_resource_types_by_action(actions, action_type)
  actions.each_with_object([]) do |act, resource_types|
    resource_types << act['resource']['resourceType'] if act['type'] == action_type
  end
end