puffing-billy 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +1 -1
- data/README.md +34 -6
- data/bin/proxy.rb +3 -0
- data/examples/tumblr_api.html +22 -0
- data/lib/billy/proxy.rb +21 -13
- data/lib/billy/proxy_connection.rb +3 -2
- data/lib/billy/version.rb +1 -1
- data/spec/requests/examples/tumblr_api_spec.rb +30 -0
- metadata +8 -3
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,13 +1,15 @@
|
|
1
1
|
# Puffing Billy
|
2
2
|
|
3
|
-
A stubbing proxy server for ruby. Connect it to your browser in integration
|
4
|
-
interactions with remote HTTP(S) servers.
|
3
|
+
A stubbing proxy server for ruby. Connect it to your browser in integration
|
4
|
+
tests to fake interactions with remote HTTP(S) servers.
|
5
5
|
|
6
6
|
![](http://upload.wikimedia.org/wikipedia/commons/0/01/Puffing_Billy_1862.jpg)
|
7
7
|
|
8
8
|
## Overview
|
9
9
|
|
10
|
-
|
10
|
+
Billy spawns an EventMachine-based proxy server, which it uses to intercept
|
11
|
+
requests sent by your browser. It has a simple rspec plugin for configuring
|
12
|
+
which requests need stubbing and what they should return.
|
11
13
|
|
12
14
|
```ruby
|
13
15
|
it 'should stub google' do
|
@@ -17,6 +19,7 @@ it 'should stub google' do
|
|
17
19
|
end
|
18
20
|
```
|
19
21
|
|
22
|
+
|
20
23
|
## Installation
|
21
24
|
|
22
25
|
Add this line to your application's Gemfile:
|
@@ -47,23 +50,47 @@ Capybara.javascript_driver = :selenium_billy
|
|
47
50
|
In your tests:
|
48
51
|
|
49
52
|
```ruby
|
50
|
-
#
|
53
|
+
# Stub and return text, json, jsonp (or anything else)
|
51
54
|
proxy.stub('http://example.com/text').and_return(:text => 'Foobar')
|
52
55
|
proxy.stub('http://example.com/json').and_return(:json => { :foo => 'bar' })
|
53
56
|
proxy.stub('http://example.com/jsonp').and_return(:jsonp => { :foo => 'bar' })
|
54
57
|
proxy.stub('http://example.com/wtf').and_return(:body => 'WTF!?', :content_type => 'text/wtf')
|
55
58
|
|
56
|
-
#
|
59
|
+
# Stub redirections and other return codes
|
57
60
|
proxy.stub('http://example.com/redirect').and_return(:redirect_to => 'http://example.com/other')
|
58
61
|
proxy.stub('http://example.com/missing').and_return(:code => 404, :body => 'Not found')
|
59
62
|
|
60
|
-
#
|
63
|
+
# Even stub HTTPS!
|
61
64
|
proxy.stub('https://example.com/secure').and_return(:text => 'secrets!!1!')
|
65
|
+
|
66
|
+
# Pass a Proc (or Proc-style object) to create dynamic responses.
|
67
|
+
#
|
68
|
+
# The proc will be called with the following arguments:
|
69
|
+
# params: Query string parameters hash, CGI::escape-style
|
70
|
+
# headers: Headers hash
|
71
|
+
# body: Request body string
|
72
|
+
#
|
73
|
+
proxy.stub('https://example.com/proc').and_return(Proc.new { |params, headers, body|
|
74
|
+
{ :text => "Hello, #{params['name'][0]}"}
|
75
|
+
})
|
62
76
|
```
|
63
77
|
|
64
78
|
Stubs are reset between tests. Any requests that are not stubbed will be
|
65
79
|
proxied to the remote server.
|
66
80
|
|
81
|
+
## Customising the javascript driver
|
82
|
+
|
83
|
+
If you use a customised Capybara driver, remember to set the proxy address
|
84
|
+
and tell it to ignore SSL certificate warnings. See
|
85
|
+
[lib/billy/rspec.rb](https://github.com/oesmith/puffing-billy/blob/master/lib/billy/rspec.rb)
|
86
|
+
to see how Billy's default drivers are configured.
|
87
|
+
|
88
|
+
## FAQ
|
89
|
+
|
90
|
+
1. Why name it after a train?
|
91
|
+
|
92
|
+
Trains are *cool*.
|
93
|
+
|
67
94
|
## Contributing
|
68
95
|
|
69
96
|
1. Fork it
|
@@ -76,3 +103,4 @@ proxied to the remote server.
|
|
76
103
|
|
77
104
|
1. Integration for test frameworks other than rspec.
|
78
105
|
2. Caching (for super awesome improved test performance).
|
106
|
+
3. Show errors from the EventMachine reactor loop in the test output.
|
data/bin/proxy.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
<body>
|
3
|
+
<h1>Latest news</h1>
|
4
|
+
<div id="news"></div>
|
5
|
+
|
6
|
+
<script type='text/javascript' src='http://code.jquery.com/jquery-1.8.2.min.js'></script>
|
7
|
+
<script type='text/javascript'>
|
8
|
+
$(function () {
|
9
|
+
var url = 'http://blog.howmanyleft.co.uk/api/read/json?callback=?&type=text&num=3&filter=text';
|
10
|
+
$.getJSON(url, function (data) {
|
11
|
+
$.each(data.posts, function (idx, post) {
|
12
|
+
var title = post['regular-title'];
|
13
|
+
var href = post['url-with-slug'];
|
14
|
+
var body = post['regular-body'];
|
15
|
+
$('#news').append(
|
16
|
+
'<h3><a href="' + href + '">' + title + '</a></h3>' +
|
17
|
+
'<p>' + body + '</p>');
|
18
|
+
});
|
19
|
+
});
|
20
|
+
})
|
21
|
+
</script>
|
22
|
+
</body>
|
data/lib/billy/proxy.rb
CHANGED
@@ -8,20 +8,13 @@ module Billy
|
|
8
8
|
reset
|
9
9
|
end
|
10
10
|
|
11
|
-
def start
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
end
|
18
|
-
|
19
|
-
@signature = EM.start_server('127.0.0.1', 0, ProxyConnection) do |p|
|
20
|
-
p.handler = self
|
21
|
-
end
|
22
|
-
end
|
11
|
+
def start(threaded = true)
|
12
|
+
if threaded
|
13
|
+
Thread.new { main_loop }
|
14
|
+
sleep(0.01) while @signature.nil?
|
15
|
+
else
|
16
|
+
main_loop
|
23
17
|
end
|
24
|
-
sleep(0.01) while @signature.nil?
|
25
18
|
end
|
26
19
|
|
27
20
|
def url
|
@@ -63,5 +56,20 @@ module Billy
|
|
63
56
|
end
|
64
57
|
nil
|
65
58
|
end
|
59
|
+
|
60
|
+
def main_loop
|
61
|
+
EM.run do
|
62
|
+
EM.error_handler do |e|
|
63
|
+
puts e.class.name, e
|
64
|
+
puts e.backtrace.join("\n")
|
65
|
+
end
|
66
|
+
|
67
|
+
@signature = EM.start_server('127.0.0.1', 0, ProxyConnection) do |p|
|
68
|
+
p.handler = self
|
69
|
+
end
|
70
|
+
|
71
|
+
Billy.log(:info, "Proxy listening on #{url}")
|
72
|
+
end
|
73
|
+
end
|
66
74
|
end
|
67
75
|
end
|
@@ -85,6 +85,7 @@ module Billy
|
|
85
85
|
|
86
86
|
def proxy_request
|
87
87
|
headers = Hash[@headers.map { |k,v| [k.downcase, v] }]
|
88
|
+
headers.delete('accept-encoding')
|
88
89
|
|
89
90
|
req = EventMachine::HttpRequest.new(@url)
|
90
91
|
req_opts = {
|
@@ -98,7 +99,7 @@ module Billy
|
|
98
99
|
req = req.send(@parser.http_method.downcase, req_opts)
|
99
100
|
|
100
101
|
req.errback do
|
101
|
-
puts "Request failed: #{url}"
|
102
|
+
puts "Request failed: #{@url}"
|
102
103
|
close_connection
|
103
104
|
end
|
104
105
|
|
@@ -106,7 +107,7 @@ module Billy
|
|
106
107
|
res = EM::DelegatedHttpResponse.new(self)
|
107
108
|
res.status = req.response_header.status
|
108
109
|
res.headers = req.response_header.merge('Connection' => 'close')
|
109
|
-
res.content = req.response
|
110
|
+
res.content = req.response.force_encoding('BINARY')
|
110
111
|
res.send_response
|
111
112
|
end
|
112
113
|
end
|
data/lib/billy/version.rb
CHANGED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Tumblr API example', :type => :request, :js => true do
|
4
|
+
before do
|
5
|
+
proxy.stub('http://blog.howmanyleft.co.uk/api/read/json').and_return(
|
6
|
+
:jsonp => {
|
7
|
+
:posts => [
|
8
|
+
{
|
9
|
+
'regular-title' => 'News Item 1',
|
10
|
+
'url-with-slug' => 'http://example.com/news/1',
|
11
|
+
'regular-body' => 'News item 1 content here'
|
12
|
+
},
|
13
|
+
{
|
14
|
+
'regular-title' => 'News Item 2',
|
15
|
+
'url-with-slug' => 'http://example.com/news/2',
|
16
|
+
'regular-body' => 'News item 2 content here'
|
17
|
+
}
|
18
|
+
]
|
19
|
+
})
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should show news stories', :js => true do
|
23
|
+
visit '/tumblr_api.html'
|
24
|
+
page.should have_link('News Item 1', :href => 'http://example.com/news/1')
|
25
|
+
page.should have_content('News item 1 content here')
|
26
|
+
page.should have_link('News Item 2', :href => 'http://example.com/news/2')
|
27
|
+
page.should have_content('News item 2 content here')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: puffing-billy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-10-
|
12
|
+
date: 2012-10-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
@@ -223,7 +223,8 @@ description: A stubbing proxy server for ruby. Connect it to your browser in int
|
|
223
223
|
tests to fake interactions with remote HTTP(S) servers.
|
224
224
|
email:
|
225
225
|
- olly.smith@gmail.com
|
226
|
-
executables:
|
226
|
+
executables:
|
227
|
+
- proxy.rb
|
227
228
|
extensions: []
|
228
229
|
extra_rdoc_files: []
|
229
230
|
files:
|
@@ -234,8 +235,10 @@ files:
|
|
234
235
|
- LICENSE
|
235
236
|
- README.md
|
236
237
|
- Rakefile
|
238
|
+
- bin/proxy.rb
|
237
239
|
- examples/README.md
|
238
240
|
- examples/facebook_api.html
|
241
|
+
- examples/tumblr_api.html
|
239
242
|
- lib/billy.rb
|
240
243
|
- lib/billy/config.rb
|
241
244
|
- lib/billy/mitm.crt
|
@@ -251,6 +254,7 @@ files:
|
|
251
254
|
- spec/fixtures/test-server.key
|
252
255
|
- spec/lib/billy/proxy_request_stub_spec.rb
|
253
256
|
- spec/requests/examples/facebook_api_spec.rb
|
257
|
+
- spec/requests/examples/tumblr_api_spec.rb
|
254
258
|
- spec/requests/proxy_spec.rb
|
255
259
|
- spec/spec_helper.rb
|
256
260
|
- spec/support/test_server.rb
|
@@ -283,6 +287,7 @@ test_files:
|
|
283
287
|
- spec/fixtures/test-server.key
|
284
288
|
- spec/lib/billy/proxy_request_stub_spec.rb
|
285
289
|
- spec/requests/examples/facebook_api_spec.rb
|
290
|
+
- spec/requests/examples/tumblr_api_spec.rb
|
286
291
|
- spec/requests/proxy_spec.rb
|
287
292
|
- spec/spec_helper.rb
|
288
293
|
- spec/support/test_server.rb
|