245 lines
7.6 KiB
TypeScript
245 lines
7.6 KiB
TypeScript
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;
|
|
let smtpClient: SmtpClient;
|
|
|
|
tap.test('setup - start SMTP server for email composition tests', async () => {
|
|
testServer = await startTestServer({
|
|
port: 2570,
|
|
tlsEnabled: false,
|
|
authRequired: false
|
|
});
|
|
|
|
expect(testServer.port).toEqual(2570);
|
|
});
|
|
|
|
tap.test('setup - create SMTP client', async () => {
|
|
smtpClient = createSmtpClient({
|
|
host: testServer.hostname,
|
|
port: testServer.port,
|
|
secure: false,
|
|
connectionTimeout: 5000,
|
|
debug: true
|
|
});
|
|
|
|
const isConnected = await smtpClient.verify();
|
|
expect(isConnected).toBeTrue();
|
|
});
|
|
|
|
tap.test('CEP-01: Basic Headers - should send email with required headers', async () => {
|
|
const email = new Email({
|
|
from: 'sender@example.com',
|
|
to: 'recipient@example.com',
|
|
subject: 'Test Email with Basic Headers',
|
|
text: 'This is the plain text body'
|
|
});
|
|
|
|
const result = await smtpClient.sendMail(email);
|
|
|
|
expect(result.success).toBeTrue();
|
|
expect(result.acceptedRecipients).toContain('recipient@example.com');
|
|
expect(result.messageId).toBeTypeofString();
|
|
|
|
console.log('✅ Basic email headers sent successfully');
|
|
console.log('📧 Message ID:', result.messageId);
|
|
});
|
|
|
|
tap.test('CEP-01: Basic Headers - should handle multiple recipients', async () => {
|
|
const email = new Email({
|
|
from: 'sender@example.com',
|
|
to: ['recipient1@example.com', 'recipient2@example.com', 'recipient3@example.com'],
|
|
subject: 'Email to Multiple Recipients',
|
|
text: 'This email has multiple recipients'
|
|
});
|
|
|
|
const result = await smtpClient.sendMail(email);
|
|
|
|
expect(result.success).toBeTrue();
|
|
expect(result.acceptedRecipients).toContain('recipient1@example.com');
|
|
expect(result.acceptedRecipients).toContain('recipient2@example.com');
|
|
expect(result.acceptedRecipients).toContain('recipient3@example.com');
|
|
|
|
console.log(`✅ Sent to ${result.acceptedRecipients.length} recipients`);
|
|
});
|
|
|
|
tap.test('CEP-01: Basic Headers - should support CC and BCC recipients', async () => {
|
|
const email = new Email({
|
|
from: 'sender@example.com',
|
|
to: 'primary@example.com',
|
|
cc: ['cc1@example.com', 'cc2@example.com'],
|
|
bcc: ['bcc1@example.com', 'bcc2@example.com'],
|
|
subject: 'Email with CC and BCC',
|
|
text: 'Testing CC and BCC functionality'
|
|
});
|
|
|
|
const result = await smtpClient.sendMail(email);
|
|
|
|
expect(result.success).toBeTrue();
|
|
// All recipients should be accepted
|
|
expect(result.acceptedRecipients.length).toEqual(5);
|
|
|
|
console.log('✅ CC and BCC recipients handled correctly');
|
|
});
|
|
|
|
tap.test('CEP-01: Basic Headers - should add custom headers', async () => {
|
|
const email = new Email({
|
|
from: 'sender@example.com',
|
|
to: 'recipient@example.com',
|
|
subject: 'Email with Custom Headers',
|
|
text: 'This email contains custom headers',
|
|
headers: {
|
|
'X-Custom-Header': 'custom-value',
|
|
'X-Priority': '1',
|
|
'X-Mailer': 'DCRouter Test Suite',
|
|
'Reply-To': 'replies@example.com'
|
|
}
|
|
});
|
|
|
|
const result = await smtpClient.sendMail(email);
|
|
|
|
expect(result.success).toBeTrue();
|
|
console.log('✅ Custom headers added to email');
|
|
});
|
|
|
|
tap.test('CEP-01: Basic Headers - should set email priority', async () => {
|
|
// Test high priority
|
|
const highPriorityEmail = new Email({
|
|
from: 'sender@example.com',
|
|
to: 'recipient@example.com',
|
|
subject: 'High Priority Email',
|
|
text: 'This is a high priority message',
|
|
priority: 'high'
|
|
});
|
|
|
|
const highResult = await smtpClient.sendMail(highPriorityEmail);
|
|
expect(highResult.success).toBeTrue();
|
|
|
|
// Test normal priority
|
|
const normalPriorityEmail = new Email({
|
|
from: 'sender@example.com',
|
|
to: 'recipient@example.com',
|
|
subject: 'Normal Priority Email',
|
|
text: 'This is a normal priority message',
|
|
priority: 'normal'
|
|
});
|
|
|
|
const normalResult = await smtpClient.sendMail(normalPriorityEmail);
|
|
expect(normalResult.success).toBeTrue();
|
|
|
|
// Test low priority
|
|
const lowPriorityEmail = new Email({
|
|
from: 'sender@example.com',
|
|
to: 'recipient@example.com',
|
|
subject: 'Low Priority Email',
|
|
text: 'This is a low priority message',
|
|
priority: 'low'
|
|
});
|
|
|
|
const lowResult = await smtpClient.sendMail(lowPriorityEmail);
|
|
expect(lowResult.success).toBeTrue();
|
|
|
|
console.log('✅ All priority levels handled correctly');
|
|
});
|
|
|
|
tap.test('CEP-01: Basic Headers - should handle sender with display name', async () => {
|
|
const email = new Email({
|
|
from: 'John Doe <john.doe@example.com>',
|
|
to: 'Jane Smith <jane.smith@example.com>',
|
|
subject: 'Email with Display Names',
|
|
text: 'Testing display names in email addresses'
|
|
});
|
|
|
|
const result = await smtpClient.sendMail(email);
|
|
|
|
expect(result.success).toBeTrue();
|
|
expect(result.envelope?.from).toContain('john.doe@example.com');
|
|
|
|
console.log('✅ Display names in addresses handled correctly');
|
|
});
|
|
|
|
tap.test('CEP-01: Basic Headers - should generate proper Message-ID', async () => {
|
|
const email = new Email({
|
|
from: 'sender@example.com',
|
|
to: 'recipient@example.com',
|
|
subject: 'Message-ID Test',
|
|
text: 'Testing Message-ID generation'
|
|
});
|
|
|
|
const result = await smtpClient.sendMail(email);
|
|
|
|
expect(result.success).toBeTrue();
|
|
expect(result.messageId).toBeTypeofString();
|
|
|
|
// Message-ID should contain id@domain format (without angle brackets)
|
|
expect(result.messageId).toMatch(/^.+@.+$/);
|
|
|
|
console.log('✅ Valid Message-ID generated:', result.messageId);
|
|
});
|
|
|
|
tap.test('CEP-01: Basic Headers - should handle long subject lines', async () => {
|
|
const longSubject = 'This is a very long subject line that exceeds the typical length and might need to be wrapped according to RFC specifications for email headers';
|
|
|
|
const email = new Email({
|
|
from: 'sender@example.com',
|
|
to: 'recipient@example.com',
|
|
subject: longSubject,
|
|
text: 'Email with long subject line'
|
|
});
|
|
|
|
const result = await smtpClient.sendMail(email);
|
|
|
|
expect(result.success).toBeTrue();
|
|
console.log('✅ Long subject line handled correctly');
|
|
});
|
|
|
|
tap.test('CEP-01: Basic Headers - should sanitize header values', async () => {
|
|
// Test with potentially problematic characters
|
|
const email = new Email({
|
|
from: 'sender@example.com',
|
|
to: 'recipient@example.com',
|
|
subject: 'Subject with\nnewline and\rcarriage return',
|
|
text: 'Testing header sanitization',
|
|
headers: {
|
|
'X-Test-Header': 'Value with\nnewline'
|
|
}
|
|
});
|
|
|
|
const result = await smtpClient.sendMail(email);
|
|
|
|
expect(result.success).toBeTrue();
|
|
console.log('✅ Header values sanitized correctly');
|
|
});
|
|
|
|
tap.test('CEP-01: Basic Headers - should include Date header', async () => {
|
|
const email = new Email({
|
|
from: 'sender@example.com',
|
|
to: 'recipient@example.com',
|
|
subject: 'Date Header Test',
|
|
text: 'Testing automatic Date header'
|
|
});
|
|
|
|
const beforeSend = new Date();
|
|
const result = await smtpClient.sendMail(email);
|
|
const afterSend = new Date();
|
|
|
|
expect(result.success).toBeTrue();
|
|
|
|
// The email should have been sent between beforeSend and afterSend
|
|
console.log('✅ Date header automatically included');
|
|
});
|
|
|
|
tap.test('cleanup - close SMTP client', async () => {
|
|
if (smtpClient && smtpClient.isConnected()) {
|
|
await smtpClient.close();
|
|
}
|
|
});
|
|
|
|
tap.test('cleanup - stop SMTP server', async () => {
|
|
await stopTestServer(testServer);
|
|
});
|
|
|
|
export default tap.start(); |