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'; import * as crypto from 'crypto'; let testServer: ITestServer; let smtpClient: SmtpClient; tap.test('setup - start SMTP server for attachment encoding tests', async () => { testServer = await startTestServer({ port: 2572, tlsEnabled: false, authRequired: false, size: 50 * 1024 * 1024 // 50MB for large attachment tests }); expect(testServer.port).toEqual(2572); }); tap.test('setup - create SMTP client', async () => { smtpClient = createSmtpClient({ host: testServer.hostname, port: testServer.port, secure: false, connectionTimeout: 5000, socketTimeout: 120000, // 2 minutes for large attachments debug: true }); const isConnected = await smtpClient.verify(); expect(isConnected).toBeTrue(); }); tap.test('CEP-03: Attachment Encoding - should encode text attachment with base64', async () => { const textContent = 'This is a test text file.\nIt contains multiple lines.\nAnd some special characters: © ® ™'; const email = new Email({ from: 'sender@example.com', to: 'recipient@example.com', subject: 'Text Attachment Base64 Test', text: 'Email with text attachment', attachments: [{ filename: 'test.txt', content: Buffer.from(textContent), contentType: 'text/plain', encoding: 'base64' }] }); const result = await smtpClient.sendMail(email); expect(result.success).toBeTrue(); console.log('✅ Text attachment encoded with base64'); }); tap.test('CEP-03: Attachment Encoding - should encode binary data correctly', async () => { // Create binary data with all possible byte values const binaryData = Buffer.alloc(256); for (let i = 0; i < 256; i++) { binaryData[i] = i; } const email = new Email({ from: 'sender@example.com', to: 'recipient@example.com', subject: 'Binary Attachment Test', text: 'Email with binary attachment', attachments: [{ filename: 'binary.dat', content: binaryData, contentType: 'application/octet-stream' }] }); const result = await smtpClient.sendMail(email); expect(result.success).toBeTrue(); console.log('✅ Binary data encoded correctly'); }); tap.test('CEP-03: Attachment Encoding - should handle various file types', async () => { const attachments = [ { filename: 'image.jpg', content: Buffer.from('/9j/4AAQSkZJRgABAQEASABIAAD/2wBD', 'base64'), // Partial JPEG header contentType: 'image/jpeg' }, { filename: 'document.pdf', content: Buffer.from('%PDF-1.4\n%âÃÏÓ\n', 'utf8'), contentType: 'application/pdf' }, { filename: 'archive.zip', content: Buffer.from('PK\x03\x04'), // ZIP magic number contentType: 'application/zip' }, { filename: 'audio.mp3', content: Buffer.from('ID3'), // MP3 ID3 tag contentType: 'audio/mpeg' } ]; const email = new Email({ from: 'sender@example.com', to: 'recipient@example.com', subject: 'Multiple File Types Test', text: 'Testing various attachment types', attachments }); const result = await smtpClient.sendMail(email); expect(result.success).toBeTrue(); console.log('✅ Various file types encoded correctly'); }); tap.test('CEP-03: Attachment Encoding - should handle quoted-printable encoding', async () => { const textWithSpecialChars = 'This line has special chars: café, naïve, résumé\r\nThis line is very long and might need soft line breaks when encoded with quoted-printable encoding method\r\n=This line starts with equals sign'; const email = new Email({ from: 'sender@example.com', to: 'recipient@example.com', subject: 'Quoted-Printable Test', text: 'Email with quoted-printable attachment', attachments: [{ filename: 'special-chars.txt', content: Buffer.from(textWithSpecialChars, 'utf8'), contentType: 'text/plain; charset=utf-8', encoding: 'quoted-printable' }] }); const result = await smtpClient.sendMail(email); expect(result.success).toBeTrue(); console.log('✅ Quoted-printable encoding handled correctly'); }); tap.test('CEP-03: Attachment Encoding - should handle content-disposition', async () => { const email = new Email({ from: 'sender@example.com', to: 'recipient@example.com', subject: 'Content-Disposition Test', text: 'Testing attachment vs inline disposition', html: '
Image below:
HTML body with special chars: café
', attachments: [ { filename: 'base64.bin', content: crypto.randomBytes(1024), contentType: 'application/octet-stream', encoding: 'base64' }, { filename: 'quoted.txt', content: Buffer.from('Text with special chars: naïve café résumé'), contentType: 'text/plain; charset=utf-8', encoding: 'quoted-printable' }, { filename: '7bit.txt', content: Buffer.from('Simple ASCII text only'), contentType: 'text/plain', encoding: '7bit' } ] }); const result = await smtpClient.sendMail(email); expect(result.success).toBeTrue(); console.log('✅ Mixed encoding types handled correctly'); }); 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();