package repository_test import ( "context" "path/filepath" "strings" "testing" "time" managedaccess "billing/internal/access" "billing/internal/repository" ) func TestBusinessEventsPersistKeyQuotaAndAutomaticResetActions(t *testing.T) { path := filepath.Join(t.TempDir(), "usage.db") store, err := repository.OpenSQLiteUsage(path) if err != nil { t.Fatal(err) } if _, err := store.BootstrapManagedKey(context.Background(), "default", "000000"); err != nil { t.Fatal(err) } now := time.Date(2026, 8, 19, 1, 0, 0, 0, time.UTC) next := now.Add(time.Hour) if _, err := store.UpdateBilling(context.Background(), "key_default", managedaccess.BillingSettings{ QuotaMicros: 20_000_000, ResetPeriod: managedaccess.ResetDaily, NextResetAt: &next, MaxConcurrency: 4, }, now); err != nil { t.Fatal(err) } if _, err := store.BillingState(context.Background(), "key_default", next.Add(time.Minute)); err != nil { t.Fatal(err) } if _, err := store.ResetBilling(context.Background(), "key_default", next.Add(2*time.Minute)); err != nil { t.Fatal(err) } events, err := store.ListBusinessEvents(context.Background(), 100) if err != nil { t.Fatal(err) } joined := businessEventText(events) for _, expected := range []string{ "系统初始化用户 `default` 的 Key", "管理员调整用户 `default` 的额度:$0 → $20", "系统执行用户 `default` 的额度自然重置", "管理员手动重置用户 `default` 的额度", } { if !strings.Contains(joined, expected) { t.Fatalf("missing %q in %s", expected, joined) } } for _, event := range events { if event.Status != repository.BusinessEventSucceeded { t.Fatalf("unexpected status: %+v", event) } } if err := store.Close(); err != nil { t.Fatal(err) } reopened, err := repository.OpenSQLiteUsage(path) if err != nil { t.Fatal(err) } defer reopened.Close() persisted, err := reopened.ListBusinessEvents(context.Background(), 100) if err != nil || len(persisted) != len(events) { t.Fatalf("persisted events=%d want=%d err=%v", len(persisted), len(events), err) } } func businessEventText(events []repository.BusinessEvent) string { values := make([]string, 0, len(events)) for _, event := range events { values = append(values, event.Event) } return strings.Join(values, "\n") }