Files
sultan/pkg/ledger/customers_test.go
T

119 lines
4.4 KiB
Go

package ledger
import (
"errors"
"testing"
"sultan/pkg/store"
)
// Kunden entstehen automatisch aus Mandanten-IDs; vorhandene bleiben unberührt.
func TestEnsureCustomers(t *testing.T) {
l := open(t)
if err := l.EnsureCustomers(ctx, "webproxy11", []TenantRef{{ID: "kunde", Name: "Kunde A"}, {ID: "andere", Name: "Andere"}}); err != nil {
t.Fatal(err)
}
c, err := l.GetCustomer(ctx, "kunde")
if err != nil || c.Name != "Kunde A" || !c.Auto || c.Cycle != CycleUnclassified || c.FlatRate != nil {
t.Errorf("automatisch angelegt: %+v, %v", c, err)
}
// Von Hand geändert: ein späterer Bericht überschreibt nichts.
c.Name, c.Group, c.Note, c.Cycle = "Kunde A GmbH", "extern", "Kumpel, zahlt in Bier", CycleQuarterly
cents := int64(8900)
c.FlatRate = &cents
if err := l.UpdateCustomer(ctx, c); err != nil {
t.Fatal(err)
}
l.EnsureCustomers(ctx, "webproxy11", []TenantRef{{ID: "kunde", Name: "Neuer Name"}})
got, _ := l.GetCustomer(ctx, "kunde")
if got.Name != "Kunde A GmbH" || got.Auto || got.Group != "extern" || got.Cycle != CycleQuarterly || *got.FlatRate != 8900 {
t.Errorf("nach erneutem Bericht: %+v", got)
}
// Ungültige Mandanten-IDs (sollte es nicht geben) werden übersprungen.
if err := l.EnsureCustomers(ctx, "webproxy11", []TenantRef{{ID: "Kein Gültiger"}}); err != nil {
t.Errorf("ungültige ID: %v", err)
}
}
// Zuordnung: Payee + Mandant > Mandant auf allen Payees > gleiche ID. Ein
// zugeordneter Mandant erzeugt keinen eigenen Kunden mehr.
func TestResolveCustomer(t *testing.T) {
l := open(t)
l.AddCustomer(ctx, Customer{ID: "k-1001", Name: "Kunde A"})
l.AddCustomer(ctx, Customer{ID: "familie", Name: "Familie", Group: "familie"})
if err := l.MapTenant(ctx, "", "kunde", "k-1001"); err != nil {
t.Fatal(err)
}
if err := l.MapTenant(ctx, "webproxy12", "kunde-a", "k-1001"); err != nil { // Tippfehler auf Nebencluster
t.Fatal(err)
}
l.EnsureCustomers(ctx, "webproxy11", []TenantRef{{ID: "kunde"}, {ID: "neffe"}})
l.EnsureCustomers(ctx, "webproxy12", []TenantRef{{ID: "kunde-a"}})
tests := []struct{ payee, tenant, want string }{
{"webproxy11", "kunde", "k-1001"},
{"webproxy12", "kunde", "k-1001"},
{"webproxy12", "kunde-a", "k-1001"},
{"webproxy11", "neffe", "neffe"}, // automatisch
{"webproxy11", "unbekannt", ""},
}
r, err := l.CustomerResolver(ctx)
if err != nil {
t.Fatal(err)
}
for _, tt := range tests {
if got := r.Resolve(tt.payee, tt.tenant); got != tt.want {
t.Errorf("Resolve(%s, %s) = %q, erwartet %q", tt.payee, tt.tenant, got, tt.want)
}
}
if _, err := l.GetCustomer(ctx, "kunde"); !errors.Is(err, store.ErrNotFound) {
t.Errorf("zugeordneter Mandant hat eigenen Kunden erzeugt: %v", err)
}
if _, err := l.GetCustomer(ctx, "kunde-a"); !errors.Is(err, store.ErrNotFound) {
t.Errorf("Tippfehler-Mandant hat eigenen Kunden erzeugt: %v", err)
}
maps, _ := l.ListMappings(ctx)
if len(maps) != 2 {
t.Errorf("Zuordnungen: %+v", maps)
}
if err := l.UnmapTenant(ctx, "webproxy12", "kunde-a"); err != nil {
t.Fatal(err)
}
if err := l.UnmapTenant(ctx, "webproxy12", "kunde-a"); !errors.Is(err, store.ErrNotFound) {
t.Errorf("zweites Entfernen: %v", err)
}
if err := l.MapTenant(ctx, "", "x", "gibts-nicht"); !errors.Is(err, store.ErrNotFound) {
t.Errorf("Zuordnung zu unbekanntem Kunden: %v", err)
}
}
func TestCustomers_CRUD(t *testing.T) {
l := open(t)
if err := l.AddCustomer(ctx, Customer{ID: "familie", Name: "Familie", Group: "familie", Cycle: CycleYearly}); err != nil {
t.Fatal(err)
}
if err := l.AddCustomer(ctx, Customer{ID: "familie", Name: "x"}); !errors.Is(err, store.ErrExists) {
t.Errorf("doppelt: %v", err)
}
for _, bad := range []Customer{{ID: "Ungültig", Name: "x"}, {ID: "ok", Name: ""}, {ID: "ok2", Name: "x", Cycle: "wöchentlich"}} {
if err := l.AddCustomer(ctx, bad); !errors.Is(err, store.ErrInvalid) {
t.Errorf("%+v: %v", bad, err)
}
}
l.AddCustomer(ctx, Customer{ID: "k-1001", Name: "Kunde A", Group: "extern"})
list, _ := l.ListCustomers(ctx)
if len(list) != 2 || list[0].ID != "familie" {
t.Errorf("Liste: %+v", list)
}
if err := l.UpdateCustomer(ctx, Customer{ID: "gibts-nicht", Name: "x"}); !errors.Is(err, store.ErrNotFound) {
t.Errorf("Update unbekannt: %v", err)
}
l.MapTenant(ctx, "", "kunde", "k-1001")
if err := l.DeleteCustomer(ctx, "k-1001"); err != nil {
t.Fatal(err)
}
if maps, _ := l.ListMappings(ctx); len(maps) != 0 {
t.Errorf("Zuordnungen nach Löschen: %+v", maps)
}
}