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