mirror of
https://github.com/Smile-QWQ/SubTracker.git
synced 2026-06-03 15:40:27 +08:00
## 中文 - 为 web 单测补上统一的测试语言初始化,避免每个用例重复手动设置 locale。 - 修复 lite Worker 中匿名读取 /api/v1/app/locale 会被鉴权拦截的问题,使新会话也能读取已持久化的语言设置。 - 同步补齐相关 API / Web 测试断言,并将换汇缺失汇率时的错误提示接入 i18n。 ## English - Add shared locale initialization for web tests so each case no longer has to set the locale manually. - Fix the lite Worker auth guard so anonymous GET /api/v1/app/locale can read the persisted locale in fresh sessions. - Update the related API and web assertions and localize the missing-rate currency conversion error.
89 lines
2.4 KiB
TypeScript
89 lines
2.4 KiB
TypeScript
import { getMessage } from '@subtracker/shared'
|
|
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
import { buildPreparedSubtrackerBackupPayload } from '@/utils/subtracker-backup-client'
|
|
import { getAppLocale } from '@/locales'
|
|
|
|
const { unzipSyncMock } = vi.hoisted(() => ({
|
|
unzipSyncMock: vi.fn<(bytes: Uint8Array) => Record<string, Uint8Array>>()
|
|
}))
|
|
|
|
vi.mock('fflate', async () => {
|
|
const actual = await vi.importActual<typeof import('fflate')>('fflate')
|
|
return {
|
|
...actual,
|
|
unzipSync: unzipSyncMock
|
|
}
|
|
})
|
|
|
|
function createFile(name = 'subtracker-backup.zip') {
|
|
return {
|
|
name,
|
|
async arrayBuffer() {
|
|
return Uint8Array.from([1, 2, 3]).buffer
|
|
}
|
|
} as unknown as File
|
|
}
|
|
|
|
describe('buildPreparedSubtrackerBackupPayload', () => {
|
|
beforeEach(() => {
|
|
unzipSyncMock.mockReset()
|
|
})
|
|
|
|
it('parses a valid backup zip into manifest and logo assets', async () => {
|
|
const manifest = {
|
|
schemaVersion: 1,
|
|
exportedAt: '2026-05-02T12:08:16Z',
|
|
app: 'SubTracker',
|
|
scope: 'business-complete',
|
|
data: {
|
|
settings: {},
|
|
notificationWebhook: {},
|
|
tags: [],
|
|
subscriptions: [],
|
|
paymentRecords: [],
|
|
subscriptionOrder: []
|
|
},
|
|
assets: {
|
|
logos: [
|
|
{
|
|
path: 'logos/test.png',
|
|
filename: 'test.png',
|
|
sourceLogoUrl: '/static/logos/test.png',
|
|
contentType: 'image/png',
|
|
referencedBySubscriptionIds: []
|
|
}
|
|
]
|
|
}
|
|
}
|
|
|
|
unzipSyncMock.mockReturnValue({
|
|
'manifest.json': new TextEncoder().encode(JSON.stringify(manifest)),
|
|
'logos/test.png': Uint8Array.from([137, 80, 78, 71])
|
|
})
|
|
|
|
const file = createFile()
|
|
|
|
const prepared = await buildPreparedSubtrackerBackupPayload(file)
|
|
|
|
expect((prepared.manifest as { app: string }).app).toBe('SubTracker')
|
|
expect(prepared.logoAssets).toHaveLength(1)
|
|
expect(prepared.logoAssets[0]).toMatchObject({
|
|
path: 'logos/test.png',
|
|
filename: 'test.png',
|
|
contentType: 'image/png'
|
|
})
|
|
})
|
|
|
|
it('throws a friendly error when manifest is missing', async () => {
|
|
unzipSyncMock.mockReturnValue({
|
|
'logos/test.png': Uint8Array.from([137, 80, 78, 71])
|
|
})
|
|
|
|
const file = createFile('broken.zip')
|
|
|
|
await expect(buildPreparedSubtrackerBackupPayload(file)).rejects.toThrow(
|
|
getMessage(getAppLocale(), 'api.errors.imports.subtrackerBackupMissingManifest')
|
|
)
|
|
})
|
|
})
|