Class: RSpec::HTTPBin

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/rspec/httpbin.rb,
lib/rspec/httpbin/version.rb

Constant Summary collapse

VERSION =
"0.1.0"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(env) ⇒ HTTPBin

Returns a new instance of HTTPBin.



18
19
20
# File 'lib/rspec/httpbin.rb', line 18

def initialize(env)
  @req = Rack::Request.new(env)
end

Instance Attribute Details

#reqRack::Request (readonly)

Returns Rack request.

Returns:

  • (Rack::Request)

    Rack request



16
17
18
# File 'lib/rspec/httpbin.rb', line 16

def req
  @req
end

Class Method Details

.call(env) ⇒ Object



10
11
12
# File 'lib/rspec/httpbin.rb', line 10

def call(env)
  new(env).call
end

Instance Method Details

#bodyObject



60
61
62
63
64
65
66
# File 'lib/rspec/httpbin.rb', line 60

def body
  @body ||= [].tap do |out|
    req.body.rewind
    out << req.body.read
    req.body.rewind
  end.first || ""
end

#body_payloadObject



95
96
97
98
99
# File 'lib/rspec/httpbin.rb', line 95

def body_payload
  return {} if body.empty?

  {data:, files:, form:, json:}
end

#callObject



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/rspec/httpbin.rb', line 25

def call
  case path_info
  when "/get"
    get? ? ok_response : error_405
  when "/post"
    post? ? ok_response : error_405
  when "/delete"
    delete? ? ok_response : error_405
  when "/put"
    put? ? ok_response : error_405
  when "/patch"
    patch? ? ok_response : error_405
  when %r{^/status/[0-9]+$}
    status = path_info.split("/").last
    status_response status
  else
    error_404
  end
end

#dataObject



89
90
91
92
93
# File 'lib/rspec/httpbin.rb', line 89

def data
  return "" if form_data? || !files.nil?

  body
end

#error_404Object



112
113
114
# File 'lib/rspec/httpbin.rb', line 112

def error_404
  ["404", {"Content-Type" => "application/json"}, [JSON.generate({})]]
end

#error_405Object



116
117
118
# File 'lib/rspec/httpbin.rb', line 116

def error_405
  ["405", {"Content-Type" => "application/json"}, [JSON.generate({})]]
end

#filesObject



68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/rspec/httpbin.rb', line 68

def files
  return nil unless post? && Rack::Multipart::MULTIPART.match?(content_type)

  @files ||= [].tap do |out|
    multipart = Rack::Multipart.parse_multipart(env)
    out << multipart.to_h.map do |k, v|
      [k, v[:tempfile].read]
    end.to_h
  rescue
    # do nothing
  end.first
end

#formObject



81
82
83
# File 'lib/rspec/httpbin.rb', line 81

def form
  Rack::Utils.parse_nested_query(body) if form_data?
end

#headersObject



45
46
47
48
49
50
# File 'lib/rspec/httpbin.rb', line 45

def headers
  http_headers = env.select { |k, _v| k.start_with?("HTTP_") }
  http_headers.transform_keys do |k|
    k.sub(/^HTTP_/, "").downcase.gsub(/(^|_)\w/, &:upcase).tr("_", "-")
  end
end

#jsonObject



85
86
87
# File 'lib/rspec/httpbin.rb', line 85

def json
  JSON.parse(body) if json?
end

#json?Boolean

Returns:

  • (Boolean)


52
53
54
# File 'lib/rspec/httpbin.rb', line 52

def json?
  content_type == "application/json"
end

#ok_responseObject



101
102
103
104
105
106
# File 'lib/rspec/httpbin.rb', line 101

def ok_response
  payload = body_payload.merge(args: query_string, headers:, origin:, url:)

  ["200", {"Content-Type" => "application/json"}, [JSON.generate(payload)]]
  ["200", {"Content-Type" => "text/plain"}, [JSON.generate(payload)]]
end

#originObject



56
57
58
# File 'lib/rspec/httpbin.rb', line 56

def origin
  env["REMOTE_ADDR"]
end

#status_response(status) ⇒ Object



108
109
110
# File 'lib/rspec/httpbin.rb', line 108

def status_response(status)
  [status, {"Content-Type" => "text/plain"}, [JSON.generate({})]]
end