einvoice/ts/formats/factories/validator.factory.ts
Philipp Kunz 56fd12a6b2 test(suite): comprehensive test suite improvements and new validators
- Update test-utils import path and refactor to helpers/utils.ts
- Migrate all CorpusLoader usage from getFiles() to loadCategory() API
- Add new EN16931 UBL validator with comprehensive validation rules
- Add new XRechnung validator extending EN16931 with German requirements
- Update validator factory to support new validators
- Fix format detector for better XRechnung and EN16931 detection
- Update all test files to use proper import paths
- Improve error handling in security tests
- Fix validation tests to use realistic thresholds
- Add proper namespace handling in corpus validation tests
- Update format detection tests for improved accuracy
- Fix test imports from classes.xinvoice.ts to index.js

All test suites now properly aligned with the updated APIs and realistic performance expectations.
2025-05-30 18:18:42 +00:00

134 lines
3.9 KiB
TypeScript

import { BaseValidator } from '../base/base.validator.js';
import { InvoiceFormat, ValidationLevel } from '../../interfaces/common.js';
import type { ValidationResult } from '../../interfaces/common.js';
import { FormatDetector } from '../utils/format.detector.js';
// Import specific validators
import { EN16931UBLValidator } from '../ubl/en16931.ubl.validator.js';
import { XRechnungValidator } from '../ubl/xrechnung.validator.js';
import { FacturXValidator } from '../cii/facturx/facturx.validator.js';
import { ZUGFeRDValidator } from '../cii/zugferd/zugferd.validator.js';
// The EN16931UBLValidator handles all UBL-based formats with proper business rules
// No need for legacy validator implementations here
/**
* FatturaPA validator implementation
* Basic implementation for Italian electronic invoices
*/
class FatturaPAValidator extends BaseValidator {
validate(level: ValidationLevel = ValidationLevel.SYNTAX): ValidationResult {
// Reset errors
this.errors = [];
let valid = true;
if (level === ValidationLevel.SYNTAX) {
valid = this.validateSchema();
} else if (level === ValidationLevel.SEMANTIC || level === ValidationLevel.BUSINESS) {
valid = this.validateSchema() && this.validateBusinessRules();
}
return {
valid,
errors: this.errors,
level
};
}
protected validateSchema(): boolean {
// Basic schema validation for FatturaPA
if (!this.xml.includes('<FatturaElettronica')) {
this.addError('FATT-SCHEMA-1', 'Root element must be FatturaElettronica', '/');
return false;
}
return true;
}
protected validateBusinessRules(): boolean {
// Basic placeholder implementation - would need more detailed rules
// for a real implementation
return this.validateSchema();
}
}
/**
* Factory to create the appropriate validator based on the XML format
*/
export class ValidatorFactory {
/**
* Creates a validator for the specified XML content
* @param xml XML content to validate
* @returns Appropriate validator instance
*/
public static createValidator(xml: string): BaseValidator {
try {
const format = FormatDetector.detectFormat(xml);
switch (format) {
case InvoiceFormat.UBL:
return new EN16931UBLValidator(xml);
case InvoiceFormat.XRECHNUNG:
return new XRechnungValidator(xml);
case InvoiceFormat.CII:
// For now, use Factur-X validator for generic CII
return new FacturXValidator(xml);
case InvoiceFormat.ZUGFERD:
return new ZUGFeRDValidator(xml);
case InvoiceFormat.FACTURX:
return new FacturXValidator(xml);
case InvoiceFormat.FATTURAPA:
return new FatturaPAValidator(xml);
default:
// For unknown formats, provide a generic validator that will
// mark the document as invalid but won't throw an exception
return new GenericValidator(xml, format);
}
} catch (error) {
// If an error occurs during validator creation, return a generic validator
// that will provide meaningful error information instead of throwing
console.error(`Error creating validator: ${error}`);
return new GenericValidator(xml, 'unknown');
}
}
}
/**
* Generic validator for unknown or unsupported formats
* Provides meaningful validation errors instead of throwing exceptions
*/
class GenericValidator extends BaseValidator {
private format: string;
constructor(xml: string, format: string) {
super(xml);
this.format = format;
this.addError(
'GEN-1',
`Unsupported invoice format: ${format}`,
'/'
);
}
validate(level: ValidationLevel = ValidationLevel.SYNTAX): ValidationResult {
return {
valid: false,
errors: this.errors,
level
};
}
protected validateSchema(): boolean {
return false;
}
protected validateBusinessRules(): boolean {
return false;
}
}