package main import ( "bytes" "io/ioutil" "net/mail" "os" "testing" ) func TestScrapeAmex(t *testing.T) { b, _ := os.ReadFile("testdata/amex.txt") message := &mail.Message{ Header: map[string][]string{ "Subject": []string{"Large Purchase Approved"}, }, Body: bytes.NewReader(b), } amex := &amexScraper{} gots, err := amex.scrape(message) if err != nil { t.Fatal(err) } if len(gots) != 1 { t.Fatal(gots) } got := gots[0] if got.Account != "AmericanExpress-2003" { t.Fatalf("bad account: %v: %+v", got.Account, got) } if got.Amount != "-30.00" { t.Fatalf("bad amount: %v: %+v", got.Amount, got) } if got.Vendor != "CRAWFORD LEISHMAN DENTAL" { t.Fatalf("bad vendor: %v: %+v", got.Vendor, got) } t.Logf("%+v", got) } func TestScrapeUCCUBalance(t *testing.T) { b, _ := os.ReadFile("testdata/uccu.balance.txt") message := &mail.Message{ Header: map[string][]string{ "Subject": []string{"UCCU Account Alert Notification"}, }, } uccu := &uccuScraper{} gots, err := uccu.scrapeBalance(message, b) if err != nil { t.Fatal(err) } if len(gots) != 1 { t.Fatal(gots) } got := gots[0] if got.Account != "UCCU-33350" { t.Fatalf("bad account: %v: %+v", got.Account, got) } if got.Amount != "=231.20" { t.Fatalf("bad amount: %v: %+v", got.Amount, got) } if got.Vendor != "*" { t.Fatalf("bad vendor: %v: %+v", got.Vendor, got) } t.Logf("%+v", got) } func TestScrapeFidelityBalance(t *testing.T) { b, _ := os.ReadFile("testdata/fidelity.balance.txt") message := &mail.Message{ Header: map[string][]string{ "Subject": []string{"Fidelity Alerts: Daily Balance"}, }, Body: bytes.NewReader(b), } fidelity := &fidelityScraper{} gots, err := fidelity.scrapeBalance(message) if err != nil { t.Fatal(err) } if len(gots) != 1 { t.Fatal(gots) } got := gots[0] if got.Account != "Fidelity-5576" { t.Fatalf("bad account: %v: %+v", got.Account, got) } if got.Amount != "=5525.52" { t.Fatalf("bad amount: %v: %+v", got.Amount, got) } if got.Vendor != "*" { t.Fatalf("bad vendor: %v: %+v", got.Vendor, got) } t.Logf("%+v", got) } func TestScrapeChase2025Balance(t *testing.T) { b, _ := os.ReadFile("testdata/chase.2025.balance.txt") message := &mail.Message{ Header: map[string][]string{ "Subject": []string{"Your Chase Freedom Unlimited balance is $1,029.08"}, }, Body: bytes.NewReader(b), } chase := &chaseScraper{} gots, err := chase.scrape2025Balance(message) if err != nil { t.Fatal(err) } if len(gots) != 1 { t.Fatal(gots) } got := gots[0] if got.Account != "5876" { t.Fatalf("bad account: %v: %+v", got.Account, got) } if got.Amount != "=1029.08" { t.Fatalf("bad amount: %v: %+v", got.Amount, got) } if got.Vendor != "*" { t.Fatalf("bad vendor: %v: %+v", got.Vendor, got) } t.Logf("%+v", got) } func TestScrapeChase202112Payment(t *testing.T) { b, err := ioutil.ReadFile("./testdata/chase.2021.12.payment.txt") if err != nil { t.Fatal(err) } message := &mail.Message{ Header: map[string][]string{ "Subject": []string{"We've received your Chase Freedom Unlimited payment"}, }, Body: bytes.NewReader(b), } chase := &chaseScraper{} gots, err := chase.scrape2021(message) if err != nil { t.Fatal(err) } if len(gots) != 1 { t.Fatal(gots) } got := gots[0] if got.Account != "1049" { t.Fatalf("bad account: %v: %+v", got.Account, got) } if got.Amount != "1750.00" { t.Fatalf("bad amount: %v: %+v", got.Amount, got) } if got.Vendor != "Payment" { t.Fatalf("bad vendor: %v: %+v", got.Vendor, got) } t.Logf("%+v", got) } func TestScrapeChase2021Payment(t *testing.T) { b, err := ioutil.ReadFile("./testdata/chase.2021.payment.txt") if err != nil { t.Fatal(err) } message := &mail.Message{ Header: map[string][]string{ "Subject": []string{"We've received your AARP from Chase payment"}, }, Body: bytes.NewReader(b), } chase := &chaseScraper{} gots, err := chase.scrape2021(message) if err != nil { t.Fatal(err) } if len(gots) != 1 { t.Fatal(gots) } got := gots[0] if got.Account != "8824" { t.Fatalf("bad account: %v: %+v", got.Account, got) } if got.Amount != "100.00" { t.Fatalf("bad amount: %v: %+v", got.Amount, got) } if got.Vendor != "Payment" { t.Fatalf("bad vendor: %v: %+v", got.Vendor, got) } t.Logf("%+v", got) } func TestScrapeChase202506Credit(t *testing.T) { b, err := ioutil.ReadFile("./testdata/chase.202506.credit.txt") if err != nil { t.Fatal(err) } message := &mail.Message{ Header: map[string][]string{ "Subject": []string{"You have a $394.96 credit pending on your credit card"}, }, Body: bytes.NewReader(b), } chase := &chaseScraper{} gots, err := chase.scrape202506(message) if err != nil { t.Fatal(err) } if len(gots) != 1 { t.Fatal(gots) } got := gots[0] if got.Account != "5876" { t.Fatalf("bad account: %v: %+v", got.Account, got) } if got.Amount != "394.96" { t.Fatalf("bad amount: %v: %+v", got.Amount, got) } if got.Vendor != "*" { t.Fatalf("bad vendor: %v: %+v", got.Vendor, got) } t.Logf("%+v", got) } func TestScrapeChase202506(t *testing.T) { b, err := ioutil.ReadFile("./testdata/chase.202506.txt") if err != nil { t.Fatal(err) } message := &mail.Message{ Header: map[string][]string{ "Subject": []string{"You made a $3.42 transaction with Nintendo CB141137080"}, }, Body: bytes.NewReader(b), } chase := &chaseScraper{} gots, err := chase.scrape202506(message) if err != nil { t.Fatal(err) } if len(gots) != 1 { t.Fatal(gots) } got := gots[0] if got.Account != "5876" { t.Fatalf("bad account: %v: %+v", got.Account, got) } if got.Amount != "3.42" { t.Fatalf("bad amount: %v: %+v", got.Amount, got) } if got.Vendor != "Nintendo CB141137080" { t.Fatalf("bad vendor: %v: %+v", got.Vendor, got) } t.Logf("%+v", got) } func TestScrapeChase202506Online(t *testing.T) { b, err := ioutil.ReadFile("./testdata/chase.202506.online.txt") if err != nil { t.Fatal(err) } message := &mail.Message{ Header: map[string][]string{ "Subject": []string{"You made an online, phone, or mail transaction with DD *KLUCKSKRISPYCHIC"}, }, Body: bytes.NewReader(b), } chase := &chaseScraper{} gots, err := chase.scrape202506(message) if err != nil { t.Fatal(err) } if len(gots) != 1 { t.Fatal(gots) } got := gots[0] if got.Account != "5876" { t.Fatalf("bad account: %v: %+v", got.Account, got) } if got.Amount != "18.17" { t.Fatalf("bad amount: %v: %+v", got.Amount, got) } if got.Vendor != "DD *KLUCKSKRISPYCHIC" { t.Fatalf("bad vendor: %v: %+v", got.Vendor, got) } t.Logf("%+v", got) } func TestScrapeChase2021(t *testing.T) { b, err := ioutil.ReadFile("./testdata/chase.2021.txt") if err != nil { t.Fatal(err) } message := &mail.Message{ Header: map[string][]string{ "Subject": []string{"Your $38.84 transaction with TARGET T-1754"}, }, Body: bytes.NewReader(b), } chase := &chaseScraper{} gots, err := chase.scrape2021(message) if err != nil { t.Fatal(err) } if len(gots) != 1 { t.Fatal(gots) } got := gots[0] if got.Account != "8824" { t.Fatalf("bad account: %v: %+v", got.Account, got) } if got.Amount != "38.84" { t.Fatalf("bad amount: %v: %+v", got.Amount, got) } if got.Vendor != "TARGET T-1754" { t.Fatalf("bad vendor: %v: %+v", got.Vendor, got) } t.Logf("%+v", got) } func TestScrapeChase2020(t *testing.T) { b, err := ioutil.ReadFile("./testdata/chase.2020.txt") if err != nil { t.Fatal(err) } message := &mail.Message{ Body: bytes.NewReader(b), } chase := &chaseScraper{} gots, err := chase.scrape2020(message) if err != nil { t.Fatal(err) } if len(gots) != 1 { t.Fatal(gots) } got := gots[0] if got.Account != "8824" { t.Fatalf("bad account: %v: %+v", got.Account, got) } if got.Amount != "16.08" { t.Fatalf("bad amount: %v: %+v", got.Amount, got) } if got.Vendor != "PAYPAL *BLIZZARDENT" { t.Fatalf("bad vendor: %q: %+v", got.Vendor, got) } t.Logf("%+v", got) } func TestScrapeBofAPayment(t *testing.T) { b, err := ioutil.ReadFile("./testdata/bofa.payment.txt") if err != nil { t.Fatal(err) } message := &mail.Message{ Header: map[string][]string{ "Subject": []string{"Confirmation: Thanks for Your Credit Card Payment"}, }, Body: bytes.NewReader(b), } bofa := &bankOfAmericaScraper{} gots, err := bofa.scrape(message) if err != nil { t.Fatal(err) } if len(gots) != 1 { t.Fatal(len(gots)) } got := gots[0] want := Transaction{ ID: got.ID, Bank: BankOfAmerica, Amount: "-251.74", Vendor: "Payment", Date: "[]", Account: BankOfAmerica.String(), } if *got != want { t.Fatalf("want:\n\t%+v, got\n\t%+v", want, *got) } } func TestScrapeFidelityDeposit(t *testing.T) { b, err := ioutil.ReadFile("./testdata/fidelity.deposit.txt") if err != nil { t.Fatal(err) } message := &mail.Message{ Header: map[string][]string{ "Subject": []string{"Fidelity Alerts: Deposit Received"}, }, Body: bytes.NewReader(b), } fidelity := &fidelityScraper{} gots, err := fidelity.scrape(message) if err != nil { t.Fatal(err) } if len(gots) != 1 { t.Fatal(len(gots)) } got := gots[0] want := Transaction{ ID: got.ID, Bank: Fidelity, Amount: "?.??", Vendor: "misc", Date: "[]", Account: Fidelity.String() + "-5576", } if *got != want { t.Fatalf("want:\n\t%+v, got\n\t%+v", want, *got) } } func TestScrapeFidelityWithdrawal(t *testing.T) { b, err := ioutil.ReadFile("./testdata/fidelity.withdrawal.txt") if err != nil { t.Fatal(err) } message := &mail.Message{ Header: map[string][]string{ "Subject": []string{"Fidelity Alerts - Direct Debit Withdrawal"}, }, Body: bytes.NewReader(b), } fidelity := &fidelityScraper{} gots, err := fidelity.scrape(message) if err != nil { t.Fatal(err) } if len(gots) != 1 { t.Fatal(len(gots)) } got := gots[0] want := Transaction{ ID: got.ID, Bank: Fidelity, Amount: "1.00", Vendor: "CHASE CREDIT CRD", Date: "[]", Account: Fidelity.String() + "-5576", } if *got != want { t.Fatalf("want:\n\t%+v, got\n\t%+v", want, *got) } } func TestScrapeBofACharge2024(t *testing.T) { b, err := ioutil.ReadFile("./testdata/bofa.charge.2024.txt") if err != nil { t.Fatal(err) } message := &mail.Message{ Header: map[string][]string{ "Subject": []string{"Credit card transaction exceeds alert limit you set"}, }, Body: bytes.NewReader(b), } bofa := &bankOfAmericaScraper{} gots, err := bofa.scrape(message) if err != nil { t.Fatal(err) } if len(gots) != 1 { t.Fatal(len(gots)) } got := gots[0] want := Transaction{ ID: got.ID, Bank: BankOfAmerica, Amount: "21.48", Vendor: "PP SPOTIFYUSAI", Date: "[]", Account: BankOfAmerica.String(), } if *got != want { t.Fatalf("want:\n\t%+v, got\n\t%+v", want, *got) } } func TestScrapeBofACharge(t *testing.T) { b, err := ioutil.ReadFile("./testdata/bofa.charge.txt") if err != nil { t.Fatal(err) } message := &mail.Message{ Header: map[string][]string{ "Subject": []string{"Credit card transaction exceeds alert limit you set"}, }, Body: bytes.NewReader(b), } bofa := &bankOfAmericaScraper{} gots, err := bofa.scrape(message) if err != nil { t.Fatal(err) } if len(gots) != 1 { t.Fatal(len(gots)) } got := gots[0] want := Transaction{ ID: got.ID, Bank: BankOfAmerica, Amount: "75.08", Vendor: "PAYPAL GIBBDOGENTE MA", Date: "[]", Account: BankOfAmerica.String(), } if *got != want { t.Fatalf("want:\n\t%+v, got\n\t%+v", want, *got) } }