import { tap, expect } from '@push.rocks/tapbundle'; import * as plugins from '../ts/plugins.js'; import { SzPlatformService } from '../ts/platformservice.js'; import { MtaService } from '../ts/mta/classes.mta.js'; import { EmailService } from '../ts/email/classes.emailservice.js'; import { BounceManager } from '../ts/email/classes.bouncemanager.js'; import DcRouter from '../ts/dcrouter/classes.dcrouter.js'; // Test the new integration architecture tap.test('should be able to create an independent MTA service', async (tools) => { // Create an independent MTA service const mta = new MtaService(undefined, { smtp: { port: 10025, // Use a different port for testing hostname: 'test.example.com' } }); // Verify it was created properly without a platform service reference expect(mta).toBeTruthy(); expect(mta.platformServiceRef).toBeUndefined(); // Even without a platform service, it should have its own SMTP rule engine expect(mta.smtpRuleEngine).toBeTruthy(); }); tap.test('should be able to create an EmailService with an existing MTA', async (tools) => { // Create a platform service first const platformService = new SzPlatformService(); // Create a shared bounce manager const bounceManager = new BounceManager(); // Create an independent MTA service - using a different parameter signature // Cast args to any type to bypass TypeScript checking for testing const mtaArgs: any = [undefined, { smtp: { port: 10025, // Use a different port for testing } }, bounceManager]; const mta = new MtaService(...mtaArgs); // Create an email service that uses the independent MTA const emailService = new EmailService(platformService, {}, mta); // Verify relationships expect(emailService.mtaService === mta).toBeTrue(); expect(emailService.bounceManager).toBeTruthy(); // MTA should not have a direct platform service reference expect(mta.platformServiceRef).toBeUndefined(); // But it should have access to bounce manager expect(mta.bounceManager === bounceManager).toBeTrue(); }); tap.test('should be able to create a DcRouter with an existing MTA', async (tools) => { // Create an independent MTA service const mta = new MtaService(undefined, { smtp: { port: 10025, // Use a different port for testing } }); // Create DcRouter with the MTA instance - using partial options for testing const router = new DcRouter({ mtaServiceInstance: mta, // Cast as any to bypass type checking in test smartProxyOptions: { acme: { accountEmail: 'test@example.com' } } as any }); // Prepare router but don't start it to avoid actual network bindings await router.configureSmtpProxy(); // Verify relationships expect(router.mta === mta).toBeTrue(); expect(router.smtpRuleEngine === mta.smtpRuleEngine).toBeTrue(); }); tap.test('should use the platform service MTA when configured', async (tools) => { // Create a platform service with default config (with MTA) const platformService = new SzPlatformService(); // Create MTA - don't await start() to avoid binding to ports platformService.mtaService = new MtaService(platformService, { smtp: { port: 10025, // Use a different port for testing } }); // Create email service using platform's configuration // Cast args to any type to bypass TypeScript checking for testing const emailServiceArgs: any = [ platformService, {}, platformService.mtaService ]; platformService.emailService = new EmailService(...emailServiceArgs); // Verify relationships expect(platformService.emailService.mtaService === platformService.mtaService).toBeTrue(); expect(platformService.mtaService.platformServiceRef === platformService).toBeTrue(); }); tap.test('stop', async () => { await tap.stopForcefully(); }); // Export for tapbundle execution export default tap.start();