class Rack::OverridePath

Constants

DEFAULT_BODY
DEFAULT_DELAY
DEFAULT_HEADERS
DEFAULT_STATUS
OVERRIDE_ENDPOINT
OVERRIDE_KEYS

Public Class Methods

new(app) click to toggle source
# File lib/rack/override_path.rb, line 15
def initialize(app)
  @app = app
  @overridden_paths = []
end

Public Instance Methods

at_least_one_override_key?(payload) click to toggle source
# File lib/rack/override_path.rb, line 94
def at_least_one_override_key?(payload)
  !(payload.keys & OVERRIDE_KEYS).empty?
end
call(env) click to toggle source
# File lib/rack/override_path.rb, line 20
def call(env)
  req = request(env)
  if override_path?(req)
    override_path(req)
  elsif path_overridden?(req.path) && override_matches_method?(req)
    handle_override(req.path, env)
  elsif get_override?(req)
    get_override(req)
  elsif delete_overrides?(req)
    delete_overrides(req)
  else
    @app.call(env)
  end
end
delete_overrides(req) click to toggle source
# File lib/rack/override_path.rb, line 35
def delete_overrides(req)
  @overridden_paths.clear
  get_override(req)
end
delete_overrides?(req) click to toggle source
# File lib/rack/override_path.rb, line 40
def delete_overrides?(req)
  override_endpoint?(req) && req.delete?
end
get_override(_req) click to toggle source
# File lib/rack/override_path.rb, line 57
def get_override(_req)
  [200, { 'Content-Type' => 'application/json' }, [@overridden_paths.to_json]]
end
get_override?(req) click to toggle source
# File lib/rack/override_path.rb, line 53
def get_override?(req)
  override_endpoint?(req) && req.get?
end
handle_override(path, env) click to toggle source
# File lib/rack/override_path.rb, line 110
def handle_override(path, env)
  o = override(path)
  handle_override_delay(o['delay']) if o['delay']
  status, headers, body = @app.call(env) unless o['body']
  handle_override_response(o, status, headers, body)
end
handle_override_delay(delay) click to toggle source
# File lib/rack/override_path.rb, line 117
def handle_override_delay(delay)
  sleep delay
end
handle_override_response(override, status, headers, body) click to toggle source
# File lib/rack/override_path.rb, line 121
def handle_override_response(override, status, headers, body)
  response_status = override['status'] || status || DEFAULT_STATUS
  response_headers = override['headers'] || headers || DEFAULT_HEADERS
  response_body = override['body'] || body || DEFAULT_BODY
  [response_status, response_headers, prepare_response_body_for_rack(response_body)]
end
literal_path(path) click to toggle source
# File lib/rack/override_path.rb, line 72
def literal_path(path)
  "^#{path}$"
end
literal_path?(path) click to toggle source
# File lib/rack/override_path.rb, line 68
def literal_path?(path)
  path[0] == '/'
end
override(path) click to toggle source
# File lib/rack/override_path.rb, line 61
def override(path)
  @overridden_paths.find do |override|
    override_path = literal_path?(override['path']) ? literal_path(override['path']) : override['path']
    path.match(Regexp.new(override_path))
  end
end
override_endpoint?(req) click to toggle source
# File lib/rack/override_path.rb, line 49
def override_endpoint?(req)
  req.path == '/override/path'
end
override_matches_method?(req) click to toggle source
# File lib/rack/override_path.rb, line 44
def override_matches_method?(req)
  o = override(req.path)
  o['method'].nil? ? true : o['method'].downcase == req.request_method.downcase
end
override_path(req) click to toggle source
# File lib/rack/override_path.rb, line 80
def override_path(req)
  payload = request_body_json(req)
  if valid?(payload)
    @overridden_paths.prepend(payload)
    override_path_successful_response(payload)
  else
    override_path_failed_response_no_body
  end
end
override_path?(req) click to toggle source
# File lib/rack/override_path.rb, line 76
def override_path?(req)
  override_endpoint?(req) && req.post?
end
override_path_failed_response_no_body() click to toggle source
# File lib/rack/override_path.rb, line 102
def override_path_failed_response_no_body
  [400, { 'Content-Type' => 'application/json' }, [{ 'message' => 'No body provided' }.to_json]]
end
override_path_successful_response(payload) click to toggle source
# File lib/rack/override_path.rb, line 98
def override_path_successful_response(payload)
  [200, { 'Content-Type' => 'application/json' }, [payload.to_json]]
end
path_overridden?(path) click to toggle source
# File lib/rack/override_path.rb, line 106
def path_overridden?(path)
  override(path).nil? ? false : true
end
prepare_response_body_for_rack(response_body) click to toggle source
# File lib/rack/override_path.rb, line 128
def prepare_response_body_for_rack(response_body)
  response_body = response_body.is_a?(Hash) ? response_body.to_json : response_body
  response_body.is_a?(Array) ? response_body : [response_body]
end
request(env) click to toggle source
# File lib/rack/override_path.rb, line 133
def request(env)
  Rack::Request.new(env)
end
request_body(req) click to toggle source
# File lib/rack/override_path.rb, line 143
def request_body(req)
  req.body.rewind
  req.body.read
rescue StandardError => _e
  ''
end
request_body_json(req) click to toggle source
# File lib/rack/override_path.rb, line 137
def request_body_json(req)
  JSON.parse(request_body(req))
rescue StandardError => _e
  nil
end
valid?(payload) click to toggle source
# File lib/rack/override_path.rb, line 90
def valid?(payload)
  payload&.key?('path') && at_least_one_override_key?(payload)
end