syrup 0.0.3 → 0.0.4
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.
- data/.gitignore +8 -7
- data/.rspec +2 -2
- data/CHANGELOG.rdoc +8 -2
- data/Gemfile +4 -4
- data/README.rdoc +46 -46
- data/Rakefile +8 -8
- data/TODO.rdoc +12 -12
- data/lib/syrup/account.rb +142 -143
- data/lib/syrup/information_missing_error.rb +8 -8
- data/lib/syrup/institutions/institution_base.rb +142 -142
- data/lib/syrup/institutions/uccu.rb +135 -0
- data/lib/syrup/institutions/zions_bank.rb +175 -175
- data/lib/syrup/transaction.rb +19 -19
- data/lib/syrup/version.rb +3 -3
- data/lib/syrup.rb +46 -46
- data/spec/spec_helper.rb +15 -15
- data/spec/syrup/account_spec.rb +52 -52
- data/spec/syrup/institutions/institution_base_spec.rb +119 -119
- data/spec/syrup/institutions/uccu_spec.rb +45 -0
- data/spec/syrup/institutions/zions_bank_spec.rb +40 -40
- data/spec/syrup/syrup_spec.rb +40 -40
- data/spec/syrup/transaction_spec.rb +20 -20
- data/syrup.gemspec +26 -26
- metadata +60 -42
@@ -1,176 +1,176 @@
|
|
1
|
-
require 'date'
|
2
|
-
|
3
|
-
module Syrup
|
4
|
-
module Institutions
|
5
|
-
class ZionsBank < InstitutionBase
|
6
|
-
|
7
|
-
class << self
|
8
|
-
def name
|
9
|
-
"Zions Bank"
|
10
|
-
end
|
11
|
-
|
12
|
-
def id
|
13
|
-
"zions_bank"
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def fetch_account(account_id)
|
18
|
-
fetch_accounts
|
19
|
-
end
|
20
|
-
|
21
|
-
def fetch_accounts
|
22
|
-
ensure_authenticated
|
23
|
-
|
24
|
-
# List accounts
|
25
|
-
page = agent.get('https://banking.zionsbank.com/ibuir/displayAccountBalance.htm')
|
26
|
-
json = MultiJson.decode(page.body)
|
27
|
-
|
28
|
-
accounts = []
|
29
|
-
json['accountBalance']['depositAccountList'].each do |account|
|
30
|
-
new_account = Account.new(:id => account['accountId'])
|
31
|
-
new_account.name = account['name']
|
32
|
-
new_account.account_number = account['number']
|
33
|
-
new_account.current_balance = parse_currency(account['currentAmt'])
|
34
|
-
new_account.available_balance = parse_currency(account['availableAmt'])
|
35
|
-
new_account.type = :deposit
|
36
|
-
|
37
|
-
accounts << new_account
|
38
|
-
end
|
39
|
-
json['accountBalance']['creditAccountList'].each do |account|
|
40
|
-
new_account = Account.new(:id => account['accountId'])
|
41
|
-
new_account.name = account['name']
|
42
|
-
new_account.account_number = account['number']
|
43
|
-
new_account.current_balance = parse_currency(account['balanceDueAmt'])
|
44
|
-
new_account.type = :credit
|
45
|
-
|
46
|
-
accounts << new_account
|
47
|
-
end
|
48
|
-
|
49
|
-
accounts
|
50
|
-
end
|
51
|
-
|
52
|
-
def fetch_transactions(account_id, starting_at, ending_at)
|
53
|
-
ensure_authenticated
|
54
|
-
|
55
|
-
transactions = []
|
56
|
-
|
57
|
-
post_vars = { "actAcct" => account_id, "dayRange.searchType" => "dates", "dayRange.startDate" => starting_at.strftime('%m/%d/%Y'), "dayRange.endDate" => ending_at.strftime('%m/%d/%Y'), "submit_view.x" => 11, "submit_view.y" => 11, "submit_view" => "view" }
|
58
|
-
|
59
|
-
page = agent.post("https://banking.zionsbank.com/zfnb/userServlet/app/bank/user/register_view_main?reSort=false&actAcct=#{account_id}", post_vars)
|
60
|
-
|
61
|
-
# Get all the transactions
|
62
|
-
page.search('tr').each do |row_element|
|
63
|
-
# Look for the account information first
|
64
|
-
account = find_account_by_id(account_id)
|
65
|
-
datapart = row_element.css('.acct')
|
66
|
-
if datapart
|
67
|
-
/Prior Day Balance:\s*([^<]+)/.match(datapart.inner_html) do |match|
|
68
|
-
account.prior_day_balance = parse_currency(match[1])
|
69
|
-
end
|
70
|
-
/Current Balance:\s*([^<]+)/.match(datapart.inner_html) do |match|
|
71
|
-
account.current_balance = parse_currency(match[1])
|
72
|
-
end
|
73
|
-
/Available Balance:\s*([^<]+)/.match(datapart.inner_html) do |match|
|
74
|
-
account.available_balance = parse_currency(match[1])
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
data = []
|
79
|
-
datapart = row_element.css('.data')
|
80
|
-
if datapart
|
81
|
-
data += datapart
|
82
|
-
datapart = row_element.css('.curr')
|
83
|
-
data += datapart if datapart
|
84
|
-
end
|
85
|
-
|
86
|
-
datapart = row_element.css('.datagrey')
|
87
|
-
if datapart
|
88
|
-
data += datapart
|
89
|
-
datapart = row_element.css('.currgrey')
|
90
|
-
data += datapart if datapart
|
91
|
-
end
|
92
|
-
|
93
|
-
if data.size == 7
|
94
|
-
data.map! {|cell| cell.inner_html.strip.gsub(/[^ -~]/, '') }
|
95
|
-
|
96
|
-
transaction = Transaction.new
|
97
|
-
|
98
|
-
transaction.posted_at = Date.strptime(data[0], '%m/%d/%Y')
|
99
|
-
transaction.payee = data[2]
|
100
|
-
transaction.status = data[3].include?("Posted") ? :posted : :pending
|
101
|
-
unless data[4].empty?
|
102
|
-
transaction.amount = -parse_currency(data[4])
|
103
|
-
end
|
104
|
-
unless data[5].empty?
|
105
|
-
transaction.amount = parse_currency(data[5])
|
106
|
-
end
|
107
|
-
|
108
|
-
transactions << transaction
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
transactions
|
113
|
-
end
|
114
|
-
|
115
|
-
private
|
116
|
-
|
117
|
-
def ensure_authenticated
|
118
|
-
|
119
|
-
# Check to see if already authenticated
|
120
|
-
page = agent.get('https://banking.zionsbank.com/ibuir')
|
121
|
-
if page.body.include?("SessionTimeOutException")
|
122
|
-
|
123
|
-
raise InformationMissingError, "Please supply a username" unless self.username
|
124
|
-
raise InformationMissingError, "Please supply a password" unless self.password
|
125
|
-
|
126
|
-
@agent = Mechanize.new
|
127
|
-
|
128
|
-
# Enter the username
|
129
|
-
page = agent.get('https://zionsbank.com')
|
130
|
-
form = page.form('logonForm')
|
131
|
-
form.publicCred1 = username
|
132
|
-
page = form.submit
|
133
|
-
|
134
|
-
# If the supplied username is incorrect, raise an exception
|
135
|
-
raise InformationMissingError, "Invalid username" if page.title == "Error Page"
|
136
|
-
|
137
|
-
# Go on to the next page
|
138
|
-
page = page.links.first.click
|
139
|
-
|
140
|
-
# Find the secret question
|
141
|
-
question = page.search('div.form_field')[2].css('div').inner_text
|
142
|
-
|
143
|
-
# If the answer to this question was not supplied, raise an exception
|
144
|
-
raise InformationMissingError, "Please answer the question, \"#{question}\"" unless secret_questions[question]
|
145
|
-
|
146
|
-
# Enter the answer to the secret question
|
147
|
-
form = page.forms.first
|
148
|
-
form["challengeEntry.answerText"] = secret_questions[question]
|
149
|
-
form.radiobutton_with(:value => 'false').check
|
150
|
-
submit_button = form.button_with(:name => '_eventId_submit')
|
151
|
-
page = form.submit(submit_button)
|
152
|
-
|
153
|
-
# If the supplied answer is incorrect, raise an exception
|
154
|
-
raise InformationMissingError, "\"#{secret_questions[question]}\" is not the correct answer to, \"#{question}\"" unless page.search('#errorComponent').empty?
|
155
|
-
|
156
|
-
# Enter the password
|
157
|
-
form = page.forms.first
|
158
|
-
form.privateCred1 = password
|
159
|
-
submit_button = form.button_with(:name => '_eventId_submit')
|
160
|
-
page = form.submit(submit_button)
|
161
|
-
|
162
|
-
# If the supplied password is incorrect, raise an exception
|
163
|
-
raise InformationMissingError, "An invalid password was supplied" unless page.search('#errorComponent').empty?
|
164
|
-
|
165
|
-
# Clicking this link logs us into the banking.zionsbank.com domain
|
166
|
-
page = page.links.first.click
|
167
|
-
|
168
|
-
raise "Unknown URL reached. Try logging in manually through a browser." if page.uri.to_s != "https://banking.zionsbank.com/ibuir/displayUserInterface.htm"
|
169
|
-
end
|
170
|
-
|
171
|
-
true
|
172
|
-
end
|
173
|
-
|
174
|
-
end
|
175
|
-
end
|
1
|
+
require 'date'
|
2
|
+
|
3
|
+
module Syrup
|
4
|
+
module Institutions
|
5
|
+
class ZionsBank < InstitutionBase
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def name
|
9
|
+
"Zions Bank"
|
10
|
+
end
|
11
|
+
|
12
|
+
def id
|
13
|
+
"zions_bank"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def fetch_account(account_id)
|
18
|
+
fetch_accounts
|
19
|
+
end
|
20
|
+
|
21
|
+
def fetch_accounts
|
22
|
+
ensure_authenticated
|
23
|
+
|
24
|
+
# List accounts
|
25
|
+
page = agent.get('https://banking.zionsbank.com/ibuir/displayAccountBalance.htm')
|
26
|
+
json = MultiJson.decode(page.body)
|
27
|
+
|
28
|
+
accounts = []
|
29
|
+
json['accountBalance']['depositAccountList'].each do |account|
|
30
|
+
new_account = Account.new(:id => account['accountId'], :institution => self)
|
31
|
+
new_account.name = account['name']
|
32
|
+
new_account.account_number = account['number']
|
33
|
+
new_account.current_balance = parse_currency(account['currentAmt'])
|
34
|
+
new_account.available_balance = parse_currency(account['availableAmt'])
|
35
|
+
new_account.type = :deposit
|
36
|
+
|
37
|
+
accounts << new_account
|
38
|
+
end
|
39
|
+
json['accountBalance']['creditAccountList'].each do |account|
|
40
|
+
new_account = Account.new(:id => account['accountId'], :institution => self)
|
41
|
+
new_account.name = account['name']
|
42
|
+
new_account.account_number = account['number']
|
43
|
+
new_account.current_balance = parse_currency(account['balanceDueAmt'])
|
44
|
+
new_account.type = :credit
|
45
|
+
|
46
|
+
accounts << new_account
|
47
|
+
end
|
48
|
+
|
49
|
+
accounts
|
50
|
+
end
|
51
|
+
|
52
|
+
def fetch_transactions(account_id, starting_at, ending_at)
|
53
|
+
ensure_authenticated
|
54
|
+
|
55
|
+
transactions = []
|
56
|
+
|
57
|
+
post_vars = { "actAcct" => account_id, "dayRange.searchType" => "dates", "dayRange.startDate" => starting_at.strftime('%m/%d/%Y'), "dayRange.endDate" => ending_at.strftime('%m/%d/%Y'), "submit_view.x" => 11, "submit_view.y" => 11, "submit_view" => "view" }
|
58
|
+
|
59
|
+
page = agent.post("https://banking.zionsbank.com/zfnb/userServlet/app/bank/user/register_view_main?reSort=false&actAcct=#{account_id}", post_vars)
|
60
|
+
|
61
|
+
# Get all the transactions
|
62
|
+
page.search('tr').each do |row_element|
|
63
|
+
# Look for the account information first
|
64
|
+
account = find_account_by_id(account_id)
|
65
|
+
datapart = row_element.css('.acct')
|
66
|
+
if datapart
|
67
|
+
/Prior Day Balance:\s*([^<]+)/.match(datapart.inner_html) do |match|
|
68
|
+
account.prior_day_balance = parse_currency(match[1])
|
69
|
+
end
|
70
|
+
/Current Balance:\s*([^<]+)/.match(datapart.inner_html) do |match|
|
71
|
+
account.current_balance = parse_currency(match[1])
|
72
|
+
end
|
73
|
+
/Available Balance:\s*([^<]+)/.match(datapart.inner_html) do |match|
|
74
|
+
account.available_balance = parse_currency(match[1])
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
data = []
|
79
|
+
datapart = row_element.css('.data')
|
80
|
+
if datapart
|
81
|
+
data += datapart
|
82
|
+
datapart = row_element.css('.curr')
|
83
|
+
data += datapart if datapart
|
84
|
+
end
|
85
|
+
|
86
|
+
datapart = row_element.css('.datagrey')
|
87
|
+
if datapart
|
88
|
+
data += datapart
|
89
|
+
datapart = row_element.css('.currgrey')
|
90
|
+
data += datapart if datapart
|
91
|
+
end
|
92
|
+
|
93
|
+
if data.size == 7
|
94
|
+
data.map! {|cell| cell.inner_html.strip.gsub(/[^ -~]/, '') }
|
95
|
+
|
96
|
+
transaction = Transaction.new
|
97
|
+
|
98
|
+
transaction.posted_at = Date.strptime(data[0], '%m/%d/%Y')
|
99
|
+
transaction.payee = data[2]
|
100
|
+
transaction.status = data[3].include?("Posted") ? :posted : :pending
|
101
|
+
unless data[4].empty?
|
102
|
+
transaction.amount = -parse_currency(data[4])
|
103
|
+
end
|
104
|
+
unless data[5].empty?
|
105
|
+
transaction.amount = parse_currency(data[5])
|
106
|
+
end
|
107
|
+
|
108
|
+
transactions << transaction
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
transactions
|
113
|
+
end
|
114
|
+
|
115
|
+
private
|
116
|
+
|
117
|
+
def ensure_authenticated
|
118
|
+
|
119
|
+
# Check to see if already authenticated
|
120
|
+
page = agent.get('https://banking.zionsbank.com/ibuir')
|
121
|
+
if page.body.include?("SessionTimeOutException")
|
122
|
+
|
123
|
+
raise InformationMissingError, "Please supply a username" unless self.username
|
124
|
+
raise InformationMissingError, "Please supply a password" unless self.password
|
125
|
+
|
126
|
+
@agent = Mechanize.new
|
127
|
+
|
128
|
+
# Enter the username
|
129
|
+
page = agent.get('https://zionsbank.com')
|
130
|
+
form = page.form('logonForm')
|
131
|
+
form.publicCred1 = username
|
132
|
+
page = form.submit
|
133
|
+
|
134
|
+
# If the supplied username is incorrect, raise an exception
|
135
|
+
raise InformationMissingError, "Invalid username" if page.title == "Error Page"
|
136
|
+
|
137
|
+
# Go on to the next page
|
138
|
+
page = page.links.first.click
|
139
|
+
|
140
|
+
# Find the secret question
|
141
|
+
question = page.search('div.form_field')[2].css('div').inner_text
|
142
|
+
|
143
|
+
# If the answer to this question was not supplied, raise an exception
|
144
|
+
raise InformationMissingError, "Please answer the question, \"#{question}\"" unless secret_questions && secret_questions[question]
|
145
|
+
|
146
|
+
# Enter the answer to the secret question
|
147
|
+
form = page.forms.first
|
148
|
+
form["challengeEntry.answerText"] = secret_questions[question]
|
149
|
+
form.radiobutton_with(:value => 'false').check
|
150
|
+
submit_button = form.button_with(:name => '_eventId_submit')
|
151
|
+
page = form.submit(submit_button)
|
152
|
+
|
153
|
+
# If the supplied answer is incorrect, raise an exception
|
154
|
+
raise InformationMissingError, "\"#{secret_questions[question]}\" is not the correct answer to, \"#{question}\"" unless page.search('#errorComponent').empty?
|
155
|
+
|
156
|
+
# Enter the password
|
157
|
+
form = page.forms.first
|
158
|
+
form.privateCred1 = password
|
159
|
+
submit_button = form.button_with(:name => '_eventId_submit')
|
160
|
+
page = form.submit(submit_button)
|
161
|
+
|
162
|
+
# If the supplied password is incorrect, raise an exception
|
163
|
+
raise InformationMissingError, "An invalid password was supplied" unless page.search('#errorComponent').empty?
|
164
|
+
|
165
|
+
# Clicking this link logs us into the banking.zionsbank.com domain
|
166
|
+
page = page.links.first.click
|
167
|
+
|
168
|
+
raise "Unknown URL reached. Try logging in manually through a browser." if page.uri.to_s != "https://banking.zionsbank.com/ibuir/displayUserInterface.htm"
|
169
|
+
end
|
170
|
+
|
171
|
+
true
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
175
|
+
end
|
176
176
|
end
|
data/lib/syrup/transaction.rb
CHANGED
@@ -1,20 +1,20 @@
|
|
1
|
-
module Syrup
|
2
|
-
class Transaction
|
3
|
-
##
|
4
|
-
# :attr_accessor: status
|
5
|
-
# Currently, the only valid types are :posted and :pending
|
6
|
-
|
7
|
-
#
|
8
|
-
attr_accessor :id, :payee, :amount, :posted_at, :status
|
9
|
-
|
10
|
-
# New objects can be instantiated as either empty (pass no construction parameter) or pre-set with
|
11
|
-
# attributes (pass a hash with key names matching the associated attribute names).
|
12
|
-
def initialize(attr_hash = nil)
|
13
|
-
if attr_hash
|
14
|
-
attr_hash.each do |k, v|
|
15
|
-
instance_variable_set "@#{k}", v
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
1
|
+
module Syrup
|
2
|
+
class Transaction
|
3
|
+
##
|
4
|
+
# :attr_accessor: status
|
5
|
+
# Currently, the only valid types are :posted and :pending
|
6
|
+
|
7
|
+
#
|
8
|
+
attr_accessor :id, :payee, :amount, :posted_at, :status
|
9
|
+
|
10
|
+
# New objects can be instantiated as either empty (pass no construction parameter) or pre-set with
|
11
|
+
# attributes (pass a hash with key names matching the associated attribute names).
|
12
|
+
def initialize(attr_hash = nil)
|
13
|
+
if attr_hash
|
14
|
+
attr_hash.each do |k, v|
|
15
|
+
instance_variable_set "@#{k}", v
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
20
|
end
|
data/lib/syrup/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
module Syrup
|
2
|
-
VERSION = "0.0.
|
3
|
-
end
|
1
|
+
module Syrup
|
2
|
+
VERSION = "0.0.4"
|
3
|
+
end
|
data/lib/syrup.rb
CHANGED
@@ -1,46 +1,46 @@
|
|
1
|
-
require 'date'
|
2
|
-
require 'mechanize'
|
3
|
-
require 'multi_json'
|
4
|
-
require 'syrup/information_missing_error'
|
5
|
-
require 'syrup/account'
|
6
|
-
require 'syrup/transaction'
|
7
|
-
|
8
|
-
# require all institutions
|
9
|
-
require 'syrup/institutions/institution_base'
|
10
|
-
Dir[File.dirname(__FILE__) + '/syrup/institutions/*.rb'].each {|file| require file }
|
11
|
-
|
12
|
-
module Syrup
|
13
|
-
extend self
|
14
|
-
|
15
|
-
# Returns an array of institutions.
|
16
|
-
#
|
17
|
-
# Syrup.institutions.each do |institution|
|
18
|
-
# puts "name: #{institution.name}, id: #{institution.id}"
|
19
|
-
# end
|
20
|
-
def institutions
|
21
|
-
Institutions::InstitutionBase.subclasses
|
22
|
-
end
|
23
|
-
|
24
|
-
# Returns a new institution object with the specified +institution_id+.
|
25
|
-
# If you pass in a block, you can use it to setup the username, password, and secret_questions.
|
26
|
-
#
|
27
|
-
# Syrup.setup_institution('zions_bank') do |config|
|
28
|
-
# config.username = "my_user"
|
29
|
-
# config.password = "my_password"
|
30
|
-
# config.secret_questions = {
|
31
|
-
# 'How long is your beard?' => '6in'
|
32
|
-
# }
|
33
|
-
# end
|
34
|
-
def setup_institution(institution_id)
|
35
|
-
institution = institutions.find { |i| i.id == institution_id }
|
36
|
-
|
37
|
-
if institution
|
38
|
-
i = institution.new
|
39
|
-
if block_given?
|
40
|
-
i.setup { |config| yield config }
|
41
|
-
else
|
42
|
-
i
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
1
|
+
require 'date'
|
2
|
+
require 'mechanize'
|
3
|
+
require 'multi_json'
|
4
|
+
require 'syrup/information_missing_error'
|
5
|
+
require 'syrup/account'
|
6
|
+
require 'syrup/transaction'
|
7
|
+
|
8
|
+
# require all institutions
|
9
|
+
require 'syrup/institutions/institution_base'
|
10
|
+
Dir[File.dirname(__FILE__) + '/syrup/institutions/*.rb'].each {|file| require file }
|
11
|
+
|
12
|
+
module Syrup
|
13
|
+
extend self
|
14
|
+
|
15
|
+
# Returns an array of institutions.
|
16
|
+
#
|
17
|
+
# Syrup.institutions.each do |institution|
|
18
|
+
# puts "name: #{institution.name}, id: #{institution.id}"
|
19
|
+
# end
|
20
|
+
def institutions
|
21
|
+
Institutions::InstitutionBase.subclasses
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns a new institution object with the specified +institution_id+.
|
25
|
+
# If you pass in a block, you can use it to setup the username, password, and secret_questions.
|
26
|
+
#
|
27
|
+
# Syrup.setup_institution('zions_bank') do |config|
|
28
|
+
# config.username = "my_user"
|
29
|
+
# config.password = "my_password"
|
30
|
+
# config.secret_questions = {
|
31
|
+
# 'How long is your beard?' => '6in'
|
32
|
+
# }
|
33
|
+
# end
|
34
|
+
def setup_institution(institution_id)
|
35
|
+
institution = institutions.find { |i| i.id == institution_id }
|
36
|
+
|
37
|
+
if institution
|
38
|
+
i = institution.new
|
39
|
+
if block_given?
|
40
|
+
i.setup { |config| yield config }
|
41
|
+
else
|
42
|
+
i
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'bundler/setup'
|
3
|
-
require 'syrup'
|
4
|
-
|
5
|
-
RSpec.configure do |config|
|
6
|
-
include Syrup
|
7
|
-
|
8
|
-
config.filter_run_excluding :bank_integration => true
|
9
|
-
end
|
10
|
-
|
11
|
-
module Syrup
|
12
|
-
def spec_resource_path
|
13
|
-
File.dirname(__FILE__) + '/resources/'
|
14
|
-
end
|
15
|
-
end
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
require 'syrup'
|
4
|
+
|
5
|
+
RSpec.configure do |config|
|
6
|
+
include Syrup
|
7
|
+
|
8
|
+
config.filter_run_excluding :bank_integration => true
|
9
|
+
end
|
10
|
+
|
11
|
+
module Syrup
|
12
|
+
def spec_resource_path
|
13
|
+
File.dirname(__FILE__) + '/resources/'
|
14
|
+
end
|
15
|
+
end
|
data/spec/syrup/account_spec.rb
CHANGED
@@ -1,53 +1,53 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe Account do
|
4
|
-
before(:each) do
|
5
|
-
@institution = double()
|
6
|
-
@institution.stub(:populate_account) do
|
7
|
-
@account.populated = true
|
8
|
-
@account.instance_variable_set :@name, 'my name'
|
9
|
-
end
|
10
|
-
@institution.stub(:fetch_transactions) do
|
11
|
-
[
|
12
|
-
Transaction.new(:id => 1, :payee => 'Wal-Mart', :posted_at => Date.today - 1, :amount => 30.14),
|
13
|
-
Transaction.new(:id => 2, :payee => 'Pizza Hut', :posted_at => Date.today - 2, :amount => 10.23)
|
14
|
-
]
|
15
|
-
end
|
16
|
-
@account = Account.new :id => 1, :institution => @institution
|
17
|
-
end
|
18
|
-
|
19
|
-
it "has lots of useful properties" do
|
20
|
-
account = Account.new
|
21
|
-
|
22
|
-
account.should respond_to(:id)
|
23
|
-
account.should respond_to(:name)
|
24
|
-
account.should respond_to(:type)
|
25
|
-
account.should respond_to(:account_number)
|
26
|
-
account.should respond_to(:current_balance)
|
27
|
-
account.should respond_to(:available_balance)
|
28
|
-
account.should respond_to(:prior_day_balance)
|
29
|
-
end
|
30
|
-
|
31
|
-
it "is populated when properties are accessed" do
|
32
|
-
@account.instance_variable_get(:@name).should be_nil
|
33
|
-
@account.name.should == "my name"
|
34
|
-
end
|
35
|
-
|
36
|
-
it "is considered == if the id is the same" do
|
37
|
-
account1 = Account.new :id => 1, :name => "checking"
|
38
|
-
account2 = Account.new :id => 1, :name => "savings"
|
39
|
-
account3 = Account.new :id => 2, :name => "trash"
|
40
|
-
|
41
|
-
account1.should == account2
|
42
|
-
account1.should_not == account3
|
43
|
-
end
|
44
|
-
|
45
|
-
context "given a date range" do
|
46
|
-
it "gets transactions" do
|
47
|
-
@account.find_transactions(Date.today - 30)
|
48
|
-
end
|
49
|
-
#it "only fetches transactions when needed"
|
50
|
-
end
|
51
|
-
|
52
|
-
#it "doesn't allow there to be too many cached transactions"
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Account do
|
4
|
+
before(:each) do
|
5
|
+
@institution = double()
|
6
|
+
@institution.stub(:populate_account) do
|
7
|
+
@account.populated = true
|
8
|
+
@account.instance_variable_set :@name, 'my name'
|
9
|
+
end
|
10
|
+
@institution.stub(:fetch_transactions) do
|
11
|
+
[
|
12
|
+
Transaction.new(:id => 1, :payee => 'Wal-Mart', :posted_at => Date.today - 1, :amount => 30.14),
|
13
|
+
Transaction.new(:id => 2, :payee => 'Pizza Hut', :posted_at => Date.today - 2, :amount => 10.23)
|
14
|
+
]
|
15
|
+
end
|
16
|
+
@account = Account.new :id => 1, :institution => @institution
|
17
|
+
end
|
18
|
+
|
19
|
+
it "has lots of useful properties" do
|
20
|
+
account = Account.new
|
21
|
+
|
22
|
+
account.should respond_to(:id)
|
23
|
+
account.should respond_to(:name)
|
24
|
+
account.should respond_to(:type)
|
25
|
+
account.should respond_to(:account_number)
|
26
|
+
account.should respond_to(:current_balance)
|
27
|
+
account.should respond_to(:available_balance)
|
28
|
+
account.should respond_to(:prior_day_balance)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "is populated when properties are accessed" do
|
32
|
+
@account.instance_variable_get(:@name).should be_nil
|
33
|
+
@account.name.should == "my name"
|
34
|
+
end
|
35
|
+
|
36
|
+
it "is considered == if the id is the same" do
|
37
|
+
account1 = Account.new :id => 1, :name => "checking"
|
38
|
+
account2 = Account.new :id => 1, :name => "savings"
|
39
|
+
account3 = Account.new :id => 2, :name => "trash"
|
40
|
+
|
41
|
+
account1.should == account2
|
42
|
+
account1.should_not == account3
|
43
|
+
end
|
44
|
+
|
45
|
+
context "given a date range" do
|
46
|
+
it "gets transactions" do
|
47
|
+
@account.find_transactions(Date.today - 30)
|
48
|
+
end
|
49
|
+
#it "only fetches transactions when needed"
|
50
|
+
end
|
51
|
+
|
52
|
+
#it "doesn't allow there to be too many cached transactions"
|
53
53
|
end
|