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

Create getAllTransactions wrapper around getTransactions #148

Merged
merged 1 commit into from
May 6, 2018

Conversation

evanlimanto
Copy link
Contributor

Fixes #145.

@evanlimanto
Copy link
Contributor Author

Seems like we need async/await support in circleci to successfully run the tests.

@@ -210,6 +210,42 @@ Client.prototype.getTransactions =
}, options, cb);
};

// getAllTransactions(String, Date, Date, Object?, Function)
Client.prototype.getAllTransactions =
async function(access_token, start_date, end_date, cb) {
Copy link
Collaborator

@ntindall ntindall Mar 21, 2018

Choose a reason for hiding this comment

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

@evanlimanto, lets write this without using mode modern node features. I can't imagine that all of our clients have node on 7.x or greater right now.

I would consider looking at http://bluebirdjs.com/docs/api/promise.coroutine.html

@evanlimanto evanlimanto force-pushed the get-all-transactions branch 5 times, most recently from 137d623 to 9f27b83 Compare March 22, 2018 04:34
@evanlimanto
Copy link
Contributor Author

evanlimanto commented Mar 22, 2018

I've updated it to use bluebird, thanks!

@@ -1,5 +1,6 @@
'use strict';

var Promise = require('bluebird');
Copy link
Collaborator

Choose a reason for hiding this comment

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

rather than shadowing Promise, it would be more idiomatic to give the bluebird promise implementation a different name.

canonically @ plaid, we use P

var P = require('bluebird')


var handleResponse = function(transactionsResponse) {
total_transactions = transactionsResponse.total_transactions;
transactions.push(...transactionsResponse.transactions);
Copy link
Collaborator

Choose a reason for hiding this comment

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

we should not use the spread operator, since it assumes that the client is using a version of node that supports it.

even though node4 is almost at end of life... we should not do this.

consider:

transactions = R.concat(transactions, transactionsResponse.transactions);

Client.prototype.getAllTransactions =
function(access_token, start_date, end_date, cb) {
var transactions = [];
var offset = 0, total_transactions = null;
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: two statements per line

we don't have a linter set up for this project, but it would probably not like this :).

break;
}

yield self.getTransactions(
Copy link
Collaborator

Choose a reason for hiding this comment

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

since we are in a generator, we can do something like

const intermediaryTransactionsResponse  = yield self.getTransactions( /* ... */ );
handleResponse(intermediaryTransactionsResponse);

In that world, its probably best to have handleTransactions be inline within the loop.

});
}
})().then(function() {
return cb(null, transactions);
Copy link
Collaborator

Choose a reason for hiding this comment

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

this seems reasonable to me... I agree with you that we should be using the Promise api internally...

});

it('all transactions', cb => {
pCl.getAllTransactions(accessToken, now, now,
Copy link
Collaborator

Choose a reason for hiding this comment

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

this is good for an end-to-end test, but I'm not sure it tests anything other than that the function doesn't throw an exception. This is generally OK for the other functions, since they don't do much other than call the API, but now that we are implementing some real logic, I think we need more.

@evanlimanto could we add some unit tests for the pagination? I would suggest using sinon to stub out the implementation of self.getTransactions to return fake data in pages (and assert that the aggregate result is returned).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

added unit tests!

var self = this;

var handleResponse = function(transactionsResponse) {
total_transactions = transactionsResponse.total_transactions;
Copy link
Collaborator

Choose a reason for hiding this comment

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

the documentation is somewhat ambiguous, but I believe that this represents the total transactions available within the date range (e.g. that this is the proper way to terminate the pagination).

cc @michaelckelly @pbernasconi we should consider clarifying the documentation here: https://plaid.com/docs/api/#transactions

@evanlimanto evanlimanto force-pushed the get-all-transactions branch 6 times, most recently from 010b942 to a581158 Compare April 2, 2018 06:42
@evanlimanto
Copy link
Contributor Author

i've fixed all the issues you mentioned.

transactions: R.range(0, 200),
total_transactions: 200,
});
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

i think we should throw an error in any other case

transactionsResponse.transactions = R.range(500, 1000);
} else if (options.offset === 1000) {
transactionsResponse.transactions = R.range(1000, 1200);
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

any other case should be an error

var self = this;

P.coroutine(function*() {
while (true) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

makes sense, we will break out when we get the correct number of transactions or if any of the requests throws an error.

assuming the plaid API works correctly, this looks right to me.

@ntindall ntindall requested a review from a user April 28, 2018 15:05
@ntindall
Copy link
Collaborator

@jacksiegel anything to add here? it looks right to me (just left a few nits for @evanlimanto)

@ghost
Copy link

ghost commented Apr 29, 2018

@ntindall nope, looks good to me.

@evanlimanto evanlimanto force-pushed the get-all-transactions branch from a581158 to a7776bf Compare May 6, 2018 03:52
@evanlimanto
Copy link
Contributor Author

sorry it took a while — i've fixed the nits you mentioned.

Copy link
Collaborator

@ntindall ntindall left a comment

Choose a reason for hiding this comment

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

Looks good after the final (yes, really this time) comment @evanlimanto !


transactions = R.concat(
transactions, transactionsResponse.transactions);
if (transactions.length === transactionsResponse.total_transactions) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

can we change this to be >= ? I am somewhat concerned about the possibility of this loop not terminating.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

makes sense, though something could be wrong with the plaid API in that case

Copy link
Collaborator

Choose a reason for hiding this comment

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

yes -- I think that it "should never happen"

better to be safe!

@evanlimanto evanlimanto force-pushed the get-all-transactions branch from a7776bf to ddd1bbb Compare May 6, 2018 16:30
@ntindall ntindall merged commit 73cbd39 into plaid:master May 6, 2018
@ntindall
Copy link
Collaborator

ntindall commented May 6, 2018

thanks @evanlimanto -- see you soon!

This was referenced May 6, 2018
@snyamathi
Copy link

@ntindall @evanlimanto It doesn't look like this function returns a promise. Is that something which can easily be fixed?

@evanlimanto
Copy link
Contributor Author

Good catch — I think it should be an easy fix with wrapPromise.

@ntindall
Copy link
Collaborator

Ah, sorry about that @snyamathi, we'll work on a fix. @evanlimanto is right, we already have an easy way to support both the cps and promise styles internally.

@ntindall
Copy link
Collaborator

#157

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants