budgeteer/server/main_test.go
Jan Bader 684efffbdf
Some checks failed
continuous-integration/drone/push Build is failing
Fix bugs in calculateBalances and handle not found categories
2022-04-05 19:33:41 +00:00

180 lines
4.3 KiB
Go

package server
import (
"context"
"encoding/json"
"fmt"
"io/fs"
"log"
"net/http"
"os"
"testing"
"time"
"git.javil.eu/jacob1123/budgeteer/bcrypt"
"git.javil.eu/jacob1123/budgeteer/config"
"git.javil.eu/jacob1123/budgeteer/jwt"
"git.javil.eu/jacob1123/budgeteer/postgres"
"git.javil.eu/jacob1123/budgeteer/web"
)
func TestMain(t *testing.T) {
t.Parallel()
cfg := config.Config{
DatabaseConnection: "postgres://budgeteer:budgeteer@db:5432/budgeteer_test",
SessionSecret: "random string for JWT authorization",
}
queries, err := postgres.Connect("pgtx", cfg.DatabaseConnection)
if err != nil {
log.Fatalf("Failed connecting to DB: %v", err)
}
static, err := fs.Sub(web.Static, "dist")
if err != nil {
panic("couldn't open static files")
}
tokenVerifier, err := jwt.NewTokenVerifier(cfg.SessionSecret)
if err != nil {
panic(fmt.Errorf("couldn't create token verifier: %w", err))
}
handler := &Handler{
Service: queries,
TokenVerifier: tokenVerifier,
CredentialsVerifier: &bcrypt.Verifier{},
StaticFS: http.FS(static),
}
ctx := context.Background()
createUserParams := postgres.CreateUserParams{
Email: "test@example.com",
Name: "test@example.com",
Password: "this is my dumb password",
}
user, err := handler.Service.CreateUser(ctx, createUserParams)
if err != nil {
fmt.Println(err)
t.Fail()
return
}
budget, err := handler.Service.NewBudget(ctx, "My nice Budget", user.ID)
if err != nil {
fmt.Println(err)
t.Fail()
return
}
handler.DoYNABImport(ctx, t, budget)
// check available balance for more dates
handler.CheckAvailableBalance(ctx, t, budget)
// check categories
// check accounts
}
type CategoryTestData struct {
Available float64
Activity float64
Assigned float64
}
func (h Handler) CheckAvailableBalance(ctx context.Context, t *testing.T, budget *postgres.Budget) {
t.Helper()
loc := time.Now().Location()
first := time.Date(2021, 12, 1, 0, 0, 0, 0, loc)
firstOfNextMonth := time.Date(2022, 1, 1, 0, 0, 0, 0, loc)
data, err := h.prepareBudgeting(ctx, *budget, firstOfNextMonth, first)
if err != nil {
t.Errorf("prepare budgeting: %s", err)
return
}
// 2022-01 assert_equal(t, -115170.56, data.AvailableBalance.GetFloat64(), "available balance")
assert_equal(t, -110181.600, data.AvailableBalance.GetFloat64(), "available balance")
categoryTestDataFile, err := os.Open("../testdata/production-export/results/categories-2021-12.json")
if err != nil {
t.Errorf("could not load category test data: %s", err)
return
}
var categoryTestData map[string]CategoryTestData
dec := json.NewDecoder(categoryTestDataFile)
err = dec.Decode(&categoryTestData)
if err != nil {
t.Errorf("could not decode category test data: %s", err)
return
}
for categoryName, categoryTestData := range categoryTestData {
found := false
for _, category := range data.Categories {
name := category.Group + " : " + category.Name
if name == categoryName {
assert_equal(t, categoryTestData.Available, category.Available.GetFloat64(), "available for "+categoryName)
assert_equal(t, categoryTestData.Activity, category.Activity.GetFloat64(), "activity for "+categoryName)
assert_equal(t, categoryTestData.Assigned, category.Assigned.GetFloat64(), "assigned for "+categoryName)
found = true
}
}
if !found {
t.Errorf("category " + categoryName + " was not found in result")
}
}
}
func assert_equal(t *testing.T, expected, actual float64, message string) {
if expected == actual {
return
}
t.Errorf("%s: expected %f, got %f", message, expected, actual)
}
func (h Handler) DoYNABImport(ctx context.Context, t *testing.T, budget *postgres.Budget) {
t.Helper()
budgetID := budget.ID
ynab, err := postgres.NewYNABImport(ctx, h.Service.Queries, budgetID)
if err != nil {
fmt.Println(err)
t.Fail()
return
}
transactions, err := os.Open("../testdata/production-export/Register.tsv")
if err != nil {
fmt.Println(err)
t.Fail()
return
}
assignments, err := os.Open("../testdata/production-export/Budget.tsv")
if err != nil {
fmt.Println(err)
t.Fail()
return
}
err = ynab.ImportTransactions(ctx, transactions)
if err != nil {
fmt.Println(err)
t.Fail()
return
}
err = ynab.ImportAssignments(ctx, assignments)
if err != nil {
fmt.Println(err)
t.Fail()
return
}
}