ofx_br 0.3.3

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.
Files changed (49) hide show
  1. checksums.yaml +7 -0
  2. data/.github/dependabot.yml +13 -0
  3. data/.gitignore +4 -0
  4. data/.rspec +1 -0
  5. data/.travis.yml +9 -0
  6. data/Gemfile +2 -0
  7. data/Gemfile.lock +50 -0
  8. data/README.rdoc +51 -0
  9. data/Rakefile +7 -0
  10. data/lib/ofx_br/account.rb +11 -0
  11. data/lib/ofx_br/balance.rb +7 -0
  12. data/lib/ofx_br/errors.rb +3 -0
  13. data/lib/ofx_br/foundation.rb +9 -0
  14. data/lib/ofx_br/parser/ofx102.rb +201 -0
  15. data/lib/ofx_br/parser/ofx103.rb +7 -0
  16. data/lib/ofx_br/parser/ofx211.rb +40 -0
  17. data/lib/ofx_br/parser.rb +72 -0
  18. data/lib/ofx_br/sign_on.rb +8 -0
  19. data/lib/ofx_br/statement.rb +5 -0
  20. data/lib/ofx_br/status.rb +12 -0
  21. data/lib/ofx_br/transaction.rb +16 -0
  22. data/lib/ofx_br/version.rb +8 -0
  23. data/lib/ofx_br.rb +33 -0
  24. data/ofx_br.gemspec +32 -0
  25. data/spec/fixtures/avatar.gif +0 -0
  26. data/spec/fixtures/bb.ofx +700 -0
  27. data/spec/fixtures/bradesco.ofx +96 -0
  28. data/spec/fixtures/creditcard.ofx +79 -0
  29. data/spec/fixtures/dtsof_balance_issue.ofx +54 -0
  30. data/spec/fixtures/error.ofx +24 -0
  31. data/spec/fixtures/invalid_version.ofx +308 -0
  32. data/spec/fixtures/nd-amex-sample.ofx +12 -0
  33. data/spec/fixtures/sample.ofx +315 -0
  34. data/spec/fixtures/santander.ofx +91 -0
  35. data/spec/fixtures/utf8.ofx +308 -0
  36. data/spec/fixtures/v103.ofx +80 -0
  37. data/spec/fixtures/v211.ofx +85 -0
  38. data/spec/ofx_br/account_spec.rb +131 -0
  39. data/spec/ofx_br/ofx102_spec.rb +67 -0
  40. data/spec/ofx_br/ofx103_spec.rb +50 -0
  41. data/spec/ofx_br/ofx211_spec.rb +84 -0
  42. data/spec/ofx_br/ofx_parser_spec.rb +123 -0
  43. data/spec/ofx_br/ofx_spec.rb +21 -0
  44. data/spec/ofx_br/sign_on_spec.rb +27 -0
  45. data/spec/ofx_br/statement_spec.rb +131 -0
  46. data/spec/ofx_br/status_spec.rb +47 -0
  47. data/spec/ofx_br/transaction_spec.rb +201 -0
  48. data/spec/spec_helper.rb +9 -0
  49. metadata +174 -0
@@ -0,0 +1,80 @@
1
+
2
+
3
+ OFXHEADER:100
4
+ DATA:OFXSGML
5
+ VERSION:103
6
+ SECURITY:NONE
7
+ ENCODING:USASCII
8
+ CHARSET:1252
9
+ COMPRESSION:NONE
10
+ OLDFILEUID:NONE
11
+ NEWFILEUID:NONE
12
+
13
+ <OFX>
14
+ <SIGNONMSGSRSV1>
15
+ <SONRS>
16
+ <STATUS>
17
+ <CODE>0</CODE>
18
+ <SEVERITY>INFO</SEVERITY>
19
+ </STATUS>
20
+ <DTSERVER>20150507164333.979[-0300:BRT]</DTSERVER>
21
+ <LANGUAGE>POR</LANGUAGE>
22
+ <FI>
23
+ <ORG>HSBC Bank Brasil S.A.</ORG>
24
+ <FID>1</FID>
25
+ </FI>
26
+ </SONRS>
27
+ </SIGNONMSGSRSV1>
28
+ <BANKMSGSRSV1>
29
+ <STMTTRNRS>
30
+ <TRNUID>1</TRNUID>
31
+ <STATUS>
32
+ <CODE>0</CODE>
33
+ <SEVERITY>INFO</SEVERITY>
34
+ </STATUS>
35
+ <STMTRS>
36
+ <CURDEF>BRL</CURDEF>
37
+ <BANKACCTFROM>
38
+ <BANKID>399</BANKID>
39
+ <ACCTID>26215973324</ACCTID>
40
+ <ACCTTYPE>CHECKING</ACCTTYPE>
41
+ </BANKACCTFROM>
42
+ <BANKTRANLIST>
43
+ <DTSTART>20150501</DTSTART>
44
+ <DTEND>20150507</DTEND>
45
+
46
+ <STMTTRN>
47
+ <TRNTYPE>PAYMENT</TRNTYPE>
48
+ <DTPOSTED>20150504120000</DTPOSTED>
49
+ <DTUSER>20150504120000</DTUSER>
50
+ <TRNAMT>-1020.88</TRNAMT>
51
+ <FITID>201505041</FITID>
52
+ <CHECKNUM>0390003</CHECKNUM>
53
+ <NAME>PAGAMENTO TITULO-CNB </NAME>
54
+ <MEMO>PAGAMENTO TITULO-CNB </MEMO>
55
+ </STMTTRN>
56
+
57
+ <STMTTRN>
58
+ <TRNTYPE>PAYMENT</TRNTYPE>
59
+ <DTPOSTED>20150505120000</DTPOSTED>
60
+ <DTUSER>20150505120000</DTUSER>
61
+ <TRNAMT>-82.10</TRNAMT>
62
+ <FITID>201505051</FITID>
63
+ <CHECKNUM>0000000</CHECKNUM>
64
+ <NAME>TAR PACOTE MENSAL </NAME>
65
+ <MEMO>TAR PACOTE MENSAL </MEMO>
66
+ </STMTTRN>
67
+
68
+ </BANKTRANLIST>
69
+ <LEDGERBAL>
70
+ <BALAMT>3806.63</BALAMT>
71
+ <DTASOF>20150507164333.980[-0300:BRT]</DTASOF>
72
+ </LEDGERBAL>
73
+ <AVAILBAL>
74
+ <BALAMT>3806.63</BALAMT>
75
+ <DTASOF>20150507164333.980[-0300:BRT]</DTASOF>
76
+ </AVAILBAL>
77
+ </STMTRS>
78
+ </STMTTRNRS>
79
+ </BANKMSGSRSV1>
80
+ </OFX>
@@ -0,0 +1,85 @@
1
+ <?xml version="1.0" encoding="US-ASCII"?>
2
+
3
+ <!-- This example is taken from the 2.1.1 specification, pages 610-612 -->
4
+ <?OFX OFXHEADER="200" VERSION="211" SECURITY="NONE" OLDFILEUID="NONE" NEWFILEUID="NONE"?>
5
+ <OFX>
6
+ <SIGNONMSGSRSV1>
7
+ <SONRS>
8
+ <STATUS>
9
+ <CODE>0</CODE>
10
+ <SEVERITY>INFO</SEVERITY>
11
+ </STATUS>
12
+ <DTSERVER>20050831165153.000[-8:PST]</DTSERVER>
13
+ <LANGUAGE>ENG</LANGUAGE>
14
+ </SONRS>
15
+ </SIGNONMSGSRSV1>
16
+ <BANKMSGSRSV1>
17
+ <STMTTRNRS>
18
+ <TRNUID>0</TRNUID>
19
+ <STATUS>
20
+ <CODE>0</CODE>
21
+ <SEVERITY>INFO</SEVERITY>
22
+ </STATUS>
23
+ <STMTRS>
24
+ <CURDEF>USD</CURDEF>
25
+ <BANKACCTFROM>
26
+ <BANKID>000000123</BANKID>
27
+ <ACCTID>123456</ACCTID>
28
+ <ACCTTYPE>CHECKING</ACCTTYPE>
29
+ </BANKACCTFROM>
30
+ <BANKTRANLIST>
31
+ <DTSTART>20040801</DTSTART>
32
+ <DTEND>20050831165153.000[-8:PST]</DTEND>
33
+ <STMTTRN>
34
+ <TRNTYPE>POS</TRNTYPE>
35
+ <DTPOSTED>20050824080000</DTPOSTED>
36
+ <TRNAMT>-80</TRNAMT>
37
+ <FITID>219378</FITID>
38
+ <NAME>FrogKick Scuba Gear</NAME>
39
+ </STMTTRN>
40
+ </BANKTRANLIST>
41
+ <LEDGERBAL>
42
+ <BALAMT>2156.56</BALAMT>
43
+ <DTASOF>20050831165153</DTASOF>
44
+ </LEDGERBAL>
45
+ </STMTRS>
46
+ </STMTTRNRS>
47
+ </BANKMSGSRSV1>
48
+ <CREDITCARDMSGSRSV1>
49
+ <CCSTMTTRNRS>
50
+ <TRNUID>0</TRNUID>
51
+ <STATUS>
52
+ <CODE>0</CODE>
53
+ <SEVERITY>INFO</SEVERITY>
54
+ </STATUS>
55
+ <CCSTMTRS>
56
+ <CURDEF>USD</CURDEF>
57
+ <CCACCTFROM>
58
+ <ACCTID>123412341234</ACCTID>
59
+ </CCACCTFROM>
60
+ <BANKTRANLIST>
61
+ <DTSTART>20050801</DTSTART>
62
+ <DTEND>20050831165153.000[-8:PST]</DTEND>
63
+ <STMTTRN>
64
+ <TRNTYPE>INT</TRNTYPE>
65
+ <DTPOSTED>20050811080000</DTPOSTED>
66
+ <TRNAMT>-23.00</TRNAMT>
67
+ <FITID>219867</FITID>
68
+ <NAME>Interest Charge</NAME>
69
+ </STMTTRN>
70
+ <STMTTRN>
71
+ <TRNTYPE>CREDIT</TRNTYPE>
72
+ <DTPOSTED>20050811080000</DTPOSTED>
73
+ <TRNAMT>350.00</TRNAMT>
74
+ <FITID>219868</FITID>
75
+ <NAME>Payment - Thank You</NAME>
76
+ </STMTTRN>
77
+ </BANKTRANLIST>
78
+ <LEDGERBAL>
79
+ <BALAMT>-562.00</BALAMT>
80
+ <DTASOF>20050831165153</DTASOF>
81
+ </LEDGERBAL>
82
+ </CCSTMTRS>
83
+ </CCSTMTTRNRS>
84
+ </CREDITCARDMSGSRSV1>
85
+ </OFX>
@@ -0,0 +1,131 @@
1
+ require "spec_helper"
2
+
3
+ describe OFX::Account do
4
+ before do
5
+ @ofx = OFX::Parser::Base.new("spec/fixtures/sample.ofx")
6
+ @parser = @ofx.parser
7
+ @account = @parser.account
8
+ end
9
+
10
+ describe "account" do
11
+ it "should return currency" do
12
+ @account.currency.should == "BRL"
13
+ end
14
+
15
+ it "should return bank id" do
16
+ @account.bank_id.should == "0356"
17
+ end
18
+
19
+ it "should return id" do
20
+ @account.id.should == "03227113109"
21
+ end
22
+
23
+ it "should return type" do
24
+ @account.type.should == :checking
25
+ end
26
+
27
+ it "should return transactions" do
28
+ @account.transactions.should be_a_kind_of(Array)
29
+ @account.transactions.size.should == 36
30
+ end
31
+
32
+ it "should return balance" do
33
+ @account.balance.amount.should == BigDecimal('598.44')
34
+ end
35
+
36
+ it "should return balance in pennies" do
37
+ @account.balance.amount_in_pennies.should == 59844
38
+ end
39
+
40
+ it "should return balance date" do
41
+ @account.balance.posted_at.should == Time.gm(2009,11,1)
42
+ end
43
+
44
+ context "available_balance" do
45
+ it "should return available balance" do
46
+ @account.available_balance.amount.should == BigDecimal('1555.99')
47
+ end
48
+
49
+ it "should return available balance in pennies" do
50
+ @account.available_balance.amount_in_pennies.should == 155599
51
+ end
52
+
53
+ it "should return available balance date" do
54
+ @account.available_balance.posted_at.should == Time.gm(2009,11,1)
55
+ end
56
+
57
+ it "should return nil if AVAILBAL not found" do
58
+ @ofx = OFX::Parser::Base.new("spec/fixtures/utf8.ofx")
59
+ @parser = @ofx.parser
60
+ @account = @parser.account
61
+ @account.available_balance.should be_nil
62
+ end
63
+ end
64
+
65
+ context "Credit Card" do
66
+ before do
67
+ @ofx = OFX::Parser::Base.new("spec/fixtures/creditcard.ofx")
68
+ @parser = @ofx.parser
69
+ @account = @parser.account
70
+ end
71
+
72
+ it "should return id" do
73
+ @account.id.should == "XXXXXXXXXXXX1111"
74
+ end
75
+
76
+ it "should return currency" do
77
+ @account.currency.should == "USD"
78
+ end
79
+ end
80
+ context "With Issue" do # Bradesco do not provide a valid date in balance
81
+ before do
82
+ @ofx = OFX::Parser::Base.new("spec/fixtures/dtsof_balance_issue.ofx")
83
+ @parser = @ofx.parser
84
+ @account = @parser.account
85
+ end
86
+
87
+ it "should return nil for date balance" do
88
+ @account.balance.posted_at.should be_nil
89
+ end
90
+ end
91
+
92
+ context "Invalid Dates" do
93
+ before do
94
+ @ofx = OFX::Parser::Base.new("spec/fixtures/bradesco.ofx")
95
+ @parser = @ofx.parser
96
+ end
97
+ it "should not raise error when balance has date zero" do
98
+ expect { @parser.account.balance }.to_not raise_error
99
+ end
100
+ it "should return NIL in balance.posted_at when balance date is zero" do
101
+ @parser.account.balance.posted_at.should be_nil
102
+ end
103
+ end
104
+
105
+ context "decimal values using a comma" do
106
+ before do
107
+ @ofx = OFX::Parser::Base.new("spec/fixtures/santander.ofx")
108
+ @parser = @ofx.parser
109
+ @account = @parser.account
110
+ end
111
+
112
+ it "should return balance" do
113
+ @account.balance.amount.should == BigDecimal('348.29')
114
+ end
115
+
116
+ it "should return balance in pennies" do
117
+ @account.balance.amount_in_pennies.should == 34829
118
+ end
119
+
120
+ context "available_balance" do
121
+ it "should return available balance" do
122
+ @account.available_balance.amount.should == BigDecimal('2415.87')
123
+ end
124
+
125
+ it "should return available balance in pennies" do
126
+ @account.available_balance.amount_in_pennies.should == 241587
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,67 @@
1
+ require "spec_helper"
2
+
3
+ describe OFX::Parser::OFX102 do
4
+ before do
5
+ @ofx = OFX::Parser::Base.new("spec/fixtures/sample.ofx")
6
+ @parser = @ofx.parser
7
+ end
8
+
9
+ it "should have a version" do
10
+ OFX::Parser::OFX102::VERSION.should == "1.0.2"
11
+ end
12
+
13
+ it "should set headers" do
14
+ @parser.headers.should == @ofx.headers
15
+ end
16
+
17
+ it "should trim trailing whitespace from headers" do
18
+ headers = OFX::Parser::OFX102.parse_headers("VERSION:102 ")
19
+ headers["VERSION"].should == "102"
20
+ end
21
+
22
+ it "should set body" do
23
+ @parser.body.should == @ofx.body
24
+ end
25
+
26
+ it "should set account" do
27
+ @parser.account.should be_a_kind_of(OFX::Account)
28
+ end
29
+
30
+ it "should set account" do
31
+ @parser.sign_on.should be_a_kind_of(OFX::SignOn)
32
+ end
33
+
34
+ it "should set statements" do
35
+ @parser.statements.size.should == 1
36
+ @parser.statements.first.should be_a_kind_of(OFX::Statement)
37
+ end
38
+
39
+ it "should know about all transaction types" do
40
+ valid_types = [
41
+ 'CREDIT', 'DEBIT', 'INT', 'DIV', 'FEE', 'SRVCHG', 'DEP', 'ATM', 'POS', 'XFER',
42
+ 'CHECK', 'PAYMENT', 'CASH', 'DIRECTDEP', 'DIRECTDEBIT', 'REPEATPMT', 'OTHER'
43
+ ]
44
+ valid_types.sort.should == OFX::Parser::OFX102::TRANSACTION_TYPES.keys.sort
45
+
46
+ valid_types.each do |transaction_type|
47
+ transaction_type.downcase.to_sym.should equal OFX::Parser::OFX102::TRANSACTION_TYPES[transaction_type]
48
+ end
49
+ end
50
+
51
+ describe "#build_date" do
52
+ context "without a Time Zone" do
53
+ it "should default to GMT" do
54
+ @parser.send(:build_date, "20170904").should == Time.gm(2017, 9, 4)
55
+ @parser.send(:build_date, "20170904082855").should == Time.gm(2017, 9, 4, 8, 28, 55)
56
+ end
57
+ end
58
+
59
+ context "with a Time Zone" do
60
+ it "should returns the correct date" do
61
+ @parser.send(:build_date, "20150507164333[-0300:BRT]").should == Time.new(2015, 5, 7, 16, 43, 33, "-03:00")
62
+ @parser.send(:build_date, "20180507120000[0:GMT]").should == Time.gm(2018, 5, 7, 12)
63
+ @parser.send(:build_date, "20170904082855[-3:GMT]").should == Time.new(2017, 9, 4, 8, 28, 55, "-03:00")
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,50 @@
1
+ require "spec_helper"
2
+
3
+ describe OFX::Parser::OFX103 do
4
+ before do
5
+ @ofx = OFX::Parser::Base.new("spec/fixtures/v103.ofx")
6
+ @parser = @ofx.parser
7
+ end
8
+
9
+ it "should have a version" do
10
+ OFX::Parser::OFX103::VERSION.should == "1.0.3"
11
+ end
12
+
13
+ it "should set headers" do
14
+ @parser.headers.should == @ofx.headers
15
+ end
16
+
17
+ it "should trim trailing whitespace from headers" do
18
+ headers = OFX::Parser::OFX103.parse_headers("VERSION:103 ")
19
+ headers["VERSION"].should == "103"
20
+ end
21
+
22
+ it "should set body" do
23
+ @parser.body.should == @ofx.body
24
+ end
25
+
26
+ it "should set account" do
27
+ @parser.account.should be_a_kind_of(OFX::Account)
28
+ end
29
+
30
+ it "should set account" do
31
+ @parser.sign_on.should be_a_kind_of(OFX::SignOn)
32
+ end
33
+
34
+ it "should set statements" do
35
+ @parser.statements.size.should == 1
36
+ @parser.statements.first.should be_a_kind_of(OFX::Statement)
37
+ end
38
+
39
+ it "should know about all transaction types" do
40
+ valid_types = [
41
+ 'CREDIT', 'DEBIT', 'INT', 'DIV', 'FEE', 'SRVCHG', 'DEP', 'ATM', 'POS', 'XFER',
42
+ 'CHECK', 'PAYMENT', 'CASH', 'DIRECTDEP', 'DIRECTDEBIT', 'REPEATPMT', 'OTHER'
43
+ ]
44
+ valid_types.sort.should == OFX::Parser::OFX103::TRANSACTION_TYPES.keys.sort
45
+
46
+ valid_types.each do |transaction_type|
47
+ transaction_type.downcase.to_sym.should equal OFX::Parser::OFX103::TRANSACTION_TYPES[transaction_type]
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,84 @@
1
+ require "spec_helper"
2
+
3
+ describe OFX::Parser::OFX211 do
4
+ before do
5
+ @ofx = OFX::Parser::Base.new("spec/fixtures/v211.ofx")
6
+ @parser = @ofx.parser
7
+ end
8
+
9
+ it "should have a version" do
10
+ OFX::Parser::OFX211::VERSION.should == "2.1.1"
11
+ end
12
+
13
+ it "should set headers" do
14
+ @parser.headers.should == @ofx.headers
15
+ end
16
+
17
+ it "should set body" do
18
+ @parser.body.should == @ofx.body
19
+ end
20
+
21
+ it "should set account" do
22
+ @parser.account.should be_a_kind_of(OFX::Account)
23
+ end
24
+
25
+ it "should set account" do
26
+ @parser.sign_on.should be_a_kind_of(OFX::SignOn)
27
+ end
28
+
29
+ it "should set accounts" do
30
+ @parser.accounts.size.should == 2
31
+ end
32
+
33
+ it "should set statements" do
34
+ @parser.statements.size.should == 2
35
+ @parser.statements.first.should be_a_kind_of(OFX::Statement)
36
+ end
37
+
38
+ context "transactions" do
39
+ # Test file contains only three transactions. Let's just check
40
+ # them all.
41
+ context "first" do
42
+ before do
43
+ @t = @parser.accounts[0].transactions[0]
44
+ end
45
+
46
+ it "should contain the correct values" do
47
+ @t.amount.should == BigDecimal('-80')
48
+ @t.fit_id.should == "219378"
49
+ @t.memo.should be_empty
50
+ @t.posted_at.should == Time.parse("2005-08-24 08:00:00 +0000")
51
+ @t.name.should == "FrogKick Scuba Gear"
52
+ end
53
+ end
54
+
55
+ context "second" do
56
+ before do
57
+ @t = @parser.accounts[1].transactions[0]
58
+ end
59
+
60
+ it "should contain the correct values" do
61
+ @t.amount.should == BigDecimal('-23')
62
+ @t.fit_id.should == "219867"
63
+ @t.memo.should be_empty
64
+ @t.posted_at.should == Time.parse("2005-08-11 08:00:00 +0000")
65
+ @t.name.should == "Interest Charge"
66
+ end
67
+ end
68
+
69
+ context "third" do
70
+ before do
71
+ @t = @parser.accounts[1].transactions[1]
72
+ end
73
+
74
+ it "should contain the correct values" do
75
+ @t.amount.should == BigDecimal('350')
76
+ @t.fit_id.should == "219868"
77
+ @t.memo.should be_empty
78
+ @t.posted_at.should == Time.parse("2005-08-11 08:00:00 +0000")
79
+ @t.name.should == "Payment - Thank You"
80
+ end
81
+ end
82
+ end
83
+ end
84
+
@@ -0,0 +1,123 @@
1
+ require "spec_helper"
2
+
3
+ describe OFX::Parser do
4
+ before do
5
+ @ofx = OFX::Parser::Base.new("spec/fixtures/sample.ofx")
6
+ end
7
+
8
+ it "should accept file path" do
9
+ @ofx = OFX::Parser::Base.new("spec/fixtures/sample.ofx")
10
+ @ofx.content.should_not be_nil
11
+ end
12
+
13
+ it "should accept file handler" do
14
+ file = open("spec/fixtures/sample.ofx")
15
+ @ofx = OFX::Parser::Base.new(file)
16
+ @ofx.content.should_not be_nil
17
+ end
18
+
19
+ it "should accept file content" do
20
+ file = open("spec/fixtures/sample.ofx").read
21
+ @ofx = OFX::Parser::Base.new(file)
22
+ @ofx.content.should_not be_nil
23
+ end
24
+
25
+ it "should set content" do
26
+ @ofx.content.should == open("spec/fixtures/sample.ofx").read
27
+ end
28
+
29
+ it "should work with UTF8 and Latin1 encodings" do
30
+ @ofx = OFX::Parser::Base.new("spec/fixtures/utf8.ofx")
31
+ @ofx.content.should == open("spec/fixtures/utf8.ofx").read
32
+ end
33
+
34
+ it "should set body" do
35
+ @ofx.body.should_not be_nil
36
+ end
37
+
38
+ it "should raise exception when trying to parse an unsupported OFX version" do
39
+ lambda {
40
+ OFX::Parser::Base.new("spec/fixtures/invalid_version.ofx")
41
+ }.should raise_error(OFX::UnsupportedFileError)
42
+ end
43
+
44
+ it "should raise exception when trying to parse an invalid file" do
45
+ lambda {
46
+ OFX::Parser::Base.new("spec/fixtures/avatar.gif")
47
+ }.should raise_error(OFX::UnsupportedFileError)
48
+ end
49
+
50
+ it "should use 211 parser to parse version 200 ofx files" do
51
+ OFX::Parser::OFX211.stub(:new).and_return('ofx-211-parser')
52
+ ofx = OFX::Parser::Base.new(ofx_2_example('200'))
53
+ ofx.parser.should == 'ofx-211-parser'
54
+ end
55
+
56
+ it "should use 211 parser to parse version 202 ofx files" do
57
+ OFX::Parser::OFX211.stub(:new).and_return('ofx-211-parser')
58
+ ofx = OFX::Parser::Base.new(ofx_2_example('202'))
59
+ ofx.parser.should == 'ofx-211-parser'
60
+ end
61
+
62
+ describe "headers" do
63
+ it "should have OFXHEADER" do
64
+ @ofx.headers["OFXHEADER"].should == "100"
65
+ end
66
+
67
+ it "should have DATA" do
68
+ @ofx.headers["DATA"].should == "OFXSGML"
69
+ end
70
+
71
+ it "should have VERSION" do
72
+ @ofx.headers["VERSION"].should == "102"
73
+ end
74
+
75
+ it "should have SECURITY" do
76
+ @ofx.headers.should have_key("SECURITY")
77
+ @ofx.headers["SECURITY"].should be_nil
78
+ end
79
+
80
+ it "should have ENCODING" do
81
+ @ofx.headers["ENCODING"].should == "USASCII"
82
+ end
83
+
84
+ it "should have CHARSET" do
85
+ @ofx.headers["CHARSET"].should == "1252"
86
+ end
87
+
88
+ it "should have COMPRESSION" do
89
+ @ofx.headers.should have_key("COMPRESSION")
90
+ @ofx.headers["COMPRESSION"].should be_nil
91
+ end
92
+
93
+ it "should have OLDFILEUID" do
94
+ @ofx.headers.should have_key("OLDFILEUID")
95
+ @ofx.headers["OLDFILEUID"].should be_nil
96
+ end
97
+
98
+ it "should have NEWFILEUID" do
99
+ @ofx.headers.should have_key("NEWFILEUID")
100
+ @ofx.headers["NEWFILEUID"].should be_nil
101
+ end
102
+
103
+ it "should parse headers with CR and without LF" do
104
+ @ofx = OFX::Parser::Base.new(ofx_with_carriage_return)
105
+ @ofx.headers.size.should be(9)
106
+ end
107
+ end
108
+
109
+ def ofx_with_carriage_return
110
+ header = %{OFXHEADER:100\rDATA:OFXSGML\rVERSION:102\rSECURITY:NONE\rENCODING:USASCII\rCHARSET:1252\rCOMPRESSION:NONE\rOLDFILEUID:NONE\rNEWFILEUID:NONE\r}
111
+ body = open("spec/fixtures/sample.ofx").read.split(/<OFX>/, 2)[1]
112
+ header + "<OFX>" + body
113
+ end
114
+
115
+ def ofx_2_example(version)
116
+ <<-EndOfx
117
+ <?xml version="1.0" encoding="US-ASCII"?>
118
+ <?OFX OFXHEADER="200" VERSION="#{version}" SECURITY="NONE" OLDFILEUID="NONE" NEWFILEUID="NONE"?>"
119
+ <OFX>
120
+ </OFX>
121
+ EndOfx
122
+ end
123
+ end
@@ -0,0 +1,21 @@
1
+ require "spec_helper"
2
+
3
+ describe OFX do
4
+ describe "#OFX" do
5
+ it "should yield an OFX instance" do
6
+ OFX("spec/fixtures/sample.ofx") do |ofx|
7
+ ofx.class.should == OFX::Parser::OFX102
8
+ end
9
+ end
10
+
11
+ it "should be an OFX instance" do
12
+ OFX("spec/fixtures/sample.ofx") do
13
+ self.class.should == OFX::Parser::OFX102
14
+ end
15
+ end
16
+
17
+ it "should return parser" do
18
+ OFX("spec/fixtures/sample.ofx").class.should == OFX::Parser::OFX102
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,27 @@
1
+ require "spec_helper"
2
+
3
+ describe OFX::SignOn do
4
+ before do
5
+ @ofx = OFX::Parser::Base.new("spec/fixtures/creditcard.ofx")
6
+ @parser = @ofx.parser
7
+ @sign_on = @parser.sign_on
8
+ end
9
+
10
+ describe "sign_on" do
11
+ it "should return language" do
12
+ @sign_on.language.should == "ENG"
13
+ end
14
+
15
+ it "should return Financial Institution ID" do
16
+ @sign_on.fi_id.should == "24909"
17
+ end
18
+
19
+ it "should return Financial Institution Name" do
20
+ @sign_on.fi_name.should == "Citigroup"
21
+ end
22
+
23
+ it "should return status" do
24
+ @sign_on.status.should be_a(OFX::Status)
25
+ end
26
+ end
27
+ end