gongxiangp2/lib/__tests__/task-detail-preview-storage.test.ts

82 lines
2.8 KiB
TypeScript

/** @jest-environment node */
import { mkdtemp, readFile, rm } from 'fs/promises'
import os from 'os'
import path from 'path'
import { uploadPublicDisplayToS3 } from '@/lib/public-display'
import { saveTaskDetailPreview } from '@/lib/task-detail-preview-storage'
jest.mock('@/lib/public-display', () => ({
...jest.requireActual('@/lib/public-display'),
uploadPublicDisplayToS3: jest.fn(),
}))
describe('task-detail-preview-storage', () => {
beforeEach(() => {
jest.clearAllMocks()
})
test('公开预览仍沿用既有 public-display 路径', async () => {
const buffer = Buffer.from('public-preview')
;(uploadPublicDisplayToS3 as jest.Mock).mockResolvedValue(
'https://s3.example/public-display/task-detail/material-1/detail/cover.webp',
)
const result = await saveTaskDetailPreview(
buffer,
'material-1',
'detail',
'cover.webp',
false,
)
expect(result).toBe('https://s3.example/public-display/task-detail/material-1/detail/cover.webp')
expect(uploadPublicDisplayToS3).toHaveBeenCalledWith(
buffer,
'task-detail/material-1/detail/cover.webp',
'image/webp',
)
})
test('私密预览写入本地 uploads/materials 私有目录并返回相对存储路径', async () => {
const uploadRoot = await mkdtemp(path.join(os.tmpdir(), 'task-detail-preview-storage-'))
const previousUploadDir = process.env.UPLOAD_DIR
process.env.UPLOAD_DIR = uploadRoot
try {
const first = await saveTaskDetailPreview(
Buffer.from('private-preview-1'),
'material-1',
'detail',
'bad/../封面?.webp',
true,
)
const second = await saveTaskDetailPreview(
Buffer.from('private-preview-2'),
'material-1',
'detail',
'bad/../封面?.webp',
true,
)
expect(first).toMatch(/^uploads\/materials\/material-1\/private-previews\/detail\/.+\.webp$/)
expect(second).toMatch(/^uploads\/materials\/material-1\/private-previews\/detail\/.+\.webp$/)
expect(second).not.toBe(first)
expect(uploadPublicDisplayToS3).not.toHaveBeenCalled()
const firstAbsolutePath = path.join(uploadRoot, first.replace(/^uploads\//, '').replace(/\//g, path.sep))
const secondAbsolutePath = path.join(uploadRoot, second.replace(/^uploads\//, '').replace(/\//g, path.sep))
await expect(readFile(firstAbsolutePath)).resolves.toEqual(Buffer.from('private-preview-1'))
await expect(readFile(secondAbsolutePath)).resolves.toEqual(Buffer.from('private-preview-2'))
} finally {
if (previousUploadDir === undefined) {
delete process.env.UPLOAD_DIR
} else {
process.env.UPLOAD_DIR = previousUploadDir
}
await rm(uploadRoot, { recursive: true, force: true })
}
})
})