64 lines
1.8 KiB
TypeScript
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()
|
|
})
|
|
})
|