mirror of
				https://github.com/aclindsa/ofxgo.git
				synced 2025-11-03 18:03:25 -05:00 
			
		
		
		
	Compare commits
	
		
			8 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| afd882f7d2 | |||
| 5ed0050aad | |||
| 09f161e13e | |||
| e1a72fcd54 | |||
| a4a166aa74 | |||
| 3ee400d1ec | |||
| 
						 | 
					67fa945cc8 | ||
| 
						 | 
					cb48d30deb | 
							
								
								
									
										2
									
								
								.github/workflows/test.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/test.yml
									
									
									
									
										vendored
									
									
								
							@@ -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:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										97
									
								
								bank_test.go
									
									
									
									
									
								
							
							
						
						
									
										97
									
								
								bank_test.go
									
									
									
									
									
								
							@@ -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")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								go.mod
									
									
									
									
									
								
							@@ -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
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								go.sum
									
									
									
									
									
								
							@@ -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=
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user