/** @jest-environment node */ import { mkdtemp, mkdir, rm, writeFile } from 'fs/promises' import os from 'os' import path from 'path' import { validateCanonicalMaterialSource, } from '@/lib/material-canonical-source' describe('canonical 音乐/视频源文件完整性校验', () => { let uploadRoot = '' const previousUploadDir = process.env.UPLOAD_DIR beforeEach(async () => { uploadRoot = await mkdtemp(path.join(os.tmpdir(), 'canonical-material-source-')) process.env.UPLOAD_DIR = uploadRoot }) afterEach(async () => { if (previousUploadDir === undefined) { delete process.env.UPLOAD_DIR } else { process.env.UPLOAD_DIR = previousUploadDir } await rm(uploadRoot, { recursive: true, force: true }) }) test('受信根内的非空普通文件且实际大小一致时通过', async () => { const sourcePath = path.join(uploadRoot, 'video-source.mp4') const source = Buffer.from('canonical-video-source') await writeFile(sourcePath, source) await expect(validateCanonicalMaterialSource({ storedPath: sourcePath, expectedSize: BigInt(source.length), })).resolves.toEqual({ sourcePath, size: BigInt(source.length), }) }) test('stat 失败时拒绝提交', async () => { const missingPath = path.join(uploadRoot, 'missing-source.mp4') await expect(validateCanonicalMaterialSource({ storedPath: missingPath, expectedSize: BigInt(10), })).rejects.toMatchObject({ code: 'CANONICAL_SOURCE_STAT_FAILED', }) }) test('实际大小与已知 zipFileSize 不一致时拒绝提交', async () => { const sourcePath = path.join(uploadRoot, 'audio-source.mp3') await writeFile(sourcePath, Buffer.from('actual-audio')) await expect(validateCanonicalMaterialSource({ storedPath: sourcePath, expectedSize: BigInt(1), })).rejects.toMatchObject({ code: 'CANONICAL_SOURCE_SIZE_MISMATCH', }) }) test('目录和受信根外路径不能伪装成 canonical 普通文件', async () => { const directoryPath = path.join(uploadRoot, 'not-a-file') await mkdir(directoryPath) await expect(validateCanonicalMaterialSource({ storedPath: directoryPath, expectedSize: BigInt(1), })).rejects.toMatchObject({ code: 'CANONICAL_SOURCE_NOT_REGULAR', }) const outsidePath = path.join(path.dirname(uploadRoot), 'outside-source.mp4') await writeFile(outsidePath, Buffer.from('outside')) try { await expect(validateCanonicalMaterialSource({ storedPath: outsidePath, expectedSize: BigInt(7), })).rejects.toMatchObject({ code: 'CANONICAL_SOURCE_PATH_UNTRUSTED', }) } finally { await rm(outsidePath, { force: true }) } }) })