| 1 | import fs from 'fs' |
| 2 | import path from 'path' |
| 3 | import { describe, expect, it } from 'vitest' |
| 4 | |
| 5 | const readSource = (filePath: string): string => fs.readFileSync(path.resolve(filePath), 'utf8') |
| 6 | |
| 7 | describe('generated page addition', () => { |
| 8 | it('creates a blank target page before generating its content', () => { |
| 9 | const dialogSource = readSource( |
| 10 | 'src/renderer/src/components/session-detail/modal/AddPageDialog.tsx' |
| 11 | ) |
| 12 | const addPageFlowSource = readSource('src/main/generation/add-page-flow.ts') |
| 13 | const blankPageServiceSource = readSource('src/main/session/page-management-service.ts') |
| 14 | |
| 15 | const createBlankPageIndex = dialogSource.indexOf( |
| 16 | 'ipc.createBlankSessionPage({ sessionId, sourcePageId })' |
| 17 | ) |
| 18 | const addPageIndex = dialogSource.indexOf('await ipc.addPage({') |
| 19 | |
| 20 | expect(createBlankPageIndex).toBeGreaterThan(-1) |
| 21 | expect(createBlankPageIndex).toBeLessThan(addPageIndex) |
| 22 | expect(dialogSource).toContain('targetPageId = blankPage.selectedPageId') |
| 23 | expect(dialogSource.indexOf('setAddingPageId(targetPageId)')).toBeGreaterThan( |
| 24 | createBlankPageIndex |
| 25 | ) |
| 26 | expect(dialogSource).toContain('targetPageId') |
| 27 | expect(addPageFlowSource).toContain('targetPageId?: string') |
| 28 | expect(addPageFlowSource).toContain('page.id === context.targetPageId') |
| 29 | expect(addPageFlowSource).toContain('page.id === targetPage.id ? newPageEntry : page') |
| 30 | expect(blankPageServiceSource).toContain('pages.slice(0, sourceIndex + 1)') |
| 31 | expect(blankPageServiceSource).toContain('pages.slice(sourceIndex + 1)') |
| 32 | }) |
| 33 | |
| 34 | it('hands generated page insertion and single-page retry to persistent jobs', () => { |
| 35 | const handlerSource = readSource('src/main/generation/handlers.ts') |
| 36 | const addPageHandler = handlerSource.slice( |
| 37 | handlerSource.indexOf("ipcMain.handle('generate:addPage'"), |
| 38 | handlerSource.indexOf("ipcMain.handle('generate:retrySinglePage'") |
| 39 | ) |
| 40 | const retrySinglePageHandler = handlerSource.slice( |
| 41 | handlerSource.indexOf("ipcMain.handle('generate:retrySinglePage'"), |
| 42 | handlerSource.indexOf("ipcMain.handle('generate:cancel'") |
| 43 | ) |
| 44 | const jobManagerSource = readSource('src/main/generation/job-manager.ts') |
| 45 | |
| 46 | expect(addPageHandler).toContain('jobManager.enqueue({') |
| 47 | expect(addPageHandler).toContain("kind: 'add-page'") |
| 48 | expect(addPageHandler).toContain("activityKind: 'addPage'") |
| 49 | expect(addPageHandler).toContain('targetPageId: targetPage?.id || addPageContext.targetPageId') |
| 50 | expect(retrySinglePageHandler).toContain('jobManager.enqueue({') |
| 51 | expect(retrySinglePageHandler).toContain("kind: 'single-page-retry'") |
| 52 | expect(retrySinglePageHandler).toContain("activityKind: 'single-page-retry'") |
| 53 | expect(retrySinglePageHandler).toContain('targetPageId: retryCtx.pageId') |
| 54 | expect(jobManagerSource).toContain("'add-page'") |
| 55 | expect(jobManagerSource).toContain("'single-page-retry'") |
| 56 | }) |
| 57 | |
| 58 | it('keeps placeholder state recoverable when a generated-page job fails to start or finish', () => { |
| 59 | const handlerSource = readSource('src/main/generation/handlers.ts') |
| 60 | const finalizationSource = readSource('src/main/generation/finalization.ts') |
| 61 | const dialogSource = readSource( |
| 62 | 'src/renderer/src/components/session-detail/modal/AddPageDialog.tsx' |
| 63 | ) |
| 64 | const sidebarControllerSource = readSource( |
| 65 | 'src/renderer/src/components/session-detail/sidebar/usePageSidebarController.ts' |
| 66 | ) |
| 67 | const previewStageSource = readSource( |
| 68 | 'src/renderer/src/components/session-detail/preview/PreviewStage.tsx' |
| 69 | ) |
| 70 | |
| 71 | expect(handlerSource).toContain("status: 'pending'") |
| 72 | expect(finalizationSource).toContain("context.effectiveMode === 'addPage'") |
| 73 | expect(finalizationSource).toContain("status: 'failed'") |
| 74 | expect(dialogSource).toContain('await loadSession(sessionId)') |
| 75 | expect(sidebarControllerSource).toContain('useGenerateStore.getState().addPage(page)') |
| 76 | expect(previewStageSource).toContain("selectedPage?.status === 'pending'") |
| 77 | }) |
| 78 | }) |
| 79 |