feat(storage): add comprehensive tests for StorageManager with memory, filesystem, and custom function backends
feat(email): implement EmailSendJob class for robust email delivery with retry logic and MX record resolution feat(mail): restructure mail module exports for simplified access to core and delivery functionalities
This commit is contained in:
		@@ -0,0 +1,527 @@
 | 
			
		||||
import { tap, expect } from '@git.zone/tstest/tapbundle';
 | 
			
		||||
import * as net from 'net';
 | 
			
		||||
import { startTestServer, stopTestServer } from '../../helpers/server.loader.ts'
 | 
			
		||||
import type { ITestServer } from '../../helpers/server.loader.ts';
 | 
			
		||||
const TEST_PORT = 2525;
 | 
			
		||||
 | 
			
		||||
let testServer: ITestServer;
 | 
			
		||||
 | 
			
		||||
tap.test('setup - start test server', async () => {
 | 
			
		||||
  testServer = await startTestServer({ port: TEST_PORT });
 | 
			
		||||
  await new Promise(resolve => setTimeout(resolve, 1000));
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
tap.test('Email Routing - Local domain routing', async (tools) => {
 | 
			
		||||
  const done = tools.defer();
 | 
			
		||||
  
 | 
			
		||||
  const socket = net.createConnection({
 | 
			
		||||
    host: 'localhost',
 | 
			
		||||
    port: TEST_PORT,
 | 
			
		||||
    timeout: 30000
 | 
			
		||||
  });
 | 
			
		||||
  
 | 
			
		||||
  let dataBuffer = '';
 | 
			
		||||
  let step = 'greeting';
 | 
			
		||||
  let completed = false;
 | 
			
		||||
  
 | 
			
		||||
  socket.on('data', (data) => {
 | 
			
		||||
    if (completed) return;
 | 
			
		||||
    
 | 
			
		||||
    dataBuffer += data.toString();
 | 
			
		||||
    console.log('Server response:', data.toString());
 | 
			
		||||
    
 | 
			
		||||
    if (step === 'greeting' && dataBuffer.includes('220 ')) {
 | 
			
		||||
      step = 'ehlo';
 | 
			
		||||
      socket.write('EHLO localhost\r\n');
 | 
			
		||||
      dataBuffer = '';
 | 
			
		||||
    } else if (step === 'ehlo' && dataBuffer.includes('250')) {
 | 
			
		||||
      step = 'mail';
 | 
			
		||||
      // Local sender
 | 
			
		||||
      socket.write('MAIL FROM:<test@example.com>\r\n');
 | 
			
		||||
      dataBuffer = '';
 | 
			
		||||
    } else if (step === 'mail' && dataBuffer.includes('250')) {
 | 
			
		||||
      step = 'rcpt';
 | 
			
		||||
      // Local recipient
 | 
			
		||||
      socket.write('RCPT TO:<local@localhost>\r\n');
 | 
			
		||||
      dataBuffer = '';
 | 
			
		||||
    } else if (step === 'rcpt') {
 | 
			
		||||
      const accepted = dataBuffer.includes('250');
 | 
			
		||||
      console.log(`Local domain routing: ${accepted ? 'accepted' : 'rejected'}`);
 | 
			
		||||
      
 | 
			
		||||
      if (accepted) {
 | 
			
		||||
        step = 'data';
 | 
			
		||||
        socket.write('DATA\r\n');
 | 
			
		||||
        dataBuffer = '';
 | 
			
		||||
      } else {
 | 
			
		||||
        socket.write('QUIT\r\n');
 | 
			
		||||
        socket.end();
 | 
			
		||||
        done.resolve();
 | 
			
		||||
      }
 | 
			
		||||
    } else if (step === 'data' && dataBuffer.includes('354')) {
 | 
			
		||||
      const email = [
 | 
			
		||||
        `From: test@example.com`,
 | 
			
		||||
        `To: local@localhost`,
 | 
			
		||||
        `Subject: Local Domain Routing Test`,
 | 
			
		||||
        `Date: ${new Date().toUTCString()}`,
 | 
			
		||||
        `Message-ID: <local-routing-${Date.now()}@localhost>`,
 | 
			
		||||
        '',
 | 
			
		||||
        'This email tests local domain routing.',
 | 
			
		||||
        'The server should route this email locally.',
 | 
			
		||||
        '.',
 | 
			
		||||
        ''
 | 
			
		||||
      ].join('\r\n');
 | 
			
		||||
      
 | 
			
		||||
      socket.write(email);
 | 
			
		||||
      dataBuffer = '';
 | 
			
		||||
      step = 'sent';
 | 
			
		||||
    } else if (step === 'sent' && dataBuffer.includes('250 ') && dataBuffer.includes('message queued')) {
 | 
			
		||||
      if (!completed) {
 | 
			
		||||
        completed = true;
 | 
			
		||||
        console.log('Local domain email routed successfully');
 | 
			
		||||
        expect(true).toEqual(true);
 | 
			
		||||
        
 | 
			
		||||
        socket.write('QUIT\r\n');
 | 
			
		||||
        socket.end();
 | 
			
		||||
        done.resolve();
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
  
 | 
			
		||||
  socket.on('error', (err) => {
 | 
			
		||||
    console.error('Socket error:', err);
 | 
			
		||||
    done.reject(err);
 | 
			
		||||
  });
 | 
			
		||||
  
 | 
			
		||||
  await done.promise;
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
tap.test('Email Routing - External domain routing', async (tools) => {
 | 
			
		||||
  const done = tools.defer();
 | 
			
		||||
  
 | 
			
		||||
  const socket = net.createConnection({
 | 
			
		||||
    host: 'localhost',
 | 
			
		||||
    port: TEST_PORT,
 | 
			
		||||
    timeout: 30000
 | 
			
		||||
  });
 | 
			
		||||
  
 | 
			
		||||
  let dataBuffer = '';
 | 
			
		||||
  let step = 'greeting';
 | 
			
		||||
  let completed = false;
 | 
			
		||||
  
 | 
			
		||||
  socket.on('data', (data) => {
 | 
			
		||||
    if (completed) return;
 | 
			
		||||
    
 | 
			
		||||
    dataBuffer += data.toString();
 | 
			
		||||
    console.log('Server response:', data.toString());
 | 
			
		||||
    
 | 
			
		||||
    if (step === 'greeting' && dataBuffer.includes('220 ')) {
 | 
			
		||||
      step = 'ehlo';
 | 
			
		||||
      socket.write('EHLO localhost\r\n');
 | 
			
		||||
      dataBuffer = '';
 | 
			
		||||
    } else if (step === 'ehlo' && dataBuffer.includes('250')) {
 | 
			
		||||
      step = 'mail';
 | 
			
		||||
      socket.write('MAIL FROM:<sender@example.com>\r\n');
 | 
			
		||||
      dataBuffer = '';
 | 
			
		||||
    } else if (step === 'mail' && dataBuffer.includes('250')) {
 | 
			
		||||
      step = 'rcpt';
 | 
			
		||||
      // External recipient
 | 
			
		||||
      socket.write('RCPT TO:<recipient@external.com>\r\n');
 | 
			
		||||
      dataBuffer = '';
 | 
			
		||||
    } else if (step === 'rcpt') {
 | 
			
		||||
      const accepted = dataBuffer.includes('250');
 | 
			
		||||
      console.log(`External domain routing: ${accepted ? 'accepted' : 'rejected'}`);
 | 
			
		||||
      
 | 
			
		||||
      if (accepted) {
 | 
			
		||||
        step = 'data';
 | 
			
		||||
        socket.write('DATA\r\n');
 | 
			
		||||
        dataBuffer = '';
 | 
			
		||||
      } else {
 | 
			
		||||
        socket.write('QUIT\r\n');
 | 
			
		||||
        socket.end();
 | 
			
		||||
        done.resolve();
 | 
			
		||||
      }
 | 
			
		||||
    } else if (step === 'data' && dataBuffer.includes('354')) {
 | 
			
		||||
      const email = [
 | 
			
		||||
        `From: sender@example.com`,
 | 
			
		||||
        `To: recipient@external.com`,
 | 
			
		||||
        `Subject: External Domain Routing Test`,
 | 
			
		||||
        `Date: ${new Date().toUTCString()}`,
 | 
			
		||||
        `Message-ID: <external-routing-${Date.now()}@example.com>`,
 | 
			
		||||
        '',
 | 
			
		||||
        'This email tests external domain routing.',
 | 
			
		||||
        'The server should accept this for relay.',
 | 
			
		||||
        '.',
 | 
			
		||||
        ''
 | 
			
		||||
      ].join('\r\n');
 | 
			
		||||
      
 | 
			
		||||
      socket.write(email);
 | 
			
		||||
      dataBuffer = '';
 | 
			
		||||
      step = 'sent';
 | 
			
		||||
    } else if (step === 'sent' && dataBuffer.includes('250 ') && dataBuffer.includes('message queued')) {
 | 
			
		||||
      if (!completed) {
 | 
			
		||||
        completed = true;
 | 
			
		||||
        console.log('External domain email accepted for relay');
 | 
			
		||||
        expect(true).toEqual(true);
 | 
			
		||||
        
 | 
			
		||||
        socket.write('QUIT\r\n');
 | 
			
		||||
        socket.end();
 | 
			
		||||
        done.resolve();
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
  
 | 
			
		||||
  socket.on('error', (err) => {
 | 
			
		||||
    console.error('Socket error:', err);
 | 
			
		||||
    done.reject(err);
 | 
			
		||||
  });
 | 
			
		||||
  
 | 
			
		||||
  await done.promise;
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
tap.test('Email Routing - Multiple recipients', async (tools) => {
 | 
			
		||||
  const done = tools.defer();
 | 
			
		||||
  
 | 
			
		||||
  const socket = net.createConnection({
 | 
			
		||||
    host: 'localhost',
 | 
			
		||||
    port: TEST_PORT,
 | 
			
		||||
    timeout: 30000
 | 
			
		||||
  });
 | 
			
		||||
  
 | 
			
		||||
  let dataBuffer = '';
 | 
			
		||||
  let step = 'greeting';
 | 
			
		||||
  let recipientCount = 0;
 | 
			
		||||
  const totalRecipients = 5;
 | 
			
		||||
  let completed = false;
 | 
			
		||||
  
 | 
			
		||||
  socket.on('data', (data) => {
 | 
			
		||||
    if (completed) return;
 | 
			
		||||
    
 | 
			
		||||
    dataBuffer += data.toString();
 | 
			
		||||
    console.log('Server response:', data.toString());
 | 
			
		||||
    
 | 
			
		||||
    if (step === 'greeting' && dataBuffer.includes('220 ')) {
 | 
			
		||||
      step = 'ehlo';
 | 
			
		||||
      socket.write('EHLO localhost\r\n');
 | 
			
		||||
      dataBuffer = '';
 | 
			
		||||
    } else if (step === 'ehlo' && dataBuffer.includes('250')) {
 | 
			
		||||
      step = 'mail';
 | 
			
		||||
      socket.write('MAIL FROM:<sender@example.com>\r\n');
 | 
			
		||||
      dataBuffer = '';
 | 
			
		||||
    } else if (step === 'mail' && dataBuffer.includes('250')) {
 | 
			
		||||
      step = 'rcpt';
 | 
			
		||||
      recipientCount++;
 | 
			
		||||
      socket.write(`RCPT TO:<recipient${recipientCount}@example.com>\r\n`);
 | 
			
		||||
      dataBuffer = '';
 | 
			
		||||
    } else if (step === 'rcpt' && dataBuffer.includes('250')) {
 | 
			
		||||
      if (recipientCount < totalRecipients) {
 | 
			
		||||
        recipientCount++;
 | 
			
		||||
        socket.write(`RCPT TO:<recipient${recipientCount}@example.com>\r\n`);
 | 
			
		||||
        dataBuffer = '';
 | 
			
		||||
      } else {
 | 
			
		||||
        console.log(`All ${totalRecipients} recipients accepted`);
 | 
			
		||||
        step = 'data';
 | 
			
		||||
        socket.write('DATA\r\n');
 | 
			
		||||
        dataBuffer = '';
 | 
			
		||||
      }
 | 
			
		||||
    } else if (step === 'data' && dataBuffer.includes('354')) {
 | 
			
		||||
      const recipients = Array.from({length: totalRecipients}, (_, i) => `recipient${i+1}@example.com`);
 | 
			
		||||
      const email = [
 | 
			
		||||
        `From: sender@example.com`,
 | 
			
		||||
        `To: ${recipients.join(', ')}`,
 | 
			
		||||
        `Subject: Multiple Recipients Routing Test`,
 | 
			
		||||
        `Date: ${new Date().toUTCString()}`,
 | 
			
		||||
        `Message-ID: <multi-recipient-${Date.now()}@example.com>`,
 | 
			
		||||
        '',
 | 
			
		||||
        'This email tests routing to multiple recipients.',
 | 
			
		||||
        `Total recipients: ${totalRecipients}`,
 | 
			
		||||
        '.',
 | 
			
		||||
        ''
 | 
			
		||||
      ].join('\r\n');
 | 
			
		||||
      
 | 
			
		||||
      socket.write(email);
 | 
			
		||||
      dataBuffer = '';
 | 
			
		||||
      step = 'sent';
 | 
			
		||||
    } else if (step === 'sent' && dataBuffer.includes('250 ') && dataBuffer.includes('message queued')) {
 | 
			
		||||
      if (!completed) {
 | 
			
		||||
        completed = true;
 | 
			
		||||
        console.log('Email with multiple recipients routed successfully');
 | 
			
		||||
        expect(true).toEqual(true);
 | 
			
		||||
        
 | 
			
		||||
        socket.write('QUIT\r\n');
 | 
			
		||||
        socket.end();
 | 
			
		||||
        done.resolve();
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
  
 | 
			
		||||
  socket.on('error', (err) => {
 | 
			
		||||
    console.error('Socket error:', err);
 | 
			
		||||
    done.reject(err);
 | 
			
		||||
  });
 | 
			
		||||
  
 | 
			
		||||
  await done.promise;
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
tap.test('Email Routing - Invalid domain handling', async (tools) => {
 | 
			
		||||
  const done = tools.defer();
 | 
			
		||||
  
 | 
			
		||||
  const socket = net.createConnection({
 | 
			
		||||
    host: 'localhost',
 | 
			
		||||
    port: TEST_PORT,
 | 
			
		||||
    timeout: 30000
 | 
			
		||||
  });
 | 
			
		||||
  
 | 
			
		||||
  let dataBuffer = '';
 | 
			
		||||
  let step = 'greeting';
 | 
			
		||||
  let testType = 'invalid-tld';
 | 
			
		||||
  const testCases = [
 | 
			
		||||
    { email: 'user@invalid-tld', type: 'invalid-tld' },
 | 
			
		||||
    { email: 'user@.com', type: 'missing-domain' },
 | 
			
		||||
    { email: 'user@domain..com', type: 'double-dot' },
 | 
			
		||||
    { email: 'user@-domain.com', type: 'leading-dash' },
 | 
			
		||||
    { email: 'user@domain-.com', type: 'trailing-dash' }
 | 
			
		||||
  ];
 | 
			
		||||
  let currentTest = 0;
 | 
			
		||||
  
 | 
			
		||||
  socket.on('data', (data) => {
 | 
			
		||||
    dataBuffer += data.toString();
 | 
			
		||||
    console.log('Server response:', data.toString());
 | 
			
		||||
    
 | 
			
		||||
    if (step === 'greeting' && dataBuffer.includes('220 ')) {
 | 
			
		||||
      step = 'ehlo';
 | 
			
		||||
      socket.write('EHLO localhost\r\n');
 | 
			
		||||
      dataBuffer = '';
 | 
			
		||||
    } else if (step === 'ehlo' && dataBuffer.includes('250')) {
 | 
			
		||||
      step = 'mail';
 | 
			
		||||
      socket.write('MAIL FROM:<sender@example.com>\r\n');
 | 
			
		||||
      dataBuffer = '';
 | 
			
		||||
    } else if (step === 'mail' && dataBuffer.includes('250')) {
 | 
			
		||||
      step = 'rcpt';
 | 
			
		||||
      testType = testCases[currentTest].type;
 | 
			
		||||
      socket.write(`RCPT TO:<${testCases[currentTest].email}>\r\n`);
 | 
			
		||||
      dataBuffer = '';
 | 
			
		||||
    } else if (step === 'rcpt') {
 | 
			
		||||
      const rejected = dataBuffer.includes('550') || dataBuffer.includes('553') || dataBuffer.includes('501');
 | 
			
		||||
      console.log(`Invalid domain test (${testType}): ${rejected ? 'properly rejected' : 'unexpectedly accepted'}`);
 | 
			
		||||
      
 | 
			
		||||
      currentTest++;
 | 
			
		||||
      if (currentTest < testCases.length) {
 | 
			
		||||
        // Reset for next test
 | 
			
		||||
        socket.write('RSET\r\n');
 | 
			
		||||
        step = 'rset';
 | 
			
		||||
        dataBuffer = '';
 | 
			
		||||
      } else {
 | 
			
		||||
        socket.write('QUIT\r\n');
 | 
			
		||||
        socket.end();
 | 
			
		||||
        done.resolve();
 | 
			
		||||
      }
 | 
			
		||||
    } else if (step === 'rset' && dataBuffer.includes('250')) {
 | 
			
		||||
      step = 'mail';
 | 
			
		||||
      socket.write('MAIL FROM:<sender@example.com>\r\n');
 | 
			
		||||
      dataBuffer = '';
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
  
 | 
			
		||||
  socket.on('error', (err) => {
 | 
			
		||||
    console.error('Socket error:', err);
 | 
			
		||||
    done.reject(err);
 | 
			
		||||
  });
 | 
			
		||||
  
 | 
			
		||||
  await done.promise;
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
tap.test('Email Routing - Mixed local and external recipients', async (tools) => {
 | 
			
		||||
  const done = tools.defer();
 | 
			
		||||
  
 | 
			
		||||
  const socket = net.createConnection({
 | 
			
		||||
    host: 'localhost',
 | 
			
		||||
    port: TEST_PORT,
 | 
			
		||||
    timeout: 30000
 | 
			
		||||
  });
 | 
			
		||||
  
 | 
			
		||||
  let dataBuffer = '';
 | 
			
		||||
  let step = 'greeting';
 | 
			
		||||
  let completed = false;
 | 
			
		||||
  const recipients = [
 | 
			
		||||
    'local@localhost',
 | 
			
		||||
    'external@example.com',
 | 
			
		||||
    'another@localhost',
 | 
			
		||||
    'remote@external.com'
 | 
			
		||||
  ];
 | 
			
		||||
  let currentRecipient = 0;
 | 
			
		||||
  let acceptedRecipients: string[] = [];
 | 
			
		||||
  
 | 
			
		||||
  socket.on('data', (data) => {
 | 
			
		||||
    if (completed) return;
 | 
			
		||||
    
 | 
			
		||||
    dataBuffer += data.toString();
 | 
			
		||||
    console.log('Server response:', data.toString());
 | 
			
		||||
    
 | 
			
		||||
    if (step === 'greeting' && dataBuffer.includes('220 ')) {
 | 
			
		||||
      step = 'ehlo';
 | 
			
		||||
      socket.write('EHLO localhost\r\n');
 | 
			
		||||
      dataBuffer = '';
 | 
			
		||||
    } else if (step === 'ehlo' && dataBuffer.includes('250')) {
 | 
			
		||||
      step = 'mail';
 | 
			
		||||
      socket.write('MAIL FROM:<sender@example.com>\r\n');
 | 
			
		||||
      dataBuffer = '';
 | 
			
		||||
    } else if (step === 'mail' && dataBuffer.includes('250')) {
 | 
			
		||||
      step = 'rcpt';
 | 
			
		||||
      socket.write(`RCPT TO:<${recipients[currentRecipient]}>\r\n`);
 | 
			
		||||
      dataBuffer = '';
 | 
			
		||||
    } else if (step === 'rcpt') {
 | 
			
		||||
      if (dataBuffer.includes('250')) {
 | 
			
		||||
        acceptedRecipients.push(recipients[currentRecipient]);
 | 
			
		||||
        console.log(`Recipient ${recipients[currentRecipient]} accepted`);
 | 
			
		||||
      } else {
 | 
			
		||||
        console.log(`Recipient ${recipients[currentRecipient]} rejected`);
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      currentRecipient++;
 | 
			
		||||
      if (currentRecipient < recipients.length) {
 | 
			
		||||
        socket.write(`RCPT TO:<${recipients[currentRecipient]}>\r\n`);
 | 
			
		||||
        dataBuffer = '';
 | 
			
		||||
      } else if (acceptedRecipients.length > 0) {
 | 
			
		||||
        step = 'data';
 | 
			
		||||
        socket.write('DATA\r\n');
 | 
			
		||||
        dataBuffer = '';
 | 
			
		||||
      } else {
 | 
			
		||||
        socket.write('QUIT\r\n');
 | 
			
		||||
        socket.end();
 | 
			
		||||
        done.resolve();
 | 
			
		||||
      }
 | 
			
		||||
    } else if (step === 'data' && dataBuffer.includes('354')) {
 | 
			
		||||
      const email = [
 | 
			
		||||
        `From: sender@example.com`,
 | 
			
		||||
        `To: ${acceptedRecipients.join(', ')}`,
 | 
			
		||||
        `Subject: Mixed Recipients Routing Test`,
 | 
			
		||||
        `Date: ${new Date().toUTCString()}`,
 | 
			
		||||
        `Message-ID: <mixed-routing-${Date.now()}@example.com>`,
 | 
			
		||||
        '',
 | 
			
		||||
        'This email tests routing to mixed local and external recipients.',
 | 
			
		||||
        `Accepted recipients: ${acceptedRecipients.length}`,
 | 
			
		||||
        '.',
 | 
			
		||||
        ''
 | 
			
		||||
      ].join('\r\n');
 | 
			
		||||
      
 | 
			
		||||
      socket.write(email);
 | 
			
		||||
      dataBuffer = '';
 | 
			
		||||
      step = 'sent';
 | 
			
		||||
    } else if (step === 'sent' && dataBuffer.includes('250 ') && dataBuffer.includes('message queued')) {
 | 
			
		||||
      if (!completed) {
 | 
			
		||||
        completed = true;
 | 
			
		||||
        console.log('Email with mixed recipients routed successfully');
 | 
			
		||||
        expect(acceptedRecipients.length).toBeGreaterThan(0);
 | 
			
		||||
        
 | 
			
		||||
        socket.write('QUIT\r\n');
 | 
			
		||||
        socket.end();
 | 
			
		||||
        done.resolve();
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
  
 | 
			
		||||
  socket.on('error', (err) => {
 | 
			
		||||
    console.error('Socket error:', err);
 | 
			
		||||
    done.reject(err);
 | 
			
		||||
  });
 | 
			
		||||
  
 | 
			
		||||
  await done.promise;
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
tap.test('Email Routing - Subdomain routing', async (tools) => {
 | 
			
		||||
  const done = tools.defer();
 | 
			
		||||
  
 | 
			
		||||
  const socket = net.createConnection({
 | 
			
		||||
    host: 'localhost',
 | 
			
		||||
    port: TEST_PORT,
 | 
			
		||||
    timeout: 30000
 | 
			
		||||
  });
 | 
			
		||||
  
 | 
			
		||||
  let dataBuffer = '';
 | 
			
		||||
  let step = 'greeting';
 | 
			
		||||
  let completed = false;
 | 
			
		||||
  const subdomainTests = [
 | 
			
		||||
    'user@mail.example.com',
 | 
			
		||||
    'user@smtp.corp.example.com',
 | 
			
		||||
    'user@deep.sub.domain.example.com'
 | 
			
		||||
  ];
 | 
			
		||||
  let currentTest = 0;
 | 
			
		||||
  
 | 
			
		||||
  socket.on('data', (data) => {
 | 
			
		||||
    if (completed) return;
 | 
			
		||||
    
 | 
			
		||||
    dataBuffer += data.toString();
 | 
			
		||||
    console.log('Server response:', data.toString());
 | 
			
		||||
    
 | 
			
		||||
    if (step === 'greeting' && dataBuffer.includes('220 ')) {
 | 
			
		||||
      step = 'ehlo';
 | 
			
		||||
      socket.write('EHLO localhost\r\n');
 | 
			
		||||
      dataBuffer = '';
 | 
			
		||||
    } else if (step === 'ehlo' && dataBuffer.includes('250')) {
 | 
			
		||||
      step = 'mail';
 | 
			
		||||
      socket.write('MAIL FROM:<sender@example.com>\r\n');
 | 
			
		||||
      dataBuffer = '';
 | 
			
		||||
    } else if (step === 'mail' && dataBuffer.includes('250')) {
 | 
			
		||||
      step = 'rcpt';
 | 
			
		||||
      socket.write(`RCPT TO:<${subdomainTests[currentTest]}>\r\n`);
 | 
			
		||||
      dataBuffer = '';
 | 
			
		||||
    } else if (step === 'rcpt') {
 | 
			
		||||
      const accepted = dataBuffer.includes('250');
 | 
			
		||||
      console.log(`Subdomain routing test (${subdomainTests[currentTest]}): ${accepted ? 'accepted' : 'rejected'}`);
 | 
			
		||||
      
 | 
			
		||||
      currentTest++;
 | 
			
		||||
      if (currentTest < subdomainTests.length) {
 | 
			
		||||
        socket.write('RSET\r\n');
 | 
			
		||||
        step = 'rset';
 | 
			
		||||
        dataBuffer = '';
 | 
			
		||||
      } else {
 | 
			
		||||
        step = 'data';
 | 
			
		||||
        socket.write('DATA\r\n');
 | 
			
		||||
        dataBuffer = '';
 | 
			
		||||
      }
 | 
			
		||||
    } else if (step === 'rset' && dataBuffer.includes('250')) {
 | 
			
		||||
      step = 'mail';
 | 
			
		||||
      socket.write('MAIL FROM:<sender@example.com>\r\n');
 | 
			
		||||
      dataBuffer = '';
 | 
			
		||||
    } else if (step === 'data' && dataBuffer.includes('354')) {
 | 
			
		||||
      const email = [
 | 
			
		||||
        `From: sender@example.com`,
 | 
			
		||||
        `To: ${subdomainTests[subdomainTests.length - 1]}`,
 | 
			
		||||
        `Subject: Subdomain Routing Test`,
 | 
			
		||||
        `Date: ${new Date().toUTCString()}`,
 | 
			
		||||
        `Message-ID: <subdomain-routing-${Date.now()}@example.com>`,
 | 
			
		||||
        '',
 | 
			
		||||
        'This email tests subdomain routing.',
 | 
			
		||||
        '.',
 | 
			
		||||
        ''
 | 
			
		||||
      ].join('\r\n');
 | 
			
		||||
      
 | 
			
		||||
      socket.write(email);
 | 
			
		||||
      dataBuffer = '';
 | 
			
		||||
      step = 'sent';
 | 
			
		||||
    } else if (step === 'sent' && dataBuffer.includes('250 ') && dataBuffer.includes('message queued')) {
 | 
			
		||||
      if (!completed) {
 | 
			
		||||
        completed = true;
 | 
			
		||||
        console.log('Subdomain routing test completed');
 | 
			
		||||
        expect(true).toEqual(true);
 | 
			
		||||
        
 | 
			
		||||
        socket.write('QUIT\r\n');
 | 
			
		||||
        socket.end();
 | 
			
		||||
        done.resolve();
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
  
 | 
			
		||||
  socket.on('error', (err) => {
 | 
			
		||||
    console.error('Socket error:', err);
 | 
			
		||||
    done.reject(err);
 | 
			
		||||
  });
 | 
			
		||||
  
 | 
			
		||||
  await done.promise;
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
tap.test('cleanup - stop test server', async () => {
 | 
			
		||||
  await stopTestServer(testServer);
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export default tap.start();
 | 
			
		||||
		Reference in New Issue
	
	Block a user