package server import ( "context" "testing" "time" "neuralhunt/internal/auth" "neuralhunt/internal/data" rtx "neuralhunt/internal/runtime" ) func TestProfileCleanupPreviewProtectsConnectedClient(t *testing.T) { ctx := context.Background() db, err := data.OpenSQLite(ctx, t.TempDir()+"/cleanup.db") if err != nil { t.Fatal(err) } defer db.Close() store := data.New(db) jwk := auth.PublicJWK{Kty: "EC", Crv: "P-256", X: "AQ", Y: "Ag"} for _, id := range []string{"offline_old", "online_old"} { if err := store.UpsertClient(ctx, id, jwk); err != nil { t.Fatal(err) } } old := time.Now().UTC().Add(-10 * 24 * time.Hour).UnixMilli() if _, err := db.ExecContext(ctx, `UPDATE clients SET last_seen=?`, old); err != nil { t.Fatal(err) } runtimeState := rtx.New() if _, err := runtimeState.AcquirePresence("online_old", "session"); err != nil { t.Fatal(err) } s := &Server{store: store, runtime: runtimeState} preview, ids, err := s.profileCleanupPreview(ctx, 7*24*60*60) if err != nil { t.Fatal(err) } if preview.Eligible != 1 || preview.ProtectedConnected != 1 { t.Fatalf("unexpected preview: %+v", preview) } if len(ids) != 1 || ids[0] != "offline_old" { t.Fatalf("unexpected ids: %#v", ids) } } func TestProfileCleanupDurationGuard(t *testing.T) { if _, err := profileCleanupDurationSeconds("3599"); err == nil { t.Fatal("sub-hour cleanup window should be rejected") } if got, err := profileCleanupDurationSeconds("86400"); err != nil || got != 86400 { t.Fatalf("got=%d err=%v", got, err) } } func TestProfileCleanupProtectsPlaceParticipant(t *testing.T) { ctx := context.Background() db, err := data.OpenSQLite(ctx, t.TempDir()+"/cleanup-place.db") if err != nil { t.Fatal(err) } defer db.Close() store := data.New(db) jwk := auth.PublicJWK{Kty: "EC", Crv: "P-256", X: "AQ", Y: "Ag"} if err := store.UpsertClient(ctx, "place_old", jwk); err != nil { t.Fatal(err) } old := time.Now().UTC().Add(-10 * 24 * time.Hour).UnixMilli() if _, err := db.ExecContext(ctx, `UPDATE clients SET last_seen=? WHERE id='place_old'`, old); err != nil { t.Fatal(err) } if _, err := db.ExecContext(ctx, `INSERT INTO place_wallets(client_id,balance_milli,earned_milli,updated_at) VALUES('place_old',1000,1000,?)`, old); err != nil { t.Fatal(err) } s := &Server{store: store, runtime: rtx.New()} preview, ids, err := s.profileCleanupPreview(ctx, 7*24*60*60) if err != nil { t.Fatal(err) } if preview.Eligible != 0 || preview.ProtectedPlace != 1 { t.Fatalf("unexpected preview: %+v", preview) } if len(ids) != 0 { t.Fatalf("place participant should be protected, got ids %#v", ids) } deleted, err := store.DeleteInactiveNonWinnerClients(ctx, time.Now().UTC().Add(-7*24*time.Hour).UnixMilli(), []string{"place_old"}) if err != nil { t.Fatal(err) } if len(deleted) != 0 || !store.ClientExists(ctx, "place_old") { t.Fatal("place participant was deleted") } }