puffing-billy 0.4.1 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6557e02e504855ec7a7776eeee317695021c9e50
4
- data.tar.gz: c25a26247ee30db7daa8158f739503b19848615f
3
+ metadata.gz: 556d5bc9c625544467f4dfcfcde6a1e5666b3c24
4
+ data.tar.gz: 5ef5ee675e69541bde2bb75807db1c252a154f5f
5
5
  SHA512:
6
- metadata.gz: 94a428edbe74084084326f1daad96992928f8c22dcc6e52d0c95bc153e3d4296bd754f3bd3dfb02d1a435729e62e46726f5ed772fd6a646ce9c8e95a1ae0452d
7
- data.tar.gz: c0d6395651e775a9bde1a67cb164617fceb901baa758e204dc4fc5adea37932cd68a0095471906f5d31fbaae3868c9b9092d4cd8e43705553f781d1266836357
6
+ metadata.gz: 12b4fe682ddd846585f468dfe16f54dce866d4e14a5176d4bf5a409a0e5d4553e701fad2c956887ea207142072e7ed7f6a1dd9ab738f4ea89ed2909e1b883652
7
+ data.tar.gz: 773d1bbd8d4aac55a7f67bd1903e86e801d21bc7619b55cbf7a3e19bac6efa12e8d95e5bea444f5484164b1bb4ccdda12a872579fb3fd4fc936637112b4750fe
@@ -1,3 +1,10 @@
1
+ v0.5.0, 2015-02-22
2
+ ------------------
3
+
4
+ * Rubocop code cleanup (#89)
5
+ * Create option for strip query params in request stub (#93)
6
+ * Require compatible version of em-http-request (#94)
7
+
1
8
  v0.4.1, 2015-01-02
2
9
  ------------------
3
10
 
@@ -1,9 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- puffing-billy (0.4.1)
4
+ puffing-billy (0.5.0)
5
5
  addressable
6
- em-http-request
6
+ em-http-request (~> 1.1.0)
7
7
  em-synchrony
8
8
  eventmachine
9
9
  eventmachine_httpserver
data/Guardfile CHANGED
@@ -1,18 +1,18 @@
1
1
  # A sample Guardfile
2
2
  # More info at https://github.com/guard/guard#readme
3
3
 
4
- guard 'rspec', :version => 2 do
4
+ guard 'rspec', version: 2 do
5
5
  watch(%r{^spec/.+_spec\.rb$})
6
6
  watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
- watch('spec/spec_helper.rb') { "spec" }
7
+ watch('spec/spec_helper.rb') { 'spec' }
8
8
 
9
9
  # Rails example
10
10
  watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
11
11
  watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
12
12
  watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
13
- watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
14
- watch('config/routes.rb') { "spec/routing" }
15
- watch('app/controllers/application_controller.rb') { "spec/controllers" }
13
+ watch(%r{^spec/support/(.+)\.rb$}) { 'spec' }
14
+ watch('config/routes.rb') { 'spec/routing' }
15
+ watch('app/controllers/application_controller.rb') { 'spec/controllers' }
16
16
 
17
17
  # Capybara request specs
18
18
  watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" }
data/README.md CHANGED
@@ -137,6 +137,12 @@ It's good practice to reset the driver after each scenario, so having an
137
137
  stubs are reset after each step, so any usage of a stub should be in the
138
138
  same step that it was created in.
139
139
 
140
+ ## Minitest Usage
141
+
142
+ Please see [this link](https://gist.github.com/sauy7/1b081266dd453a1b737b) for
143
+ details and report back to [Issue #49](https://github.com/oesmith/puffing-billy/issues/49)
144
+ if you get it fully working.
145
+
140
146
  ## Caching
141
147
 
142
148
  Requests routed through the external proxy are cached.
@@ -202,6 +208,12 @@ caching. You should mostly use this for analytics and various social buttons as
202
208
  they use cache avoidance techniques, but return practically the same response
203
209
  that most often does not affect your test results.
204
210
 
211
+ `c.strip_query_params` is used to strip query parameters when you stub some requests
212
+ with query parameters. Default value is true. For example, `proxy.stub('http://myapi.com/user/?country=FOO')`
213
+ is considered the same as: `proxy.stub('http://myapi.com/user/?anything=FOO')` and
214
+ generally the same as: `proxy.stub('http://myapi.com/user/')`. When you need to distinguish between all these requests,
215
+ you may set this config value to false.
216
+
205
217
  `c.dynamic_jsonp` is used to rewrite the body of JSONP responses based on the
206
218
  callback parameter. For example, if a request to `http://example.com/foo?callback=bar`
207
219
  returns `bar({"some": "json"});` and is recorded, then a later request to
@@ -327,7 +339,7 @@ and tell it to ignore SSL certificate warnings. See
327
339
  to see how Billy's default drivers are configured.
328
340
 
329
341
  ## Working with VCR and Webmock
330
- If you use VCR and Webmock elsewhere in your specs, you will need to disable them
342
+ If you use VCR and Webmock elsewhere in your specs, you may need to disable them
331
343
  for your specs utilizing Puffing Billy. To do so, you can configure your `spec_helper.rb`
332
344
  as shown below:
333
345
 
@@ -341,6 +353,12 @@ RSpec.configure do |config|
341
353
  end
342
354
  ```
343
355
 
356
+ ## Resources
357
+
358
+ [Bring Ruby VCR to Javascript testing with Capybara and puffing-billy](http://architects.dzone.com/articles/bring-ruby-vcr-javascript)
359
+ [Integration Testing Stripe.js With Mocked Network Requests](http://dev.contractual.ly/testing-stripe-js-with-mocked-network/)
360
+ [Clean-up unused cache files periodically with this config](https://github.com/oesmith/puffing-billy/pull/26#issuecomment-29905030)
361
+
344
362
  ## FAQ
345
363
 
346
364
  1. Why name it after a train?
data/Rakefile CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env rake
2
- require "bundler/gem_tasks"
2
+ require 'bundler/gem_tasks'
@@ -1,15 +1,15 @@
1
- require "billy/version"
2
- require "billy/config"
3
- require "billy/handlers/handler"
4
- require "billy/handlers/request_handler"
5
- require "billy/handlers/stub_handler"
6
- require "billy/handlers/proxy_handler"
7
- require "billy/handlers/cache_handler"
8
- require "billy/proxy_request_stub"
9
- require "billy/cache"
10
- require "billy/proxy"
11
- require "billy/proxy_connection"
12
- require "billy/railtie" if defined?(Rails)
1
+ require 'billy/version'
2
+ require 'billy/config'
3
+ require 'billy/handlers/handler'
4
+ require 'billy/handlers/request_handler'
5
+ require 'billy/handlers/stub_handler'
6
+ require 'billy/handlers/proxy_handler'
7
+ require 'billy/handlers/cache_handler'
8
+ require 'billy/proxy_request_stub'
9
+ require 'billy/cache'
10
+ require 'billy/proxy'
11
+ require 'billy/proxy_connection'
12
+ require 'billy/railtie' if defined?(Rails)
13
13
 
14
14
  module Billy
15
15
  def self.proxy
@@ -44,8 +44,8 @@ module Billy
44
44
  Capybara.register_driver :webkit_billy do |app|
45
45
  driver = Capybara::Webkit::Driver.new(app)
46
46
  driver.browser.ignore_ssl_errors
47
- driver.browser.set_proxy(:host => Billy.proxy.host,
48
- :port => Billy.proxy.port)
47
+ driver.browser.set_proxy(host: Billy.proxy.host,
48
+ port: Billy.proxy.port)
49
49
  driver
50
50
  end
51
51
  end
@@ -55,9 +55,9 @@ module Billy
55
55
  profile = Selenium::WebDriver::Firefox::Profile.new
56
56
  profile.assume_untrusted_certificate_issuer = false
57
57
  profile.proxy = Selenium::WebDriver::Proxy.new(
58
- :http => "#{Billy.proxy.host}:#{Billy.proxy.port}",
59
- :ssl => "#{Billy.proxy.host}:#{Billy.proxy.port}")
60
- Capybara::Selenium::Driver.new(app, :profile => profile)
58
+ http: "#{Billy.proxy.host}:#{Billy.proxy.port}",
59
+ ssl: "#{Billy.proxy.host}:#{Billy.proxy.port}")
60
+ Capybara::Selenium::Driver.new(app, profile: profile)
61
61
  end
62
62
  end
63
63
  end
@@ -17,51 +17,50 @@ module Billy
17
17
  def cached?(method, url, body)
18
18
  # Only log the key the first time it's looked up (in this method)
19
19
  key = key(method, url, body, true)
20
- !@cache[key].nil? or persisted?(key)
20
+ !@cache[key].nil? || persisted?(key)
21
21
  end
22
22
 
23
23
  def persisted?(key)
24
- Billy.config.persist_cache and File.exists?(cache_file(key))
24
+ Billy.config.persist_cache && File.exist?(cache_file(key))
25
25
  end
26
26
 
27
27
  def fetch(method, url, body)
28
28
  key = key(method, url, body)
29
- @cache[key] or fetch_from_persistence(key)
29
+ @cache[key] || fetch_from_persistence(key)
30
30
  end
31
31
 
32
32
  def fetch_from_persistence(key)
33
- begin
34
- @cache[key] = YAML.load(File.open(cache_file(key))) if persisted?(key)
35
- rescue ArgumentError => e
36
- Billy.log :error, "Could not parse YAML: #{e.message}"
37
- nil
38
- end
33
+ @cache[key] = YAML.load(File.open(cache_file(key))) if persisted?(key)
34
+ rescue ArgumentError => e
35
+ Billy.log :error, "Could not parse YAML: #{e.message}"
36
+ nil
39
37
  end
40
38
 
41
39
  def store(method, url, request_headers, body, response_headers, status, content)
42
40
  cached = {
43
- :scope => scope,
44
- :url => format_url(url),
45
- :body => body,
46
- :status => status,
47
- :method => method,
48
- :headers => response_headers,
49
- :content => content
41
+ scope: scope,
42
+ url: format_url(url),
43
+ body: body,
44
+ status: status,
45
+ method: method,
46
+ headers: response_headers,
47
+ content: content
50
48
  }
51
49
 
52
- cached.merge!({:request_headers => request_headers}) if Billy.config.cache_request_headers
50
+ cached.merge!(request_headers: request_headers) if Billy.config.cache_request_headers
53
51
 
54
52
  key = key(method, url, body)
55
53
  @cache[key] = cached
56
54
 
57
55
  if Billy.config.persist_cache
58
- Dir.mkdir(Billy.config.cache_path) unless File.exists?(Billy.config.cache_path)
56
+ Dir.mkdir(Billy.config.cache_path) unless File.exist?(Billy.config.cache_path)
59
57
 
60
58
  begin
61
59
  File.open(cache_file(key), 'w') do |f|
62
- f.write(cached.to_yaml(:Encoding => :Utf8))
60
+ f.write(cached.to_yaml(Encoding: :Utf8))
63
61
  end
64
62
  rescue StandardError => e
63
+ Billy.log :error, "Error storing cache file: #{e.message}"
65
64
  end
66
65
  end
67
66
  end
@@ -75,33 +74,33 @@ module Billy
75
74
  merge_cached_response_key = _merge_cached_response_key(orig_url)
76
75
  url = Addressable::URI.parse(format_url(orig_url, ignore_params))
77
76
  key = if merge_cached_response_key
78
- method+'_'+Digest::SHA1.hexdigest(scope.to_s + merge_cached_response_key)
79
- else
80
- method+'_'+url.host+'_'+Digest::SHA1.hexdigest(scope.to_s + url.to_s)
81
- end
77
+ method + '_' + Digest::SHA1.hexdigest(scope.to_s + merge_cached_response_key)
78
+ else
79
+ method + '_' + url.host + '_' + Digest::SHA1.hexdigest(scope.to_s + url.to_s)
80
+ end
82
81
  body_msg = ''
83
82
 
84
83
  if method == 'post' && !ignore_params && !merge_cached_response_key
85
- body_formatted = JSONUtils::json?(body.to_s) ? JSONUtils::sort_json(body.to_s) : body.to_s
84
+ body_formatted = JSONUtils.json?(body.to_s) ? JSONUtils.sort_json(body.to_s) : body.to_s
86
85
  body_msg = " with body '#{body_formatted}'"
87
- key += '_'+Digest::SHA1.hexdigest(body_formatted)
86
+ key += '_' + Digest::SHA1.hexdigest(body_formatted)
88
87
  end
89
88
 
90
89
  Billy.log(:info, "puffing-billy: CACHE KEY for '#{orig_url}#{body_msg}' is '#{key}'") if log_key
91
90
  key
92
91
  end
93
92
 
94
- def format_url(url, ignore_params=false, dynamic_jsonp=Billy.config.dynamic_jsonp)
93
+ def format_url(url, ignore_params = false, dynamic_jsonp = Billy.config.dynamic_jsonp)
95
94
  url = Addressable::URI.parse(url)
96
95
  port_to_include = Billy.config.ignore_cache_port ? '' : ":#{url.port}"
97
- formatted_url = url.scheme+'://'+url.host+port_to_include+url.path
96
+ formatted_url = url.scheme + '://' + url.host + port_to_include + url.path
98
97
 
99
98
  return formatted_url if ignore_params
100
99
 
101
100
  if url.query
102
101
  query_string = if dynamic_jsonp
103
102
  query_hash = Rack::Utils.parse_query(url.query)
104
- Billy.config.dynamic_jsonp_keys.each{|k| query_hash.delete(k) }
103
+ Billy.config.dynamic_jsonp_keys.each { |k| query_hash.delete(k) }
105
104
  Rack::Utils.build_query(query_hash)
106
105
  else
107
106
  url.query
@@ -110,7 +109,7 @@ module Billy
110
109
  formatted_url += "?#{query_string}"
111
110
  end
112
111
 
113
- formatted_url += '#'+url.fragment if url.fragment
112
+ formatted_url += '#' + url.fragment if url.fragment
114
113
 
115
114
  formatted_url
116
115
  end
@@ -124,10 +123,10 @@ module Billy
124
123
  end
125
124
 
126
125
  def with_scope(use_scope = nil, &block)
127
- raise ArgumentError, 'Expected a block but none was received.' if block.nil?
126
+ fail ArgumentError, 'Expected a block but none was received.' if block.nil?
128
127
  original_scope = scope
129
128
  scope_to use_scope
130
- block.call()
129
+ block.call
131
130
  ensure
132
131
  scope_to original_scope
133
132
  end
@@ -9,7 +9,8 @@ module Billy
9
9
  attr_accessor :logger, :cache, :cache_request_headers, :whitelist, :path_blacklist, :ignore_params,
10
10
  :persist_cache, :ignore_cache_port, :non_successful_cache_disabled, :non_successful_error_level,
11
11
  :non_whitelisted_requests_disabled, :cache_path, :proxy_port, :proxied_request_inactivity_timeout,
12
- :proxied_request_connect_timeout, :dynamic_jsonp, :dynamic_jsonp_keys, :merge_cached_responses_whitelist
12
+ :proxied_request_connect_timeout, :dynamic_jsonp, :dynamic_jsonp_keys, :merge_cached_responses_whitelist,
13
+ :strip_query_params
13
14
 
14
15
  def initialize
15
16
  @logger = defined?(Rails) ? Rails.logger : Logger.new(STDOUT)
@@ -25,7 +26,7 @@ module Billy
25
26
  @ignore_params = []
26
27
  @persist_cache = false
27
28
  @dynamic_jsonp = false
28
- @dynamic_jsonp_keys = ["callback"]
29
+ @dynamic_jsonp_keys = ['callback']
29
30
  @ignore_cache_port = true
30
31
  @non_successful_cache_disabled = false
31
32
  @non_successful_error_level = :warn
@@ -34,6 +35,7 @@ module Billy
34
35
  @proxy_port = RANDOM_AVAILABLE_PORT
35
36
  @proxied_request_inactivity_timeout = 10 # defaults from https://github.com/igrigorik/em-http-request/wiki/Redirects-and-Timeouts
36
37
  @proxied_request_connect_timeout = 5
38
+ @strip_query_params = true
37
39
  end
38
40
  end
39
41
 
@@ -7,6 +7,8 @@ module Billy
7
7
  extend Forwardable
8
8
  include Handler
9
9
 
10
+ attr_reader :cache
11
+
10
12
  def_delegators :cache, :reset, :cached?
11
13
 
12
14
  def initialize
@@ -29,7 +31,7 @@ module Billy
29
31
  nil
30
32
  end
31
33
 
32
- def handles_request?(method, url, headers, body)
34
+ def handles_request?(method, url, _headers, body)
33
35
  cached?(method, url, body)
34
36
  end
35
37
 
@@ -38,15 +40,11 @@ module Billy
38
40
  def replace_response_callback(response, url)
39
41
  request_uri = Addressable::URI.parse(url)
40
42
  if request_uri.query
41
- params = CGI::parse(request_uri.query)
42
- if params['callback'].any? and response[:content].match(/\w+\(/)
43
+ params = CGI.parse(request_uri.query)
44
+ if params['callback'].any? && response[:content].match(/\w+\(/)
43
45
  response[:content].sub!(/\w+\(/, params['callback'].first + '(')
44
46
  end
45
47
  end
46
48
  end
47
-
48
- def cache
49
- @cache
50
- end
51
49
  end
52
50
  end
@@ -15,7 +15,7 @@ module Billy
15
15
  # @return [Hash] A hash with the keys [:status, :headers, :content]
16
16
  # Returns {:error => "Some error message"} if a failure occurs.
17
17
  # Returns nil if the request cannot be fulfilled.
18
- def handle_request(http_method, url, headers, body)
18
+ def handle_request(_http_method, _url, _headers, _body)
19
19
  { error: 'The handler has not overridden the handle_request method!' }
20
20
  end
21
21
 
@@ -29,7 +29,7 @@ module Billy
29
29
  # @param [String] body The body of the HTTP request.
30
30
  # @return [Boolean] True if the Handler can respond to the request, else false.
31
31
  #
32
- def handles_request?(http_method, url, headers, body)
32
+ def handles_request?(_http_method, _url, _headers, _body)
33
33
  false
34
34
  end
35
35
 
@@ -7,20 +7,20 @@ module Billy
7
7
  class ProxyHandler
8
8
  include Handler
9
9
 
10
- def handles_request?(method, url, headers, body)
10
+ def handles_request?(_method, url, _headers, _body)
11
11
  !disabled_request?(url)
12
12
  end
13
13
 
14
14
  def handle_request(method, url, headers, body)
15
15
  if handles_request?(method, url, headers, body)
16
- req = EventMachine::HttpRequest.new(url, {
17
- :inactivity_timeout => Billy.config.proxied_request_inactivity_timeout,
18
- :connect_timeout => Billy.config.proxied_request_connect_timeout})
16
+ req = EventMachine::HttpRequest.new(url,
17
+ inactivity_timeout: Billy.config.proxied_request_inactivity_timeout,
18
+ connect_timeout: Billy.config.proxied_request_connect_timeout)
19
19
 
20
20
  req = req.send(method.downcase, build_request_options(headers, body))
21
21
 
22
22
  if req.error
23
- return { :error => "Request to #{url} failed with error: #{req.error}" }
23
+ return { error: "Request to #{url} failed with error: #{req.error}" }
24
24
  end
25
25
 
26
26
  if req.response
@@ -28,7 +28,7 @@ module Billy
28
28
 
29
29
  unless allowed_response_code?(response[:status])
30
30
  if Billy.config.non_successful_error_level == :error
31
- return { :error => "Request failed due to response status #{response[:status]} for '#{url}' which was not allowed." }
31
+ return { error: "Request failed due to response status #{response[:status]} for '#{url}' which was not allowed." }
32
32
  else
33
33
  Billy.log(:warn, "puffing-billy: Received response status code #{response[:status]} for '#{url}'")
34
34
  end
@@ -48,14 +48,14 @@ module Billy
48
48
  private
49
49
 
50
50
  def build_request_options(headers, body)
51
- headers = Hash[headers.map { |k,v| [k.downcase, v] }]
51
+ headers = Hash[headers.map { |k, v| [k.downcase, v] }]
52
52
  headers.delete('accept-encoding')
53
53
 
54
54
  req_opts = {
55
- :redirects => 0,
56
- :keepalive => false,
57
- :head => headers,
58
- :ssl => { :verify => false }
55
+ redirects: 0,
56
+ keepalive: false,
57
+ head: headers,
58
+ ssl: { verify: false }
59
59
  }
60
60
  req_opts[:body] = body if body
61
61
  req_opts
@@ -63,9 +63,9 @@ module Billy
63
63
 
64
64
  def process_response(req)
65
65
  response = {
66
- :status => req.response_header.status,
67
- :headers => req.response_header.raw,
68
- :content => req.response.force_encoding('BINARY') }
66
+ status: req.response_header.status,
67
+ headers: req.response_header.raw,
68
+ content: req.response.force_encoding('BINARY') }
69
69
  response[:headers].merge!('Connection' => 'close')
70
70
  response[:headers].delete('Transfer-Encoding')
71
71
  response
@@ -84,7 +84,7 @@ module Billy
84
84
  successful_status?(status)
85
85
  end
86
86
 
87
- def cacheable?(url, headers, status)
87
+ def cacheable?(url, _headers, status)
88
88
  return false unless Billy.config.cache
89
89
 
90
90
  url = Addressable::URI.parse(url)
@@ -99,7 +99,7 @@ module Billy
99
99
  end
100
100
 
101
101
  def blacklisted_path?(path)
102
- !Billy.config.path_blacklist.index{|bl| path.include?(bl)}.nil?
102
+ !Billy.config.path_blacklist.index { |bl| path.include?(bl) }.nil?
103
103
  end
104
104
 
105
105
  def successful_status?(status)