mirror of
https://github.com/nexu-io/open-design.git
synced 2026-05-31 19:04:39 +07:00
104 lines
3.5 KiB
TypeScript
104 lines
3.5 KiB
TypeScript
import { mkdtempSync, rmSync } from 'node:fs';
|
|
import { mkdir, writeFile } from 'node:fs/promises';
|
|
import { tmpdir } from 'node:os';
|
|
import path from 'node:path';
|
|
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
|
|
import { buildDesktopPdfExportInput } from '../src/pdf-export.js';
|
|
import { startServer } from '../src/server.js';
|
|
|
|
describe('buildDesktopPdfExportInput', () => {
|
|
let projectsRoot = '';
|
|
const projectId = 'proj-pdf-test';
|
|
|
|
beforeEach(async () => {
|
|
projectsRoot = mkdtempSync(path.join(tmpdir(), 'od-pdf-export-'));
|
|
await mkdir(path.join(projectsRoot, projectId, 'deck', 'assets'), { recursive: true });
|
|
await writeFile(
|
|
path.join(projectsRoot, projectId, 'deck', 'index.html'),
|
|
'<!doctype html><section class="slide">One</section>',
|
|
);
|
|
});
|
|
|
|
afterEach(() => {
|
|
if (projectsRoot) rmSync(projectsRoot, { recursive: true, force: true });
|
|
});
|
|
|
|
it('reads the project file and derives a raw-route baseHref from the file directory', async () => {
|
|
const input = await buildDesktopPdfExportInput({
|
|
daemonUrl: 'http://127.0.0.1:7456',
|
|
deck: true,
|
|
fileName: 'deck/index.html',
|
|
projectId,
|
|
projectsRoot,
|
|
title: 'Seed Deck',
|
|
});
|
|
|
|
expect(input).toEqual({
|
|
baseHref: 'http://127.0.0.1:7456/api/projects/proj-pdf-test/raw/deck/',
|
|
deck: true,
|
|
defaultFilename: 'Seed-Deck.pdf',
|
|
html: '<!doctype html><section class="slide">One</section>',
|
|
title: 'Seed Deck',
|
|
});
|
|
});
|
|
|
|
it('falls back to the file basename when the caller omits a title', async () => {
|
|
const input = await buildDesktopPdfExportInput({
|
|
daemonUrl: 'http://127.0.0.1:7456',
|
|
deck: false,
|
|
fileName: 'deck/index.html',
|
|
projectId,
|
|
projectsRoot,
|
|
});
|
|
|
|
expect(input.title).toBe('index');
|
|
expect(input.defaultFilename).toBe('index.pdf');
|
|
});
|
|
});
|
|
|
|
describe('POST /api/projects/:id/export/pdf', () => {
|
|
it('forwards the project HTML file to the configured desktop PDF exporter', async () => {
|
|
const projectId = `proj-pdf-route-${Date.now()}`;
|
|
const calls: unknown[] = [];
|
|
const started = await startServer({
|
|
port: 0,
|
|
returnServer: true,
|
|
desktopPdfExporter: async (input: unknown) => {
|
|
calls.push(input);
|
|
return { ok: true, path: '/tmp/seed.pdf' };
|
|
},
|
|
}) as { server: { close(cb: () => void): void }; url: string };
|
|
|
|
try {
|
|
await fetch(`${started.url}/api/projects/${encodeURIComponent(projectId)}/files`, {
|
|
body: JSON.stringify({
|
|
content: '<!doctype html><section class="slide">One</section>',
|
|
name: 'deck/index.html',
|
|
}),
|
|
headers: { 'content-type': 'application/json' },
|
|
method: 'POST',
|
|
});
|
|
|
|
const response = await fetch(`${started.url}/api/projects/${encodeURIComponent(projectId)}/export/pdf`, {
|
|
body: JSON.stringify({ deck: true, fileName: 'deck/index.html', title: 'Seed Deck' }),
|
|
headers: { 'content-type': 'application/json' },
|
|
method: 'POST',
|
|
});
|
|
|
|
expect(response.status).toBe(200);
|
|
expect(await response.json()).toEqual({ ok: true, path: '/tmp/seed.pdf' });
|
|
expect(calls).toEqual([
|
|
{
|
|
baseHref: `${started.url}/api/projects/${encodeURIComponent(projectId)}/raw/deck/`,
|
|
deck: true,
|
|
defaultFilename: 'Seed-Deck.pdf',
|
|
html: '<!doctype html><section class="slide">One</section>',
|
|
title: 'Seed Deck',
|
|
},
|
|
]);
|
|
} finally {
|
|
await new Promise<void>((resolve) => started.server.close(resolve));
|
|
}
|
|
});
|
|
});
|