gongxiangp2/lib/__tests__/client-download.test.ts
2026-03-06 14:14:50 +08:00

64 lines
1.8 KiB
TypeScript

import {
buildValidateDownloadUrl,
validateAndTriggerDownload,
} from '@/lib/client-download'
describe('client-download', () => {
beforeEach(() => {
jest.restoreAllMocks()
document.body.innerHTML = ''
})
test('buildValidateDownloadUrl 应在原 URL 上追加 validate=1', () => {
const url = '/api/materials/download?id=abc&type=all'
const result = buildValidateDownloadUrl(url)
expect(result).toBe('/api/materials/download?id=abc&type=all&validate=1')
})
test('validate 成功后应触发直连下载', async () => {
jest.useFakeTimers()
const fetchMock = jest.fn().mockResolvedValue({
ok: true,
json: async () => ({ success: true }),
})
global.fetch = fetchMock as any
const clickSpy = jest
.spyOn(HTMLAnchorElement.prototype, 'click')
.mockImplementation(() => {})
await validateAndTriggerDownload('/api/materials/download?id=mid-1')
expect(fetchMock).toHaveBeenCalledWith(
'/api/materials/download?id=mid-1&validate=1',
expect.objectContaining({
method: 'GET',
cache: 'no-store',
})
)
expect(clickSpy).toHaveBeenCalledTimes(1)
jest.runAllTimers()
jest.useRealTimers()
})
test('validate 失败时不应触发下载,并抛出后端错误', async () => {
const fetchMock = jest.fn().mockResolvedValue({
ok: false,
json: async () => ({ code: 'FORBIDDEN', error: '无权限下载该素材' }),
})
global.fetch = fetchMock as any
const clickSpy = jest
.spyOn(HTMLAnchorElement.prototype, 'click')
.mockImplementation(() => {})
await expect(
validateAndTriggerDownload('/api/materials/download?id=mid-2')
).rejects.toMatchObject({ code: 'FORBIDDEN' })
expect(clickSpy).not.toHaveBeenCalled()
})
})