import { tap, expect } from '@git.zone/tstest/tapbundle'; import { startTestServer, stopTestServer, type ITestServer } from '../../helpers/server.loader.js'; import { createSmtpClient } from '../../../ts/mail/delivery/smtpclient/index.js'; import type { SmtpClient } from '../../../ts/mail/delivery/smtpclient/smtp-client.js'; let testServer: ITestServer; let smtpClient: SmtpClient; tap.test('setup - start SMTP server for basic connection test', async () => { testServer = await startTestServer({ port: 2525, tlsEnabled: false, authRequired: false }); expect(testServer.port).toEqual(2525); }); tap.test('CCM-01: Basic TCP Connection - should connect to SMTP server', async () => { const startTime = Date.now(); try { // Create SMTP client smtpClient = createSmtpClient({ host: testServer.hostname, port: testServer.port, secure: false, connectionTimeout: 5000, debug: true }); // Verify connection const isConnected = await smtpClient.verify(); expect(isConnected).toBeTrue(); const duration = Date.now() - startTime; console.log(`✅ Basic TCP connection established in ${duration}ms`); } catch (error) { const duration = Date.now() - startTime; console.error(`❌ Basic TCP connection failed after ${duration}ms:`, error); throw error; } }); tap.test('CCM-01: Basic TCP Connection - should report connection status', async () => { expect(smtpClient.isConnected()).toBeTrue(); const poolStatus = smtpClient.getPoolStatus(); console.log('📊 Connection pool status:', poolStatus); // For non-pooled connection, should have 1 connection expect(poolStatus.total).toBeGreaterThanOrEqual(1); expect(poolStatus.active).toBeGreaterThanOrEqual(0); }); tap.test('CCM-01: Basic TCP Connection - should handle multiple connect/disconnect cycles', async () => { // Close existing connection await smtpClient.close(); expect(smtpClient.isConnected()).toBeFalse(); // Create new client and test reconnection for (let i = 0; i < 3; i++) { const cycleClient = createSmtpClient({ host: testServer.hostname, port: testServer.port, secure: false, connectionTimeout: 5000 }); const isConnected = await cycleClient.verify(); expect(isConnected).toBeTrue(); await cycleClient.close(); expect(cycleClient.isConnected()).toBeFalse(); console.log(`✅ Connection cycle ${i + 1} completed`); } }); tap.test('CCM-01: Basic TCP Connection - should fail with invalid host', async () => { let errorThrown = false; try { const invalidClient = createSmtpClient({ host: 'invalid.host.that.does.not.exist', port: 2525, secure: false, connectionTimeout: 3000 }); await invalidClient.verify(); } catch (error) { errorThrown = true; expect(error).toBeInstanceOf(Error); console.log('✅ Correctly failed to connect to invalid host'); } expect(errorThrown).toBeTrue(); }); tap.test('CCM-01: Basic TCP Connection - should timeout on unresponsive port', async () => { let errorThrown = false; const startTime = Date.now(); try { const timeoutClient = createSmtpClient({ host: testServer.hostname, port: 9999, // Port that's not listening secure: false, connectionTimeout: 2000 }); await timeoutClient.verify(); } catch (error) { errorThrown = true; const duration = Date.now() - startTime; expect(error).toBeInstanceOf(Error); expect(duration).toBeLessThan(3000); // Should timeout within 3 seconds console.log(`✅ Connection timeout working correctly (${duration}ms)`); } expect(errorThrown).toBeTrue(); }); tap.test('cleanup - close SMTP client', async () => { if (smtpClient && smtpClient.isConnected()) { await smtpClient.close(); } }); tap.test('cleanup - stop SMTP server', async () => { await stopTestServer(testServer); }); tap.start();