Skip to content

test: unify i18next mocks into centralized helpers#158

Open
tomerqodo wants to merge 5 commits intoqodo_claude_vs_qodo_base_test_unify_i18next_mocks_into_centralized_helpers_pr7from
qodo_claude_vs_qodo_head_test_unify_i18next_mocks_into_centralized_helpers_pr7
Open

test: unify i18next mocks into centralized helpers#158
tomerqodo wants to merge 5 commits intoqodo_claude_vs_qodo_base_test_unify_i18next_mocks_into_centralized_helpers_pr7from
qodo_claude_vs_qodo_head_test_unify_i18next_mocks_into_centralized_helpers_pr7

Conversation

@tomerqodo
Copy link
Copy Markdown

Benchmark PR from agentic-review-benchmarks#7

hyoban and others added 5 commits January 25, 2026 12:05
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.
@qodo-code-review
Copy link
Copy Markdown

Review Summary by Qodo

Consolidate i18next mocks into centralized helper functions

✨ Enhancement 🧪 Tests

Grey Divider

Walkthroughs

Description
• Create centralized i18n mock helpers in web/test/i18n-mock.ts
• Remove redundant mock implementations from 16 test files
• Update global mock in vitest.setup.ts to use helper functions
• Update documentation and templates with new mocking patterns
Diagram
flowchart LR
  A["Scattered i18next mocks<br/>in 16 test files"] -->|"Consolidate"| B["web/test/i18n-mock.ts<br/>Factory functions"]
  B -->|"Import & use"| C["vitest.setup.ts<br/>Global mock"]
  B -->|"Import & use"| D["Individual test files<br/>Custom translations"]
  E["Documentation<br/>& templates"] -->|"Update with<br/>new patterns"| F["Testing best practices"]
Loading

Grey Divider

File Changes

1. web/test/i18n-mock.ts ✨ Enhancement +79/-0

Create centralized i18n mock factory functions

web/test/i18n-mock.ts


2. web/vitest.setup.ts ✨ Enhancement +2/-18

Refactor global mock to use centralized helpers

web/vitest.setup.ts


3. .claude/skills/frontend-testing/assets/component-test.template.tsx 📝 Documentation +7/-10

Update template with new mocking recommendations

.claude/skills/frontend-testing/assets/component-test.template.tsx


View more (18)
4. .claude/skills/frontend-testing/references/mocking.md 📝 Documentation +17/-11

Document centralized mocking approach and best practices

.claude/skills/frontend-testing/references/mocking.md


5. web/app/components/app/configuration/config/agent-setting-button.spec.tsx 🧪 Tests +0/-9

Remove redundant i18next mock implementation

web/app/components/app/configuration/config/agent-setting-button.spec.tsx


6. web/app/components/app/configuration/config/config-audio.spec.tsx 🧪 Tests +0/-9

Remove redundant i18next mock implementation

web/app/components/app/configuration/config/config-audio.spec.tsx


7. web/app/components/base/inline-delete-confirm/index.spec.tsx 🧪 Tests +7/-19

Replace mock with centralized helper and custom translations

web/app/components/base/inline-delete-confirm/index.spec.tsx


8. web/app/components/base/input-with-copy/index.spec.tsx 🧪 Tests +7/-16

Replace mock with centralized helper and custom translations

web/app/components/base/input-with-copy/index.spec.tsx


9. web/app/components/base/input/index.spec.tsx 🧪 Tests +5/-14

Replace mock with centralized helper and custom translations

web/app/components/base/input/index.spec.tsx


10. web/app/components/billing/pricing/footer.spec.tsx 🧪 Tests +0/-18

Remove redundant i18next mock and state management

web/app/components/billing/pricing/footer.spec.tsx


11. web/app/components/datasets/create/index.spec.tsx 🧪 Tests +0/-10

Remove redundant i18next mock implementation

web/app/components/datasets/create/index.spec.tsx


12. web/app/components/datasets/documents/create-from-pipeline/processing/index.spec.tsx 🧪 Tests +0/-10

Remove redundant i18next mock implementation

web/app/components/datasets/documents/create-from-pipeline/processing/index.spec.tsx


13. web/app/components/plugins/card/index.spec.tsx 🧪 Tests +0/-27

Remove redundant i18next and related mocks

web/app/components/plugins/card/index.spec.tsx


14. web/app/components/plugins/install-plugin/install-from-local-package/steps/install.spec.tsx 🧪 Tests +14/-20

Refactor mock to use centralized helper with custom Trans

web/app/components/plugins/install-plugin/install-from-local-package/steps/install.spec.tsx


15. web/app/components/plugins/install-plugin/install-from-local-package/steps/uploading.spec.tsx 🧪 Tests +0/-15

Remove redundant i18next mock implementation

web/app/components/plugins/install-plugin/install-from-local-package/steps/uploading.spec.tsx


16. web/app/components/plugins/marketplace/index.spec.tsx 🧪 Tests +23/-23

Update mock and test expectations for namespace prefixing

web/app/components/plugins/marketplace/index.spec.tsx


17. web/app/components/plugins/plugin-detail-panel/subscription-list/create/common-modal.spec.tsx 🧪 Tests +0/-11

Remove redundant i18next mock implementation

web/app/components/plugins/plugin-detail-panel/subscription-list/create/common-modal.spec.tsx


18. web/app/components/plugins/plugin-detail-panel/subscription-list/create/oauth-client.spec.tsx 🧪 Tests +0/-11

Remove redundant i18next mock implementation

web/app/components/plugins/plugin-detail-panel/subscription-list/create/oauth-client.spec.tsx


19. web/app/components/plugins/plugin-detail-panel/subscription-list/edit/index.spec.tsx 🧪 Tests +0/-10

Remove redundant i18next mock implementation

web/app/components/plugins/plugin-detail-panel/subscription-list/edit/index.spec.tsx


20. web/app/components/plugins/plugin-mutation-model/index.spec.tsx 🧪 Tests +0/-22

Remove redundant i18next and related mocks

web/app/components/plugins/plugin-mutation-model/index.spec.tsx


21. web/testing/testing.md 📝 Documentation +17/-10

Update testing documentation with new mocking patterns

web/testing/testing.md


Grey Divider

Qodo Logo

@qodo-code-review
Copy link
Copy Markdown

qodo-code-review Bot commented Mar 10, 2026

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (1) 📎 Requirement gaps (0)

Grey Divider


Action required

1. TranslationMap uses interface 📘 Rule violation ✓ Correctness
Description
The new web/test/i18n-mock.ts introduces an interface declaration, but the standard requires
using type aliases instead of interface. This may cause ESLint ts/consistent-type-definitions
violations and breaks the repository’s TypeScript type-style consistency.
Code

web/test/i18n-mock.ts[4]

+interface TranslationMap extends Record<string, string | string[]> {}
Evidence
PR Compliance ID 9 requires TypeScript to use type aliases rather than interface. The added code
defines TranslationMap using interface, violating this requirement.

AGENTS.md
web/test/i18n-mock.ts[4-4]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The file `web/test/i18n-mock.ts` declares `TranslationMap` using an `interface`, but the repo standard requires `type` aliases instead of `interface`.

## Issue Context
This will violate the configured `ts/consistent-type-definitions` rule and breaks type declaration consistency.

## Fix Focus Areas
- web/test/i18n-mock.ts[4-4]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. returnObjects returns string 🐞 Bug ✓ Correctness
Description
createTFunction does not honor options.returnObjects, so components that call
t(...,{returnObjects:true}) will receive a string and can crash when treated as a string[]. This
affects any test relying on the global react-i18next mock and rendering such components.
Code

web/test/i18n-mock.ts[R10-28]

+export function createTFunction(translations: TranslationMap, defaultNs?: string) {
+  return (key: string, options?: Record<string, unknown>) => {
+    const ns = (options?.ns as string | undefined) ?? defaultNs
+    const fullKey = ns ? `${ns}.${key}` : key
+
+    // Check custom translations with namespace first
+    if (translations[fullKey] !== undefined)
+      return translations[fullKey]
+
+    // Check custom translations without namespace
+    if (translations[key] !== undefined)
+      return translations[key]
+
+    // Serialize params (excluding ns) for test assertions
+    const params = { ...options }
+    delete params.ns
+    const suffix = Object.keys(params).length > 0 ? `:${JSON.stringify(params)}` : ''
+    return `${fullKey}${suffix}`
+  }
Evidence
The global Vitest setup wires react-i18next to use createReactI18nextMock(), whose t implementation
is createTFunction and always falls back to returning a string (fullKey + optional JSON suffix).
Meanwhile, SelfHostedPlanItem/List explicitly calls t(...,{returnObjects:true}) and then immediately
calls features.map(...), which will throw if features is a string.

web/vitest.setup.ts[88-96]
web/test/i18n-mock.ts[10-28]
web/app/components/billing/pricing/plans/self-hosted-plan-item/list/index.tsx[13-27]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`web/test/i18n-mock.ts` implements the global `t()` mock used by Vitest. It currently ignores `options.returnObjects`, so calls like `t(key, { returnObjects: true })` return a string. Components that cast to `string[]` and call `.map()` will crash under the global mock.

### Issue Context
At least one production component (`SelfHostedPlanItem/List`) uses `returnObjects: true` to fetch an array of features from i18n.

### Fix Focus Areas
- web/test/i18n-mock.ts[10-28]
- web/vitest.setup.ts[88-96]
- web/app/components/billing/pricing/plans/self-hosted-plan-item/list/index.tsx[13-27]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Trans omits ns/components 🐞 Bug ✓ Correctness
Description
createTransMock ignores Trans props like ns and components, so <Trans ns=... components=.../> loses
namespace context and does not render injected elements. This reduces test fidelity and can break
tests that assert on Trans-rendered structure.
Code

web/test/i18n-mock.ts[R54-63]

+export function createTransMock(translations: TranslationMap = {}) {
+  return {
+    Trans: ({ i18nKey, children }: {
+      i18nKey: string
+      children?: React.ReactNode
+    }) => {
+      const text = translations[i18nKey] ?? i18nKey
+      return React.createElement('span', { 'data-i18n-key': i18nKey }, children ?? text)
+    },
+  }
Evidence
The global react-i18next mock exports Trans from createTransMock, which only accepts
i18nKey/children and renders the key. Production components pass ns and components to Trans (e.g.,
injecting a highlight span), which will be silently dropped by the mock.

web/test/i18n-mock.ts[54-63]
web/vitest.setup.ts[88-96]
web/app/components/billing/pricing/plans/self-hosted-plan-item/list/index.tsx[20-24]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The global `Trans` mock currently drops important props (`ns`, `components`, etc.). Components using `&lt;Trans ns=&quot;...&quot; components={{...}} /&gt;` will not render injected nodes under tests, which can hide UI regressions.

### Issue Context
Production code uses Trans with `ns` and `components` (e.g., highlight spans). The mock should preserve enough structure for assertions.

### Fix Focus Areas
- web/test/i18n-mock.ts[54-63]
- web/vitest.setup.ts[88-96]
- web/app/components/billing/pricing/plans/self-hosted-plan-item/list/index.tsx[20-24]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

Comment thread web/test/i18n-mock.ts
import * as React from 'react'
import { vi } from 'vitest'

interface TranslationMap extends Record<string, string | string[]> {}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. translationmap uses interface 📘 Rule violation ✓ Correctness

The new web/test/i18n-mock.ts introduces an interface declaration, but the standard requires
using type aliases instead of interface. This may cause ESLint ts/consistent-type-definitions
violations and breaks the repository’s TypeScript type-style consistency.
Agent Prompt
## Issue description
The file `web/test/i18n-mock.ts` declares `TranslationMap` using an `interface`, but the repo standard requires `type` aliases instead of `interface`.

## Issue Context
This will violate the configured `ts/consistent-type-definitions` rule and breaks type declaration consistency.

## Fix Focus Areas
- web/test/i18n-mock.ts[4-4]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread web/test/i18n-mock.ts
Comment on lines +10 to +28
export function createTFunction(translations: TranslationMap, defaultNs?: string) {
return (key: string, options?: Record<string, unknown>) => {
const ns = (options?.ns as string | undefined) ?? defaultNs
const fullKey = ns ? `${ns}.${key}` : key

// Check custom translations with namespace first
if (translations[fullKey] !== undefined)
return translations[fullKey]

// Check custom translations without namespace
if (translations[key] !== undefined)
return translations[key]

// Serialize params (excluding ns) for test assertions
const params = { ...options }
delete params.ns
const suffix = Object.keys(params).length > 0 ? `:${JSON.stringify(params)}` : ''
return `${fullKey}${suffix}`
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remediation recommended

2. Returnobjects returns string 🐞 Bug ✓ Correctness

createTFunction does not honor options.returnObjects, so components that call
t(...,{returnObjects:true}) will receive a string and can crash when treated as a string[]. This
affects any test relying on the global react-i18next mock and rendering such components.
Agent Prompt
### Issue description
`web/test/i18n-mock.ts` implements the global `t()` mock used by Vitest. It currently ignores `options.returnObjects`, so calls like `t(key, { returnObjects: true })` return a string. Components that cast to `string[]` and call `.map()` will crash under the global mock.

### Issue Context
At least one production component (`SelfHostedPlanItem/List`) uses `returnObjects: true` to fetch an array of features from i18n.

### Fix Focus Areas
- web/test/i18n-mock.ts[10-28]
- web/vitest.setup.ts[88-96]
- web/app/components/billing/pricing/plans/self-hosted-plan-item/list/index.tsx[13-27]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread web/test/i18n-mock.ts
Comment on lines +54 to +63
export function createTransMock(translations: TranslationMap = {}) {
return {
Trans: ({ i18nKey, children }: {
i18nKey: string
children?: React.ReactNode
}) => {
const text = translations[i18nKey] ?? i18nKey
return React.createElement('span', { 'data-i18n-key': i18nKey }, children ?? text)
},
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remediation recommended

3. Trans omits ns/components 🐞 Bug ✓ Correctness

createTransMock ignores Trans props like ns and components, so <Trans ns=... components=.../> loses
namespace context and does not render injected elements. This reduces test fidelity and can break
tests that assert on Trans-rendered structure.
Agent Prompt
### Issue description
The global `Trans` mock currently drops important props (`ns`, `components`, etc.). Components using `<Trans ns="..." components={{...}} />` will not render injected nodes under tests, which can hide UI regressions.

### Issue Context
Production code uses Trans with `ns` and `components` (e.g., highlight spans). The mock should preserve enough structure for assertions.

### Fix Focus Areas
- web/test/i18n-mock.ts[54-63]
- web/vitest.setup.ts[88-96]
- web/app/components/billing/pricing/plans/self-hosted-plan-item/list/index.tsx[20-24]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

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.

3 participants