Files
SubTracker/apps/web/tests/unit/utils/subtracker-backup-client.test.ts
SmileQWQ dba8fb4cd0 test: stabilize lite locale-aware coverage
## 中文

- 为 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.
2026-06-01 01:59:49 +08:00

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')
)
})
})