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();