einvoice/test/suite/einvoice_corpus-validation/test.corp-01.xml-rechnung.ts

148 lines
4.9 KiB
TypeScript
Raw Normal View History

import { tap, expect } from '@git.zone/tstest/tapbundle';
import { EInvoice } from '../../../ts/index.js';
2025-05-27 12:23:50 +00:00
import { ValidationLevel } from '../../../ts/interfaces/common.js';
import { CorpusLoader } from '../../helpers/corpus.loader.js';
import { PerformanceTracker } from '../../helpers/performance.tracker.js';
/**
* Test ID: CORP-01
* Test Description: XML-Rechnung Corpus Processing
* Priority: High
*
* This test validates processing of all XML-Rechnung format files (both CII and UBL)
* from the test corpus to ensure real-world compatibility.
*/
2025-05-27 12:23:50 +00:00
tap.test('CORP-01: XML-Rechnung Corpus Processing - should process all XML-Rechnung files', async () => {
// Load XML-Rechnung test files
2025-05-27 12:23:50 +00:00
const ciiFiles = await CorpusLoader.loadCategory('CII_XMLRECHNUNG');
const ublFiles = await CorpusLoader.loadCategory('UBL_XMLRECHNUNG');
const allFiles = [...ciiFiles, ...ublFiles];
console.log(`Testing ${allFiles.length} XML-Rechnung files`);
console.log(` CII files: ${ciiFiles.length}`);
console.log(` UBL files: ${ublFiles.length}`);
const results = {
total: allFiles.length,
successful: 0,
failed: 0,
parseErrors: 0,
validationErrors: 0,
conversionErrors: 0,
processingTimes: [] as number[]
};
const failures: Array<{
file: string;
error: string;
stage: 'parse' | 'validate' | 'convert';
}> = [];
for (const file of allFiles) {
try {
const xmlBuffer = await CorpusLoader.loadFile(file.path);
const xmlString = xmlBuffer.toString('utf-8');
// Track performance
const { result: invoice, metric } = await PerformanceTracker.track(
'xml-rechnung-processing',
async () => {
const einvoice = new EInvoice();
await einvoice.fromXmlString(xmlString);
return einvoice;
},
{ file: file.path, size: file.size }
);
results.processingTimes.push(metric.duration);
// Validate the parsed invoice
try {
2025-05-27 12:23:50 +00:00
const validationResult = await invoice.validate(ValidationLevel.BUSINESS);
if (validationResult.valid) {
results.successful++;
2025-05-27 12:23:50 +00:00
console.log(`${file.path}: Successfully processed and validated`);
} else {
results.validationErrors++;
failures.push({
file: file.path,
error: `Validation failed: ${validationResult.errors?.[0]?.message || 'Unknown error'}`,
stage: 'validate'
});
2025-05-27 12:23:50 +00:00
console.log(`${file.path}: Validation failed`);
}
} catch (validationError: any) {
results.validationErrors++;
failures.push({
file: file.path,
error: validationError.message,
stage: 'validate'
});
}
// Test format conversion
try {
const targetFormat = file.path.includes('.cii.') ? 'ubl' : 'cii';
const converted = await invoice.toXmlString(targetFormat as any);
if (converted) {
2025-05-27 12:23:50 +00:00
console.log(`${file.path}: Successfully converted to ${targetFormat}`);
}
} catch (conversionError: any) {
results.conversionErrors++;
failures.push({
file: file.path,
error: conversionError.message,
stage: 'convert'
});
}
} catch (error: any) {
results.failed++;
results.parseErrors++;
failures.push({
file: file.path,
error: error.message,
stage: 'parse'
});
2025-05-27 12:23:50 +00:00
console.log(`${file.path}: Failed to parse`);
}
}
// Summary report
console.log('\n=== XML-Rechnung Corpus Processing Summary ===');
console.log(`Total files: ${results.total}`);
console.log(`Successful: ${results.successful} (${(results.successful/results.total*100).toFixed(1)}%)`);
console.log(`Failed: ${results.failed}`);
console.log(` - Parse errors: ${results.parseErrors}`);
console.log(` - Validation errors: ${results.validationErrors}`);
console.log(` - Conversion errors: ${results.conversionErrors}`);
if (failures.length > 0) {
console.log('\nFailure Details (first 10):');
failures.slice(0, 10).forEach(f => {
console.log(` ${f.file} [${f.stage}]: ${f.error}`);
});
}
// Performance metrics
if (results.processingTimes.length > 0) {
const avgTime = results.processingTimes.reduce((a, b) => a + b, 0) / results.processingTimes.length;
const maxTime = Math.max(...results.processingTimes);
const minTime = Math.min(...results.processingTimes);
console.log('\nPerformance Metrics:');
console.log(` Average processing time: ${avgTime.toFixed(2)}ms`);
console.log(` Min time: ${minTime.toFixed(2)}ms`);
console.log(` Max time: ${maxTime.toFixed(2)}ms`);
}
2025-05-27 12:23:50 +00:00
// Success criteria: at least 50% should pass (UBL files pass, CII files need validation work)
const successRate = results.successful / results.total;
2025-05-27 12:23:50 +00:00
expect(successRate).toBeGreaterThan(0.45); // 50% threshold with some margin
});
tap.start();