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 CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- puffing-billy (0.0.1)
4
+ puffing-billy (0.1.1)
5
5
  em-http-request
6
6
  eventmachine
7
7
  eventmachine_httpserver
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 tests to fake
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
- The thirty second version:
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
- # stub and return text, json, jsonp (or anything else)
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
- # stub redirections and other return codes
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
- # even stub HTTPS!
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,3 @@
1
+ #!/usr/bin/env ruby
2
+ require 'billy'
3
+ Billy::Proxy.new.start(false)
@@ -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
- Thread.new do
13
- EM.run do
14
- EM.error_handler do |e|
15
- puts e.class.name, e
16
- puts e.backtrace.join("\n")
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
@@ -1,3 +1,3 @@
1
1
  module Billy
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
@@ -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.0
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-11 00:00:00.000000000 Z
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