Module: Operation

Included in:
TestScriptRunnable
Defined in:
lib/testscript_engine/operation.rb

Defined Under Namespace

Classes: OperationException

Constant Summary collapse

OPERATION_NEEDS_RESOURCE_TYPE =
%w[
  put
  patch
  delete
  read
  vread
  update
  create
].freeze
INTERACTION_NEEDS_PAYLOAD =
%w[
  patch
  post
  put
].freeze

Instance Method Summary collapse

Instance Method Details

#build_request(operation) ⇒ Object



41
42
43
44
45
46
47
48
# File 'lib/testscript_engine/operation.rb', line 41

def build_request(operation)
  path = get_path(operation)
  headers = get_headers(operation)
  interaction = get_interaction(operation)
  payload = get_payload(operation, interaction)

  [interaction, path, payload, headers].compact
end

#create_operation(source_id) ⇒ Object



147
148
149
150
151
152
# File 'lib/testscript_engine/operation.rb', line 147

def create_operation(source_id)
  FHIR::TestScript::Setup::Action::Operation.new({
                                                   sourceId: source_id,
                                                   method: 'post'
                                                 })
end

#delete_operation(source_id) ⇒ Object



154
155
156
157
158
159
# File 'lib/testscript_engine/operation.rb', line 154

def delete_operation(source_id)
  FHIR::TestScript::Setup::Action::Operation.new({
                                                   targetId: id_map[source_id],
                                                   method: 'delete'
                                                 })
end

#execute(operation) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/testscript_engine/operation.rb', line 28

def execute(operation)
  request = build_request(operation)

  begin
    client.send(*request)
  rescue
    raise OperationException, :bad_request
  end

  storage(operation)
  pass(:pass_execute_operation, operation.label || 'unlabeled')
end

#get_format(format) ⇒ Object



126
127
128
129
130
# File 'lib/testscript_engine/operation.rb', line 126

def get_format(format)
  return 'application/fhir+xml' if format == 'xml'

  'application/fhir+json'
end

#get_headers(operation) ⇒ Object



76
77
78
79
80
81
82
83
84
85
# File 'lib/testscript_engine/operation.rb', line 76

def get_headers(operation)
   headers = {
     'Content-Type' => get_format(operation.contentType),
     'Accept' => get_format(operation.accept)
   }

	operation.requestHeader.each_with_object(headers) do |header|
		headers[header.field] = header.value
	end
end

#get_id(operation, resource) ⇒ Object



110
111
112
113
114
# File 'lib/testscript_engine/operation.rb', line 110

def get_id(operation, resource)
  id = resource.id
  (raise OperationException, :noId) ['read', 'vread'].include?(operation.type&.code) if id.nil?
  "/#{id}"
end

#get_interaction(operation) ⇒ Object



87
88
89
90
# File 'lib/testscript_engine/operation.rb', line 87

def get_interaction(operation)
  interaction = operation.local_method || operation_to_interaction(operation.type&.code)
  interaction || (raise OperationException, :noInteraction)
end

#get_path(operation) ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/testscript_engine/operation.rb', line 50

def get_path(operation)
  return replace_variables(operation.url) if operation.url

  if operation.params
    # [type]/[params]
    "#{get_resource_type(operation)}#{replace_variables(operation.params)}"
  elsif operation.targetId
    resource = get_resource(operation.targetId)
    # TODO: Move this exception into the get_resource method in runnable/utilities
    # just need to make sure that raising this exception is always going to be acceptbale i.e. in any action ever,
    # if the resource isn't available, we should dip
    (raise OperationException, :noResource) unless resource
    path = resource.resourceType
    id = get_id(operation, resource)
    vid = get_vid(operation, resource)
    "#{path}#{id}" + (operation.type&.code == 'history' ? '/_history' : vid)
  elsif operation.sourceId
    resource = get_resource(operation.sourceId)
    raise OperationException, :noResource unless resource

    %w[batch transaction].include?(operation.type&.code) ? '' : resource.resourceType
  else
    raise OperationException, :no_path
  end
end

#get_payload(operation, interaction) ⇒ Object

Raises:



92
93
94
95
96
97
98
# File 'lib/testscript_engine/operation.rb', line 92

def get_payload(operation, interaction)
  return unless INTERACTION_NEEDS_PAYLOAD.include?(interaction)

  payload = get_resource(operation.sourceId)
  raise OperationException, :noPayload if INTERACTION_NEEDS_PAYLOAD.include?(interaction) && !payload
  payload
end

#get_resource_type(operation) ⇒ Object



100
101
102
103
104
105
106
107
108
# File 'lib/testscript_engine/operation.rb', line 100

def get_resource_type(operation)
  operation_type = operation.local_method || operation.type.code

  if OPERATION_NEEDS_RESOURCE_TYPE.include?(operation_type) && operation.resource.nil?
    raise OperationException, :noResourceType
  end

  operation.resource
end

#get_vid(operation, resource) ⇒ Object



116
117
118
119
120
121
122
123
124
# File 'lib/testscript_engine/operation.rb', line 116

def get_vid(operation, resource)
  vid = resource.meta&.versionId
  if operation.type&.code == 'vread'
    (raise OperationException, :noVid) unless vid
    "/_history/#{vid}"
  else
    ''
  end
end

#operation_to_interaction(interaction) ⇒ Object



132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/testscript_engine/operation.rb', line 132

def operation_to_interaction(interaction)
  case interaction
  when 'read', 'vread', 'search', 'search-type', 'search-system', 'capabilities', 'history', 'history-instance', 'history-type', 'history-system', 'operation'
    'get'
  when 'create', 'batch', 'transaction'
    'post'
  when 'update'
    'put'
  when 'patch'
    'patch'
  when 'delete'
    'delete'
  end
end