Files
web-cad/frontend/tests/pdfLayoutExport.test.ts
T

100 lines
4.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Task G4 PDF-Export je Layout im Ausgabemaßstab.
*
* exportLayoutPDF rendert den Layout-Viewport (center/scale) auf eine A4-
* Seite (landscape), skaliert Weltkoordinaten in den Ausgabemaßstab,
* berücksichtigt Linienbreiten aus Layern (lineType) und unterstützt
* eine monochrome Option. Titelblock (frameBlockRef) wird mitgezeichnet.
* Rückgabe: PDF-Bytes, per PDFDocument.load verifizierbar.
*/
import { describe, it, expect } from 'vitest';
import { PDFDocument } from 'pdf-lib';
import { CADDocument } from '../src/kernel/document/CADDocument';
import { createInMemoryDoc } from './helpers/inMemoryDoc';
import { exportLayoutPDF } from '../src/services/pdfExport';
import type { CADElement, LayoutDefinition } from '../src/types/cad.types';
function line(id: string, x1: number, y1: number, x2: number, y2: number, layerId = 'layer-0'): CADElement {
return {
id, type: 'line', layerId,
x: Math.min(x1, x2), y: Math.min(y1, y2),
width: Math.abs(x2 - x1), height: Math.abs(y2 - y1),
properties: { x1, y1, x2, y2, stroke: '#ff0000' },
} as CADElement;
}
function mkDoc(els: CADElement[], layouts: LayoutDefinition[]): CADDocument {
const { ydoc } = createInMemoryDoc();
const doc = new CADDocument(ydoc);
for (const e of els) doc.addElement(e);
for (const l of layouts) doc.addLayout(l);
return doc;
}
const LAYOUT: LayoutDefinition = {
id: 'layout-1', name: 'A4 Plan',
viewport: { center: { x: 50, y: 50 }, scale: 1 },
};
describe('G4: exportLayoutPDF', () => {
it('liefert valides PDF mit genau einer A4-landscape-Seite', async () => {
const doc = mkDoc([line('l1', 0, 0, 100, 100)], [LAYOUT]);
const bytes = await exportLayoutPDF(doc, 'layout-1');
expect(bytes.byteLength).toBeGreaterThan(500);
const pdf = await PDFDocument.load(bytes);
expect(pdf.getPageCount()).toBe(1);
const { width, height } = pdf.getPage(0).getSize();
expect(width).toBe(842); // A4 landscape pt
expect(height).toBe(595);
});
it('Titelblock-Elemente (frameBlockRef) werden mitgezeichnet', async () => {
const doc = mkDoc([line('l1', 0, 0, 100, 0)], [LAYOUT]);
// Titelblock-Definition anlegen und referenzieren
const blockId = 'title-1';
doc.addBlock({
id: blockId, name: 'Titelblock', description: '', category: 'frame',
elements: [line('tb1', 0, 0, 50, 0)],
});
doc.updateLayout('layout-1', { frameBlockRef: blockId });
const bytes = await exportLayoutPDF(doc, 'layout-1');
const pdf = await PDFDocument.load(bytes);
expect(pdf.getPageCount()).toBe(1);
// Strukturelle Prüfung: Export läuft fehlerfrei mit Frame-Block
expect(bytes.byteLength).toBeGreaterThan(500);
});
it('monochrome Option exportiert ohne Farbinformationen zu verlieren', async () => {
const doc = mkDoc([line('l1', 0, 0, 100, 100)], [LAYOUT]);
const bytes = await exportLayoutPDF(doc, 'layout-1', { monochrome: true });
const pdf = await PDFDocument.load(bytes);
expect(pdf.getPageCount()).toBe(1);
});
it('leeres Layout (keine Elemente im Viewport) exportiert trotzdem eine Seite', async () => {
const doc = mkDoc([], [LAYOUT]);
const bytes = await exportLayoutPDF(doc, 'layout-1');
const pdf = await PDFDocument.load(bytes);
expect(pdf.getPageCount()).toBe(1);
});
it('Layout ohne existierende ID → throw', async () => {
const doc = mkDoc([], []);
await expect(exportLayoutPDF(doc, 'gibts-nicht')).rejects.toThrow();
});
it('unsichtbare Layer werden übersprungen (Export läuft fehlerfrei)', async () => {
const { ydoc } = createInMemoryDoc();
const doc = new CADDocument(ydoc);
ydoc.data.layers.set('layer-0', {
id: 'layer-0', name: '0', visible: false, locked: false,
color: '#ffffff', lineType: 'solid', transparency: 0, sortOrder: 0, parentId: null,
});
doc.addElement(line('l1', 0, 0, 100, 100));
doc.addLayout(LAYOUT);
const bytes = await exportLayoutPDF(doc, 'layout-1');
const pdf = await PDFDocument.load(bytes);
expect(pdf.getPageCount()).toBe(1);
});
});