puffing-billy 2.3.1 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +17 -0
  3. data/README.md +18 -5
  4. data/lib/billy/browsers/capybara.rb +13 -9
  5. data/lib/billy/browsers/watir.rb +4 -2
  6. data/lib/billy/config.rb +2 -1
  7. data/lib/billy/handlers/proxy_handler.rb +4 -0
  8. data/lib/billy/proxy.rb +1 -1
  9. data/lib/billy/ssl/certificate_helpers.rb +1 -1
  10. data/lib/billy/version.rb +1 -1
  11. metadata +29 -80
  12. data/.gitignore +0 -6
  13. data/.rspec +0 -2
  14. data/.travis.yml +0 -36
  15. data/Dockerfile +0 -14
  16. data/Gemfile +0 -4
  17. data/Guardfile +0 -23
  18. data/Rakefile +0 -11
  19. data/bin/proxy.rb +0 -3
  20. data/examples/README.md +0 -1
  21. data/examples/facebook_api.html +0 -59
  22. data/examples/intercept_request.html +0 -10
  23. data/examples/post_api.html +0 -16
  24. data/examples/preflight_request.html +0 -22
  25. data/examples/tumblr_api.html +0 -22
  26. data/examples/tumblr_api_https.html +0 -22
  27. data/lib/tasks/billy.rake +0 -87
  28. data/log/.gitkeep +0 -0
  29. data/puffing-billy.gemspec +0 -39
  30. data/spec/features/examples/facebook_api_spec.rb +0 -23
  31. data/spec/features/examples/intercept_request_spec.rb +0 -31
  32. data/spec/features/examples/post_api_spec.rb +0 -15
  33. data/spec/features/examples/preflight_request_spec.rb +0 -29
  34. data/spec/features/examples/tumblr_api_spec.rb +0 -59
  35. data/spec/lib/billy/browsers/capybara_spec.rb +0 -28
  36. data/spec/lib/billy/cache_spec.rb +0 -158
  37. data/spec/lib/billy/handlers/cache_handler_spec.rb +0 -191
  38. data/spec/lib/billy/handlers/handler_spec.rb +0 -16
  39. data/spec/lib/billy/handlers/proxy_handler_spec.rb +0 -254
  40. data/spec/lib/billy/handlers/request_handler_spec.rb +0 -200
  41. data/spec/lib/billy/handlers/request_log_spec.rb +0 -74
  42. data/spec/lib/billy/handlers/stub_handler_spec.rb +0 -117
  43. data/spec/lib/billy/proxy_connection_spec.rb +0 -20
  44. data/spec/lib/billy/proxy_request_stub_spec.rb +0 -252
  45. data/spec/lib/billy/resource_utils_spec.rb +0 -55
  46. data/spec/lib/billy/ssl/authority_spec.rb +0 -84
  47. data/spec/lib/billy/ssl/certificate_chain_spec.rb +0 -39
  48. data/spec/lib/billy/ssl/certificate_spec.rb +0 -89
  49. data/spec/lib/billy/watir/watir_spec.rb +0 -18
  50. data/spec/lib/proxy_spec.rb +0 -431
  51. data/spec/spec_helper.rb +0 -52
  52. data/spec/support/test_server.rb +0 -79
@@ -1,191 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Billy::CacheHandler do
4
- let(:handler) { Billy::CacheHandler.new }
5
- let(:request_url) { 'http://example.test:8080/index?some=param&callback=dynamicCallback5678' }
6
- let(:request) do
7
- {
8
- method: 'post',
9
- url: request_url,
10
- headers: { 'Accept-Encoding' => 'gzip',
11
- 'Cache-Control' => 'no-cache' },
12
- body: 'Some body'
13
- }
14
- end
15
-
16
- it 'delegates #reset to the cache' do
17
- expect(Billy::Cache.instance).to receive(:reset).at_least(:once)
18
- handler.reset
19
- end
20
-
21
- it 'delegates #cached? to the cache' do
22
- expect(Billy::Cache.instance).to receive :cached?
23
- handler.cached?
24
- end
25
-
26
- describe '#handles_request?' do
27
- it 'handles the request if it is cached' do
28
- expect(Billy::Cache.instance).to receive(:cached?).and_return(true)
29
- expect(handler.handles_request?(nil, nil, nil, nil)).to be true
30
- end
31
-
32
- it 'does not handle the request if it is not cached' do
33
- expect(Billy::Cache.instance).to receive(:cached?).and_return(false)
34
- expect(handler.handles_request?(nil, nil, nil, nil)).to be false
35
- end
36
- end
37
-
38
- describe '#handle_request' do
39
- it 'returns nil if the request cannot be handled' do
40
- expect(Billy::Cache.instance).to receive(:cached?).and_return(false)
41
- expect(handler.handle_request(request[:method],
42
- request[:url],
43
- request[:headers],
44
- request[:body])).to be nil
45
- end
46
-
47
- it 'returns a cached response if the request can be handled' do
48
- expect(Billy::Cache.instance).to receive(:cached?).and_return(true)
49
- expect(Billy::Cache.instance).to receive(:fetch).and_return(status: 200, headers: { 'Connection' => 'close' }, content: 'The response body')
50
- expect(handler.handle_request(request[:method],
51
- request[:url],
52
- request[:headers],
53
- request[:body])).to eql(status: 200, headers: { 'Connection' => 'close' }, content: 'The response body')
54
- end
55
-
56
- context 'updating jsonp callback names enabled' do
57
- before do
58
- Billy.config.dynamic_jsonp = true
59
- end
60
-
61
- it 'updates the cached response if the callback is dynamic' do
62
- expect(Billy::Cache.instance).to receive(:cached?).and_return(true)
63
- expect(Billy::Cache.instance).to receive(:fetch).and_return(status: 200, headers: { 'Connection' => 'close' }, content: 'dynamicCallback1234({"yolo":"kitten"})')
64
- expect(handler.handle_request(request[:method],
65
- request[:url],
66
- request[:headers],
67
- request[:body])).to eql(status: 200, headers: { 'Connection' => 'close' }, content: 'dynamicCallback5678({"yolo":"kitten"})')
68
- end
69
-
70
- it 'is flexible about the format of the response body' do
71
- expect(Billy::Cache.instance).to receive(:cached?).and_return(true)
72
- expect(Billy::Cache.instance).to receive(:fetch).and_return(status: 200, headers: { 'Connection' => 'close' }, content: "/**/ dynamicCallback1234(\n{\"yolo\":\"kitten\"})")
73
- expect(handler.handle_request(request[:method],
74
- request[:url],
75
- request[:headers],
76
- request[:body])).to eql(status: 200, headers: { 'Connection' => 'close' }, content: "/**/ dynamicCallback5678(\n{\"yolo\":\"kitten\"})")
77
- end
78
-
79
- it 'does not interfere with non-jsonp requests' do
80
- jsonp_request = request
81
- other_request = {
82
- method: 'get',
83
- url: 'http://example.test:8080/index?hanukkah=latkes',
84
- headers: { 'Accept-Encoding' => 'gzip', 'Cache-Control' => 'no-cache' },
85
- body: 'no jsonp'
86
- }
87
-
88
- allow(Billy::Cache.instance).to receive(:cached?).and_return(true)
89
- allow(Billy::Cache.instance).to receive(:fetch).with(jsonp_request[:method], jsonp_request[:url], jsonp_request[:body]).and_return(status: 200,
90
- headers: { 'Connection' => 'close' },
91
- content: 'dynamicCallback1234({"yolo":"kitten"})')
92
- allow(Billy::Cache.instance).to receive(:fetch).with(other_request[:method], other_request[:url], other_request[:body]).and_return(status: 200,
93
- headers: { 'Connection' => 'close' },
94
- content: 'no jsonp but has parentheses()')
95
-
96
- expect(handler.handle_request(other_request[:method],
97
- other_request[:url],
98
- other_request[:headers],
99
- other_request[:body])).to eql(status: 200, headers: { 'Connection' => 'close' }, content: 'no jsonp but has parentheses()')
100
- end
101
-
102
- context 'when after_cache_handles_request is set' do
103
- it "should call the callback with the request and response" do
104
- allow(Billy.config).to receive(:after_cache_handles_request) do
105
- proc do |request, response|
106
- response[:headers]['Access-Control-Allow-Origin'] = "*"
107
- response[:content] = request[:body]
108
- end
109
- end
110
- expect(Billy::Cache.instance).to receive(:cached?).and_return(true)
111
- expect(Billy::Cache.instance).to receive(:fetch).and_return(status: 200, headers: { 'Connection' => 'close' }, content: 'The response body')
112
- expect(handler.handle_request(request[:method],
113
- request[:url],
114
- request[:headers],
115
- request[:body])).to eql(status: 200, headers: { 'Connection' => 'close', 'Access-Control-Allow-Origin' => "*" }, content: 'Some body')
116
- end
117
- end
118
-
119
- context 'when dynamic_jsonp_callback_name is set' do
120
- let(:dynamic_jsonp_callback_name) { 'customCallback' }
121
- let(:request_url) { "http://example.test:8080/index?some=param&#{dynamic_jsonp_callback_name}=dynamicCallback5678" }
122
-
123
- before do
124
- allow(Billy.config).to receive(:dynamic_jsonp_callback_name) do
125
- dynamic_jsonp_callback_name
126
- end
127
- end
128
-
129
- it 'should call the callback with the specified name' do
130
- expect(Billy::Cache.instance).to receive(:cached?).and_return(true)
131
- expect(Billy::Cache.instance).to receive(:fetch).and_return(status: 200, headers: { 'Connection' => 'close' }, content: 'dynamicCallback1234({"yolo":"kitten"})')
132
- expect(handler.handle_request(request[:method],
133
- request[:url],
134
- request[:headers],
135
- request[:body])).to eql(status: 200, headers: { 'Connection' => 'close' }, content: 'dynamicCallback5678({"yolo":"kitten"})')
136
- end
137
- end
138
- end
139
-
140
- context 'updating jsonp callback names disabled' do
141
- before do
142
- Billy.config.dynamic_jsonp = false
143
- end
144
-
145
- it 'does not change the response' do
146
- expect(Billy::Cache.instance).to receive(:cached?).and_return(true)
147
- expect(Billy::Cache.instance).to receive(:fetch).and_return(status: 200, headers: { 'Connection' => 'close' }, content: 'dynamicCallback1234({"yolo":"kitten"})')
148
- expect(handler.handle_request(request[:method],
149
- request[:url],
150
- request[:headers],
151
- request[:body])).to eql(status: 200, headers: { 'Connection' => 'close' }, content: 'dynamicCallback1234({"yolo":"kitten"})')
152
- end
153
- end
154
-
155
- it 'returns nil if the Cache fails to handle the response for some reason' do
156
- expect(Billy::Cache.instance).to receive(:cached?).and_return(true)
157
- expect(Billy::Cache.instance).to receive(:fetch).and_return(nil)
158
- expect(handler.handle_request(request[:method],
159
- request[:url],
160
- request[:headers],
161
- request[:body])).to be nil
162
- end
163
-
164
- context 'network delay simulation' do
165
- before do
166
- allow(Billy::Cache.instance).to receive(:cached?).and_return(true)
167
- allow(Billy::Cache.instance).to receive(:fetch).and_return(status: 200, headers: { 'Connection' => 'close' }, content: 'dynamicCallback1234({"yolo":"kitten"})')
168
- end
169
-
170
- context 'when cache_simulates_network_delays is disabled' do
171
- it 'does not sleep for default delay before responding' do
172
- expect(Kernel).not_to receive(:sleep)
173
- handler.handle_request(request[:method], request[:url], request[:headers], request[:body])
174
- end
175
- end
176
-
177
- context 'when cache_simulates_network_delays is enabled' do
178
- around do |example|
179
- Billy.config.cache_simulates_network_delays = true
180
- example.call
181
- Billy.config.cache_simulates_network_delays = false
182
- end
183
-
184
- it 'sleeps for default delay before responding' do
185
- expect(Kernel).to receive(:sleep).with(Billy.config.cache_simulates_network_delay_time)
186
- handler.handle_request(request[:method], request[:url], request[:headers], request[:body])
187
- end
188
- end
189
- end
190
- end
191
- end
@@ -1,16 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Billy::Handler do
4
- let(:handler) { Class.new { include Billy::Handler }.new }
5
- it '#handle_request raises an error if not overridden' do
6
- expect(handler.handle_request(nil, nil, nil, nil)).to eql(error: 'The handler has not overridden the handle_request method!')
7
- end
8
-
9
- it '#handles_request returns false by default' do
10
- expect(handler.handles_request?(nil, nil, nil, nil)).to be false
11
- end
12
-
13
- it 'responds to #reset' do
14
- expect(handler).to respond_to :reset
15
- end
16
- end
@@ -1,254 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Billy::ProxyHandler do
4
- subject { Billy::ProxyHandler.new }
5
- let(:request) do
6
- {
7
- method: 'post',
8
- url: 'http://usern:pw@example.test:8080/index?some=param',
9
- headers: { 'Accept-Encoding' => 'gzip',
10
- 'Cache-Control' => 'no-cache' },
11
- body: 'Some body'
12
- }
13
- end
14
-
15
- describe '#handles_request?' do
16
- context 'with non-whitelisted requests enabled' do
17
- before do
18
- expect(Billy.config).to receive(:non_whitelisted_requests_disabled).and_return(false)
19
- end
20
-
21
- it 'handles all requests' do
22
- expect(subject.handles_request?(request[:method],
23
- request[:url],
24
- request[:headers],
25
- request[:body])).to be true
26
- end
27
- end
28
- context 'with non-whitelisted requests disabled' do
29
- before do
30
- expect(Billy.config).to receive(:non_whitelisted_requests_disabled).and_return(true)
31
- end
32
-
33
- it 'does not handle requests that are not white or black listed' do
34
- expect(subject.handles_request?(request[:method],
35
- request[:url],
36
- request[:headers],
37
- request[:body])).to be false
38
- end
39
-
40
- context 'a whitelisted host' do
41
- context 'with a blacklisted path' do
42
- before do
43
- expect(Billy.config).to receive(:path_blacklist) { ['/index'] }
44
- end
45
-
46
- it 'does not handle requests for blacklisted paths' do
47
- expect(subject.handles_request?(request[:method],
48
- 'http://example.test:8080/index?some=param',
49
- request[:headers],
50
- request[:body])).to be false
51
- end
52
- end
53
-
54
- context 'as a regex' do
55
- before do
56
- expect(Billy.config).to receive(:whitelist) { [%r{example\.test\/a}] }
57
- end
58
-
59
- it 'handles requests for the host without a port' do
60
- expect(subject.handles_request?(request[:method],
61
- 'http://example.test/a',
62
- request[:headers],
63
- request[:body])).to be true
64
- end
65
-
66
- it 'handles requests for the host with a port' do
67
- expect(subject.handles_request?(request[:method],
68
- 'http://example.test:8080/a',
69
- request[:headers],
70
- request[:body])).to be true
71
- end
72
- end
73
-
74
- context 'without a port' do
75
- before do
76
- expect(Billy.config).to receive(:whitelist) { ['example.test'] }
77
- end
78
-
79
- it 'handles requests for the host without a port' do
80
- expect(subject.handles_request?(request[:method],
81
- 'http://example.test',
82
- request[:headers],
83
- request[:body])).to be true
84
- end
85
-
86
- it 'handles requests for the host with a port' do
87
- expect(subject.handles_request?(request[:method],
88
- 'http://example.test:8080',
89
- request[:headers],
90
- request[:body])).to be true
91
- end
92
- end
93
-
94
- context 'with a port' do
95
- before do
96
- expect(Billy.config).to receive(:whitelist) { ['example.test:8080'] }
97
- end
98
-
99
- it 'does not handle requests whitelisted for a specific port' do
100
- expect(subject.handles_request?(request[:method],
101
- 'http://example.test',
102
- request[:headers],
103
- request[:body])).to be false
104
- end
105
-
106
- it 'handles requests for the host with a port' do
107
- expect(subject.handles_request?(request[:method],
108
- 'http://example.test:8080',
109
- request[:headers],
110
- request[:body])).to be true
111
- end
112
- end
113
- end
114
- end
115
- end
116
-
117
- describe '#handle_request' do
118
- it 'returns nil if it does not handle the request' do
119
- expect(subject).to receive(:handles_request?).and_return(false)
120
- expect(subject.handle_request(request[:method],
121
- request[:url],
122
- request[:headers],
123
- request[:body])).to be nil
124
- end
125
-
126
- context 'with a handled request' do
127
- let(:response_header) do
128
- header = Struct.new(:status, :raw).new
129
- header.status = 200
130
- header.raw = {}
131
- header
132
- end
133
-
134
- let(:em_response) { double('response') }
135
- let(:em_request) do
136
- double('EM::HttpRequest', error: nil, response: em_response, response_header: response_header)
137
- end
138
-
139
- before do
140
- allow(subject).to receive(:handles_request?).and_return(true)
141
- allow(em_response).to receive(:force_encoding).and_return('The response body')
142
- allow(EventMachine::HttpRequest).to receive(:new).and_return(em_request)
143
- expect(em_request).to receive(:post).and_return(em_request)
144
- end
145
-
146
- it 'returns any error in the response' do
147
- allow(em_request).to receive(:error).and_return('ERROR!')
148
- expect(subject.handle_request(request[:method],
149
- request[:url],
150
- request[:headers],
151
- request[:body])).to eql(error: "Request to #{request[:url]} failed with error: ERROR!")
152
- end
153
-
154
- it 'returns a hashed response if the request succeeds' do
155
- expect(subject.handle_request(request[:method],
156
- request[:url],
157
- request[:headers],
158
- request[:body])).to eql(status: 200, headers: { 'Connection' => 'close' }, content: 'The response body')
159
- end
160
-
161
- it 'returns nil if both the error and response are for some reason nil' do
162
- allow(em_request).to receive(:response).and_return(nil)
163
- expect(subject.handle_request(request[:method],
164
- request[:url],
165
- request[:headers],
166
- request[:body])).to be nil
167
- end
168
-
169
- it 'caches the response if cacheable' do
170
- expect(subject).to receive(:allowed_response_code?).and_return(true)
171
- expect(Billy::Cache.instance).to receive(:store)
172
- subject.handle_request(request[:method],
173
- request[:url],
174
- request[:headers],
175
- request[:body])
176
- end
177
-
178
- it 'does NOT cache the response if the host is whitelisted but not cache_whitelisted' do
179
- uri = Addressable::URI.parse(request[:url])
180
-
181
- expect(subject).to receive(:allowed_response_code?).and_return(true)
182
- expect(Billy.config).to receive(:whitelist).and_return([uri.host])
183
- expect(Billy.config).to receive(:cache_whitelist).and_return([])
184
-
185
- expect(Billy::Cache.instance).not_to receive(:store)
186
- subject.handle_request(request[:method],
187
- request[:url],
188
- request[:headers],
189
- request[:body])
190
- end
191
-
192
- it 'caches the response if the host is whitelisted AND cache_whitelisted' do
193
- uri = Addressable::URI.parse(request[:url])
194
-
195
- expect(subject).to receive(:allowed_response_code?).and_return(true)
196
- expect(Billy.config).to receive(:whitelist).and_return([uri.host])
197
- expect(Billy.config).to receive(:cache_whitelist).and_return([uri.host])
198
-
199
- expect(Billy::Cache.instance).to receive(:store)
200
- subject.handle_request(request[:method],
201
- request[:url],
202
- request[:headers],
203
- request[:body])
204
- end
205
-
206
- it 'uses the timeouts defined in configuration' do
207
- allow(Billy.config).to receive(:proxied_request_inactivity_timeout).and_return(42)
208
- allow(Billy.config).to receive(:proxied_request_connect_timeout).and_return(24)
209
-
210
- expect(EventMachine::HttpRequest).to receive(:new).with(request[:url],
211
- inactivity_timeout: 42,
212
- connect_timeout: 24
213
- )
214
-
215
- subject.handle_request(request[:method],
216
- request[:url],
217
- request[:headers],
218
- request[:body])
219
- end
220
-
221
- it 'uses the internal proxy settings defined in configuration' do
222
- allow(Billy.config).to receive(:proxied_request_host).and_return('10.10.10.10')
223
- allow(Billy.config).to receive(:proxied_request_port).and_return('2080')
224
-
225
- expect(EventMachine::HttpRequest).to receive(:new).with(request[:url],
226
- inactivity_timeout: 10,
227
- connect_timeout: 5,
228
- proxy: { host: '10.10.10.10', port: '2080' }
229
- )
230
-
231
- subject.handle_request(request[:method],
232
- request[:url],
233
- request[:headers],
234
- request[:body])
235
- end
236
- end
237
- end
238
-
239
- describe '#build_request_options' do
240
- it 'creates authorization header when URL has basic auth' do
241
- request_options = subject.send(:build_request_options, request[:url],
242
- request[:headers],
243
- request[:body])
244
- expect(request_options[:head]).to have_key 'authorization'
245
- end
246
-
247
- it 'does not include authorization header without basic auth' do
248
- request_options = subject.send(:build_request_options, request[:url].gsub('usern:pw@',''),
249
- request[:headers],
250
- request[:body])
251
- expect(request_options[:head]).not_to have_key 'authorization'
252
- end
253
- end
254
- end
@@ -1,200 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Billy::RequestHandler do
4
- subject { Billy::RequestHandler.new }
5
-
6
- it 'implements Handler' do
7
- expect(subject).to be_a Billy::Handler
8
- end
9
-
10
- describe '#handlers' do
11
- it 'has a stub handler' do
12
- expect(subject.handlers[:stubs]).to be_a Billy::StubHandler
13
- end
14
-
15
- it 'has a cache handler' do
16
- expect(subject.handlers[:cache]).to be_a Billy::CacheHandler
17
- end
18
-
19
- it 'has a proxy handler' do
20
- expect(subject.handlers[:proxy]).to be_a Billy::ProxyHandler
21
- end
22
- end
23
-
24
- context 'with stubbed handlers' do
25
- let(:args) { %w(get url headers body) }
26
- let(:stub_handler) { double('StubHandler') }
27
- let(:cache_handler) { double('CacheHandler') }
28
- let(:proxy_handler) { double('ProxyHandler') }
29
- let(:handlers) do
30
- {
31
- stubs: stub_handler,
32
- cache: cache_handler,
33
- proxy: proxy_handler
34
- }
35
- end
36
-
37
- before do
38
- allow(subject).to receive(:handlers).and_return(handlers)
39
- end
40
-
41
- describe '#handles_request?' do
42
- it 'returns false if no handlers handle the request' do
43
- handlers.each do |_key, handler|
44
- expect(handler).to receive(:handles_request?).with(*args).and_return(false)
45
- end
46
- expect(subject.handles_request?(*args)).to be false
47
- end
48
-
49
- it 'returns true immediately if the stub handler handles the request' do
50
- expect(stub_handler).to receive(:handles_request?).with(*args).and_return(true)
51
- expect(cache_handler).to_not receive(:handles_request?)
52
- expect(proxy_handler).to_not receive(:handles_request?)
53
- expect(subject.handles_request?(*args)).to be true
54
- end
55
-
56
- it 'returns true if the cache handler handles the request' do
57
- expect(stub_handler).to receive(:handles_request?).with(*args).and_return(false)
58
- expect(cache_handler).to receive(:handles_request?).with(*args).and_return(true)
59
- expect(proxy_handler).to_not receive(:handles_request?)
60
- expect(subject.handles_request?(*args)).to be true
61
- end
62
-
63
- it 'returns true if the proxy handler handles the request' do
64
- expect(stub_handler).to receive(:handles_request?).with(*args).and_return(false)
65
- expect(cache_handler).to receive(:handles_request?).with(*args).and_return(false)
66
- expect(proxy_handler).to receive(:handles_request?).with(*args).and_return(true)
67
- expect(subject.handles_request?(*args)).to be true
68
- end
69
- end
70
-
71
- describe '#handle_request' do
72
- before do
73
- allow(Billy::config).to receive(:record_requests).and_return(true)
74
- end
75
-
76
- it 'returns stubbed responses' do
77
- expect(stub_handler).to receive(:handle_request).with(*args).and_return('foo')
78
- expect(cache_handler).to_not receive(:handle_request)
79
- expect(proxy_handler).to_not receive(:handle_request)
80
- expect(subject.handle_request(*args)).to eql 'foo'
81
- expect(subject.requests).to eql([{status: :complete, handler: :stubs, method: 'get', url: 'url', headers: 'headers', body: 'body'}])
82
- end
83
-
84
- it 'returns cached responses' do
85
- expect(stub_handler).to receive(:handle_request).with(*args)
86
- expect(cache_handler).to receive(:handle_request).with(*args).and_return('bar')
87
- expect(proxy_handler).to_not receive(:handle_request)
88
- expect(subject.handle_request(*args)).to eql 'bar'
89
- expect(subject.requests).to eql([{status: :complete, handler: :cache, method: 'get', url: 'url', headers: 'headers', body: 'body'}])
90
- end
91
-
92
- it 'returns proxied responses' do
93
- expect(stub_handler).to receive(:handle_request).with(*args)
94
- expect(cache_handler).to receive(:handle_request).with(*args)
95
- expect(proxy_handler).to receive(:handle_request).with(*args).and_return('baz')
96
- expect(subject.handle_request(*args)).to eql 'baz'
97
- expect(subject.requests).to eql([{status: :complete, handler: :proxy, method: 'get', url: 'url', headers: 'headers', body: 'body'}])
98
- end
99
-
100
- it 'returns an error hash if request is not handled' do
101
- expect(stub_handler).to receive(:handle_request).with(*args)
102
- expect(cache_handler).to receive(:handle_request).with(*args)
103
- expect(proxy_handler).to receive(:handle_request).with(*args)
104
- expect(subject.handle_request(*args)).to eql(error: 'Connection to url not cached and new http connections are disabled')
105
- expect(subject.requests).to eql([{status: :complete, handler: :error, method: 'get', url: 'url', headers: 'headers', body: 'body'}])
106
- end
107
-
108
- it 'returns an error hash with body message if request cached based on body is not handled' do
109
- args[0] = Billy.config.cache_request_body_methods[0]
110
- expect(stub_handler).to receive(:handle_request).with(*args)
111
- expect(cache_handler).to receive(:handle_request).with(*args)
112
- expect(proxy_handler).to receive(:handle_request).with(*args)
113
- expect(subject.handle_request(*args)).to eql(error: "Connection to url with body 'body' not cached and new http connections are disabled")
114
- expect(subject.requests).to eql([{status: :complete, handler: :error, method: 'post', url: 'url', headers: 'headers', body: 'body'}])
115
- end
116
-
117
- it 'returns an error hash on unhandled exceptions' do
118
- # Allow handling requests initially
119
- allow(stub_handler).to receive(:handle_request)
120
- allow(cache_handler).to receive(:handle_request)
121
-
122
- allow(proxy_handler).to receive(:handle_request).and_raise("Any Proxy Error")
123
- expect(subject.handle_request(*args)).to eql(error: "Any Proxy Error")
124
-
125
- allow(cache_handler).to receive(:handle_request).and_raise("Any Cache Error")
126
- expect(subject.handle_request(*args)).to eql(error: "Any Cache Error")
127
-
128
- allow(stub_handler).to receive(:handle_request).and_raise("Any Stub Error")
129
- expect(subject.handle_request(*args)).to eql(error: "Any Stub Error")
130
- end
131
-
132
- context 'before_handle_request activated' do
133
- before do
134
- handle_request = proc { |method, url, headers, body|
135
- [method, url, headers, "#{body}_modified"]
136
- }
137
- allow(Billy::config).to receive(:before_handle_request).and_return(handle_request)
138
- end
139
-
140
- after do
141
- allow(Billy::config).to receive(:before_handle_request).and_call_original
142
- end
143
-
144
- it 'modify request before handling' do
145
- new_args = %w(get url headers body_modified)
146
- expect(stub_handler).to receive(:handle_request).with(*new_args)
147
- expect(cache_handler).to receive(:handle_request).with(*new_args).and_return('bar')
148
- expect(proxy_handler).to_not receive(:handle_request)
149
- expect(subject.handle_request(*args)).to eql 'bar'
150
- expect(subject.requests).to eql([{status: :complete, handler: :cache, method: 'get', url: 'url', headers: 'headers', body: 'body'}])
151
- end
152
- end
153
- end
154
-
155
- describe '#stubs' do
156
- it 'delegates to the stub_handler' do
157
- expect(stub_handler).to receive(:stubs)
158
- subject.stubs
159
- end
160
- end
161
-
162
- describe '#stub' do
163
- it 'delegates to the stub_handler' do
164
- expect(stub_handler).to receive(:stub).with('some args')
165
- subject.stub('some args')
166
- end
167
- end
168
-
169
- describe '#reset' do
170
- it 'resets all of the handlers' do
171
- handlers.each do |_key, handler|
172
- expect(handler).to receive(:reset)
173
- end
174
- expect(subject.request_log).to receive(:reset)
175
- subject.reset
176
- end
177
- end
178
-
179
- describe '#reset_stubs' do
180
- it 'resets the stub handler' do
181
- expect(stub_handler).to receive(:reset)
182
- subject.reset_stubs
183
- end
184
- end
185
-
186
- describe '#reset_cache' do
187
- it 'resets the cache handler' do
188
- expect(cache_handler).to receive(:reset)
189
- subject.reset_cache
190
- end
191
- end
192
-
193
- describe '#restore_cache' do
194
- it 'resets the cache handler' do
195
- expect(cache_handler).to receive(:reset)
196
- subject.reset_cache
197
- end
198
- end
199
- end
200
- end