-
Notifications
You must be signed in to change notification settings - Fork 170
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
Conversation
Seems like we need async/await support in circleci to successfully run the tests. |
lib/PlaidClient.js
Outdated
@@ -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) { |
There was a problem hiding this comment.
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
137d623
to
9f27b83
Compare
I've updated it to use bluebird, thanks! |
lib/PlaidClient.js
Outdated
@@ -1,5 +1,6 @@ | |||
'use strict'; | |||
|
|||
var Promise = require('bluebird'); |
There was a problem hiding this comment.
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')
lib/PlaidClient.js
Outdated
|
||
var handleResponse = function(transactionsResponse) { | ||
total_transactions = transactionsResponse.total_transactions; | ||
transactions.push(...transactionsResponse.transactions); |
There was a problem hiding this comment.
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);
lib/PlaidClient.js
Outdated
Client.prototype.getAllTransactions = | ||
function(access_token, start_date, end_date, cb) { | ||
var transactions = []; | ||
var offset = 0, total_transactions = null; |
There was a problem hiding this comment.
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 :).
lib/PlaidClient.js
Outdated
break; | ||
} | ||
|
||
yield self.getTransactions( |
There was a problem hiding this comment.
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.
lib/PlaidClient.js
Outdated
}); | ||
} | ||
})().then(function() { | ||
return cb(null, transactions); |
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added unit tests!
lib/PlaidClient.js
Outdated
var self = this; | ||
|
||
var handleResponse = function(transactionsResponse) { | ||
total_transactions = transactionsResponse.total_transactions; |
There was a problem hiding this comment.
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
010b942
to
a581158
Compare
i've fixed all the issues you mentioned. |
test/PlaidClientTest.js
Outdated
transactions: R.range(0, 200), | ||
total_transactions: 200, | ||
}); | ||
} |
There was a problem hiding this comment.
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
test/PlaidClientTest.js
Outdated
transactionsResponse.transactions = R.range(500, 1000); | ||
} else if (options.offset === 1000) { | ||
transactionsResponse.transactions = R.range(1000, 1200); | ||
} |
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
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.
@jacksiegel anything to add here? it looks right to me (just left a few nits for @evanlimanto) |
@ntindall nope, looks good to me. |
a581158
to
a7776bf
Compare
sorry it took a while — i've fixed the nits you mentioned. |
There was a problem hiding this 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 !
lib/PlaidClient.js
Outdated
|
||
transactions = R.concat( | ||
transactions, transactionsResponse.transactions); | ||
if (transactions.length === transactionsResponse.total_transactions) { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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!
a7776bf
to
ddd1bbb
Compare
thanks @evanlimanto -- see you soon! |
@ntindall @evanlimanto It doesn't look like this function returns a promise. Is that something which can easily be fixed? |
Good catch — I think it should be an easy fix with wrapPromise. |
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. |
Fixes #145.