stripe 1.30.2 → 1.30.3

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: a832c74b94a7a2346a38e3053363aa80f31b04d5
4
- data.tar.gz: 2b0d72e9641fdde9d3a4db16e39407ceb33ecd6b
3
+ metadata.gz: 57a7cdc2de64371c76c7f0a74cc2b179819a6589
4
+ data.tar.gz: 3d3f0155191a28d7cda3ae40f9551880d0c63f73
5
5
  SHA512:
6
- metadata.gz: 019e999e649b2f9e39dd0a900aec1b0b44ff19a740ea37663f67ca77749fc93f540b7c4c588e47e30ba050be9ffaca7a8e7d43ccbd518c1781bcc92c077fa3e7
7
- data.tar.gz: 692e479177426a0b3974ffa7ed6d5725e01b40ddd61afd0c42fe133b764a0f6b3201afb387f8f17efe7a7d66ed1e5e06e892f21c37a88fc172cdde4d4a3b3700
6
+ metadata.gz: 57b53ee9cce83fa1bd0a8e78b548594239799e46a1105dbda7d67d33302b7578bbc33280416f78058bc112808a49ea3a57e7e0fd42104fb331b82383832158a7
7
+ data.tar.gz: 804c78f9c635f021c6e8dec7c1c78a16c9ddf4b43ac81f60782ecec1c247bacd6bd9fd21a6b5b563eb12f815ee5d96b0b16fbe6ecaf8e31251a74a67e3290997
@@ -1,3 +1,7 @@
1
+ === 1.30.3 2015-10-28
2
+
3
+ * Fix bug where arrays that were not `additional_owners` were not properly encoded for requests
4
+
1
5
  === 1.30.2 2015-10-12
2
6
 
3
7
  * Fix bug where `opts` didn't properly propagate to descendant `StripeObjects`
@@ -1,5 +1,20 @@
1
1
  = Stripe Ruby bindings {<img src="https://travis-ci.org/stripe/stripe-ruby.svg?branch=master" alt="Build Status" />}[https://travis-ci.org/stripe/stripe-ruby]
2
2
 
3
+ The Stripe Ruby bindings provide a small SDK for convenient access to the
4
+ Stripe API from applications written in the Ruby language. It provides a
5
+ pre-defined set of classes for API resources that initialize themselves
6
+ dynamically from API responses which allows the bindings to tolerate a number
7
+ of different versions of the API.
8
+
9
+ The bindings also provide other features. For example:
10
+
11
+ * Easy configuration path for fast setup and use.
12
+ * Helpers for pagination.
13
+ * Tracking of "fresh" values in API resources so that partial updates can be
14
+ executed.
15
+ * Built-in mechanisms for the serialization of parameters according to the
16
+ expectations of Stripe's API.
17
+
3
18
  == Documentation
4
19
 
5
20
  {Ruby API Docs}[https://stripe.com/docs/api/ruby#intro]
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.30.2
1
+ 1.30.3
@@ -16,17 +16,56 @@ module Stripe
16
16
  # @override To make id optional
17
17
  def self.retrieve(id=ARGUMENT_NOT_PROVIDED, opts={})
18
18
  id = id.equal?(ARGUMENT_NOT_PROVIDED) ? nil : Util.check_string_argument!(id)
19
- # Account used to be a singleton, where this method's signature was `(opts={})`.
20
- # For the sake of not breaking folks who pass in an OAuth key in opts, let's lurkily
21
- # string match for it.
19
+
20
+ # Account used to be a singleton, where this method's signature was
21
+ # `(opts={})`. For the sake of not breaking folks who pass in an OAuth
22
+ # key in opts, let's lurkily string match for it.
22
23
  if opts == {} && id.is_a?(String) && id.start_with?('sk_')
23
24
  # `super` properly assumes a String opts is the apiKey and normalizes as expected.
24
25
  opts = id
25
26
  id = nil
26
27
  end
28
+
27
29
  super(id, opts)
28
30
  end
29
31
 
32
+ # Somewhat unfortunately, we attempt to do a special encoding trick when
33
+ # serializing `additional_owners` under an account: when updating a value,
34
+ # we actually send the update parameters up as an integer-indexed hash
35
+ # rather than an array. So instead of this:
36
+ #
37
+ # field[]=item1&field[]=item2&field[]=item3
38
+ #
39
+ # We send this:
40
+ #
41
+ # field[0]=item1&field[1]=item2&field[2]=item3
42
+ #
43
+ # There are two major problems with this technique:
44
+ #
45
+ # * Entities are addressed by array index, which is not stable and can
46
+ # easily result in unexpected results between two different requests.
47
+ #
48
+ # * A replacement of the array's contents is ambiguous with setting a
49
+ # subset of the array. Because of this, the only way to shorten an
50
+ # array is to unset it completely by making sure it goes into the
51
+ # server as an empty string, then setting its contents again.
52
+ #
53
+ # We're trying to get this overturned on the server side, but for now,
54
+ # patch in a special allowance.
55
+ def self.serialize_params(obj, original_value=nil)
56
+ update_hash = StripeObject.serialize_params(obj, original_value)
57
+ case obj
58
+ when StripeObject
59
+ obj_values = obj.instance_variable_get(:@values)
60
+ obj_values.each do |k, v|
61
+ if k == :additional_owners && v.is_a?(Array)
62
+ update_hash[k] = serialize_additional_owners(obj, v)
63
+ end
64
+ end
65
+ end
66
+ update_hash
67
+ end
68
+
30
69
  def protected_fields
31
70
  [:legal_entity]
32
71
  end
@@ -47,5 +86,28 @@ module Stripe
47
86
  end
48
87
 
49
88
  ARGUMENT_NOT_PROVIDED = Object.new
89
+
90
+ private
91
+
92
+ def self.serialize_additional_owners(obj, value)
93
+ original_value = obj.instance_variable_get(:@original_values)[:additional_owners]
94
+ if original_value && original_value.length > value.length
95
+ # url params provide no mechanism for deleting an item in an array,
96
+ # just overwriting the whole array or adding new items. So let's not
97
+ # allow deleting without a full overwrite until we have a solution.
98
+ raise ArgumentError.new(
99
+ "You cannot delete an item from an array, you must instead set a new array"
100
+ )
101
+ end
102
+
103
+ update_hash = {}
104
+ value.each_with_index do |v, i|
105
+ update = StripeObject.serialize_params(v)
106
+ if update != {} && (!original_value || update != original_value[i])
107
+ update_hash[i.to_s] = update
108
+ end
109
+ end
110
+ update_hash
111
+ end
50
112
  end
51
113
  end
@@ -170,6 +170,13 @@ module Stripe
170
170
  case obj
171
171
  when nil
172
172
  ''
173
+ when Array
174
+ update = obj.map { |v| serialize_params(v) }
175
+ if original_value != update
176
+ update
177
+ else
178
+ nil
179
+ end
173
180
  when StripeObject
174
181
  unsaved_keys = obj.instance_variable_get(:@unsaved_values)
175
182
  obj_values = obj.instance_variable_get(:@values)
@@ -180,37 +187,23 @@ module Stripe
180
187
  end
181
188
 
182
189
  obj_values.each do |k, v|
183
- if v.is_a?(StripeObject) || v.is_a?(Hash)
184
- update_hash[k] = obj.serialize_nested_object(k)
185
- elsif v.is_a?(Array)
186
- original_value = obj.instance_variable_get(:@original_values)[k]
187
- if original_value && original_value.length > v.length
188
- # url params provide no mechanism for deleting an item in an array,
189
- # just overwriting the whole array or adding new items. So let's not
190
- # allow deleting without a full overwrite until we have a solution.
191
- raise ArgumentError.new(
192
- "You cannot delete an item from an array, you must instead set a new array"
193
- )
194
- end
195
- update_hash[k] = serialize_params(v, original_value)
190
+ if v.is_a?(Array)
191
+ original_value = obj.instance_variable_get(:@original_values)[k]
192
+
193
+ # the conditional here tests whether the old and new values are
194
+ # different (and therefore needs an update), or the same (meaning
195
+ # we can leave it out of the request)
196
+ if updated = serialize_params(v, original_value)
197
+ update_hash[k] = updated
198
+ else
199
+ update_hash.delete(k)
200
+ end
201
+ elsif v.is_a?(StripeObject) || v.is_a?(Hash)
202
+ update_hash[k] = obj.serialize_nested_object(k)
196
203
  end
197
204
  end
198
205
 
199
206
  update_hash
200
- when Array
201
- update_hash = {}
202
- obj.each_with_index do |value, index|
203
- update = serialize_params(value)
204
- if update != {} && (!original_value || update != original_value[index])
205
- update_hash[index] = update
206
- end
207
- end
208
-
209
- if update_hash == {}
210
- nil
211
- else
212
- update_hash
213
- end
214
207
  else
215
208
  obj
216
209
  end
@@ -116,7 +116,10 @@ module Stripe
116
116
 
117
117
  def self.flatten_params(params, parent_key=nil)
118
118
  result = []
119
- params.each do |key, value|
119
+
120
+ # do not sort the final output because arrays (and arrays of hashes
121
+ # especially) can be order sensitive, but do sort incoming parameters
122
+ params.sort_by { |(k, v)| k.to_s }.each do |key, value|
120
123
  calculated_key = parent_key ? "#{parent_key}[#{key}]" : "#{key}"
121
124
  if value.is_a?(Hash)
122
125
  result += flatten_params(value, calculated_key)
@@ -1,3 +1,3 @@
1
1
  module Stripe
2
- VERSION = '1.30.2'
2
+ VERSION = '1.30.3'
3
3
  end
@@ -20,6 +20,14 @@ spec = Gem::Specification.new do |s|
20
20
  s.add_development_dependency('test-unit')
21
21
  s.add_development_dependency('rake')
22
22
 
23
+ # to avoid problems, bring Byebug in on just versions of Ruby under which
24
+ # it's known to work well
25
+ if Gem::Version.new(RUBY_VERSION.dup) >= Gem::Version.new('2.0.0')
26
+ s.add_development_dependency("byebug")
27
+ s.add_development_dependency("pry")
28
+ s.add_development_dependency("pry-byebug")
29
+ end
30
+
23
31
  s.files = `git ls-files`.split("\n")
24
32
  s.test_files = `git ls-files -- test/*`.split("\n")
25
33
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
@@ -68,7 +68,7 @@ module Stripe
68
68
 
69
69
  @mock.expects(:post).
70
70
  once.
71
- with('https://api.stripe.com/v1/accounts/acct_foo', nil, 'legal_entity[first_name]=Bob&legal_entity[address][line1]=2+Three+Four').
71
+ with('https://api.stripe.com/v1/accounts/acct_foo', nil, 'legal_entity[address][line1]=2+Three+Four&legal_entity[first_name]=Bob').
72
72
  returns(make_response(resp))
73
73
 
74
74
  a = Stripe::Account.retrieve('acct_foo')
@@ -151,5 +151,102 @@ module Stripe
151
151
  a = Stripe::Account.retrieve
152
152
  assert_equal(BankAccount, a.external_accounts.data[0].class)
153
153
  end
154
+
155
+ should "#serialize_params an a new additional_owners" do
156
+ obj = Stripe::Util.convert_to_stripe_object({
157
+ :object => "account",
158
+ :legal_entity => {
159
+ },
160
+ }, {})
161
+ obj.legal_entity.additional_owners = [
162
+ { :first_name => "Joe" },
163
+ { :first_name => "Jane" },
164
+ ]
165
+
166
+ expected = {
167
+ :legal_entity => {
168
+ :additional_owners => {
169
+ "0" => { :first_name => "Joe" },
170
+ "1" => { :first_name => "Jane" },
171
+ }
172
+ }
173
+ }
174
+ assert_equal(expected, obj.class.serialize_params(obj))
175
+ end
176
+
177
+ should "#serialize_params on an partially changed additional_owners" do
178
+ obj = Stripe::Util.convert_to_stripe_object({
179
+ :object => "account",
180
+ :legal_entity => {
181
+ :additional_owners => [
182
+ Stripe::StripeObject.construct_from({
183
+ :first_name => "Joe"
184
+ }),
185
+ Stripe::StripeObject.construct_from({
186
+ :first_name => "Jane"
187
+ }),
188
+ ]
189
+ }
190
+ }, {})
191
+ obj.legal_entity.additional_owners[1].first_name = "Stripe"
192
+
193
+ expected = {
194
+ :legal_entity => {
195
+ :additional_owners => {
196
+ "1" => { :first_name => "Stripe" }
197
+ }
198
+ }
199
+ }
200
+ assert_equal(expected, obj.class.serialize_params(obj))
201
+ end
202
+
203
+ should "#serialize_params on an unchanged additional_owners" do
204
+ obj = Stripe::Util.convert_to_stripe_object({
205
+ :object => "account",
206
+ :legal_entity => {
207
+ :additional_owners => [
208
+ Stripe::StripeObject.construct_from({
209
+ :first_name => "Joe"
210
+ }),
211
+ Stripe::StripeObject.construct_from({
212
+ :first_name => "Jane"
213
+ }),
214
+ ]
215
+ }
216
+ }, {})
217
+
218
+ expected = {
219
+ :legal_entity => {
220
+ :additional_owners => {}
221
+ }
222
+ }
223
+ assert_equal(expected, obj.class.serialize_params(obj))
224
+ end
225
+
226
+ # Note that the empty string that we send for this one has a special
227
+ # meaning for the server, which interprets it as an array unset.
228
+ should "#serialize_params on an unset additional_owners" do
229
+ obj = Stripe::Util.convert_to_stripe_object({
230
+ :object => "account",
231
+ :legal_entity => {
232
+ :additional_owners => [
233
+ Stripe::StripeObject.construct_from({
234
+ :first_name => "Joe"
235
+ }),
236
+ Stripe::StripeObject.construct_from({
237
+ :first_name => "Jane"
238
+ }),
239
+ ]
240
+ }
241
+ }, {})
242
+ obj.legal_entity.additional_owners = nil
243
+
244
+ expected = {
245
+ :legal_entity => {
246
+ :additional_owners => ""
247
+ }
248
+ }
249
+ assert_equal(expected, obj.class.serialize_params(obj))
250
+ end
154
251
  end
155
252
  end
@@ -60,7 +60,7 @@ module Stripe
60
60
 
61
61
  if is_greater_than_ruby_1_9?
62
62
  check_metadata({:metadata => {:initial => 'true'}},
63
- 'metadata[uuid]=6735&metadata[initial]=',
63
+ 'metadata[initial]=&metadata[uuid]=6735',
64
64
  update_actions)
65
65
  end
66
66
  end
@@ -99,5 +99,82 @@ module Stripe
99
99
  # it to something more useful).
100
100
  assert_equal opts, source.instance_variable_get(:@opts)
101
101
  end
102
+
103
+ should "#serialize_params on an empty object" do
104
+ obj = Stripe::StripeObject.construct_from({})
105
+ assert_equal({}, Stripe::StripeObject.serialize_params(obj))
106
+ end
107
+
108
+ should "#serialize_params on a basic object" do
109
+ obj = Stripe::StripeObject.construct_from({ :foo => nil })
110
+ obj.update_attributes(:foo => "bar")
111
+ assert_equal({ :foo => "bar" }, Stripe::StripeObject.serialize_params(obj))
112
+ end
113
+
114
+ should "#serialize_params on a more complex object" do
115
+ obj = Stripe::StripeObject.construct_from({
116
+ :foo => Stripe::StripeObject.construct_from({
117
+ :bar => nil,
118
+ :baz => nil,
119
+ }),
120
+ })
121
+ obj.foo.bar = "newbar"
122
+ assert_equal({ :foo => { :bar => "newbar" } },
123
+ Stripe::StripeObject.serialize_params(obj))
124
+ end
125
+
126
+ should "#serialize_params on an array" do
127
+ obj = Stripe::StripeObject.construct_from({
128
+ :foo => nil,
129
+ })
130
+ obj.foo = ["new-value"]
131
+ assert_equal({ :foo => ["new-value"] },
132
+ Stripe::StripeObject.serialize_params(obj))
133
+ end
134
+
135
+ should "#serialize_params on an array that shortens" do
136
+ obj = Stripe::StripeObject.construct_from({
137
+ :foo => ["0-index", "1-index", "2-index"],
138
+ })
139
+ obj.foo = ["new-value"]
140
+ assert_equal({ :foo => ["new-value"] },
141
+ Stripe::StripeObject.serialize_params(obj))
142
+ end
143
+
144
+ should "#serialize_params on an array that lengthens" do
145
+ obj = Stripe::StripeObject.construct_from({
146
+ :foo => ["0-index", "1-index", "2-index"],
147
+ })
148
+ obj.foo = ["new-value"] * 4
149
+ assert_equal({ :foo => ["new-value"] * 4 },
150
+ Stripe::StripeObject.serialize_params(obj))
151
+ end
152
+
153
+ should "#serialize_params on an array of hashes" do
154
+ obj = Stripe::StripeObject.construct_from({
155
+ :foo => nil,
156
+ })
157
+ obj.foo = [
158
+ Stripe::StripeObject.construct_from({
159
+ :bar => nil
160
+ })
161
+ ]
162
+ obj.foo[0].bar = "baz"
163
+ assert_equal({ :foo => [{ :bar => "baz" }] },
164
+ Stripe::StripeObject.serialize_params(obj))
165
+ end
166
+
167
+ should "#serialize_params doesn't include unchanged values" do
168
+ obj = Stripe::StripeObject.construct_from({ :foo => nil })
169
+ assert_equal({}, Stripe::StripeObject.serialize_params(obj))
170
+ end
171
+
172
+ should "#serialize_params on an array that is unchanged" do
173
+ obj = Stripe::StripeObject.construct_from({
174
+ :foo => ["0-index", "1-index", "2-index"],
175
+ })
176
+ obj.foo = ["0-index", "1-index", "2-index"]
177
+ assert_equal({}, Stripe::StripeObject.serialize_params(obj))
178
+ end
102
179
  end
103
180
  end
@@ -10,6 +10,9 @@ module Stripe
10
10
  [:c, "bar&baz"],
11
11
  [:d, { :a => "a", :b => "b" }],
12
12
  [:e, [0, 1]],
13
+
14
+ # note the empty hash won't even show up in the request
15
+ [:f, []]
13
16
  ]
14
17
  assert_equal(
15
18
  "a=3&b=%2Bfoo%3F&c=bar%26baz&d[a]=a&d[b]=b&e[]=0&e[]=1",
@@ -33,8 +36,8 @@ module Stripe
33
36
  [:d, { :a => "a", :b => "b" }],
34
37
  [:e, [0, 1]],
35
38
  [:f, [
36
- { :foo => "1", :bar => "2" },
37
- { :foo => "3", :baz => "4" },
39
+ { :bar => "1", :foo => "2" },
40
+ { :baz => "3", :foo => "4" },
38
41
  ]],
39
42
  ]
40
43
  assert_equal([
@@ -49,10 +52,10 @@ module Stripe
49
52
  # *The key here is the order*. In order to be properly interpreted as
50
53
  # an array of hashes on the server, everything from a single hash must
51
54
  # come in at once. A duplicate key in an array triggers a new element.
52
- ["f[][foo]", "1"],
53
- ["f[][bar]", "2"],
54
- ["f[][foo]", "3"],
55
- ["f[][baz]", "4"],
55
+ ["f[][bar]", "1"],
56
+ ["f[][foo]", "2"],
57
+ ["f[][baz]", "3"],
58
+ ["f[][foo]", "4"],
56
59
  ], Stripe::Util.flatten_params(params))
57
60
  end
58
61
 
@@ -84,5 +87,31 @@ module Stripe
84
87
  assert_raise { Stripe::Util.normalize_opts(nil) }
85
88
  assert_raise { Stripe::Util.normalize_opts(:api_key => nil) }
86
89
  end
90
+
91
+ should "#convert_to_stripe_object should pass through unknown types" do
92
+ obj = Util.convert_to_stripe_object(7, {})
93
+ assert_equal 7, obj
94
+ end
95
+
96
+ should "#convert_to_stripe_object should turn hashes into StripeObjects" do
97
+ obj = Util.convert_to_stripe_object({ :foo => "bar" }, {})
98
+ assert obj.is_a?(StripeObject)
99
+ assert_equal "bar", obj.foo
100
+ end
101
+
102
+ should "#convert_to_stripe_object should turn lists into ListObjects" do
103
+ obj = Util.convert_to_stripe_object({ :object => "list" }, {})
104
+ assert obj.is_a?(ListObject)
105
+ end
106
+
107
+ should "#convert_to_stripe_object should marshal other classes" do
108
+ obj = Util.convert_to_stripe_object({ :object => "account" }, {})
109
+ assert obj.is_a?(Account)
110
+ end
111
+
112
+ should "#convert_to_stripe_object should marshal arrays" do
113
+ obj = Util.convert_to_stripe_object([1, 2, 3], {})
114
+ assert_equal [1, 2, 3], obj
115
+ end
87
116
  end
88
117
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stripe
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.30.2
4
+ version: 1.30.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ross Boucher
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-10-12 00:00:00.000000000 Z
12
+ date: 2015-10-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rest-client
@@ -95,6 +95,48 @@ dependencies:
95
95
  - - ">="
96
96
  - !ruby/object:Gem::Version
97
97
  version: '0'
98
+ - !ruby/object:Gem::Dependency
99
+ name: byebug
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ - !ruby/object:Gem::Dependency
113
+ name: pry
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: pry-byebug
128
+ requirement: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ type: :development
134
+ prerelease: false
135
+ version_requirements: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
98
140
  description: Stripe is the easiest way to accept payments online. See https://stripe.com
99
141
  for details.
100
142
  email: