import { tap, expect } from '@git.zone/tstest/tapbundle'; import * as plugins from '../ts/plugins.js'; import * as path from 'path'; import * as fs from 'fs'; import { DcRouter, type IDcRouterOptions, type IEmailConfig, type EmailProcessingMode, type IDomainRule } from '../ts/classes.dcrouter.js'; tap.test('DcRouter class - Custom email port configuration', async () => { // Define custom port mapping const customPortMapping = { 25: 11025, // Custom SMTP port mapping 587: 11587, // Custom submission port mapping 465: 11465, // Custom SMTPS port mapping 2525: 12525 // Additional custom port }; // Create a custom email configuration const emailConfig: IEmailConfig = { ports: [25, 587, 465, 2525], // Added a non-standard port hostname: 'mail.example.com', maxMessageSize: 50 * 1024 * 1024, // 50MB defaultMode: 'forward' as EmailProcessingMode, defaultServer: 'fallback-mail.example.com', defaultPort: 25, defaultTls: true, domainRules: [ { pattern: '*@example.com', mode: 'forward' as EmailProcessingMode, target: { server: 'mail1.example.com', port: 25, useTls: true } }, { pattern: '*@example.org', mode: 'mta' as EmailProcessingMode, mtaOptions: { domain: 'example.org', allowLocalDelivery: true } } ] }; // Create custom email storage path const customEmailsPath = path.join(process.cwd(), 'email'); // Ensure directory exists and is empty if (fs.existsSync(customEmailsPath)) { try { fs.rmdirSync(customEmailsPath, { recursive: true }); } catch (e) { console.warn('Could not remove test directory:', e); } } fs.mkdirSync(customEmailsPath, { recursive: true }); // Create DcRouter options with custom email port configuration const options: IDcRouterOptions = { emailConfig, emailPortConfig: { portMapping: customPortMapping, portSettings: { 2525: { terminateTls: false, routeName: 'custom-smtp-route' } }, receivedEmailsPath: customEmailsPath }, tls: { contactEmail: 'test@example.com' } }; // Create DcRouter instance const router = new DcRouter(options); // Verify the options are correctly set expect(router.options.emailPortConfig).toBeTruthy(); expect(router.options.emailPortConfig.portMapping).toEqual(customPortMapping); expect(router.options.emailPortConfig.receivedEmailsPath).toEqual(customEmailsPath); // Test the generateEmailRoutes method if (typeof router['generateEmailRoutes'] === 'function') { const routes = router['generateEmailRoutes'](emailConfig); // Verify that all ports are configured expect(routes.length).toBeGreaterThan(0); // At least some routes are configured // Check the custom port configuration const customPortRoute = routes.find(r => { const ports = r.match.ports; return ports === 2525 || (Array.isArray(ports) && (ports as number[]).includes(2525)); }); expect(customPortRoute).toBeTruthy(); expect(customPortRoute?.name).toEqual('custom-smtp-route'); expect(customPortRoute?.action.target.port).toEqual(12525); // Check standard port mappings const smtpRoute = routes.find(r => { const ports = r.match.ports; return ports === 25 || (Array.isArray(ports) && (ports as number[]).includes(25)); }); expect(smtpRoute?.action.target.port).toEqual(11025); const submissionRoute = routes.find(r => { const ports = r.match.ports; return ports === 587 || (Array.isArray(ports) && (ports as number[]).includes(587)); }); expect(submissionRoute?.action.target.port).toEqual(11587); } // Clean up try { fs.rmdirSync(customEmailsPath, { recursive: true }); } catch (e) { console.warn('Could not remove test directory in cleanup:', e); } }); tap.test('DcRouter class - Custom email storage path', async () => { // Create custom email storage path const customEmailsPath = path.join(process.cwd(), 'email'); // Ensure directory exists and is empty if (fs.existsSync(customEmailsPath)) { try { fs.rmdirSync(customEmailsPath, { recursive: true }); } catch (e) { console.warn('Could not remove test directory:', e); } } fs.mkdirSync(customEmailsPath, { recursive: true }); // Create a basic email configuration const emailConfig: IEmailConfig = { ports: [25], hostname: 'mail.example.com', defaultMode: 'mta' as EmailProcessingMode, domainRules: [] }; // Create DcRouter options with custom email storage path const options: IDcRouterOptions = { emailConfig, emailPortConfig: { receivedEmailsPath: customEmailsPath }, tls: { contactEmail: 'test@example.com' } }; // Create DcRouter instance const router = new DcRouter(options); // Start the router to initialize email services await router.start(); // Verify that the custom email storage path was configured expect(router.options.emailPortConfig?.receivedEmailsPath).toEqual(customEmailsPath); // Verify the directory exists expect(fs.existsSync(customEmailsPath)).toEqual(true); // Verify unified email server was initialized expect(router.unifiedEmailServer).toBeTruthy(); // Stop the router await router.stop(); // Clean up try { fs.rmdirSync(customEmailsPath, { recursive: true }); } catch (e) { console.warn('Could not remove test directory in cleanup:', e); } }); // Final clean-up test tap.test('clean up after tests', async () => { // No-op - just to make sure everything is cleaned up properly }); tap.test('stop', async () => { await tap.stopForcefully(); }); // Export a function to run all tests export default tap.start();