import { tap, expect } from '@git.zone/tstest/tapbundle';
import { EInvoice } from '../../../ts/index.js';
import { PerformanceTracker } from '../performance.tracker.js';
import { FormatDetector } from '../../../ts/formats/utils/format.detector.js';
const performanceTracker = new PerformanceTracker('EDGE-08: Mixed Format Documents');
tap.test('EDGE-08: Mixed Format Documents - should handle documents with mixed or ambiguous formats', async () => {
console.log('Testing mixed format document handling...\n');
// Test 1: Invalid XML with mixed namespaces
const invalidMixedTest = await performanceTracker.measureAsync(
'invalid-mixed-xml',
async () => {
const invalidMixedXML = `
MIXED-001
MIXED-001
`;
try {
const format = FormatDetector.detectFormat(invalidMixedXML);
return {
detected: true,
format: format,
error: null
};
} catch (error) {
return {
detected: false,
format: null,
error: error.message
};
}
}
);
console.log(`Test 1 - Invalid mixed XML: ${invalidMixedTest.detected ? 'Handled' : 'Failed'}`);
if (invalidMixedTest.format) {
console.log(` Detected format: ${invalidMixedTest.format}`);
}
// Test 2: Valid UBL with unusual namespace declarations
const unusualNamespacesTest = await performanceTracker.measureAsync(
'unusual-namespaces',
async () => {
const unusualUBL = `
UNUSUAL-001
2024-01-15
380
EUR
Test Supplier
Test Street
Test City
12345
DE
Test Customer
Customer Street
Customer City
54321
DE
100.00
1
1
100.00
Test Item
`;
try {
const einvoice = new EInvoice();
await einvoice.loadXml(unusualUBL);
const exported = await einvoice.toXmlString('ubl');
return {
success: true,
invoiceId: einvoice.id,
hasValidStructure: exported.includes('Invoice'),
preservedData: exported.includes('UNUSUAL-001')
};
} catch (error) {
return {
success: false,
error: error.message
};
}
}
);
console.log(`\nTest 2 - Unusual namespaces: ${unusualNamespacesTest.success ? 'Success' : 'Failed'}`);
if (unusualNamespacesTest.success) {
console.log(` Invoice ID: ${unusualNamespacesTest.invoiceId}`);
console.log(` Valid structure: ${unusualNamespacesTest.hasValidStructure}`);
console.log(` Data preserved: ${unusualNamespacesTest.preservedData}`);
}
expect(unusualNamespacesTest.success).toEqual(true);
// Test 3: Malformed but recoverable XML
const malformedRecoverableTest = await performanceTracker.measureAsync(
'malformed-recoverable',
async () => {
const malformedXML = `
MALFORMED-001
2024-01-15
380
EUR
&
Test & Supplier
Test Street
Test City
12345
DE
Test Customer
Customer Street
Customer City
54321
DE
100.00
1
1
100.00
Test Item
`;
try {
const einvoice = new EInvoice();
await einvoice.loadXml(malformedXML);
return {
parsed: true,
invoiceId: einvoice.id,
supplierName: einvoice.from?.name,
preserved: einvoice.from?.name?.includes('&')
};
} catch (error) {
return {
parsed: false,
error: error.message
};
}
}
);
console.log(`\nTest 3 - Malformed but recoverable: ${malformedRecoverableTest.parsed ? 'Parsed' : 'Failed'}`);
if (malformedRecoverableTest.parsed) {
console.log(` Invoice ID: ${malformedRecoverableTest.invoiceId}`);
console.log(` Supplier name: ${malformedRecoverableTest.supplierName}`);
console.log(` Special chars preserved: ${malformedRecoverableTest.preserved}`);
}
// Test 4: Format detection edge cases
const formatDetectionTest = await performanceTracker.measureAsync(
'format-detection-edge',
async () => {
const testCases = [
{
name: 'Empty namespace',
xml: `TEST`
},
{
name: 'Wrong root element',
xml: `
TEST
`
},
{
name: 'Mixed case namespace',
xml: `
TEST
`
}
];
const results = [];
for (const testCase of testCases) {
try {
const format = FormatDetector.detectFormat(testCase.xml);
results.push({
name: testCase.name,
detected: true,
format: format
});
} catch (error) {
results.push({
name: testCase.name,
detected: false,
error: error.message
});
}
}
return results;
}
);
console.log('\nTest 4 - Format detection edge cases:');
formatDetectionTest.forEach(result => {
console.log(` ${result.name}: ${result.detected ? `Detected as ${result.format}` : 'Failed'}`);
});
// Test 5: Round-trip with format confusion
const roundTripTest = await performanceTracker.measureAsync(
'round-trip-confusion',
async () => {
try {
// Start with a simple invoice
const einvoice = new EInvoice();
einvoice.id = 'ROUNDTRIP-001';
einvoice.date = Date.now();
einvoice.currency = 'EUR';
einvoice.from = {
type: 'company',
name: 'Round Trip Supplier',
description: 'Test supplier',
address: {
streetName: 'Test Street',
houseNumber: '1',
postalCode: '12345',
city: 'Test City',
country: 'DE'
},
status: 'active',
registrationDetails: {
vatId: 'DE123456789',
registrationId: 'HRB 12345',
registrationName: 'Test Registry'
},
foundedDate: { year: 2020, month: 1, day: 1 }
};
einvoice.to = {
type: 'company',
name: 'Round Trip Customer',
description: 'Test customer',
address: {
streetName: 'Customer Street',
houseNumber: '2',
postalCode: '54321',
city: 'Customer City',
country: 'DE'
},
status: 'active',
registrationDetails: {
vatId: 'FR987654321',
registrationId: 'RCS 54321',
registrationName: 'Customer Registry'
},
foundedDate: { year: 2021, month: 6, day: 15 }
};
einvoice.items = [{
position: 1,
name: 'Test Product',
unitType: 'EA',
unitQuantity: 1,
unitNetPrice: 100,
vatPercentage: 19
}];
// Convert to UBL
const ublXml = await einvoice.toXmlString('ubl');
// Load it back
const reloaded = new EInvoice();
await reloaded.loadXml(ublXml);
// Convert to CII
const ciiXml = await reloaded.toXmlString('cii');
// Load it back again
const finalInvoice = new EInvoice();
await finalInvoice.loadXml(ciiXml);
return {
success: true,
originalId: einvoice.id,
finalId: finalInvoice.id,
preservedSupplier: finalInvoice.from?.name === einvoice.from?.name,
preservedCustomer: finalInvoice.to?.name === einvoice.to?.name,
itemCount: finalInvoice.items?.length
};
} catch (error) {
return {
success: false,
error: error.message
};
}
}
);
console.log(`\nTest 5 - Round-trip with format changes: ${roundTripTest.success ? 'Success' : 'Failed'}`);
if (roundTripTest.success) {
console.log(` ID preserved: ${roundTripTest.originalId === roundTripTest.finalId}`);
console.log(` Supplier preserved: ${roundTripTest.preservedSupplier}`);
console.log(` Customer preserved: ${roundTripTest.preservedCustomer}`);
console.log(` Items preserved: ${roundTripTest.itemCount} item(s)`);
}
expect(roundTripTest.success).toEqual(true);
// Print performance summary
console.log('\n' + performanceTracker.getSummary());
// Verify at least some tests succeeded
const successfulTests = [
unusualNamespacesTest.success,
roundTripTest.success
].filter(Boolean).length;
expect(successfulTests).toBeGreaterThan(0);
console.log(`\n✓ ${successfulTests} out of 5 edge case tests handled successfully`);
});
tap.start();