Skip to content

test(metering): fix time-bombed test 'filters by from/to date range' (blocks all PRs to develop + main) #4637

Description

@OneStepAt4time

Bug

`src/tests/metering.test.ts:600` ("MeteringService > getDailyTokenBreakdown > filters by from/to date range") hardcodes record timestamps to `'2026-05-10T10:00:00Z'` and `'2026-05-12T10:00:00Z'`. Combined with `src/metering.ts:515-517` (`autoPrune` filters records older than `Date.now() - maxAgeMs`), this test silently breaks ~28 days after the test was authored.

Test authored: 2026-05-13 (commit `35fde64c`, PR #3288, "feat(analytics): per-day token breakdown endpoint")
Last green main CI: 2026-05-31 (PR #4536)
First red: 2026-06-09 (today, PR #4636 CI run)

Failure:
```
AssertionError: expected [] to have a length of 1 but got +0
❯ src/tests/metering.test.ts:600:22
```

Date math: Today is 2026-06-09, exactly 28 days after `2026-05-12T10:00:00Z`. The test's `2026-05-10` record is 30 days old. Once `maxAgeMs` cuts in, both records are filtered as "too old" → `getDailyTokenBreakdown` returns `[]` → `toHaveLength(1)` fails.

Impact

  • Blocks ALL PRs to develop + main (required check `test (ubuntu-latest, 22)` is on the required-status-checks list for main)
  • Pre-existing regression, not introduced by any current PR
  • Affects both ubuntu-20 and ubuntu-22 test runs (deterministic, same failure)
  • No user-facing bug (test-only); the production `metering.ts` is correct
  • Silently red between 2026-05-31 and 2026-06-09 (no CI run on main between those dates — main was quiet for v0.6.6 hotfix → v0.6.7-prep work)

Acceptance Criteria

  • Test `'filters by from/to date range'` no longer depends on the current wall clock
  • Two suggested approaches (either is acceptable):
    • A. `vi.useFakeTimers()` + `vi.setSystemTime(new Date('2026-05-15T12:00:00Z'))` in the test, then `vi.useRealTimers()` after
    • B. Replace hardcoded dates with `Date.now() - N * 86400_000` offsets (e.g., `new Date(Date.now() - 7 * 86400_000).toISOString()`)
  • Same test, same assertion, just not time-bombed
  • All other metering tests must continue to pass
  • Test should be robust to running in any future month/year without modification
  • Land on develop → CI re-runs against all open PRs (including docs(README): correct 'ag setup telegram' to 'ag init' + phone-approvals guide (#4614) #4636 default-Z hotfix)

Repro

  1. `git checkout origin/main`
  2. `npm install && npm test -- src/tests/metering.test.ts -t "filters by from/to date range"`
  3. Observe: PASS or fail depending on the current date — flaky on date boundaries

Related

Out of Scope

  • Don't refactor other metering tests
  • Don't change `metering.ts` production code (the test is wrong, the code is right)
  • Don't open a long-running discussion on test patterns — this is a targeted fix

Suggested Branch + PR

Branch: `fix/metering-timebomb-test` (off develop, per the standard backend workflow)
PR target: `develop`
After develop CI green: PR #4636 will auto-rebase or get a fresh CI run; if green, Argus reviews, I merge to main.


Severity: P1 — CI gate silently broken, blocks 1 active PR (#4636) + every future PR to develop or main until fixed. Not user-facing, but it's a gate regression, not a test flake.

Handoff: <@1490089546099069048> per Boss msg 1513850654420898003, 2026-06-09 12:22 GMT+2: "fix `metering.test.ts:600`. Either use `vi.useFakeTimers()` + `vi.setSystemTime()` to freeze clock, or replace hardcoded dates with `Date.now() - N` offsets. Single-file, ~30 min. Land on develop, CI re-runs on PR #4636."

cc <@1490089830472880218> — your review comes after CI flips green. Bot approval covers branch-protection `required_approving_review_count: 1` on main.

cc <@1494004694803153058> — for awareness, this is Boss-routed per the 12:22 GMT+2 message.

Metadata

Metadata

Assignees

No one assigned

    Labels

    backendbugSomething isn't workingcipriority:P1High priority bug/issuereleasedIncluded in a published releasetests

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions