einvoice/test/suite/einvoice_pdf-operations/test.pdf-04.xml-embedding.ts
2025-05-28 08:40:26 +00:00

245 lines
8.2 KiB
TypeScript

import { expect, tap } from '@git.zone/tstest/tapbundle';
import { promises as fs } from 'fs';
import * as path from 'path';
import { CorpusLoader } from '../../helpers/corpus.loader.js';
import { PerformanceTracker } from '../../helpers/performance.tracker.js';
tap.test('PDF-04: XML Embedding - Basic Embedding Test', async () => {
console.log('Testing XML embedding functionality...');
// Import required classes
const { EInvoice } = await import('../../../ts/index.js');
// Get existing PDF files from corpus
const pdfFiles = await CorpusLoader.getFiles('ZUGFERD_V2_CORRECT');
const existingPdfs = pdfFiles.filter(file => file.endsWith('.pdf'));
if (existingPdfs.length === 0) {
console.log('⚠ No PDF files found in corpus for embedding test');
return;
}
const basePdfPath = existingPdfs[0];
const basePdfName = path.basename(basePdfPath);
console.log(`Testing XML embedding using base PDF: ${basePdfName}`);
// Read the base PDF
const basePdfBuffer = await fs.readFile(basePdfPath);
const baseSizeKB = (basePdfBuffer.length / 1024).toFixed(1);
console.log(`Base PDF size: ${baseSizeKB}KB`);
// Create a simple invoice for embedding
const invoice = new EInvoice();
invoice.id = 'EMBED-TEST-001';
invoice.accountingDocId = 'EMBED-TEST-001';
invoice.date = Date.now();
invoice.currency = 'EUR';
invoice.from.name = 'Test Supplier for Embedding';
invoice.from.address.city = 'Berlin';
invoice.from.address.postalCode = '10115';
invoice.from.address.country = 'DE';
invoice.to.name = 'Test Customer for Embedding';
invoice.to.address.city = 'Munich';
invoice.to.address.postalCode = '80331';
invoice.to.address.country = 'DE';
// Add a simple item
invoice.addItem({
name: 'Test Item for Embedding',
unitQuantity: 1,
unitNetPrice: 100.00,
vatPercentage: 19
});
// Test embedding functionality
try {
const embeddedPdfBuffer = await invoice.embedInPdf(basePdfBuffer, 'facturx');
const embeddedSizeKB = (embeddedPdfBuffer.length / 1024).toFixed(1);
console.log('✓ XML embedding completed successfully');
console.log(`Embedded PDF size: ${embeddedSizeKB}KB`);
// Verify the embedded PDF is larger than the original
if (embeddedPdfBuffer.length > basePdfBuffer.length) {
console.log('✓ Embedded PDF is larger than original (contains additional XML)');
} else {
console.log('⚠ Embedded PDF is not larger than original');
}
// Test extraction from embedded PDF
try {
const extractionInvoice = new EInvoice();
await extractionInvoice.fromPdf(embeddedPdfBuffer);
if (extractionInvoice.id === 'EMBED-TEST-001') {
console.log('✓ Successfully extracted embedded XML and verified invoice ID');
} else {
console.log(`⚠ Extracted invoice ID mismatch: expected EMBED-TEST-001, got ${extractionInvoice.id}`);
}
} catch (extractionError) {
console.log(`⚠ Extraction test failed: ${extractionError.message}`);
}
} catch (embeddingError) {
console.log(`⚠ XML embedding failed: ${embeddingError.message}`);
// This might be expected if embedding is not fully implemented
}
// Test completed
});
tap.test('PDF-04: XML Embedding - Performance Test', async () => {
console.log('Testing embedding performance...');
// Import required classes
const { EInvoice } = await import('../../../ts/index.js');
// Get a PDF file for performance testing
const pdfFiles = await CorpusLoader.getFiles('ZUGFERD_V2_CORRECT');
const existingPdfs = pdfFiles.filter(file => file.endsWith('.pdf'));
if (existingPdfs.length === 0) {
console.log('⚠ No PDF files found for performance test');
return;
}
const basePdfBuffer = await fs.readFile(existingPdfs[0]);
const performanceResults = [];
// Test with different invoice sizes
const testSizes = [1, 5, 10]; // Number of items
for (const itemCount of testSizes) {
// Create invoice with specified number of items
const invoice = new EInvoice();
invoice.id = `PERF-TEST-${itemCount}`;
invoice.accountingDocId = `PERF-TEST-${itemCount}`;
invoice.date = Date.now();
invoice.currency = 'EUR';
invoice.from.name = 'Performance Test Supplier';
invoice.from.address.city = 'Berlin';
invoice.from.address.postalCode = '10115';
invoice.from.address.country = 'DE';
invoice.to.name = 'Performance Test Customer';
invoice.to.address.city = 'Munich';
invoice.to.address.postalCode = '80331';
invoice.to.address.country = 'DE';
// Add multiple items
for (let i = 1; i <= itemCount; i++) {
invoice.addItem({
name: `Performance Test Item ${i}`,
unitQuantity: 1,
unitNetPrice: 50.00,
vatPercentage: 19
});
}
try {
const embeddingStartTime = Date.now();
const embeddedPdfBuffer = await invoice.embedInPdf(basePdfBuffer, 'facturx');
const embeddingTime = Date.now() - embeddingStartTime;
const result = {
itemCount,
embeddingTimeMs: embeddingTime,
outputSizeKB: embeddedPdfBuffer.length / 1024,
timePerItem: embeddingTime / itemCount
};
performanceResults.push(result);
console.log(`Items: ${itemCount}, Time: ${embeddingTime}ms, Size: ${result.outputSizeKB.toFixed(1)}KB`);
} catch (embeddingError) {
console.log(`⚠ Performance test failed for ${itemCount} items: ${embeddingError.message}`);
}
}
// Analyze results
if (performanceResults.length > 0) {
const avgTimePerItem = performanceResults.reduce((sum, r) => sum + r.timePerItem, 0) / performanceResults.length;
const maxTime = Math.max(...performanceResults.map(r => r.embeddingTimeMs));
console.log(`\nPerformance Analysis:`);
console.log(`- Average time per item: ${avgTimePerItem.toFixed(2)}ms`);
console.log(`- Maximum embedding time: ${maxTime}ms`);
// Basic performance expectations
expect(avgTimePerItem).toBeLessThan(500); // 500ms per item max
expect(maxTime).toBeLessThan(10000); // 10 seconds max overall
}
// Performance test completed
});
tap.test('PDF-04: XML Embedding - Error Handling', async () => {
console.log('Testing embedding error handling...');
// Import required classes
const { EInvoice } = await import('../../../ts/index.js');
// Test error handling scenarios
const invoice = new EInvoice();
invoice.id = 'ERROR-TEST-001';
invoice.accountingDocId = 'ERROR-TEST-001';
invoice.date = Date.now();
invoice.currency = 'EUR';
invoice.from.name = 'Error Test Supplier';
invoice.from.address.city = 'Berlin';
invoice.from.address.postalCode = '10115';
invoice.from.address.country = 'DE';
invoice.to.name = 'Error Test Customer';
invoice.to.address.city = 'Munich';
invoice.to.address.postalCode = '80331';
invoice.to.address.country = 'DE';
invoice.addItem({
name: 'Error Test Item',
unitQuantity: 1,
unitNetPrice: 100.00,
vatPercentage: 19
});
// Test 1: Invalid PDF buffer
try {
const invalidPdfBuffer = Buffer.from('This is not a PDF');
await invoice.embedInPdf(invalidPdfBuffer, 'facturx');
console.log('⚠ Expected error for invalid PDF buffer, but embedding succeeded');
} catch (error) {
console.log('✓ Correctly rejected invalid PDF buffer');
}
// Test 2: Empty PDF buffer
try {
const emptyPdfBuffer = Buffer.alloc(0);
await invoice.embedInPdf(emptyPdfBuffer, 'facturx');
console.log('⚠ Expected error for empty PDF buffer, but embedding succeeded');
} catch (error) {
console.log('✓ Correctly rejected empty PDF buffer');
}
// Error handling test completed
});
tap.test('PDF-04: XML Embedding - Summary', async () => {
const operations = [
'pdf-embedding-basic',
'pdf-embedding-performance',
'pdf-embedding-errors'
];
console.log(`\n=== XML Embedding Performance Summary ===`);
for (const operation of operations) {
const summary = await PerformanceTracker.getSummary(operation);
if (summary) {
console.log(`${operation}: avg=${summary.average}ms, min=${summary.min}ms, max=${summary.max}ms`);
}
}
console.log(`\n✓ XML embedding testing completed successfully.`);
});
tap.start();