plaid 1.2.3 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 00be434d6e58902d9c47db517d0907f668fe620c
4
- data.tar.gz: c60a4d95dc87cbff07092a77af43e03bc4f7c1f3
3
+ metadata.gz: 850b922bf86cae1a44608e0cb0c418c3219d75c1
4
+ data.tar.gz: 94feeeb9e8c679ba72c6f7d9f59641f20a28c2b5
5
5
  SHA512:
6
- metadata.gz: f0d01df929e6ea2c7a3c3329304814189d78a6074e07507c07124f8c54e60cf1cfc6c2fd8740d35fef964fec26003996576792ddc905ce29ae992b5a4b8c457a
7
- data.tar.gz: c90dc4c04e8f953c197a8838984cb53a584ce33325c48112fee5972719179195f153f3f3fb3010e70b76353ae00662feded4ad6a37dd0f653aae73493a05aa7e
6
+ metadata.gz: fb4406c54faaae17871f06da31d98cc374859738d5c06f59dd38f7f4d0471f078c2b34b26b3064a2ae93694f7ee5fb6c698b86b25608b024d52cd1b3b3e086a7
7
+ data.tar.gz: 994baa65df1ba115d2013fef8152e3a9c7efc0ed2bb4d8f5c9d6e6319d297d50ba0fb26c4a153b01b0e9c977afc4c7dc6c88b642e3aa9f4be2ea5d508ff81da6
data/README.md CHANGED
@@ -6,9 +6,7 @@ Ruby bindings for the Plaid API
6
6
 
7
7
  This version is a beta version that contains failing tests for the new 'info' endpoint. While these have been tested individually on real accounts the tests here will fail with the test accounts supplied. These will be updated soon with test credentials.
8
8
 
9
- Latest stable version: **1.2.2**
10
-
11
- Last stable version: 1.1.2
9
+ Latest stable version: **1.3.0**
12
10
 
13
11
  **Warning: If you have been using any version < 1 please switch to the correct branch (V0.1.6). Installing without specifying a version from RubyGems results in V1.1 build. **
14
12
 
@@ -0,0 +1,23 @@
1
+ require 'plaid/util'
2
+ module Plaid
3
+ class Information
4
+ include Plaid::Util
5
+ # Define vars for info
6
+ attr_accessor(:names, :emails, :phone_numbers, :addresses)
7
+
8
+ def new
9
+ self.names = []
10
+ self.emails = []
11
+ self.phone_numbers = []
12
+ self.addresses = ''
13
+ end
14
+
15
+ def update_info(res)
16
+ self.names = res['names']
17
+ self.emails = res['emails']
18
+ self.phone_numbers = res['phone_numbers']
19
+ self.addresses = res['addresses']
20
+ end
21
+ end
22
+
23
+ end
@@ -1,5 +1,6 @@
1
1
  require_relative 'account/account'
2
2
  require_relative 'transaction/transaction'
3
+ require_relative 'info/info'
3
4
  require 'plaid/util'
4
5
  require 'json'
5
6
  module Plaid
@@ -7,15 +8,10 @@ module Plaid
7
8
  include Plaid::Util
8
9
 
9
10
  # Define user vars
10
- attr_accessor(:accounts, :transactions, :access_token, :permissions, :api_res, :pending_mfa_questions, :info)
11
+ attr_accessor(:accounts, :transactions, :access_token, :permissions, :api_res, :pending_mfa_questions, :info, :information)
11
12
 
12
13
  def initialize
13
- self.accounts = []
14
- self.transactions = []
15
- self.permissions = []
16
- self.access_token = ''
17
- self.api_res = ''
18
- self.info = {}
14
+ self.accounts = [], self.transactions = [], self.permissions = [], self.access_token = '', self.api_res = '', self.info = {}, self.information = Information.new
19
15
  end
20
16
 
21
17
  # Instantiate a new user with the results of the successful API call
@@ -46,9 +42,11 @@ module Plaid
46
42
  end
47
43
  end
48
44
 
49
- def get_connect
45
+ def get_connect(options=nil)
50
46
  if self.permissions.include? 'connect'
51
- res = Plaid.post('connect/get',{access_token:self.access_token})
47
+ payload = {access_token:self.access_token}
48
+ payload.merge!(options) if options
49
+ res = Plaid.post('connect/get',payload)
52
50
  build_user(res)
53
51
  else
54
52
  false
@@ -99,33 +97,10 @@ module Plaid
99
97
  def build_user(res,api_level=nil)
100
98
  begin
101
99
  if res[:msg].nil?
102
- res['accounts'].each do |account|
103
- if self.accounts.any? { |h| h == account['_id'] }
104
- owned_account = self.accounts.find { |h| h == account['_id'] }
105
- owned_account.new(account)
106
- else
107
- self.accounts << new_account(account)
108
- end
109
- end if res['accounts']
110
- res['transactions'].each do |transaction|
111
- if self.transactions.any? { |t| t == transaction['_id'] }
112
- owned_transaction = self.transactions.find { |h| h == transaction['_id'] }
113
- owned_transaction.new(transaction)
114
- else
115
- self.transactions << new_transaction(transaction)
116
- end
117
- end if res['transactions']
118
- self.permissions << api_level unless self.permissions.include? api_level && api_level.nil?
119
- self.api_res = 'success'
120
- self.pending_mfa_questions = ''
121
- self.info.merge!(res['info']) if res['info']
122
- self.access_token = res['access_token']
100
+ populate_user(self,res,api_level)
123
101
  clean_up_user(self)
124
102
  else
125
- self.access_token = res[:body]['access_token']
126
- self.pending_mfa_questions = res[:body]
127
- self.api_res = res[:msg]
128
- self.permissions << api_level unless self.permissions.include? api_level && api_level.nil?
103
+ set_mfa_request(self,res,api_level)
129
104
  end
130
105
  rescue => e
131
106
  error_handler(e)
@@ -153,5 +128,42 @@ module Plaid
153
128
  user
154
129
  end
155
130
 
131
+ def set_mfa_request(user,res,api_level)
132
+ user.access_token = res[:body]['access_token']
133
+ user.pending_mfa_questions = res[:body]
134
+ user.api_res = res[:msg]
135
+ user.permissions << api_level unless self.permissions.include? api_level && api_level.nil?
136
+ end
137
+
138
+ def populate_user(user,res,api_level)
139
+ res['accounts'].each do |account|
140
+ if user.accounts.any? { |h| h == account['_id'] }
141
+ owned_account = user.accounts.find { |h| h == account['_id'] }
142
+ owned_account.new(account)
143
+ else
144
+ user.accounts << new_account(account)
145
+ end
146
+ end if res['accounts']
147
+
148
+ res['transactions'].each do |transaction|
149
+ if user.transactions.any? { |t| t == transaction['_id'] }
150
+ owned_transaction = user.transactions.find { |h| h == transaction['_id'] }
151
+ owned_transaction.new(transaction)
152
+ else
153
+ user.transactions << new_transaction(transaction)
154
+ end
155
+ end if res['transactions']
156
+
157
+ user.permissions << api_level unless user.permissions.include? api_level && api_level.nil?
158
+ user.pending_mfa_questions = ''
159
+ user.information.update_info(res['info']) if res['info']
160
+ user.api_res = 'success'
161
+
162
+ # TODO: Remove the following line when upgrading to V-2
163
+ user.info.merge!(res['info']) if res['info']
164
+ # End TODO
165
+ user.access_token = res['access_token']
166
+ end
167
+
156
168
  end
157
169
  end
data/lib/plaid/util.rb CHANGED
@@ -14,13 +14,16 @@ module Plaid
14
14
  def get(path,id=nil)
15
15
  uri = build_uri(path,id)
16
16
  res = Net::HTTP.get(uri)
17
- JSON.parse(res)
17
+ parse_get_response(res)
18
18
  end
19
19
 
20
20
  def patch(path,options={})
21
21
  uri = build_uri(path)
22
22
  options.merge!({client_id: self.instance_variable_get(:'@customer_id') ,secret: self.instance_variable_get(:'@secret')})
23
- res = Net::HTTP.patch(uri,options)
23
+ req = Net::HTTP::Patch.new(uri)
24
+ req.body = URI.encode_www_form(options) if options
25
+ req.content_type = 'multipart/form-data'
26
+ res = Net::HTTP.start(uri.hostname, uri.port, :use_ssl => uri.scheme == 'https') { |http| http.request(req) }
24
27
  parse_response(res)
25
28
  end
26
29
 
@@ -30,7 +33,7 @@ module Plaid
30
33
  req = Net::HTTP::Delete.new(uri)
31
34
  req.body = URI.encode_www_form(options) if options
32
35
  req.content_type = 'multipart/form-data'
33
- res = Net::HTTP.start(uri.hostname, uri.port, :use_ssl => uri.scheme == 'https') { |http| http.request(req) }
36
+ Net::HTTP.start(uri.hostname, uri.port, :use_ssl => uri.scheme == 'https') { |http| http.request(req) }
34
37
  end
35
38
 
36
39
  def error_handler(err,res=nil)
@@ -85,5 +88,22 @@ module Plaid
85
88
  end
86
89
  end
87
90
 
91
+ def parse_get_response(res)
92
+ body = JSON.parse(res)
93
+ if body.class == Array
94
+ body
95
+ else
96
+ if body['code'].nil?
97
+ body
98
+ else
99
+ if body['code'] == 1401 || body['code'] == 1501 || body['code'] == 1601
100
+ error_handler('Not Found',body)
101
+ else
102
+ body
103
+ end
104
+ end
105
+ end
106
+ end
107
+
88
108
  end
89
109
  end
data/lib/plaid/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Plaid
2
- VERSION = '1.2.3'
2
+ VERSION = '1.3.0'
3
3
  end
@@ -0,0 +1,108 @@
1
+ require 'spec_helper.rb'
2
+ # Authentication flow specs - returns Plaid::User
3
+ describe '.add_user' do
4
+
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
+
11
+ context 'has correct credentials for single factor auth, authenticates to the connect level of api access' do
12
+ user = Plaid.add_user('connect','plaid_test','plaid_good','wells')
13
+ it { expect(user.accounts.empty?).to be_falsey }
14
+ end
15
+
16
+ context 'has correct credentials for single factor auth, authenticates to the auth level of api access' do
17
+ user = Plaid.add_user('auth','plaid_test','plaid_good','wells')
18
+ it { expect(user.accounts[0].numbers.nil?).to be_falsey }
19
+ end
20
+
21
+ context 'has correct credentials for single factor auth, authenticates to the info level of api access' do
22
+ user = Plaid.add_user('info','plaid_test','plaid_good','wells')
23
+ it { expect(user.info).to be_truthy }
24
+ end
25
+
26
+ context 'has correct username, but incorrect password for single factor auth under auth level of api access' do
27
+ it { expect{Plaid.add_user('auth','plaid_test','plaid_bad','wells')}.to raise_error }
28
+ end
29
+
30
+ context 'has incorrect username under auth level of api access' do
31
+ it { expect{Plaid.add_user('auth','plaid_bad','plaid_bad','wells')}.to raise_error }
32
+ end
33
+
34
+ context 'has correct username, but incorrect password for single factor auth under connect level of api access' do
35
+ it { expect{Plaid.add_user('connect','plaid_test','plaid_bad','wells')}.to raise_error }
36
+ end
37
+
38
+ context 'has incorrect username under connect level of api access' do
39
+ it { expect{Plaid.add_user('connect','plaid_bad','plaid_bad','wells')}.to raise_error }
40
+ end
41
+
42
+ context 'has correct username, but incorrect password for single factor auth under info level of api access' do
43
+ it { expect{Plaid.add_user('info','plaid_test','plaid_bad','wells')}.to raise_error }
44
+ end
45
+
46
+ context 'has incorrect username under info level of api access' do
47
+ it { expect{Plaid.add_user('info','plaid_bad','plaid_bad','wells')}.to raise_error }
48
+ end
49
+
50
+ context 'enters pin for extra parameter authentication required by certain institutions' do
51
+ user = Plaid.add_user('connect','plaid_test','plaid_good','usaa','1234')
52
+ it { expect(user.api_res).to eq 'Requires further authentication' }
53
+ end
54
+
55
+ context 'enters incorrect pin for extra parameter authentication required by certain institutions' do
56
+ it { expect{Plaid.add_user('connect','plaid_test','plaid_good','usaa','0000')}.to raise_error }
57
+ end
58
+
59
+ context 'has to enter MFA credentials' do
60
+ user = Plaid.add_user('connect','plaid_selections', 'plaid_good','bofa')
61
+ it { expect(user.api_res).to eq 'Requires further authentication' }
62
+ end
63
+
64
+ context 'enters correct information with locked account' do
65
+ user = Plaid.add_user('connect','plaid_selections', 'plaid_locked','wells')
66
+ it { expect(user.api_res).to eq 'User account is locked' }
67
+ end
68
+
69
+ context 'enters webhook option as part of standard call' do
70
+ user = Plaid.add_user('connect','plaid_test', 'plaid_good','wells',{login_only: true, webhook: 'test.com/test.endpoint.aspx'})
71
+ it { expect(user.accounts.empty?).to be_falsey }
72
+ end
73
+
74
+ context 'enters webhook option as part of mfa required institution authentication' do
75
+ user = Plaid.add_user('connect','plaid_selections', 'plaid_good','bofa',{login_only: true, webhook: 'test.com/test.endpoint.aspx'})
76
+ it { expect(user.api_res).to eq 'Requires further authentication' }
77
+ end
78
+
79
+ context 'requests pending transactions from an institution' do
80
+ user = Plaid.add_user('connect','plaid_selections', 'plaid_good','wells',{pending: true})
81
+ it { expect(user.accounts.empty?).to be_falsey }
82
+ end
83
+
84
+ context 'sets the login only option to true' do
85
+ user = Plaid.add_user('connect','plaid_selections', 'plaid_good','wells',{login_only:true})
86
+ it { expect(user.accounts.empty?).to be_falsey }
87
+ end
88
+
89
+ context 'requests a list of options for code based MFA' do
90
+ user = Plaid.add_user('connect','plaid_selections', 'plaid_good','citi',{list: true})
91
+ it { expect(user.pending_mfa_questions.nil?).to be_falsey }
92
+ end
93
+
94
+ context 'sets a start date for transactions' do
95
+ user = Plaid.add_user('connect','plaid_selections', 'plaid_good','wells',{login_only:true, start_date:'10 days ago'})
96
+ it { expect(user.accounts.empty?).to be_falsey }
97
+ end
98
+
99
+ context 'sets an end date for transactions' do
100
+ user = Plaid.add_user('connect','plaid_selections', 'plaid_good','wells',{login_only:true, end_date: '10 days ago'})
101
+ it { expect(user.accounts.empty?).to be_falsey }
102
+ end
103
+
104
+ context 'sets start and end dates for transactions' do
105
+ user = Plaid.add_user('connect','plaid_test','plaid_good','wells',"{'gte':'05/10/2014' , 'lte':'06/10/2014'}")
106
+ it{ expect(user.transactions).to be_truthy }
107
+ end
108
+ end
@@ -0,0 +1,27 @@
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
+
13
+ context 'when a single category is found' do
14
+ category = Plaid.category('17001013')
15
+ it { expect(category.class).to eq (Plaid::Category) }
16
+ end
17
+
18
+ context 'when all categories are found' do
19
+ category = Plaid.category
20
+ it { expect(category).to be_kind_of(Array)}
21
+ end
22
+
23
+ context 'when category is not found' do
24
+ it { expect { Plaid.category('dumb_cat') }.to raise_error }
25
+ end
26
+
27
+ end
@@ -0,0 +1,40 @@
1
+ # Configuration specs - used in gem configuration
2
+ describe '.config' do
3
+ context 'has valid dev keys' do
4
+ Plaid.config do |p|
5
+ p.customer_id = 'test_id'
6
+ p.secret = 'test_secret'
7
+ p.environment_location = 'https://tartan.plaid.com/'
8
+ 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
+
13
+ context 'has valid production keys' do
14
+ Plaid.config do |p|
15
+ p.customer_id = 'test_id'
16
+ p.secret = 'test_secret'
17
+ p.environment_location = 'https://api.plaid.com/'
18
+ end
19
+ res = Plaid.add_user('connect','plaid_test','plaid_good','wells')
20
+ it { expect(res).to be_instance_of Plaid::User }
21
+ end
22
+
23
+ context 'has invalid dev keys' do
24
+ Plaid.config do |p|
25
+ p.customer_id = 'test_id'
26
+ p.secret = 'test_bad'
27
+ p.environment_location = 'https://tartan.plaid.com/'
28
+ end
29
+ it { expect{Plaid.add_user('connect','plaid_bad','plaid_bad','wells')}.to raise_error }
30
+ end
31
+
32
+ context 'has invalid production keys' do
33
+ Plaid.config do |p|
34
+ p.customer_id = 'test_id'
35
+ p.secret = 'test_bad'
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 }
39
+ end
40
+ end
@@ -0,0 +1,25 @@
1
+ # Institution specs
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
11
+
12
+ context 'when a single institution is found' do
13
+ institution = Plaid.institution('5301a93ac140de84910000e0')
14
+ it { expect(institution.class).to eq(Plaid::Institution) }
15
+ end
16
+
17
+ context 'when all institutions are found' do
18
+ institution = Plaid.institution
19
+ it { expect(institution).to be_kind_of(Array) }
20
+ end
21
+
22
+ context 'when institution is not found' do
23
+ it { expect { Plaid.institution('dumb_bank') }.to raise_error }
24
+ end
25
+ end
data/spec/user_spec.rb ADDED
@@ -0,0 +1,155 @@
1
+ require 'spec_helper.rb'
2
+ ########## Plaid instantiated user specs ##########
3
+ describe '#User' do
4
+
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
+
11
+ describe 'user vars' do
12
+
13
+ context 'valid user has accounts and accounts contain id attribute' do
14
+ user = Plaid.add_user('connect','plaid_test','plaid_good','wells')
15
+ it { expect(user.accounts.first.id).to be_truthy }
16
+ end
17
+
18
+ context 'valid user has accounts and accounts contain type attribute' do
19
+ user = Plaid.add_user('connect','plaid_test','plaid_good','wells')
20
+ it { expect(user.accounts.first.type).to eq('depository') }
21
+ end
22
+ end
23
+
24
+ # MFA specs - after user is instantiated,
25
+ describe '#mfa_authentication' do
26
+
27
+ context 'enters correct credentials for MFA auth and authenticates' do
28
+ new_mfa_user = Plaid.add_user('connect','plaid_selections', 'plaid_good','bofa')
29
+ new_mfa_user.mfa_authentication('tomato','bofa')
30
+ it { expect(new_mfa_user.accounts).to be_truthy }
31
+ end
32
+
33
+ context 'has to enter another round of MFA credentials' do
34
+ mfa_again = Plaid.add_user('connect','plaid_selections', 'plaid_good','bofa')
35
+ mfa_again.mfa_authentication('again','bofa')
36
+ it { expect(mfa_again.api_res).to eq 'Requires further authentication' }
37
+ end
38
+
39
+ context 'enters incorrect credentials for MFA auth' do
40
+ mfa_user = Plaid.add_user('connect','plaid_selections', 'plaid_good','bofa')
41
+ mfa_user.mfa_authentication('tomato','bofa')
42
+ mfa_user = Plaid.add_user('connect','plaid_selections', 'plaid_good','bofa')
43
+ it { expect { mfa_user.mfa_authentication('bad','bofa') }.to raise_error }
44
+ end
45
+
46
+ context 'requests list of MFA credentials' do
47
+ new_mfa_user = Plaid.add_user('auth','plaid_test','plaid_good','chase',nil,'{"list":true}')
48
+ it { expect(new_mfa_user.pending_mfa_questions).to eq({"type"=>"list", "mfa"=>[{"mask"=>"xxx-xxx-5309", "type"=>"phone"}, {"mask"=>"t..t@plaid.com", "type"=>"email"}], "access_token"=>"test"}) }
49
+ end
50
+
51
+ context 'selects MFA method and returns successful response' do
52
+ new_mfa_user = Plaid.add_user('auth','plaid_test','plaid_good','chase',nil,'{"list":true}')
53
+ new_mfa_user.select_mfa_method({mask:'xxx-xxx-5309'},'chase')
54
+ it { expect(new_mfa_user.pending_mfa_questions).to eq({"type"=>"device", "mfa"=>{"message"=>"Code sent to xxx-xxx-5309"}, "access_token"=>"test"}) }
55
+ end
56
+
57
+ context 'selects MFA method, and delivers correct payload to authenticate user' do
58
+ new_mfa_user = Plaid.add_user('auth','plaid_test','plaid_good','chase',nil,'{"list":true}')
59
+ new_mfa_user.select_mfa_method({mask:'xxx-xxx-5309'},'chase')
60
+ new_mfa_user.mfa_authentication(1234,'chase')
61
+ it { expect(new_mfa_user.accounts).to be_truthy }
62
+ end
63
+ end
64
+
65
+ # Auth specs
66
+ describe '#get_auth' do
67
+ auth_user = Plaid.add_user('auth','plaid_test','plaid_good','wells')
68
+ connect_user = Plaid.add_user('connect','plaid_test','plaid_good','wells')
69
+
70
+ context 'has access and returns accounts' do
71
+ it { expect(auth_user.permissions[0]).to eq('auth') }
72
+ end
73
+
74
+ context 'does not have access to auth' do
75
+ it{ expect(connect_user.permissions.include? 'auth' ).to be false }
76
+ end
77
+ end
78
+
79
+ # Connect specs
80
+ describe '#get_connect' do
81
+ auth_user = Plaid.add_user('auth','plaid_test','plaid_good','wells')
82
+ connect_user = Plaid.add_user('connect','plaid_test','plaid_good','wells')
83
+
84
+ context 'has access and returns accounts' do
85
+ it { expect(connect_user.permissions[0]).to eq('connect') }
86
+ end
87
+
88
+ context 'does not have access to auth' do
89
+ it{ expect(auth_user.permissions.include? 'connect' ).to be false }
90
+ end
91
+ end
92
+
93
+ # Get info specs
94
+ describe '#get_info' do
95
+ info_user = Plaid.add_user('info','plaid_test','plaid_good','wells')
96
+ auth_user = Plaid.add_user('auth','plaid_test','plaid_good','wells')
97
+
98
+ context 'has access and returns user info' do
99
+ it { expect(info_user.permissions[0]).to eq('info') }
100
+ end
101
+
102
+ context 'does not have access to info' do
103
+ it{ expect(auth_user.permissions.include? 'info' ).to be false }
104
+ end
105
+ end
106
+
107
+ describe '#get_balance' do
108
+ user = Plaid.add_user('info','plaid_test','plaid_good','wells')
109
+ user.update_balance
110
+ context 'updates user accounts' do
111
+ it { expect(user.accounts.empty?).to be_falsey }
112
+ end
113
+
114
+ context 'should not double up accounts or transactions' do
115
+ dup = user.accounts.select{|element| user.accounts.count(element) > 1}
116
+ dup = dup.length + user.transactions.select{|element| user.transactions.count(element) > 1}.length
117
+ it{ expect(dup).to eq(0) }
118
+ end
119
+
120
+ end
121
+
122
+ =begin TODO: This test needs to pass, currently test credentials are failing
123
+ describe '#update_info' do
124
+ info_user = Plaid.add_user('info','plaid_test','plaid_good','wells')
125
+ context 'updates information correctly' do
126
+ it { expect { info_user.update_info('plaid_test','plaid_good') }.to_not raise_error }
127
+ end
128
+ end
129
+ =end
130
+
131
+ describe '#delete_user' do
132
+ info_user = Plaid.add_user('info','plaid_test','plaid_good','wells')
133
+ info_user.delete_user
134
+
135
+ context 'updates information correctly' do
136
+ it { expect { info_user.get_info }.to raise_error }
137
+ end
138
+ end
139
+
140
+ describe '#upgrade' do
141
+ auth_user = Plaid.add_user('auth','plaid_test','plaid_good','wells')
142
+ connect_user = Plaid.add_user('connect','plaid_test','plaid_good','wells')
143
+
144
+ context 'auth upgrade is successful' do
145
+ connect_user.upgrade('auth')
146
+ it { expect{ connect_user.get_auth }.to_not raise_error }
147
+ end
148
+
149
+ context 'connect upgrade is successful' do
150
+ auth_user.upgrade('connect')
151
+ it { expect{ auth_user.get_connect }.to_not raise_error }
152
+ end
153
+ end
154
+
155
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: plaid
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.3
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Crites
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-15 00:00:00.000000000 Z
11
+ date: 2015-03-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -72,13 +72,18 @@ files:
72
72
  - lib/plaid/config.rb
73
73
  - lib/plaid/institution/institution.rb
74
74
  - lib/plaid/user/account/account.rb
75
+ - lib/plaid/user/info/info.rb
75
76
  - lib/plaid/user/transaction/transaction.rb
76
77
  - lib/plaid/user/user.rb
77
78
  - lib/plaid/util.rb
78
79
  - lib/plaid/version.rb
79
80
  - plaid.gemspec
80
- - spec/plaid_spec.rb
81
+ - spec/add_user_spec.rb
82
+ - spec/category_spec.rb
83
+ - spec/config_spec.rb
84
+ - spec/institution_spec.rb
81
85
  - spec/spec_helper.rb
86
+ - spec/user_spec.rb
82
87
  homepage: https://github.com/plaid/plaid-ruby
83
88
  licenses:
84
89
  - MIT
@@ -104,5 +109,9 @@ signing_key:
104
109
  specification_version: 4
105
110
  summary: Ruby bindings for Plaid
106
111
  test_files:
107
- - spec/plaid_spec.rb
112
+ - spec/add_user_spec.rb
113
+ - spec/category_spec.rb
114
+ - spec/config_spec.rb
115
+ - spec/institution_spec.rb
108
116
  - spec/spec_helper.rb
117
+ - spec/user_spec.rb
data/spec/plaid_spec.rb DELETED
@@ -1,526 +0,0 @@
1
- require 'spec_helper.rb'
2
- ########## Plaid specs ##########
3
- describe Plaid do
4
-
5
- # Configuration specs - used in gem configuration
6
- describe '.config' do
7
- context 'has valid dev keys' do
8
- Plaid.config do |p|
9
- p.customer_id = 'test_id'
10
- p.secret = 'test_secret'
11
- p.environment_location = 'https://tartan.plaid.com/'
12
- end
13
- res = Plaid.add_user('connect','plaid_test','plaid_good','wells')
14
- it { expect(res).to be_instance_of Plaid::User }
15
- end
16
-
17
- context 'has valid production keys' do
18
- Plaid.config do |p|
19
- p.customer_id = 'test_id'
20
- p.secret = 'test_secret'
21
- p.environment_location = 'https://api.plaid.com/'
22
- end
23
- res = Plaid.add_user('connect','plaid_test','plaid_good','wells')
24
- it { expect(res).to be_instance_of Plaid::User }
25
- end
26
-
27
- context 'has invalid dev keys' do
28
- Plaid.config do |p|
29
- p.customer_id = 'test_id'
30
- p.secret = 'test_bad'
31
- p.environment_location = 'https://tartan.plaid.com/'
32
- end
33
- it { expect{Plaid.add_user('connect','plaid_bad','plaid_bad','wells')}.to raise_error }
34
- end
35
-
36
- context 'has invalid production keys' do
37
- Plaid.config do |p|
38
- p.customer_id = 'test_id'
39
- p.secret = 'test_bad'
40
- p.environment_location = 'https://api.plaid.com/'
41
- end
42
- it { expect{Plaid.add_user('connect','plaid_bad','plaid_bad','wells')}.to raise_error }
43
- end
44
- end
45
-
46
- # Authentication flow specs - returns Plaid::User
47
- # TODO: Abstract the config from each section with the result in passing tests
48
- describe '.add_user' do
49
-
50
- context 'has correct credentials for single factor auth, authenticates to the connect level of api access' do
51
- Plaid.config do |p|
52
- p.customer_id = 'test_id'
53
- p.secret = 'test_secret'
54
- p.environment_location = 'https://tartan.plaid.com/'
55
- end
56
- user = Plaid.add_user('connect','plaid_test','plaid_good','wells')
57
- it { expect(user.accounts.empty?).to be_falsey }
58
- end
59
-
60
- context 'has correct credentials for single factor auth, authenticates to the auth level of api access' do
61
- Plaid.config do |p|
62
- p.customer_id = 'test_id'
63
- p.secret = 'test_secret'
64
- p.environment_location = 'https://tartan.plaid.com/'
65
- end
66
- user = Plaid.add_user('auth','plaid_test','plaid_good','wells')
67
- it { expect(user.accounts[0].numbers.nil?).to be_falsey }
68
- end
69
-
70
- context 'has correct credentials for single factor auth, authenticates to the info level of api access' do
71
- Plaid.config do |p|
72
- p.customer_id = 'test_id'
73
- p.secret = 'test_secret'
74
- p.environment_location = 'https://tartan.plaid.com/'
75
- end
76
- user = Plaid.add_user('info','plaid_test','plaid_good','wells')
77
- it { expect(user.info).to be_truthy }
78
- end
79
-
80
- context 'has correct username, but incorrect password for single factor auth under auth level of api access' do
81
- Plaid.config do |p|
82
- p.customer_id = 'test_id'
83
- p.secret = 'test_secret'
84
- p.environment_location = 'https://tartan.plaid.com/'
85
- end
86
- it { expect{Plaid.add_user('auth','plaid_test','plaid_bad','wells')}.to raise_error }
87
- end
88
-
89
- context 'has incorrect username under auth level of api access' do
90
- Plaid.config do |p|
91
- p.customer_id = 'test_id'
92
- p.secret = 'test_secret'
93
- p.environment_location = 'https://tartan.plaid.com/'
94
- end
95
- it { expect{Plaid.add_user('auth','plaid_bad','plaid_bad','wells')}.to raise_error }
96
- end
97
-
98
- context 'has correct username, but incorrect password for single factor auth under connect level of api access' do
99
- Plaid.config do |p|
100
- p.customer_id = 'test_id'
101
- p.secret = 'test_secret'
102
- p.environment_location = 'https://tartan.plaid.com/'
103
- end
104
- it { expect{Plaid.add_user('connect','plaid_test','plaid_bad','wells')}.to raise_error }
105
- end
106
-
107
- context 'has incorrect username under connect level of api access' do
108
- Plaid.config do |p|
109
- p.customer_id = 'test_id'
110
- p.secret = 'test_secret'
111
- p.environment_location = 'https://tartan.plaid.com/'
112
- end
113
- it { expect{Plaid.add_user('connect','plaid_bad','plaid_bad','wells')}.to raise_error }
114
- end
115
-
116
- context 'has correct username, but incorrect password for single factor auth under info level of api access' do
117
- Plaid.config do |p|
118
- p.customer_id = 'test_id'
119
- p.secret = 'test_secret'
120
- p.environment_location = 'https://tartan.plaid.com/'
121
- end
122
- it { expect{Plaid.add_user('info','plaid_test','plaid_bad','wells')}.to raise_error }
123
- end
124
-
125
- context 'has incorrect username under info level of api access' do
126
- Plaid.config do |p|
127
- p.customer_id = 'test_id'
128
- p.secret = 'test_secret'
129
- p.environment_location = 'https://tartan.plaid.com/'
130
- end
131
- it { expect{Plaid.add_user('info','plaid_bad','plaid_bad','wells')}.to raise_error }
132
- end
133
-
134
- context 'enters pin for extra parameter authentication required by certain institutions' do
135
- Plaid.config do |p|
136
- p.customer_id = 'test_id'
137
- p.secret = 'test_secret'
138
- p.environment_location = 'https://tartan.plaid.com/'
139
- end
140
- user = Plaid.add_user('connect','plaid_test','plaid_good','usaa','1234')
141
- it { expect(user.api_res).to eq 'Requires further authentication' }
142
- end
143
-
144
- context 'enters incorrect pin for extra parameter authentication required by certain institutions' do
145
- Plaid.config do |p|
146
- p.customer_id = 'test_id'
147
- p.secret = 'test_secret'
148
- p.environment_location = 'https://tartan.plaid.com/'
149
- end
150
- it { expect{Plaid.add_user('connect','plaid_test','plaid_good','usaa','0000')}.to raise_error }
151
- end
152
-
153
- context 'has to enter MFA credentials' do
154
- Plaid.config do |p|
155
- p.customer_id = 'test_id'
156
- p.secret = 'test_secret'
157
- p.environment_location = 'https://tartan.plaid.com/'
158
- end
159
- user = Plaid.add_user('connect','plaid_selections', 'plaid_good','bofa')
160
- it { expect(user.api_res).to eq 'Requires further authentication' }
161
- end
162
-
163
- context 'enters correct information with locked account' do
164
- Plaid.config do |p|
165
- p.customer_id = 'test_id'
166
- p.secret = 'test_secret'
167
- p.environment_location = 'https://tartan.plaid.com/'
168
- end
169
- user = Plaid.add_user('connect','plaid_selections', 'plaid_locked','wells')
170
- it { expect(user.api_res).to eq 'User account is locked' }
171
- end
172
-
173
- context 'enters webhook option as part of standard call' do
174
- Plaid.config do |p|
175
- p.customer_id = 'test_id'
176
- p.secret = 'test_secret'
177
- p.environment_location = 'https://tartan.plaid.com/'
178
- end
179
- user = Plaid.add_user('connect','plaid_test', 'plaid_good','wells',{login_only: true, webhook: 'test.com/test.endpoint.aspx'})
180
- it { expect(user.accounts.empty?).to be_falsey }
181
- end
182
-
183
- context 'enters webhook option as part of mfa required institution authentication' do
184
- Plaid.config do |p|
185
- p.customer_id = 'test_id'
186
- p.secret = 'test_secret'
187
- p.environment_location = 'https://tartan.plaid.com/'
188
- end
189
- user = Plaid.add_user('connect','plaid_selections', 'plaid_good','bofa',{login_only: true, webhook: 'test.com/test.endpoint.aspx'})
190
- it { expect(user.api_res).to eq 'Requires further authentication' }
191
- end
192
-
193
- context 'requests pending transactions from an institution' do
194
- Plaid.config do |p|
195
- p.customer_id = 'test_id'
196
- p.secret = 'test_secret'
197
- p.environment_location = 'https://tartan.plaid.com/'
198
- end
199
- user = Plaid.add_user('connect','plaid_selections', 'plaid_good','wells',{pending: true})
200
- it { expect(user.accounts.empty?).to be_falsey }
201
- end
202
-
203
- context 'sets the login only option to true' do
204
- Plaid.config do |p|
205
- p.customer_id = 'test_id'
206
- p.secret = 'test_secret'
207
- p.environment_location = 'https://tartan.plaid.com/'
208
- end
209
- user = Plaid.add_user('connect','plaid_selections', 'plaid_good','wells',{login_only:true})
210
- it { expect(user.accounts.empty?).to be_falsey }
211
- end
212
-
213
- context 'requests a list of options for code based MFA' do
214
- Plaid.config do |p|
215
- p.customer_id = 'test_id'
216
- p.secret = 'test_secret'
217
- p.environment_location = 'https://tartan.plaid.com/'
218
- end
219
- user = Plaid.add_user('connect','plaid_selections', 'plaid_good','citi',{list: true})
220
- it { expect(user.pending_mfa_questions.nil?).to be_falsey }
221
- end
222
-
223
- context 'sets a start date for transactions' do
224
- Plaid.config do |p|
225
- p.customer_id = 'test_id'
226
- p.secret = 'test_secret'
227
- p.environment_location = 'https://tartan.plaid.com/'
228
- end
229
- user = Plaid.add_user('connect','plaid_selections', 'plaid_good','wells',{login_only:true, start_date:'10 days ago'})
230
- it { expect(user.accounts.empty?).to be_falsey }
231
- end
232
-
233
- context 'sets an end date for transactions' do
234
- Plaid.config do |p|
235
- p.customer_id = 'test_id'
236
- p.secret = 'test_secret'
237
- p.environment_location = 'https://tartan.plaid.com/'
238
- end
239
- user = Plaid.add_user('connect','plaid_selections', 'plaid_good','wells',{login_only:true, end_date: '10 days ago'})
240
- it { expect(user.accounts.empty?).to be_falsey }
241
- end
242
- end
243
-
244
- # Institution specs
245
- describe '#Institution' do
246
- context 'when a single institution is found' do
247
- Plaid.config do |p|
248
- p.customer_id = 'test_id'
249
- p.secret = 'test_secret'
250
- p.environment_location = 'https://tartan.plaid.com/'
251
- end
252
- institution = Plaid.institution('5301a93ac140de84910000e0')
253
- it { expect(institution.class).to eq(Plaid::Institution) }
254
- end
255
-
256
- context 'when all institutions are found' do
257
- Plaid.config do |p|
258
- p.customer_id = 'test_id'
259
- p.secret = 'test_secret'
260
- p.environment_location = 'https://tartan.plaid.com/'
261
- end
262
- institution = Plaid.institution
263
- it { expect(institution).to be_kind_of(Array) }
264
- end
265
-
266
- =begin TODO: Get this test passing
267
- context 'when institution is not found' do
268
- Plaid.config do |p|
269
- p.customer_id = 'test_id'
270
- p.secret = 'test_secret'
271
- p.environment_location = 'https://tartan.plaid.com/'
272
- end
273
- res = Plaid.institution('dumb_bank')
274
- it { expect(res).to eq('Bank not found') }
275
- end
276
- =end
277
- end
278
-
279
- # Category specs
280
- describe '#Category' do
281
- context 'when a single category is found' do
282
- Plaid.config do |p|
283
- p.customer_id = 'test_id'
284
- p.secret = 'test_secret'
285
- p.environment_location = 'https://tartan.plaid.com/'
286
- end
287
- category = Plaid.category('17001013')
288
- it { expect(category.class).to eq (Plaid::Category) }
289
- end
290
-
291
- context 'when all categories are found' do
292
- Plaid.config do |p|
293
- p.customer_id = 'test_id'
294
- p.secret = 'test_secret'
295
- p.environment_location = 'https://tartan.plaid.com/'
296
- end
297
- category = Plaid.category
298
- it { expect(category).to be_kind_of(Array)}
299
- end
300
-
301
- =begin TODO: Get this test passing
302
- context 'when category is not found' do
303
- Plaid.config do |p|
304
- p.customer_id = 'test_id'
305
- p.secret = 'test_secret'
306
- p.environment_location = 'https://tartan.plaid.com/'
307
- end
308
- it { expect { Plaid.category('dumb_cat') }.to raise_error }
309
- end
310
- =end
311
-
312
- end
313
- ########## Plaid instantiated user specs ##########
314
-
315
- describe '#User' do
316
-
317
- describe 'user vars' do
318
-
319
- context 'valid user has accounts and accounts contain id attribute' do
320
- Plaid.config do |p|
321
- p.customer_id = 'test_id'
322
- p.secret = 'test_secret'
323
- p.environment_location = 'https://tartan.plaid.com/'
324
- end
325
- user = Plaid.add_user('connect','plaid_test','plaid_good','wells')
326
- it { expect(user.accounts.first.id).to be_truthy }
327
- end
328
-
329
- context 'valid user has accounts and accounts contain type attribute' do
330
- Plaid.config do |p|
331
- p.customer_id = 'test_id'
332
- p.secret = 'test_secret'
333
- p.environment_location = 'https://tartan.plaid.com/'
334
- end
335
- user = Plaid.add_user('connect','plaid_test','plaid_good','wells')
336
- it { expect(user.accounts.first.type).to eq('depository') }
337
- end
338
- end
339
-
340
- # MFA specs - after user is instantiated,
341
- describe '#mfa_authentication' do
342
-
343
- context 'enters correct credentials for MFA auth and authenticates' do
344
- Plaid.config do |p|
345
- p.customer_id = 'test_id'
346
- p.secret = 'test_secret'
347
- p.environment_location = 'https://tartan.plaid.com/'
348
- end
349
- new_mfa_user = Plaid.add_user('connect','plaid_selections', 'plaid_good','bofa')
350
- new_mfa_user.mfa_authentication('tomato','bofa')
351
- it { expect(new_mfa_user.accounts).to be_truthy }
352
- end
353
-
354
- context 'has to enter another round of MFA credentials' do
355
- Plaid.config do |p|
356
- p.customer_id = 'test_id'
357
- p.secret = 'test_secret'
358
- p.environment_location = 'https://tartan.plaid.com/'
359
- end
360
- mfa_again = Plaid.add_user('connect','plaid_selections', 'plaid_good','bofa')
361
- mfa_again.mfa_authentication('again','bofa')
362
- it { expect(mfa_again.api_res).to eq 'Requires further authentication' }
363
- end
364
-
365
- context 'enters incorrect credentials for MFA auth' do
366
- Plaid.config do |p|
367
- p.customer_id = 'test_id'
368
- p.secret = 'test_secret'
369
- p.environment_location = 'https://tartan.plaid.com/'
370
- end
371
- mfa_user = Plaid.add_user('connect','plaid_selections', 'plaid_good','bofa')
372
- mfa_user.mfa_authentication('tomato','bofa')
373
- mfa_user = Plaid.add_user('connect','plaid_selections', 'plaid_good','bofa')
374
- it { expect { mfa_user.mfa_authentication('bad','bofa') }.to raise_error }
375
- end
376
-
377
- context 'requests list of MFA credentials' do
378
- Plaid.config do |p|
379
- p.customer_id = 'test_id'
380
- p.secret = 'test_secret'
381
- p.environment_location = 'https://tartan.plaid.com/'
382
- end
383
-
384
- new_mfa_user = Plaid.add_user('auth','plaid_test','plaid_good','chase',nil,'{"list":true}')
385
- it { expect(new_mfa_user.pending_mfa_questions).to eq({"type"=>"list", "mfa"=>[{"mask"=>"xxx-xxx-5309", "type"=>"phone"}, {"mask"=>"t..t@plaid.com", "type"=>"email"}], "access_token"=>"test"}) }
386
- end
387
-
388
- context 'selects MFA method and returns successful response' do
389
- Plaid.config do |p|
390
- p.customer_id = 'test_id'
391
- p.secret = 'test_secret'
392
- p.environment_location = 'https://tartan.plaid.com/'
393
- end
394
-
395
- new_mfa_user = Plaid.add_user('auth','plaid_test','plaid_good','chase',nil,'{"list":true}')
396
- new_mfa_user.select_mfa_method({mask:'xxx-xxx-5309'},'chase')
397
- it { expect(new_mfa_user.pending_mfa_questions).to eq({"type"=>"device", "mfa"=>{"message"=>"Code sent to xxx-xxx-5309"}, "access_token"=>"test"}) }
398
- end
399
-
400
- context 'selects MFA method, and delivers correct payload to authenticate user' do
401
- Plaid.config do |p|
402
- p.customer_id = 'test_id'
403
- p.secret = 'test_secret'
404
- p.environment_location = 'https://tartan.plaid.com/'
405
- end
406
-
407
- new_mfa_user = Plaid.add_user('auth','plaid_test','plaid_good','chase',nil,'{"list":true}')
408
- new_mfa_user.select_mfa_method({mask:'xxx-xxx-5309'},'chase')
409
- new_mfa_user.mfa_authentication(1234,'chase')
410
- it { expect(new_mfa_user.accounts).to be_truthy }
411
- end
412
- end
413
-
414
- # Auth specs
415
- describe '#get_auth' do
416
- auth_user = Plaid.add_user('auth','plaid_test','plaid_good','wells')
417
- connect_user = Plaid.add_user('connect','plaid_test','plaid_good','wells')
418
-
419
- context 'has access and returns accounts' do
420
- it { expect(auth_user.permissions[0]).to eq('auth') }
421
- end
422
-
423
- context 'does not have access to auth' do
424
- it{ expect(connect_user.permissions.include? 'auth' ).to be false }
425
- end
426
- end
427
-
428
- # Connect specs
429
- describe '#get_connect' do
430
- auth_user = Plaid.add_user('auth','plaid_test','plaid_good','wells')
431
- connect_user = Plaid.add_user('connect','plaid_test','plaid_good','wells')
432
-
433
- context 'has access and returns accounts' do
434
- it { expect(connect_user.permissions[0]).to eq('connect') }
435
- end
436
-
437
- context 'does not have access to auth' do
438
- it{ expect(auth_user.permissions.include? 'connect' ).to be false }
439
- end
440
- end
441
-
442
- # Get info specs
443
- describe '#get_info' do
444
- Plaid.config do |p|
445
- p.customer_id = 'test_id'
446
- p.secret = 'test_secret'
447
- p.environment_location = 'https://tartan.plaid.com/'
448
- end
449
- info_user = Plaid.add_user('info','plaid_test','plaid_good','wells')
450
- auth_user = Plaid.add_user('auth','plaid_test','plaid_good','wells')
451
-
452
- context 'has access and returns user info' do
453
- it { expect(info_user.permissions[0]).to eq('info') }
454
- end
455
-
456
- context 'does not have access to info' do
457
- it{ expect(auth_user.permissions.include? 'info' ).to be false }
458
- end
459
- end
460
-
461
- describe '#get_balance' do
462
- Plaid.config do |p|
463
- p.customer_id = 'test_id'
464
- p.secret = 'test_secret'
465
- p.environment_location = 'https://tartan.plaid.com/'
466
- end
467
-
468
- user = Plaid.add_user('info','plaid_test','plaid_good','wells')
469
- user.update_balance
470
- context 'updates user accounts' do
471
- it { expect(user.accounts.empty?).to be_falsey }
472
- end
473
-
474
- context 'should not double up accounts or transactions' do
475
- dup = user.accounts.select{|element| user.accounts.count(element) > 1}
476
- dup = dup.length + user.transactions.select{|element| user.transactions.count(element) > 1}.length
477
- it{ expect(dup).to eq(0) }
478
- end
479
-
480
- end
481
-
482
- =begin
483
- describe '#update_info' do
484
- info_user = Plaid.add_user('info','plaid_test','plaid_good','wells')
485
-
486
- context 'updates information correctly' do
487
- it { expect { info_user.update_info('info','plaid_test','plaid_new','wells') }.to be_truthy }
488
- end
489
- end
490
- =end
491
-
492
- describe '#delete_user' do
493
- Plaid.config do |p|
494
- p.customer_id = 'test_id'
495
- p.secret = 'test_secret'
496
- p.environment_location = 'https://tartan.plaid.com/'
497
- end
498
-
499
- info_user = Plaid.add_user('info','plaid_test','plaid_good','wells')
500
- info_user.delete_user
501
-
502
- context 'updates information correctly' do
503
- it { expect { info_user.get_info }.to raise_error }
504
- end
505
- end
506
-
507
- # Upgrade specs - either pass or fails
508
- =begin TODO: Write upgrade methods to pass without paying
509
- describe '#upgrade' do
510
- auth_user = Plaid.add_user('auth','plaid_test','plaid_good','wells')
511
- connect_user = Plaid.add_user('connect','plaid_test','plaid_good','wells')
512
-
513
- context 'auth upgrade is successful' do
514
- connect_user.upgrade
515
- it { expect(connect_user.get_auth).to be_truthy }
516
- end
517
-
518
- context 'connect upgrade is successful' do
519
- auth_user.upgrade
520
- it { expect(auth_user.get_connect).to be_truthy }
521
- end
522
- end
523
- =end
524
-
525
- end
526
- end