import { tap, expect } from '@push.rocks/tapbundle'; import { XInvoice } from '../ts/classes.xinvoice.js'; import { ValidationLevel } from '../ts/interfaces/common.js'; import type { ExportFormat } from '../ts/interfaces/common.js'; // Basic XInvoice tests tap.test('XInvoice should have the correct default properties', async () => { const xinvoice = new XInvoice(); expect(xinvoice.type).toEqual('invoice'); expect(xinvoice.invoiceType).toEqual('debitnote'); expect(xinvoice.status).toEqual('invoice'); expect(xinvoice.from).toBeTruthy(); expect(xinvoice.to).toBeTruthy(); expect(xinvoice.items).toBeArray(); expect(xinvoice.currency).toEqual('EUR'); }); // Test XML export functionality tap.test('XInvoice should export XML in the correct format', async () => { const xinvoice = new XInvoice(); xinvoice.id = 'TEST-XML-EXPORT'; xinvoice.invoiceId = 'TEST-XML-EXPORT'; xinvoice.from.name = 'Test Seller'; xinvoice.to.name = 'Test Buyer'; // Add an item xinvoice.items.push({ position: 1, name: 'Test Product', articleNumber: 'TP-001', unitType: 'EA', unitQuantity: 2, unitNetPrice: 100, vatPercentage: 19 }); // Export as Factur-X const xml = await xinvoice.exportXml('facturx'); // Check that the XML contains the expected elements expect(xml).toInclude('CrossIndustryInvoice'); expect(xml).toInclude('TEST-XML-EXPORT'); expect(xml).toInclude('Test Seller'); expect(xml).toInclude('Test Buyer'); expect(xml).toInclude('Test Product'); }); // Test XML loading functionality tap.test('XInvoice should load XML correctly', async () => { // Create a sample XML string const sampleXml = ` urn:cen.eu:en16931:2017 TEST-XML-LOAD 380 20230101 XML Seller Seller Street 123 12345 Seller City DE XML Buyer Buyer Street 456 54321 Buyer City DE EUR `; // Create XInvoice from XML const xinvoice = await XInvoice.fromXml(sampleXml); // Check that the XInvoice instance has the expected properties expect(xinvoice.id).toEqual('TEST-XML-LOAD'); expect(xinvoice.from.name).toEqual('XML Seller'); expect(xinvoice.to.name).toEqual('XML Buyer'); expect(xinvoice.currency).toEqual('EUR'); }); // Test circular encoding/decoding tap.test('XInvoice should maintain data integrity through export/import cycle', async () => { // Create a sample invoice const originalInvoice = new XInvoice(); originalInvoice.id = 'TEST-CIRCULAR'; originalInvoice.invoiceId = 'TEST-CIRCULAR'; originalInvoice.from.name = 'Circular Seller'; originalInvoice.to.name = 'Circular Buyer'; // Add an item originalInvoice.items.push({ position: 1, name: 'Circular Product', articleNumber: 'CP-001', unitType: 'EA', unitQuantity: 3, unitNetPrice: 150, vatPercentage: 19 }); // Export as Factur-X const xml = await originalInvoice.exportXml('facturx'); // Create a new XInvoice from the XML const importedInvoice = await XInvoice.fromXml(xml); // Check that key properties match expect(importedInvoice.id).toEqual(originalInvoice.id); expect(importedInvoice.from.name).toEqual(originalInvoice.from.name); expect(importedInvoice.to.name).toEqual(originalInvoice.to.name); // Check that items match expect(importedInvoice.items).toHaveLength(1); expect(importedInvoice.items[0].name).toEqual('Circular Product'); expect(importedInvoice.items[0].unitQuantity).toEqual(3); expect(importedInvoice.items[0].unitNetPrice).toEqual(150); }); // Test validation tap.test('XInvoice should validate XML correctly', async () => { const xinvoice = new XInvoice(); xinvoice.id = 'TEST-VALIDATION'; xinvoice.invoiceId = 'TEST-VALIDATION'; xinvoice.from.name = 'Validation Seller'; xinvoice.to.name = 'Validation Buyer'; // Export as Factur-X const xml = await xinvoice.exportXml('facturx'); // Set the XML string for validation xinvoice['xmlString'] = xml; // Validate the XML const result = await xinvoice.validate(ValidationLevel.SYNTAX); // Check that validation passed expect(result.valid).toBeTrue(); expect(result.errors).toHaveLength(0); }); // Run the tests tap.start();