stripe 3.11.0 → 3.12.0

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
- SHA256:
3
- metadata.gz: 981d54e75ed0dc6a6c6e9134cbf338a2d8ed02e7169afc93f37c5c65d1e23955
4
- data.tar.gz: 844de1199f90a2e1eb32f2a011fda913b0ee3c799cd670c8dd42d441d0135805
2
+ SHA1:
3
+ metadata.gz: 78c2ddb890e46edf9e8e3d9b726ea6799d3aea52
4
+ data.tar.gz: ac32ac6e198a21dc2dd448a00601801d604e56fb
5
5
  SHA512:
6
- metadata.gz: 7890d0984cb8d83aec246a5fe745f2e57343e1b1c256343e79c49f35479de9cbafd90046dd00b537339a6b08257eb9dd39a1aa96f420059d5596584f7f2b7bd5
7
- data.tar.gz: 371d48d97dedf110422c91e70b25be7aa092576f55e87d5b1cf3e3d336b847ff9e0000fa18bd5f234459f33dd9b5826a7400fc53c7ac8939ac42de3c831220f3
6
+ metadata.gz: df6c4329f75ef7bb548630cc4d097d900b2a006c45d14c9bdea8884c9d27ccf7cfe746c302bc8e14bff25dc02c5a1d6b9f10967c97f86aa29628d6cfe0bcc5dd
7
+ data.tar.gz: 1e467d30f83de17b389f656343e90f5f9725e769e16b2c54fa755e8767cb7c13bb81d375f2671dccf8831d2d0a73f3a505939c3861860d9ecadf153a006d9d7d
@@ -22,7 +22,7 @@ Metrics/ClassLength:
22
22
 
23
23
  # Offense count: 11
24
24
  Metrics/CyclomaticComplexity:
25
- Max: 13
25
+ Max: 15
26
26
 
27
27
  # Offense count: 259
28
28
  # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
@@ -47,7 +47,7 @@ Metrics/ParameterLists:
47
47
 
48
48
  # Offense count: 5
49
49
  Metrics/PerceivedComplexity:
50
- Max: 15
50
+ Max: 17
51
51
 
52
52
  # Offense count: 2
53
53
  Style/ClassVars:
@@ -1,5 +1,8 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.12.0 - 2018-04-05
4
+ * [#632](https://github.com/stripe/stripe-ruby/pull/632) Introduce `additive_object_param` so that non-`metadata` subobjects don't zero their keys as they're being replaced
5
+
3
6
  ## 3.11.0 - 2018-02-26
4
7
  * [#628](https://github.com/stripe/stripe-ruby/pull/628) Add support for `code` attribute on all Stripe exceptions
5
8
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.11.0
1
+ 3.12.0
@@ -62,6 +62,15 @@ module Stripe
62
62
  end
63
63
 
64
64
  def self.included(base)
65
+ # Set `metadata` as additive so that when it's set directly we remember
66
+ # to clear keys that may have been previously set by sending empty
67
+ # values for them.
68
+ #
69
+ # It's possible that not every object with `Save` has `metadata`, but
70
+ # it's a close enough heuristic, and having this option set when there
71
+ # is no `metadata` field is not harmful.
72
+ base.additive_object_param(:metadata)
73
+
65
74
  base.extend(ClassMethods)
66
75
  end
67
76
 
@@ -7,6 +7,66 @@ module Stripe
7
7
  # The default :id method is deprecated and isn't useful to us
8
8
  undef :id if method_defined?(:id)
9
9
 
10
+ # Sets the given parameter name to one which is known to be an additive
11
+ # object.
12
+ #
13
+ # Additive objects are subobjects in the API that don't have the same
14
+ # semantics as most subobjects, which are fully replaced when they're set.
15
+ # This is best illustrated by example. The `source` parameter sent when
16
+ # updating a subscription is *not* additive; if we set it:
17
+ #
18
+ # source[object]=card&source[number]=123
19
+ #
20
+ # We expect the old `source` object to have been overwritten completely. If
21
+ # the previous source had an `address_state` key associated with it and we
22
+ # didn't send one this time, that value of `address_state` is gone.
23
+ #
24
+ # By contrast, additive objects are those that will have new data added to
25
+ # them while keeping any existing data in place. The only known case of its
26
+ # use is for `metadata`, but it could in theory be more general. As an
27
+ # example, say we have a `metadata` object that looks like this on the
28
+ # server side:
29
+ #
30
+ # metadata = { old: "old_value" }
31
+ #
32
+ # If we update the object with `metadata[new]=new_value`, the server side
33
+ # object now has *both* fields:
34
+ #
35
+ # metadata = { old: "old_value", new: "new_value" }
36
+ #
37
+ # This is okay in itself because usually users will want to treat it as
38
+ # additive:
39
+ #
40
+ # obj.metadata[:new] = "new_value"
41
+ # obj.save
42
+ #
43
+ # However, in other cases, they may want to replace the entire existing
44
+ # contents:
45
+ #
46
+ # obj.metadata = { new: "new_value" }
47
+ # obj.save
48
+ #
49
+ # This is where things get a little bit tricky because in order to clear
50
+ # any old keys that may have existed, we actually have to send an explicit
51
+ # empty string to the server. So the operation above would have to send
52
+ # this form to get the intended behavior:
53
+ #
54
+ # metadata[old]=&metadata[new]=new_value
55
+ #
56
+ # This method allows us to track which parameters are considered additive,
57
+ # and lets us behave correctly where appropriate when serializing
58
+ # parameters to be sent.
59
+ def self.additive_object_param(name)
60
+ @additive_params ||= Set.new
61
+ @additive_params << name
62
+ end
63
+
64
+ # Returns whether the given name is an additive object parameter. See
65
+ # `.additive_object_param` for details.
66
+ def self.additive_object_param?(name)
67
+ !@additive_params.nil? && @additive_params.include?(name)
68
+ end
69
+
10
70
  def initialize(id = nil, opts = {})
11
71
  id, @retrieve_params = Util.normalize_id(id)
12
72
  @opts = Util.normalize_opts(opts)
@@ -410,10 +470,14 @@ module Stripe
410
470
  elsif value.is_a?(StripeObject)
411
471
  update = value.serialize_params(force: force)
412
472
 
413
- # If the entire object was replaced, then we need blank each field of
414
- # the old object that held a value. The new serialized values will
415
- # override any of these empty values.
416
- update = empty_values(original).merge(update) if original && unsaved
473
+ # If the entire object was replaced and this is an additive object,
474
+ # then we need blank each field of the old object that held a value
475
+ # because otherwise the update to the keys of the object will be
476
+ # additive instead of a full replacement. The new serialized values
477
+ # will override any of these empty values.
478
+ if original && unsaved && key && self.class.additive_object_param?(key)
479
+ update = empty_values(original).merge(update)
480
+ end
417
481
 
418
482
  update
419
483
 
@@ -25,13 +25,8 @@ module Stripe
25
25
  end
26
26
 
27
27
  def serialize_params(options = {})
28
- update_hash = super
29
- if @unsaved_values.include?(:items)
30
- value = Util.array_to_hash(@values[:items])
31
- update_hash[:items] =
32
- serialize_params_value(value, nil, true, options[:force], key: :items)
33
- end
34
- update_hash
28
+ @values[:items] = Util.array_to_hash(@values[:items]) if @values[:items]
29
+ super
35
30
  end
36
31
 
37
32
  private
@@ -1,3 +1,3 @@
1
1
  module Stripe
2
- VERSION = "3.11.0".freeze
2
+ VERSION = "3.12.0".freeze
3
3
  end
@@ -303,12 +303,27 @@ module Stripe
303
303
  assert_equal({ foo: "bar" }, serialized[:metadata])
304
304
  end
305
305
 
306
- should "#serialize_params with a StripeObject that's been replaced" do
307
- obj = Stripe::StripeObject.construct_from(metadata: Stripe::StripeObject.construct_from(bar: "foo"))
306
+ should "#serialize_params with StripeObject that's been replaced" do
307
+ obj = Stripe::StripeObject.construct_from(source: Stripe::StripeObject.construct_from(bar: "foo"))
308
308
 
309
- # Here we replace the object wholesale which means that the client must
310
- # be able to blank out the values that were in the old object, but which
311
- # are no longer present in the new one.
309
+ # Here we replace the object wholesale.
310
+ obj.source =
311
+ Stripe::StripeObject.construct_from(baz: "foo")
312
+
313
+ serialized = obj.serialize_params
314
+ assert_equal({ baz: "foo" }, serialized[:source])
315
+ end
316
+
317
+ should "#serialize_params with StripeObject that's been replaced which is `metadata`" do
318
+ class WithAdditiveObjectParam < Stripe::StripeObject
319
+ additive_object_param :metadata
320
+ end
321
+
322
+ obj = WithAdditiveObjectParam.construct_from(metadata: Stripe::StripeObject.construct_from(bar: "foo"))
323
+
324
+ # Here we replace the object wholesale. Because it's `metadata`, the
325
+ # client must be able to blank out the values that were in the old
326
+ # object, but which are no longer present in the new one.
312
327
  obj.metadata =
313
328
  Stripe::StripeObject.construct_from(baz: "foo")
314
329
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stripe
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.11.0
4
+ version: 3.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stripe
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-02-26 00:00:00.000000000 Z
11
+ date: 2018-04-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -184,7 +184,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
184
184
  version: '0'
185
185
  requirements: []
186
186
  rubyforge_project:
187
- rubygems_version: 2.7.6
187
+ rubygems_version: 2.6.14
188
188
  signing_key:
189
189
  specification_version: 4
190
190
  summary: Ruby bindings for the Stripe API