plaid 0.1.6 → 1.0.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: e809fa56df8552695b93076d9d4e657301214dce
4
- data.tar.gz: 599f6ceeb4e92f61fe31a93e28babac8726a067d
3
+ metadata.gz: 177a3e175a0defda0b9303805fe7f1f841d161d6
4
+ data.tar.gz: addfdce9ab4abe67eb4fa0478a83e56e5e09172e
5
5
  SHA512:
6
- metadata.gz: 491571f86e7ff9f2bd61e0cc58e4088a79dcc92a118c69686863296882dfe5c5f0d3a3d57e477d4c48cc1e76d049e5a0571aafac08ab8f2129cfebda35373468
7
- data.tar.gz: 50d6b0fabe1074af7a13590b038192d29bcef0846e4717f305fbaa6077a7382811c7fdf76e101aa0f6b717c7a43efd56cded725cac97604d4e2e4d6de1f21bdc
6
+ metadata.gz: 578a30e11a1c222c77a8c8cc6d5877400cd77d25cca5d898ade5e2f2fc5092d2fb248c874676999ab134911804724c7a23e3ef96af53b755056427c71cabe92c
7
+ data.tar.gz: e0e2213f052cb3641f715603ee0991cb24ee1edae76c5d913ecc3aabcddaf6bd7be5b10cd4841c4aeceff5209b6477a48080529ab12faaa25b35a2b9f525d674
data/.gitignore ADDED
@@ -0,0 +1,15 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ .idea
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in plaid.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Justin Crites
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,31 @@
1
+ # Plaid
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'plaid'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install plaid
20
+
21
+ ## Usage
22
+
23
+ TODO: Write usage instructions here
24
+
25
+ ## Contributing
26
+
27
+ 1. Fork it ( https://github.com/[my-github-username]/plaid/fork )
28
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
29
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
30
+ 4. Push to the branch (`git push origin my-new-feature`)
31
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require 'rake'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/lib/plaid.rb CHANGED
@@ -1,20 +1,43 @@
1
+ require 'plaid/version'
1
2
  require 'plaid/config'
2
- require 'plaid/call'
3
- require 'plaid/customer'
4
- require 'rest_client'
3
+ require 'plaid/util'
4
+
5
+ require 'plaid/auth'
6
+ require 'plaid/user/user'
7
+ require 'plaid/institution/institution'
8
+ require 'plaid/category/category'
9
+
5
10
  module Plaid
11
+ # Define an instance of the gem thus responding with one customer at a time
6
12
  class << self
13
+ # Include the SDK methods
14
+
15
+ # Configures the gem with the public, private, and environment vars
7
16
  include Plaid::Configure
8
17
 
9
- # Defined when a user exists with a unique access_token. Ex: Plaid.customer.get_transactions
10
- def customer
11
- @customer = Plaid::Customer.new
18
+ # Include the utility classes used throughout the gem
19
+ include Plaid::Util
20
+
21
+ # Includes the method to authenticate the user. Defined in auth.rb
22
+ include Plaid::Auth
23
+
24
+ # Builds the user object and returns on successful authentication
25
+ def user(res)
26
+ @user = Plaid::User.new
27
+ @user.new(res)
28
+ end
29
+
30
+ # Builds an institution object and returns when the institution details exist
31
+ def institution(res)
32
+ @institution = Plaid::Institution.new
33
+ @institution.new(res)
12
34
  end
13
35
 
14
- # Defined for generic calls without access_tokens required. Ex: Plaid.call.add_accounts(username,password,type)
15
- def call
16
- @call = Plaid::Call.new
36
+ # Builds an institution object and returns when the category details exist
37
+ def category(res)
38
+ @category = Plaid::Category.new
39
+ @category.new(res)
17
40
  end
18
41
 
19
42
  end
20
- end
43
+ end
data/lib/plaid/auth.rb ADDED
@@ -0,0 +1,12 @@
1
+ module Plaid
2
+ module Auth
3
+ def auth(api_level,username,password,type)
4
+ begin
5
+ res = self.post(api_level,username,password,type)
6
+ self.user(res)
7
+ rescue => e
8
+ error_handler(e)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,36 @@
1
+ require 'plaid/util'
2
+ module Plaid
3
+ class Category
4
+ include Plaid::Util
5
+
6
+ attr_accessor(:type, :hierarchy, :id)
7
+
8
+ # Returns an instantiated category object, or an array of all categories
9
+ def new(id=nil)
10
+ res = get('categories',id)
11
+ id.nil? ? cat = instantiate_all_categories(res) : cat = instantiate_one_category(res)
12
+ cat
13
+ end
14
+
15
+ def instantiate_all_categories(res)
16
+ cat_array = []
17
+ res['category'].each do |cat|
18
+ @category = Category.new
19
+ cat_array << @category.build_category(cat)
20
+ end
21
+ cat_array
22
+ end
23
+
24
+ def instantiate_one_category(res)
25
+ @category = Category.new
26
+ @category.build_category(res)
27
+ end
28
+
29
+ protected
30
+
31
+ def build_category(cat)
32
+ self.type = cat['type'], self.hierarchy = cat['hierarchy'], self.id = cat['id']
33
+ end
34
+
35
+ end
36
+ end
data/lib/plaid/config.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  module Plaid
2
2
  module Configure
3
- attr_writer :customer_id, :secret
3
+ attr_writer :customer_id, :secret, :environment_location
4
4
 
5
- KEYS = [:customer_id, :secret]
5
+ KEYS = [:customer_id, :secret, :environment_location]
6
6
 
7
7
  def config
8
8
  yield self
@@ -10,4 +10,4 @@ module Plaid
10
10
  end
11
11
 
12
12
  end
13
- end
13
+ end
@@ -0,0 +1,36 @@
1
+ require 'plaid/util'
2
+ module Plaid
3
+ class Institution
4
+ include Plaid::Util
5
+
6
+ attr_accessor(:id, :name, :type, :has_mfa, :mfa)
7
+
8
+ # Returns an instantiated category object, or an array of all categories
9
+ def new(id=nil)
10
+ res = get('institutions',id)
11
+ id.nil? ? cat = instantiate_all_institutions(res) : cat = instantiate_one_institution(res)
12
+ cat
13
+ end
14
+
15
+ def instantiate_all_institutions(res)
16
+ inst_array = []
17
+ res['institution'].each do |inst|
18
+ @institution = Institution.new
19
+ inst_array << @institution.build_institution(inst)
20
+ end
21
+ inst_array
22
+ end
23
+
24
+ def instantiate_one_institution(res)
25
+ @category = Institution.new
26
+ @category.build_institution(res)
27
+ end
28
+
29
+ protected
30
+
31
+ def build_institution(cat)
32
+ self.id = cat['id'], self.name = cat['name'], self.type = cat['type'], self.has_mfa = cat['has_mfa'], self.mfa = cat['mfa']
33
+ end
34
+
35
+ end
36
+ end
@@ -0,0 +1,23 @@
1
+ require 'plaid/util'
2
+ module Plaid
3
+ class Account
4
+ include Plaid::Util
5
+ # Define vars for user accounts
6
+ attr_accessor(:available_balance, :current_balance, :institution_type, :meta, :transactions, :numbers, :name)
7
+
8
+ # Instantiate a new account with the results of the successful API call
9
+ # Build an array of nested transactions, and return self if successful
10
+ def new(res)
11
+ begin
12
+ self.name = res['name'], self.available_balance = res['balance']['available'], self.current_balance = res['balance']['current'], self.institution_type = res['institution_type']
13
+ self.meta = res['meta'] if res['meta']
14
+ res['numbers'] ? self.numbers = res['numbers'] : self.numbers = 'Upgrade user to access routing information for this account'
15
+ rescue => e
16
+ error_handler(e)
17
+ else
18
+ self
19
+ end
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,19 @@
1
+ require 'plaid/util'
2
+ module Plaid
3
+ class Transaction
4
+ include Plaid::Util
5
+ # Define vars for user accounts
6
+ attr_accessor(:id, :account, :amount, :name, :meta, :location, :pending, :score, :type, :category, :category_id)
7
+
8
+ # Instantiate a new account with the results of the successful API call
9
+ # Build an array of nested transactions, and return self if successful
10
+ def new(res)
11
+ begin
12
+ self.id = res['_id'], self.account = res['_account'], self.amount = res['amount'], self.name = res['name'], self.meta = res['meta'], self.location = res['location'], self.pending = res['pending'], self.score = res['score'], self.type = res['type'], self.category = res['category'], self.category_id = res['category_id']
13
+ rescue => e
14
+ error_handler(e)
15
+ end
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,54 @@
1
+ require_relative 'account/account'
2
+ require_relative 'transaction/transaction'
3
+ require 'plaid/util'
4
+ module Plaid
5
+ class User
6
+ include Plaid::Util
7
+
8
+ # Define user vars
9
+ attr_accessor(:accounts, :transactions, :access_token)
10
+
11
+ def initialize
12
+ self.accounts = []
13
+ self.transactions = []
14
+ self.access_token = ''
15
+ end
16
+
17
+ # Instantiate a new user with the results of the successful API call
18
+ # Build an array of nested accounts, and return self if successful
19
+ def new(res)
20
+ begin
21
+ self.access_token = res['access_token']
22
+ if res['msg'].nil?
23
+ res['accounts'].each do |account|
24
+ self.accounts << new_account(account)
25
+ end if res['accounts']
26
+ res['transactions'].each do |transaction|
27
+ self.transactions << new_transaction(transaction)
28
+ end if res['transactions']
29
+ else
30
+ self.accounts = res.msg, self.transactions = res.msg
31
+ end
32
+ rescue => e
33
+ error_handler(e)
34
+ else
35
+ self
36
+ end
37
+ end
38
+
39
+ protected
40
+
41
+ # Instantiate and build a new account object, return this to the accounts array
42
+ def new_account(account)
43
+ @account = Account.new
44
+ @account.new(account)
45
+ end
46
+
47
+ # Instantiate and build a new account object, return this to the accounts array
48
+ def new_transaction(transaction)
49
+ @transaction = Transaction.new
50
+ @transaction.new(transaction)
51
+ end
52
+
53
+ end
54
+ end
data/lib/plaid/util.rb ADDED
@@ -0,0 +1,67 @@
1
+ require 'net/http'
2
+ require 'json'
3
+ require 'uri'
4
+ module Plaid
5
+ module Util
6
+
7
+ def post(path,username,password,type,options={})
8
+ uri = build_uri(path)
9
+ res = Net::HTTP.post_form(uri, {client_id: self.instance_variable_get(:'@customer_id') ,secret: self.instance_variable_get(:'@secret'), username: username, password: password, type: type})
10
+ parse_response(res)
11
+ end
12
+
13
+ def get(path,id=nil)
14
+ uri = build_uri(path,id)
15
+ res = Net::HTTP.get(uri)
16
+ parse_response(res)
17
+ end
18
+
19
+ def error_handler(err,res=nil)
20
+ case err
21
+ when 'Bad Request'
22
+ raise 'The request was malformed. Did you check the API docs?'
23
+ when 'Unauthorized'
24
+ raise 'Access denied: Try using the correct credentials.'
25
+ when 'Request Failed'
26
+ raise 'Request Failed'
27
+ when 'Not Found'
28
+ raise 'Not Found'
29
+ else
30
+ raise err
31
+ end
32
+ end
33
+
34
+ protected
35
+
36
+ def build_uri(path,id=nil)
37
+ id ? URI.parse(self.instance_variable_get(:'@environment_location') + path + id) :
38
+ URI.parse(self.instance_variable_get(:'@environment_location') + path)
39
+ end
40
+
41
+ private
42
+
43
+ def parse_response(res)
44
+ body = JSON.parse(res.body)
45
+ case res.code
46
+ when '200'
47
+ return body
48
+ when '201'
49
+ return { msg: 'Requires further authentication', body: body}
50
+ when '400'
51
+ error_handler('Bad Request',res)
52
+ when '401'
53
+ error_handler('Unauthorized',res)
54
+ when '402'
55
+ if body['code'] == 1205
56
+ return { msg: 'User account is locked', body: body }
57
+ else
58
+ error_handler('Request Failed',res)
59
+ end
60
+ when '404'
61
+ error_handler('Not Found',res)
62
+ else
63
+ error_handler('Server Error',res)
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,3 @@
1
+ module Plaid
2
+ VERSION = '1.0.0'
3
+ end
data/plaid.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'plaid/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'plaid'
7
+ spec.version = Plaid::VERSION
8
+ spec.authors = ['Justin Crites']
9
+ spec.email = ['crites.justin@gmail.com']
10
+ spec.summary = 'Ruby bindings for Plaid'
11
+ spec.description = 'Ruby gem wrapper for the Plaid API. Read more at the homepage, the wiki, or the plaid documentation.'
12
+ spec.homepage = 'https://github.com/plaid/plaid-ruby'
13
+ spec.license = 'MIT'
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ['lib']
19
+
20
+ spec.add_development_dependency 'bundler', '~> 1.7'
21
+ spec.add_development_dependency 'rake', '~> 10.0'
22
+ spec.add_development_dependency 'rspec', '~>3.1'
23
+ end
@@ -0,0 +1,252 @@
1
+ require 'spec_helper.rb'
2
+ ########## Plaid specs ##########
3
+ describe Plaid do
4
+ # Configuration specs - used in gem configuration
5
+ describe '.config' do
6
+ context 'has valid dev keys' do
7
+ Plaid.config do |p|
8
+ p.customer_id = 'test_id'
9
+ p.secret = 'test_secret'
10
+ p.environment_location = 'https://tartan.plaid.com/'
11
+ end
12
+ res = Plaid.auth('connect','plaid_test','plaid_good','wells')
13
+ it { expect(res).to be instance_of Plaid::User }
14
+ end
15
+
16
+ context 'has valid production keys' do
17
+ Plaid.config do |p|
18
+ p.customer_id = 'test_id'
19
+ p.secret = 'test_secret'
20
+ p.environment_location = 'https://api.plaid.com/'
21
+ end
22
+ #TODO: Test production level credentials
23
+ res = Plaid.auth('connect','plaid_test','plaid_good','wells')
24
+ it { expect(res).to raise_error }
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.auth('connect','plaid_test','plaid_good','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.auth('connect','plaid_test','plaid_good','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 '.auth' do
49
+
50
+ context 'has correct credentials for single factor auth, authenticates to the connect path' 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.auth('connect','plaid_test','plaid_good','wells')
57
+ it { expect(user.accounts.blank?).to be_false }
58
+ end
59
+
60
+ context 'has correct credentials for single factor auth, authenticates to the auth path' 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.auth('auth','plaid_test','plaid_good','wells')
67
+ it { expect(user.accounts[0].numbers.nil?).to be_false }
68
+ end
69
+
70
+ context 'has correct username, but incorrect password for single factor auth under auth path' 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
+ it { expect(Plaid.auth('auth','plaid_test','plaid_bad','wells')).to raise_error }
77
+ end
78
+
79
+ context 'has incorrect username under auth path' do
80
+ Plaid.config do |p|
81
+ p.customer_id = 'test_id'
82
+ p.secret = 'test_secret'
83
+ p.environment_location = 'https://tartan.plaid.com/'
84
+ end
85
+ it { expect(Plaid.auth('auth','plaid_bad','plaid_bad','wells')).to raise_error }
86
+ end
87
+
88
+ context 'has correct username, but incorrect password for single factor auth under connect path' do
89
+ Plaid.config do |p|
90
+ p.customer_id = 'test_id'
91
+ p.secret = 'test_secret'
92
+ p.environment_location = 'https://tartan.plaid.com/'
93
+ end
94
+ it { expect(Plaid.auth('connect','plaid_test','plaid_bad','wells')).to raise_error }
95
+ end
96
+
97
+ context 'has incorrect username under connect path' do
98
+ Plaid.config do |p|
99
+ p.customer_id = 'test_id'
100
+ p.secret = 'test_secret'
101
+ p.environment_location = 'https://tartan.plaid.com/'
102
+ end
103
+ it { expect(Plaid.auth('connect','plaid_bad','plaid_bad','wells')).to raise_error }
104
+ end
105
+
106
+ context 'has to enter MFA credentials' do
107
+ Plaid.config do |p|
108
+ p.customer_id = 'test_id'
109
+ p.secret = 'test_secret'
110
+ p.environment_location = 'https://tartan.plaid.com/'
111
+ end
112
+ user = Plaid.auth('connect','plaid_selections', 'plaid_good','wells')
113
+ it { expect(user.accounts).to eq 'Requires further authentication' }
114
+ end
115
+
116
+ context 'enters correct information with locked account' 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
+ user = Plaid.auth('connect','plaid_selections', 'plaid_locked','wells')
123
+ it { expect(user.accounts).to eq 'User account is locked' }
124
+ end
125
+ end
126
+
127
+ =begin
128
+ TODO: Finish up these tests
129
+ # Institution specs
130
+ describe Plaid::Institution do
131
+
132
+ context 'when institution is found' do
133
+ Plaid.config do |p|
134
+ p.customer_id = 'test_id'
135
+ p.secret = 'test_secret'
136
+ p.environment_location = 'https://tartan.plaid.com/'
137
+ end
138
+ institution = Plaid.institution('amex')
139
+ it { expect(institution).to be instance_of Plaid::Institution }
140
+ end
141
+
142
+ context 'when institution is not found' do
143
+ Plaid.config do |p|
144
+ p.customer_id = 'test_id'
145
+ p.secret = 'test_secret'
146
+ p.environment_location = 'https://tartan.plaid.com/'
147
+ end
148
+ it { expect(Plaid.institution('dumb_bank')).to raise_error }
149
+ end
150
+ end
151
+
152
+ # Category specs
153
+ describe Plaid::Category do
154
+
155
+ context 'when category is found' do
156
+ Plaid.config do |p|
157
+ p.customer_id = 'test_id'
158
+ p.secret = 'test_secret'
159
+ p.environment_location = 'https://tartan.plaid.com/'
160
+ end
161
+ category = Plaid.category('17001013')
162
+ it { expect(category).to be instance_of Plaid::Category }
163
+ end
164
+
165
+ context 'when category is not found' do
166
+ Plaid.config do |p|
167
+ p.customer_id = 'test_id'
168
+ p.secret = 'test_secret'
169
+ p.environment_location = 'https://tartan.plaid.com/'
170
+ end
171
+ it { expect(Plaid.category('dumb_cat')).to raise_error }
172
+ end
173
+
174
+ end
175
+ end
176
+
177
+ ########## Plaid instantiated user specs ##########
178
+
179
+ describe Plaid::User do
180
+ subject(:success_user) { Plaid.auth('connect','plaid_test','plaid_good','wells') }
181
+ subject(:mfa_user) { Plaid.auth('connect','plaid_selections', 'plaid_good','wells') }
182
+
183
+ # MFA specs - after user is instantiated,
184
+ describe '#mfa_authentication' do
185
+ context 'has to enter another round of MFA credentials' do
186
+ res = user.mfa_authenticaiton('again')
187
+ expect(res).to eq 'Another round requested'
188
+ end
189
+
190
+ context 'enters correct credentials for MFA auth and authenticates' do
191
+ user.mfa_authentication('tomato')
192
+ expect(user.accounts).to be_truthy
193
+ end
194
+
195
+ context 'enters incorrect credentials for MFA auth' do
196
+ res = user.mfa_authentication('bad')
197
+ expect(res).to eq 'Incorrect answer to MFA'
198
+ end
199
+ end
200
+
201
+ # Upgrade specs - either pass or fails
202
+ describe '#upgrade' do
203
+ context 'auth upgrade is successful' do
204
+ user.upgrade('auth')
205
+ expect(user.auth).to be true
206
+ end
207
+
208
+ context 'auth upgrade failed' do
209
+ user.upgrade('auth')
210
+ expect(user.auth).to be false
211
+ end
212
+
213
+ context 'connect upgrade is successful' do
214
+ user.upgrade('connect')
215
+ expect(user.auth).to be true
216
+ end
217
+
218
+ context 'connect upgrade failed' do
219
+ user.upgrade('connect')
220
+ expect(user.auth).to be false
221
+ end
222
+ end
223
+
224
+ # Auth specs
225
+ describe '#auth' do
226
+ context 'has access and returns accounts' do
227
+ auth = user.auth
228
+ expect(auth).to be true
229
+ expect(user.accounts).to be_truthy
230
+ end
231
+
232
+ context 'does not have access to auth' do
233
+ auth = user.auth
234
+ expect(auth).to be false
235
+ end
236
+ end
237
+
238
+ # Connect specs
239
+ describe '#connect' do
240
+ context 'has access and returns accounts' do
241
+ expect(user.connect).to be true
242
+ expect(user.transactions).to be_truthy
243
+ end
244
+
245
+ context 'does not have access to auth' do
246
+ expect(user.connect).to be false
247
+ end
248
+ end
249
+
250
+ =end
251
+
252
+ end
@@ -0,0 +1,4 @@
1
+ require 'bundler/setup'
2
+ Bundler.setup
3
+
4
+ require 'plaid'
metadata CHANGED
@@ -1,83 +1,83 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: plaid
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Crites
8
- - Gamble McAdam
9
- - Rahul Ramakrishnan
10
8
  autorequire:
11
9
  bindir: bin
12
10
  cert_chain: []
13
- date: 2014-04-11 00:00:00.000000000 Z
11
+ date: 2015-01-22 00:00:00.000000000 Z
14
12
  dependencies:
15
13
  - !ruby/object:Gem::Dependency
16
- name: rest-client
14
+ name: bundler
17
15
  requirement: !ruby/object:Gem::Requirement
18
16
  requirements:
19
- - - ">="
17
+ - - "~>"
20
18
  - !ruby/object:Gem::Version
21
- version: '0'
22
- type: :runtime
23
- prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
25
- requirements:
26
- - - ">="
27
- - !ruby/object:Gem::Version
28
- version: '0'
29
- - !ruby/object:Gem::Dependency
30
- name: json
31
- requirement: !ruby/object:Gem::Requirement
32
- requirements:
33
- - - ">="
34
- - !ruby/object:Gem::Version
35
- version: '0'
36
- type: :runtime
19
+ version: '1.7'
20
+ type: :development
37
21
  prerelease: false
38
22
  version_requirements: !ruby/object:Gem::Requirement
39
23
  requirements:
40
- - - ">="
24
+ - - "~>"
41
25
  - !ruby/object:Gem::Version
42
- version: '0'
26
+ version: '1.7'
43
27
  - !ruby/object:Gem::Dependency
44
28
  name: rake
45
29
  requirement: !ruby/object:Gem::Requirement
46
30
  requirements:
47
- - - ">="
31
+ - - "~>"
48
32
  - !ruby/object:Gem::Version
49
- version: '0'
33
+ version: '10.0'
50
34
  type: :development
51
35
  prerelease: false
52
36
  version_requirements: !ruby/object:Gem::Requirement
53
37
  requirements:
54
- - - ">="
38
+ - - "~>"
55
39
  - !ruby/object:Gem::Version
56
- version: '0'
40
+ version: '10.0'
57
41
  - !ruby/object:Gem::Dependency
58
42
  name: rspec
59
43
  requirement: !ruby/object:Gem::Requirement
60
44
  requirements:
61
- - - ">="
45
+ - - "~>"
62
46
  - !ruby/object:Gem::Version
63
- version: '0'
47
+ version: '3.1'
64
48
  type: :development
65
49
  prerelease: false
66
50
  version_requirements: !ruby/object:Gem::Requirement
67
51
  requirements:
68
- - - ">="
52
+ - - "~>"
69
53
  - !ruby/object:Gem::Version
70
- version: '0'
71
- description: Ruby Gem wrapper for Plaid API.
72
- email: justin@guavatext.com
54
+ version: '3.1'
55
+ description: Ruby gem wrapper for the Plaid API. Read more at the homepage, the wiki,
56
+ or the plaid documentation.
57
+ email:
58
+ - crites.justin@gmail.com
73
59
  executables: []
74
60
  extensions: []
75
61
  extra_rdoc_files: []
76
62
  files:
63
+ - ".gitignore"
64
+ - Gemfile
65
+ - LICENSE.txt
66
+ - README.md
67
+ - Rakefile
77
68
  - lib/plaid.rb
78
- - lib/plaid/call.rb
69
+ - lib/plaid/auth.rb
70
+ - lib/plaid/category/category.rb
79
71
  - lib/plaid/config.rb
80
- - lib/plaid/customer.rb
72
+ - lib/plaid/institution/institution.rb
73
+ - lib/plaid/user/account/account.rb
74
+ - lib/plaid/user/transaction/transaction.rb
75
+ - lib/plaid/user/user.rb
76
+ - lib/plaid/util.rb
77
+ - lib/plaid/version.rb
78
+ - plaid.gemspec
79
+ - spec/plaid_spec.rb
80
+ - spec/spec_helper.rb
81
81
  homepage: https://github.com/plaid/plaid-ruby
82
82
  licenses:
83
83
  - MIT
@@ -101,5 +101,7 @@ rubyforge_project:
101
101
  rubygems_version: 2.2.2
102
102
  signing_key:
103
103
  specification_version: 4
104
- summary: Plaid Ruby Gem
105
- test_files: []
104
+ summary: Ruby bindings for Plaid
105
+ test_files:
106
+ - spec/plaid_spec.rb
107
+ - spec/spec_helper.rb
data/lib/plaid/call.rb DELETED
@@ -1,83 +0,0 @@
1
- module Plaid
2
- class Call
3
-
4
- BASE_URL = 'https://tartan.plaid.com/'
5
-
6
- # This initializes our instance variables, and sets up a new Customer class.
7
- def initialize
8
- Plaid::Configure::KEYS.each do |key|
9
- instance_variable_set(:"@#{key}", Plaid.instance_variable_get(:"@#{key}"))
10
- end
11
- end
12
-
13
- # This is a specific route for auth,
14
- # it returns specific acct info
15
- def add_account_auth(type, username, password, email)
16
- parse_auth_response(post('/auth', type, username, password, email))
17
- end
18
-
19
- # This is a specific route for connect,
20
- # it returns transaction information
21
- def add_account_connect(type,username,password,email,options={})
22
- parse_connect_response(post('/connect',type,username,password,email,options))
23
- end
24
-
25
- def get_place(id)
26
- parse_place(get('entities/',id))
27
- end
28
-
29
- def get_institutions
30
- JSON.parse(get('/institutions'))
31
- end
32
-
33
- protected
34
-
35
- # Specific parser for auth response
36
- def parse_auth_response(response)
37
- parsed = JSON.parse(response)
38
- case response.code
39
- when 200
40
- {code: response.code, access_token: parsed['access_token'], accounts: parsed['accounts']}
41
- when 201
42
- {code: response.code, type: parsed['type'], access_token: parsed['access_token'], mfa: parsed['mfa']}
43
- else
44
- {code: response.code, message: parsed}
45
- end
46
- end
47
-
48
- def parse_connect_response(response)
49
- parsed = JSON.parse(response)
50
- case response.code
51
- when 200
52
- {code: response.code, access_token: parsed['access_token'], accounts: parsed['accounts'], transactions: parsed['transactions']}
53
- when 201
54
- {code: response.code, type: parsed['type'], access_token: parsed['access_token'], mfa: parsed['mfa']}
55
- else
56
- {code: response.code, message: parsed}
57
- end
58
- end
59
-
60
- def parse_place(response)
61
- parsed = JSON.parse(response)
62
- {code: response.code, category: parsed['category'], name: parsed['name'], id: parsed['_id'], phone: parsed['meta']['contact']['telephone'], location: parsed['meta']['location']}
63
- end
64
-
65
- def parse_institutions(response)
66
- parsed = JSON.parse(response)
67
- {code: response.code, institutions: parsed}
68
- end
69
-
70
- private
71
-
72
- def post(path,type,username,password,email,options={})
73
- url = BASE_URL + path
74
- RestClient.post url, client_id: self.instance_variable_get(:'@customer_id') ,secret: self.instance_variable_get(:'@secret'), type: type ,credentials: {username: username, password: password} ,email: email, options: options
75
- end
76
-
77
- def get(path,id = nil)
78
- url = BASE_URL + path + id.to_s
79
- RestClient.get(url)
80
- end
81
-
82
- end
83
- end
@@ -1,68 +0,0 @@
1
- module Plaid
2
- # This is used when a customer needs to be defined by the plaid access token.
3
- # Abstracting as a class makes it easier since we wont have to redefine the access_token over and over.
4
- class Customer
5
-
6
- BASE_URL = 'https://tartan.plaid.com'
7
-
8
- # This initializes our instance variables, and sets up a new Customer class.
9
- def initialize
10
- Plaid::Configure::KEYS.each do |key|
11
- instance_variable_set(:"@#{key}", Plaid.instance_variable_get(:"@#{key}"))
12
- end
13
- end
14
-
15
- def mfa_auth_step(access_token, code, type)
16
- parse_response(post('/auth/step', access_token, mfa: code, type: type), 0)
17
- end
18
-
19
- def mfa_connect_step(access_token,code)
20
- parse_response(post('/connect/step', access_token, mfa: code),1)
21
- end
22
-
23
- def get_transactions(access_token)
24
- parse_response(get('/connect', access_token),2)
25
- end
26
-
27
- def delete_account(access_token)
28
- parse_response(delete('/connect', access_token),3)
29
- end
30
-
31
- protected
32
-
33
- def parse_response(response,method)
34
- parsed = JSON.parse(response)
35
- if response.code == '200'
36
- case method
37
- when 0
38
- {code: response.code, access_token: parsed['access_token'], accounts: parsed['accounts']}
39
- when 1
40
- {code: response.code, access_token: parsed['access_token'], accounts: parsed['accounts'], transactions: parsed['transactions']}
41
- when 2
42
- {code: response.code, transactions: parsed['transactions']}
43
- else
44
- {code: response.code, message: parsed}
45
- end
46
- else
47
- {code: response.code, message: parsed}
48
- end
49
- end
50
-
51
- private
52
-
53
- def get(path,access_token)
54
- url = BASE_URL + path
55
- RestClient.get(url, params: {client_id: self.instance_variable_get(:'@customer_id'), secret: self.instance_variable_get(:'@secret'), access_token: access_token})
56
- end
57
-
58
- def post(path,access_token,options={})
59
- url = BASE_URL + path
60
- RestClient.post url, client_id: self.instance_variable_get(:'@customer_id'), secret: self.instance_variable_get(:'@secret'), access_token: access_token, mfa: options[:mfa], type: options[:type]
61
- end
62
-
63
- def delete(path,access_token)
64
- url = BASE_URL + path
65
- RestClient.delete(url, params: {client_id: self.instance_variable_get(:'@customer_id'), secret: self.instance_variable_get(:'@secret'), access_token: access_token})
66
- end
67
- end
68
- end