package runners_test import ( "context" "errors" "testing" "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/yan1h/agent-coding-workflow/internal/jobs/runners" ) type fakeMCPTokensPurgeRepo struct { purged int64 purgeErr error capturedCutoff time.Time called bool } func (f *fakeMCPTokensPurgeRepo) PurgeExpired(_ context.Context, before time.Time) (int64, error) { f.called = true f.capturedCutoff = before if f.purgeErr != nil { return 0, f.purgeErr } return f.purged, nil } func TestMCPTokensPurge_RunCallsPurgeWithCorrectCutoff(t *testing.T) { t.Parallel() repo := &fakeMCPTokensPurgeRepo{purged: 4} retention := 168 * time.Hour r := runners.NewMCPTokensPurge(repo, retention, discardLogger()) before := time.Now() r.Run(context.Background()) after := time.Now() require.True(t, repo.called) expectedFloor := before.Add(-retention).Add(-time.Second) expectedCeil := after.Add(-retention).Add(time.Second) assert.True(t, !repo.capturedCutoff.Before(expectedFloor) && !repo.capturedCutoff.After(expectedCeil), "cutoff %s outside [%s, %s]", repo.capturedCutoff, expectedFloor, expectedCeil) } func TestMCPTokensPurge_RunErrorDoesNotPanic(t *testing.T) { t.Parallel() repo := &fakeMCPTokensPurgeRepo{purgeErr: errors.New("db down")} r := runners.NewMCPTokensPurge(repo, time.Hour, discardLogger()) require.NotPanics(t, func() { r.Run(context.Background()) }) assert.True(t, repo.called) } func TestMCPTokensPurge_NoRowsIsNoOp(t *testing.T) { t.Parallel() repo := &fakeMCPTokensPurgeRepo{purged: 0} r := runners.NewMCPTokensPurge(repo, time.Hour, discardLogger()) require.NotPanics(t, func() { r.Run(context.Background()) }) assert.True(t, repo.called) }