Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix encoding of list params for bank accounts and cards #633

Merged
merged 1 commit into from
Jul 24, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions bankaccount.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ type BankAccountListParams struct {
Customer *string `form:"-"`
}

func (p *BankAccountListParams) AppendTo(body *form.Values, keyParts []string) {
body.Add(form.FormatKey(append(keyParts, "object")), "bank_account")
}

// BankAccount represents a Stripe bank account.
type BankAccount struct {
AccountHolderName string `json:"account_holder_name"`
Expand Down
8 changes: 6 additions & 2 deletions bankaccount/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,13 +135,17 @@ func (c Client) List(listParams *stripe.BankAccountListParams) *Iter {
var path string
var outerErr error

// There's no bank accounts list URL, so we use one sources or external
// accounts. An override on BankAccountListParam's `AppendTo` will add the
// filter `object=bank_account` to make sure that only bank accounts come
// back with the response.
if listParams == nil {
outerErr = errors.New("params should not be nil")
} else if listParams.Customer != nil {
path = stripe.FormatURLPath("/customers/%s/sources?object=bank_account",
path = stripe.FormatURLPath("/customers/%s/sources",
stripe.StringValue(listParams.Customer))
} else if listParams.Account != nil {
path = stripe.FormatURLPath("/accounts/%s/external_accounts?object=bank_account",
path = stripe.FormatURLPath("/accounts/%s/external_accounts",
stripe.StringValue(listParams.Account))
} else {
outerErr = errors.New("Invalid bank account params: either Customer or Account need to be set")
Expand Down
20 changes: 20 additions & 0 deletions bankaccount_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,26 @@ func TestBankAccount_UnmarshalJSON(t *testing.T) {
}
}

func TestBankAccountListParams_AppendTo(t *testing.T) {
// Adds `object` for account (this will hit the customer sources endpoint)
{
params := &BankAccountListParams{Account: String("acct_123")}
body := &form.Values{}
form.AppendTo(body, params)
t.Logf("body = %+v", body)
assert.Equal(t, []string{"bank_account"}, body.Get("object"))
}

// Adds `object` for customer (this will hit the external accounts endpoint)
{
params := &BankAccountListParams{Customer: String("cus_123")}
body := &form.Values{}
form.AppendTo(body, params)
t.Logf("body = %+v", body)
assert.Equal(t, []string{"bank_account"}, body.Get("object"))
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should you be testing Account and Customer like you do for cards?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I skipped it because the same conditional branch just adds object regardless of the circumstances, but I guess it can't hurt to be explicit. Broke it into two test cases like cards.

}

func TestBankAccountParams_AppendToAsSourceOrExternalAccount(t *testing.T) {
// We should add more tests for all the various corner cases here ...

Expand Down
6 changes: 6 additions & 0 deletions card.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,12 @@ type CardListParams struct {
Recipient *string `form:"-"`
}

func (p *CardListParams) AppendTo(body *form.Values, keyParts []string) {
if p.Account != nil || p.Customer != nil {
body.Add(form.FormatKey(append(keyParts, "object")), "card")
}
}

// Card is the resource representing a Stripe credit/debit card.
// For more details see https://stripe.com/docs/api#cards.
type Card struct {
Expand Down
7 changes: 5 additions & 2 deletions card/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,13 +152,16 @@ func (c Client) List(listParams *stripe.CardListParams) *Iter {
var path string
var outerErr error

// Because the external accounts and sources endpoints can return non-card
// objects, CardListParam's `AppendTo` will add the filter `object=card` to
// make sure that only cards come back with the response.
if listParams == nil {
outerErr = errors.New("params should not be nil")
} else if listParams.Account != nil {
path = stripe.FormatURLPath("/accounts/%s/external_accounts?object=card",
path = stripe.FormatURLPath("/accounts/%s/external_accounts",
stripe.StringValue(listParams.Account))
} else if listParams.Customer != nil {
path = stripe.FormatURLPath("/customers/%s/sources?object=card",
path = stripe.FormatURLPath("/customers/%s/sources",
stripe.StringValue(listParams.Customer))
} else if listParams.Recipient != nil {
path = stripe.FormatURLPath("/recipients/%s/cards", stripe.StringValue(listParams.Recipient))
Expand Down
31 changes: 31 additions & 0 deletions card_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,39 @@ import (
"testing"

assert "github.com/stretchr/testify/require"
"github.com/stripe/stripe-go/form"
)

func TestCardListParams_AppendTo(t *testing.T) {
// Adds `object` for account (this will hit the external accounts endpoint)
{
params := &CardListParams{Account: String("acct_123")}
body := &form.Values{}
form.AppendTo(body, params)
t.Logf("body = %+v", body)
assert.Equal(t, []string{"card"}, body.Get("object"))
}

// Adds `object` for customer (this will hit the sources endpoint)
{
params := &CardListParams{Customer: String("cus_123")}
body := &form.Values{}
form.AppendTo(body, params)
t.Logf("body = %+v", body)
assert.Equal(t, []string{"card"}, body.Get("object"))
}

// *Doesn't* add `object` for recipient (this will hit the recipient cards
// endpoint, so all possible resources are cards)
{
params := &CardListParams{Recipient: String("rp_123")}
body := &form.Values{}
form.AppendTo(body, params)
t.Logf("body = %+v", body)
assert.Equal(t, []string(nil), body.Get("object"))
}
}

func TestCard_UnmarshalJSON(t *testing.T) {
// Unmarshals from a JSON string
{
Expand Down