gongxiangp2/lib/__tests__/brand-knowledge-image-browser.test.ts
2026-09-16 11:27:06 +08:00

93 lines
3.4 KiB
TypeScript

import {
canUseBrandKnowledgeLegacyServerPreview,
prepareBrandKnowledgePreviewInBrowser,
} from '@/lib/brand-knowledge-image-browser'
import {
BRAND_KNOWLEDGE_PREVIEW_SINGLE_IMAGE_MAX_HEIGHT,
planBrandKnowledgePreviewSlices,
shouldSliceBrandKnowledgePreview,
} from '@/lib/performance-survey-image-source-guard'
const mockPreparePerformanceSurveyImagesInBrowser = jest.fn()
jest.mock('@/lib/performance-survey-image-browser', () => ({
preparePerformanceSurveyImagesInBrowser: (...args: unknown[]) => (
mockPreparePerformanceSurveyImagesInBrowser(...args)
),
}))
describe('brand knowledge preview browser processing', () => {
beforeEach(() => {
jest.clearAllMocks()
mockPreparePerformanceSurveyImagesInBrowser.mockResolvedValue([
{ file: new File(['one'], 'long-001.webp', { type: 'image/webp' }), kind: 'slice' },
{ file: new File(['two'], 'long-002.webp', { type: 'image/webp' }), kind: 'slice' },
])
})
test('uses 3000px as the inclusive single-image boundary', () => {
expect(BRAND_KNOWLEDGE_PREVIEW_SINGLE_IMAGE_MAX_HEIGHT).toBe(3_000)
expect(shouldSliceBrandKnowledgePreview(2_999)).toBe(false)
expect(shouldSliceBrandKnowledgePreview(3_000)).toBe(false)
expect(shouldSliceBrandKnowledgePreview(3_001)).toBe(true)
expect(planBrandKnowledgePreviewSlices(3_000, 1_200, 1_500)).toEqual({
sliceHeightLimit: 1_200,
sliceCount: 1,
})
expect(planBrandKnowledgePreviewSlices(3_001, 1_200, 1_500)).toEqual({
sliceHeightLimit: 600,
sliceCount: 2,
})
})
test('uses the dedicated 120MP brand profile and returns ordered slices', async () => {
const controller = new AbortController()
const source = new File(['image'], 'long.jpg', { type: 'image/jpeg' })
const result = await prepareBrandKnowledgePreviewInBrowser(source, undefined, {
signal: controller.signal,
timeoutMs: 12_345,
})
expect(result.map((item) => item.file.name)).toEqual(['long-001.webp', 'long-002.webp'])
expect(mockPreparePerformanceSurveyImagesInBrowser).toHaveBeenCalledWith(
[source],
undefined,
{
profile: 'brand_knowledge_preview',
signal: controller.signal,
timeoutMs: 12_345,
},
)
})
test('allows server fallback only when the image header is within 60 million pixels', async () => {
function pngFile(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 {
name: 'preview.png',
size: bytes.byteLength,
slice: () => ({ arrayBuffer: async () => bytes.buffer }),
} as unknown as File
}
await expect(canUseBrandKnowledgeLegacyServerPreview(pngFile(10_000, 6_000))).resolves.toBe(true)
await expect(canUseBrandKnowledgeLegacyServerPreview(pngFile(10_000, 6_001))).resolves.toBe(false)
})
test('rejects browser output that exceeds the derived preview byte limits', async () => {
mockPreparePerformanceSurveyImagesInBrowser.mockResolvedValue([{
file: { name: 'huge.webp', size: 10 * 1024 * 1024 + 1 },
kind: 'slice',
}])
await expect(prepareBrandKnowledgePreviewInBrowser(
new File(['image'], 'long.jpg', { type: 'image/jpeg' }),
)).rejects.toThrow('单个切片过大')
})
})