nordea-rb 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown CHANGED
@@ -114,6 +114,7 @@ Transfer money between your own accounts:
114
114
  salary_account.deposit(10.0, 'SEK', :withdraw_from => savings)
115
115
  end
116
116
 
117
+ There are more, real world examples in the examples folder.
117
118
 
118
119
  ## Command Line Tool
119
120
 
data/Rakefile CHANGED
@@ -18,6 +18,7 @@ begin
18
18
  gemspec.email = "name@my-domain.se"
19
19
  gemspec.homepage = "http://github.com/haraldmartin/nordea-rb"
20
20
  gemspec.authors = ["Martin Ström"]
21
+ gemspec.add_dependency 'hpricot'
21
22
  end
22
23
  Jeweler::GemcutterTasks.new
23
24
  rescue LoadError
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.1
1
+ 0.3.0
@@ -0,0 +1,9 @@
1
+ AddHandler cgi-script .cgi
2
+
3
+ RewriteEngine on
4
+
5
+ # foo.atom -> foo.cgi
6
+ RewriteRule ^(.+)\.atom$ $1.cgi
7
+
8
+ # Give Apache CGI access to HTTP auth, http://www.besthostratings.com/articles/http-auth-php-cgi.html
9
+ RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Based on/stolen from http://github.com/henrik/atomica -- Thanks!
4
+
5
+ require 'rubygems'
6
+ require 'nordea'
7
+ require('builder') rescue require('active_support') # gem install builder
8
+
9
+ class NordeAtom
10
+ NAME = "NordeAtom"
11
+ VERSION = "1.0"
12
+ SCHEMA_DATE = "2009-11-02"
13
+
14
+ def initialize(pnr, pin)
15
+ @pnr, @pin = pnr, pin
16
+ end
17
+
18
+ def render
19
+ atomize(fetch)
20
+ end
21
+
22
+ protected
23
+
24
+ def fetch
25
+ transactions = nil
26
+ Nordea.new(@pnr, @pin) do |n|
27
+ transactions = n.accounts.map(&:transactions).flatten.sort_by(&:date).reverse
28
+ end
29
+ transactions
30
+ end
31
+
32
+ def atomize(items)
33
+ updated_at = (Time.parse(items.first.date.to_s) || Time.now).iso8601
34
+
35
+ xml = Builder::XmlMarkup.new(:indent => 2, :target => $stdout)
36
+ xml.instruct! :xml, :version => "1.0"
37
+
38
+ xml.feed(:xmlns => "http://www.w3.org/2005/Atom") do |feed|
39
+ feed.title "Kontohistorik för #{@pnr}"
40
+ feed.id "tag:nordea,#{SCHEMA_DATE}:#{@pnr}"
41
+ feed.link :href => 'http://www.nordea.se'
42
+ feed.updated updated_at
43
+ feed.author { |a| a.name 'Nordea' }
44
+ feed.generator NAME, :version => VERSION
45
+
46
+ items.each do |item|
47
+ item_time = Time.parse(item.date.to_s)
48
+ item_date = [%w[Sön Mån Tis Ons Tors Fre Lör][item_time.wday], item_time.strftime('%Y-%m-%d')].join(' ')
49
+ style = item.withdrawal? ? 'color: red' : 'color: green'
50
+
51
+ feed.entry do |entry|
52
+ entry.id "tag:nordea,#{SCHEMA_DATE}:#{@pnr}/#{item.account.index};" +
53
+ "#{item_time.strftime('%Y-%m-%d')};#{item.text.gsub(/\W/, '')};" +
54
+ amount = %Q{%.2f SEK} % item.amount
55
+ entry.title "#{item.text} #{amount}"
56
+ "#{item.amount};#{}".gsub(/\s+/, '')
57
+ entry.content %{<table>
58
+ <tr><th>Konto:</th> <td>#{item.account.name}</td></tr>
59
+ <tr><th>Datum:</th> <td>#{item_date}</td></tr>
60
+ <tr><th>Belopp:</th> <td style="#{style}">#{item.amount}</td></tr>
61
+ </table>}, :type => 'html'
62
+ entry.updated item_time.iso8601
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+
69
+ if __FILE__ == $0
70
+
71
+ # HTTP Basic auth based on code from http://blogs.23.nu/c0re/2005/04/antville-7409/
72
+ require 'base64'
73
+
74
+ auth = ENV.has_key?('HTTP_AUTHORIZATION') && ENV['HTTP_AUTHORIZATION'].to_s.split
75
+ if auth && auth[0] == 'Basic'
76
+ pnr, pwd = Base64.decode64(auth[1]).split(':')[0..1]
77
+ puts "Content-Type: application/atom+xml"
78
+ puts
79
+ NordeAtom.new(pnr, pwd).render
80
+ else
81
+ puts "Status: 401 Authorization Required"
82
+ puts %{WWW-Authenticate: Basic realm="#{NordeAtom::NAME} pnr/PIN"}
83
+ puts "Content-Type: text/plain"
84
+ puts
85
+ puts "Please provide personnummer and PIN as HTTP auth username/password."
86
+ end
87
+ end
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # This script will take an amount as argument (or default to 3000 SEK)
4
+ # and transfer that amount from the salary to the payments account.
5
+
6
+ require 'rubygems'
7
+ require 'nordea'
8
+
9
+ amount = (ARGV.first || 3000).to_f
10
+
11
+ Nordea.new(:keychain) do |n|
12
+ main, payments = n.accounts[/Salary/], n.accounts[/payments/i]
13
+ puts "Current balance:", main, payments
14
+ puts
15
+ print "Transfer #{amount} SEK to payments account? (yes/no) "
16
+
17
+ if STDIN.gets.chop =~ /^y/i
18
+ print "\nTransferring..."
19
+ main.withdraw(amount, 'SEK', :deposit_to => payments)
20
+ puts "Done"
21
+ puts
22
+ puts "Current balance:", main, payments
23
+ end
24
+ end
@@ -3,7 +3,8 @@ module Nordea
3
3
  def initialize(fields = {}, command_params = {}, session = nil)
4
4
  @name, @balance, @currency, @index = fields[:name], fields[:balance], fields[:currency], fields[:index]
5
5
  @command_params = command_params
6
- @session = session
6
+ @session = session if session
7
+ yield self if block_given?
7
8
  end
8
9
 
9
10
  attr_accessor :name, :balance, :currency, :index, :session
@@ -14,13 +15,21 @@ module Nordea
14
15
  @command_params
15
16
  end
16
17
 
17
- # TODO move shared transaction fetching to Nordea::Resource and call super
18
18
  def transactions(reload = false)
19
19
  @transactions = nil if reload
20
20
  @transactions ||= begin
21
- doc = session.request(Commands::TRANSACTIONS, to_command_params).parse_xml
22
- doc.search('go[@href="#trans"]').inject([]) do |all, node|
23
- all << Transaction.new_from_xml(node)
21
+ # for some reason it needs this otherwise it would use the old transaction list
22
+ session.request(Nordea::Commands::RESOURCE)
23
+
24
+ nodes = session.request(Commands::TRANSACTIONS, to_command_params).parse_xml.search('go[@href="#trans"]')
25
+ idx = nodes.length
26
+
27
+ nodes.inject([]) do |all, node|
28
+ trans = Transaction.new_from_xml(node, self)
29
+ # since transactions don't have a time (just date) but are listed in chronological order
30
+ # we add one second to each item in the collection so they can be sorted by date
31
+ trans.date = Time.parse(trans.date.to_s) + (idx -= 1)
32
+ all << trans
24
33
  end
25
34
  end
26
35
  end
@@ -33,10 +42,15 @@ module Nordea
33
42
  %Q{%.#{decimals}f} % balance
34
43
  end
35
44
 
36
- def self.new_from_xml(xml_node, session)
45
+ def reload
46
+ @transactions = nil
47
+ session.accounts(true)
48
+ end
49
+
50
+ def reload_from_xml(xml_node)
37
51
  xml_node = Hpricot(xml_node) unless xml_node.class.to_s =~ /^Hpricot::/
38
52
  xml_node = xml_node.at("anchor") unless xml_node.name == 'anchor'
39
- new _setup_fields(xml_node), _setup_command_params(xml_node), session
53
+ initialize(self.class._setup_fields(xml_node), self.class._setup_command_params(xml_node))
40
54
  end
41
55
 
42
56
  def withdraw(amount, currency = 'SEK', options = {})
@@ -68,7 +82,7 @@ module Nordea
68
82
  :to_currency_code => currency
69
83
  })
70
84
 
71
- session.accounts(true)
85
+ reload
72
86
  end
73
87
 
74
88
  def deposit(amount, currency = 'SEK', options = {})
@@ -80,8 +94,12 @@ module Nordea
80
94
  from.withdraw(amount, currency, options.merge(:deposit_to => self))
81
95
  end
82
96
 
97
+ def self.new_from_xml(xml_node, session)
98
+ new({}, {}, session) { |acc| acc.reload_from_xml(xml_node) }
99
+ end
100
+
83
101
  private
84
-
102
+
85
103
  def self._setup_fields(xml_node)
86
104
  name = xml_node.at("postfield[@name='account_name']")['value']
87
105
  currency = xml_node.at("postfield[@name='account_currency_code']")['value']
@@ -99,4 +117,4 @@ module Nordea
99
117
  end
100
118
  end
101
119
  end
102
- end
120
+ end
@@ -45,19 +45,30 @@ module Nordea
45
45
  end
46
46
 
47
47
  def accounts(reload = false)
48
- @accounts = nil if reload
49
- @accounts ||= setup_resources(Account)
48
+ if reload && @accounts
49
+ reloaded_xml_nodes = reload_resources(Account)
50
+ @accounts.each_with_index { |account, idx| account.reload_from_xml(reloaded_xml_nodes[idx]) }
51
+ else
52
+ @accounts ||= setup_resources(Account)
53
+ end
50
54
  end
51
55
 
52
56
  private
53
57
 
54
- def setup_resources(klass)
58
+ def fetch_resources(klass)
55
59
  type = klass.new.account_type_name
56
60
  doc = request(Commands::RESOURCE, "account_type_name" => type).parse_xml
57
- (doc/"go postfield[@name='OBJECT'][@value='#{Commands::TRANSACTIONS}']").
58
- inject(ResourceCollection.new) do |all, field|
59
- all << klass.new_from_xml(field.parent.parent, self)
60
- end
61
+ (doc/"go postfield[@name='OBJECT'][@value='#{Commands::TRANSACTIONS}']")
62
+ end
63
+
64
+ def reload_resources(klass)
65
+ fetch_resources(klass).map { |field| field.parent.parent }
66
+ end
67
+
68
+ def setup_resources(klass)
69
+ fetch_resources(klass).inject(ResourceCollection.new) do |all, field|
70
+ all << klass.new_from_xml(field.parent.parent, self)
71
+ end
61
72
  end
62
73
  end
63
74
  end
@@ -2,11 +2,11 @@ require 'date'
2
2
 
3
3
  module Nordea
4
4
  class Transaction
5
- def initialize(date, amount, text)
6
- @date, @amount, @text = date, amount, text
5
+ def initialize(date, amount, text, account = nil)
6
+ @date, @amount, @text, @account = date, amount, text, account
7
7
  end
8
8
 
9
- attr_accessor :date, :amount, :text
9
+ attr_accessor :date, :amount, :text, :account
10
10
 
11
11
  def withdrawal?
12
12
  amount < 0
@@ -16,12 +16,12 @@ module Nordea
16
16
  amount > 0
17
17
  end
18
18
 
19
- def self.new_from_xml(xml)
19
+ def self.new_from_xml(xml, account = nil)
20
20
  node = xml.is_a?(String) ? Hpricot.XML(xml) : xml
21
21
  date = Date.parse(node.at("setvar[@name='date']")['value'])
22
22
  amount = Support.dirty_currency_string_to_f(node.at("setvar[@name='amount']")['value'])
23
23
  text = node.at("setvar[@name='text']")['value']
24
- new date, amount, text
24
+ new(date, amount, text, account)
25
25
  end
26
26
  end
27
27
  end
@@ -1,8 +1,8 @@
1
1
  module Nordea
2
2
  module Version
3
3
  MAJOR = 0
4
- MINOR = 2
5
- TINY = 1
4
+ MINOR = 3
5
+ TINY = 0
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join(".")
8
8
  end
data/lib/nordea.rb CHANGED
@@ -40,30 +40,39 @@ module Nordea
40
40
 
41
41
  private
42
42
 
43
- # TODO clean up
44
43
  def self.extract_login_details(pnr_or_hash, pin_or_options)
45
44
  if pnr_or_hash.is_a?(Hash)
46
- pnr_or_hash.symbolize_keys!
47
- pnr = pnr_or_hash[:pnr]
48
- pin = pnr_or_hash[:pin]
45
+ pnr, pin = _login_details_from_hash(pnr_or_hash)
49
46
  elsif pnr_or_hash.is_a?(Symbol)
50
- if pnr_or_hash == :keychain
51
- options = { :label => 'Nordea' }.merge(pin_or_options.symbolize_keys)
52
- pnr, pin = account_details_from_keychain(options)
53
- end
47
+ pnr, pin = _login_details_from_symbol(pnr_or_hash, pin_or_options)
54
48
  elsif pnr_or_hash.is_a?(String) && pin_or_options.is_a?(String)
55
- pnr = pnr_or_hash
56
- pin = pin_or_options
49
+ pnr, pin = pnr_or_hash, pin_or_options
57
50
  else
58
51
  raise ArgumentError
59
52
  end
60
53
  [pnr.to_s.gsub(/\D+/, ''), pin.to_s.gsub(/\D+/, '')]
61
54
  end
62
-
63
- def Nordea.account_details_from_keychain(options)
55
+
56
+ def Nordea._login_details_from_hash(pnr_or_hash)
57
+ pnr_or_hash.symbolize_keys!
58
+ [pnr_or_hash[:pnr], pnr_or_hash[:pin]]
59
+ end
60
+
61
+ def Nordea._login_details_from_symbol(symbol, options)
62
+ if symbol == :keychain
63
+ _account_details_from_keychain({ :label => 'Nordea' }.merge(options.symbolize_keys))
64
+ else
65
+ raise ArgumentError
66
+ end
67
+ end
68
+
69
+ def Nordea._account_details_from_keychain(options)
64
70
  command = "security find-generic-password -l '#{options[:label]}' -g"
65
71
  command << " #{options[:keychain_file].inspect}" if options[:keychain_file]
66
72
  command << " 2>&1"
67
- `#{command}`.scan(/password: "(\d{4})"|"acct"<blob>="(\d{10})"/).flatten.compact.reverse
73
+ output = `#{command}`
74
+ pnr = output.match(/"acct"<blob>="(\d{10})"/)[1]
75
+ pin = output.match(/password: "(\d{4})"/)[1]
76
+ [pnr, pin]
68
77
  end
69
78
  end
data/nordea-rb.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{nordea-rb}
8
- s.version = "0.2.1"
8
+ s.version = "0.3.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Martin Str\303\266m"]
12
- s.date = %q{2009-10-24}
12
+ s.date = %q{2009-11-10}
13
13
  s.default_executable = %q{nordea}
14
14
  s.description = %q{Ruby library for accessing your Nordea Bank account and transferring money between your own accounts.}
15
15
  s.email = %q{name@my-domain.se}
@@ -25,6 +25,9 @@ Gem::Specification.new do |s|
25
25
  "Rakefile",
26
26
  "VERSION",
27
27
  "bin/nordea",
28
+ "examples/atom_feed/.htaccess",
29
+ "examples/atom_feed/nordea.cgi",
30
+ "examples/transfer-to-salary",
28
31
  "lib/nordea.rb",
29
32
  "lib/nordea/request.rb",
30
33
  "lib/nordea/resources.rb",
@@ -80,9 +83,12 @@ Gem::Specification.new do |s|
80
83
  s.specification_version = 3
81
84
 
82
85
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
86
+ s.add_runtime_dependency(%q<hpricot>, [">= 0"])
83
87
  else
88
+ s.add_dependency(%q<hpricot>, [">= 0"])
84
89
  end
85
90
  else
91
+ s.add_dependency(%q<hpricot>, [">= 0"])
86
92
  end
87
93
  end
88
94
 
data/test/test_account.rb CHANGED
@@ -6,6 +6,7 @@ class TestAccount < Test::Unit::TestCase
6
6
  @session = Nordea::Session.new('foo', 'bar')
7
7
  @account = Nordea::Account.new(:name => "savings account", :balance => 1234.50, :currency => 'EUR', :index => '2')
8
8
  @account.session = @session
9
+ @session.stubs(:request)
9
10
  end
10
11
 
11
12
  context "each Account instance" do
@@ -20,8 +21,14 @@ class TestAccount < Test::Unit::TestCase
20
21
  should "request the transactions from the server" do
21
22
  response = mock(:parse_xml => Hpricot.XML(fixture_content('account')))
22
23
  @session.expects(:request).with('KF11TW', {}).returns(response)
24
+ @session.expects(:request).with('KF00TW') # it needs this command to reset the transaction list
23
25
  @account.transactions
24
26
  end
27
+
28
+ should "reload the account object from session" do
29
+ @session.expects(:accounts).with(true)
30
+ @account.reload
31
+ end
25
32
  end
26
33
 
27
34
  context "transfers" do
@@ -72,7 +79,7 @@ class TestAccount < Test::Unit::TestCase
72
79
  end
73
80
 
74
81
  should "reload the accounts" do
75
- @session.expects(:accounts).with(true)
82
+ @account.expects(:reload)
76
83
  @savings.withdraw(6.5, "EUR", :deposit_to => @checking)
77
84
  end
78
85
  end
@@ -105,7 +112,11 @@ class TestAccount < Test::Unit::TestCase
105
112
  end
106
113
 
107
114
  should "set transaction's date" do
108
- assert_equal "2009-08-16", @transactions.first.date.to_s
115
+ assert_equal "2009-08-16", @transactions.first.date.strftime("%Y-%m-%d")
116
+ end
117
+
118
+ should "set each transaction's time increased in the same order as listed" do
119
+ assert_equal (0...20).to_a.reverse, @transactions.map { |t| t.date.sec }
109
120
  end
110
121
 
111
122
  should "set transaction's amount" do
@@ -115,6 +126,10 @@ class TestAccount < Test::Unit::TestCase
115
126
  should "set transaction's text" do
116
127
  assert_equal "Res. köp", @transactions.first.text
117
128
  end
129
+
130
+ should "set transaction's account" do
131
+ assert_equal @account, @transactions.first.account
132
+ end
118
133
  end
119
134
 
120
135
  context "creating a new Account object from XML" do
@@ -163,6 +178,12 @@ class TestAccount < Test::Unit::TestCase
163
178
  should "have an index" do
164
179
  assert_equal "1", @account.index
165
180
  end
181
+
182
+ should "reload via xml" do
183
+ xml = @xml_node.sub('2.000,00', '1.234,00')
184
+ @account.reload_from_xml(xml)
185
+ assert_equal 1234.0, @account.balance
186
+ end
166
187
  end
167
188
  end
168
189
  end
@@ -18,13 +18,6 @@ class FunctionalTest < Test::Unit::TestCase
18
18
  end
19
19
 
20
20
  should "login and display the number of accounts" do
21
- def assert_requests_made(session, num_requests = 1, msg = nil, &blk)
22
- before = session.num_requests
23
- yield
24
- after = session.num_requests
25
- assert_equal before + num_requests, after, msg
26
- end
27
-
28
21
  Nordea.new('1234567890', '0987') do |n|
29
22
 
30
23
  # logging in
@@ -39,7 +32,7 @@ class FunctionalTest < Test::Unit::TestCase
39
32
  assert_requests_made(n, 1, "reloading the accounts cache") { n.accounts(true) }
40
33
 
41
34
  # getting one of the account's transactions
42
- assert_requests_made(n, 1) do
35
+ assert_requests_made(n, 2) do
43
36
  assert_equal 5, n.accounts.first.transactions.size # we use the same ficture so all accounts have 20 transactions
44
37
  end
45
38
 
@@ -48,12 +41,12 @@ class FunctionalTest < Test::Unit::TestCase
48
41
  assert_equal 5, n.accounts['Sparkonto'].transactions.size
49
42
  end
50
43
 
51
- assert_requests_made(n, 1, "reload the cached transactions list") {
44
+ assert_requests_made(n, 2, "reload the cached transactions list") {
52
45
  n.accounts['Sparkonto'].transactions(true).size
53
46
  }
54
47
 
55
48
  # ask for the other accounts's transactions
56
- assert_requests_made(n, 2) do
49
+ assert_requests_made(n, 4) do
57
50
  assert_equal 10, n.accounts['Huvudkonto'].transactions.size
58
51
  assert_equal 20, n.accounts['Betalkonto'].transactions.size
59
52
  end
data/test/test_helper.rb CHANGED
@@ -55,4 +55,15 @@ class Test::Unit::TestCase
55
55
  end
56
56
  end
57
57
  end
58
+
59
+ def assert_requests_made(session, num_requests = 1, msg = nil, &blk)
60
+ before = session.num_requests
61
+ yield
62
+ after = session.num_requests
63
+ assert_equal before + num_requests, after, msg
64
+ end
65
+
66
+ def assert_no_requests_made(session, msg = nil, &blk)
67
+ assert_requests_made(session, 0, msg, &blk)
68
+ end
58
69
  end
data/test/test_nordea.rb CHANGED
@@ -45,5 +45,39 @@ class TestNordea < Test::Unit::TestCase
45
45
  should "raise an error if there is no pin provided" do
46
46
  assert_raise(ArgumentError) { Nordea.new("1234567890") }
47
47
  end
48
+
49
+ should "raise an error when using a symbol other than :keychain" do
50
+ assert_raise(ArgumentError) { Nordea.new(:foo) }
51
+ end
52
+
53
+ should "raise call the secutiry commando on OS X to retreive the password" do
54
+ #Nordea.expects(:`).returns(<<-EOF)
55
+ return_value = <<-EOF
56
+ keychain: "/Users/me/Library/Keychains/login.keychain"
57
+ class: "genp"
58
+ attributes:
59
+ 0x00000001 <blob>="Nordea"
60
+ 0x00000002 <blob>=<NULL>
61
+ "acct"<blob>="1234567890"
62
+ "cdat"<timedate>=0x11111111111111111111111111111111 "111111111111111\000"
63
+ "crtr"<uint32>=<NULL>
64
+ "cusi"<sint32>=<NULL>
65
+ "desc"<blob>=<NULL>
66
+ "gena"<blob>=<NULL>
67
+ "icmt"<blob>=<NULL>
68
+ "invi"<sint32>=<NULL>
69
+ "mdat"<timedate>=0x22222222222222222222222222222222 "222222222222222\000"
70
+ "nega"<sint32>=<NULL>
71
+ "prot"<blob>=<NULL>
72
+ "scrp"<sint32>=<NULL>
73
+ "svce"<blob>="Nordea"
74
+ "type"<uint32>=<NULL>
75
+ password: "1337"
76
+ EOF
77
+
78
+ Nordea.expects(:`).with(anything).returns(return_value)
79
+
80
+ Nordea.new(:keychain)
81
+ end
48
82
  end
49
83
  end
data/test/test_session.rb CHANGED
@@ -125,5 +125,34 @@ class TestSession < Test::Unit::TestCase
125
125
  should "find the account's name by pattern when using #[] with a regexp" do
126
126
  assert_equal @session.accounts[1], @session.accounts[/huvud/i]
127
127
  end
128
+
129
+ should "cache the account objects" do
130
+ @session.accounts
131
+ assert_no_requests_made(@session) do
132
+ @session.accounts
133
+ @session.accounts
134
+ end
135
+ end
136
+
137
+ should "refetch the account objects when passing true as argument" do
138
+ @session.accounts
139
+ assert_requests_made(@session, 1) { @session.accounts(true) }
140
+ end
141
+
142
+ should "not create new account objects when reloading" do
143
+ assert_equal @session.accounts, @session.accounts(true)
144
+ end
145
+
146
+ should "setup the objects first time when passing reload flag" do
147
+ assert_requests_made(@session, 1) { @session.accounts(true) }
148
+ assert_equal 3, @session.accounts.length
149
+ end
150
+
151
+ should "set new balance when reloading" do
152
+ @session.accounts # create the account objects
153
+ xml = Hpricot.XML(fixture_content('accounts').sub('179,05', '1234,56'))
154
+ Nordea::Request.stubs(:new).returns(stub(:parse_xml => xml))
155
+ assert_equal 1234.56, @session.accounts(true)[/Betal/].balance
156
+ end
128
157
  end
129
158
  end
@@ -11,6 +11,7 @@ class TestTransaction < Test::Unit::TestCase
11
11
  </go>
12
12
  </anchor>
13
13
  END
14
+ @account = stub("Account", :name => 'fake account')
14
15
  @transaction = Nordea::Transaction.new_from_xml(@xml_node)
15
16
  end
16
17
 
@@ -55,4 +56,15 @@ class TestTransaction < Test::Unit::TestCase
55
56
  assert t.deposit?
56
57
  assert !t.withdrawal?
57
58
  end
59
+
60
+ should "allow to pass an account to the contstructor" do
61
+ t = Nordea::Transaction.new('2009-01-01', 10.00, 'Salery', @account)
62
+ assert_equal @account, t.account
63
+ end
64
+
65
+ should "have a setter for the account property" do
66
+ t = Nordea::Transaction.new('2009-01-01', 10.00, 'Salery')
67
+ t.account = @account
68
+ assert_equal @account, t.account
69
+ end
58
70
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nordea-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - "Martin Str\xC3\xB6m"
@@ -9,10 +9,19 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-10-24 00:00:00 -04:00
12
+ date: 2009-11-10 00:00:00 +01:00
13
13
  default_executable: nordea
14
- dependencies: []
15
-
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: hpricot
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
16
25
  description: Ruby library for accessing your Nordea Bank account and transferring money between your own accounts.
17
26
  email: name@my-domain.se
18
27
  executables:
@@ -29,6 +38,9 @@ files:
29
38
  - Rakefile
30
39
  - VERSION
31
40
  - bin/nordea
41
+ - examples/atom_feed/.htaccess
42
+ - examples/atom_feed/nordea.cgi
43
+ - examples/transfer-to-salary
32
44
  - lib/nordea.rb
33
45
  - lib/nordea/request.rb
34
46
  - lib/nordea/resources.rb