import { assertPerformanceSurveyBrowserSourceImageDimensions, PERFORMANCE_SURVEY_BROWSER_SOURCE_LIMITS, readPerformanceSurveySourceImageDimensions, TASK_DETAIL_BROWSER_SOURCE_MAX_PIXELS, } from '@/lib/performance-survey-image-source-guard' function pngHeader(width: number, height: number) { const bytes = new Uint8Array(24) bytes.set([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]) const view = new DataView(bytes.buffer) view.setUint32(16, width) view.setUint32(20, height) return bytes } function jpegHeader(width: number, height: number) { return new Uint8Array([ 0xff, 0xd8, 0xff, 0xc0, 0x00, 0x11, 0x08, (height >> 8) & 0xff, height & 0xff, (width >> 8) & 0xff, width & 0xff, 0x03, 0x01, 0x11, 0x00, 0x02, 0x11, 0x00, 0x03, 0x11, 0x00, ]) } describe('performance survey browser source image guard', () => { test('在解码前读取 PNG 与 JPG 尺寸', () => { expect(readPerformanceSurveySourceImageDimensions(pngHeader(1200, 3200))).toEqual({ width: 1200, height: 3200 }) expect(readPerformanceSurveySourceImageDimensions(jpegHeader(1600, 4800))).toEqual({ width: 1600, height: 4800 }) }) test('拒绝超宽或超像素源图,不进入浏览器解码', () => { expect(() => assertPerformanceSurveyBrowserSourceImageDimensions( { width: PERFORMANCE_SURVEY_BROWSER_SOURCE_LIMITS.maxWidth + 1, height: 100 }, 'too-wide.png', )).toThrow('图片「too-wide.png」宽度超过 12000px') expect(() => assertPerformanceSurveyBrowserSourceImageDimensions( { width: 10000, height: 12001 }, 'too-many-pixels.png', )).toThrow('像素总量超过 120,000,000') }) test('保留 1600px 长图,并在解码前按最终切片数量限制超长图片', () => { expect(() => assertPerformanceSurveyBrowserSourceImageDimensions( { width: 1600, height: 75_000 }, 'long-design.png', )).not.toThrow() expect(() => assertPerformanceSurveyBrowserSourceImageDimensions( { width: 1, height: 90_001 }, 'too-tall.png', )).toThrow('处理后需要 61 张切片') }) test('任务详情像素门禁与服务器 Edge 兜底的 60M 限制一致', () => { const dimensions = { width: 10_000, height: 7_000 } expect(() => assertPerformanceSurveyBrowserSourceImageDimensions( dimensions, 'performance-survey.png', )).not.toThrow() expect(() => assertPerformanceSurveyBrowserSourceImageDimensions( dimensions, 'task-detail.png', { maxPixels: TASK_DETAIL_BROWSER_SOURCE_MAX_PIXELS }, )).toThrow('像素总量超过 60,000,000') }) })