59 lines
3.1 KiB
TypeScript
59 lines
3.1 KiB
TypeScript
/** @jest-environment node */
|
|
|
|
import { mkdtemp, readFile, rm, writeFile } from 'fs/promises'
|
|
import os from 'os'
|
|
import path from 'path'
|
|
import { existsSync } from 'fs'
|
|
import { prepareOperationsGMaterialFiles } from '@/lib/material-access-scope-storage'
|
|
import { downloadS3ObjectToFile } from '@/lib/s3'
|
|
import { resolveStoredUploadPath } from '@/lib/upload-paths'
|
|
|
|
jest.mock('@/lib/s3', () => ({ downloadS3ObjectToFile: jest.fn(), uploadToS3: jest.fn(), uploadFileToS3: jest.fn() }))
|
|
|
|
let root: string
|
|
const prior = { upload: process.env.UPLOAD_DIR, domain: process.env.S3_PUBLIC_DOMAIN, prefix: process.env.S3_FILE_PATH }
|
|
beforeEach(async () => {
|
|
root = await mkdtemp(path.join(os.tmpdir(), 'material-scope-storage-'))
|
|
process.env.UPLOAD_DIR = root
|
|
process.env.S3_PUBLIC_DOMAIN = 'https://storage.scope.local'
|
|
process.env.S3_FILE_PATH = 'scope'
|
|
jest.clearAllMocks()
|
|
;(downloadS3ObjectToFile as jest.Mock).mockImplementation(async (url: string, destination: string) => {
|
|
await writeFile(destination, Buffer.from(`object:${url}`))
|
|
})
|
|
})
|
|
afterEach(async () => {
|
|
for (const [key, value] of Object.entries({ UPLOAD_DIR: prior.upload, S3_PUBLIC_DOMAIN: prior.domain, S3_FILE_PATH: prior.prefix })) {
|
|
if (value === undefined) delete process.env[key]
|
|
else process.env[key] = value
|
|
}
|
|
expect(root.startsWith(path.join(os.tmpdir(), 'material-scope-storage-'))).toBe(true)
|
|
await rm(root, { recursive: true, force: true })
|
|
})
|
|
|
|
test('更改范围时复制公开原件与预览,素材、资产和 SKU 共享同一份受保护文件', async () => {
|
|
const preview = 'https://storage.scope.local/scope/preview.webp'
|
|
const source = 'https://storage.scope.local/scope/source.zip'
|
|
const result = await prepareOperationsGMaterialFiles({
|
|
id: 'material-1', previewUrl: preview, zipFilePath: source, zipFileName: 'source.zip', displayImages: [preview],
|
|
}, [{ id: 'asset-1', fileUrl: preview }], [{ id: 'sku-1', filePath: source, previewUrl: preview }])
|
|
expect(downloadS3ObjectToFile).toHaveBeenCalledTimes(2)
|
|
expect(result.assetFiles[0].fileUrl).toBe(result.materialFiles.previewUrl)
|
|
expect(result.skuFiles[0].previewUrl).toBe(result.materialFiles.previewUrl)
|
|
expect(result.skuFiles[0].filePath).toBe(result.materialFiles.zipFilePath)
|
|
expect(result.publicUrls).toEqual([preview, source])
|
|
const stored = result.materialFiles.previewUrl as string
|
|
expect(stored).toMatch(/^uploads\/materials\/material-1\/protected-display\//)
|
|
expect(await readFile(resolveStoredUploadPath(stored), 'utf8')).toBe(`object:${preview}`)
|
|
})
|
|
|
|
test('白底图的派生预览迁入可按原图定位的鉴权目录', async () => {
|
|
const result = await prepareOperationsGMaterialFiles({ id: 'material-1' }, [{
|
|
id: 'asset-1', fileUrl: 'uploads/materials/material-1/white-background/sku-1/front.webp',
|
|
}])
|
|
const expected = 'uploads/materials/material-1/protected-display/white-background/material-1/sku-1/front.webp'
|
|
expect(existsSync(resolveStoredUploadPath(expected))).toBe(true)
|
|
expect(result.publicUrls).toEqual(['https://storage.scope.local/scope/public-display/white-background/material-1/sku-1/front.webp'])
|
|
expect(result.assetFiles).toEqual([])
|
|
})
|