import { expect, tap } from '@git.zone/tstest/tapbundle'; import { EInvoice } from '../../../ts/index.js'; tap.test('ENC-10: Cross-Format Encoding - should handle encoding across different invoice formats', async () => { console.log('Testing cross-format encoding consistency...\n'); // Test 1: UBL to CII encoding consistency const testUblToCiiEncoding = async () => { const einvoice = new EInvoice(); einvoice.id = 'CROSS-FORMAT-TEST'; einvoice.issueDate = new Date(2025, 0, 25); einvoice.subject = 'Cross-format test with special chars: éñüß'; einvoice.from = { type: 'company', name: 'Test Company éñüß', description: 'Testing cross-format encoding: €£¥', address: { streetName: 'Straße with ümlaut', houseNumber: '1', postalCode: '12345', city: 'München', country: 'DE' }, status: 'active', foundedDate: { year: 2020, month: 1, day: 1 }, registrationDetails: { vatId: 'DE123456789', registrationId: 'HRB 12345', registrationName: 'Commercial Register' } }; einvoice.to = { type: 'person', name: 'José', surname: 'Müller', salutation: 'Mr' as const, sex: 'male' as const, title: 'Doctor' as const, description: 'Customer with spëcial chars', address: { streetName: 'Côte d\'Azur', houseNumber: '2', postalCode: '54321', city: 'São Paulo', country: 'BR' } }; einvoice.items = [{ position: 1, name: 'Product with éñü symbols', articleNumber: 'CROSS-001', unitType: 'EA', unitQuantity: 1, unitNetPrice: 100, vatPercentage: 19 }]; try { // Export as UBL const ublXml = await einvoice.toXmlString('ubl'); // Export as CII const ciiXml = await einvoice.toXmlString('cii'); // Verify both formats preserve special characters const ublHasSpecialChars = ublXml.includes('éñüß') && ublXml.includes('München') && ublXml.includes('José'); const ciiHasSpecialChars = ciiXml.includes('éñüß') && ciiXml.includes('München') && ciiXml.includes('José'); // Test round-trip for both formats const ublInvoice = new EInvoice(); await ublInvoice.fromXmlString(ublXml); const ciiInvoice = new EInvoice(); await ciiInvoice.fromXmlString(ciiXml); const ublRoundTrip = ublInvoice.from?.name?.includes('éñüß') && ublInvoice.to?.name?.includes('José'); const ciiRoundTrip = ciiInvoice.from?.name?.includes('éñüß') && ciiInvoice.to?.name?.includes('José'); console.log(`Test 1 - UBL to CII encoding:`); console.log(` UBL preserves special chars: ${ublHasSpecialChars ? 'Yes' : 'No'}`); console.log(` CII preserves special chars: ${ciiHasSpecialChars ? 'Yes' : 'No'}`); console.log(` UBL round-trip successful: ${ublRoundTrip ? 'Yes' : 'No'}`); console.log(` CII round-trip successful: ${ciiRoundTrip ? 'Yes' : 'No'}`); return { ublHasSpecialChars, ciiHasSpecialChars, ublRoundTrip, ciiRoundTrip }; } catch (error) { console.log(`Test 1 - UBL to CII encoding:`); console.log(` Cross-format encoding failed: ${error.message}`); return { ublHasSpecialChars: false, ciiHasSpecialChars: false, ublRoundTrip: false, ciiRoundTrip: false }; } }; // Test 2: Different encoding declarations consistency const testEncodingDeclarations = async () => { const ublWithUnicodeXml = ` 2.1 ENCODING-CONSISTENCY-TEST 2025-01-25 EUR Ünîcödë Company €éñ 1 1 Product with spëcîãl chars `; try { // Parse UBL with Unicode content const ublInvoice = new EInvoice(); await ublInvoice.fromXmlString(ublWithUnicodeXml); // Convert to CII and back to UBL const ciiXml = await ublInvoice.toXmlString('cii'); const ublFromCii = new EInvoice(); await ublFromCii.fromXmlString(ciiXml); // Check if special characters survive format conversion const originalHasUnicode = ublInvoice.from?.name?.includes('Ünîcödë') && ublInvoice.from?.name?.includes('€éñ'); const ciiPreservesUnicode = ciiXml.includes('Ünîcödë') && ciiXml.includes('€éñ'); const roundTripPreservesUnicode = ublFromCii.from?.name?.includes('Ünîcödë') && ublFromCii.from?.name?.includes('€éñ'); console.log(`\nTest 2 - Encoding declaration consistency:`); console.log(` Original UBL has Unicode: ${originalHasUnicode ? 'Yes' : 'No'}`); console.log(` CII conversion preserves Unicode: ${ciiPreservesUnicode ? 'Yes' : 'No'}`); console.log(` Round-trip preserves Unicode: ${roundTripPreservesUnicode ? 'Yes' : 'No'}`); return { originalHasUnicode, ciiPreservesUnicode, roundTripPreservesUnicode }; } catch (error) { console.log(`\nTest 2 - Encoding declaration consistency:`); console.log(` Encoding consistency test failed: ${error.message}`); return { originalHasUnicode: false, ciiPreservesUnicode: false, roundTripPreservesUnicode: false }; } }; // Test 3: Mixed format documents const testMixedFormatSupport = async () => { try { const einvoice = new EInvoice(); einvoice.id = 'MIXED-FORMAT-TEST'; einvoice.issueDate = new Date(2025, 0, 25); einvoice.subject = 'Mixed format test'; einvoice.from = { type: 'company', name: 'Mixed Format Tëst Co.', description: 'Testing mixed formats with €áàâ', address: { streetName: 'Test Street', houseNumber: '1', postalCode: '12345', city: 'Test City', country: 'DE' }, status: 'active', foundedDate: { year: 2020, month: 1, day: 1 }, registrationDetails: { vatId: 'DE123456789', registrationId: 'HRB 12345', registrationName: 'Commercial Register' } }; einvoice.to = { type: 'person', name: 'Test', surname: 'Customer', salutation: 'Mr' as const, sex: 'male' as const, title: 'Doctor' as const, description: 'Test customer', address: { streetName: 'Customer Street', houseNumber: '2', postalCode: '54321', city: 'Customer City', country: 'DE' } }; einvoice.items = [{ position: 1, name: 'Test Product', articleNumber: 'MIXED-001', unitType: 'EA', unitQuantity: 1, unitNetPrice: 100, vatPercentage: 19 }]; // Test multiple format exports and verify encoding consistency const ublXml = await einvoice.toXmlString('ubl'); const ciiXml = await einvoice.toXmlString('cii'); // All formats should have proper UTF-8 encoding declaration const ublHasUtf8 = ublXml.includes('encoding="UTF-8"') || !ublXml.includes('encoding='); const ciiHasUtf8 = ciiXml.includes('encoding="UTF-8"') || !ciiXml.includes('encoding='); // Check if special characters are preserved across formats const ublPreservesChars = ublXml.includes('Tëst') && ublXml.includes('€áàâ'); const ciiPreservesChars = ciiXml.includes('Tëst') && ciiXml.includes('€áàâ'); console.log(`\nTest 3 - Mixed format support:`); console.log(` UBL has UTF-8 encoding: ${ublHasUtf8 ? 'Yes' : 'No'}`); console.log(` CII has UTF-8 encoding: ${ciiHasUtf8 ? 'Yes' : 'No'}`); console.log(` UBL preserves special chars: ${ublPreservesChars ? 'Yes' : 'No'}`); console.log(` CII preserves special chars: ${ciiPreservesChars ? 'Yes' : 'No'}`); return { ublHasUtf8, ciiHasUtf8, ublPreservesChars, ciiPreservesChars }; } catch (error) { console.log(`\nTest 3 - Mixed format support:`); console.log(` Mixed format test failed: ${error.message}`); return { ublHasUtf8: false, ciiHasUtf8: false, ublPreservesChars: false, ciiPreservesChars: false }; } }; // Test 4: Encoding header consistency const testEncodingHeaders = async () => { try { const einvoice = new EInvoice(); einvoice.id = 'HEADER-TEST'; einvoice.issueDate = new Date(2025, 0, 25); einvoice.subject = 'Encoding header test'; einvoice.from = { type: 'company', name: 'Header Test Company', description: 'Testing encoding headers', address: { streetName: 'Test Street', houseNumber: '1', postalCode: '12345', city: 'Test City', country: 'DE' }, status: 'active', foundedDate: { year: 2020, month: 1, day: 1 }, registrationDetails: { vatId: 'DE123456789', registrationId: 'HRB 12345', registrationName: 'Commercial Register' } }; einvoice.to = { type: 'person', name: 'Test', surname: 'Customer', salutation: 'Mr' as const, sex: 'male' as const, title: 'Doctor' as const, description: 'Test customer', address: { streetName: 'Customer Street', houseNumber: '2', postalCode: '54321', city: 'Customer City', country: 'DE' } }; einvoice.items = [{ position: 1, name: 'Test Product', articleNumber: 'HEADER-001', unitType: 'EA', unitQuantity: 1, unitNetPrice: 100, vatPercentage: 19 }]; // Generate both formats and check XML headers const ublXml = await einvoice.toXmlString('ubl'); const ciiXml = await einvoice.toXmlString('cii'); // Check if both start with proper XML declaration const ublHasXmlDecl = ublXml.startsWith('