puffing-billy 0.6.2 → 0.7.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.
- checksums.yaml +4 -4
- data/.travis.yml +3 -1
- data/CHANGELOG.md +7 -0
- data/Gemfile.lock +8 -8
- data/README.md +19 -1
- data/examples/post_api.html +16 -0
- data/examples/preflight_request.html +22 -0
- data/lib/billy.rb +1 -1
- data/lib/billy/cache.rb +1 -1
- data/lib/billy/config.rb +2 -1
- data/lib/billy/handlers/request_handler.rb +1 -1
- data/lib/billy/proxy.rb +1 -1
- data/lib/billy/version.rb +1 -1
- data/lib/tasks/billy.rake +1 -1
- data/spec/features/examples/post_api_spec.rb +15 -0
- data/spec/features/examples/preflight_request_spec.rb +29 -0
- data/spec/lib/billy/cache_spec.rb +28 -0
- data/spec/lib/billy/handlers/request_handler_spec.rb +2 -2
- data/spec/lib/billy/proxy_request_stub_spec.rb +11 -0
- data/spec/lib/proxy_spec.rb +10 -0
- metadata +9 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3655cba82676b1deab3539e52a0905e2235fd121
|
4
|
+
data.tar.gz: 1b4fac47e1c38eed0c59038924ae10218bc753d0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 161f4b1ac60dd9f946a60f78b2abe69f16c7fdf7cfe3a4e3e8599c495de9c32b2825c5b0f7beb3df644a2bde58694b77c6b1058d83eb9db49d067d547e5590e8
|
7
|
+
data.tar.gz: 683a32965991b618db46c6943ccd535b9f92a11df8fc5da8dce371b1e4f8b58df4d581c54919047c347adf85f5c61ec4a48becd40597234fcd774d1c3199d814
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
v0.7.0, 2016-05-05
|
2
|
+
------------------
|
3
|
+
* Change WebKit driver to ignore SSL errors [#140](https://github.com/oesmith/puffing-billy/pull/140)
|
4
|
+
* Add documentation and specs for stubbing out options requests [#141](https://github.com/oesmith/puffing-billy/pull/141)
|
5
|
+
* Support distinguishing non-POST requests in cache based on request body [#148](https://github.com/oesmith/puffing-billy/pull/148)
|
6
|
+
* Allow Puffing Billy to run with custom host [#150](https://github.com/oesmith/puffing-billy/pull/150)
|
7
|
+
|
1
8
|
v0.6.2, 2015-11-23
|
2
9
|
------------------
|
3
10
|
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
puffing-billy (0.
|
4
|
+
puffing-billy (0.7.0)
|
5
5
|
addressable
|
6
6
|
em-http-request (~> 1.1.0)
|
7
7
|
em-synchrony
|
@@ -13,7 +13,7 @@ PATH
|
|
13
13
|
GEM
|
14
14
|
remote: https://rubygems.org/
|
15
15
|
specs:
|
16
|
-
addressable (2.
|
16
|
+
addressable (2.4.0)
|
17
17
|
builder (3.2.2)
|
18
18
|
capybara (2.4.4)
|
19
19
|
mime-types (>= 1.16)
|
@@ -28,7 +28,7 @@ GEM
|
|
28
28
|
ffi (~> 1.0, >= 1.0.11)
|
29
29
|
cliver (0.3.2)
|
30
30
|
coderay (1.1.0)
|
31
|
-
cookiejar (0.3.
|
31
|
+
cookiejar (0.3.0)
|
32
32
|
cucumber (2.0.2)
|
33
33
|
builder (>= 2.1.2)
|
34
34
|
cucumber-core (~> 1.2.0)
|
@@ -40,15 +40,15 @@ GEM
|
|
40
40
|
gherkin (~> 2.12.0)
|
41
41
|
daemons (1.2.3)
|
42
42
|
diff-lcs (1.2.5)
|
43
|
-
em-http-request (1.1.
|
43
|
+
em-http-request (1.1.3)
|
44
44
|
addressable (>= 2.3.4)
|
45
|
-
cookiejar
|
45
|
+
cookiejar (<= 0.3.0)
|
46
46
|
em-socksify (>= 0.3)
|
47
47
|
eventmachine (>= 1.0.3)
|
48
48
|
http_parser.rb (>= 0.6.0)
|
49
|
-
em-socksify (0.3.
|
49
|
+
em-socksify (0.3.1)
|
50
50
|
eventmachine (>= 1.0.0.beta.4)
|
51
|
-
em-synchrony (1.0.
|
51
|
+
em-synchrony (1.0.5)
|
52
52
|
eventmachine (>= 1.0.0.beta.1)
|
53
53
|
eventmachine (1.0.8)
|
54
54
|
eventmachine_httpserver (0.2.1)
|
@@ -152,4 +152,4 @@ DEPENDENCIES
|
|
152
152
|
thin
|
153
153
|
|
154
154
|
BUNDLED WITH
|
155
|
-
1.
|
155
|
+
1.11.2
|
data/README.md
CHANGED
@@ -92,6 +92,22 @@ proxy.stub('https://example.com:443/secure/').and_return(:text => 'secrets!!1!')
|
|
92
92
|
proxy.stub('https://example.com/proc/').and_return(Proc.new { |params, headers, body|
|
93
93
|
{ :text => "Hello, #{params['name'][0]}"}
|
94
94
|
})
|
95
|
+
|
96
|
+
# Stub out a POST. Don't forget to allow a CORS request and set the method to 'post'
|
97
|
+
proxy.stub('http://example.com/api', :method => 'post').and_return(
|
98
|
+
:headers => { 'Access-Control-Allow-Origin' => '*' },
|
99
|
+
:code => 201
|
100
|
+
)
|
101
|
+
|
102
|
+
# Stub out an OPTIONS request. Set the headers to the values you require.
|
103
|
+
proxy.stub('http://example.com/api', :method => :options).and_return(
|
104
|
+
:headers => {
|
105
|
+
'Access-Control-Allow-Methods' => 'GET, PATCH, POST, PUT, OPTIONS',
|
106
|
+
'Access-Control-Allow-Headers' => 'X-Requested-With, X-Prototype-Version, Content-Type',
|
107
|
+
'Access-Control-Allow-Origin' => '*'
|
108
|
+
},
|
109
|
+
:code => 200
|
110
|
+
)
|
95
111
|
```
|
96
112
|
|
97
113
|
Stubs are reset between tests. Any requests that are not stubbed will be
|
@@ -198,6 +214,7 @@ Billy.configure do |c|
|
|
198
214
|
c.proxy_port = 12345 # defaults to random
|
199
215
|
c.proxied_request_host = nil
|
200
216
|
c.proxied_request_port = 80
|
217
|
+
c.cache_request_body_methods = ['post', 'patch', 'put'] # defaults to ['post']
|
201
218
|
end
|
202
219
|
```
|
203
220
|
|
@@ -265,6 +282,8 @@ continuous integration).
|
|
265
282
|
`c.proxied_request_host` and `c.proxied_request_port` are used if an internal proxy
|
266
283
|
server is required to access the internet. Most common in larger companies.
|
267
284
|
|
285
|
+
`c.cache_request_body_methods` is used to specify HTTP methods of requests that you would like to cache separately based on the contents of the request body. The default is ['post'].
|
286
|
+
|
268
287
|
### Cache Scopes
|
269
288
|
|
270
289
|
If you need to cache different responses to the same HTTP request, you can use
|
@@ -401,4 +420,3 @@ Note that this approach may cause unexpected behavior if your backend sends the
|
|
401
420
|
|
402
421
|
1. Integration for test frameworks other than rspec.
|
403
422
|
2. Show errors from the EventMachine reactor loop in the test output.
|
404
|
-
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
<body>
|
3
|
+
<h1>POST to API</h1>
|
4
|
+
<div id="result"></div>
|
5
|
+
<script type='text/javascript' src='http://code.jquery.com/jquery-1.8.2.min.js'></script>
|
6
|
+
<script type='text/javascript'>
|
7
|
+
$(function () {
|
8
|
+
$.post('http://example.com/api', { foo: 'bar' }).done(function(data) {
|
9
|
+
$('#result').append('Success!');
|
10
|
+
})
|
11
|
+
.fail(function(data) {
|
12
|
+
$('#result').append('Fail!');
|
13
|
+
});
|
14
|
+
})
|
15
|
+
</script>
|
16
|
+
</body>
|
@@ -0,0 +1,22 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
<body>
|
3
|
+
<h1>Cross Domain Request</h1>
|
4
|
+
<div id="result"></div>
|
5
|
+
<script type='text/javascript' src='http://code.jquery.com/jquery-1.8.2.min.js'></script>
|
6
|
+
<script type='text/javascript'>
|
7
|
+
$(function () {
|
8
|
+
$.ajax(
|
9
|
+
{
|
10
|
+
url: 'http://example.com/api',
|
11
|
+
method: 'GET',
|
12
|
+
contentType: 'json' // setting this forces an OPTIONS request
|
13
|
+
}
|
14
|
+
).done(function(data) {
|
15
|
+
$('#result').append('Success!');
|
16
|
+
})
|
17
|
+
.fail(function(data) {
|
18
|
+
$('#result').append('Fail!');
|
19
|
+
});
|
20
|
+
})
|
21
|
+
</script>
|
22
|
+
</body>
|
data/lib/billy.rb
CHANGED
@@ -43,7 +43,7 @@ module Billy
|
|
43
43
|
if defined?(Capybara::Webkit::Driver)
|
44
44
|
Capybara.register_driver :webkit_billy do |app|
|
45
45
|
options = {
|
46
|
-
ignore_ssl_errors:
|
46
|
+
ignore_ssl_errors: true,
|
47
47
|
proxy: {host: Billy.proxy.host, port: Billy.proxy.port}
|
48
48
|
}
|
49
49
|
Capybara::Webkit::Driver.new(app, Capybara::Webkit::Configuration.to_hash.merge(options))
|
data/lib/billy/cache.rb
CHANGED
@@ -80,7 +80,7 @@ module Billy
|
|
80
80
|
end
|
81
81
|
body_msg = ''
|
82
82
|
|
83
|
-
if method
|
83
|
+
if Billy.config.cache_request_body_methods.include?(method) && !ignore_params && !merge_cached_response_key
|
84
84
|
body_formatted = JSONUtils.json?(body.to_s) ? JSONUtils.sort_json(body.to_s) : body.to_s
|
85
85
|
body_msg = " with body '#{body_formatted}'"
|
86
86
|
key += '_' + Digest::SHA1.hexdigest(body_formatted)
|
data/lib/billy/config.rb
CHANGED
@@ -10,7 +10,7 @@ module Billy
|
|
10
10
|
:persist_cache, :ignore_cache_port, :non_successful_cache_disabled, :non_successful_error_level,
|
11
11
|
:non_whitelisted_requests_disabled, :cache_path, :proxy_host, :proxy_port, :proxied_request_inactivity_timeout,
|
12
12
|
:proxied_request_connect_timeout, :dynamic_jsonp, :dynamic_jsonp_keys, :merge_cached_responses_whitelist,
|
13
|
-
:strip_query_params, :proxied_request_host, :proxied_request_port
|
13
|
+
:strip_query_params, :proxied_request_host, :proxied_request_port, :cache_request_body_methods
|
14
14
|
|
15
15
|
def initialize
|
16
16
|
@logger = defined?(Rails) ? Rails.logger : Logger.new(STDOUT)
|
@@ -39,6 +39,7 @@ module Billy
|
|
39
39
|
@strip_query_params = true
|
40
40
|
@proxied_request_host = nil
|
41
41
|
@proxied_request_port = 80
|
42
|
+
@cache_request_body_methods = ['post']
|
42
43
|
end
|
43
44
|
end
|
44
45
|
|
@@ -21,7 +21,7 @@ module Billy
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
body_msg = method
|
24
|
+
body_msg = Billy.config.cache_request_body_methods.include?(method) ? " with body '#{body}'" : ''
|
25
25
|
{ error: "Connection to #{url}#{body_msg} not cached and new http connections are disabled" }
|
26
26
|
end
|
27
27
|
|
data/lib/billy/proxy.rb
CHANGED
@@ -47,7 +47,7 @@ module Billy
|
|
47
47
|
Billy.log :error, e.backtrace.join("\n")
|
48
48
|
end
|
49
49
|
|
50
|
-
@signature = EM.start_server(
|
50
|
+
@signature = EM.start_server(host, Billy.config.proxy_port, ProxyConnection) do |p|
|
51
51
|
p.handler = request_handler
|
52
52
|
p.cache = @cache if defined?(@cache)
|
53
53
|
p.errback do |msg|
|
data/lib/billy/version.rb
CHANGED
data/lib/tasks/billy.rake
CHANGED
@@ -75,7 +75,7 @@ namespace :cache do
|
|
75
75
|
def print_cache_details(cache)
|
76
76
|
puts " Scope: #{cache[:scope]}" if cache[:scope]
|
77
77
|
puts " URL: #{cache[:url]}"
|
78
|
-
puts " Body: #{cache[:body]}" if cache[:method]
|
78
|
+
puts " Body: #{cache[:body]}" if Billy.config.cache_request_body_methods.include?(cache[:method])
|
79
79
|
puts " Details: Request method '#{cache[:method]}' returned response status code: '#{cache[:status]}'"
|
80
80
|
puts "Filename: #{cache[:filename]}"
|
81
81
|
puts "\n\n"
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'jQuery POST API example', type: :feature, js: true do
|
4
|
+
before do
|
5
|
+
proxy.stub('http://example.com/api', method: 'post').and_return(
|
6
|
+
headers: { 'Access-Control-Allow-Origin' => '*' },
|
7
|
+
code: 201
|
8
|
+
)
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'posts to an API' do
|
12
|
+
visit '/post_api.html'
|
13
|
+
expect(page.find('#result')).to have_content 'Success!'
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'jQuery preflight request example', type: :feature, js: true do
|
4
|
+
let(:url) { 'http://example.com/api' }
|
5
|
+
|
6
|
+
before do
|
7
|
+
proxy.stub(url, method: 'get').and_return(
|
8
|
+
headers: { 'Access-Control-Allow-Origin' => '*' },
|
9
|
+
code: 201
|
10
|
+
)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'stubs out the OPTIONS request' do
|
14
|
+
visit '/preflight_request.html'
|
15
|
+
expect(page.find('#result')).to have_content 'Fail!'
|
16
|
+
|
17
|
+
proxy.stub(url, method: 'options').and_return(
|
18
|
+
headers: {
|
19
|
+
'Access-Control-Allow-Methods' => 'GET, OPTIONS',
|
20
|
+
'Access-Control-Allow-Headers' => 'Content-Type',
|
21
|
+
'Access-Control-Allow-Origin' => '*'
|
22
|
+
},
|
23
|
+
code: 200
|
24
|
+
)
|
25
|
+
|
26
|
+
visit '/preflight_request.html'
|
27
|
+
expect(page.find('#result')).to have_content 'Success!'
|
28
|
+
end
|
29
|
+
end
|
@@ -86,5 +86,33 @@ describe Billy::Cache do
|
|
86
86
|
expect(cache.key('post', analytics_url2, 'body')).to eq identical_cache_key
|
87
87
|
end
|
88
88
|
end
|
89
|
+
|
90
|
+
context 'with cache_request_body_methods set' do
|
91
|
+
before do
|
92
|
+
allow(Billy.config).to receive(:cache_request_body_methods) {
|
93
|
+
['patch']
|
94
|
+
}
|
95
|
+
end
|
96
|
+
|
97
|
+
context "for requests with methods specified in cache_request_body_methods" do
|
98
|
+
it "should have a different cache key for requests with different bodies" do
|
99
|
+
key1 = cache.key('patch', "http://example.com", "body1")
|
100
|
+
key2 = cache.key('patch', "http://example.com", "body2")
|
101
|
+
expect(key1).not_to eq key2
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should have the same cache key for requests with the same bodies" do
|
105
|
+
key1 = cache.key('patch', "http://example.com", "body1")
|
106
|
+
key2 = cache.key('patch', "http://example.com", "body1")
|
107
|
+
expect(key1).to eq key2
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should have the same cache key for request with different bodies if their methods are not included in cache_request_body_methods" do
|
112
|
+
key1 = cache.key('put', "http://example.com", "body1")
|
113
|
+
key2 = cache.key('put', "http://example.com", "body2")
|
114
|
+
expect(key1).to eq key2
|
115
|
+
end
|
116
|
+
end
|
89
117
|
end
|
90
118
|
end
|
@@ -97,8 +97,8 @@ describe Billy::RequestHandler do
|
|
97
97
|
expect(subject.handle_request(*args)).to eql(error: 'Connection to url not cached and new http connections are disabled')
|
98
98
|
end
|
99
99
|
|
100
|
-
it 'returns an error hash with body message if
|
101
|
-
args[0] =
|
100
|
+
it 'returns an error hash with body message if request cached based on body is not handled' do
|
101
|
+
args[0] = Billy.config.cache_request_body_methods[0]
|
102
102
|
expect(stub_handler).to receive(:handle_request).with(*args)
|
103
103
|
expect(cache_handler).to receive(:handle_request).with(*args)
|
104
104
|
expect(proxy_handler).to receive(:handle_request).with(*args)
|
@@ -12,11 +12,22 @@ describe Billy::ProxyRequestStub do
|
|
12
12
|
.matches?('GET', 'http://example.com')).to be
|
13
13
|
expect(Billy::ProxyRequestStub.new('http://example.com', method: :post)
|
14
14
|
.matches?('GET', 'http://example.com')).to_not be
|
15
|
+
expect(Billy::ProxyRequestStub.new('http://example.com', method: :options)
|
16
|
+
.matches?('GET', 'http://example.com')).to_not be
|
15
17
|
|
16
18
|
expect(Billy::ProxyRequestStub.new('http://example.com', method: :post)
|
17
19
|
.matches?('POST', 'http://example.com')).to be
|
18
20
|
expect(Billy::ProxyRequestStub.new('http://fooxample.com', method: :post)
|
19
21
|
.matches?('POST', 'http://example.com')).to_not be
|
22
|
+
expect(Billy::ProxyRequestStub.new('http://fooxample.com', method: :options)
|
23
|
+
.matches?('POST', 'http://example.com')).to_not be
|
24
|
+
|
25
|
+
expect(Billy::ProxyRequestStub.new('http://example.com', method: :options)
|
26
|
+
.matches?('OPTIONS', 'http://example.com')).to be
|
27
|
+
expect(Billy::ProxyRequestStub.new('http://example.com', method: :options)
|
28
|
+
.matches?('OPTIONS', 'http://zzzzzexample.com')).to_not be
|
29
|
+
expect(Billy::ProxyRequestStub.new('http://example.com', method: :post)
|
30
|
+
.matches?('OPTIONS', 'http://example.com')).to_not be
|
20
31
|
end
|
21
32
|
|
22
33
|
it 'should match regexps' do
|
data/spec/lib/proxy_spec.rb
CHANGED
@@ -22,6 +22,10 @@ shared_examples_for 'a proxy server' do
|
|
22
22
|
it 'should proxy DELETE requests' do
|
23
23
|
expect(http.delete('/echo').body).to eql 'DELETE /echo'
|
24
24
|
end
|
25
|
+
|
26
|
+
it 'should proxy OPTIONS requests' do
|
27
|
+
expect(http.run_request(:options, '/echo', nil, nil).body).to eql 'OPTIONS /echo'
|
28
|
+
end
|
25
29
|
end
|
26
30
|
|
27
31
|
shared_examples_for 'a request stub' do
|
@@ -60,6 +64,12 @@ shared_examples_for 'a request stub' do
|
|
60
64
|
.and_return(text: 'hello, DELETE!')
|
61
65
|
expect(http.delete('/bam').body).to eql 'hello, DELETE!'
|
62
66
|
end
|
67
|
+
|
68
|
+
it 'should stub OPTIONS requests' do
|
69
|
+
proxy.stub("#{url}/bim", method: :options)
|
70
|
+
.and_return(text: 'hello, OPTIONS!')
|
71
|
+
expect(http.run_request(:options, '/bim', nil, nil).body).to eql 'hello, OPTIONS!'
|
72
|
+
end
|
63
73
|
end
|
64
74
|
|
65
75
|
shared_examples_for 'a cache' do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: puffing-billy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Olly Smith
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-05-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -298,6 +298,8 @@ files:
|
|
298
298
|
- bin/proxy.rb
|
299
299
|
- examples/README.md
|
300
300
|
- examples/facebook_api.html
|
301
|
+
- examples/post_api.html
|
302
|
+
- examples/preflight_request.html
|
301
303
|
- examples/tumblr_api.html
|
302
304
|
- lib/billy.rb
|
303
305
|
- lib/billy/cache.rb
|
@@ -323,6 +325,8 @@ files:
|
|
323
325
|
- log/.gitkeep
|
324
326
|
- puffing-billy.gemspec
|
325
327
|
- spec/features/examples/facebook_api_spec.rb
|
328
|
+
- spec/features/examples/post_api_spec.rb
|
329
|
+
- spec/features/examples/preflight_request_spec.rb
|
326
330
|
- spec/features/examples/tumblr_api_spec.rb
|
327
331
|
- spec/fixtures/test-server.crt
|
328
332
|
- spec/fixtures/test-server.key
|
@@ -356,12 +360,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
356
360
|
version: '0'
|
357
361
|
requirements: []
|
358
362
|
rubyforge_project:
|
359
|
-
rubygems_version: 2.
|
363
|
+
rubygems_version: 2.5.1
|
360
364
|
signing_key:
|
361
365
|
specification_version: 4
|
362
366
|
summary: Easy request stubs for browser tests.
|
363
367
|
test_files:
|
364
368
|
- spec/features/examples/facebook_api_spec.rb
|
369
|
+
- spec/features/examples/post_api_spec.rb
|
370
|
+
- spec/features/examples/preflight_request_spec.rb
|
365
371
|
- spec/features/examples/tumblr_api_spec.rb
|
366
372
|
- spec/fixtures/test-server.crt
|
367
373
|
- spec/fixtures/test-server.key
|
@@ -376,4 +382,3 @@ test_files:
|
|
376
382
|
- spec/lib/proxy_spec.rb
|
377
383
|
- spec/spec_helper.rb
|
378
384
|
- spec/support/test_server.rb
|
379
|
-
has_rdoc:
|