From a48fd12c70a988f998e2172168559f321450d60e Mon Sep 17 00:00:00 2001 From: Brandur Date: Tue, 6 Oct 2015 14:01:19 -0700 Subject: [PATCH] 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. --- lib/stripe.rb | 9 ++++----- lib/stripe/util.rb | 9 +++++++++ test/stripe/util_test.rb | 37 +++++++++++++++++++++++++++++++++++-- 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/lib/stripe.rb b/lib/stripe.rb index a68912eb..60c655e9 100644 --- a/lib/stripe.rb +++ b/lib/stripe.rb @@ -120,13 +120,13 @@ module Stripe case method.to_s.downcase.to_sym when :get, :head, :delete # 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 else if headers[:content_type] && headers[:content_type] == "multipart/form-data" payload = params else - payload = uri_encode(params) + payload = Util.encode_parameters(params) end end @@ -205,10 +205,9 @@ module Stripe "uname lookup failed" end - + # DEPRECATED. Use `Util#encode_parameters` instead. def self.uri_encode(params) - Util.flatten_params(params). - map { |k,v| "#{k}=#{Util.url_encode(v)}" }.join('&') + Util.encode_parameters(params) end def self.request_headers(api_key) diff --git a/lib/stripe/util.rb b/lib/stripe/util.rb index eab1b3aa..3dd40bb7 100644 --- a/lib/stripe/util.rb +++ b/lib/stripe/util.rb @@ -92,6 +92,15 @@ module Stripe 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) URI.escape(key.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]")) end diff --git a/test/stripe/util_test.rb b/test/stripe/util_test.rb index a7c4f91a..e60f8abf 100644 --- a/test/stripe/util_test.rb +++ b/test/stripe/util_test.rb @@ -2,7 +2,40 @@ require File.expand_path('../../test_helper', __FILE__) module Stripe 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 = { 'foo' => 'bar', 'array' => [{ 'foo' => 'bar' }], @@ -26,7 +59,7 @@ module Stripe assert_equal(finish, symbolized) 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(:api_key => nil) } end