working
This commit is contained in:
@ -1,33 +1,168 @@
|
||||
import { tap, expect } from '@push.rocks/tapbundle';
|
||||
import { XInvoice } from '../ts/classes.xinvoice.js';
|
||||
import { ValidationLevel } from '../ts/interfaces/common.js';
|
||||
import * as assert from 'assert';
|
||||
import type { ExportFormat } from '../ts/interfaces/common.js';
|
||||
|
||||
/**
|
||||
* Test for XInvoice class
|
||||
*/
|
||||
async function testXInvoice() {
|
||||
console.log('Starting XInvoice tests...');
|
||||
// Basic XInvoice tests
|
||||
tap.test('XInvoice should have the correct default properties', async () => {
|
||||
const xinvoice = new XInvoice();
|
||||
|
||||
try {
|
||||
// Test creating a new XInvoice instance
|
||||
const xinvoice = new XInvoice();
|
||||
|
||||
// Check that the XInvoice instance has the expected properties
|
||||
assert.strictEqual(xinvoice.type, 'invoice', 'XInvoice type should be "invoice"');
|
||||
assert.strictEqual(xinvoice.invoiceType, 'debitnote', 'XInvoice invoiceType should be "debitnote"');
|
||||
assert.strictEqual(xinvoice.status, 'invoice', 'XInvoice status should be "invoice"');
|
||||
|
||||
// Check that the XInvoice instance has the expected methods
|
||||
assert.strictEqual(typeof xinvoice.exportXml, 'function', 'XInvoice should have an exportXml method');
|
||||
assert.strictEqual(typeof xinvoice.exportPdf, 'function', 'XInvoice should have an exportPdf method');
|
||||
assert.strictEqual(typeof xinvoice.validate, 'function', 'XInvoice should have a validate method');
|
||||
|
||||
console.log('All XInvoice tests passed!');
|
||||
} catch (error) {
|
||||
console.error('XInvoice test failed:', error);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
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');
|
||||
});
|
||||
|
||||
// Run the test
|
||||
testXInvoice();
|
||||
// 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 = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rsm:CrossIndustryInvoice xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100"
|
||||
xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100"
|
||||
xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100">
|
||||
<rsm:ExchangedDocumentContext>
|
||||
<ram:GuidelineSpecifiedDocumentContextParameter>
|
||||
<ram:ID>urn:cen.eu:en16931:2017</ram:ID>
|
||||
</ram:GuidelineSpecifiedDocumentContextParameter>
|
||||
</rsm:ExchangedDocumentContext>
|
||||
<rsm:ExchangedDocument>
|
||||
<ram:ID>TEST-XML-LOAD</ram:ID>
|
||||
<ram:TypeCode>380</ram:TypeCode>
|
||||
<ram:IssueDateTime>
|
||||
<udt:DateTimeString format="102">20230101</udt:DateTimeString>
|
||||
</ram:IssueDateTime>
|
||||
</rsm:ExchangedDocument>
|
||||
<rsm:SupplyChainTradeTransaction>
|
||||
<ram:ApplicableHeaderTradeAgreement>
|
||||
<ram:SellerTradeParty>
|
||||
<ram:Name>XML Seller</ram:Name>
|
||||
<ram:PostalTradeAddress>
|
||||
<ram:LineOne>Seller Street</ram:LineOne>
|
||||
<ram:LineTwo>123</ram:LineTwo>
|
||||
<ram:PostcodeCode>12345</ram:PostcodeCode>
|
||||
<ram:CityName>Seller City</ram:CityName>
|
||||
<ram:CountryID>DE</ram:CountryID>
|
||||
</ram:PostalTradeAddress>
|
||||
</ram:SellerTradeParty>
|
||||
<ram:BuyerTradeParty>
|
||||
<ram:Name>XML Buyer</ram:Name>
|
||||
<ram:PostalTradeAddress>
|
||||
<ram:LineOne>Buyer Street</ram:LineOne>
|
||||
<ram:LineTwo>456</ram:LineTwo>
|
||||
<ram:PostcodeCode>54321</ram:PostcodeCode>
|
||||
<ram:CityName>Buyer City</ram:CityName>
|
||||
<ram:CountryID>DE</ram:CountryID>
|
||||
</ram:PostalTradeAddress>
|
||||
</ram:BuyerTradeParty>
|
||||
</ram:ApplicableHeaderTradeAgreement>
|
||||
<ram:ApplicableHeaderTradeSettlement>
|
||||
<ram:InvoiceCurrencyCode>EUR</ram:InvoiceCurrencyCode>
|
||||
</ram:ApplicableHeaderTradeSettlement>
|
||||
</rsm:SupplyChainTradeTransaction>
|
||||
</rsm:CrossIndustryInvoice>`;
|
||||
|
||||
// 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();
|
||||
|
Reference in New Issue
Block a user