Class: Inferno::DSL::SuiteEndpoint
- Inherits:
-
Hanami::Action
- Object
- Hanami::Action
- Inferno::DSL::SuiteEndpoint
- 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](github.com/hanami/controller/tree/v2.0.0).
class AuthorizedEndpoint < Inferno::DSL::SuiteEndpoint
# Identify the incoming request based on a bearer token
def test_run_identifier
request.header['authorization']&.delete_prefix('Bearer ')
end
# 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
['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
Instance Attribute Summary collapse
-
#req ⇒ Object
readonly
Returns the value of attribute req.
-
#res ⇒ Object
readonly
Returns the value of attribute res.
Overrides These methods should be overridden by subclasses to define the behavior of the endpoint collapse
-
#make_response ⇒ Void
Override this method to build the response.
-
#name ⇒ String
Override this method to assign a name to the request.
-
#persist_request? ⇒ Boolean
Override this method to specify whether this request should be persisted.
-
#tags ⇒ Array<String>
Override this method to define the tags which will be applied to the request.
-
#test_run_identifier ⇒ String
Override this method to determine a test run’s identifier based on an incoming request.
-
#update_result ⇒ Void
Override this method to update the current waiting result.
Class Method Summary collapse
Instance Method Summary collapse
- #add_persistence_callback ⇒ Object
- #find_result ⇒ Object
- #find_test_run_identifier ⇒ Object
- #handle(req, res) ⇒ Object
-
#initialize(config: self.class.config) ⇒ SuiteEndpoint
constructor
A new instance of SuiteEndpoint.
-
#logger ⇒ Logger
Inferno’s logger.
-
#persist_request ⇒ Object
The actual persisting happens in Inferno::Utils::Middleware::RequestRecorder, which allows the response to include response headers added by other parts of the rack stack rather than only the response headers explicitly added in the endpoint.
-
#request ⇒ Hanami::Action::Request
The incoming request as a ‘Hanami::Action::Request`.
- #requests_repo ⇒ Inferno::Repositories::Requests
-
#response ⇒ Hanami::Action::Response
The response as a ‘Hanami::Action::Response`.
-
#result ⇒ Inferno::Entities::Result
The result which is waiting for incoming requests for the current test run.
- #results_repo ⇒ Inferno::Repositories::Results
-
#resume ⇒ Object
Inferno::Utils::Middleware::RequestRecorder actually resumes the TestRun.
- #resume_test_run? ⇒ Boolean
-
#test ⇒ Inferno::Entities::Test
The test which is currently waiting for incoming requests.
-
#test_run ⇒ Inferno::Entities::TestRun
The test run which is waiting for incoming requests.
- #test_runs_repo ⇒ Inferno::Repositories::TestRuns
- #tests_repo ⇒ Inferno::Repositories::Tests
Constructor Details
#initialize(config: self.class.config) ⇒ SuiteEndpoint
Returns a new instance of SuiteEndpoint.
159 160 161 |
# File 'lib/inferno/dsl/suite_endpoint.rb', line 159 def initialize(config: self.class.config) # rubocop:disable Lint/MissingSuper @config = config end |
Instance Attribute Details
#req ⇒ Object (readonly)
Returns the value of attribute req.
61 62 63 |
# File 'lib/inferno/dsl/suite_endpoint.rb', line 61 def req @req end |
#res ⇒ Object (readonly)
Returns the value of attribute res.
61 62 63 |
# File 'lib/inferno/dsl/suite_endpoint.rb', line 61 def res @res end |
Class Method Details
.call ⇒ Object
134 135 136 |
# File 'lib/inferno/dsl/suite_endpoint.rb', line 134 def self.call(...) new.call(...) end |
Instance Method Details
#add_persistence_callback ⇒ Object
277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 |
# File 'lib/inferno/dsl/suite_endpoint.rb', line 277 def add_persistence_callback # rubocop:disable Metrics/CyclomaticComplexity logger = Application['logger'] env = req.env env['rack.after_reply'] ||= [] env['rack.after_reply'] << proc do repo = Inferno::Repositories::Requests.new uri = URI('http://example.com') uri.scheme = env['rack.url_scheme'] uri.host = env['SERVER_NAME'] uri.port = env['SERVER_PORT'] uri.path = env['REQUEST_PATH'] || '' uri.query = env['rack.request.query_string'] if env['rack.request.query_string'].present? url = uri&.to_s verb = env['REQUEST_METHOD'] request_body = env['rack.input'] request_body.rewind if env['rack.input'].respond_to? :rewind request_body = request_body.instance_of?(Puma::NullIO) ? nil : request_body.string request_headers = ::Rack::Request.new(env).headers.to_h.map { |name, value| { name:, value: } } status, response_headers, response_body = env['inferno.response'] response_headers = response_headers.map { |name, value| { name:, value: } } repo.create( verb:, url:, direction: 'incoming', name: env['inferno.name'], status:, request_body:, response_body: response_body.join, result_id: env['inferno.result_id'], test_session_id: env['inferno.test_session_id'], request_headers:, response_headers:, tags: env['inferno.tags'] ) if env['inferno.resume_test_run'] test_run_id = env['inferno.test_run_id'] Inferno::Repositories::TestRuns.new.mark_as_no_longer_waiting(test_run_id) Inferno::Jobs.perform(Jobs::ResumeTestRun, test_run_id) end rescue StandardError => e logger.error(e.) end end |
#find_result ⇒ Object
227 228 229 |
# File 'lib/inferno/dsl/suite_endpoint.rb', line 227 def find_result results_repo.find_waiting_result(test_run_id: test_run.id) end |
#find_test_run_identifier ⇒ Object
220 221 222 223 224 |
# File 'lib/inferno/dsl/suite_endpoint.rb', line 220 def find_test_run_identifier @test_run_identifier ||= test_run_identifier rescue StandardError => e halt 500, "Unable to determine test run identifier:\n#{e.}" end |
#handle(req, res) ⇒ Object
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 |
# File 'lib/inferno/dsl/suite_endpoint.rb', line 260 def handle(req, res) @req = req @res = res test_run persist_request if persist_request? update_result resume if resume_test_run? make_response rescue StandardError => e halt 500, e. end |
#logger ⇒ Logger
Returns Inferno’s logger.
215 216 217 |
# File 'lib/inferno/dsl/suite_endpoint.rb', line 215 def logger @logger ||= Application['logger'] end |
#make_response ⇒ Void
Override this method to build the response.
def make_response
response.status = 200
response.body = { abc: 123 }.to_json
response.format = :json
end
91 92 93 |
# File 'lib/inferno/dsl/suite_endpoint.rb', line 91 def make_response nil end |
#name ⇒ String
Override this method to assign a name to the request
106 107 108 |
# File 'lib/inferno/dsl/suite_endpoint.rb', line 106 def name result&.runnable&.incoming_request_name end |
#persist_request ⇒ Object
The actual persisting happens in Inferno::Utils::Middleware::RequestRecorder, which allows the response to include response headers added by other parts of the rack stack rather than only the response headers explicitly added in the endpoint.
236 237 238 239 240 241 242 243 |
# File 'lib/inferno/dsl/suite_endpoint.rb', line 236 def persist_request req.env['inferno.test_session_id'] = test_run.test_session_id req.env['inferno.result_id'] = result.id req.env['inferno.tags'] = req.env['inferno.name'] = name if name.present? add_persistence_callback end |
#persist_request? ⇒ Boolean
Override this method to specify whether this request should be persisted. Defaults to true.
127 128 129 |
# File 'lib/inferno/dsl/suite_endpoint.rb', line 127 def persist_request? true end |
#request ⇒ Hanami::Action::Request
The incoming request as a ‘Hanami::Action::Request`
request.params # Get url/query params request.body.read # Get body request.headers # Get Accept header
171 172 173 |
# File 'lib/inferno/dsl/suite_endpoint.rb', line 171 def request req end |
#requests_repo ⇒ Inferno::Repositories::Requests
139 140 141 |
# File 'lib/inferno/dsl/suite_endpoint.rb', line 139 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.
response.status = 200 # Set the status response.body = ‘Ok’ # Set the body # Set headers response.headers.merge!(‘X-Custom-Header’ => ‘CUSTOM_HEADER_VALUE’)
185 186 187 |
# File 'lib/inferno/dsl/suite_endpoint.rb', line 185 def response res end |
#result ⇒ Inferno::Entities::Result
The result which is waiting for incoming requests for the current test run
203 204 205 |
# File 'lib/inferno/dsl/suite_endpoint.rb', line 203 def result @result ||= find_result end |
#results_repo ⇒ Inferno::Repositories::Results
144 145 146 |
# File 'lib/inferno/dsl/suite_endpoint.rb', line 144 def results_repo @results_repo ||= Inferno::Repositories::Results.new end |
#resume ⇒ Object
Inferno::Utils::Middleware::RequestRecorder actually resumes the TestRun. If it were resumed here, it would be resuming prior to the Request being persisted.
254 255 256 257 |
# File 'lib/inferno/dsl/suite_endpoint.rb', line 254 def resume req.env['inferno.resume_test_run'] = true req.env['inferno.test_run_id'] = test_run.id end |
#resume_test_run? ⇒ Boolean
246 247 248 |
# File 'lib/inferno/dsl/suite_endpoint.rb', line 246 def resume_test_run? find_result&.result != 'wait' end |
#tags ⇒ Array<String>
Override this method to define the tags which will be applied to the request.
99 100 101 |
# File 'lib/inferno/dsl/suite_endpoint.rb', line 99 def @tags ||= [] end |
#test ⇒ Inferno::Entities::Test
The test which is currently waiting for incoming requests
210 211 212 |
# File 'lib/inferno/dsl/suite_endpoint.rb', line 210 def test @test ||= tests_repo.find(result.test_id) end |
#test_run ⇒ Inferno::Entities::TestRun
The test run which is waiting for incoming requests
192 193 194 195 196 197 |
# File 'lib/inferno/dsl/suite_endpoint.rb', line 192 def test_run @test_run ||= test_runs_repo.find_latest_waiting_by_identifier(find_test_run_identifier).tap do |test_run| halt 500, "Unable to find test run with identifier '#{test_run_identifier}'." 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.
def test_run_identifier
# Identify the test session of an incoming request based on the bearer
# token
request.headers['authorization']&.delete_prefix('Bearer ')
end
77 78 79 |
# File 'lib/inferno/dsl/suite_endpoint.rb', line 77 def test_run_identifier nil end |
#test_runs_repo ⇒ Inferno::Repositories::TestRuns
149 150 151 |
# File 'lib/inferno/dsl/suite_endpoint.rb', line 149 def test_runs_repo @test_runs_repo ||= Inferno::Repositories::TestRuns.new end |
#tests_repo ⇒ Inferno::Repositories::Tests
154 155 156 |
# File 'lib/inferno/dsl/suite_endpoint.rb', line 154 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’.
def update_result
results_repo.update(result.id, result: 'pass')
end
119 120 121 |
# File 'lib/inferno/dsl/suite_endpoint.rb', line 119 def update_result nil end |