puffing-billy 0.1.0 → 0.1.1
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.
- 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
|

|
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
|