rest-client 2.0.2-x64-mingw32 → 2.1.0.rc1-x64-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -51,7 +51,8 @@ module RestClient
51
51
  Request.execute(options.merge(
52
52
  :method => :get,
53
53
  :url => url,
54
- :headers => headers), &(block || @block))
54
+ :headers => headers,
55
+ :log => log), &(block || @block))
55
56
  end
56
57
 
57
58
  def head(additional_headers={}, &block)
@@ -59,7 +60,8 @@ module RestClient
59
60
  Request.execute(options.merge(
60
61
  :method => :head,
61
62
  :url => url,
62
- :headers => headers), &(block || @block))
63
+ :headers => headers,
64
+ :log => log), &(block || @block))
63
65
  end
64
66
 
65
67
  def post(payload, additional_headers={}, &block)
@@ -68,7 +70,8 @@ module RestClient
68
70
  :method => :post,
69
71
  :url => url,
70
72
  :payload => payload,
71
- :headers => headers), &(block || @block))
73
+ :headers => headers,
74
+ :log => log), &(block || @block))
72
75
  end
73
76
 
74
77
  def put(payload, additional_headers={}, &block)
@@ -77,7 +80,8 @@ module RestClient
77
80
  :method => :put,
78
81
  :url => url,
79
82
  :payload => payload,
80
- :headers => headers), &(block || @block))
83
+ :headers => headers,
84
+ :log => log), &(block || @block))
81
85
  end
82
86
 
83
87
  def patch(payload, additional_headers={}, &block)
@@ -86,7 +90,8 @@ module RestClient
86
90
  :method => :patch,
87
91
  :url => url,
88
92
  :payload => payload,
89
- :headers => headers), &(block || @block))
93
+ :headers => headers,
94
+ :log => log), &(block || @block))
90
95
  end
91
96
 
92
97
  def delete(additional_headers={}, &block)
@@ -94,7 +99,8 @@ module RestClient
94
99
  Request.execute(options.merge(
95
100
  :method => :delete,
96
101
  :url => url,
97
- :headers => headers), &(block || @block))
102
+ :headers => headers,
103
+ :log => log), &(block || @block))
98
104
  end
99
105
 
100
106
  def to_s
@@ -121,6 +127,10 @@ module RestClient
121
127
  options[:open_timeout]
122
128
  end
123
129
 
130
+ def log
131
+ options[:log] || RestClient.log
132
+ end
133
+
124
134
  # Construct a subresource, preserving authentication.
125
135
  #
126
136
  # Example:
@@ -38,15 +38,25 @@ module RestClient
38
38
  "<RestClient::Response #{code.inspect} #{body_truncated(10).inspect}>"
39
39
  end
40
40
 
41
- def self.create(body, net_http_res, request)
41
+ # Initialize a Response object. Because RestClient::Response is
42
+ # (unfortunately) a subclass of String for historical reasons,
43
+ # Response.create is the preferred initializer.
44
+ #
45
+ # @param [String, nil] body The response body from the Net::HTTPResponse
46
+ # @param [Net::HTTPResponse] net_http_res
47
+ # @param [RestClient::Request] request
48
+ # @param [Time] start_time
49
+ def self.create(body, net_http_res, request, start_time=nil)
42
50
  result = self.new(body || '')
43
51
 
44
- result.response_set_vars(net_http_res, request)
52
+ result.response_set_vars(net_http_res, request, start_time)
45
53
  fix_encoding(result)
46
54
 
47
55
  result
48
56
  end
49
57
 
58
+ # Set the String encoding according to the 'Content-Type: charset' header,
59
+ # if possible.
50
60
  def self.fix_encoding(response)
51
61
  charset = RestClient::Utils.get_encoding_from_headers(response.headers)
52
62
  encoding = nil
@@ -54,8 +64,8 @@ module RestClient
54
64
  begin
55
65
  encoding = Encoding.find(charset) if charset
56
66
  rescue ArgumentError
57
- if RestClient.log
58
- RestClient.log << "No such encoding: #{charset.inspect}"
67
+ if response.log
68
+ response.log << "No such encoding: #{charset.inspect}"
59
69
  end
60
70
  end
61
71
 
@@ -1,3 +1,5 @@
1
+ require 'http/accept'
2
+
1
3
  module RestClient
2
4
  # Various utility methods
3
5
  module Utils
@@ -13,8 +15,8 @@ module RestClient
13
15
  #
14
16
  # @param headers [Hash<Symbol,String>]
15
17
  #
16
- # @return [String, nil] encoding Return the string encoding or nil if no
17
- # header is found.
18
+ # @return [String, nil] Return the string encoding or nil if no header is
19
+ # found.
18
20
  #
19
21
  # @example
20
22
  # >> get_encoding_from_headers({:content_type => 'text/plain; charset=UTF-8'})
@@ -24,19 +26,52 @@ module RestClient
24
26
  type_header = headers[:content_type]
25
27
  return nil unless type_header
26
28
 
27
- _content_type, params = cgi_parse_header(type_header)
29
+ # TODO: remove this hack once we drop support for Ruby 2.0
30
+ if RUBY_VERSION.start_with?('2.0')
31
+ _content_type, params = deprecated_cgi_parse_header(type_header)
32
+
33
+ if params.include?('charset')
34
+ return params.fetch('charset').gsub(/(\A["']*)|(["']*\z)/, '')
35
+ end
36
+
37
+ else
28
38
 
29
- if params.include?('charset')
30
- return params.fetch('charset').gsub(/(\A["']*)|(["']*\z)/, '')
39
+ begin
40
+ _content_type, params = cgi_parse_header(type_header)
41
+ rescue HTTP::Accept::ParseError
42
+ return nil
43
+ else
44
+ params['charset']
45
+ end
31
46
  end
47
+ end
32
48
 
33
- nil
49
+ # Parse a Content-Type like header.
50
+ #
51
+ # Return the main content-type and a hash of params.
52
+ #
53
+ # @param [String] line
54
+ # @return [Array(String, Hash)]
55
+ #
56
+ def self.cgi_parse_header(line)
57
+ types = HTTP::Accept::MediaTypes.parse(line)
58
+
59
+ if types.empty?
60
+ raise HTTP::Accept::ParseError.new("Found no types in header line")
61
+ end
62
+
63
+ [types.first.mime_type, types.first.parameters]
34
64
  end
35
65
 
36
66
  # Parse semi-colon separated, potentially quoted header string iteratively.
37
67
  #
38
68
  # @private
39
69
  #
70
+ # @deprecated This method is deprecated and only exists to support Ruby
71
+ # 2.0, which is not supported by HTTP::Accept.
72
+ #
73
+ # @todo remove this method when dropping support for Ruby 2.0
74
+ #
40
75
  def self._cgi_parseparam(s)
41
76
  return enum_for(__method__, s) unless block_given?
42
77
 
@@ -66,11 +101,15 @@ module RestClient
66
101
  # probably doesn't read or perform particularly well in ruby.
67
102
  # https://github.com/python/cpython/blob/3.4/Lib/cgi.py#L301-L331
68
103
  #
69
- #
70
104
  # @param [String] line
71
105
  # @return [Array(String, Hash)]
72
106
  #
73
- def self.cgi_parse_header(line)
107
+ # @deprecated This method is deprecated and only exists to support Ruby
108
+ # 2.0, which is not supported by HTTP::Accept.
109
+ #
110
+ # @todo remove this method when dropping support for Ruby 2.0
111
+ #
112
+ def self.deprecated_cgi_parse_header(line)
74
113
  parts = _cgi_parseparam(';' + line)
75
114
  key = parts.next
76
115
  pdict = {}
@@ -1,6 +1,6 @@
1
1
  module RestClient
2
- VERSION_INFO = [2, 0, 2] unless defined?(self::VERSION_INFO)
3
- VERSION = VERSION_INFO.map(&:to_s).join('.') unless defined?(self::VERSION)
2
+ VERSION_INFO = [2, 1, 0, 'rc1'].freeze
3
+ VERSION = VERSION_INFO.map(&:to_s).join('.').freeze
4
4
 
5
5
  def self.version
6
6
  VERSION
@@ -23,6 +23,7 @@ Gem::Specification.new do |s|
23
23
  s.add_development_dependency('rdoc', '>= 2.4.2', '< 6.0')
24
24
  s.add_development_dependency('rubocop', '~> 0')
25
25
 
26
+ s.add_dependency('http-accept', '>= 1.7.0', '< 2.0')
26
27
  s.add_dependency('http-cookie', '>= 1.0.2', '< 2.0')
27
28
  s.add_dependency('mime-types', '>= 1.16', '< 4.0')
28
29
  s.add_dependency('netrc', '~> 0.8')
Binary file
@@ -1,10 +1,36 @@
1
1
  require 'uri'
2
2
 
3
3
  module Helpers
4
- def response_double(opts={})
5
- double('response', {:to_hash => {}}.merge(opts))
4
+
5
+ # @param [Hash] opts A hash of methods, passed directly to the double
6
+ # definition. Use this to stub other required methods.
7
+ #
8
+ # @return double for Net::HTTPResponse
9
+ def res_double(opts={})
10
+ instance_double('Net::HTTPResponse', {to_hash: {}, body: 'response body'}.merge(opts))
11
+ end
12
+
13
+ # Given a Net::HTTPResponse or double and a Request or double, create a
14
+ # RestClient::Response object.
15
+ #
16
+ # @param net_http_res_double an rspec double for Net::HTTPResponse
17
+ # @param request A RestClient::Request or rspec double
18
+ #
19
+ # @return [RestClient::Response]
20
+ #
21
+ def response_from_res_double(net_http_res_double, request=nil, duration: 1)
22
+ request ||= request_double()
23
+ start_time = Time.now - duration
24
+
25
+ response = RestClient::Response.create(net_http_res_double.body, net_http_res_double, request, start_time)
26
+
27
+ # mock duration to ensure it gets the value we expect
28
+ allow(response).to receive(:duration).and_return(duration)
29
+
30
+ response
6
31
  end
7
32
 
33
+ # Redirect stderr to a string for the duration of the passed block.
8
34
  def fake_stderr
9
35
  original_stderr = $stderr
10
36
  $stderr = StringIO.new
@@ -14,9 +40,15 @@ module Helpers
14
40
  $stderr = original_stderr
15
41
  end
16
42
 
43
+ # Create a double for RestClient::Request
17
44
  def request_double(url: 'http://example.com', method: 'get')
18
- double('request', url: url, uri: URI.parse(url), method: method,
19
- user: nil, password: nil, cookie_jar: HTTP::CookieJar.new,
20
- redirection_history: nil, args: {url: url, method: method})
45
+ instance_double('RestClient::Request',
46
+ url: url, uri: URI.parse(url), method: method, user: nil, password: nil,
47
+ cookie_jar: HTTP::CookieJar.new, redirection_history: nil,
48
+ args: {url: url, method: method})
49
+ end
50
+
51
+ def test_image_path
52
+ File.dirname(__FILE__) + "/ISS.jpg"
21
53
  end
22
54
  end
@@ -1,6 +1,8 @@
1
1
  require_relative '_lib'
2
2
  require 'json'
3
3
 
4
+ require 'zlib'
5
+
4
6
  describe RestClient::Request do
5
7
  before(:all) do
6
8
  WebMock.disable!
@@ -83,5 +85,44 @@ describe RestClient::Request do
83
85
  expect(ex.http_code).to eq 401
84
86
  }
85
87
  end
88
+
89
+ it 'handles gzipped/deflated responses' do
90
+ [['gzip', 'gzipped'], ['deflate', 'deflated']].each do |encoding, var|
91
+ raw = execute_httpbin(encoding, method: :get)
92
+
93
+ begin
94
+ data = JSON.parse(raw)
95
+ rescue
96
+ puts "Failed to parse: " + raw.inspect
97
+ raise
98
+ end
99
+
100
+ expect(data['method']).to eq 'GET'
101
+ expect(data.fetch(var)).to be true
102
+ end
103
+ end
104
+
105
+ it 'does not uncompress response when accept-encoding is set' do
106
+ # == gzip ==
107
+ raw = execute_httpbin('gzip', method: :get, headers: {accept_encoding: 'gzip, deflate'})
108
+
109
+ # check for gzip magic number
110
+ expect(raw.body).to start_with("\x1F\x8B".b)
111
+
112
+ decoded = Zlib::GzipReader.new(StringIO.new(raw.body)).read
113
+ parsed = JSON.parse(decoded)
114
+
115
+ expect(parsed['method']).to eq 'GET'
116
+ expect(parsed.fetch('gzipped')).to be true
117
+
118
+ # == delate ==
119
+ raw = execute_httpbin('deflate', method: :get, headers: {accept_encoding: 'gzip, deflate'})
120
+
121
+ decoded = Zlib::Inflate.new.inflate(raw.body)
122
+ parsed = JSON.parse(decoded)
123
+
124
+ expect(parsed['method']).to eq 'GET'
125
+ expect(parsed.fetch('deflated')).to be true
126
+ end
86
127
  end
87
128
  end
@@ -12,13 +12,6 @@ describe RestClient do
12
12
  expect(response.body).to eq body
13
13
  end
14
14
 
15
- it "a simple request with gzipped content" do
16
- stub_request(:get, "www.example.com").with(:headers => { 'Accept-Encoding' => 'gzip, deflate' }).to_return(:body => "\037\213\b\b\006'\252H\000\003t\000\313T\317UH\257\312,HM\341\002\000G\242(\r\v\000\000\000", :status => 200, :headers => { 'Content-Encoding' => 'gzip' } )
17
- response = RestClient.get "www.example.com"
18
- expect(response.code).to eq 200
19
- expect(response.body).to eq "i'm gziped\n"
20
- end
21
-
22
15
  it "a 404" do
23
16
  body = "Ho hai ! I'm not here !"
24
17
  stub_request(:get, "www.example.com").to_return(:body => body, :status => 404)
@@ -2,21 +2,21 @@ require_relative '_lib'
2
2
 
3
3
  describe RestClient::AbstractResponse, :include_helpers do
4
4
 
5
+ # Sample class implementing AbstractResponse used for testing.
5
6
  class MyAbstractResponse
6
7
 
7
8
  include RestClient::AbstractResponse
8
9
 
9
10
  attr_accessor :size
10
11
 
11
- def initialize net_http_res, request
12
- @net_http_res = net_http_res
13
- @request = request
12
+ def initialize(net_http_res, request)
13
+ response_set_vars(net_http_res, request, Time.now - 1)
14
14
  end
15
15
 
16
16
  end
17
17
 
18
18
  before do
19
- @net_http_res = double('net http response')
19
+ @net_http_res = res_double()
20
20
  @request = request_double(url: 'http://example.com', method: 'get')
21
21
  @response = MyAbstractResponse.new(@net_http_res, @request)
22
22
  end
@@ -92,8 +92,8 @@ describe RestClient::AbstractResponse, :include_helpers do
92
92
  it 'handles cookies when URI scheme is implicit' do
93
93
  net_http_res = double('net http response')
94
94
  expect(net_http_res).to receive(:to_hash).and_return('set-cookie' => ['session_id=1; path=/'])
95
- request = double(url: 'example.com', uri: URI.parse('http://example.com'),
96
- method: 'get', cookie_jar: HTTP::CookieJar.new)
95
+ request = double('request', url: 'example.com', uri: URI.parse('http://example.com'),
96
+ method: 'get', cookie_jar: HTTP::CookieJar.new, redirection_history: nil)
97
97
  response = MyAbstractResponse.new(net_http_res, request)
98
98
  expect(response.cookie_jar).to be_a HTTP::CookieJar
99
99
 
@@ -135,7 +135,7 @@ describe RestClient::AbstractResponse, :include_helpers do
135
135
  end
136
136
 
137
137
  it "should gracefully handle 302 redirect with no location header" do
138
- @net_http_res = response_double(code: 302, location: nil)
138
+ @net_http_res = res_double(code: 302)
139
139
  @request = request_double()
140
140
  @response = MyAbstractResponse.new(@net_http_res, @request)
141
141
  expect(@response).to receive(:check_max_redirects).and_return('fake-check')
@@ -2,7 +2,7 @@
2
2
 
3
3
  require_relative '_lib'
4
4
 
5
- describe RestClient::Payload do
5
+ describe RestClient::Payload, :include_helpers do
6
6
  context "Base Payload" do
7
7
  it "should reset stream after to_s" do
8
8
  payload = RestClient::Payload::Base.new('foobar')
@@ -80,7 +80,7 @@ describe RestClient::Payload do
80
80
  end
81
81
 
82
82
  it 'should not error on close if stream already closed' do
83
- m = RestClient::Payload::Multipart.new(:file => File.new(File.join(File.dirname(File.expand_path(__FILE__)), 'master_shake.jpg')))
83
+ m = RestClient::Payload::Multipart.new(:file => File.new(test_image_path))
84
84
  3.times {m.close}
85
85
  end
86
86
 
@@ -111,11 +111,11 @@ baz\r
111
111
  end
112
112
 
113
113
  it "should form properly separated multipart data" do
114
- f = File.new(File.dirname(__FILE__) + "/master_shake.jpg")
114
+ f = File.new(test_image_path)
115
115
  m = RestClient::Payload::Multipart.new({:foo => f})
116
116
  expect(m.to_s).to eq <<-EOS
117
117
  --#{m.boundary}\r
118
- Content-Disposition: form-data; name="foo"; filename="master_shake.jpg"\r
118
+ Content-Disposition: form-data; name="foo"; filename="ISS.jpg"\r
119
119
  Content-Type: image/jpeg\r
120
120
  \r
121
121
  #{File.open(f.path, 'rb'){|bin| bin.read}}\r
@@ -124,11 +124,11 @@ Content-Type: image/jpeg\r
124
124
  end
125
125
 
126
126
  it "should ignore the name attribute when it's not set" do
127
- f = File.new(File.dirname(__FILE__) + "/master_shake.jpg")
127
+ f = File.new(test_image_path)
128
128
  m = RestClient::Payload::Multipart.new({nil => f})
129
129
  expect(m.to_s).to eq <<-EOS
130
130
  --#{m.boundary}\r
131
- Content-Disposition: form-data; filename="master_shake.jpg"\r
131
+ Content-Disposition: form-data; filename="ISS.jpg"\r
132
132
  Content-Type: image/jpeg\r
133
133
  \r
134
134
  #{File.open(f.path, 'rb'){|bin| bin.read}}\r
@@ -137,9 +137,9 @@ Content-Type: image/jpeg\r
137
137
  end
138
138
 
139
139
  it "should detect optional (original) content type and filename" do
140
- f = File.new(File.dirname(__FILE__) + "/master_shake.jpg")
141
- f.instance_eval "def content_type; 'text/plain'; end"
142
- f.instance_eval "def original_filename; 'foo.txt'; end"
140
+ f = File.new(test_image_path)
141
+ expect(f).to receive(:content_type).and_return('text/plain')
142
+ expect(f).to receive(:original_filename).and_return('foo.txt')
143
143
  m = RestClient::Payload::Multipart.new({:foo => f})
144
144
  expect(m.to_s).to eq <<-EOS
145
145
  --#{m.boundary}\r
@@ -161,7 +161,7 @@ foo\r
161
161
  --#{m.boundary}--\r
162
162
  EOS
163
163
 
164
- f = File.new(File.dirname(__FILE__) + "/master_shake.jpg")
164
+ f = File.new(test_image_path)
165
165
  f.instance_eval "def content_type; 'text/plain'; end"
166
166
  f.instance_eval "def original_filename; 'foo.txt'; end"
167
167
  m = RestClient::Payload::Multipart.new({:foo => {:bar => f}})
@@ -177,7 +177,7 @@ Content-Type: text/plain\r
177
177
 
178
178
  it 'should correctly format hex boundary' do
179
179
  allow(SecureRandom).to receive(:base64).with(12).and_return('TGs89+ttw/xna6TV')
180
- f = File.new(File.dirname(__FILE__) + '/master_shake.jpg')
180
+ f = File.new(test_image_path)
181
181
  m = RestClient::Payload::Multipart.new({:foo => f})
182
182
  expect(m.boundary).to eq('-' * 4 + 'RubyFormBoundary' + 'TGs89AttwBxna6TV')
183
183
  end
@@ -186,10 +186,10 @@ Content-Type: text/plain\r
186
186
 
187
187
  context "streamed payloads" do
188
188
  it "should properly determine the size of file payloads" do
189
- f = File.new(File.dirname(__FILE__) + "/master_shake.jpg")
189
+ f = File.new(test_image_path)
190
190
  payload = RestClient::Payload.generate(f)
191
- expect(payload.size).to eq 76_988
192
- expect(payload.length).to eq 76_988
191
+ expect(payload.size).to eq 72_463
192
+ expect(payload.length).to eq 72_463
193
193
  end
194
194
 
195
195
  it "should properly determine the size of other kinds of streaming payloads" do
@@ -209,6 +209,14 @@ Content-Type: text/plain\r
209
209
  f.close
210
210
  end
211
211
  end
212
+
213
+ it "should have a closed? method" do
214
+ f = File.new(test_image_path)
215
+ payload = RestClient::Payload.generate(f)
216
+ expect(payload.closed?).to be_falsey
217
+ payload.close
218
+ expect(payload.closed?).to be_truthy
219
+ end
212
220
  end
213
221
 
214
222
  context "Payload generation" do
@@ -217,7 +225,7 @@ Content-Type: text/plain\r
217
225
  end
218
226
 
219
227
  it "should recognize multipart params" do
220
- f = File.new(File.dirname(__FILE__) + "/master_shake.jpg")
228
+ f = File.new(test_image_path)
221
229
  expect(RestClient::Payload.generate({"foo" => f})).to be_kind_of(RestClient::Payload::Multipart)
222
230
  end
223
231
 
@@ -226,7 +234,7 @@ Content-Type: text/plain\r
226
234
  end
227
235
 
228
236
  it "should handle deeply nested multipart" do
229
- f = File.new(File.dirname(__FILE__) + "/master_shake.jpg")
237
+ f = File.new(test_image_path)
230
238
  params = {foo: RestClient::ParamsArray.new({nested: f})}
231
239
  expect(RestClient::Payload.generate(params)).to be_kind_of(RestClient::Payload::Multipart)
232
240
  end
@@ -237,17 +245,17 @@ Content-Type: text/plain\r
237
245
  end
238
246
 
239
247
  it "should recognize nested multipart payloads in hashes" do
240
- f = File.new(File.dirname(__FILE__) + "/master_shake.jpg")
248
+ f = File.new(test_image_path)
241
249
  expect(RestClient::Payload.generate({"foo" => {"file" => f}})).to be_kind_of(RestClient::Payload::Multipart)
242
250
  end
243
251
 
244
252
  it "should recognize nested multipart payloads in arrays" do
245
- f = File.new(File.dirname(__FILE__) + "/master_shake.jpg")
253
+ f = File.new(test_image_path)
246
254
  expect(RestClient::Payload.generate({"foo" => [f]})).to be_kind_of(RestClient::Payload::Multipart)
247
255
  end
248
256
 
249
257
  it "should recognize file payloads that can be streamed" do
250
- f = File.new(File.dirname(__FILE__) + "/master_shake.jpg")
258
+ f = File.new(test_image_path)
251
259
  expect(RestClient::Payload.generate(f)).to be_kind_of(RestClient::Payload::Streamed)
252
260
  end
253
261
 
@@ -259,5 +267,29 @@ Content-Type: text/plain\r
259
267
  it "shouldn't treat hashes as streameable" do
260
268
  expect(RestClient::Payload.generate({"foo" => 'bar'})).to be_kind_of(RestClient::Payload::UrlEncoded)
261
269
  end
270
+
271
+ it "should recognize multipart payload wrapped in ParamsArray" do
272
+ f = File.new(test_image_path)
273
+ params = RestClient::ParamsArray.new([[:image, f]])
274
+ expect(RestClient::Payload.generate(params)).to be_kind_of(RestClient::Payload::Multipart)
275
+ end
276
+
277
+ it "should handle non-multipart payload wrapped in ParamsArray" do
278
+ params = RestClient::ParamsArray.new([[:arg, 'value1'], [:arg, 'value2']])
279
+ expect(RestClient::Payload.generate(params)).to be_kind_of(RestClient::Payload::UrlEncoded)
280
+ end
281
+
282
+ it "should pass through Payload::Base and subclasses unchanged" do
283
+ payloads = [
284
+ RestClient::Payload::Base.new('foobar'),
285
+ RestClient::Payload::UrlEncoded.new({:foo => 'bar'}),
286
+ RestClient::Payload::Streamed.new(File.new(test_image_path)),
287
+ RestClient::Payload::Multipart.new({myfile: File.new(test_image_path)}),
288
+ ]
289
+
290
+ payloads.each do |payload|
291
+ expect(RestClient::Payload.generate(payload)).to equal(payload)
292
+ end
293
+ end
262
294
  end
263
295
  end