test: unify i18next mocks into centralized helpers#7
Conversation
Consolidate scattered i18next mock implementations across test files into a single source of truth. This reduces duplication and ensures consistent mock behavior. - Create test/i18n-mock.ts with reusable factory functions - Update vitest.setup.ts to use the centralized helpers - Remove redundant mock definitions from 8 test files - Update testing.md documentation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…eateReactI18nextMock` and detail global mock provisions.
There was a problem hiding this comment.
Pull request overview
This PR centralizes and standardizes i18n mocking for frontend tests, reducing repeated inline mocks and documenting the new testing pattern.
Changes:
- Introduces
web/test/i18n-mock.tswith reusable helpers (createTFunction,createUseTranslationMock,createTransMock,createReactI18nextMock) and wires the globalreact-i18nextmock inweb/vitest.setup.tsto use them. - Refactors numerous spec files to rely on the global i18n mock and/or the new helpers, deleting bespoke
useTranslation/Transmocks and aligning expectations (e.g., namespace-prefixed keys). - Updates testing documentation and the component test template to describe the new centralized i18n mocking approach and to discourage ad‑hoc “return key” mocks.
Reviewed changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
web/vitest.setup.ts |
Switches the global react-i18next mock to use createReactI18nextMock from the new shared helper, establishing the central i18n test behavior. |
web/testing/testing.md |
Documents the global i18n mock and how to use @/test/i18n-mock, but currently overstates that it also provides useMixedTranslation/useGetLanguage and mis-documents useGetLanguage’s return format. |
web/test/i18n-mock.ts |
Adds shared i18n mock helpers (createTFunction, createUseTranslationMock, createTransMock, createReactI18nextMock) that reproduce the previous test behavior (namespace prefixing and parameter serialization) in a reusable way. |
web/app/components/plugins/plugin-mutation-model/index.spec.tsx |
Removes now-unnecessary local i18n/context mocks so the test focuses only on plugin-mutation modal behavior; relies on actual hooks/global config where applicable. |
web/app/components/plugins/plugin-detail-panel/subscription-list/edit/index.spec.tsx |
Drops redundant react-i18next mocking; tests now rely on global i18n and on local mocks only for plugin store, triggers, forms, and modal plumbing. |
web/app/components/plugins/plugin-detail-panel/subscription-list/create/oauth-client.spec.tsx |
Removes a custom useTranslation mock in favor of the global setup, while keeping detailed mocks for plugin store, trigger services, modal, and form behavior intact. |
web/app/components/plugins/plugin-detail-panel/subscription-list/create/common-modal.spec.tsx |
Similar cleanup of unused i18n mocking, leaving a rich set of mocks around subscription building, forms, toast, and modals. |
web/app/components/plugins/marketplace/index.spec.tsx |
Stops mocking react-i18next locally and adjusts the mocked getFixedT to match the new “namespace-prefixed key” contract; updates expectations in a few tests to match the new t-output. |
web/app/components/plugins/install-plugin/install-from-local-package/steps/uploading.spec.tsx |
Removes a detailed local useTranslation mock and relies on the global i18n mock; tests assert against keys / patterns compatible with the new global behavior. |
web/app/components/plugins/install-plugin/install-from-local-package/steps/install.spec.tsx |
Replaces a bespoke react-i18next mock with one based on createReactI18nextMock, while still overriding Trans locally to expose a data-testid for assertions. |
web/app/components/plugins/card/index.spec.tsx |
Drops local react-i18next, useMixedTranslation, and useGetLanguage mocks, relying on real hooks and mocked i18n-config/language; tests only assert on labels, icons, and structure, not on specific translation strings. |
web/app/components/datasets/documents/create-from-pipeline/processing/index.spec.tsx |
Removes a simple namespace-prefixing useTranslation mock so this test also uses the shared global i18n behavior. |
web/app/components/datasets/create/index.spec.tsx |
Similar removal of a local useTranslation mock, consolidating onto the global mock for translation behavior. |
web/app/components/billing/pricing/footer.spec.tsx |
Eliminates a per-test useTranslation mock and related mutable mockTranslations map, letting the global i18n mock supply “key-like” text; the test logic itself doesn’t depend on the specific translation values. |
web/app/components/base/input/index.spec.tsx |
Replaces inline useTranslation logic with createReactI18nextMock plus a small translation map for the specific keys the tests assert on. |
web/app/components/base/input-with-copy/index.spec.tsx |
Same pattern as Input tests: uses createReactI18nextMock to provide stable text for copy/copy-success states instead of an ad‑hoc mock. |
web/app/components/base/inline-delete-confirm/index.spec.tsx |
Uses createReactI18nextMock with a focused map for the delete confirmation copy, dropping the hand-written mock that encoded similar behavior. |
web/app/components/app/configuration/config/config-audio.spec.tsx |
Removes a local “namespace-prefix” useTranslation mock and defers to the global mock, which now encodes that behavior. |
web/app/components/app/configuration/config/agent-setting-button.spec.tsx |
Likewise removes a small local useTranslation mock, centralizing i18n mocking. |
.claude/skills/frontend-testing/references/mocking.md |
Updates the mocking reference to describe the new i18n helper and global behavior, but like web/testing/testing.md incorrectly claims global mocks exist for useMixedTranslation/useGetLanguage and misstates the useGetLanguage return format. |
.claude/skills/frontend-testing/assets/component-test.template.tsx |
Adjusts the component-test template’s comments to reference the global i18n mock and @/test/i18n-mock, but the commentary about what the global mock provides is slightly out of sync with vitest.setup.ts and useGetLanguage. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| - `useMixedTranslation` (from `@/app/components/plugins/marketplace/hooks`) | ||
| - `useGetLanguage` (from `@/context/i18n`) - returns `'en-US'` | ||
|
|
There was a problem hiding this comment.
These bullets say the global i18n mock provides useMixedTranslation and useGetLanguage returning 'en-US', but the codebase only has a global mock for react-i18next in web/vitest.setup.ts, and useGetLanguage actually returns a value like 'en_US' via getLanguage in web/context/i18n.ts. Please either introduce matching global mocks for @/app/components/plugins/marketplace/hooks and @/context/i18n or update this reference to reflect the real behavior (and correct the documented return value).
| - `useMixedTranslation` (from `@/app/components/plugins/marketplace/hooks`) | |
| - `useGetLanguage` (from `@/context/i18n`) - returns `'en-US'` | |
| Hooks like `useMixedTranslation` (from `@/app/components/plugins/marketplace/hooks`) and `useGetLanguage` (from `@/context/i18n`, which returns a locale like `'en_US'`) are **not** part of this global mock. If your tests depend on their behavior, mock those modules explicitly in the relevant test files. |
| // i18n (automatically mocked) | ||
| // WHY: Global mock in web/vitest.setup.ts is auto-loaded by Vitest setup | ||
| // No explicit mock needed - it returns translation keys as-is | ||
| // The global mock provides: useTranslation, Trans, useMixedTranslation, useGetLanguage | ||
| // No explicit mock needed for most tests | ||
| // | ||
| // Override only if custom translations are required: | ||
| // vi.mock('react-i18next', () => ({ | ||
| // useTranslation: () => ({ | ||
| // t: (key: string) => { | ||
| // const customTranslations: Record<string, string> = { | ||
| // 'my.custom.key': 'Custom Translation', | ||
| // } | ||
| // return customTranslations[key] || key | ||
| // }, | ||
| // }), | ||
| // import { createReactI18nextMock } from '@/test/i18n-mock' | ||
| // vi.mock('react-i18next', () => createReactI18nextMock({ | ||
| // 'my.custom.key': 'Custom Translation', | ||
| // 'button.save': 'Save', |
There was a problem hiding this comment.
This comment block states that the global mock in web/vitest.setup.ts provides useMixedTranslation and useGetLanguage, but vitest.setup.ts only mocks react-i18next and the real useGetLanguage returns values like 'en_US' (not 'en-US'). To keep the template accurate for new tests, either extend the global setup to mock these hooks as described, or simplify this comment to only mention the behaviors actually provided (and fix the noted return value format).
| - `useMixedTranslation` (from `@/app/components/plugins/marketplace/hooks`) | ||
| - `useGetLanguage` (from `@/context/i18n`) - returns `'en-US'` | ||
|
|
There was a problem hiding this comment.
This section claims the global i18n mock also provides useMixedTranslation and useGetLanguage returning 'en-US', but web/vitest.setup.ts only mocks react-i18next and the real useGetLanguage implementation in web/context/i18n.ts returns values like 'en_US' via getLanguage. To avoid misleading new tests, either extend the global setup to mock these hooks as described, or update this documentation to match the actual behavior and correct the noted return value format.
| - `useMixedTranslation` (from `@/app/components/plugins/marketplace/hooks`) | |
| - `useGetLanguage` (from `@/context/i18n`) - returns `'en-US'` | |
| Other i18n-related hooks use their real implementations: | |
| - `useMixedTranslation` (from `@/app/components/plugins/marketplace/hooks`) - **not** globally mocked | |
| - `useGetLanguage` (from `@/context/i18n`) - uses `getLanguage` and returns locale codes like `'en_US'` |
Benchmark PR from agentic-review-benchmarks#7