20260917212907
This commit is contained in:
1 parent
6fa3d8535e
commit
5cbf745bbf
115 files changed
+4104
-85
No files matched your search
@@ -0,0 +1,109 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { createTestPinia } from '../helpers/app'
|
||||
import { useI18nStore } from '@/stores/i18n'
|
||||
import { BUILTIN_MESSAGES } from '@/i18n/builtin-messages'
|
||||
|
||||
const loadDataApi = vi.fn()
|
||||
|
||||
vi.mock('@/services/api', () => ({
|
||||
loadDataApi: (...args) => loadDataApi(...args),
|
||||
}))
|
||||
|
||||
/** 按 s_i18n 行结构构造返回值 */
|
||||
function rows(locale, entries) {
|
||||
return {
|
||||
data: entries.map(([b_key, b_value]) => ({ b_key, b_locale: locale, b_value, b_canuse: 1 })),
|
||||
}
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
loadDataApi.mockReset()
|
||||
createTestPinia()
|
||||
const i18n = useI18nStore()
|
||||
i18n.setLocale('zh-CN')
|
||||
i18n.clearMessages()
|
||||
})
|
||||
|
||||
describe('i18n store · 译文加载(s_i18n)', () => {
|
||||
it('加载当前语言译文并写入运行时(t 生效)', async () => {
|
||||
loadDataApi.mockResolvedValue(rows('zh-CN', [['field.x.b_name', '客户名称']]))
|
||||
const i18n = useI18nStore()
|
||||
|
||||
await i18n.loadMessages()
|
||||
|
||||
expect(loadDataApi).toHaveBeenCalledTimes(1)
|
||||
const [viewName, condition] = loadDataApi.mock.calls[0]
|
||||
expect(viewName).toBe('s_i18n')
|
||||
expect(condition).toContain("b_locale = N'zh-CN'")
|
||||
expect(condition).toContain('b_canuse = 1')
|
||||
expect(i18n.t('field.x.b_name', '名称')).toBe('客户名称')
|
||||
})
|
||||
|
||||
it('英文模式:内置 UI 文案兜底,库表译文覆盖同名 key', async () => {
|
||||
loadDataApi.mockResolvedValue(rows('en-US', [['common.cancel', 'Cancel!!']]))
|
||||
const i18n = useI18nStore()
|
||||
i18n.setLocale('en-US')
|
||||
|
||||
await i18n.loadMessages()
|
||||
|
||||
// 库里有的以库为准
|
||||
expect(i18n.t('common.cancel', '取消')).toBe('Cancel!!')
|
||||
// 库里没有的走前端内置英文
|
||||
expect(i18n.t('common.applyQuery', '应用')).toBe(BUILTIN_MESSAGES['en-US']['common.applyQuery'])
|
||||
expect(i18n.t('common.applyQuery', '应用')).toBe('Apply')
|
||||
})
|
||||
|
||||
it('切换语言后重新加载,且缓存命中不再发请求', async () => {
|
||||
loadDataApi.mockResolvedValue(rows('zh-CN', [['k', '中文']]))
|
||||
const i18n = useI18nStore()
|
||||
await i18n.loadMessages()
|
||||
expect(loadDataApi).toHaveBeenCalledTimes(1)
|
||||
|
||||
// 切到英文:新语言未缓存 → 发请求
|
||||
loadDataApi.mockResolvedValue(rows('en-US', [['k', 'EN']]))
|
||||
i18n.setLocale('en-US')
|
||||
await i18n.loadMessages('en-US')
|
||||
expect(loadDataApi).toHaveBeenCalledTimes(2)
|
||||
expect(i18n.t('k', 'x')).toBe('EN')
|
||||
|
||||
// 切回中文:命中缓存 → 不再请求,但译文要切回来
|
||||
i18n.setLocale('zh-CN')
|
||||
await i18n.loadMessages()
|
||||
expect(loadDataApi).toHaveBeenCalledTimes(2)
|
||||
expect(i18n.t('k', 'x')).toBe('中文')
|
||||
})
|
||||
|
||||
it('并发同语言只发一个请求', async () => {
|
||||
loadDataApi.mockResolvedValue(rows('zh-CN', [['k', 'v']]))
|
||||
const i18n = useI18nStore()
|
||||
await Promise.all([i18n.loadMessages(), i18n.loadMessages(), i18n.loadMessages()])
|
||||
expect(loadDataApi).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('接口失败不抛出,界面回落兜底文案', async () => {
|
||||
loadDataApi.mockRejectedValue(new Error('boom'))
|
||||
const i18n = useI18nStore()
|
||||
await expect(i18n.loadMessages()).resolves.toEqual({})
|
||||
expect(i18n.t('common.cancel', '取消')).toBe('取消')
|
||||
expect(i18n.error).toBe('boom')
|
||||
})
|
||||
|
||||
it('b_locale 走转义,单引号不会拼坏 SQL', async () => {
|
||||
loadDataApi.mockResolvedValue({ data: [] })
|
||||
const i18n = useI18nStore()
|
||||
await i18n.loadMessages("zh'; drop table s_i18n --")
|
||||
expect(loadDataApi.mock.calls[0][1]).toContain("N'zh''; drop table s_i18n --'")
|
||||
})
|
||||
|
||||
it('请求回来时语言已被切走则不覆盖当前译文', async () => {
|
||||
let resolveQuery
|
||||
loadDataApi.mockReturnValue(new Promise((r) => (resolveQuery = r)))
|
||||
const i18n = useI18nStore()
|
||||
const pending = i18n.loadMessages()
|
||||
i18n.setLocale('en-US')
|
||||
resolveQuery({ data: [{ b_key: 'k', b_value: '中文值' }] })
|
||||
await pending
|
||||
// 当前是英文,中文译文不应写进运行时(英文下 k 无译文 → 回落 fallback)
|
||||
expect(i18n.t('k', 'fallback')).toBe('fallback')
|
||||
})
|
||||
})
|
||||
Reference in new issue
Block a user