dev: 4 failing web unit tests (Agenda count, voice Play, ModeIcon weight literal, SearchPreview formatter) #1159

Open
opened 2026-10-05 16:17:27 +00:00 by kayg · 4 comments
Owner

dev has 4 failing unit tests (found by #1133's full bun run test, 2026-10-05)

cd apps/web && bun run test on dev: "Test Files 4 failed | 258 passed (262); Tests 4 failed | 1800 passed (1804)". Jobs reported them as "unrelated" because perf-lint used to stop check first. Each is a real regression from a merge today; fix the CODE (not the test) unless the test encodes an outdated decision, and say which with evidence:

  1. Agenda: expected +3 but got +5 (likely the Agenda paging/overflow change, 76f0aa23a or #1086–#1088 in batch 1).
  2. Audio playback: no Play button found (voice player; check #822 shared voice components vs today's card/hover-card changes).
  3. Font-weight guard: numeric 700 literal in packages/ui ModeIcon.svelte (tray icons, batch 9, #1095): use the weight token.
  4. Date formatter guard: a direct formatter in SearchPreview.svelte (palette work): use the shared date formatter (this also matters for #1139's locale-correct dates).
    Run the full bun run test and bun run check after the fixes and quote both verbatim; all green is the goal. Commit per fix; comment on this issue with head SHA. Do not push.
## dev has 4 failing unit tests (found by #1133's full `bun run test`, 2026-10-05) `cd apps/web && bun run test` on dev: "Test Files 4 failed | 258 passed (262); Tests 4 failed | 1800 passed (1804)". Jobs reported them as "unrelated" because perf-lint used to stop `check` first. Each is a real regression from a merge today; fix the CODE (not the test) unless the test encodes an outdated decision, and say which with evidence: 1. Agenda: expected `+3` but got `+5` (likely the Agenda paging/overflow change, 76f0aa23a or #1086–#1088 in batch 1). 2. Audio playback: no Play button found (voice player; check #822 shared voice components vs today's card/hover-card changes). 3. Font-weight guard: numeric `700` literal in packages/ui ModeIcon.svelte (tray icons, batch 9, #1095): use the weight token. 4. Date formatter guard: a direct formatter in SearchPreview.svelte (palette work): use the shared date formatter (this also matters for #1139's locale-correct dates). Run the full `bun run test` and `bun run check` after the fixes and quote both verbatim; all green is the goal. Commit per fix; comment on this issue with head SHA. Do not push.
Author
Owner

Starting #1159 in job/devtests-1159 from base 52e7e4c2fe. I am reproducing the four reported web test failures and will commit each code fix separately; no push or merge is planned.

Starting #1159 in job/devtests-1159 from base 52e7e4c2fe4c80015c86eba93e50c1f933edd4f3. I am reproducing the four reported web test failures and will commit each code fix separately; no push or merge is planned.
Author
Owner

Baseline on job/devtests-1159 (after bun install --frozen-lockfile):

Test Files  4 failed | 261 passed (265)
Tests       4 failed | 1819 passed (1823)

Findings:

  • Agenda +5 is caused by its fixture omitting indexed mediaType on linked .jpg files. The deck classifies by indexed MIME under #851; the Calendar range builder sets media_type for an existing linked file (crates/plugins/calendar/src/view.rs, attachment hydration around media_type.clone_from(mime)). The fixture has valid item IDs and thumbnail hashes but lacks that field. I will keep the +3 assertion and make the fixture match the API contract.
  • Search voice Play is a code bug. searchVoiceKey calls itemRepresentationKind without SearchResult.mime, even though the search server maps hit.mime onto each result (apps/web/src/lib/search/server.ts, entryFromHit). Also, itemRepresentationKind maps audio but not the voice-memo family returned for Voice Memos paths. I will pass MIME through and map both audio families to the shared voice card; the playback assertion stays unchanged.
  • The remaining failures are the exact guard violations reported: ModeIcon.svelte:49 uses numeric 700, and SearchPreview.svelte:418 constructs a formatter directly.
Baseline on `job/devtests-1159` (after `bun install --frozen-lockfile`): ``` Test Files 4 failed | 261 passed (265) Tests 4 failed | 1819 passed (1823) ``` Findings: - Agenda `+5` is caused by its fixture omitting indexed `mediaType` on linked `.jpg` files. The deck classifies by indexed MIME under #851; the Calendar range builder sets `media_type` for an existing linked file (`crates/plugins/calendar/src/view.rs`, attachment hydration around `media_type.clone_from(mime)`). The fixture has valid item IDs and thumbnail hashes but lacks that field. I will keep the `+3` assertion and make the fixture match the API contract. - Search voice Play is a code bug. `searchVoiceKey` calls `itemRepresentationKind` without `SearchResult.mime`, even though the search server maps `hit.mime` onto each result (`apps/web/src/lib/search/server.ts`, `entryFromHit`). Also, `itemRepresentationKind` maps `audio` but not the `voice-memo` family returned for Voice Memos paths. I will pass MIME through and map both audio families to the shared voice card; the playback assertion stays unchanged. - The remaining failures are the exact guard violations reported: `ModeIcon.svelte:49` uses numeric `700`, and `SearchPreview.svelte:418` constructs a formatter directly.
Author
Owner

Gate finding after the required merge: bun run check exits at perf-lint before the Svelte checks. It reports contracts/perf/exceptions.json at 21,977 entries versus the ratchet's 21,964, with 13 rule counts above their ceilings by one each. This exact mismatch is present at the starting SHA 52e7e4c2, origin/dev, and the merge result. Raising the ratchet would violate check_ratchet's rule that a ceiling cannot exceed the origin/dev merge-base ceiling, so I am leaving the unrelated debt contract intact and will run the remaining check steps directly. The full Vitest suite remains in this job's required gates.

Gate finding after the required merge: `bun run check` exits at perf-lint before the Svelte checks. It reports `contracts/perf/exceptions.json` at 21,977 entries versus the ratchet's 21,964, with 13 rule counts above their ceilings by one each. This exact mismatch is present at the starting SHA `52e7e4c2`, `origin/dev`, and the merge result. Raising the ratchet would violate `check_ratchet`'s rule that a ceiling cannot exceed the `origin/dev` merge-base ceiling, so I am leaving the unrelated debt contract intact and will run the remaining check steps directly. The full Vitest suite remains in this job's required gates.
Author
Owner

#1159 complete

Fixed all four reported failures. HEAD: 2e61309b4d291c05f3046b9f6eba8d26a838ce80.

Changes

  • Agenda’s +3 expectation remains correct. The failing fixture omitted indexed MIME data for its JPEGs, so I added image/jpeg to the fixture rather than changing overflow behavior or the assertion.
  • Search voice results now pass MIME data to the shared representation resolver. Audio and voice-memo results now expose the shared Play control. The playback fixture includes its real audio/mp4 MIME.
  • ModeIcon uses the shared --weight-bold token instead of numeric 700.
  • SearchPreview uses the shared preference-aware formatLongDate formatter for Mail dates.

Files: apps/web/src/lib/calendar/agenda.svelte.test.ts, apps/web/src/lib/calendar/audioPlayback.svelte.test.ts, apps/web/src/lib/search/voice.ts, packages/ui/src/components/calendar/attachments.ts, packages/ui/src/components/ModeIcon.svelte, apps/web/src/lib/search/SearchPreview.svelte.

Commits: 34edb5cb7, 8f2cd1fe1, cb60c88bf, 6b81c1efa. I merged origin/dev once before final verification. No push or merge to dev was made.

Decisions

The Agenda fixture now states the JPEG MIME because Calendar’s indexed API supplies it and the fixture previously relied on extension guessing. No other design decision was needed.

Verification

bun run test passed. Final output:

Test Files  265 passed (265)
Tests       1823 passed (1823)
Start at  20:03:27
Duration  448.78s (transform 34%, environment 24%, import 22%, tests 15%, setup 5%)

Environment  |component| jsdom was created 100 times · 169.43s total, 27% of tracked time

bun run check stopped at the existing perf-lint exception ratchet. This same ledger mismatch was present at the starting SHA and origin/dev; raising its ceilings here would alter unrelated baseline data. Output:

perf-lint: INVALID: exception ratchet: contract.blaze: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.blocked-network: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; contract.dom-bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.model-bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.row-identity: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.snapshot: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; coverage.profile: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; coverage.readiness: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; io.unresolved-call: 16191 exceptions exceed the ratchet ceiling 16190; fix the new violation instead; render.blaze-adapter: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.model_byte_cap: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.model_row_cap: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; total: ledger has 21977 exceptions; ratchet total is 21964

Other check steps run directly: glass, type, focus and motion token checks passed; svelte-kit sync passed; svelte-check reported 0 errors and 4 warnings in 3 untouched files. The user-storage check reports existing direct sessionStorage access in the unowned apps/web/src/lib/navigation/clientRouteStatus.svelte.ts. The production web build succeeded. No Rust source changed, so Rust clippy/test gates did not apply. cargo clean removed 7.2 GiB; generated web build output was deleted.

UX gaps closed

  • Search’s voice memo result has its Play action again and shares playback state with the app player.
  • Search Mail dates follow the same user preference as other long dates.
  • ModeIcon’s date weight follows the design token.
  • The Agenda overflow fixture carries the indexed metadata needed to represent real files.

UX gaps left

  • The full bun run check remains blocked by the pre-existing perf-lint ratchet mismatch above. The direct user-storage check also reports the unowned route file above.
  • The focused Search palette screenshot review passed for 390, 820 and 1440 px with macOS platform signals and light/dark themes. The SEARCH_E2E_1123_ONLY=1 flow captured the Mail preview at 1440 px in light theme, then failed when the adjacent Note preview body did not render; the Search API returned the real Note snippet. SEARCH_E2E_TITLE_ONLY=1 stopped earlier: /search?q=... raised Cannot read properties of null (reading 'pathname'), and the Search surface timed out.
  • agenda-decks-822.mjs captured the Agenda voice row at 390 and 820 px in both themes and 1440 px light. It later timed out in the 1440 px light Calendar week grid: .attachment-list.is-fan remained hidden (172 observations) while the test waited for it to become visible. The e2e assertions were not changed.

Attached macOS screenshots

Search palette, light/dark at 390, 820 and 1440 px: 390 light, 390 dark, 820 light, 820 dark, 1440 light, 1440 dark.

Selected Search preview, light/dark at 390 and 1440 px: 390 light, 390 dark, 1440 light, 1440 dark. Mail preview, light, 1440 px: Mail result preview.

Agenda voice row: 390 light, 390 dark, 820 light, 820 dark, 1440 light.

## #1159 complete Fixed all four reported failures. HEAD: `2e61309b4d291c05f3046b9f6eba8d26a838ce80`. ### Changes - Agenda’s `+3` expectation remains correct. The failing fixture omitted indexed MIME data for its JPEGs, so I added `image/jpeg` to the fixture rather than changing overflow behavior or the assertion. - Search voice results now pass MIME data to the shared representation resolver. Audio and `voice-memo` results now expose the shared Play control. The playback fixture includes its real `audio/mp4` MIME. - ModeIcon uses the shared `--weight-bold` token instead of numeric `700`. - SearchPreview uses the shared preference-aware `formatLongDate` formatter for Mail dates. Files: `apps/web/src/lib/calendar/agenda.svelte.test.ts`, `apps/web/src/lib/calendar/audioPlayback.svelte.test.ts`, `apps/web/src/lib/search/voice.ts`, `packages/ui/src/components/calendar/attachments.ts`, `packages/ui/src/components/ModeIcon.svelte`, `apps/web/src/lib/search/SearchPreview.svelte`. Commits: `34edb5cb7`, `8f2cd1fe1`, `cb60c88bf`, `6b81c1efa`. I merged `origin/dev` once before final verification. No push or merge to `dev` was made. ### Decisions The Agenda fixture now states the JPEG MIME because Calendar’s indexed API supplies it and the fixture previously relied on extension guessing. No other design decision was needed. ### Verification `bun run test` passed. Final output: ```text Test Files 265 passed (265) Tests 1823 passed (1823) Start at 20:03:27 Duration 448.78s (transform 34%, environment 24%, import 22%, tests 15%, setup 5%) Environment |component| jsdom was created 100 times · 169.43s total, 27% of tracked time ``` `bun run check` stopped at the existing perf-lint exception ratchet. This same ledger mismatch was present at the starting SHA and `origin/dev`; raising its ceilings here would alter unrelated baseline data. Output: ```text perf-lint: INVALID: exception ratchet: contract.blaze: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.blocked-network: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; contract.dom-bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.model-bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.row-identity: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; contract.snapshot: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; coverage.profile: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; coverage.readiness: 356 exceptions exceed the ratchet ceiling 355; fix the new violation instead; io.unresolved-call: 16191 exceptions exceed the ratchet ceiling 16190; fix the new violation instead; render.blaze-adapter: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.bound: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.model_byte_cap: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; render.model_row_cap: 290 exceptions exceed the ratchet ceiling 289; fix the new violation instead; total: ledger has 21977 exceptions; ratchet total is 21964 ``` Other `check` steps run directly: glass, type, focus and motion token checks passed; `svelte-kit sync` passed; `svelte-check` reported 0 errors and 4 warnings in 3 untouched files. The user-storage check reports existing direct `sessionStorage` access in the unowned `apps/web/src/lib/navigation/clientRouteStatus.svelte.ts`. The production web build succeeded. No Rust source changed, so Rust clippy/test gates did not apply. `cargo clean` removed 7.2 GiB; generated web build output was deleted. ### UX gaps closed - Search’s voice memo result has its Play action again and shares playback state with the app player. - Search Mail dates follow the same user preference as other long dates. - ModeIcon’s date weight follows the design token. - The Agenda overflow fixture carries the indexed metadata needed to represent real files. ### UX gaps left - The full `bun run check` remains blocked by the pre-existing perf-lint ratchet mismatch above. The direct user-storage check also reports the unowned route file above. - The focused Search palette screenshot review passed for 390, 820 and 1440 px with macOS platform signals and light/dark themes. The `SEARCH_E2E_1123_ONLY=1` flow captured the Mail preview at 1440 px in light theme, then failed when the adjacent Note preview body did not render; the Search API returned the real Note snippet. `SEARCH_E2E_TITLE_ONLY=1` stopped earlier: `/search?q=...` raised `Cannot read properties of null (reading 'pathname')`, and the Search surface timed out. - `agenda-decks-822.mjs` captured the Agenda voice row at 390 and 820 px in both themes and 1440 px light. It later timed out in the 1440 px light Calendar week grid: `.attachment-list.is-fan` remained hidden (`172` observations) while the test waited for it to become visible. The e2e assertions were not changed. ### Attached macOS screenshots Search palette, light/dark at 390, 820 and 1440 px: [390 light](https://git.kayg.org/attachments/6355661e-ef18-4467-b60e-dd1d177bf9b3), [390 dark](https://git.kayg.org/attachments/ebaad2ba-fec8-40ec-adb8-c3e2a3b079ad), [820 light](https://git.kayg.org/attachments/c594542f-22b1-4273-90aa-2115eaed5783), [820 dark](https://git.kayg.org/attachments/b769835c-4a56-4905-bf93-5c3aa0a93de6), [1440 light](https://git.kayg.org/attachments/234ff83b-7a66-4695-b004-b1918ad5ff17), [1440 dark](https://git.kayg.org/attachments/928e9ff8-97d2-48da-b753-a996e53d5e18). Selected Search preview, light/dark at 390 and 1440 px: [390 light](https://git.kayg.org/attachments/4e13145d-e345-453d-b949-8f4c1cd909c8), [390 dark](https://git.kayg.org/attachments/71d87657-c805-41e0-b750-77d28df6af09), [1440 light](https://git.kayg.org/attachments/944c2e26-b542-45b2-9aaf-49d7df6ac8ba), [1440 dark](https://git.kayg.org/attachments/0acf8f11-97d2-4a53-99f3-1f797cafa547). Mail preview, light, 1440 px: [Mail result preview](https://git.kayg.org/attachments/13561366-0049-4f66-b264-181023872df5). Agenda voice row: [390 light](https://git.kayg.org/attachments/6458b481-5edc-49ed-9beb-27e97ec93e8d), [390 dark](https://git.kayg.org/attachments/5b702d93-0fd6-4e96-ab64-283f0d1adeea), [820 light](https://git.kayg.org/attachments/eb56bf9d-6096-4981-831f-d6c8e830b51e), [820 dark](https://git.kayg.org/attachments/cb90f70d-512e-485c-8290-746c0c0a0e3d), [1440 light](https://git.kayg.org/attachments/52d79d1d-8f1c-4c6b-a8e7-395956f4b29f).
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/calternal#1159
No description provided.