Add regression suite for testing parameter encoding

Pulls the test suite out of #319 so that we can get some coverage around
parameter encoding. This should prevent any recurrence of #318.

Also includes a little bit of refactoring.
This commit is contained in:
Brandur 2015-10-06 14:01:19 -07:00
parent b7d714b58e
commit a48fd12c70
3 changed files with 48 additions and 7 deletions

View File

@ -120,13 +120,13 @@ module Stripe
case method.to_s.downcase.to_sym case method.to_s.downcase.to_sym
when :get, :head, :delete when :get, :head, :delete
# Make params into GET parameters # Make params into GET parameters
url += "#{URI.parse(url).query ? '&' : '?'}#{uri_encode(params)}" if params && params.any? url += "#{URI.parse(url).query ? '&' : '?'}#{Util.encode_parameters(params)}" if params && params.any?
payload = nil payload = nil
else else
if headers[:content_type] && headers[:content_type] == "multipart/form-data" if headers[:content_type] && headers[:content_type] == "multipart/form-data"
payload = params payload = params
else else
payload = uri_encode(params) payload = Util.encode_parameters(params)
end end
end end
@ -205,10 +205,9 @@ module Stripe
"uname lookup failed" "uname lookup failed"
end end
# DEPRECATED. Use `Util#encode_parameters` instead.
def self.uri_encode(params) def self.uri_encode(params)
Util.flatten_params(params). Util.encode_parameters(params)
map { |k,v| "#{k}=#{Util.url_encode(v)}" }.join('&')
end end
def self.request_headers(api_key) def self.request_headers(api_key)

View File

@ -92,6 +92,15 @@ module Stripe
end end
end end
# Encodes a hash of parameters in a way that's suitable for use as query
# parameters in a URI or as form parameters in a request body. This mainly
# involves escaping special characters from parameter keys and values (e.g.
# `&`).
def self.encode_parameters(params)
Util.flatten_params(params).
map { |k,v| "#{k}=#{Util.url_encode(v)}" }.join('&')
end
def self.url_encode(key) def self.url_encode(key)
URI.escape(key.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]")) URI.escape(key.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
end end

View File

@ -2,7 +2,40 @@ require File.expand_path('../../test_helper', __FILE__)
module Stripe module Stripe
class UtilTest < Test::Unit::TestCase class UtilTest < Test::Unit::TestCase
should "symbolize_names should convert names to symbols" do should "#encode_parameters should prepare parameters for an HTTP request" do
params = {
:a => 3,
:b => "+foo?",
:c => "bar&baz",
:d => { :a => "a", :b => "b" },
:e => [0, 1],
}
assert_equal(
"a=3&b=%2Bfoo%3F&c=bar%26baz&d[a]=a&d[b]=b&e[]=0&e[]=1",
Stripe::Util.encode_parameters(params)
)
end
should "#flatten_params should encode parameters according to Rails convention" do
params = {
:a => 3,
:b => "foo?",
:c => "bar&baz",
:d => { :a => "a", :b => "b" },
:e => [0, 1],
}
assert_equal([
["a", 3],
["b", "foo?"],
["c", "bar&baz"],
["d[a]", "a"],
["d[b]", "b"],
["e[]", 0],
["e[]", 1],
], Stripe::Util.flatten_params(params))
end
should "#symbolize_names should convert names to symbols" do
start = { start = {
'foo' => 'bar', 'foo' => 'bar',
'array' => [{ 'foo' => 'bar' }], 'array' => [{ 'foo' => 'bar' }],
@ -26,7 +59,7 @@ module Stripe
assert_equal(finish, symbolized) assert_equal(finish, symbolized)
end end
should "normalize_opts should reject nil keys" do should "#normalize_opts should reject nil keys" do
assert_raise { Stripe::Util.normalize_opts(nil) } assert_raise { Stripe::Util.normalize_opts(nil) }
assert_raise { Stripe::Util.normalize_opts(:api_key => nil) } assert_raise { Stripe::Util.normalize_opts(:api_key => nil) }
end end