mirror of
https://github.com/langgenius/dify.git
synced 2026-05-04 17:38:04 +08:00
test: unify i18next mocks into centralized helpers (#30376)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: yyh <yuanyouhuilyz@gmail.com>
This commit is contained in:
79
web/test/i18n-mock.ts
Normal file
79
web/test/i18n-mock.ts
Normal file
@ -0,0 +1,79 @@
|
||||
import * as React from 'react'
|
||||
import { vi } from 'vitest'
|
||||
|
||||
type TranslationMap = Record<string, string | string[]>
|
||||
|
||||
/**
|
||||
* Create a t function with optional custom translations
|
||||
* Checks translations[key] first, then translations[ns.key], then returns ns.key as fallback
|
||||
*/
|
||||
export function createTFunction(translations: TranslationMap, defaultNs?: string) {
|
||||
return (key: string, options?: Record<string, unknown>) => {
|
||||
// Check custom translations first (without namespace)
|
||||
if (translations[key] !== undefined)
|
||||
return translations[key]
|
||||
|
||||
const ns = (options?.ns as string | undefined) ?? defaultNs
|
||||
const fullKey = ns ? `${ns}.${key}` : key
|
||||
|
||||
// Check custom translations with namespace
|
||||
if (translations[fullKey] !== undefined)
|
||||
return translations[fullKey]
|
||||
|
||||
// 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}`
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create useTranslation mock with optional custom translations
|
||||
*
|
||||
* @example
|
||||
* vi.mock('react-i18next', () => createUseTranslationMock({
|
||||
* 'operation.confirm': 'Confirm',
|
||||
* }))
|
||||
*/
|
||||
export function createUseTranslationMock(translations: TranslationMap = {}) {
|
||||
return {
|
||||
useTranslation: (defaultNs?: string) => ({
|
||||
t: createTFunction(translations, defaultNs),
|
||||
i18n: {
|
||||
language: 'en',
|
||||
changeLanguage: vi.fn(),
|
||||
},
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Trans component mock with optional custom translations
|
||||
*/
|
||||
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)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create complete react-i18next mock (useTranslation + Trans)
|
||||
*
|
||||
* @example
|
||||
* vi.mock('react-i18next', () => createReactI18nextMock({
|
||||
* 'modal.title': 'My Modal',
|
||||
* }))
|
||||
*/
|
||||
export function createReactI18nextMock(translations: TranslationMap = {}) {
|
||||
return {
|
||||
...createUseTranslationMock(translations),
|
||||
...createTransMock(translations),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user