webmock 3.14.0 → 3.25.0

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.
Files changed (144) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +213 -3
  3. data/README.md +66 -20
  4. data/lib/webmock/api.rb +2 -0
  5. data/lib/webmock/assertion_failure.rb +2 -0
  6. data/lib/webmock/callback_registry.rb +2 -0
  7. data/lib/webmock/config.rb +2 -0
  8. data/lib/webmock/cucumber.rb +2 -0
  9. data/lib/webmock/deprecation.rb +2 -0
  10. data/lib/webmock/errors.rb +2 -0
  11. data/lib/webmock/http_lib_adapters/async_http_client_adapter.rb +16 -4
  12. data/lib/webmock/http_lib_adapters/curb_adapter.rb +4 -2
  13. data/lib/webmock/http_lib_adapters/em_http_request_adapter.rb +17 -7
  14. data/lib/webmock/http_lib_adapters/excon_adapter.rb +2 -0
  15. data/lib/webmock/http_lib_adapters/http_lib_adapter.rb +2 -0
  16. data/lib/webmock/http_lib_adapters/http_lib_adapter_registry.rb +2 -0
  17. data/lib/webmock/http_lib_adapters/http_rb/client.rb +3 -3
  18. data/lib/webmock/http_lib_adapters/http_rb/request.rb +17 -5
  19. data/lib/webmock/http_lib_adapters/http_rb/response.rb +32 -9
  20. data/lib/webmock/http_lib_adapters/http_rb/streamer.rb +10 -2
  21. data/lib/webmock/http_lib_adapters/http_rb/webmock.rb +8 -2
  22. data/lib/webmock/http_lib_adapters/http_rb_adapter.rb +7 -5
  23. data/lib/webmock/http_lib_adapters/httpclient_adapter.rb +26 -25
  24. data/lib/webmock/http_lib_adapters/manticore_adapter.rb +2 -0
  25. data/lib/webmock/http_lib_adapters/net_http.rb +46 -121
  26. data/lib/webmock/http_lib_adapters/net_http_response.rb +2 -0
  27. data/lib/webmock/http_lib_adapters/patron_adapter.rb +3 -1
  28. data/lib/webmock/http_lib_adapters/typhoeus_hydra_adapter.rb +18 -2
  29. data/lib/webmock/matchers/any_arg_matcher.rb +2 -0
  30. data/lib/webmock/matchers/hash_argument_matcher.rb +2 -0
  31. data/lib/webmock/matchers/hash_excluding_matcher.rb +2 -0
  32. data/lib/webmock/matchers/hash_including_matcher.rb +2 -0
  33. data/lib/webmock/minitest.rb +2 -0
  34. data/lib/webmock/rack_response.rb +5 -1
  35. data/lib/webmock/request_body_diff.rb +2 -0
  36. data/lib/webmock/request_execution_verifier.rb +2 -0
  37. data/lib/webmock/request_pattern.rb +35 -12
  38. data/lib/webmock/request_registry.rb +2 -0
  39. data/lib/webmock/request_signature.rb +4 -2
  40. data/lib/webmock/request_signature_snippet.rb +2 -0
  41. data/lib/webmock/request_stub.rb +34 -0
  42. data/lib/webmock/response.rb +15 -13
  43. data/lib/webmock/responses_sequence.rb +2 -0
  44. data/lib/webmock/rspec/matchers/request_pattern_matcher.rb +2 -0
  45. data/lib/webmock/rspec/matchers/webmock_matcher.rb +2 -0
  46. data/lib/webmock/rspec/matchers.rb +2 -0
  47. data/lib/webmock/rspec.rb +2 -0
  48. data/lib/webmock/stub_registry.rb +2 -0
  49. data/lib/webmock/stub_request_snippet.rb +2 -0
  50. data/lib/webmock/test_unit.rb +2 -0
  51. data/lib/webmock/util/hash_counter.rb +12 -6
  52. data/lib/webmock/util/hash_keys_stringifier.rb +2 -0
  53. data/lib/webmock/util/hash_validator.rb +2 -0
  54. data/lib/webmock/util/headers.rb +23 -10
  55. data/lib/webmock/util/parsers/json.rb +72 -0
  56. data/lib/webmock/util/parsers/parse_error.rb +7 -0
  57. data/lib/webmock/util/parsers/xml.rb +16 -0
  58. data/lib/webmock/util/query_mapper.rb +2 -0
  59. data/lib/webmock/util/uri.rb +3 -1
  60. data/lib/webmock/util/values_stringifier.rb +2 -0
  61. data/lib/webmock/util/version_checker.rb +7 -5
  62. data/lib/webmock/version.rb +3 -1
  63. data/lib/webmock/webmock.rb +12 -0
  64. data/lib/webmock.rb +4 -2
  65. metadata +66 -185
  66. data/.gemtest +0 -0
  67. data/.github/workflows/CI.yml +0 -37
  68. data/.gitignore +0 -34
  69. data/.rspec-tm +0 -2
  70. data/Gemfile +0 -9
  71. data/Rakefile +0 -38
  72. data/lib/webmock/util/json.rb +0 -67
  73. data/minitest/test_helper.rb +0 -34
  74. data/minitest/test_webmock.rb +0 -9
  75. data/minitest/webmock_spec.rb +0 -60
  76. data/spec/acceptance/async_http_client/async_http_client_spec.rb +0 -375
  77. data/spec/acceptance/async_http_client/async_http_client_spec_helper.rb +0 -73
  78. data/spec/acceptance/curb/curb_spec.rb +0 -499
  79. data/spec/acceptance/curb/curb_spec_helper.rb +0 -147
  80. data/spec/acceptance/em_http_request/em_http_request_spec.rb +0 -462
  81. data/spec/acceptance/em_http_request/em_http_request_spec_helper.rb +0 -77
  82. data/spec/acceptance/excon/excon_spec.rb +0 -77
  83. data/spec/acceptance/excon/excon_spec_helper.rb +0 -52
  84. data/spec/acceptance/http_rb/http_rb_spec.rb +0 -93
  85. data/spec/acceptance/http_rb/http_rb_spec_helper.rb +0 -54
  86. data/spec/acceptance/httpclient/httpclient_spec.rb +0 -217
  87. data/spec/acceptance/httpclient/httpclient_spec_helper.rb +0 -57
  88. data/spec/acceptance/manticore/manticore_spec.rb +0 -107
  89. data/spec/acceptance/manticore/manticore_spec_helper.rb +0 -35
  90. data/spec/acceptance/net_http/net_http_shared.rb +0 -153
  91. data/spec/acceptance/net_http/net_http_spec.rb +0 -369
  92. data/spec/acceptance/net_http/net_http_spec_helper.rb +0 -64
  93. data/spec/acceptance/net_http/real_net_http_spec.rb +0 -20
  94. data/spec/acceptance/patron/patron_spec.rb +0 -125
  95. data/spec/acceptance/patron/patron_spec_helper.rb +0 -54
  96. data/spec/acceptance/shared/allowing_and_disabling_net_connect.rb +0 -313
  97. data/spec/acceptance/shared/callbacks.rb +0 -148
  98. data/spec/acceptance/shared/complex_cross_concern_behaviors.rb +0 -36
  99. data/spec/acceptance/shared/enabling_and_disabling_webmock.rb +0 -95
  100. data/spec/acceptance/shared/precedence_of_stubs.rb +0 -15
  101. data/spec/acceptance/shared/request_expectations.rb +0 -930
  102. data/spec/acceptance/shared/returning_declared_responses.rb +0 -409
  103. data/spec/acceptance/shared/stubbing_requests.rb +0 -678
  104. data/spec/acceptance/typhoeus/typhoeus_hydra_spec.rb +0 -135
  105. data/spec/acceptance/typhoeus/typhoeus_hydra_spec_helper.rb +0 -60
  106. data/spec/acceptance/webmock_shared.rb +0 -41
  107. data/spec/fixtures/test.txt +0 -1
  108. data/spec/quality_spec.rb +0 -84
  109. data/spec/spec_helper.rb +0 -48
  110. data/spec/support/example_curl_output.txt +0 -22
  111. data/spec/support/failures.rb +0 -9
  112. data/spec/support/my_rack_app.rb +0 -53
  113. data/spec/support/network_connection.rb +0 -19
  114. data/spec/support/webmock_server.rb +0 -70
  115. data/spec/unit/api_spec.rb +0 -175
  116. data/spec/unit/errors_spec.rb +0 -129
  117. data/spec/unit/http_lib_adapters/http_lib_adapter_registry_spec.rb +0 -17
  118. data/spec/unit/http_lib_adapters/http_lib_adapter_spec.rb +0 -12
  119. data/spec/unit/matchers/hash_excluding_matcher_spec.rb +0 -61
  120. data/spec/unit/matchers/hash_including_matcher_spec.rb +0 -87
  121. data/spec/unit/rack_response_spec.rb +0 -112
  122. data/spec/unit/request_body_diff_spec.rb +0 -90
  123. data/spec/unit/request_execution_verifier_spec.rb +0 -208
  124. data/spec/unit/request_pattern_spec.rb +0 -736
  125. data/spec/unit/request_registry_spec.rb +0 -95
  126. data/spec/unit/request_signature_snippet_spec.rb +0 -89
  127. data/spec/unit/request_signature_spec.rb +0 -155
  128. data/spec/unit/request_stub_spec.rb +0 -199
  129. data/spec/unit/response_spec.rb +0 -286
  130. data/spec/unit/stub_registry_spec.rb +0 -103
  131. data/spec/unit/stub_request_snippet_spec.rb +0 -115
  132. data/spec/unit/util/hash_counter_spec.rb +0 -39
  133. data/spec/unit/util/hash_keys_stringifier_spec.rb +0 -27
  134. data/spec/unit/util/headers_spec.rb +0 -28
  135. data/spec/unit/util/json_spec.rb +0 -33
  136. data/spec/unit/util/query_mapper_spec.rb +0 -157
  137. data/spec/unit/util/uri_spec.rb +0 -371
  138. data/spec/unit/util/version_checker_spec.rb +0 -65
  139. data/spec/unit/webmock_spec.rb +0 -60
  140. data/test/http_request.rb +0 -24
  141. data/test/shared_test.rb +0 -108
  142. data/test/test_helper.rb +0 -23
  143. data/test/test_webmock.rb +0 -12
  144. data/webmock.gemspec +0 -54
@@ -1,60 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/test_helper')
2
-
3
- describe "Webmock" do
4
- include HttpRequestTestHelper
5
-
6
- before do
7
- @stub_http = stub_http_request(:any, "http://www.example.com")
8
- @stub_https = stub_http_request(:any, "https://www.example.com")
9
- end
10
-
11
- it "should update assertions count" do
12
- assert_equal 0, assertions
13
- http_request(:get, "http://www.example.com/")
14
-
15
- assert_requested(@stub_http)
16
- assert_equal 2, assertions
17
-
18
- assert_not_requested(:post, "http://www.example.com")
19
- assert_equal 4, assertions
20
- end
21
-
22
- it "should raise error on non stubbed request" do
23
- lambda { http_request(:get, "http://www.example.net/") }.must_raise(WebMock::NetConnectNotAllowedError)
24
- end
25
-
26
- it "should verify that expected request occured" do
27
- http_request(:get, "http://www.example.com/")
28
- assert_requested(:get, "http://www.example.com", times: 1)
29
- assert_requested(:get, "http://www.example.com")
30
- end
31
-
32
- it "should verify that expected http stub occured" do
33
- http_request(:get, "http://www.example.com/")
34
- assert_requested(@stub_http, times: 1)
35
- assert_requested(@stub_http)
36
- end
37
-
38
- it "should verify that expected https stub occured" do
39
- http_request(:get, "https://www.example.com/")
40
- http_request(:get, "https://www.example.com/")
41
- assert_requested(@stub_https, times: 2)
42
- end
43
-
44
- it "should verify that expect request didn't occur" do
45
- expected_message = "The request GET http://www.example.com/ was expected to execute 1 time but it executed 0 times"
46
- expected_message += "\n\nThe following requests were made:\n\nNo requests were made.\n============================================================"
47
- assert_fail(expected_message) do
48
- assert_requested(:get, "http://www.example.com")
49
- end
50
- end
51
-
52
- it "should verify that expect stub didn't occur" do
53
- expected_message = "The request ANY http://www.example.com/ was expected to execute 1 time but it executed 0 times"
54
- expected_message += "\n\nThe following requests were made:\n\nNo requests were made.\n============================================================"
55
- assert_fail(expected_message) do
56
- assert_requested(@stub_http)
57
- end
58
- end
59
- end
60
-
@@ -1,375 +0,0 @@
1
- # encoding: utf-8
2
- require 'spec_helper'
3
- require 'acceptance/webmock_shared'
4
- require_relative './async_http_client_spec_helper'
5
-
6
- require 'protocol/http/body/file'
7
-
8
- Async.logger.debug! if ENV['ASYNC_LOGGER_DEBUG']
9
-
10
- unless RUBY_PLATFORM =~ /java/
11
- describe 'Async::HTTP::Client' do
12
- include AsyncHttpClientSpecHelper
13
-
14
- include_context "with WebMock",
15
- :no_status_message,
16
- :no_url_auth,
17
- :no_content_length_header
18
-
19
- it 'works' do
20
- stub_request(:get, 'http://www.example.com')
21
- expect(make_request(:get, 'http://www.example.com')).to eq(
22
- status: 200,
23
- headers: {},
24
- body: nil
25
- )
26
- end
27
-
28
- it 'works with request path' do
29
- stub_request(:get, 'http://www.example.com/foo')
30
- expect(make_request(:get, 'http://www.example.com/foo')).to eq(
31
- status: 200,
32
- headers: {},
33
- body: nil
34
- )
35
- end
36
-
37
- it 'works with request query' do
38
- stub_request(:get, 'http://www.example.com/').with(
39
- query: {
40
- 'foo' => 'bar'
41
- }
42
- )
43
- expect(make_request(:get, 'http://www.example.com/?foo=bar')).to eq(
44
- status: 200,
45
- headers: {},
46
- body: nil
47
- )
48
- end
49
-
50
- it 'works with request headers' do
51
- stub_request(:get, 'http://www.example.com').with(
52
- headers: {
53
- 'X-Token' => 'Token'
54
- }
55
- )
56
- expect(
57
- make_request :get, 'http://www.example.com',
58
- headers: {
59
- 'X-Token' => 'Token'
60
- }
61
- ).to eq(
62
- status: 200,
63
- headers: {},
64
- body: nil
65
- )
66
- end
67
-
68
- it 'works with request body as text' do
69
- stub_request(:post, 'http://www.example.com').with(
70
- body: 'x'*10_000
71
- )
72
- expect(
73
- make_request :post, 'http://www.example.com',
74
- body: 'x'*10_000
75
- ).to eq(
76
- status: 200,
77
- headers: {},
78
- body: nil
79
- )
80
- end
81
-
82
- it 'works with request body as file' do
83
- stub_request(:post, "www.example.com").with(
84
- body: File.read(__FILE__)
85
- )
86
- expect(
87
- make_request :post, "http://www.example.com",
88
- body: ::Protocol::HTTP::Body::File.open(__FILE__, block_size: 32)
89
- ).to eq(
90
- status: 200,
91
- headers: {},
92
- body: nil
93
- )
94
- end
95
-
96
- it 'works with response status' do
97
- stub_request(:get, 'http://www.example.com').to_return(
98
- status: 400
99
- )
100
- expect(make_request(:get, 'http://www.example.com')).to eq(
101
- status: 400,
102
- headers: {},
103
- body: nil
104
- )
105
- end
106
-
107
- it 'works with response headers' do
108
- stub_request(:get, 'http://www.example.com').to_return(
109
- headers: {
110
- 'X-Token' => 'TOKEN'
111
- }
112
- )
113
- expect(make_request(:get, 'http://www.example.com')).to eq(
114
- status: 200,
115
- headers: {
116
- 'x-token' => ['TOKEN']
117
- },
118
- body: nil
119
- )
120
- end
121
-
122
- it 'works with response body' do
123
- stub_request(:get, 'http://www.example.com').to_return(
124
- body: 'abc'
125
- )
126
- expect(make_request(:get, 'http://www.example.com')).to eq(
127
- status: 200,
128
- headers: {},
129
- body: 'abc'
130
- )
131
- end
132
-
133
- it 'works with to_timeout' do
134
- stub_request(:get, 'http://www.example.com').to_timeout
135
- expect { make_request(:get, 'http://www.example.com') }.to raise_error Async::TimeoutError
136
- end
137
-
138
- it 'does not invoke "after real request" callbacks for stubbed requests' do
139
- WebMock.allow_net_connect!
140
- stub_request(:get, 'http://www.example.com').to_return(body: 'abc')
141
-
142
- callback_invoked = false
143
- WebMock.after_request(real_requests_only: true) { |_| callback_invoked = true }
144
-
145
- make_request(:get, 'http://www.example.com')
146
- expect(callback_invoked).to eq(false)
147
- end
148
-
149
- it 'does invoke "after request" callbacks for stubbed requests' do
150
- WebMock.allow_net_connect!
151
- stub_request(:get, 'http://www.example.com').to_return(body: 'abc')
152
-
153
- callback_invoked = false
154
- WebMock.after_request(real_requests_only: false) { |_| callback_invoked = true }
155
-
156
- make_request(:get, 'http://www.example.com')
157
- expect(callback_invoked).to eq(true)
158
- end
159
-
160
- context 'scheme and protocol' do
161
- let(:default_response_headers) { {} }
162
-
163
- before do
164
- stub_request(
165
- :get, "#{scheme}://www.example.com"
166
- ).and_return(
167
- body: 'BODY'
168
- )
169
- end
170
-
171
- subject do
172
- make_request(:get, "#{scheme}://www.example.com", protocol: protocol)
173
- end
174
-
175
- shared_examples :common do
176
- specify do
177
- expect(subject).to eq(
178
- status: 200,
179
- headers: default_response_headers,
180
- body: 'BODY'
181
- )
182
- end
183
- end
184
-
185
- context 'http scheme' do
186
- let(:scheme) { 'http' }
187
-
188
- context 'default protocol' do
189
- let(:protocol) { nil }
190
-
191
- include_examples :common
192
- end
193
-
194
- context 'HTTP10 protocol' do
195
- let(:protocol) { Async::HTTP::Protocol::HTTP10 }
196
- let(:default_response_headers) { {"connection"=>["keep-alive"]} }
197
-
198
- include_examples :common
199
- end
200
-
201
- context 'HTTP11 protocol' do
202
- let(:protocol) { Async::HTTP::Protocol::HTTP11 }
203
-
204
- include_examples :common
205
- end
206
-
207
- context 'HTTP2 protocol' do
208
- let(:protocol) { Async::HTTP::Protocol::HTTP2 }
209
-
210
- include_examples :common
211
- end
212
- end
213
-
214
- context 'https scheme' do
215
- let(:scheme) { 'https' }
216
-
217
- context 'default protocol' do
218
- let(:protocol) { nil }
219
-
220
- include_examples :common
221
- end
222
-
223
- context 'HTTP10 protocol' do
224
- let(:protocol) { Async::HTTP::Protocol::HTTP10 }
225
- let(:default_response_headers) { {"connection"=>["keep-alive"]} }
226
-
227
- include_examples :common
228
- end
229
-
230
- context 'HTTP11 protocol' do
231
- let(:protocol) { Async::HTTP::Protocol::HTTP11 }
232
-
233
- include_examples :common
234
- end
235
-
236
- context 'HTTP2 protocol' do
237
- let(:protocol) { Async::HTTP::Protocol::HTTP2 }
238
-
239
- include_examples :common
240
- end
241
-
242
- context 'HTTPS protocol' do
243
- let(:protocol) { Async::HTTP::Protocol::HTTPS }
244
-
245
- include_examples :common
246
- end
247
- end
248
- end
249
-
250
- context 'multiple requests' do
251
- let(:endpoint) { Async::HTTP::Endpoint.parse('http://www.example.com') }
252
- let(:requests_count) { 3 }
253
-
254
- shared_examples :common do
255
- before do
256
- requests_count.times do |index|
257
- stub_request(
258
- :get, "http://www.example.com/foo#{index}"
259
- ).to_return(
260
- status: 200 + index,
261
- headers: {'X-Token' => "foo#{index}"},
262
- body: "FOO#{index}"
263
- )
264
- end
265
- end
266
-
267
- specify do
268
- expect(subject).to eq(
269
- 0 => {
270
- status: 200,
271
- headers: {'x-token' => ['foo0']},
272
- body: 'FOO0'
273
- },
274
- 1 => {
275
- status: 201,
276
- headers: {'x-token' => ['foo1']},
277
- body: 'FOO1'
278
- },
279
- 2 => {
280
- status: 202,
281
- headers: {'x-token' => ['foo2']},
282
- body: 'FOO2'
283
- }
284
- )
285
- end
286
- end
287
-
288
- context 'sequential' do
289
- subject do
290
- responses = {}
291
- Async do |task|
292
- Async::HTTP::Client.open(endpoint, protocol) do |client|
293
- requests_count.times do |index|
294
- response = client.get "/foo#{index}"
295
- responses[index] = response_to_hash(response)
296
- end
297
- end
298
- end
299
- responses
300
- end
301
-
302
- context 'HTTP1 protocol' do
303
- let(:protocol) { Async::HTTP::Protocol::HTTP1 }
304
-
305
- include_examples :common
306
- end
307
-
308
- context 'HTTP2 protocol' do
309
- let(:protocol) { Async::HTTP::Protocol::HTTP2 }
310
-
311
- include_examples :common
312
- end
313
- end
314
-
315
- context 'asynchronous' do
316
- subject do
317
- responses = {}
318
- Async do |task|
319
- Async::HTTP::Client.open(endpoint, protocol) do |client|
320
- tasks = requests_count.times.map do |index|
321
- task.async do
322
- response = client.get "/foo#{index}"
323
- responses[index] = response_to_hash(response)
324
- end
325
- end
326
-
327
- tasks.map(&:wait)
328
- end
329
- end
330
- responses
331
- end
332
-
333
- context 'HTTP1 protocol' do
334
- let(:protocol) { Async::HTTP::Protocol::HTTP1 }
335
-
336
- include_examples :common
337
- end
338
-
339
- context 'HTTP2 protocol' do
340
- let(:protocol) { Async::HTTP::Protocol::HTTP2 }
341
-
342
- include_examples :common
343
- end
344
- end
345
- end
346
-
347
- def make_request(method, url, protocol: nil, headers: {}, body: nil)
348
- Async do
349
- endpoint = Async::HTTP::Endpoint.parse(url)
350
-
351
- begin
352
- Async::HTTP::Client.open(endpoint, protocol || endpoint.protocol) do |client|
353
- response = client.send(
354
- method,
355
- endpoint.path,
356
- headers,
357
- body
358
- )
359
- response_to_hash(response)
360
- end
361
- rescue Async::TimeoutError => e
362
- e
363
- end
364
- end.wait
365
- end
366
-
367
- def response_to_hash(response)
368
- {
369
- status: response.status,
370
- headers: response.headers.to_h,
371
- body: response.read
372
- }
373
- end
374
- end
375
- end
@@ -1,73 +0,0 @@
1
- module AsyncHttpClientSpecHelper
2
- def http_request(method, url, options = {}, &block)
3
- endpoint = Async::HTTP::Endpoint.parse(url)
4
-
5
- path = endpoint.path
6
- path = path + "?" + options[:query] if options[:query]
7
-
8
- headers = (options[:headers] || {}).each_with_object([]) do |(k, v), o|
9
- Array(v).each do |v|
10
- o.push [k, v]
11
- end
12
- end
13
- headers.push(
14
- ['authorization', 'Basic ' + Base64.strict_encode64(options[:basic_auth].join(':'))]
15
- ) if options[:basic_auth]
16
-
17
- body = options[:body]
18
-
19
- Async do
20
- begin
21
- Async::HTTP::Client.open(endpoint) do |client|
22
- response = client.send(
23
- method,
24
- path,
25
- headers,
26
- body
27
- )
28
-
29
- OpenStruct.new(
30
- build_hash_response(response)
31
- )
32
- end
33
- rescue Exception => e
34
- e
35
- end
36
- end.wait
37
- end
38
-
39
- def client_timeout_exception_class
40
- Async::TimeoutError
41
- end
42
-
43
- def connection_refused_exception_class
44
- Errno::ECONNREFUSED
45
- end
46
-
47
- def http_library
48
- :async_http_client
49
- end
50
-
51
- private
52
-
53
- def build_hash_response(response)
54
- {
55
-
56
- status: response.status.to_s,
57
- message: Protocol::HTTP1::Reason::DESCRIPTIONS[response.status],
58
- headers: build_response_headers(response),
59
- body: response.read
60
- }
61
- end
62
-
63
- def build_response_headers(response)
64
- response.headers.each.each_with_object({}) do |(k, v), o|
65
- o[k] ||= []
66
- o[k] << v
67
- end.tap do |o|
68
- o.each do |k, v|
69
- o[k] = v.join(', ')
70
- end
71
- end
72
- end
73
- end