plaid 1.7.1 → 2.0.0.alpha

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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +3 -0
  3. data/CONTRIBUTING.md +15 -0
  4. data/LICENSE +20 -0
  5. data/README.md +215 -63
  6. data/Rakefile +50 -4
  7. data/UPGRADING.md +45 -0
  8. data/bin/console +13 -0
  9. data/bin/setup +8 -0
  10. data/lib/plaid.rb +51 -88
  11. data/lib/plaid/account.rb +144 -0
  12. data/lib/plaid/category.rb +62 -0
  13. data/lib/plaid/client.rb +67 -0
  14. data/lib/plaid/connector.rb +168 -0
  15. data/lib/plaid/errors.rb +24 -14
  16. data/lib/plaid/income.rb +106 -0
  17. data/lib/plaid/info.rb +65 -0
  18. data/lib/plaid/institution.rb +240 -0
  19. data/lib/plaid/risk.rb +34 -0
  20. data/lib/plaid/transaction.rb +123 -0
  21. data/lib/plaid/user.rb +430 -0
  22. data/lib/plaid/version.rb +1 -1
  23. data/plaid.gemspec +20 -12
  24. metadata +58 -62
  25. data/.gitignore +0 -15
  26. data/.rspec +0 -2
  27. data/.travis.yml +0 -5
  28. data/LICENSE.txt +0 -22
  29. data/PUBLISHING.md +0 -21
  30. data/lib/plaid/config.rb +0 -19
  31. data/lib/plaid/connection.rb +0 -109
  32. data/lib/plaid/models/account.rb +0 -24
  33. data/lib/plaid/models/category.rb +0 -17
  34. data/lib/plaid/models/exchange_token_response.rb +0 -11
  35. data/lib/plaid/models/info.rb +0 -12
  36. data/lib/plaid/models/institution.rb +0 -22
  37. data/lib/plaid/models/transaction.rb +0 -24
  38. data/lib/plaid/models/user.rb +0 -189
  39. data/spec/plaid/config_spec.rb +0 -67
  40. data/spec/plaid/connection_spec.rb +0 -191
  41. data/spec/plaid/error_spec.rb +0 -10
  42. data/spec/plaid/models/account_spec.rb +0 -37
  43. data/spec/plaid/models/category_spec.rb +0 -16
  44. data/spec/plaid/models/institution_spec.rb +0 -19
  45. data/spec/plaid/models/transaction_spec.rb +0 -28
  46. data/spec/plaid/models/user_spec.rb +0 -172
  47. data/spec/plaid_spec.rb +0 -263
  48. data/spec/spec_helper.rb +0 -14
@@ -1,10 +0,0 @@
1
- describe Plaid::PlaidError do
2
- describe "#new" do
3
- it "allows code, message and resolution" do
4
- error = Plaid::PlaidError.new 1, "testing", "fix it"
5
- expect(error.code).to eq(1)
6
- expect(error.message).to eq("testing")
7
- expect(error.resolve).to eq("fix it")
8
- end
9
- end
10
- end
@@ -1,37 +0,0 @@
1
- describe Plaid::Account do
2
- # API: semi-private
3
- describe '.new' do
4
- subject { Plaid::Account.new(results) }
5
-
6
- def self.with_results(_results, &examples)
7
- context "with results #{_results}" do
8
- let(:results) { _results }
9
- instance_eval(&examples)
10
- end
11
- end
12
-
13
- with_results('meta' => {'name' => 'Name'}) do it { expect(subject.name).to eql('Name') } end
14
- with_results('_id' => 'ID') do it { expect(subject.id).to eql('ID') } end
15
- with_results('type' => 'Type') do it { expect(subject.type).to eql('Type') } end
16
- with_results('type' => 'STyp') do it { expect(subject.type).to eql('STyp') } end
17
- with_results('meta' => nil) do it { expect(subject.meta).to be_nil } end
18
- with_results('meta' => {}) do it { expect(subject.meta).to eql({}) } end
19
-
20
- with_results('balance' => { 'available' => 100.00 } ) do it { expect(subject.available_balance).to eql(100.00) } end
21
- with_results('balance' => { 'current' => 200.00 } ) do it { expect(subject.current_balance).to eql(200.00) } end
22
-
23
- with_results('institution_type' => 'Type') do it { expect(subject.institution_type).to eql('Type') } end
24
-
25
- with_results('numbers' => nil) do
26
- it { expect(subject.numbers).to eql('Upgrade user to access routing information for this account') }
27
- end
28
-
29
- with_results('numbers' => {}) do
30
- it { expect(subject.numbers).to eql({}) }
31
- end
32
-
33
- with_results({}) do
34
- it { expect(subject.name).to eq nil } # doesn't blow up if 'meta' is missing
35
- end
36
- end
37
- end
@@ -1,16 +0,0 @@
1
- describe Plaid::Category do
2
- context 'when a single category is found' do
3
- let(:category) { Plaid.category('17001013') }
4
- it { expect(category).to be_kind_of(Plaid::Category) }
5
- end
6
-
7
- context 'when all categories are found' do
8
- let(:category) { Plaid.category }
9
- it { expect(category).to be_kind_of(Array)}
10
- end
11
-
12
- context 'when category is not found' do
13
- it { expect { Plaid.category('dumb_cat') }.to raise_error(Plaid::NotFound, 'unable to find category') }
14
- end
15
-
16
- end
@@ -1,19 +0,0 @@
1
- describe Plaid::Institution do
2
- context 'when a single institution is found' do
3
- let(:institution) { Plaid.institution('5301a93ac140de84910000e0') }
4
-
5
- it { expect(institution).to be_kind_of(Plaid::Institution) }
6
- it { expect(institution.mfa).to be_kind_of(Array) }
7
- it { expect(institution.products).to be_kind_of(Array) }
8
- it { expect(institution.credentials).to be_kind_of(Hash) }
9
- end
10
-
11
- context 'when all institutions are found' do
12
- let(:institution) { Plaid.institution }
13
- it { expect(institution).to be_kind_of(Array) }
14
- end
15
-
16
- context 'when institution is not found' do
17
- it { expect { Plaid.institution('dumb_bank') }.to raise_error(Plaid::NotFound, 'unable to find institution') }
18
- end
19
- end
@@ -1,28 +0,0 @@
1
- describe Plaid::Transaction do
2
- # API: semi-private
3
- describe '.new' do
4
- # The reason this looks weird is because it is. This will be refactored for 2.0
5
- subject { Plaid::Transaction.new(results) }
6
-
7
- def self.with_results(_results, &examples)
8
- context "with results #{_results}" do
9
- let(:results) { _results }
10
- instance_eval(&examples)
11
- end
12
- end
13
-
14
- with_results('_id' => 'ID') do it { expect(subject.id).to eql('ID') } end
15
- with_results('_account' => 'acct') do it { expect(subject.account).to eql('acct') } end
16
- with_results('date' => '00/00/00') do it { expect(subject.date).to eql('00/00/00') } end
17
- with_results('amount' => 100.00) do it { expect(subject.amount).to eql(100.00) } end
18
- with_results('name' => 'Name') do it { expect(subject.name).to eql('Name') } end
19
- with_results('meta' => {} ) do it { expect(subject.meta).to eql({}) } end
20
- with_results('meta' => {'location' => 'Location'}) do it { expect(subject.location).to eql('Location') } end
21
- with_results('pending' => true) do it { expect(subject.pending).to eql(true) } end
22
- with_results('score' => 200) do it { expect(subject.score).to eql(200) } end
23
- with_results('type' => 'Type') do it { expect(subject.type).to eql('Type') } end
24
-
25
- with_results('category' => 'Category') do it { expect(subject.category).to eql('Category') } end
26
- with_results('category_id' => 100) do it { expect(subject.category_id).to eql(100) } end
27
- end
28
- end
@@ -1,172 +0,0 @@
1
- describe Plaid::User do
2
- let(:auth_user) { Plaid.add_user('auth', 'plaid_test', 'plaid_good', 'wells') }
3
- let(:connect_user) { Plaid.add_user('connect', 'plaid_test', 'plaid_good', 'wells') }
4
- let(:info_user) { Plaid.add_user('info', 'plaid_test', 'plaid_good', 'wells') }
5
-
6
- context 'user vars' do
7
- context 'valid user has accounts and accounts contain id attribute' do
8
- let(:user) { Plaid.add_user('connect', 'plaid_test', 'plaid_good', 'wells') }
9
- it { expect(user.accounts.first.id).not_to be_nil }
10
- end
11
-
12
- context 'valid user has accounts and accounts contain type attribute' do
13
- let(:user) { Plaid.add_user('connect', 'plaid_test', 'plaid_good', 'wells') }
14
- it { expect(user.accounts.first.type).to eq('depository') }
15
- end
16
- end
17
-
18
- # MFA specs - after user is instantiated,
19
- describe '#mfa_authentication' do
20
- let(:user) { Plaid.add_user('connect', 'plaid_test', 'plaid_good', 'bofa') }
21
- let(:new_mfa_user) { user.mfa_authentication('tomato') }
22
-
23
- context 'enters correct credentials for MFA auth and authenticates' do
24
- it { expect(new_mfa_user.accounts).not_to be_empty }
25
- end
26
-
27
- context 'enters old method of adding type strongly in each method and authenticates correctly using 2FA' do
28
- let(:new_mfa_user) { user.mfa_authentication('tomato', 'bofa') }
29
- it { expect(new_mfa_user.accounts).to be_truthy }
30
- end
31
-
32
- context 'has to enter another round of MFA credentials' do
33
- let(:mfa_again) { user.mfa_authentication('again') }
34
- it { expect(mfa_again.api_res).to eq 'Requires further authentication' }
35
- end
36
-
37
- context 'enters incorrect credentials for MFA auth' do
38
- let(:mfa_user) { user.mfa_authentication('tomato') }
39
- let(:mfa_bad) { mfa_user; Plaid.add_user('connect', 'plaid_test', 'plaid_good', 'bofa') }
40
- it { expect { mfa_bad.mfa_authentication('bad') }.to raise_error(Plaid::RequestFailed, 'invalid mfa') }
41
- end
42
-
43
- context 'requests list of MFA credentials' do
44
- let(:new_mfa_user) { Plaid.add_user('auth', 'plaid_test', 'plaid_good', 'chase', nil, '{"list":true}') }
45
- let(:expected_questions) do
46
- {
47
- "type"=>"list",
48
- "mfa"=> [
49
- {"mask"=>"xxx-xxx-5309", "type"=>"phone"},
50
- {"mask"=>"t..t@plaid.com", "type"=>"email"}
51
- ],
52
- "access_token"=>"test_chase"
53
- }
54
- end
55
- it { expect(new_mfa_user.pending_mfa_questions).to eql(expected_questions) }
56
- end
57
-
58
- context 'selects MFA method and returns successful response' do
59
- let(:user) { Plaid.add_user('auth', 'plaid_test', 'plaid_good', 'chase', nil, '{"list":true}') }
60
- let(:new_mfa_user) { user.select_mfa_method({mask: 'xxx-xxx-5309' }, 'chase') }
61
- let(:expected_pending_questions) do
62
- {
63
- "type" => "device",
64
- "mfa" => { "message" => "Code sent to xxx-xxx-5309" },
65
- "access_token" => "test_chase"
66
- }
67
- end
68
- it { expect(new_mfa_user.pending_mfa_questions).to eql(expected_pending_questions) }
69
- end
70
-
71
- context 'selects MFA method, and delivers correct payload to authenticate user' do
72
- let(:user) { Plaid.add_user('auth', 'plaid_test', 'plaid_good', 'chase', nil, '{"list":true}') }
73
- let(:user_select_method) { user.select_mfa_method({mask:'xxx-xxx-5309'}) }
74
- let(:new_mfa_user) { user_select_method.mfa_authentication(1234) }
75
-
76
- it { expect(new_mfa_user.accounts).not_to be_empty }
77
- end
78
- end
79
-
80
- context 'when authenticating' do
81
- # Auth specs
82
- describe '#get_auth' do
83
-
84
- context 'has access and returns accounts' do
85
- it { expect(auth_user.permissions[0]).to eq('auth') }
86
- end
87
-
88
- context 'does not have access to auth' do
89
- it { expect(connect_user.permissions.include? 'auth' ).to eql(false) }
90
- end
91
- end
92
-
93
- # Connect specs
94
- describe '#get_connect' do
95
- context 'has access and returns accounts' do
96
- it { expect(connect_user.permissions[0]).to eq('connect') }
97
- end
98
-
99
- context 'does not have access to auth' do
100
- it { expect(auth_user.permissions.include? 'connect' ).to eql(false) }
101
- end
102
- end
103
-
104
- # Get info specs
105
- describe '#get_info' do
106
- context 'has access and returns user info' do
107
- it { expect(info_user.permissions[0]).to eq('info') }
108
- end
109
-
110
- context 'does not have access to info' do
111
- it{ expect(auth_user.permissions.include? 'info' ).to eql(false) }
112
- end
113
- end
114
- end
115
-
116
- describe '#get_balance' do
117
- subject { user.tap(&:update_balance) }
118
- let(:user) { Plaid.add_user('info', 'plaid_test', 'plaid_good', 'wells') }
119
-
120
- context 'updates user accounts' do
121
- it { expect(subject.accounts).not_to be_empty }
122
- end
123
-
124
- # TODO: This test needs to be rewritten better, such as using #uniq instead of this
125
- context 'does not double up accounts or transactions' do
126
- let(:total_duplicates) { duplicate_accounts.length + duplicate_transactions.length }
127
- let(:duplicate_accounts) { subject.accounts.select {|element| user.accounts.count(element) > 1} }
128
- let(:duplicate_transactions) { subject.transactions.select {|element| user.transactions.count(element) > 1} }
129
- it{ expect(total_duplicates).to eql(0) }
130
- end
131
- end
132
-
133
- describe '#update_info' do
134
- let(:info_user) { Plaid.add_user('info', 'plaid_test', 'plaid_good', 'wells') }
135
- context 'updates information correctly' do
136
- # TODO: This test needs to pass, currently test credentials are failing
137
- pending { expect { info_user.update_info('plaid_test', 'plaid_good') }.to_not raise_error }
138
- end
139
- end
140
-
141
- describe '#delete_user' do
142
- subject { info_user.tap(&:delete_user) }
143
- let(:info_user) { Plaid.add_user('info', 'plaid_test', 'plaid_good', 'wells') }
144
-
145
- context 'updates information correctly' do
146
- it { expect { subject.get_info }.to raise_error(Plaid::Unauthorized, 'client_id missing') }
147
- end
148
- end
149
-
150
- describe '#upgrade' do
151
- subject { user.tap(&upgrade!) }
152
- let(:upgrade!) { ->(x) { x.upgrade(upgrade_level) } }
153
- let(:upgrade_level) { raise 'Define upgrade level' }
154
-
155
- context 'auth upgrade is successful' do
156
- let(:user) { connect_user }
157
- let(:upgrade_level) { 'auth' }
158
- it { expect{ subject.get_auth }.to_not raise_error }
159
- end
160
-
161
- context 'connect upgrade is successful' do
162
- let(:user) { auth_user }
163
- let(:upgrade_level) { 'connect' }
164
- it { expect{ subject.get_connect }.to_not raise_error }
165
- end
166
- end
167
-
168
- # This stuff needs to be tested and rewritten. Have already
169
- # surfaced up a bug in it
170
- pending '#populate_user'
171
-
172
- end
data/spec/plaid_spec.rb DELETED
@@ -1,263 +0,0 @@
1
- # Authentication flow specs - returns Plaid::User
2
-
3
- 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
-
32
- it 'raises a locked error' do
33
- expect { user }.to raise_error(Plaid::RequestFailed) { |error|
34
- expect(error.code).to eq(1205)
35
- }
36
- end
37
- end
38
-
39
- context 'with connection options' do
40
- context 'when requests pending transactions from an institution' do
41
- let(:options) { { pending: true } }
42
- it { expect(user.accounts).not_to be_empty }
43
- end
44
-
45
- context 'when login only is true' do
46
- let(:options) { { login_only: true } }
47
- it { expect(user.accounts).not_to be_empty }
48
- end
49
-
50
- context 'sets a start date for transactions' do
51
- let(:options) { { login_only: true, start_date: '10 days ago'} }
52
- it { expect(user.accounts).not_to be_empty }
53
- end
54
-
55
- context 'sets an end date for transactions' do
56
- let(:options) { { login_only: true, end_date: '10 days ago'} }
57
- it { expect(user.accounts).not_to be_empty }
58
- end
59
-
60
- context 'sets start and end dates for transactions' do
61
- let(:options) { { gte: "05/10/2014" , lte: "06/10/2014" } }
62
- it { expect(user.transactions).not_to be_nil }
63
- end
64
-
65
- pending 'with JSON-encoded string for options'
66
- end
67
- end
68
-
69
- context 'and "auth" level of api access' do
70
- let(:api_level) { 'auth' }
71
- it { expect(user.accounts.first.numbers).not_to be_empty }
72
- end
73
-
74
- context 'and "info" level of api access' do
75
- let(:api_level) { 'info' }
76
- it { expect(user.info).not_to be_empty }
77
- end
78
- end
79
-
80
- context 'with incorrect credentials for single factor auth' do
81
- # Set up correct credentials. Override with bad element
82
- # within each context block
83
- let(:username) { 'plaid_test' }
84
- let(:password) { 'plaid_good' }
85
- let(:type) { 'wells' }
86
-
87
- context 'at "auth" level api access' do
88
- let(:api_level) { 'auth' }
89
-
90
- context 'using incorrect password' do
91
- let(:password) { 'plaid_bad' }
92
- it { expect { user }.to raise_error(Plaid::RequestFailed, 'invalid credentials') }
93
- end
94
-
95
- context 'using incorrect username' do
96
- let(:username) { 'plaid_bad' }
97
- it { expect { user }.to raise_error(Plaid::RequestFailed, 'invalid credentials') }
98
- end
99
- end
100
-
101
- context 'at "connect" level api access' do
102
- let(:api_level) { 'connect' }
103
-
104
- context 'using incorrect password' do
105
- let(:password) { 'plaid_bad' }
106
- it { expect { user }.to raise_error(Plaid::RequestFailed, 'invalid credentials') }
107
- end
108
-
109
- context 'using incorrect username' do
110
- let(:username) { 'plaid_bad' }
111
- it { expect { user }.to raise_error(Plaid::RequestFailed, 'invalid credentials') }
112
- end
113
- end
114
-
115
- context 'at "info" level api access' do
116
- let(:api_level) { 'info' }
117
-
118
- context 'using incorrect password' do
119
- let(:password) { 'plaid_bad' }
120
- it { expect { user }.to raise_error(Plaid::RequestFailed, 'invalid credentials') }
121
- end
122
-
123
- context 'using incorrect username' do
124
- let(:username) { 'plaid_bad' }
125
- it { expect { user }.to raise_error(Plaid::RequestFailed, 'invalid credentials') }
126
- end
127
- end
128
- end
129
-
130
- context 'when institution requires PIN' do
131
- let(:api_level) { 'connect' }
132
- let(:username) { 'plaid_test' }
133
- let(:password) { 'plaid_good' }
134
- let(:type) { 'usaa' }
135
-
136
- context 'using correct PIN' do
137
- let(:pin) { '1234' }
138
- it { expect(user.api_res).to eq 'Requires further authentication' }
139
- end
140
-
141
- context 'using incorrect PIN' do
142
- let(:pin) { '0000' }
143
- it { expect { user }.to raise_error(Plaid::RequestFailed, 'invalid pin') }
144
- end
145
- end
146
-
147
- context 'when institution requires MFA' do
148
- let(:api_level) { 'connect' }
149
- let(:username) { 'plaid_test' }
150
- let(:password) { 'plaid_good' }
151
- let(:type) { 'bofa' }
152
-
153
- context 'with only standard credentials' do
154
- it { expect(user.api_res).to eq 'Requires further authentication' }
155
- end
156
-
157
- context 'with options' do
158
- context 'with webhook' do
159
- let(:options) { { login_only: true, webhook: 'test.com/test.endpoint.aspx' } }
160
- it { expect(user.api_res).to eq 'Requires further authentication' }
161
- end
162
-
163
- context 'requests a list of options for code based MFA' do
164
- let(:type) { 'citi' }
165
- let(:options) { { list: true } }
166
-
167
- it { expect(user.pending_mfa_questions).not_to be_nil }
168
- end
169
- end
170
- end
171
- end
172
-
173
- describe '.set_user' do
174
- subject { Plaid.set_user(access_token) }
175
- let(:access_token) { 'test' }
176
-
177
- it { expect(subject.access_token).to eq(access_token)}
178
-
179
- context 'gets a valid user with accounts and transactions' do
180
- let(:user) { Plaid.set_user('test_wells',['connect']) }
181
- it { expect(user.transactions).not_to be_empty }
182
- end
183
-
184
- context 'gets a valid user with accounts' do
185
- let(:user) { Plaid.set_user('test_wells',['auth']) }
186
- it { expect(user.accounts).not_to be_empty }
187
- end
188
-
189
- #TODO: Fully vet the info api endpoint for the beta functions before adding this as a supported function.
190
- pending 'need to vet the info api endpoint' do
191
- context 'gets a valid user with info' do
192
- let(:user) { Plaid.set_user('test_wells',['info']) }
193
- it { expect(user.accounts).to be_truthy}
194
- end
195
-
196
- context 'gets a fully validated user with all access granted' do
197
- let(:user) { Plaid.set_user('test_wells', ['connect', 'info', 'auth']) }
198
- it { expect(user.transactions).to be_truthy}
199
- end
200
- end
201
- end
202
-
203
- describe '.exchange_token' do
204
- subject { Plaid.exchange_token('test,chase,connected', 'QPO8Jo8vdDHMepg41PBwckXm4KdK1yUdmXOwK') }
205
-
206
- it { expect(subject.access_token).to eql('test_chase') }
207
- end
208
-
209
- describe '.transactions' do
210
- subject { Plaid.transactions(access_token, options) }
211
- let(:access_token) { 'test_wells' }
212
- let(:options) { nil }
213
-
214
- context 'without options' do
215
- it 'returns all accounts' do
216
- expect(subject.accounts).not_to be_empty
217
- end
218
-
219
- it 'returns all transactions' do
220
- expect(subject.transactions).not_to be_empty
221
- end
222
- end
223
-
224
- context 'when filtering by account' do
225
- let(:options) { { account: account } }
226
- let(:account) { 'QPO8Jo8vdDHMepg41PBwckXm4KdK1yUdmXOwK' }
227
-
228
- it 'returns a subset of transactions' do
229
- expect(subject.transactions.size).to eql(2)
230
- end
231
-
232
- it 'return only transactions from the requested account' do
233
- expect(subject.transactions.map(&:account).uniq).to eql([account])
234
- end
235
- end
236
-
237
- context 'when filtering by date' do
238
- let(:options) { { gte: "2014-07-24", lte: "2014-07-25" } }
239
-
240
- it 'returns a subset of transactions' do
241
- expect(subject.transactions.size).to eql(1)
242
- end
243
-
244
- it 'return only transactions from the requested date range' do
245
- expect(subject.transactions.map(&:date).uniq).to eql(['2014-07-24'])
246
- end
247
- end
248
-
249
- context 'when filtering by account and date' do
250
- let(:options) { { account: account , gte: "2014-07-24", lte: "2014-07-25" } }
251
- let(:account) { 'XARE85EJqKsjxLp6XR8ocg8VakrkXpTXmRdOo' }
252
-
253
- it 'returns a subset of transactions' do
254
- expect(subject.transactions.size).to eql(1)
255
- end
256
-
257
- it 'returns only transactions from the requested account and date range' do
258
- expect(subject.transactions.map(&:date).uniq).to eql(['2014-07-24'])
259
- expect(subject.transactions.map(&:account).uniq).to eql([account])
260
- end
261
- end
262
- end
263
- end