finicity 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +23 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +69 -0
  7. data/Rakefile +10 -0
  8. data/finicity.gemspec +31 -0
  9. data/lib/finicity.rb +42 -0
  10. data/lib/finicity/client.rb +350 -0
  11. data/lib/finicity/configuration.rb +13 -0
  12. data/lib/finicity/errors.rb +62 -0
  13. data/lib/finicity/logger.rb +19 -0
  14. data/lib/finicity/railtie.rb +22 -0
  15. data/lib/finicity/v1.rb +29 -0
  16. data/lib/finicity/v1/request/activate_accounts.rb +73 -0
  17. data/lib/finicity/v1/request/activate_accounts_with_mfa.rb +88 -0
  18. data/lib/finicity/v1/request/add_customer.rb +54 -0
  19. data/lib/finicity/v1/request/delete_customer.rb +45 -0
  20. data/lib/finicity/v1/request/discover_accounts.rb +71 -0
  21. data/lib/finicity/v1/request/discover_accounts_with_mfa.rb +87 -0
  22. data/lib/finicity/v1/request/get_accounts.rb +50 -0
  23. data/lib/finicity/v1/request/get_customers.rb +43 -0
  24. data/lib/finicity/v1/request/get_customers_by_username.rb +52 -0
  25. data/lib/finicity/v1/request/get_institution.rb +45 -0
  26. data/lib/finicity/v1/request/get_institutions.rb +45 -0
  27. data/lib/finicity/v1/request/get_login_form.rb +47 -0
  28. data/lib/finicity/v1/request/get_transactions.rb +60 -0
  29. data/lib/finicity/v1/request/interactive_refresh_account.rb +51 -0
  30. data/lib/finicity/v1/request/interactive_refresh_account_with_mfa.rb +74 -0
  31. data/lib/finicity/v1/request/refresh_accounts.rb +47 -0
  32. data/lib/finicity/v1/response/accounts.rb +75 -0
  33. data/lib/finicity/v1/response/customers.rb +36 -0
  34. data/lib/finicity/v1/response/error.rb +13 -0
  35. data/lib/finicity/v1/response/institutions.rb +38 -0
  36. data/lib/finicity/v1/response/login_form.rb +29 -0
  37. data/lib/finicity/v1/response/mfa.rb +22 -0
  38. data/lib/finicity/v1/response/transactions.rb +28 -0
  39. data/lib/finicity/v2.rb +7 -0
  40. data/lib/finicity/v2/request/partner_authentication.rb +39 -0
  41. data/lib/finicity/v2/response/partner_authentication.rb +12 -0
  42. data/lib/finicity/version.rb +3 -0
  43. data/spec/finicity/client_spec.rb +527 -0
  44. data/spec/finicity/v1/request/activate_accounts_spec.rb +49 -0
  45. data/spec/finicity/v1/request/activate_accounts_with_mfa_spec.rb +64 -0
  46. data/spec/finicity/v1/request/add_customer_spec.rb +37 -0
  47. data/spec/finicity/v1/request/delete_customer_spec.rb +18 -0
  48. data/spec/finicity/v1/request/discover_accounts_spec.rb +42 -0
  49. data/spec/finicity/v1/request/discover_accounts_with_mfa_spec.rb +59 -0
  50. data/spec/finicity/v1/request/get_accounts_spec.rb +18 -0
  51. data/spec/finicity/v1/request/get_customers_by_username_spec.rb +18 -0
  52. data/spec/finicity/v1/request/get_customers_spec.rb +18 -0
  53. data/spec/finicity/v1/request/get_institution_spec.rb +18 -0
  54. data/spec/finicity/v1/request/get_institutions_spec.rb +18 -0
  55. data/spec/finicity/v1/request/get_login_form_spec.rb +18 -0
  56. data/spec/finicity/v1/request/get_transactions_spec.rb +19 -0
  57. data/spec/finicity/v1/request/interactive_refresh_account_spec.rb +19 -0
  58. data/spec/finicity/v1/request/interactive_refresh_account_with_mfa_spec.rb +38 -0
  59. data/spec/finicity/v1/request/refresh_accounts_spec.rb +18 -0
  60. data/spec/finicity/v1/response/accounts_spec.rb +39 -0
  61. data/spec/finicity/v1/response/customers_spec.rb +19 -0
  62. data/spec/finicity/v1/response/error_spec.rb +19 -0
  63. data/spec/finicity/v1/response/institutions_spec.rb +19 -0
  64. data/spec/finicity/v1/response/login_form_spec.rb +31 -0
  65. data/spec/finicity/v1/response/mfa_spec.rb +23 -0
  66. data/spec/finicity/v1/response/transactions_spec.rb +47 -0
  67. data/spec/finicity/v2/request/partner_authentication_spec.rb +21 -0
  68. data/spec/finicity/v2/response/partner_authentication_spec.rb +15 -0
  69. data/spec/spec_helper.rb +36 -0
  70. metadata +265 -0
@@ -0,0 +1,74 @@
1
+ module Finicity::V1
2
+ module Request
3
+ class InteractiveRefreshAccountWithMfa
4
+ include ::Finicity::Logger
5
+ extend ::HTTPClient::IncludeClient
6
+ include_http_client do |client|
7
+ client.cookie_manager = nil
8
+ end
9
+
10
+ ##
11
+ # Attributes
12
+ #
13
+ attr_accessor :account_id,
14
+ :customer_id,
15
+ :mfa_credentials,
16
+ :mfa_session,
17
+ :token
18
+
19
+ ##
20
+ # Instance Methods
21
+ #
22
+ def initialize(token, mfa_session, customer_id, account_id, mfa_credentials)
23
+ @account_id = account_id
24
+ @customer_id = customer_id
25
+ @mfa_credentials = mfa_credentials
26
+ @mfa_session = mfa_session
27
+ @token = token
28
+ end
29
+
30
+ def interactive_refresh_account_with_mfa
31
+ http_client.post(url, body, headers)
32
+ end
33
+
34
+ def body
35
+ builder = ::Nokogiri::XML::Builder.new do |xml|
36
+ xml.mfaChallenges {
37
+ xml.questions {
38
+ mfa_credentials.each do |mfa_credential|
39
+ xml.question {
40
+ xml.text_(mfa_credential[:text])
41
+ xml.answer(mfa_credential[:answer])
42
+ }
43
+ end
44
+ }
45
+ }
46
+ end
47
+
48
+ builder.to_xml
49
+ end
50
+
51
+ def headers
52
+ {
53
+ 'Finicity-App-Key' => ::Finicity.config.app_key,
54
+ 'Finicity-App-Token' => token,
55
+ 'MFA-Session' => mfa_session,
56
+ 'Content-Type' => 'application/xml'
57
+ }
58
+ end
59
+
60
+ def url
61
+ ::URI.join(
62
+ ::Finicity.config.base_url,
63
+ 'v1/',
64
+ 'customers/',
65
+ "#{customer_id}/",
66
+ 'accounts/',
67
+ "#{account_id}/",
68
+ 'mfa'
69
+ )
70
+ end
71
+
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,47 @@
1
+ module Finicity::V1
2
+ module Request
3
+ class RefreshAccounts
4
+ include ::Finicity::Logger
5
+ extend ::HTTPClient::IncludeClient
6
+ include_http_client do |client|
7
+ client.cookie_manager = nil
8
+ end
9
+
10
+ ##
11
+ # Attributes
12
+ #
13
+ attr_accessor :customer_id,
14
+ :token
15
+
16
+ ##
17
+ # Instance Methods
18
+ #
19
+ def initialize(token, customer_id)
20
+ @customer_id = customer_id
21
+ @token = token
22
+ end
23
+
24
+ def refresh_accounts
25
+ http_client.post(url, nil, headers)
26
+ end
27
+
28
+ def headers
29
+ {
30
+ 'Finicity-App-Key' => ::Finicity.config.app_key,
31
+ 'Finicity-App-Token' => token
32
+ }
33
+ end
34
+
35
+ def url
36
+ ::URI.join(
37
+ ::Finicity.config.base_url,
38
+ 'v1/',
39
+ 'customers/',
40
+ "#{customer_id}/",
41
+ 'accounts'
42
+ )
43
+ end
44
+
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,75 @@
1
+ module Finicity::V1
2
+ module Response
3
+ class Account
4
+ include ::Saxomattic
5
+
6
+ ##
7
+ # Saxomattic Attributes
8
+ #
9
+ attribute :id
10
+ attribute :number, :type => ::Integer
11
+ attribute :name
12
+ attribute :balance, :type => ::Float
13
+ attribute :type
14
+ attribute :aggregationStatusCode, :type => ::Integer, :as => :aggregation_status_code
15
+ attribute :status, :type => ::Integer
16
+ attribute :customerId, :as => :customer_id
17
+ attribute :institutionId, :as => :institution_id
18
+ attribute :balanceDate, :type => ::Integer
19
+ attribute :aggregationSuccessDate, :type => ::Integer
20
+ attribute :aggregationAttemptDate, :type => ::Integer
21
+ attribute :createdDate, :type => ::Integer
22
+ attribute :paymentMinAmount, :type => ::Float, :as => :payment_min_amount
23
+ attribute :paymentDueDate, :type => ::Integer
24
+ attribute :statementCloseBalance, :type => ::Float, :as => :statement_close_balance
25
+ attribute :statementEndDate, :type => ::Integer
26
+
27
+ ##
28
+ # Instance Methods
29
+ #
30
+ def aggregation_success_date
31
+ aggreagtionSuccessDate ? ::Time.at(aggregationSuccessDate).utc : nil
32
+ end
33
+
34
+ def aggregation_attempt_date
35
+ aggreagtionAttemptDate ? ::Time.at(aggregationAttemptDate).utc : nil
36
+ end
37
+
38
+ def balance_date
39
+ balanceDate ? ::Time.at(balanceDate).utc : nil
40
+ end
41
+
42
+ def created_date
43
+ createdDate ? ::Time.at(createdDate).utc : nil
44
+ end
45
+
46
+ def payment_due_date
47
+ paymentDueDate ? ::Time.at(paymentDueDate).utc : nil
48
+ end
49
+
50
+ def statement_end_date
51
+ statementEndDate ? ::Time.at(statementEndDate).utc : nil
52
+ end
53
+
54
+ def validate_aggregation_status!
55
+ case aggregation_status_code
56
+ when 0
57
+ true
58
+ when 103, 108, 109, 185, 187
59
+ fail ::Finicity::InvalidCredentialsError.new(aggregation_status_code)
60
+ else
61
+ fail ::Finicity::FinicityAggregationError.new(aggregation_status_code)
62
+ end
63
+ end
64
+ end
65
+
66
+ class Accounts
67
+ include ::Saxomattic
68
+
69
+ ##
70
+ # Saxomattic Attributes
71
+ #
72
+ attribute :account, :elements => true, :class => ::Finicity::V1::Response::Account, :as => :accounts
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,36 @@
1
+ module Finicity::V1
2
+ module Response
3
+ class Customer
4
+ include ::Saxomattic
5
+
6
+ ##
7
+ # Saxomattic Attributes
8
+ #
9
+ attribute :username
10
+ attribute :email
11
+ attribute :firstName, :as => :first_name
12
+ attribute :lastName, :as => :last_name
13
+ attribute :id
14
+ end
15
+
16
+ class Customers
17
+ include ::Saxomattic
18
+
19
+ ##
20
+ # Saxomattic Attributes
21
+ #
22
+ attribute :customers
23
+ attribute :moreAvailable, :attribute => true, :as => :more_available
24
+ attribute :found, :attribute => true, :type => ::Integer
25
+ attribute :displaying, :attribute => true, :type => ::Integer
26
+ attribute :customer, :elements => true, :class => ::Finicity::V1::Response::Customer, :as => :customers
27
+
28
+ ##
29
+ # Instance Methods
30
+ #
31
+ def more_available?
32
+ more_available == 'true'
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,13 @@
1
+ module Finicity::V1
2
+ module Response
3
+ class Error
4
+ include ::Saxomattic
5
+
6
+ ##
7
+ # Saxomattic Attributes
8
+ #
9
+ attribute :code, :type => ::Integer
10
+ attribute :message
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,38 @@
1
+ module Finicity::V1
2
+ module Response
3
+ class Institution
4
+ include ::Saxomattic
5
+
6
+ ##
7
+ # Saxomattic Attributes
8
+ #
9
+ attribute :id
10
+ attribute :name
11
+ attribute :accountTypeDescription, :as => :account_type_description
12
+ attribute :totalAccounts, :type => ::Integer, :as => :total_accounts
13
+ attribute :discovery
14
+ attribute :urlHomeApp, :as => :url_home_app
15
+ attribute :urlLogonApp, :as => :url_logon_app
16
+ end
17
+
18
+ class Institutions
19
+ include ::Saxomattic
20
+
21
+ ##
22
+ # Saxomattic Attributes
23
+ #
24
+ attribute :institutions
25
+ attribute :moreAvailable, :attribute => true, :as => :more_available
26
+ attribute :found, :attribute => true, :type => ::Integer
27
+ attribute :displaying, :attribute => true, :type => ::Integer
28
+ attribute :institution, :elements => true, :class => ::Finicity::V1::Response::Institution, :as => :institutions
29
+
30
+ ##
31
+ # Instance Methods
32
+ #
33
+ def more_available?
34
+ more_available == 'true'
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,29 @@
1
+ module Finicity::V1
2
+ module Response
3
+ class LoginField
4
+ include ::Saxomattic
5
+
6
+ ##
7
+ # Saxomattic Attributes
8
+ #
9
+ attribute :description
10
+ attribute :displayOrder, :type => ::Integer, :as => :display_order
11
+ attribute :id
12
+ attribute :name
13
+ attribute :mask
14
+
15
+ def mask?
16
+ mask == 'true'
17
+ end
18
+ end
19
+
20
+ class LoginForm
21
+ include ::Saxomattic
22
+
23
+ ##
24
+ # Saxomattic Attributes
25
+ #
26
+ attribute :loginField, :elements => true, :class => ::Finicity::V1::Response::LoginField, :as => :login_fields
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,22 @@
1
+ module Finicity::V1
2
+ module Response
3
+ class Question
4
+ include ::Saxomattic
5
+
6
+ ##
7
+ # Saxomattic Attributes
8
+ #
9
+ attribute :text
10
+ attribute :choice, :elements => true, :as => :choices
11
+ end
12
+
13
+ class Mfa
14
+ include ::Saxomattic
15
+
16
+ ##
17
+ # Saxomattic Attributes
18
+ #
19
+ attribute :questions, :elements => true, :class => ::Finicity::V1::Response::Question
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,28 @@
1
+ module Finicity::V1
2
+ module Response
3
+ class Transaction
4
+ include ::Saxomattic
5
+
6
+ ##
7
+ # Saxomattic Attributes
8
+ #
9
+ attribute :id
10
+ attribute :amount, :type => ::Float
11
+ attribute :accountId, :as => :account_id
12
+ attribute :customerId, :as => :customer_id
13
+ attribute :description
14
+ attribute :memo
15
+ attribute :postedDate, :type => ::Integer, :as => :posted_date
16
+ attribute :status
17
+ end
18
+
19
+ class Transactions
20
+ include ::Saxomattic
21
+
22
+ ##
23
+ # Saxomattic Attributes
24
+ #
25
+ attribute :transaction, :elements => true, :class => ::Finicity::V1::Response::Transaction, :as => :transactions
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,7 @@
1
+ require 'finicity/v2/request/partner_authentication'
2
+ require 'finicity/v2/response/partner_authentication'
3
+
4
+ module Finicity
5
+ module V2
6
+ end
7
+ end
@@ -0,0 +1,39 @@
1
+ module Finicity::V2
2
+ module Request
3
+ class PartnerAuthentication
4
+ extend ::HTTPClient::IncludeClient
5
+ include_http_client do |client|
6
+ client.cookie_manager = nil
7
+ end
8
+
9
+ ##
10
+ # Instance Methods
11
+ #
12
+ def authenticate
13
+ http_client.post(url, body, headers)
14
+ end
15
+
16
+ def body
17
+ builder = ::Nokogiri::XML::Builder.new do |xml|
18
+ xml.credentials do
19
+ xml.partnerId(::Finicity.config.partner_id)
20
+ xml.partnerSecret(::Finicity.config.partner_secret)
21
+ end
22
+ end
23
+
24
+ builder.doc.root.to_s
25
+ end
26
+
27
+ def headers
28
+ {
29
+ 'Finicity-App-Key' => ::Finicity.config.app_key,
30
+ 'Content-Type' => 'application/xml'
31
+ }
32
+ end
33
+
34
+ def url
35
+ ::URI.join(::Finicity.config.base_url, 'v2/partners/authentication')
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,12 @@
1
+ module Finicity::V2
2
+ module Response
3
+ class PartnerAuthentication
4
+ include ::Saxomattic
5
+
6
+ ##
7
+ # Saxomattic Attributes
8
+ #
9
+ attribute :token
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,3 @@
1
+ module Finicity
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,527 @@
1
+ require 'spec_helper'
2
+
3
+ describe ::Finicity::Client do
4
+ let(:mfa_session_token) { 'mfa-123' }
5
+ let(:response) { instance_double(::HTTP::Message, :ok? => true, :status_code => 200, :body => "hello") }
6
+ let(:mfa) {
7
+ instance_double(
8
+ ::HTTP::Message,
9
+ :ok? => true,
10
+ :status_code => 203,
11
+ :body => "challenge",
12
+ :headers => { 'MFA-Session' => mfa_session_token }
13
+ )
14
+ }
15
+ let(:error) {
16
+ instance_double(
17
+ ::HTTP::Message,
18
+ :ok? => false,
19
+ :status_code => 400,
20
+ :body => "fail",
21
+ :content_type => "text/plain"
22
+ )
23
+ }
24
+
25
+ describe "#activate_accounts" do
26
+ context "when the response is successful" do
27
+ it "returns the parsed response" do
28
+ allow_any_instance_of(::Finicity::V1::Request::ActivateAccounts).to(
29
+ receive(:activate_accounts).and_return(response)
30
+ )
31
+ response = subject.activate_accounts(123, 1, [])
32
+ response.should eq([])
33
+ end
34
+ end
35
+
36
+ context "when the response is mfa" do
37
+ it "returns the parsed response" do
38
+ allow_any_instance_of(::Finicity::V1::Request::ActivateAccounts).to(
39
+ receive(:activate_accounts).and_return(mfa)
40
+ )
41
+ response = subject.activate_accounts(123, 1, [])
42
+ response.should eq([])
43
+ end
44
+
45
+ it "sets the mfa session token" do
46
+ allow_any_instance_of(::Finicity::V1::Request::ActivateAccounts).to(
47
+ receive(:activate_accounts).and_return(mfa)
48
+ )
49
+ response = subject.activate_accounts(123, 1, [])
50
+ subject.mfa_session.should eq(mfa_session_token)
51
+ end
52
+ end
53
+
54
+ context "when the response is an error" do
55
+ it "fails" do
56
+ allow_any_instance_of(::Finicity::V1::Request::ActivateAccounts).to(
57
+ receive(:activate_accounts).and_return(error)
58
+ )
59
+ expect { subject.activate_accounts(123, 1, []) }.to raise_error(::Finicity::GenericError)
60
+ end
61
+ end
62
+ end
63
+
64
+ describe "#activate_accounts_with_mfa" do
65
+ context "when the response is successful" do
66
+ it "returns the parsed response" do
67
+ allow_any_instance_of(::Finicity::V1::Request::ActivateAccountsWithMfa).to(
68
+ receive(:activate_accounts_with_mfa).and_return(response)
69
+ )
70
+ response = subject.activate_accounts_with_mfa(123, 1, [], [])
71
+ response.should eq([])
72
+ end
73
+ end
74
+
75
+ context "when the response is mfa" do
76
+ it "returns the parsed response" do
77
+ allow_any_instance_of(::Finicity::V1::Request::ActivateAccountsWithMfa).to(
78
+ receive(:activate_accounts_with_mfa).and_return(mfa)
79
+ )
80
+ response = subject.activate_accounts_with_mfa(123, 1, [], [])
81
+ response.should eq([])
82
+ end
83
+
84
+ it "sets the mfa session token" do
85
+ allow_any_instance_of(::Finicity::V1::Request::ActivateAccountsWithMfa).to(
86
+ receive(:activate_accounts_with_mfa).and_return(mfa)
87
+ )
88
+ response = subject.activate_accounts_with_mfa(123, 1, [], [])
89
+ subject.mfa_session.should eq(mfa_session_token)
90
+ end
91
+ end
92
+
93
+ context "when the response is an error" do
94
+ it "fails" do
95
+ allow_any_instance_of(::Finicity::V1::Request::ActivateAccountsWithMfa).to(
96
+ receive(:activate_accounts_with_mfa).and_return(error)
97
+ )
98
+ expect { subject.activate_accounts_with_mfa(123, 1, [], []) }.to raise_error(::Finicity::GenericError)
99
+ end
100
+ end
101
+ end
102
+
103
+ describe "#add_customer" do
104
+ context "when the response is successful" do
105
+ it "returns the parsed response" do
106
+ allow_any_instance_of(::Finicity::V1::Request::AddCustomer).to(
107
+ receive(:add_customer).and_return(response)
108
+ )
109
+ response = subject.add_customer('USR-123')
110
+ response.id.should be_nil
111
+ end
112
+ end
113
+
114
+ context "when the response is an error" do
115
+ it "fails" do
116
+ allow_any_instance_of(::Finicity::V1::Request::AddCustomer).to(
117
+ receive(:add_customer).and_return(error)
118
+ )
119
+ expect { subject.add_customer('USR-123') }.to raise_error(::Finicity::GenericError)
120
+ end
121
+ end
122
+ end
123
+
124
+ describe "#authenticate!" do
125
+ context "when the response is successful" do
126
+ it "returns the parsed response" do
127
+ allow_any_instance_of(::Finicity::V2::Request::PartnerAuthentication).to(
128
+ receive(:authenticate).and_return(response)
129
+ )
130
+ response = subject.authenticate!
131
+ response.token.should be_nil
132
+ end
133
+ end
134
+
135
+ context "when the response is an error" do
136
+ it "fails" do
137
+ allow_any_instance_of(::Finicity::V2::Request::PartnerAuthentication).to(
138
+ receive(:authenticate).and_return(error)
139
+ )
140
+ expect { subject.authenticate! }.to raise_error(::Finicity::AuthenticationError)
141
+ end
142
+ end
143
+ end
144
+
145
+ describe "#delete_customer" do
146
+ context "when the response is successful" do
147
+ it "returns the parsed response" do
148
+ allow_any_instance_of(::Finicity::V1::Request::DeleteCustomer).to(
149
+ receive(:delete_customer).and_return(response)
150
+ )
151
+ response = subject.delete_customer(123)
152
+ response.should eq({})
153
+ end
154
+ end
155
+
156
+ context "when the response is an error" do
157
+ it "fails" do
158
+ allow_any_instance_of(::Finicity::V1::Request::DeleteCustomer).to(
159
+ receive(:delete_customer).and_return(error)
160
+ )
161
+ expect { subject.delete_customer(123) }.to raise_error(::Finicity::GenericError)
162
+ end
163
+ end
164
+ end
165
+
166
+ describe "#discover_accounts" do
167
+ context "when the response is successful" do
168
+ it "returns the parsed response" do
169
+ allow_any_instance_of(::Finicity::V1::Request::DiscoverAccounts).to(
170
+ receive(:discover_accounts).and_return(response)
171
+ )
172
+ response = subject.discover_accounts(123, 1, [])
173
+ response.should eq([])
174
+ end
175
+ end
176
+
177
+ context "when the response is mfa" do
178
+ it "returns the parsed response" do
179
+ allow_any_instance_of(::Finicity::V1::Request::DiscoverAccounts).to(
180
+ receive(:discover_accounts).and_return(mfa)
181
+ )
182
+ response = subject.discover_accounts(123, 1, [])
183
+ response.should eq([])
184
+ end
185
+
186
+ it "sets the mfa session token" do
187
+ allow_any_instance_of(::Finicity::V1::Request::DiscoverAccounts).to(
188
+ receive(:discover_accounts).and_return(mfa)
189
+ )
190
+ response = subject.discover_accounts(123, 1, [])
191
+ subject.mfa_session.should eq(mfa_session_token)
192
+ end
193
+ end
194
+
195
+ context "when the response is an error" do
196
+ it "fails" do
197
+ allow_any_instance_of(::Finicity::V1::Request::DiscoverAccounts).to(
198
+ receive(:discover_accounts).and_return(error)
199
+ )
200
+ expect { subject.discover_accounts(123, 1, []) }.to raise_error(::Finicity::GenericError)
201
+ end
202
+ end
203
+ end
204
+
205
+ describe "#discover_accounts_with_mfa" do
206
+ context "when the response is successful" do
207
+ it "returns the parsed response" do
208
+ allow_any_instance_of(::Finicity::V1::Request::DiscoverAccountsWithMfa).to(
209
+ receive(:discover_accounts_with_mfa).and_return(response)
210
+ )
211
+ response = subject.discover_accounts_with_mfa(123, 1, [], [])
212
+ response.should eq([])
213
+ end
214
+ end
215
+
216
+ context "when the response is mfa" do
217
+ it "returns the parsed response" do
218
+ allow_any_instance_of(::Finicity::V1::Request::DiscoverAccountsWithMfa).to(
219
+ receive(:discover_accounts_with_mfa).and_return(mfa)
220
+ )
221
+ response = subject.discover_accounts_with_mfa(123, 1, [], [])
222
+ response.should eq([])
223
+ end
224
+
225
+ it "sets the mfa session token" do
226
+ allow_any_instance_of(::Finicity::V1::Request::DiscoverAccountsWithMfa).to(
227
+ receive(:discover_accounts_with_mfa).and_return(mfa)
228
+ )
229
+ response = subject.discover_accounts_with_mfa(123, 1, [], [])
230
+ subject.mfa_session.should eq(mfa_session_token)
231
+ end
232
+ end
233
+
234
+ context "when the response is an error" do
235
+ it "fails" do
236
+ allow_any_instance_of(::Finicity::V1::Request::DiscoverAccountsWithMfa).to(
237
+ receive(:discover_accounts_with_mfa).and_return(error)
238
+ )
239
+ expect { subject.discover_accounts_with_mfa(123, 1, [], []) }.to raise_error(::Finicity::GenericError)
240
+ end
241
+ end
242
+ end
243
+
244
+ describe "#get_accounts" do
245
+ context "when the response is successful" do
246
+ it "returns the parsed response" do
247
+ allow_any_instance_of(::Finicity::V1::Request::GetAccounts).to(
248
+ receive(:get_accounts).and_return(response)
249
+ )
250
+ response = subject.get_accounts(1, 2)
251
+ response.should eq([])
252
+ end
253
+ end
254
+
255
+ context "when the response is an error" do
256
+ it "fails" do
257
+ allow_any_instance_of(::Finicity::V1::Request::GetAccounts).to(
258
+ receive(:get_accounts).and_return(error)
259
+ )
260
+ expect { subject.get_accounts(1, 2) }.to raise_error(::Finicity::GenericError)
261
+ end
262
+ end
263
+ end
264
+
265
+ describe "#get_customer_by_username" do
266
+ context "when the response is successful" do
267
+ let(:single_customer) { ::Finicity::V1::Response::Customers.new(:found => 1) }
268
+
269
+ it "returns the parsed response" do
270
+ allow(::Finicity::V1::Response::Customers).to receive(:parse).and_return(single_customer)
271
+ allow_any_instance_of(::Finicity::V1::Request::GetCustomersByUsername).to(
272
+ receive(:get_customers_by_username).and_return(response)
273
+ )
274
+ response = subject.get_customer_by_username("USR-123")
275
+ response.should be_nil
276
+ end
277
+ end
278
+
279
+ context "response contains multiple customers" do
280
+ let(:multiple_customers) { ::Finicity::V1::Response::Customers.new(:found => 2) }
281
+
282
+ it "raises an error" do
283
+ allow(::Finicity::V1::Response::Customers).to receive(:parse).and_return(multiple_customers)
284
+ allow_any_instance_of(::Finicity::V1::Request::GetCustomersByUsername).to(
285
+ receive(:get_customers_by_username).and_return(response)
286
+ )
287
+ expect { subject.get_customer_by_username("USR-123") }.to raise_error(
288
+ ::Finicity::DuplicateCustomerError
289
+ )
290
+ end
291
+ end
292
+
293
+ context "when the response is an error" do
294
+ it "fails" do
295
+ allow_any_instance_of(::Finicity::V1::Request::GetCustomersByUsername).to(
296
+ receive(:get_customers_by_username).and_return(error)
297
+ )
298
+ expect { subject.get_customer_by_username("USR-123") }.to raise_error(::Finicity::GenericError)
299
+ end
300
+ end
301
+ end
302
+
303
+ describe "#get_customers_by_username" do
304
+ context "when the response is successful" do
305
+ it "returns the parsed response" do
306
+ allow_any_instance_of(::Finicity::V1::Request::GetCustomersByUsername).to(
307
+ receive(:get_customers_by_username).and_return(response)
308
+ )
309
+ response = subject.get_customers_by_username(1, 1, 25)
310
+ response.should eq([])
311
+ end
312
+ end
313
+
314
+ context "when the response is an error" do
315
+ it "fails" do
316
+ allow_any_instance_of(::Finicity::V1::Request::GetCustomersByUsername).to(
317
+ receive(:get_customers_by_username).and_return(error)
318
+ )
319
+ expect { subject.get_customers_by_username(1, 1, 25) }.to raise_error(::Finicity::GenericError)
320
+ end
321
+ end
322
+ end
323
+
324
+ describe "#get_customers" do
325
+ context "when the response is successful" do
326
+ it "returns the parsed response" do
327
+ allow_any_instance_of(::Finicity::V1::Request::GetCustomers).to(
328
+ receive(:get_customers).and_return(response)
329
+ )
330
+ response = subject.get_customers
331
+ response.should eq([])
332
+ end
333
+ end
334
+
335
+ context "when the response is an error" do
336
+ it "fails" do
337
+ allow_any_instance_of(::Finicity::V1::Request::GetCustomers).to(
338
+ receive(:get_customers).and_return(error)
339
+ )
340
+ expect { subject.get_customers }.to raise_error(::Finicity::GenericError)
341
+ end
342
+ end
343
+ end
344
+
345
+ describe "#get_institution" do
346
+ context "when the response is successful" do
347
+ it "returns the parsed response" do
348
+ allow_any_instance_of(::Finicity::V1::Request::GetInstitution).to(
349
+ receive(:get_institution).and_return(response)
350
+ )
351
+ response = subject.get_institution(1)
352
+ response.should be_a(::Finicity::V1::Response::Institution)
353
+ end
354
+ end
355
+
356
+ context "when the response is an error" do
357
+ it "fails" do
358
+ allow_any_instance_of(::Finicity::V1::Request::GetInstitution).to(
359
+ receive(:get_institution).and_return(error)
360
+ )
361
+ expect { subject.get_institution(1) }.to raise_error(::Finicity::GenericError)
362
+ end
363
+ end
364
+ end
365
+
366
+ describe "#get_institutions" do
367
+ context "when the response is successful" do
368
+ it "returns the parsed response" do
369
+ allow_any_instance_of(::Finicity::V1::Request::GetInstitutions).to(
370
+ receive(:get_institutions).and_return(response)
371
+ )
372
+ response = subject.get_institutions("chase")
373
+ response.should eq([])
374
+ end
375
+ end
376
+
377
+ context "when the response is an error" do
378
+ it "fails" do
379
+ allow_any_instance_of(::Finicity::V1::Request::GetInstitutions).to(
380
+ receive(:get_institutions).and_return(error)
381
+ )
382
+ expect { subject.get_institutions("chase") }.to raise_error(::Finicity::GenericError)
383
+ end
384
+ end
385
+ end
386
+
387
+ describe "#get_login_form" do
388
+ context "when the response is successful" do
389
+ it "returns the parsed response" do
390
+ allow_any_instance_of(::Finicity::V1::Request::GetLoginForm).to(
391
+ receive(:get_login_form).and_return(response)
392
+ )
393
+ response = subject.get_login_form(1234)
394
+ response.should eq([])
395
+ end
396
+ end
397
+
398
+ context "when the response is an error" do
399
+ it "fails" do
400
+ allow_any_instance_of(::Finicity::V1::Request::GetLoginForm).to(
401
+ receive(:get_login_form).and_return(error)
402
+ )
403
+ expect { subject.get_login_form(1234) }.to raise_error(::Finicity::GenericError)
404
+ end
405
+ end
406
+ end
407
+
408
+ describe "#get_transactions" do
409
+ context "when the response is successful" do
410
+ it "returns the parsed response" do
411
+ allow_any_instance_of(::Finicity::V1::Request::GetTransactions).to(
412
+ receive(:get_transactions).and_return(response)
413
+ )
414
+ response = subject.get_transactions(123, 1, 1, 2)
415
+ response.should eq([])
416
+ end
417
+ end
418
+
419
+ context "when the response is an error" do
420
+ it "fails" do
421
+ allow_any_instance_of(::Finicity::V1::Request::GetTransactions).to(
422
+ receive(:get_transactions).and_return(error)
423
+ )
424
+ expect { subject.get_transactions(123, 1, 1 ,2) }.to raise_error(::Finicity::GenericError)
425
+ end
426
+ end
427
+ end
428
+
429
+ describe "#interactive_refresh_account" do
430
+ context "when the response is successful" do
431
+ it "returns the parsed response" do
432
+ allow_any_instance_of(::Finicity::V1::Request::InteractiveRefreshAccount).to(
433
+ receive(:interactive_refresh_account).and_return(response)
434
+ )
435
+ response = subject.interactive_refresh_account(123, 1)
436
+ response.should eq([])
437
+ end
438
+ end
439
+
440
+ context "when the response is mfa" do
441
+ it "returns the parsed response" do
442
+ allow_any_instance_of(::Finicity::V1::Request::InteractiveRefreshAccount).to(
443
+ receive(:interactive_refresh_account).and_return(mfa)
444
+ )
445
+ response = subject.interactive_refresh_account(123, 1)
446
+ response.should eq([])
447
+ end
448
+
449
+ it "sets the mfa session token" do
450
+ allow_any_instance_of(::Finicity::V1::Request::InteractiveRefreshAccount).to(
451
+ receive(:interactive_refresh_account).and_return(mfa)
452
+ )
453
+ response = subject.interactive_refresh_account(123, 1)
454
+ subject.mfa_session.should eq(mfa_session_token)
455
+ end
456
+ end
457
+
458
+ context "when the response is an error" do
459
+ it "fails" do
460
+ allow_any_instance_of(::Finicity::V1::Request::InteractiveRefreshAccount).to(
461
+ receive(:interactive_refresh_account).and_return(error)
462
+ )
463
+ expect { subject.interactive_refresh_account(123, 1) }.to raise_error(::Finicity::GenericError)
464
+ end
465
+ end
466
+ end
467
+
468
+ describe "#interactive_refresh_account_with_mfa" do
469
+ context "when the response is successful" do
470
+ it "returns the parsed response" do
471
+ allow_any_instance_of(::Finicity::V1::Request::InteractiveRefreshAccountWithMfa).to(
472
+ receive(:interactive_refresh_account_with_mfa).and_return(response)
473
+ )
474
+ response = subject.interactive_refresh_account_with_mfa(123, 1, [])
475
+ response.should eq([])
476
+ end
477
+ end
478
+
479
+ context "when the response is mfa" do
480
+ it "returns the parsed response" do
481
+ allow_any_instance_of(::Finicity::V1::Request::InteractiveRefreshAccountWithMfa).to(
482
+ receive(:interactive_refresh_account_with_mfa).and_return(mfa)
483
+ )
484
+ response = subject.interactive_refresh_account_with_mfa(123, 1, [])
485
+ response.should eq([])
486
+ end
487
+
488
+ it "sets the mfa session token" do
489
+ allow_any_instance_of(::Finicity::V1::Request::InteractiveRefreshAccountWithMfa).to(
490
+ receive(:interactive_refresh_account_with_mfa).and_return(mfa)
491
+ )
492
+ response = subject.interactive_refresh_account_with_mfa(123, 1, [])
493
+ subject.mfa_session.should eq(mfa_session_token)
494
+ end
495
+ end
496
+
497
+ context "when the response is an error" do
498
+ it "fails" do
499
+ allow_any_instance_of(::Finicity::V1::Request::InteractiveRefreshAccountWithMfa).to(
500
+ receive(:interactive_refresh_account_with_mfa).and_return(error)
501
+ )
502
+ expect { subject.interactive_refresh_account_with_mfa(123, 1, []) }.to raise_error(::Finicity::GenericError)
503
+ end
504
+ end
505
+ end
506
+
507
+ describe "#refresh_accounts" do
508
+ context "when the response is successful" do
509
+ it "returns the parsed response" do
510
+ allow_any_instance_of(::Finicity::V1::Request::RefreshAccounts).to(
511
+ receive(:refresh_accounts).and_return(response)
512
+ )
513
+ response = subject.refresh_accounts(1)
514
+ response.should eq([])
515
+ end
516
+ end
517
+
518
+ context "when the response is an error" do
519
+ it "fails" do
520
+ allow_any_instance_of(::Finicity::V1::Request::RefreshAccounts).to(
521
+ receive(:refresh_accounts).and_return(error)
522
+ )
523
+ expect { subject.refresh_accounts(1) }.to raise_error(::Finicity::GenericError)
524
+ end
525
+ end
526
+ end
527
+ end