1
0
mirror of https://github.com/aclindsa/ofxgo.git synced 2025-07-03 12:28:38 -04:00

8 Commits

Author SHA1 Message Date
afd882f7d2 README: Add inline link to documentation 2021-10-17 21:57:26 -04:00
5ed0050aad Add tests for String/Boolean String() methods 2021-10-17 21:55:45 -04:00
09f161e13e Add tests for Payee/Balance Valid() methods 2021-10-17 21:55:45 -04:00
e1a72fcd54 Replace github.com/howeyc/gopass with golang.org/x/term
gopass is no longer maintained, and the suggested replacement for
getting passwords from terminals is x/term.
2021-10-17 21:20:04 -04:00
a4a166aa74 Update dependencies 2021-10-17 21:04:05 -04:00
3ee400d1ec Test against latest golang: 1.17 2021-10-17 20:50:10 -04:00
67fa945cc8 cmd/ofx: check for nil Currency fields in transactions 2021-10-17 15:49:08 -04:00
cb48d30deb Added Accept http header as Citi now requires it
Without this header set Citi returns http 403 for every request.
2021-09-01 09:35:45 -04:00
10 changed files with 135 additions and 26 deletions

View File

@ -6,7 +6,7 @@ jobs:
test: test:
strategy: strategy:
matrix: matrix:
go-version: [1.13.x, 1.15.x, 1.16.x] go-version: [1.13.x, 1.16.x, 1.17.x]
os: [ubuntu-latest, macos-latest, windows-latest] os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
steps: steps:

View File

@ -26,7 +26,8 @@ created a sample command-line client which uses the library to do simple tasks
(currently it does little more than list accounts and query for balances and (currently it does little more than list accounts and query for balances and
transactions). My hope is that by studying its code, new users will be able to transactions). My hope is that by studying its code, new users will be able to
figure out how to use the library much faster than staring at the OFX figure out how to use the library much faster than staring at the OFX
specification (or this library's API documentation). The command-line client specification (or this library's [API
documentation](https://pkg.go.dev/github.com/aclindsa/ofxgo)). The command-line client
also serves as an easy way for me to test/debug the library with actual also serves as an easy way for me to test/debug the library with actual
financial institutions, which frequently have 'quirks' in their implementations. financial institutions, which frequently have 'quirks' in their implementations.
The command-line client can be found in the [cmd/ofx The command-line client can be found in the [cmd/ofx

View File

@ -284,3 +284,100 @@ func TestUnmarshalBankStatementResponse(t *testing.T) {
checkResponsesEqual(t, &expected, response) checkResponsesEqual(t, &expected, response)
checkResponseRoundTrip(t, response) checkResponseRoundTrip(t, response)
} }
func TestPayeeValid(t *testing.T) {
p := Payee{
Name: "Jane",
Addr1: "Sesame Street",
City: "Mytown",
State: "AA",
PostalCode: "12345",
Phone: "12345678901",
}
valid, err := p.Valid()
if !valid {
t.Fatalf("Unexpected error from calling Valid: %s\n", err)
}
// Ensure some empty fields trigger invalid response
badp := p
badp.Name = ""
valid, err = badp.Valid()
if valid || err == nil {
t.Fatalf("Expected error from calling Valid with empty name\n")
}
badp = p
badp.Addr1 = ""
valid, err = badp.Valid()
if valid || err == nil {
t.Fatalf("Expected error from calling Valid with empty address\n")
}
badp = p
badp.City = ""
valid, err = badp.Valid()
if valid || err == nil {
t.Fatalf("Expected error from calling Valid with empty city\n")
}
badp = p
badp.State = ""
valid, err = badp.Valid()
if valid || err == nil {
t.Fatalf("Expected error from calling Valid with empty state\n")
}
badp = p
badp.PostalCode = ""
valid, err = badp.Valid()
if valid || err == nil {
t.Fatalf("Expected error from calling Valid with empty postal code\n")
}
badp = p
badp.Phone = ""
valid, err = badp.Valid()
if valid || err == nil {
t.Fatalf("Expected error from calling Valid with empty phone\n")
}
}
func TestBalanceValid(t *testing.T) {
var a Amount
a.SetFrac64(8, 1)
b := Balance{
Name: "Checking",
Desc: "Jane's Personal Checking",
BalType: BalTypeDollar,
Value: a,
}
valid, err := b.Valid()
if !valid {
t.Fatalf("Unexpected error from calling Valid: %s\n", err)
}
badb := b
badb.Name = ""
valid, err = badb.Valid()
if valid || err == nil {
t.Fatalf("Expected error from calling Valid with empty name\n")
}
badb = b
badb.Desc = ""
valid, err = badb.Valid()
if valid || err == nil {
t.Fatalf("Expected error from calling Valid with empty description\n")
}
badb = Balance{
Name: "Checking",
Desc: "Jane's Personal Checking",
Value: a,
}
valid, err = badb.Valid()
if valid || err == nil {
t.Fatalf("Expected error from calling Valid with unspecified balance type\n")
}
}

View File

@ -75,6 +75,7 @@ func (c *BasicClient) RawRequest(URL string, r io.Reader) (*http.Response, error
return nil, err return nil, err
} }
request.Header.Set("Content-Type", "application/x-ofx") request.Header.Set("Content-Type", "application/x-ofx")
request.Header.Add("Accept", "*/*, application/x-ofx")
if c.UserAgent != "" { if c.UserAgent != "" {
request.Header.Set("User-Agent", c.UserAgent) request.Header.Set("User-Agent", c.UserAgent)
} }

View File

@ -77,7 +77,7 @@ func bankTransactions() {
func printTransaction(defCurrency ofxgo.CurrSymbol, tran *ofxgo.Transaction) { func printTransaction(defCurrency ofxgo.CurrSymbol, tran *ofxgo.Transaction) {
currency := defCurrency currency := defCurrency
if ok, _ := tran.Currency.Valid(); ok { if tran.Currency != nil {
currency = tran.Currency.CurSym currency = tran.Currency.CurSym
} }

View File

@ -60,7 +60,7 @@ func ccTransactions() {
fmt.Println("Transactions:") fmt.Println("Transactions:")
for _, tran := range stmt.BankTranList.Transactions { for _, tran := range stmt.BankTranList.Transactions {
currency := stmt.CurDef currency := stmt.CurDef
if ok, _ := tran.Currency.Valid(); ok { if tran.Currency != nil {
currency = tran.Currency.CurSym currency = tran.Currency.CurSym
} }

View File

@ -3,7 +3,8 @@ package main
import ( import (
"flag" "flag"
"fmt" "fmt"
"github.com/howeyc/gopass" "golang.org/x/term"
"os"
) )
type command struct { type command struct {
@ -55,7 +56,7 @@ func checkServerFlags() bool {
if ret && len(password) == 0 { if ret && len(password) == 0 {
fmt.Printf("Password for %s: ", username) fmt.Printf("Password for %s: ", username)
pass, err := gopass.GetPasswd() pass, err := term.ReadPassword(int(os.Stdin.Fd()))
if err != nil { if err != nil {
fmt.Printf("Error reading password: %s\n", err) fmt.Printf("Error reading password: %s\n", err)
ret = false ret = false

8
go.mod
View File

@ -1,11 +1,9 @@
module github.com/aclindsa/ofxgo module github.com/aclindsa/ofxgo
require ( require (
github.com/aclindsa/xml v0.0.0-20190701095008-453d2c6090c2 github.com/aclindsa/xml v0.0.0-20201125035057-bbd5c9ec99ac
github.com/howeyc/gopass v0.0.0-20190910152052-7cb4b85ec19c golang.org/x/term v0.0.0-20210927222741-03fcf44c2211
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0 // indirect golang.org/x/text v0.3.7
golang.org/x/sys v0.0.0-20201006155630-ac719f4daadf // indirect
golang.org/x/text v0.3.3
) )
go 1.9 go 1.9

23
go.sum
View File

@ -1,16 +1,9 @@
github.com/aclindsa/xml v0.0.0-20190701095008-453d2c6090c2 h1:ICeGSGrc6fd81VtQ3nZ2h7GEOKxWYwRxjW0v0d/mgu4= github.com/aclindsa/xml v0.0.0-20201125035057-bbd5c9ec99ac h1:xCNSfPWpcx3Sdz/+aB/Re4L8oA6Y4kRRRuTh1CHCDEw=
github.com/aclindsa/xml v0.0.0-20190701095008-453d2c6090c2/go.mod h1:GjqOUT8xlg5+T19lFv6yAGNrtMKkZ839Gt4e16mBXlY= github.com/aclindsa/xml v0.0.0-20201125035057-bbd5c9ec99ac/go.mod h1:GjqOUT8xlg5+T19lFv6yAGNrtMKkZ839Gt4e16mBXlY=
github.com/howeyc/gopass v0.0.0-20190910152052-7cb4b85ec19c h1:aY2hhxLhjEAbfXOx2nRJxCXezC6CO2V/yN+OCr1srtk= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
github.com/howeyc/gopass v0.0.0-20190910152052-7cb4b85ec19c/go.mod h1:lADxMC39cJJqL93Duh1xhAs4I2Zs8mKS89XWXFGp9cs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0 h1:hb9wdF1z5waM+dSIICn1l0DkLVDT3hqhhQsDNUmHPRE= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201006155630-ac719f4daadf h1:Bg47KQy0JhTHuf4sLiQwTMKwUMfSDwgSGatrxGR7nLM=
golang.org/x/sys v0.0.0-20201006155630-ac719f4daadf/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

View File

@ -316,6 +316,13 @@ func TestUnmarshalString(t *testing.T) {
unmarshalHelper(t, "Some Name\n ", &s, &overwritten) unmarshalHelper(t, "Some Name\n ", &s, &overwritten)
} }
func TestStringString(t *testing.T) {
var s String = "foobar"
if s.String() != "foobar" {
t.Fatalf("Unexpected result when returning String.String(): %s\n", s.String())
}
}
func TestMarshalBoolean(t *testing.T) { func TestMarshalBoolean(t *testing.T) {
var b Boolean = true var b Boolean = true
marshalHelper(t, "Y", &b) marshalHelper(t, "Y", &b)
@ -333,6 +340,17 @@ func TestUnmarshalBoolean(t *testing.T) {
unmarshalHelper(t, "N\n \t", &b, &overwritten) unmarshalHelper(t, "N\n \t", &b, &overwritten)
} }
func TestStringBoolean(t *testing.T) {
var b Boolean = true
if b.String() != "true" {
t.Fatalf("Unexpected string for Boolean.String() for true: %s\n", b.String())
}
b = false
if b.String() != "false" {
t.Fatalf("Unexpected string for Boolean.String() for false: %s\n", b.String())
}
}
func TestMarshalUID(t *testing.T) { func TestMarshalUID(t *testing.T) {
var u UID = "d1cf3d3d-9ef9-4a97-b180-81706829cb04" var u UID = "d1cf3d3d-9ef9-4a97-b180-81706829cb04"
marshalHelper(t, "d1cf3d3d-9ef9-4a97-b180-81706829cb04", &u) marshalHelper(t, "d1cf3d3d-9ef9-4a97-b180-81706829cb04", &u)