assets, move memories to proper location
This commit is contained in:
152
packages/report/src/pdf-generator.test.ts
Normal file
152
packages/report/src/pdf-generator.test.ts
Normal file
@@ -0,0 +1,152 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { pdfGenerator } from './pdf-generator';
|
||||
|
||||
const mockData = {
|
||||
exposureSummary: {
|
||||
totalExposures: 10,
|
||||
newExposures: 3,
|
||||
resolvedExposures: 2,
|
||||
criticalExposures: 1,
|
||||
warningExposures: 4,
|
||||
infoExposures: 5,
|
||||
exposuresBySource: {},
|
||||
},
|
||||
spamStats: {
|
||||
callsBlocked: 15,
|
||||
textsBlocked: 20,
|
||||
callsFlagged: 5,
|
||||
textsFlagged: 8,
|
||||
falsePositives: 2,
|
||||
totalSpamEvents: 35,
|
||||
},
|
||||
voiceStats: {
|
||||
analysesRun: 50,
|
||||
threatsDetected: 3,
|
||||
enrollmentsActive: 2,
|
||||
syntheticDetections: 3,
|
||||
voiceMismatchEvents: 3,
|
||||
},
|
||||
recommendations: [],
|
||||
protectionScore: 75,
|
||||
};
|
||||
|
||||
const pdfContext = {
|
||||
reportTitle: 'Monthly Protection Report — January 2025',
|
||||
periodStart: '2025-01-01T00:00:00.000Z',
|
||||
periodEnd: '2025-01-31T23:59:59.000Z',
|
||||
generatedAt: '2025-02-01T00:00:00.000Z',
|
||||
data: mockData,
|
||||
reportId: 'test-1',
|
||||
};
|
||||
|
||||
describe('PdfGenerator', () => {
|
||||
it('generates a non-empty PDF buffer', async () => {
|
||||
const pdf = await pdfGenerator.generate(pdfContext);
|
||||
expect(pdf).toBeInstanceOf(Buffer);
|
||||
expect(pdf.length).toBeGreaterThan(100);
|
||||
});
|
||||
|
||||
it('PDF starts with PDF magic bytes', async () => {
|
||||
const pdf = await pdfGenerator.generate(pdfContext);
|
||||
const header = pdf.subarray(0, 5).toString();
|
||||
expect(header).toBe('%PDF-');
|
||||
});
|
||||
|
||||
it('PDF ends with %%EOF', async () => {
|
||||
const pdf = await pdfGenerator.generate(pdfContext);
|
||||
const footer = pdf.subarray(-6).toString();
|
||||
expect(footer).toContain('%%EOF');
|
||||
});
|
||||
|
||||
it('PDF contains xref table', async () => {
|
||||
const pdf = await pdfGenerator.generate(pdfContext);
|
||||
const text = pdf.toString('utf8');
|
||||
expect(text).toContain('xref');
|
||||
expect(text).toContain('trailer');
|
||||
expect(text).toContain('startxref');
|
||||
});
|
||||
|
||||
it('PDF contains multiple pages', async () => {
|
||||
const pdf = await pdfGenerator.generate(pdfContext);
|
||||
const text = pdf.toString('utf8');
|
||||
// PDFKit creates multiple pages for our report
|
||||
expect(text).toContain('/Count 3');
|
||||
});
|
||||
|
||||
it('PDF registers both font families', async () => {
|
||||
const pdf = await pdfGenerator.generate(pdfContext);
|
||||
const text = pdf.toString('utf8');
|
||||
expect(text).toContain('Helvetica');
|
||||
expect(text).toContain('Helvetica-Bold');
|
||||
});
|
||||
|
||||
it('generates PDF with home title section (more content)', async () => {
|
||||
const basePdf = await pdfGenerator.generate(pdfContext);
|
||||
const premiumPdf = await pdfGenerator.generate({
|
||||
...pdfContext,
|
||||
data: {
|
||||
...mockData,
|
||||
homeTitleStats: {
|
||||
propertiesMonitored: 2,
|
||||
changesDetected: 1,
|
||||
alertsTriggered: 3,
|
||||
},
|
||||
},
|
||||
});
|
||||
// Premium report with extra section should be larger
|
||||
expect(premiumPdf.length).toBeGreaterThan(basePdf.length);
|
||||
});
|
||||
|
||||
it('generates PDF with recommendations (more content)', async () => {
|
||||
const basePdf = await pdfGenerator.generate(pdfContext);
|
||||
const withRecs = await pdfGenerator.generate({
|
||||
...pdfContext,
|
||||
data: {
|
||||
...mockData,
|
||||
recommendations: [
|
||||
{
|
||||
category: 'dark_web',
|
||||
priority: 'high',
|
||||
title: 'Address Critical Exposures',
|
||||
description: '1 critical exposure detected.',
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
// Report with recommendations should be larger
|
||||
expect(withRecs.length).toBeGreaterThan(basePdf.length);
|
||||
});
|
||||
|
||||
it('generates PDF with score change (more content)', async () => {
|
||||
const basePdf = await pdfGenerator.generate(pdfContext);
|
||||
const withChange = await pdfGenerator.generate({
|
||||
...pdfContext,
|
||||
data: {
|
||||
...mockData,
|
||||
protectionScore: 80,
|
||||
previousProtectionScore: 70,
|
||||
},
|
||||
});
|
||||
// Report with score change text should be larger
|
||||
expect(withChange.length).toBeGreaterThan(basePdf.length);
|
||||
});
|
||||
|
||||
it('generates valid PDF with all required sections', async () => {
|
||||
const pdf = await pdfGenerator.generate(pdfContext);
|
||||
const text = pdf.toString('utf8');
|
||||
// Structural validation
|
||||
expect(text).toContain('%PDF-');
|
||||
expect(text).toContain('/Type /Catalog');
|
||||
expect(text).toContain('/Type /Pages');
|
||||
expect(text).toContain('/Type /Page');
|
||||
expect(text).toContain('/ProcSet [/PDF /Text');
|
||||
});
|
||||
|
||||
it('handles empty recommendations gracefully', async () => {
|
||||
const pdf = await pdfGenerator.generate(pdfContext);
|
||||
expect(pdf).toBeInstanceOf(Buffer);
|
||||
expect(pdf.length).toBeGreaterThan(100);
|
||||
const header = pdf.subarray(0, 5).toString();
|
||||
expect(header).toBe('%PDF-');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user