working
This commit is contained in:
207
test/test.real-assets.ts
Normal file
207
test/test.real-assets.ts
Normal file
@ -0,0 +1,207 @@
|
||||
import { tap, expect } from '@push.rocks/tapbundle';
|
||||
import { XInvoice } from '../ts/classes.xinvoice.js';
|
||||
import { ValidationLevel, InvoiceFormat } from '../ts/interfaces/common.js';
|
||||
import * as fs from 'fs/promises';
|
||||
import * as path from 'path';
|
||||
|
||||
// Test loading and parsing real CII (Factur-X/ZUGFeRD) XML files
|
||||
tap.test('XInvoice should load and parse real CII XML files', async () => {
|
||||
// Test with a simple CII file
|
||||
const xmlPath = path.join(process.cwd(), 'test/assets/corpus/XML-Rechnung/CII/EN16931_Einfach.cii.xml');
|
||||
const xmlContent = await fs.readFile(xmlPath, 'utf8');
|
||||
|
||||
// Create XInvoice from XML
|
||||
const xinvoice = await XInvoice.fromXml(xmlContent);
|
||||
|
||||
// Check that the XInvoice instance has the expected properties
|
||||
expect(xinvoice).toBeTruthy();
|
||||
expect(xinvoice.from).toBeTruthy();
|
||||
expect(xinvoice.to).toBeTruthy();
|
||||
expect(xinvoice.items).toBeArray();
|
||||
|
||||
// Check that the format is detected correctly
|
||||
expect(xinvoice.getFormat()).toEqual(InvoiceFormat.FACTURX);
|
||||
|
||||
// Check that the invoice can be exported back to XML
|
||||
const exportedXml = await xinvoice.exportXml('facturx');
|
||||
expect(exportedXml).toBeTruthy();
|
||||
expect(exportedXml).toInclude('CrossIndustryInvoice');
|
||||
|
||||
// Save the exported XML for inspection
|
||||
const testDir = path.join(process.cwd(), 'test', 'output');
|
||||
await fs.mkdir(testDir, { recursive: true });
|
||||
await fs.writeFile(path.join(testDir, 'real-cii-exported.xml'), exportedXml);
|
||||
});
|
||||
|
||||
// Test loading and parsing real UBL (XRechnung) XML files
|
||||
tap.test('XInvoice should load and parse real UBL XML files', async () => {
|
||||
// Test with a simple UBL file
|
||||
const xmlPath = path.join(process.cwd(), 'test/assets/corpus/XML-Rechnung/UBL/EN16931_Einfach.ubl.xml');
|
||||
const xmlContent = await fs.readFile(xmlPath, 'utf8');
|
||||
|
||||
// Create XInvoice from XML
|
||||
const xinvoice = await XInvoice.fromXml(xmlContent);
|
||||
|
||||
// Check that the XInvoice instance has the expected properties
|
||||
expect(xinvoice).toBeTruthy();
|
||||
expect(xinvoice.from).toBeTruthy();
|
||||
expect(xinvoice.to).toBeTruthy();
|
||||
expect(xinvoice.items).toBeArray();
|
||||
|
||||
// Check that the format is detected correctly
|
||||
expect(xinvoice.getFormat()).toEqual(InvoiceFormat.XRECHNUNG);
|
||||
|
||||
// Check that the invoice can be exported back to XML
|
||||
const exportedXml = await xinvoice.exportXml('xrechnung');
|
||||
expect(exportedXml).toBeTruthy();
|
||||
expect(exportedXml).toInclude('Invoice');
|
||||
|
||||
// Save the exported XML for inspection
|
||||
const testDir = path.join(process.cwd(), 'test', 'output');
|
||||
await fs.mkdir(testDir, { recursive: true });
|
||||
await fs.writeFile(path.join(testDir, 'real-ubl-exported.xml'), exportedXml);
|
||||
});
|
||||
|
||||
// Test PDF creation and extraction with real XML files
|
||||
tap.test('XInvoice should create and parse PDFs with embedded XML', async () => {
|
||||
// Find a real CII XML file to use
|
||||
const xmlPath = path.join(process.cwd(), 'test/assets/corpus/XML-Rechnung/CII/EN16931_Einfach.cii.xml');
|
||||
const xmlContent = await fs.readFile(xmlPath, 'utf8');
|
||||
|
||||
// Create XInvoice from XML
|
||||
const xinvoice = await XInvoice.fromXml(xmlContent);
|
||||
|
||||
// Check that the XInvoice instance has the expected properties
|
||||
expect(xinvoice).toBeTruthy();
|
||||
expect(xinvoice.from).toBeTruthy();
|
||||
expect(xinvoice.to).toBeTruthy();
|
||||
expect(xinvoice.items).toBeArray();
|
||||
|
||||
// Create a simple PDF document
|
||||
const { PDFDocument } = await import('pdf-lib');
|
||||
const pdfDoc = await PDFDocument.create();
|
||||
const page = pdfDoc.addPage();
|
||||
page.drawText('Test PDF with embedded XML', { x: 50, y: 700 });
|
||||
const pdfBytes = await pdfDoc.save();
|
||||
|
||||
// Set the PDF buffer
|
||||
xinvoice.pdf = {
|
||||
name: 'test-invoice.pdf',
|
||||
id: `test-invoice-${Date.now()}`,
|
||||
metadata: {
|
||||
textExtraction: ''
|
||||
},
|
||||
buffer: pdfBytes
|
||||
};
|
||||
|
||||
// Export as PDF with embedded XML
|
||||
const exportedPdf = await xinvoice.exportPdf('facturx');
|
||||
expect(exportedPdf).toBeTruthy();
|
||||
expect(exportedPdf.buffer).toBeTruthy();
|
||||
|
||||
// Save the exported PDF for inspection
|
||||
const testDir = path.join(process.cwd(), 'test', 'output');
|
||||
await fs.mkdir(testDir, { recursive: true });
|
||||
await fs.writeFile(path.join(testDir, 'test-invoice-with-xml.pdf'), exportedPdf.buffer);
|
||||
|
||||
// Now try to load the PDF back
|
||||
const loadedXInvoice = await XInvoice.fromPdf(exportedPdf.buffer);
|
||||
|
||||
// Check that the loaded XInvoice has the expected properties
|
||||
expect(loadedXInvoice).toBeTruthy();
|
||||
expect(loadedXInvoice.from).toBeTruthy();
|
||||
expect(loadedXInvoice.to).toBeTruthy();
|
||||
expect(loadedXInvoice.items).toBeArray();
|
||||
|
||||
// Check that key properties are present
|
||||
expect(loadedXInvoice.id).toBeTruthy();
|
||||
expect(loadedXInvoice.from.name).toBeTruthy();
|
||||
expect(loadedXInvoice.to.name).toBeTruthy();
|
||||
|
||||
// Export the loaded invoice back to XML
|
||||
const reExportedXml = await loadedXInvoice.exportXml('facturx');
|
||||
expect(reExportedXml).toBeTruthy();
|
||||
expect(reExportedXml).toInclude('CrossIndustryInvoice');
|
||||
|
||||
// Save the re-exported XML for inspection
|
||||
await fs.writeFile(path.join(testDir, 'test-invoice-reextracted.xml'), reExportedXml);
|
||||
});
|
||||
|
||||
/**
|
||||
* Recursively finds all PDF files in a directory
|
||||
* @param dir Directory to search
|
||||
* @returns Array of PDF file paths
|
||||
*/
|
||||
async function findPdfFiles(dir: string): Promise<string[]> {
|
||||
const files = await fs.readdir(dir, { withFileTypes: true });
|
||||
|
||||
const pdfFiles: string[] = [];
|
||||
|
||||
for (const file of files) {
|
||||
const filePath = path.join(dir, file.name);
|
||||
|
||||
if (file.isDirectory()) {
|
||||
// Recursively search subdirectories
|
||||
const subDirFiles = await findPdfFiles(filePath);
|
||||
pdfFiles.push(...subDirFiles);
|
||||
} else if (file.name.toLowerCase().endsWith('.pdf')) {
|
||||
// Add PDF files to the list
|
||||
pdfFiles.push(filePath);
|
||||
}
|
||||
}
|
||||
|
||||
return pdfFiles;
|
||||
};
|
||||
|
||||
// Test validation of real invoice files
|
||||
tap.test('XInvoice should validate real invoice files', async () => {
|
||||
// Test with a simple CII file
|
||||
const xmlPath = path.join(process.cwd(), 'test/assets/corpus/XML-Rechnung/CII/EN16931_Einfach.cii.xml');
|
||||
const xmlContent = await fs.readFile(xmlPath, 'utf8');
|
||||
|
||||
// Create XInvoice from XML
|
||||
const xinvoice = await XInvoice.fromXml(xmlContent);
|
||||
|
||||
// Validate the XML
|
||||
const result = await xinvoice.validate(ValidationLevel.SYNTAX);
|
||||
|
||||
// Check that validation passed
|
||||
expect(result.valid).toBeTrue();
|
||||
expect(result.errors).toHaveLength(0);
|
||||
});
|
||||
|
||||
// Test with multiple real invoice files
|
||||
tap.test('XInvoice should handle multiple real invoice files', async () => {
|
||||
// Get all CII files
|
||||
const ciiDir = path.join(process.cwd(), 'test/assets/corpus/XML-Rechnung/CII');
|
||||
const ciiFiles = await fs.readdir(ciiDir);
|
||||
const xmlFiles = ciiFiles.filter(file => file.endsWith('.xml'));
|
||||
|
||||
// Test with a subset of files (to keep the test manageable)
|
||||
const testFiles = xmlFiles.slice(0, 5);
|
||||
|
||||
// Process each file
|
||||
for (const file of testFiles) {
|
||||
const xmlPath = path.join(ciiDir, file);
|
||||
const xmlContent = await fs.readFile(xmlPath, 'utf8');
|
||||
|
||||
// Create XInvoice from XML
|
||||
const xinvoice = await XInvoice.fromXml(xmlContent);
|
||||
|
||||
// Check that the XInvoice instance has the expected properties
|
||||
expect(xinvoice).toBeTruthy();
|
||||
expect(xinvoice.from).toBeTruthy();
|
||||
expect(xinvoice.to).toBeTruthy();
|
||||
|
||||
// Check that the format is detected correctly
|
||||
expect(xinvoice.getFormat()).toEqual(InvoiceFormat.FACTURX);
|
||||
|
||||
// Check that the invoice can be exported back to XML
|
||||
const exportedXml = await xinvoice.exportXml('facturx');
|
||||
expect(exportedXml).toBeTruthy();
|
||||
expect(exportedXml).toInclude('CrossIndustryInvoice');
|
||||
}
|
||||
});
|
||||
|
||||
// Run the tests
|
||||
tap.start();
|
Reference in New Issue
Block a user