| 1 | import { afterEach, describe, expect, it, vi } from 'vitest' |
| 2 | |
| 3 | const state = vi.hoisted(() => ({ |
| 4 | enqueueHtmlThumbnail: vi.fn(), |
| 5 | getFreshHtmlThumbnailPaths: vi.fn(), |
| 6 | enqueueHtmlThumbnails: vi.fn(), |
| 7 | waitForHtmlThumbnailTask: vi.fn() |
| 8 | })) |
| 9 | |
| 10 | vi.mock('../../../src/main/io/thumbnails/html-thumbnail-service', () => ({ |
| 11 | enqueueHtmlThumbnail: state.enqueueHtmlThumbnail, |
| 12 | getFreshHtmlThumbnailPaths: state.getFreshHtmlThumbnailPaths, |
| 13 | enqueueHtmlThumbnails: state.enqueueHtmlThumbnails, |
| 14 | waitForHtmlThumbnailTask: state.waitForHtmlThumbnailTask |
| 15 | })) |
| 16 | |
| 17 | describe('template cover thumbnails', () => { |
| 18 | afterEach(() => vi.clearAllMocks()) |
| 19 | |
| 20 | it('returns fresh covers and queues only missing templates', async () => { |
| 21 | state.getFreshHtmlThumbnailPaths.mockResolvedValue( |
| 22 | new Map([['template-1', '/cache/template-1.png']]) |
| 23 | ) |
| 24 | state.enqueueHtmlThumbnails.mockResolvedValue([]) |
| 25 | |
| 26 | const { warmTemplateCoverThumbnails } = |
| 27 | await import('../../../src/main/templates/template-thumbnail') |
| 28 | const result = await warmTemplateCoverThumbnails( |
| 29 | [ |
| 30 | { templateId: 'template-1', pageId: 'page-1', sourcePath: '/tmp/page-1.html' }, |
| 31 | { templateId: 'template-2', pageId: 'page-2', sourcePath: '/tmp/page-2.html' }, |
| 32 | { templateId: 'template-3', sourcePath: null } |
| 33 | ], |
| 34 | 250 |
| 35 | ) |
| 36 | |
| 37 | expect(result.get('template-1')).toBe('/cache/template-1.png') |
| 38 | expect(state.getFreshHtmlThumbnailPaths).toHaveBeenCalledWith([ |
| 39 | { |
| 40 | resourceType: 'template', |
| 41 | resourceId: 'template-1', |
| 42 | variant: 'cover', |
| 43 | sourcePath: '/tmp/page-1.html', |
| 44 | pageId: 'page-1', |
| 45 | captureWidth: undefined, |
| 46 | captureHeight: undefined, |
| 47 | thumbnailWidth: 640, |
| 48 | thumbnailHeight: undefined |
| 49 | }, |
| 50 | { |
| 51 | resourceType: 'template', |
| 52 | resourceId: 'template-2', |
| 53 | variant: 'cover', |
| 54 | sourcePath: '/tmp/page-2.html', |
| 55 | pageId: 'page-2', |
| 56 | captureWidth: undefined, |
| 57 | captureHeight: undefined, |
| 58 | thumbnailWidth: 640, |
| 59 | thumbnailHeight: undefined |
| 60 | } |
| 61 | ]) |
| 62 | expect(state.enqueueHtmlThumbnails).toHaveBeenCalledWith( |
| 63 | [ |
| 64 | { |
| 65 | resourceType: 'template', |
| 66 | resourceId: 'template-2', |
| 67 | variant: 'cover', |
| 68 | sourcePath: '/tmp/page-2.html', |
| 69 | pageId: 'page-2', |
| 70 | captureWidth: undefined, |
| 71 | captureHeight: undefined, |
| 72 | thumbnailWidth: 640, |
| 73 | thumbnailHeight: undefined |
| 74 | } |
| 75 | ], |
| 76 | { delayMs: 250 } |
| 77 | ) |
| 78 | }) |
| 79 | |
| 80 | it('waits for the imported template cover to finish', async () => { |
| 81 | state.enqueueHtmlThumbnail.mockResolvedValue({ |
| 82 | resourceType: 'template', |
| 83 | resourceId: 'template-1', |
| 84 | variant: 'cover', |
| 85 | status: 'queued', |
| 86 | thumbnailPath: null |
| 87 | }) |
| 88 | state.waitForHtmlThumbnailTask.mockResolvedValue({ |
| 89 | resourceType: 'template', |
| 90 | resourceId: 'template-1', |
| 91 | variant: 'cover', |
| 92 | status: 'completed', |
| 93 | thumbnailPath: '/cache/template-1.png' |
| 94 | }) |
| 95 | |
| 96 | const { captureTemplateCoverThumbnail } = |
| 97 | await import('../../../src/main/templates/template-thumbnail') |
| 98 | const result = await captureTemplateCoverThumbnail({ |
| 99 | templateId: 'template-1', |
| 100 | pageId: 'page-1', |
| 101 | sourcePath: '/tmp/page-1.html' |
| 102 | }) |
| 103 | |
| 104 | expect(result).toBe('/cache/template-1.png') |
| 105 | expect(state.waitForHtmlThumbnailTask).toHaveBeenCalledWith('template', 'template-1', 'cover') |
| 106 | }) |
| 107 | }) |
| 108 |