nordea-rb 0.2.1 → 0.3.0

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/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