Skip to content

Commit

Permalink
Upcoming invoices now have proper integer-index-encoded params when s…
Browse files Browse the repository at this point in the history
…ent in the request body
  • Loading branch information
enugent-stripe committed Jun 29, 2018
1 parent 674a1c9 commit ae049ad
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 12 deletions.
4 changes: 2 additions & 2 deletions lib/resources/Invoices.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,19 @@ module.exports = StripeResource.extend({
method: 'GET',
path: function(urlData) {
var url = 'upcoming?customer=' + urlData.customerId;
// Legacy support where second argument is a the subscription id
// Legacy support where second argument is the subscription id
if (urlData.invoiceOptions && typeof urlData.invoiceOptions === 'string') {
return url + '&subscription=' + urlData.invoiceOptions;
} else if (urlData.invoiceOptions && typeof urlData.invoiceOptions === 'object') {
if (urlData.invoiceOptions.subscription_items !== undefined) {
urlData.invoiceOptions.subscription_items = utils.arrayToObject(urlData.invoiceOptions.subscription_items);
}

return url + '&' + utils.stringifyRequestData(urlData.invoiceOptions);
}
return url;
},
urlParams: ['customerId', 'optional!invoiceOptions'],
encode: utils.encodeParamWithIntegerIndexes.bind(null, 'subscription_items'),
}),

});
11 changes: 2 additions & 9 deletions lib/resources/Subscriptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,21 @@ var StripeResource = require('../StripeResource');
var utils = require('../utils');
var stripeMethod = StripeResource.method;

function encode(data) {
if (data.items !== undefined) {
data.items = utils.arrayToObject(data.items);
}
return data;
}

module.exports = StripeResource.extend({

path: 'subscriptions',
includeBasic: ['list', 'retrieve', 'del',],

create: stripeMethod({
method: 'POST',
encode: encode,
encode: utils.encodeParamWithIntegerIndexes.bind(null, 'items'),
}),

update: stripeMethod({
method: 'POST',
path: '{id}',
urlParams: ['id'],
encode: encode,
encode: utils.encodeParamWithIntegerIndexes.bind(null, 'items'),
}),

/**
Expand Down
12 changes: 12 additions & 0 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,18 @@ var utils = module.exports = {
return Constructor;
},

/**
* Encodes a particular param of data, whose value is an array, as an
* object with integer string attributes. Returns the entirety of data
* with just that param modified.
*/
encodeParamWithIntegerIndexes: function(param, data) {
if (data[param] !== undefined) {
data[param] = utils.arrayToObject(data[param]);
}
return data;
},

/**
* Convert an array into an object with integer string attributes
*/
Expand Down
37 changes: 36 additions & 1 deletion test/resources/Invoices.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ describe('Invoices Resource', function() {
});
});

describe('With a options object that includes `subscription_items`', function() {
describe('With an options object that includes `subscription_items`', function() {
it('Sends the correct request', function() {
stripe.invoices.retrieveUpcoming('customerId1', {
subscription_items: [
Expand All @@ -96,6 +96,41 @@ describe('Invoices Resource', function() {
});
});

describe('With an options object that includes `subscription_items` in addition to a subscription ID', function() {
it('Sends the correct request', function() {
stripe.invoices.retrieveUpcoming('customerId1', 'subscriptionID1',
{
subscription_items: [
{plan: 'potato'},
{plan: 'rutabaga'},
{id: 'SOME_ID', deleted: true},
],
subscription_prorate: true,
});

expect(stripe.LAST_REQUEST).to.deep.equal({
method: 'GET',
url: '/v1/invoices/upcoming?customer=customerId1&subscription=subscriptionID1',
headers: {},
data: {
subscription_items: {
0: {
plan: 'potato',
},
1: {
plan: 'rutabaga',
},
2: {
deleted: true,
id: 'SOME_ID',
},
},
subscription_prorate: true,
},
});
});
});

describe('With a options object in addition to a customer ID', function() {
it('Sends the correct request', function() {
stripe.invoices.retrieveUpcoming('customerId1', {plan: 'planId123'});
Expand Down
29 changes: 29 additions & 0 deletions test/utils.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,15 @@ describe('utils', function() {
}))).to.equal('a[][b]=c&a[][b]=d');
})

it('Handles indexed arrays', function() {
expect(decodeURI(utils.stringifyRequestData({
a: {
0: 'c',
1: 'd',
},
}))).to.equal('a[0]=c&a[1]=d');
})

it('Creates a string from an object, handling shallow nested objects', function() {
expect(utils.stringifyRequestData({
test: 1,
Expand Down Expand Up @@ -237,6 +246,26 @@ describe('utils', function() {
});
});

describe('encodeParamWithIntegerIndexes', function() {
it('handles param not existing in data', function() {
var data = {'someParam': ['foo']};
expect(utils.encodeParamWithIntegerIndexes('anotherParam', data)).to.deep.equal(data);
});

it('encodes just the specified param with integer indexes', function() {
var data = {'paramToEncode': ['value1', 'value2'], 'anotherParam': ['foo']};
var expectedData = {'paramToEncode': {'0': 'value1', '1': 'value2'}, 'anotherParam': ['foo']};
expect(utils.encodeParamWithIntegerIndexes('paramToEncode', data)).to.deep.equal(expectedData);
});

it('encodes just the specified param with integer indexes when used via partial application', function() {
var data = {'paramToEncode': ['value1', 'value2'], 'anotherParam': ['foo']};
var expectedData = {'paramToEncode': {'0': 'value1', '1': 'value2'}, 'anotherParam': ['foo']};
var partial = utils.encodeParamWithIntegerIndexes.bind(null, 'paramToEncode');
expect(partial(data)).to.deep.equal(expectedData);
});
});

describe('arrayToObject', function() {
it('handles an empty array', function() {
expect(utils.arrayToObject([])).to.deep.equal({});
Expand Down

0 comments on commit ae049ad

Please sign in to comment.