Skip to content

Commit

Permalink
Revert "Remove legal_entity which is no longer part of the Account API (
Browse files Browse the repository at this point in the history
#1364)"

This reverts commit 8f78a41.
  • Loading branch information
ramya-stripe committed Apr 10, 2024
1 parent 94bbe75 commit aa09915
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 19 deletions.
51 changes: 51 additions & 0 deletions lib/stripe/resources/account.rb
Original file line number Diff line number Diff line change
Expand Up @@ -192,12 +192,32 @@ def serialize_params(options = {})
end

def serialize_params_account(_obj, update_hash, options = {})
if (entity = @values[:legal_entity]) && (owners = entity[:additional_owners])
entity_update = update_hash[:legal_entity] ||= {}
entity_update[:additional_owners] =
serialize_additional_owners(entity, owners)
end
if (individual = @values[:individual]) && (individual.is_a?(Person) && !update_hash.key?(:individual))
update_hash[:individual] = individual.serialize_params(options)
end
update_hash
end

def self.protected_fields
[:legal_entity]
end

def legal_entity
self["legal_entity"]
end

def legal_entity=(_legal_entity)
raise NoMethodError,
"Overriding legal_entity can cause serious issues. Instead, set " \
"the individual fields of legal_entity like " \
"`account.legal_entity.first_name = 'Blah'`"
end

def deauthorize(client_id = nil, opts = {})
params = {
client_id: client_id,
Expand All @@ -206,5 +226,36 @@ def deauthorize(client_id = nil, opts = {})
opts = @opts.merge(Util.normalize_opts(opts))
OAuth.deauthorize(params, opts)
end

private def serialize_additional_owners(legal_entity, additional_owners)
original_value =
legal_entity
.instance_variable_get(:@original_values)[:additional_owners]
if original_value && original_value.length > additional_owners.length
# url params provide no mechanism for deleting an item in an array,
# just overwriting the whole array or adding new items. So let's not
# allow deleting without a full overwrite until we have a solution.
raise ArgumentError,
"You cannot delete an item from an array, you must instead " \
"set a new array"
end

update_hash = {}
additional_owners.each_with_index do |v, i|
# We will almost always see a StripeObject except in the case of a Hash
# that's been appended to an array of `additional_owners`. We may be
# able to normalize that ugliness by using an array proxy object with
# StripeObjects that can detect appends and replace a hash with a
# StripeObject.
update = v.is_a?(StripeObject) ? v.serialize_params : v

next unless update != {} && (!original_value ||
update != legal_entity.serialize_params_value(original_value[i], nil,
false, true))

update_hash[i.to_s] = update
end
update_hash
end
end
end
101 changes: 101 additions & 0 deletions test/stripe/account_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,108 @@ class AccountTest < Test::Unit::TestCase
end
end

context "#legal_entity=" do
should "disallow direct overrides" do
account = Stripe::Account.construct_from(
id: "acct_123",
legal_entity: {
first_name: "name",
}
)

assert_raise NoMethodError do
account.legal_entity = { first_name: "Blah" }
end

account.legal_entity.first_name = "Blah"
end
end

context "#serialize_params" do
should "serialize a new additional_owners" do
obj = Stripe::Util.convert_to_stripe_object({
object: "account",
legal_entity: Stripe::StripeObject.construct_from({}),
}, {})
obj.legal_entity.additional_owners = [
{ first_name: "Joe" },
{ first_name: "Jane" },
]

expected = {
legal_entity: {
additional_owners: {
"0" => { first_name: "Joe" },
"1" => { first_name: "Jane" },
},
},
}
assert_equal(expected, obj.serialize_params)
end

should "serialize on an partially changed additional_owners" do
obj = Stripe::Util.convert_to_stripe_object({
object: "account",
legal_entity: {
additional_owners: [
Stripe::StripeObject.construct_from(first_name: "Joe"),
Stripe::StripeObject.construct_from(first_name: "Jane"),
],
},
}, {})
obj.legal_entity.additional_owners[1].first_name = "Stripe"

expected = {
legal_entity: {
additional_owners: {
"1" => { first_name: "Stripe" },
},
},
}
assert_equal(expected, obj.serialize_params)
end

should "serialize on an unchanged additional_owners" do
obj = Stripe::Util.convert_to_stripe_object({
object: "account",
legal_entity: {
additional_owners: [
Stripe::StripeObject.construct_from(first_name: "Joe"),
Stripe::StripeObject.construct_from(first_name: "Jane"),
],
},
}, {})

expected = {
legal_entity: {
additional_owners: {},
},
}
assert_equal(expected, obj.serialize_params)
end

# Note that the empty string that we send for this one has a special
# meaning for the server, which interprets it as an array unset.
should "serialize on an unset additional_owners" do
obj = Stripe::Util.convert_to_stripe_object({
object: "account",
legal_entity: {
additional_owners: [
Stripe::StripeObject.construct_from(first_name: "Joe"),
Stripe::StripeObject.construct_from(first_name: "Jane"),
],
},
}, {})
obj.legal_entity.additional_owners = nil

expected = {
legal_entity: {
additional_owners: "",
},
}
assert_equal(expected, obj.serialize_params)
end

should "serialize on a new individual" do
obj = Stripe::Util.convert_to_stripe_object({
object: "account",
Expand Down
40 changes: 21 additions & 19 deletions test/stripe/api_resource_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -413,15 +413,17 @@ class NestedTestAPIResource < APIResource

should "add key to nested objects on save" do
acct = Stripe::Account.construct_from(id: "myid",
capabilities: {
card_payments: "inactive",
legal_entity: {
size: "l",
score: 4,
height: 10,
})

stub_request(:post, "#{Stripe.api_base}/v1/accounts/myid")
.with(body: { capabilities: { transfers: "inactive" } })
.with(body: { legal_entity: { first_name: "Bob" } })
.to_return(body: JSON.generate("id" => "myid"))

acct.capabilities.transfers = "inactive"
acct.legal_entity.first_name = "Bob"
acct.save
end

Expand Down Expand Up @@ -483,54 +485,54 @@ class NestedTestAPIResource < APIResource

should "correctly handle array setting on save" do
acct = Stripe::Account.construct_from(id: "myid",
external_accounts: {})
legal_entity: {})

stub_request(:post, "#{Stripe.api_base}/v1/accounts/myid")
.with(body: { external_accounts: { data: [{ id: "1234" }] } })
.with(body: { legal_entity: { additional_owners: [{ first_name: "Bob" }] } })
.to_return(body: JSON.generate("id" => "myid"))

acct.external_accounts.data = [{ id: "1234" }]
acct.legal_entity.additional_owners = [{ first_name: "Bob" }]
acct.save
end

should "correctly handle array insertion on save" do
acct = Stripe::Account.construct_from(id: "myid",
external_accounts: {
data: [],
legal_entity: {
additional_owners: [],
})

# Note that this isn't a perfect check because we're using webmock's
# data decoding, which isn't aware of the Stripe array encoding that we
# use here.
stub_request(:post, "#{Stripe.api_base}/v1/accounts/myid")
.with(body: { external_accounts: { data: [{ id: "1234" }] } })
.with(body: { legal_entity: { additional_owners: [{ first_name: "Bob" }] } })
.to_return(body: JSON.generate("id" => "myid"))

acct.external_accounts.data << { id: "1234" }
acct.legal_entity.additional_owners << { first_name: "Bob" }
acct.save
end

should "correctly handle array updates on save" do
acct = Stripe::Account.construct_from(id: "myid",
external_accounts: {
data: [{ account: "1234" }, { account: "5678" }],
legal_entity: {
additional_owners: [{ first_name: "Bob" }, { first_name: "Jane" }],
})

# Note that this isn't a perfect check because we're using webmock's
# data decoding, which isn't aware of the Stripe array encoding that we
# use here.
stub_request(:post, "#{Stripe.api_base}/v1/accounts/myid")
.with(body: { external_accounts: { data: [{ account: "56789" }] } })
.with(body: { legal_entity: { additional_owners: [{ first_name: "Janet" }] } })
.to_return(body: JSON.generate("id" => "myid"))

acct.external_accounts.data[1].account = "56789"
acct.legal_entity.additional_owners[1].first_name = "Janet"
acct.save
end

should "correctly handle array noops on save" do
acct = Stripe::Account.construct_from(id: "myid",
external_accounts: {
data: [{ id: "Bob" }],
legal_entity: {
additional_owners: [{ first_name: "Bob" }],
},
currencies_supported: %w[usd cad])

Expand All @@ -543,8 +545,8 @@ class NestedTestAPIResource < APIResource

should "correctly handle hash noops on save" do
acct = Stripe::Account.construct_from(id: "myid",
settings: {
bacs_debit_payments: { display_name: "1 Two Three" },
legal_entity: {
address: { line1: "1 Two Three" },
})

stub_request(:post, "#{Stripe.api_base}/v1/accounts/myid")
Expand Down

0 comments on commit aa09915

Please sign in to comment.