plaid 1.4.3 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +66 -2
- data/lib/plaid/config.rb +8 -2
- data/lib/plaid/connection.rb +121 -0
- data/lib/plaid/models/account.rb +24 -0
- data/lib/plaid/models/category.rb +17 -0
- data/lib/plaid/models/exchange_token_response.rb +9 -0
- data/lib/plaid/models/info.rb +12 -0
- data/lib/plaid/models/institution.rb +20 -0
- data/lib/plaid/models/transaction.rb +23 -0
- data/lib/plaid/models/user.rb +192 -0
- data/lib/plaid/version.rb +1 -1
- data/lib/plaid.rb +77 -35
- data/plaid.gemspec +3 -1
- data/spec/account_spec.rb +35 -0
- data/spec/category_spec.rb +5 -14
- data/spec/config_spec.rb +57 -28
- data/spec/institution_spec.rb +6 -14
- data/spec/plaid_spec.rb +258 -0
- data/spec/spec_helper.rb +8 -1
- data/spec/transaction_spec.rb +30 -0
- data/spec/user_spec.rb +98 -109
- metadata +44 -12
- data/lib/plaid/add_user.rb +0 -24
- data/lib/plaid/category/category.rb +0 -29
- data/lib/plaid/institution/institution.rb +0 -29
- data/lib/plaid/user/account/account.rb +0 -35
- data/lib/plaid/user/info/info.rb +0 -23
- data/lib/plaid/user/transaction/transaction.rb +0 -19
- data/lib/plaid/user/user.rb +0 -173
- data/lib/plaid/util.rb +0 -120
- data/spec/add_user_spec.rb +0 -113
data/lib/plaid.rb
CHANGED
@@ -1,54 +1,96 @@
|
|
1
1
|
require 'plaid/version'
|
2
2
|
require 'plaid/config'
|
3
|
-
require 'plaid/util'
|
4
3
|
|
5
|
-
require 'plaid/
|
6
|
-
require 'plaid/
|
7
|
-
require 'plaid/
|
8
|
-
require 'plaid/
|
4
|
+
require 'plaid/models/user'
|
5
|
+
require 'plaid/models/institution'
|
6
|
+
require 'plaid/models/category'
|
7
|
+
require 'plaid/models/exchange_token_response'
|
8
|
+
|
9
|
+
require 'json'
|
9
10
|
|
10
11
|
module Plaid
|
12
|
+
autoload :Connection, 'plaid/connection'
|
13
|
+
|
11
14
|
class << self
|
12
15
|
# Configures the gem with the public, private, and environment vars
|
13
|
-
include
|
16
|
+
include Configure
|
17
|
+
|
18
|
+
# API: public
|
19
|
+
# Use this to create a new Plaid user
|
20
|
+
# Required parameters:
|
21
|
+
# api_level, username, password, type
|
22
|
+
# TODO: Rename this to something more descriptive for 2.0, such as 'create_user`
|
23
|
+
def add_user(api_level, username, password, type, pin = nil, options = nil)
|
24
|
+
payload = { username: username, password: password, type: type }
|
14
25
|
|
15
|
-
|
16
|
-
|
26
|
+
payload[:pin] = pin if pin
|
27
|
+
payload[:options] = options.is_a?(Hash) ? JSON.generate(options) : options if options
|
17
28
|
|
18
|
-
|
19
|
-
|
29
|
+
res = Connection.post(api_level, payload)
|
30
|
+
User.build(res, api_level)
|
31
|
+
end
|
32
|
+
|
33
|
+
# API: public
|
34
|
+
# Exchange a Plaid Link public_token for a Plaid access_token
|
35
|
+
# Required parameters:
|
36
|
+
# public_token
|
37
|
+
def exchange_token(public_token)
|
38
|
+
payload = { public_token: public_token }
|
20
39
|
|
21
|
-
|
22
|
-
|
23
|
-
@user = Plaid::User.new
|
24
|
-
@user.new(res,api_level)
|
40
|
+
res = Connection.post('exchange_token', payload)
|
41
|
+
ExchangeTokenResponse.new(res)
|
25
42
|
end
|
26
43
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
@user
|
44
|
+
# API: public
|
45
|
+
# Use this to restore a user from Plaid based upon the access token
|
46
|
+
# TODO: Rename this to something more descriptive for 2.0, such as 'get_user'
|
47
|
+
def set_user(token, api_levels=[], institution_type=nil)
|
48
|
+
_user = User.new
|
49
|
+
_user.access_token = fully_qualified_token(token, institution_type)
|
50
|
+
_user.permissions = api_levels
|
51
|
+
api_levels.each { |l| _user.get(l) }
|
52
|
+
return _user
|
37
53
|
end
|
38
54
|
|
39
|
-
#
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
55
|
+
# API: public
|
56
|
+
# Given an access code and query options, use this to get a dataset of
|
57
|
+
# transactions and accounts for # a given user. See /connect/get endpoint
|
58
|
+
#
|
59
|
+
# Returns a User object with accounts and transactions within
|
60
|
+
# the date range given
|
61
|
+
# Examples:
|
62
|
+
# Plaid.transactions 'test_wells', account: 'QPO8Jo8vdDHMepg41PBwckXm4KdK1yUdmXOwK'
|
63
|
+
def transactions(token, options = {})
|
64
|
+
_user = User.new
|
65
|
+
_user.access_token = token
|
66
|
+
_user.permit! 'connect'
|
67
|
+
|
68
|
+
# TODO: For 2.0, submit all data as JSON
|
69
|
+
options = JSON.generate(options) if options.kind_of?(Hash)
|
70
|
+
|
71
|
+
_user.get_connect(options: options)
|
72
|
+
return _user
|
73
|
+
end
|
74
|
+
|
75
|
+
# API: public
|
76
|
+
# Returns the fully-qualified token based upon type
|
77
|
+
# Note: Don't see this documented in the Plaid API docs, need to investigate this
|
78
|
+
def fully_qualified_token(token, institution_type)
|
79
|
+
institution_type.nil? ? token : token + '_' + institution_type
|
44
80
|
end
|
45
81
|
|
46
|
-
#
|
47
|
-
|
48
|
-
|
49
|
-
res =
|
50
|
-
id.nil? ?
|
82
|
+
# API: public
|
83
|
+
# Builds an institution object and returns when the institution details exist
|
84
|
+
def institution(id = nil)
|
85
|
+
res = Connection.get('institutions', id)
|
86
|
+
id.nil? ? Institution.all(res) : Institution.new(res)
|
51
87
|
end
|
52
88
|
|
89
|
+
# API: public
|
90
|
+
# Builds an category object and returns when the category details exist
|
91
|
+
def category(id = nil)
|
92
|
+
res = Connection.get('categories', id)
|
93
|
+
id.nil? ? Category.all(res) : Category.new(res)
|
94
|
+
end
|
53
95
|
end
|
54
|
-
end
|
96
|
+
end
|
data/plaid.gemspec
CHANGED
@@ -21,4 +21,6 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.add_development_dependency 'bundler', '~> 1.7'
|
22
22
|
spec.add_development_dependency 'rake', '~> 10.0'
|
23
23
|
spec.add_development_dependency 'rspec', '~>3.1'
|
24
|
-
|
24
|
+
spec.add_development_dependency 'pry'
|
25
|
+
spec.add_development_dependency 'pry-stack_explorer'
|
26
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper.rb'
|
2
|
+
|
3
|
+
RSpec.describe Plaid::Account do
|
4
|
+
# API: semi-private
|
5
|
+
describe '.new' do
|
6
|
+
subject { Plaid::Account.new(results) }
|
7
|
+
|
8
|
+
def self.with_results(_results, &examples)
|
9
|
+
context "with results #{_results}" do
|
10
|
+
let(:results) { _results }
|
11
|
+
instance_eval(&examples)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
with_results('name' => 'Name') do it { expect(subject.name).to eql('Name') } end
|
16
|
+
with_results('_id' => 'ID') do it { expect(subject.id).to eql('ID') } end
|
17
|
+
with_results('type' => 'Type') do it { expect(subject.type).to eql('Type') } end
|
18
|
+
with_results('type' => 'STyp') do it { expect(subject.type).to eql('STyp') } end
|
19
|
+
with_results('meta' => nil) do it { expect(subject.meta).to be_nil } end
|
20
|
+
with_results('meta' => {}) do it { expect(subject.meta).to eql({}) } end
|
21
|
+
|
22
|
+
with_results('balance' => { 'available' => 100.00 } ) do it { expect(subject.available_balance).to eql(100.00) } end
|
23
|
+
with_results('balance' => { 'current' => 200.00 } ) do it { expect(subject.current_balance).to eql(200.00) } end
|
24
|
+
|
25
|
+
with_results('institution_type' => 'Type') do it { expect(subject.institution_type).to eql('Type') } end
|
26
|
+
|
27
|
+
with_results('numbers' => nil) do
|
28
|
+
it { expect(subject.numbers).to eql('Upgrade user to access routing information for this account') }
|
29
|
+
end
|
30
|
+
|
31
|
+
with_results('numbers' => {}) do
|
32
|
+
it { expect(subject.numbers).to eql({}) }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/spec/category_spec.rb
CHANGED
@@ -1,22 +1,13 @@
|
|
1
1
|
require 'spec_helper.rb'
|
2
|
-
# Category specs
|
3
|
-
describe '#Category' do
|
4
|
-
|
5
|
-
before :all do
|
6
|
-
Plaid.config do |p|
|
7
|
-
p.customer_id = 'test_id'
|
8
|
-
p.secret = 'test_secret'
|
9
|
-
p.environment_location = 'https://tartan.plaid.com/'
|
10
|
-
end
|
11
|
-
end
|
12
2
|
|
3
|
+
RSpec.describe Plaid::Category do
|
13
4
|
context 'when a single category is found' do
|
14
|
-
category
|
15
|
-
it { expect(category
|
5
|
+
let(:category) { Plaid.category('17001013') }
|
6
|
+
it { expect(category).to be_kind_of(Plaid::Category) }
|
16
7
|
end
|
17
8
|
|
18
9
|
context 'when all categories are found' do
|
19
|
-
category
|
10
|
+
let(:category) { Plaid.category }
|
20
11
|
it { expect(category).to be_kind_of(Array)}
|
21
12
|
end
|
22
13
|
|
@@ -24,4 +15,4 @@ describe '#Category' do
|
|
24
15
|
it { expect { Plaid.category('dumb_cat') }.to raise_error }
|
25
16
|
end
|
26
17
|
|
27
|
-
end
|
18
|
+
end
|
data/spec/config_spec.rb
CHANGED
@@ -1,40 +1,69 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
require 'spec_helper.rb'
|
2
|
+
|
3
|
+
RSpec.describe 'Plaid.config' do
|
4
|
+
around(:each) do |example|
|
5
|
+
old_customer_id = Plaid.customer_id
|
6
|
+
old_secret = Plaid.secret
|
7
|
+
old_environment_location = Plaid.environment_location
|
8
|
+
|
4
9
|
Plaid.config do |p|
|
5
|
-
p.customer_id
|
6
|
-
p.secret
|
7
|
-
p.environment_location =
|
10
|
+
p.customer_id = customer_id
|
11
|
+
p.secret = secret
|
12
|
+
p.environment_location = environment_location
|
8
13
|
end
|
9
|
-
res = Plaid.add_user('connect','plaid_test','plaid_good','wells')
|
10
|
-
it { expect(res).to be_instance_of Plaid::User }
|
11
|
-
end
|
12
14
|
|
13
|
-
|
15
|
+
example.run
|
16
|
+
|
14
17
|
Plaid.config do |p|
|
15
|
-
p.customer_id
|
16
|
-
p.secret
|
17
|
-
p.environment_location =
|
18
|
+
p.customer_id = old_customer_id
|
19
|
+
p.secret = old_secret
|
20
|
+
p.environment_location = old_environment_location
|
18
21
|
end
|
19
|
-
res = Plaid.add_user('connect','plaid_test','plaid_good','wells')
|
20
|
-
it { expect(res).to be_instance_of Plaid::User }
|
21
22
|
end
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
24
|
+
let(:customer_id) { 'test_id' }
|
25
|
+
let(:secret) { 'test_secret' }
|
26
|
+
let(:dev_url) { 'https://tartan.plaid.com/' }
|
27
|
+
let(:prod_url) { 'https://api.plaid.com/' }
|
28
|
+
|
29
|
+
|
30
|
+
let(:user) { Plaid.add_user('connect','plaid_test','plaid_good','wells') }
|
31
|
+
|
32
|
+
context ':environment_location' do
|
33
|
+
context 'with trailing slash' do
|
34
|
+
let(:environment_location) { 'http://example.org/' }
|
35
|
+
it 'should leave it as-is' do
|
36
|
+
expect(Plaid.environment_location).to eql(environment_location)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'without trailing slash' do
|
41
|
+
let(:environment_location) { 'http://example.org' }
|
42
|
+
it 'should add a trailing slash' do
|
43
|
+
expect(Plaid.environment_location).to eql(environment_location + '/')
|
44
|
+
end
|
28
45
|
end
|
29
|
-
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'has valid dev keys' do
|
49
|
+
let(:environment_location) { dev_url }
|
50
|
+
it { expect(user).to be_instance_of Plaid::User }
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'has valid production keys' do
|
54
|
+
let(:environment_location) { prod_url }
|
55
|
+
it { expect(user).to be_instance_of Plaid::User }
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'has invalid dev keys' do
|
59
|
+
let(:secret) { 'test_bad' }
|
60
|
+
let(:environment_location) { dev_url }
|
61
|
+
it { expect { user }.to raise_error }
|
30
62
|
end
|
31
63
|
|
32
64
|
context 'has invalid production keys' do
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
p.environment_location = 'https://api.plaid.com/'
|
37
|
-
end
|
38
|
-
it { expect{Plaid.add_user('connect','plaid_bad','plaid_bad','wells')}.to raise_error }
|
65
|
+
let(:secret) { 'test_bad' }
|
66
|
+
let(:environment_location) { prod_url }
|
67
|
+
it { expect { user }.to raise_error }
|
39
68
|
end
|
40
|
-
end
|
69
|
+
end
|
data/spec/institution_spec.rb
CHANGED
@@ -1,25 +1,17 @@
|
|
1
|
-
|
2
|
-
describe '#Institution' do
|
3
|
-
|
4
|
-
before :all do
|
5
|
-
Plaid.config do |p|
|
6
|
-
p.customer_id = 'test_id'
|
7
|
-
p.secret = 'test_secret'
|
8
|
-
p.environment_location = 'https://tartan.plaid.com/'
|
9
|
-
end
|
10
|
-
end
|
1
|
+
require 'spec_helper.rb'
|
11
2
|
|
3
|
+
RSpec.describe Plaid::Institution do
|
12
4
|
context 'when a single institution is found' do
|
13
|
-
institution
|
14
|
-
it { expect(institution
|
5
|
+
let(:institution) { Plaid.institution('5301a93ac140de84910000e0') }
|
6
|
+
it { expect(institution).to be_kind_of(Plaid::Institution) }
|
15
7
|
end
|
16
8
|
|
17
9
|
context 'when all institutions are found' do
|
18
|
-
institution
|
10
|
+
let(:institution) { Plaid.institution }
|
19
11
|
it { expect(institution).to be_kind_of(Array) }
|
20
12
|
end
|
21
13
|
|
22
14
|
context 'when institution is not found' do
|
23
15
|
it { expect { Plaid.institution('dumb_bank') }.to raise_error }
|
24
16
|
end
|
25
|
-
end
|
17
|
+
end
|
data/spec/plaid_spec.rb
ADDED
@@ -0,0 +1,258 @@
|
|
1
|
+
require 'spec_helper.rb'
|
2
|
+
# Authentication flow specs - returns Plaid::User
|
3
|
+
RSpec.describe Plaid do
|
4
|
+
let(:api_level) { raise "Define let(:api_level)" }
|
5
|
+
let(:username) { raise "Define let(:username)" }
|
6
|
+
let(:password) { raise "Define let(:password)" }
|
7
|
+
let(:type) { raise "Define let(:type)" }
|
8
|
+
let(:pin) { nil }
|
9
|
+
let(:options) { nil }
|
10
|
+
|
11
|
+
describe '.add_user' do
|
12
|
+
let(:user) { Plaid.add_user api_level, username, password, type, pin, options }
|
13
|
+
|
14
|
+
context 'with correct credentials for single user auth' do
|
15
|
+
let(:username) { 'plaid_test' }
|
16
|
+
let(:password) { 'plaid_good' }
|
17
|
+
let(:type) { 'wells' }
|
18
|
+
|
19
|
+
context 'and "connect" level of api access' do
|
20
|
+
let(:api_level) { 'connect' }
|
21
|
+
|
22
|
+
it { expect(user.accounts).not_to be_empty }
|
23
|
+
|
24
|
+
context 'with webhook' do
|
25
|
+
let(:options) { { login_only: true, webhook: 'test.com/test.endpoint.aspx' } }
|
26
|
+
it { expect(user.accounts).not_to be_empty }
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'when account is locked' do
|
30
|
+
let(:password) { 'plaid_locked' }
|
31
|
+
it { expect(user.api_res).to eq 'User account is locked' }
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'with connection options' do
|
35
|
+
context 'when requests pending transactions from an institution' do
|
36
|
+
let(:options) { { pending: true } }
|
37
|
+
it { expect(user.accounts).not_to be_empty }
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'when login only is true' do
|
41
|
+
let(:options) { { login_only: true } }
|
42
|
+
it { expect(user.accounts).not_to be_empty }
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'sets a start date for transactions' do
|
46
|
+
let(:options) { { login_only: true, start_date: '10 days ago'} }
|
47
|
+
it { expect(user.accounts).not_to be_empty }
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'sets an end date for transactions' do
|
51
|
+
let(:options) { { login_only: true, end_date: '10 days ago'} }
|
52
|
+
it { expect(user.accounts).not_to be_empty }
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'sets start and end dates for transactions' do
|
56
|
+
let(:options) { { gte: "05/10/2014" , lte: "06/10/2014" } }
|
57
|
+
it { expect(user.transactions).not_to be_nil }
|
58
|
+
end
|
59
|
+
|
60
|
+
pending 'with JSON-encoded string for options'
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'and "auth" level of api access' do
|
65
|
+
let(:api_level) { 'auth' }
|
66
|
+
it { expect(user.accounts.first.numbers).not_to be_empty }
|
67
|
+
end
|
68
|
+
|
69
|
+
context 'and "info" level of api access' do
|
70
|
+
let(:api_level) { 'info' }
|
71
|
+
it { expect(user.info).not_to be_empty }
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'with incorrect credentials for single factor auth' do
|
76
|
+
# Set up correct credentials. Override with bad element
|
77
|
+
# within each context block
|
78
|
+
let(:username) { 'plaid_test' }
|
79
|
+
let(:password) { 'plaid_good' }
|
80
|
+
let(:type) { 'wells' }
|
81
|
+
|
82
|
+
context 'at "auth" level api access' do
|
83
|
+
let(:api_level) { 'auth' }
|
84
|
+
|
85
|
+
context 'using incorrect password' do
|
86
|
+
let(:password) { 'plaid_bad' }
|
87
|
+
it { expect { user }.to raise_error }
|
88
|
+
end
|
89
|
+
|
90
|
+
context 'using incorrect username' do
|
91
|
+
let(:username) { 'plaid_bad' }
|
92
|
+
it { expect { user }.to raise_error }
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context 'at "connect" level api access' do
|
97
|
+
let(:api_level) { 'connect' }
|
98
|
+
|
99
|
+
context 'using incorrect password' do
|
100
|
+
let(:password) { 'plaid_bad' }
|
101
|
+
it { expect { user }.to raise_error }
|
102
|
+
end
|
103
|
+
|
104
|
+
context 'using incorrect username' do
|
105
|
+
let(:username) { 'plaid_bad' }
|
106
|
+
it { expect { user }.to raise_error }
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
context 'at "info" level api access' do
|
111
|
+
let(:api_level) { 'info' }
|
112
|
+
|
113
|
+
context 'using incorrect password' do
|
114
|
+
let(:password) { 'plaid_bad' }
|
115
|
+
it { expect { user }.to raise_error }
|
116
|
+
end
|
117
|
+
|
118
|
+
context 'using incorrect username' do
|
119
|
+
let(:username) { 'plaid_bad' }
|
120
|
+
it { expect { user }.to raise_error }
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context 'when institution requires PIN' do
|
126
|
+
let(:api_level) { 'connect' }
|
127
|
+
let(:username) { 'plaid_test' }
|
128
|
+
let(:password) { 'plaid_good' }
|
129
|
+
let(:type) { 'usaa' }
|
130
|
+
|
131
|
+
context 'using correct PIN' do
|
132
|
+
let(:pin) { '1234' }
|
133
|
+
it { expect(user.api_res).to eq 'Requires further authentication' }
|
134
|
+
end
|
135
|
+
|
136
|
+
context 'using incorrect PIN' do
|
137
|
+
let(:pin) { '0000' }
|
138
|
+
it { expect { user }.to raise_error }
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
context 'when institution requires MFA' do
|
143
|
+
let(:api_level) { 'connect' }
|
144
|
+
let(:username) { 'plaid_test' }
|
145
|
+
let(:password) { 'plaid_good' }
|
146
|
+
let(:type) { 'bofa' }
|
147
|
+
|
148
|
+
context 'with only standard credentials' do
|
149
|
+
it { expect(user.api_res).to eq 'Requires further authentication' }
|
150
|
+
end
|
151
|
+
|
152
|
+
context 'with options' do
|
153
|
+
context 'with webhook' do
|
154
|
+
let(:options) { { login_only: true, webhook: 'test.com/test.endpoint.aspx' } }
|
155
|
+
it { expect(user.api_res).to eq 'Requires further authentication' }
|
156
|
+
end
|
157
|
+
|
158
|
+
context 'requests a list of options for code based MFA' do
|
159
|
+
let(:type) { 'citi' }
|
160
|
+
let(:options) { { list: true } }
|
161
|
+
|
162
|
+
it { expect(user.pending_mfa_questions).not_to be_nil }
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
describe '.set_user' do
|
169
|
+
subject { Plaid.set_user(access_token) }
|
170
|
+
let(:access_token) { 'test' }
|
171
|
+
|
172
|
+
it { expect(subject.access_token).to eq(access_token)}
|
173
|
+
|
174
|
+
context 'gets a valid user with accounts and transactions' do
|
175
|
+
let(:user) { Plaid.set_user('test_wells',['connect']) }
|
176
|
+
it { expect(user.transactions).not_to be_empty }
|
177
|
+
end
|
178
|
+
|
179
|
+
context 'gets a valid user with accounts' do
|
180
|
+
let(:user) { Plaid.set_user('test_wells',['auth']) }
|
181
|
+
it { expect(user.accounts).not_to be_empty }
|
182
|
+
end
|
183
|
+
|
184
|
+
#TODO: Fully vet the info api endpoint for the beta functions before adding this as a supported function.
|
185
|
+
pending 'need to vet the info api endpoint' do
|
186
|
+
context 'gets a valid user with info' do
|
187
|
+
let(:user) { Plaid.set_user('test_wells',['info']) }
|
188
|
+
it { expect(user.accounts).to be_truthy}
|
189
|
+
end
|
190
|
+
|
191
|
+
context 'gets a fully validated user with all access granted' do
|
192
|
+
let(:user) { Plaid.set_user('test_wells',['connect','info','auth']) }
|
193
|
+
it { expect(user.transactions).to be_truthy}
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
describe '.exchange_token' do
|
199
|
+
subject { Plaid.exchange_token('test,chase,connected') }
|
200
|
+
|
201
|
+
it { expect(subject.access_token).to eql('test_chase') }
|
202
|
+
end
|
203
|
+
|
204
|
+
describe '.transactions' do
|
205
|
+
subject { Plaid.transactions(access_token, options) }
|
206
|
+
let(:access_token) { 'test_wells' }
|
207
|
+
let(:options) { nil }
|
208
|
+
|
209
|
+
context 'without options' do
|
210
|
+
it 'should return all accounts' do
|
211
|
+
expect(subject.accounts).not_to be_empty
|
212
|
+
end
|
213
|
+
|
214
|
+
it 'should return all transactions' do
|
215
|
+
expect(subject.transactions).not_to be_empty
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
context 'when filering by account' do
|
220
|
+
let(:options) { { account: account } }
|
221
|
+
let(:account) { 'QPO8Jo8vdDHMepg41PBwckXm4KdK1yUdmXOwK' }
|
222
|
+
|
223
|
+
it 'should return a subset of transactions' do
|
224
|
+
expect(subject.transactions.size).to eql(2)
|
225
|
+
end
|
226
|
+
|
227
|
+
it 'should only return transactions from the requested account' do
|
228
|
+
expect(subject.transactions.map(&:account).uniq).to eql([account])
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
context 'when filtering by date' do
|
233
|
+
let(:options) { { gte: "2014-07-24", lte: "2014-07-25" } }
|
234
|
+
|
235
|
+
it 'should return a subset of transactions' do
|
236
|
+
expect(subject.transactions.size).to eql(1)
|
237
|
+
end
|
238
|
+
|
239
|
+
it 'should only return transactions from the requested date range' do
|
240
|
+
expect(subject.transactions.map(&:date).uniq).to eql(['2014-07-24'])
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
context 'when filtering by account and date' do
|
245
|
+
let(:options) { { account: account , gte: "2014-07-24", lte: "2014-07-25" } }
|
246
|
+
let(:account) { 'XARE85EJqKsjxLp6XR8ocg8VakrkXpTXmRdOo' }
|
247
|
+
|
248
|
+
it 'should return a subset of transactions' do
|
249
|
+
expect(subject.transactions.size).to eql(1)
|
250
|
+
end
|
251
|
+
|
252
|
+
it 'should only return transactions from the requested account and date range' do
|
253
|
+
expect(subject.transactions.map(&:date).uniq).to eql(['2014-07-24'])
|
254
|
+
expect(subject.transactions.map(&:account).uniq).to eql([account])
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper.rb'
|
2
|
+
|
3
|
+
RSpec.describe Plaid::Transaction do
|
4
|
+
# API: semi-private
|
5
|
+
describe '.new' do
|
6
|
+
# The reason this looks weird is because it is. This will be refactored for 2.0
|
7
|
+
subject { Plaid::Transaction.new(results) }
|
8
|
+
|
9
|
+
def self.with_results(_results, &examples)
|
10
|
+
context "with results #{_results}" do
|
11
|
+
let(:results) { _results }
|
12
|
+
instance_eval(&examples)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
with_results('_id' => 'ID') do it { expect(subject.id).to eql('ID') } end
|
17
|
+
with_results('_account' => 'acct') do it { expect(subject.account).to eql('acct') } end
|
18
|
+
with_results('date' => '00/00/00') do it { expect(subject.date).to eql('00/00/00') } end
|
19
|
+
with_results('amount' => 100.00) do it { expect(subject.amount).to eql(100.00) } end
|
20
|
+
with_results('name' => 'Name') do it { expect(subject.name).to eql('Name') } end
|
21
|
+
with_results('meta' => {} ) do it { expect(subject.meta).to eql({}) } end
|
22
|
+
with_results('meta' => {'location' => 'Location'}) do it { expect(subject.location).to eql('Location') } end
|
23
|
+
with_results('pending' => true) do it { expect(subject.pending).to eql(true) } end
|
24
|
+
with_results('score' => 200) do it { expect(subject.score).to eql(200) } end
|
25
|
+
with_results('type' => 'Type') do it { expect(subject.type).to eql('Type') } end
|
26
|
+
|
27
|
+
with_results('category' => 'Category') do it { expect(subject.category).to eql('Category') } end
|
28
|
+
with_results('category_id' => 100) do it { expect(subject.category_id).to eql(100) } end
|
29
|
+
end
|
30
|
+
end
|