stripe 1.30.2 → 1.30.3

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.
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: