syrup 0.0.12 → 0.0.13

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.
@@ -1,188 +1,188 @@
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.load(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 = unescape_html(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 = unescape_html(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 && datapart.inner_html.size > 0
67
- if match = /Prior Day Balance:\s*([^<]+)/.match(datapart.inner_html)
68
- account.prior_day_balance = parse_currency(match[1])
69
- end
70
- if match = /Current Balance:\s*([^<]+)/.match(datapart.inner_html)
71
- account.current_balance = parse_currency(match[1])
72
- end
73
- if match = /Available Balance:\s*([^<]+)/.match(datapart.inner_html)
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 = unescape_html(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
- # Enter the username
127
- page = agent.get('https://www.zionsbank.com')
128
- form = page.form('logonForm')
129
- form.pm_fp = "version%3D1%26pm%5Ffpua%3Dmozilla%2F5%2E0%20%28windows%20nt%206%2E1%3B%20wow64%29%20applewebkit%2F535%2E19%20%28khtml%2C%20like%20gecko%29%20chrome%2F18%2E0%2E1025%2E162%20safari%2F535%2E19%7C5%2E0%20%28Windows%20NT%206%2E1%3B%20WOW64%29%20AppleWebKit%2F535%2E19%20%28KHTML%2C%20like%20Gecko%29%20Chrome%2F18%2E0%2E1025%2E162%20Safari%2F535%2E19%7CWin32%26pm%5Ffpsc%3D32%7C1920%7C1200%7C1200%26pm%5Ffpsw%3D%7Cqt1%7Cqt2%7Cqt3%7Cqt4%7Cqt5%7Cqt6%26pm%5Ffptz%3D%2D6%26pm%5Ffpln%3Dlang%3Den%2DUS%7Csyslang%3D%7Cuserlang%3D%26pm%5Ffpjv%3D1%26pm%5Ffpco%3D1"
130
- form.publicCred1 = username
131
- page = form.submit
132
-
133
- # If the supplied username is incorrect, raise an exception
134
- raise InformationMissingError, "Invalid username" if page.title == "Error Page"
135
-
136
- # Go on to the next page
137
- page = page.links.first.click
138
-
139
- refresh = page.body.match /meta http-equiv="Refresh" content="0; url=([^"]+)/
140
- if refresh
141
- url = refresh[1]
142
- page = agent.get("https://securentry.zionsbank.com#{url}")
143
- end
144
-
145
- # Skip the secret question if we are prompted for the password
146
- unless page.body.include?("Site Validation and Password")
147
- # Find the secret question
148
- question = page.search('div.form_field')[2].css('div').inner_text
149
-
150
- # If the answer to this question was not supplied, raise an exception
151
- raise InformationMissingError, "Please answer the question, \"#{question}\"" unless secret_questions && secret_questions[question]
152
-
153
- # Enter the answer to the secret question
154
- form = page.forms.first
155
- form["challengeEntry.answerText"] = secret_questions[question]
156
- form.radiobutton_with(:value => 'false').check
157
- submit_button = form.button_with(:name => '_eventId_submit')
158
- page = form.submit(submit_button)
159
-
160
- # If the supplied answer is incorrect, raise an exception
161
- raise InformationMissingError, "\"#{secret_questions[question]}\" is not the correct answer to, \"#{question}\"" unless page.search('#errorComponent').empty?
162
- end
163
-
164
- # Enter the password
165
- form = page.forms.first
166
- form.privateCred1 = password
167
- submit_button = form.button_with(:name => '_eventId_submit')
168
- page = form.submit(submit_button)
169
-
170
- # If the supplied password is incorrect, raise an exception
171
- raise InformationMissingError, "An invalid password was supplied" unless page.search('#errorComponent').empty?
172
-
173
- # Clicking this link logs us into the banking.zionsbank.com domain
174
- page = page.links.first.click
175
-
176
- if page.uri.to_s != "https://banking.zionsbank.com/ibuir/displayUserInterface.htm"
177
- page = agent.get('https://banking.zionsbank.com/zfnb/userServlet/app/bank/user/viewaccountsbysubtype/viewAccount')
178
-
179
- raise "Unknown URL reached. Try logging in manually through a browser." if page.body.include?("SessionTimeOutException")
180
- end
181
- end
182
-
183
- true
184
- end
185
-
186
- end
187
- end
188
- 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.load(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 = unescape_html(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 = unescape_html(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 && datapart.inner_html.size > 0
67
+ if match = /Prior Day Balance:\s*([^<]+)/.match(datapart.inner_html)
68
+ account.prior_day_balance = parse_currency(match[1])
69
+ end
70
+ if match = /Current Balance:\s*([^<]+)/.match(datapart.inner_html)
71
+ account.current_balance = parse_currency(match[1])
72
+ end
73
+ if match = /Available Balance:\s*([^<]+)/.match(datapart.inner_html)
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 = unescape_html(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
+ # Enter the username
127
+ page = agent.get('https://www.zionsbank.com')
128
+ form = page.form('logonForm')
129
+ form.pm_fp = "version%3D1%26pm%5Ffpua%3Dmozilla%2F5%2E0%20%28windows%20nt%206%2E1%3B%20wow64%29%20applewebkit%2F535%2E19%20%28khtml%2C%20like%20gecko%29%20chrome%2F18%2E0%2E1025%2E162%20safari%2F535%2E19%7C5%2E0%20%28Windows%20NT%206%2E1%3B%20WOW64%29%20AppleWebKit%2F535%2E19%20%28KHTML%2C%20like%20Gecko%29%20Chrome%2F18%2E0%2E1025%2E162%20Safari%2F535%2E19%7CWin32%26pm%5Ffpsc%3D32%7C1920%7C1200%7C1200%26pm%5Ffpsw%3D%7Cqt1%7Cqt2%7Cqt3%7Cqt4%7Cqt5%7Cqt6%26pm%5Ffptz%3D%2D6%26pm%5Ffpln%3Dlang%3Den%2DUS%7Csyslang%3D%7Cuserlang%3D%26pm%5Ffpjv%3D1%26pm%5Ffpco%3D1"
130
+ form.publicCred1 = username
131
+ page = form.submit
132
+
133
+ # If the supplied username is incorrect, raise an exception
134
+ raise InformationMissingError, "Invalid username" if page.title == "Error Page"
135
+
136
+ # Go on to the next page
137
+ page = page.links.first.click
138
+
139
+ refresh = page.body.match /meta http-equiv="Refresh" content="0; url=([^"]+)/
140
+ if refresh
141
+ url = refresh[1]
142
+ page = agent.get("https://securentry.zionsbank.com#{url}")
143
+ end
144
+
145
+ # Skip the secret question if we are prompted for the password
146
+ unless page.body.include?("Site Validation and Password")
147
+ # Find the secret question
148
+ question = page.search('div.form_field')[2].css('div').inner_text
149
+
150
+ # If the answer to this question was not supplied, raise an exception
151
+ raise InformationMissingError, "Please answer the question, \"#{question}\"" unless secret_questions && secret_questions[question]
152
+
153
+ # Enter the answer to the secret question
154
+ form = page.forms.first
155
+ form["challengeEntry.answerText"] = secret_questions[question]
156
+ form.radiobutton_with(:value => 'false').check
157
+ submit_button = form.button_with(:name => '_eventId_submit')
158
+ page = form.submit(submit_button)
159
+
160
+ # If the supplied answer is incorrect, raise an exception
161
+ raise InformationMissingError, "\"#{secret_questions[question]}\" is not the correct answer to, \"#{question}\"" unless page.search('#errorComponent').empty?
162
+ end
163
+
164
+ # Enter the password
165
+ form = page.forms.first
166
+ form.privateCred1 = password
167
+ submit_button = form.button_with(:name => '_eventId_submit')
168
+ page = form.submit(submit_button)
169
+
170
+ # If the supplied password is incorrect, raise an exception
171
+ raise InformationMissingError, "An invalid password was supplied" unless page.search('#errorComponent').empty?
172
+
173
+ # Clicking this link logs us into the banking.zionsbank.com domain
174
+ page = page.links.first.click
175
+
176
+ if page.uri.to_s != "https://banking.zionsbank.com/ibuir/displayUserInterface.htm"
177
+ page = agent.get('https://banking.zionsbank.com/zfnb/userServlet/app/bank/user/viewaccountsbysubtype/viewAccount')
178
+
179
+ raise "Unknown URL reached. Try logging in manually through a browser." if page.body.include?("SessionTimeOutException")
180
+ end
181
+ end
182
+
183
+ true
184
+ end
185
+
186
+ end
187
+ end
188
+ end
@@ -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.12"
3
- end
1
+ module Syrup
2
+ VERSION = "0.0.13"
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
@@ -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