Skip to content

test(frontend): T-222 i18n EN+FR parity test#116

Merged
mpiton merged 2 commits into
mainfrom
feat/i-90-t-222-i18n-keys
May 14, 2026
Merged

test(frontend): T-222 i18n EN+FR parity test#116
mpiton merged 2 commits into
mainfrom
feat/i-90-t-222-i18n-keys

Conversation

@mpiton
Copy link
Copy Markdown
Owner

@mpiton mpiton commented May 14, 2026

Summary

  • Extend src/shared/i18n/__tests__/i18n.test.tsx with a describe("locale parity (T-222)") block that asserts every leaf key in en.json mirrors fr.json (and vice versa), plus four sanity-coverage tests for the specific surface area called out in the T-222 acceptance criteria.
  • Stabilize the kanban relative-time snapshots by freezing Date.now() in the affected test beforeEach/afterEach so the populated-board + col-<phase>-3-tasks snapshots stop drifting once per day.

Closes #90 (T-222: i18n EN+FR keys — kanban / wizard / dialog / projects).

Why

The T-222 issue spec asks for three things:

  1. No hardcoded user-facing strings in components — all via useT.
  2. EN + FR parity: every key present in both locales.
  3. Vitest covers absence of missing keys (extend existing i18n test in __tests__/).

Items (1) and (2) were already satisfied by the prior T-217 / T-218 / T-219 / T-220 deliveries — every kanban / wizard / dialog / projects component already routes strings through useT("kanban") or useT("projects"), and the en.json + fr.json files have mirrored structure. Three parallel exploration agents confirmed this exhaustively before any code was written: no <span> or aria-label or placeholder carries a hardcoded literal anywhere in the surface area covered by this issue.

Item (3) was the actual deliverable: extend the existing i18n test with programmatic enforcement so a future contributor who renames kanban.column.backlog in en.json but forgets fr.json gets a hard-fail in CI instead of a silent regression.

Changes

src/shared/i18n/__tests__/i18n.test.tsx — adds a new describe("locale parity (T-222)") block with six tests:

JSON imports rely on TypeScript's resolveJsonModule (already enabled in tsconfig.json) so the locale data is read at compile time with full type-safety — no runtime file I/O.

src/features/kanban/components/KanbanColumn.test.tsx + KanbanBoard.test.tsx — adds vi.useFakeTimers({ shouldAdvanceTime: true }) + vi.setSystemTime(new Date("2026-05-14T00:00:00Z")) to the beforeEach and vi.useRealTimers() to the afterEach. The created_at: "2026-05-12T00:00:00Z" constant in the in-test task builders produces TaskCard's "X days ago" relative time against Date.now(), which drifted by one day every 24 hours of wall-clock time and silently failed eight snapshots overnight. Freezing the date pins the snapshot output deterministically; regenerated snapshots are at the canonical "2 days ago" / "in 2 days" delta.

Test plan

  • pnpm exec vitest run src/shared/i18n/__tests__/i18n.test.tsx — 15/15 pass (6 new + 9 existing)
  • pnpm exec vitest run (full suite) — 313/313 pass
  • pnpm exec tsc -b — clean
  • pnpm exec oxlint src/shared/i18n/__tests__/i18n.test.tsx — 0 warnings / 0 errors
  • pnpm exec oxfmt --check src/shared/i18n/__tests__/i18n.test.tsx — clean
  • Pre-push hook (knip + rust-test + cargo-deny + ts-typecheck + ts-test) — all green

Acceptance criteria

  • AC1 — No hardcoded user-facing strings in components — all via useT. (Already satisfied by T-217 / T-218 / T-219 / T-220; verified by exhaustive exploration before writing tests.)
  • AC2 — EN + FR parity: every key present in both locales. (Enforced programmatically by the two new universal parity tests.)
  • AC3 — Vitest covers absence of missing keys (extend existing i18n test in __tests__/). (Six new test cases inside the existing i18n.test.tsx per the issue spec.)

Adversarial review (typescript-reviewer agent)

No CRITICAL or HIGH findings. Two MEDIUM observations (spec-wording mismatch on kanban.empty per column vs the actually-shared kanban.column.empty key; module-level const Sets shared across it blocks) and two LOW observations (spec-coverage tests are intentionally non-exhaustive — universal parity tests handle the rest; collectLeafKeys silently drops empty objects) — all acknowledged as design choices rather than bugs. The empty-object edge case is theoretical (neither locale contains empty objects today); if it ever does, the parity test will surface it as asymmetric key counts between en and fr.

Out of scope

  • No migration of any component code (already migrated by prior tasks).
  • No locale-file edits (manual diff confirmed parity holds today; the parity tests pass without any locale modifications).
  • No new namespace introduction or restructure.
  • No runtime parity check in a startup hook — would add unnecessary boot cost. Compile-time + CI-time enforcement via the new tests suffices.

Summary by CodeRabbit

  • Tests
    • Improved test stability for Kanban features by pinning system time in test suites.
    • Added internationalization test suite to ensure English and French translations remain synchronized across all UI elements.

Review Change Stack

mpiton added 2 commits May 14, 2026 06:48
Extend src/shared/i18n/__tests__/i18n.test.tsx with a locale parity
describe block. Adds a collectLeafKeys helper that flattens nested
locale JSON into dot-notation paths, then asserts:

- every en.json leaf key is mirrored in fr.json
- every fr.json leaf key is mirrored in en.json
- spec-coverage sanity: kanban column phases (backlog/spec/plan/
  code/qa/pr/done + empty), wizard keys, edit + delete dialog keys,
  projects tab + create form keys

All UI strings were already migrated to useT() via T-217/T-218/T-219/
T-220, so AC1 (no hardcoded strings) was already satisfied. AC2
(parity) is now enforced programmatically. AC3 (vitest covers
missing keys) is satisfied by the six new test cases.

vitest 15/15, tsc clean, oxlint 0/0, oxfmt clean.
…ive-time snapshots

KanbanBoard and KanbanColumn snapshot tests render TaskCard's "X
days ago" timestamps which compute against `Date.now()`. With
hardcoded created_at = 2026-05-12, the snapshot drifted every day
as the wall-clock advanced. Pin Date to 2026-05-14 via
vi.setSystemTime in beforeEach + vi.useRealTimers in afterEach.
Regenerate snapshots once at "2 days ago" so they stay valid
indefinitely.

Unblocks T-222 PR push (closes #90 was blocked by these snapshots
failing the pnpm exec vitest run pre-push hook).
@qodo-code-review
Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 14, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b4bb77c7-292e-485d-bd82-6bdcba2a0623

📥 Commits

Reviewing files that changed from the base of the PR and between ded844b and 1120afe.

⛔ Files ignored due to path filters (2)
  • src/features/kanban/components/__snapshots__/KanbanBoard.test.tsx.snap is excluded by !**/*.snap
  • src/features/kanban/components/__snapshots__/KanbanColumn.test.tsx.snap is excluded by !**/*.snap
📒 Files selected for processing (4)
  • CHANGELOG.md
  • src/features/kanban/components/KanbanBoard.test.tsx
  • src/features/kanban/components/KanbanColumn.test.tsx
  • src/shared/i18n/__tests__/i18n.test.tsx

📝 Walkthrough

Walkthrough

This PR stabilizes Kanban relative-time snapshots with system-time pinning in test suites and introduces a comprehensive EN/FR locale parity validation framework that recursively mirrors leaf-key presence across translation files with targeted checks for kanban, wizard, dialog, and project UI keys.

Changes

Test Stability & i18n Coverage

Layer / File(s) Summary
i18n locale parity test suite
src/shared/i18n/__tests__/i18n.test.tsx
Added collectLeafKeys helper to recursively extract dot-delimited translation keys from nested locale objects. New describe("locale parity (T-222)") suite asserts bidirectional key mirroring between en.json and fr.json, then validates presence of required kanban column phases, wizard step fields/buttons, task edit/delete dialog fields, and project creation form fields in both locales.
Kanban test time pinning
src/features/kanban/components/KanbanBoard.test.tsx, src/features/kanban/components/KanbanColumn.test.tsx
Both test suites now enable Vitest fake timers with automatic time advancement in beforeEach and pin the system clock to 2026-05-14T00:00:00Z to ensure deterministic relative-time snapshots. afterEach now explicitly restores real timers before cleanup.
Changelog documentation
CHANGELOG.md
Added ### Fixed entry for Kanban test stabilization and ### Added entry for i18n EN+FR locale parity test suite under Unreleased section.

Possibly related PRs

  • mpiton/forgent#59: Extends the existing i18n test infrastructure (src/shared/i18n/__tests__/i18n.test.tsx) with the new EN/FR locale parity and key-presence assertions.
  • mpiton/forgent#110: The Kanban test fake-timer updates and new i18n locale parity checks for kanban-related translation keys directly validate the KanbanBoard/KanbanColumn components and kanban i18n namespace.
  • mpiton/forgent#111: Kanban test time pinning and i18n locale parity both target relative-time rendering and the newly added kanban.taskcard translation keys introduced by TaskCard and format-relative-time changes.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 Tests now tick in perfect sync,
No flaky snapshots on the brink!
EN and FR keys match with care,
Each translation finds its pair. ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'test(frontend): T-222 i18n EN+FR parity test' clearly identifies the main change: adding i18n EN+FR parity tests for issue T-222. It is concise, specific, and directly related to the primary objective of the PR.
Linked Issues check ✅ Passed The PR fully addresses issue #90 (T-222) by implementing programmatic i18n parity tests for EN+FR locales, verifying specified key groups (kanban, wizard, dialog, projects), and stabilizing snapshot tests with fake timers to prevent drift.
Out of Scope Changes check ✅ Passed All changes are directly related to the linked issue #90 objectives: i18n parity tests, kanban snapshot stability fixes via fake timers, and no hardcoded string enforcement through programmatic test coverage.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/i-90-t-222-i18n-keys

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


Comment @coderabbitai help to get the list of available commands and usage tips.

@codspeed-hq
Copy link
Copy Markdown
Contributor

codspeed-hq Bot commented May 14, 2026

Merging this PR will not alter performance

✅ 7 untouched benchmarks


Comparing feat/i-90-t-222-i18n-keys (1120afe) with main (ded844b)

Open in CodSpeed

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 6 files

@mpiton mpiton merged commit 8abf863 into main May 14, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

T-222: i18n EN+FR keys (kanban / wizard / dialog / projects)

1 participant