Class: Inferno::DSL::SuiteEndpoint

Inherits:
Hanami::Action
  • Object
show all
Defined in:
lib/inferno/dsl/suite_endpoint.rb

Overview

A base class for creating endpoints to test client requests. This class is based on Hanami::Action, and may be used similarly to a normal Hanami endpoint.

Examples:

class AuthorizedEndpoint < Inferno::DSL::SuiteEndpoint
  # Identify the incoming request based on a bearer token
  def test_run_identifier
    request.headers['authorization']&.delete_prefix('Bearer ')
  end

  error_response_format :operation_outcome

  # Return a json FHIR Patient resource
  def make_response
    response.status = 200
    response.body = FHIR::Patient.new(id: 'abcdef').to_json
    response.format = :json
  end

  # Update the waiting test to pass when the incoming request is received.
  # This will resume the test run.
  def update_result
    results_repo.update(result.id, result: 'pass')
  end

  # Apply the 'authorized' tag to the incoming request so that it may be
  # used by later tests.
  def tags
    ['authorized']
  end
end

class AuthorizedRequestSuite < Inferno::TestSuite
  id :authorized_suite
  suite_endpoint :get, '/authorized_endpoint', AuthorizedEndpoint

  group do
    title 'Authorized Request Group'

    test do
      title 'Wait for authorized request'

      input :bearer_token

      run do
        wait(
          identifier: bearer_token,
          message: "Waiting to receive a request with bearer_token: #{bearer_token}" \
                   "at `#{Inferno::Application['base_url']}/custom/authorized_suite/authorized_endpoint`"
        )
      end
    end
  end
end

Constant Summary collapse

ERROR_RESPONSE_FORMATS =

The built-in options for error_response_format

[:text, :operation_outcome].freeze

Instance Attribute Summary collapse

Overrides These methods should be overridden by subclasses to define the behavior of the endpoint collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#req ⇒ Object (readonly)

Returns the value of attribute req.



65
66
67
# File 'lib/inferno/dsl/suite_endpoint.rb', line 65

def req
  @req
end

#res ⇒ Object (readonly)

Returns the value of attribute res.



65
66
67
# File 'lib/inferno/dsl/suite_endpoint.rb', line 65

def res
  @res
end

Class Method Details

.error_response_format(format) ⇒ void

This method returns an undefined value.

Select one of Inferno's standard response formats to be returned whenever Inferno has to render an error response of its own due to problems finding the target session or an unhandled exception. You can override #no_session_response to customize the response in the no-session case.

  • :text (default): a 500 response with a plain text message
  • :operation_outcome: a 500 response with a FHIR OperationOutcome serialized as application/fhir+json

Examples:

class MyEndpoint < Inferno::DSL::SuiteEndpoint
  error_response_format :operation_outcome
end

Parameters:

  • format (Symbol) —

    :text or :operation_outcome



88
89
90
91
92
93
94
95
96
# File 'lib/inferno/dsl/suite_endpoint.rb', line 88

def error_response_format(format)
  unless ERROR_RESPONSE_FORMATS.include?(format)
    raise ArgumentError,
          "Unknown error_response_format `#{format.inspect}`. " \
          "Must be one of #{ERROR_RESPONSE_FORMATS.join(', ')}."
  end

  @error_response_format_value = format
end

Instance Method Details

#logger ⇒ Logger

Returns Inferno's logger.

Returns:

  • (Logger) —

    Inferno's logger



294
295
296
# File 'lib/inferno/dsl/suite_endpoint.rb', line 294

def logger
  @logger ||= Application['logger']
end

#make_response ⇒ Void

Override this method to build the response.

Examples:

def make_response
  response.status = 200
  response.body = { abc: 123 }.to_json
  response.format = :json
end

Returns:

  • (Void)


150
151
152
# File 'lib/inferno/dsl/suite_endpoint.rb', line 150

def make_response
  nil
end

#name ⇒ String

Override this method to assign a name to the request

Returns:

  • (String)


165
166
167
# File 'lib/inferno/dsl/suite_endpoint.rb', line 165

def name
  result&.runnable&.incoming_request_name
end

#no_session_response ⇒ Void

Override this method to fully customize the response returned when no waiting test run/session can be found for the incoming request. Set response.status and response.body (and response.content_type, if needed) — Inferno halts the request with those values. By default, this renders one of Inferno's standard responses based on the format selected with error_response_format (a plain text 500 response if none was selected).

Examples:

def no_session_response
  response.status = 404
  response.format = :json
  response.body = { error: 'no matching session' }.to_json
end

Returns:

  • (Void)


206
207
208
# File 'lib/inferno/dsl/suite_endpoint.rb', line 206

def no_session_response
  error_response(no_session_message, code: 'not-found')
end

#persist_request? ⇒ Boolean

Override this method to specify whether this request should be persisted. Defaults to true.

Returns:

  • (Boolean)


186
187
188
# File 'lib/inferno/dsl/suite_endpoint.rb', line 186

def persist_request?
  true
end

#request ⇒ Hanami::Action::Request

The incoming request as a Hanami::Action::Request

Examples:

request.params               # Get url/query params
request.body.read            # Get body
request.headers['accept']    # Get Accept header

Returns:

  • (Hanami::Action::Request)


250
251
252
# File 'lib/inferno/dsl/suite_endpoint.rb', line 250

def request
  req
end

#requests_repo ⇒ Inferno::Repositories::Requests



218
219
220
# File 'lib/inferno/dsl/suite_endpoint.rb', line 218

def requests_repo
  @requests_repo ||= Inferno::Repositories::Requests.new
end

#response ⇒ Hanami::Action::Response

The response as a Hanami::Action::Response. Modify this to build the response to the incoming request.

Examples:

response.status = 200        # Set the status
response.body = 'Ok'         # Set the body
# Set headers
response.headers.merge!('X-Custom-Header' => 'CUSTOM_HEADER_VALUE')

Returns:

  • (Hanami::Action::Response)


264
265
266
# File 'lib/inferno/dsl/suite_endpoint.rb', line 264

def response
  res
end

#result ⇒ Inferno::Entities::Result

The result which is waiting for incoming requests for the current test run



282
283
284
# File 'lib/inferno/dsl/suite_endpoint.rb', line 282

def result
  @result ||= find_result
end

#results_repo ⇒ Inferno::Repositories::Results



223
224
225
# File 'lib/inferno/dsl/suite_endpoint.rb', line 223

def results_repo
  @results_repo ||= Inferno::Repositories::Results.new
end

#tags ⇒ Array<String>

Override this method to define the tags which will be applied to the request.

Returns:

  • (Array<String>)


158
159
160
# File 'lib/inferno/dsl/suite_endpoint.rb', line 158

def tags
  @tags ||= []
end

#test ⇒ Inferno::Entities::Test

The test which is currently waiting for incoming requests



289
290
291
# File 'lib/inferno/dsl/suite_endpoint.rb', line 289

def test
  @test ||= tests_repo.find(result.test_id)
end

#test_run ⇒ Inferno::Entities::TestRun

The test run which is waiting for incoming requests



271
272
273
274
275
276
# File 'lib/inferno/dsl/suite_endpoint.rb', line 271

def test_run
  @test_run ||=
    test_runs_repo.find_latest_waiting_by_identifier(find_test_run_identifier).tap do |test_run|
      render_error_and_halt { no_session_response } if test_run.nil?
    end
end

#test_run_identifier ⇒ String

Override this method to determine a test run's identifier based on an incoming request.

Examples:

def test_run_identifier
  # Identify the test session of an incoming request based on the bearer
  # token
  request.headers['authorization']&.delete_prefix('Bearer ')
end

Returns:

  • (String)


120
121
122
# File 'lib/inferno/dsl/suite_endpoint.rb', line 120

def test_run_identifier
  nil
end

#test_run_identifier_location_description ⇒ String

Override this method to provide a short narrative description of where the test run identifier is expected to be found in an incoming request. When provided, this description is appended to the #no_session_message to help implementers debug requests that don't match a waiting test run.

Examples:

def test_run_identifier_location_description
  "the 'code' query parameter"
end

Returns:

  • (String)


136
137
138
# File 'lib/inferno/dsl/suite_endpoint.rb', line 136

def test_run_identifier_location_description
  ''
end

#test_runs_repo ⇒ Inferno::Repositories::TestRuns



228
229
230
# File 'lib/inferno/dsl/suite_endpoint.rb', line 228

def test_runs_repo
  @test_runs_repo ||= Inferno::Repositories::TestRuns.new
end

#tests_repo ⇒ Inferno::Repositories::Tests



233
234
235
# File 'lib/inferno/dsl/suite_endpoint.rb', line 233

def tests_repo
  @tests_repo ||= Inferno::Repositories::Tests.new
end

#update_result ⇒ Void

Override this method to update the current waiting result. To resume the test run, set the result to something other than 'waiting'.

Examples:

def update_result
  results_repo.update(result.id, result: 'pass')
end

Returns:

  • (Void)


178
179
180
# File 'lib/inferno/dsl/suite_endpoint.rb', line 178

def update_result
  nil
end