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'; import { Email } from '../../../ts/mail/core/classes.email.js'; let testServer: ITestServer; tap.test('setup test SMTP server', async () => { testServer = await startTestServer({ port: 2547, tlsEnabled: false, authRequired: false }); expect(testServer).toBeTruthy(); expect(testServer.port).toBeGreaterThan(0); }); tap.test('CCMD-07: Parse successful send responses', async () => { const smtpClient = createSmtpClient({ host: testServer.hostname, port: testServer.port, secure: false, connectionTimeout: 5000, debug: true }); const email = new Email({ from: 'sender@example.com', to: 'recipient@example.com', subject: 'Response Test', text: 'Testing response parsing' }); const result = await smtpClient.sendMail(email); // Verify successful response parsing expect(result.success).toBeTrue(); expect(result.response).toBeTruthy(); expect(result.messageId).toBeTruthy(); // The response should contain queue ID expect(result.response).toInclude('queued'); console.log(`✅ Parsed success response: ${result.response}`); await smtpClient.close(); }); tap.test('CCMD-07: Parse multiple recipient responses', async () => { const smtpClient = createSmtpClient({ host: testServer.hostname, port: testServer.port, secure: false, connectionTimeout: 5000, debug: true }); // Send to multiple recipients const email = new Email({ from: 'sender@example.com', to: ['recipient1@example.com', 'recipient2@example.com', 'recipient3@example.com'], subject: 'Multi-recipient Test', text: 'Testing multiple recipient response parsing' }); const result = await smtpClient.sendMail(email); // Verify parsing of multiple recipient responses expect(result.success).toBeTrue(); expect(result.acceptedRecipients.length).toEqual(3); expect(result.rejectedRecipients.length).toEqual(0); console.log(`✅ Accepted ${result.acceptedRecipients.length} recipients`); console.log('Multiple RCPT TO responses parsed correctly'); await smtpClient.close(); }); tap.test('CCMD-07: Parse error response codes', async () => { const smtpClient = createSmtpClient({ host: testServer.hostname, port: testServer.port, secure: false, connectionTimeout: 5000, debug: true }); // Test with invalid email to trigger error try { const email = new Email({ from: '', // Empty from should trigger error to: 'recipient@example.com', subject: 'Error Test', text: 'Testing error response' }); await smtpClient.sendMail(email); expect(false).toBeTrue(); // Should not reach here } catch (error: any) { expect(error).toBeInstanceOf(Error); expect(error.message).toBeTruthy(); console.log(`✅ Error response parsed: ${error.message}`); } await smtpClient.close(); }); tap.test('CCMD-07: Parse enhanced status codes', async () => { const smtpClient = createSmtpClient({ host: testServer.hostname, port: testServer.port, secure: false, connectionTimeout: 5000, debug: true }); // Normal send - server advertises ENHANCEDSTATUSCODES const email = new Email({ from: 'sender@example.com', to: 'recipient@example.com', subject: 'Enhanced Status Test', text: 'Testing enhanced status code parsing' }); const result = await smtpClient.sendMail(email); expect(result.success).toBeTrue(); // Server logs show it advertises ENHANCEDSTATUSCODES in EHLO console.log('✅ Server advertises ENHANCEDSTATUSCODES capability'); console.log('Enhanced status codes are parsed automatically'); await smtpClient.close(); }); tap.test('CCMD-07: Parse response timing and delays', async () => { const smtpClient = createSmtpClient({ host: testServer.hostname, port: testServer.port, secure: false, connectionTimeout: 5000, debug: true }); // Measure response time const email = new Email({ from: 'sender@example.com', to: 'recipient@example.com', subject: 'Timing Test', text: 'Testing response timing' }); const startTime = Date.now(); const result = await smtpClient.sendMail(email); const elapsed = Date.now() - startTime; expect(result.success).toBeTrue(); expect(elapsed).toBeGreaterThan(0); expect(elapsed).toBeLessThan(5000); // Should complete within 5 seconds console.log(`✅ Response received and parsed in ${elapsed}ms`); console.log('Client handles response timing appropriately'); await smtpClient.close(); }); tap.test('CCMD-07: Parse envelope information', async () => { const smtpClient = createSmtpClient({ host: testServer.hostname, port: testServer.port, secure: false, connectionTimeout: 5000, debug: true }); const from = 'sender@example.com'; const to = ['recipient1@example.com', 'recipient2@example.com']; const cc = ['cc@example.com']; const bcc = ['bcc@example.com']; const email = new Email({ from, to, cc, bcc, subject: 'Envelope Test', text: 'Testing envelope parsing' }); const result = await smtpClient.sendMail(email); expect(result.success).toBeTrue(); expect(result.envelope).toBeTruthy(); expect(result.envelope.from).toEqual(from); expect(result.envelope.to).toBeArray(); // Envelope should include all recipients (to, cc, bcc) const totalRecipients = to.length + cc.length + bcc.length; expect(result.envelope.to.length).toEqual(totalRecipients); console.log(`✅ Envelope parsed with ${result.envelope.to.length} recipients`); console.log('Envelope information correctly extracted from responses'); await smtpClient.close(); }); tap.test('CCMD-07: Parse connection state responses', async () => { const smtpClient = createSmtpClient({ host: testServer.hostname, port: testServer.port, secure: false, connectionTimeout: 5000, debug: true }); // Test verify() which checks connection state const isConnected = await smtpClient.verify(); expect(isConnected).toBeTrue(); console.log('✅ Connection verified through greeting and EHLO responses'); // Send email to test active connection const email = new Email({ from: 'sender@example.com', to: 'recipient@example.com', subject: 'State Test', text: 'Testing connection state' }); const result = await smtpClient.sendMail(email); expect(result.success).toBeTrue(); console.log('✅ Connection state maintained throughout session'); console.log('Response parsing handles connection state correctly'); await smtpClient.close(); }); tap.test('cleanup test SMTP server', async () => { await stopTestServer(testServer); expect(testServer).toBeTruthy(); }); export default tap.start();