import { randomBytes } from 'node:crypto' import { mkdtemp, rm } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'node:path' import sharp from 'sharp' import { afterEach, describe, expect, it } from 'vitest' import { ScreenshotStorage, ScreenshotValidationError } from '../src/server/screenshot-storage.js' const directories: string[] = [] afterEach(async () => { await Promise.all( directories.splice(0).map((directory) => rm(directory, { recursive: true, force: true }) ) ) }) describe('ScreenshotStorage', () => { it('rejects decodable formats outside PNG, JPEG, and WebP', async () => { const directory = await mkdtemp( join(tmpdir(), 'product-issue-screenshot-') ) directories.push(directory) const storage = new ScreenshotStorage(directory, 64 * 1_024) await expect( storage.store( '00000000-0000-4000-8000-000000000000', Buffer.from( '' ) ) ).rejects.toBeInstanceOf(ScreenshotValidationError) }) it('rejects images whose normalized private asset exceeds the limit', async () => { const directory = await mkdtemp( join(tmpdir(), 'product-issue-screenshot-') ) directories.push(directory) const jpeg = await sharp(randomBytes(512 * 512 * 3), { raw: { width: 512, height: 512, channels: 3 } }) .jpeg({ quality: 1 }) .toBuffer() expect(jpeg.byteLength).toBeLessThan(64 * 1_024) const storage = new ScreenshotStorage(directory, 64 * 1_024) await expect( storage.store( '00000000-0000-4000-8000-000000000001', jpeg ) ).rejects.toBeInstanceOf(ScreenshotValidationError) }) })