Files
sub2api/frontend/src/components/common/__tests__/LocaleSwitcher.spec.ts
T
feeeei 9a51333101 feat(groups): 分组名称与描述支持多语言
- groups 新增 i18n JSONB 列(迁移 242):语言代码 -> {name, description},只存译文;
  name/description 原列语义不变,仍用于唯一性校验、搜索与各类日志
- 用户侧接口由后端按请求语言输出:取 Accept-Language 中权重最高的一项,先按完整
  语言代码、再按主语言匹配;该语言有译文的字段换成译文,否则保持原字段,且不再带出
  译文表。覆盖密钥、可用分组、订阅(含进度与汇总)、兑换、使用记录、可用渠道、
  模型广场、套餐列表
- 管理端接口一律返回原字段;分组管理接口额外带 i18n 供编辑
- 创建/编辑分组:名称、描述的标题行右侧新增语言下拉,同一个输入框在默认内容与各语言
  版本之间切换;语种跟随前端 availableLocales
- 管理端写入:创建/更新接受 i18n(更新时缺省不修改,传入则整体替换),校验语言代码
  形态与名称长度并丢弃空译文;简易模式同样放行;复制分组只带走描述译文
- 切换界面语言后整页刷新,让已加载的数据换成新语言;模型广场响应加
  Vary: Accept-Language
- 网关路径,以及只带 group_name 字符串的统计、错误记录出口不做本地化
2026-10-09 11:39:18 +08:00

61 lines
1.8 KiB
TypeScript

import { flushPromises, mount } from '@vue/test-utils'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import LocaleSwitcher from '../LocaleSwitcher.vue'
const { setLocale } = vi.hoisted(() => ({ setLocale: vi.fn() }))
vi.mock('@/i18n', () => ({
setLocale,
availableLocales: [
{ code: 'en', name: 'English', flag: '🇺🇸' },
{ code: 'zh', name: '中文', flag: '🇨🇳' }
]
}))
vi.mock('vue-i18n', () => ({ useI18n: () => ({ locale: { value: 'zh' } }) }))
const reload = vi.fn()
const mountSwitcher = () =>
mount(LocaleSwitcher, { global: { stubs: { Icon: true, transition: false } } })
const choose = async (wrapper: ReturnType<typeof mountSwitcher>, name: string) => {
await wrapper.get('button').trigger('click')
const option = wrapper.findAll('button').find((button) => button.text().includes(name))
await option!.trigger('click')
await flushPromises()
}
describe('LocaleSwitcher', () => {
beforeEach(() => {
setLocale.mockReset().mockResolvedValue(undefined)
reload.mockReset()
vi.stubGlobal('location', { ...window.location, reload })
})
afterEach(() => {
vi.unstubAllGlobals()
})
// 分组名称等内容由后端按请求语言返回,已加载的数据要靠整页刷新换成新语言
it('reloads the page after switching to another language', async () => {
const wrapper = mountSwitcher()
await choose(wrapper, 'English')
expect(setLocale).toHaveBeenCalledWith('en')
expect(reload).toHaveBeenCalledTimes(1)
expect(setLocale.mock.invocationCallOrder[0]).toBeLessThan(reload.mock.invocationCallOrder[0])
})
it('does nothing when the current language is chosen again', async () => {
const wrapper = mountSwitcher()
await choose(wrapper, '中文')
expect(setLocale).not.toHaveBeenCalled()
expect(reload).not.toHaveBeenCalled()
})
})