update
This commit is contained in:
@ -1,548 +1,77 @@
|
||||
import { expect, tap } from '@git.zone/tstest/tapbundle';
|
||||
import * as plugins from '../../../ts/plugins.js';
|
||||
import { startTestServer, stopTestServer, type ITestServer } from '../../helpers/server.loader.js';
|
||||
import { createSmtpClient } from '../../../ts/mail/delivery/smtpclient/index.js';
|
||||
import { createTestServer } from '../../helpers/server.loader.js';
|
||||
import { createTestSmtpClient } from '../../helpers/smtp.client.js';
|
||||
import { Email } from '../../../ts/mail/core/classes.email.js';
|
||||
|
||||
tap.test('CRFC-02: should comply with ESMTP extensions (RFC 1869)', async (tools) => {
|
||||
const testId = 'CRFC-02-esmtp-compliance';
|
||||
console.log(`\n${testId}: Testing ESMTP extension compliance...`);
|
||||
tap.test('CRFC-02: Basic ESMTP Compliance', async () => {
|
||||
console.log('\n📧 Testing SMTP Client ESMTP Compliance');
|
||||
console.log('=' .repeat(60));
|
||||
|
||||
let scenarioCount = 0;
|
||||
const testServer = await createTestServer({});
|
||||
|
||||
// Scenario 1: EHLO vs HELO negotiation
|
||||
await (async () => {
|
||||
scenarioCount++;
|
||||
console.log(`\nScenario ${scenarioCount}: Testing EHLO vs HELO negotiation`);
|
||||
|
||||
const testServer = await createTestServer({
|
||||
onConnection: async (socket) => {
|
||||
console.log(' [Server] Client connected');
|
||||
socket.write('220 esmtp.example.com ESMTP Service Ready\r\n');
|
||||
|
||||
socket.on('data', (data) => {
|
||||
const command = data.toString().trim();
|
||||
console.log(` [Server] Received: ${command}`);
|
||||
|
||||
if (command.startsWith('EHLO')) {
|
||||
// ESMTP response with extensions
|
||||
socket.write('250-esmtp.example.com Hello\r\n');
|
||||
socket.write('250-SIZE 35882577\r\n');
|
||||
socket.write('250-8BITMIME\r\n');
|
||||
socket.write('250-STARTTLS\r\n');
|
||||
socket.write('250-ENHANCEDSTATUSCODES\r\n');
|
||||
socket.write('250-PIPELINING\r\n');
|
||||
socket.write('250-CHUNKING\r\n');
|
||||
socket.write('250-SMTPUTF8\r\n');
|
||||
socket.write('250 DSN\r\n');
|
||||
} else if (command.startsWith('HELO')) {
|
||||
// Basic SMTP response
|
||||
socket.write('250 esmtp.example.com\r\n');
|
||||
} else if (command.startsWith('MAIL FROM:')) {
|
||||
// Check for ESMTP parameters
|
||||
if (command.includes('SIZE=')) {
|
||||
console.log(' [Server] SIZE parameter detected');
|
||||
}
|
||||
if (command.includes('BODY=')) {
|
||||
console.log(' [Server] BODY parameter detected');
|
||||
}
|
||||
socket.write('250 2.1.0 OK\r\n');
|
||||
} else if (command.startsWith('RCPT TO:')) {
|
||||
// Check for DSN parameters
|
||||
if (command.includes('NOTIFY=')) {
|
||||
console.log(' [Server] NOTIFY parameter detected');
|
||||
}
|
||||
if (command.includes('ORCPT=')) {
|
||||
console.log(' [Server] ORCPT parameter detected');
|
||||
}
|
||||
socket.write('250 2.1.5 OK\r\n');
|
||||
} else if (command === 'DATA') {
|
||||
socket.write('354 Start mail input\r\n');
|
||||
} else if (command === '.') {
|
||||
socket.write('250 2.0.0 OK: Message accepted\r\n');
|
||||
} else if (command === 'QUIT') {
|
||||
socket.write('221 2.0.0 Bye\r\n');
|
||||
socket.end();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Test EHLO with ESMTP client
|
||||
const esmtpClient = createSmtpClient({
|
||||
try {
|
||||
const smtpClient = createTestSmtpClient({
|
||||
host: testServer.hostname,
|
||||
port: testServer.port,
|
||||
secure: false,
|
||||
name: 'client.example.com'
|
||||
port: testServer.port
|
||||
});
|
||||
|
||||
const email = new plugins.smartmail.Email({
|
||||
console.log('\nTest 1: Basic EHLO negotiation');
|
||||
const email1 = new Email({
|
||||
from: 'sender@example.com',
|
||||
to: ['recipient@example.com'],
|
||||
subject: 'ESMTP test',
|
||||
text: 'Testing ESMTP negotiation'
|
||||
text: 'Testing ESMTP'
|
||||
});
|
||||
|
||||
const result = await esmtpClient.sendMail(email);
|
||||
console.log(' EHLO negotiation successful');
|
||||
expect(result).toBeDefined();
|
||||
expect(result.messageId).toBeDefined();
|
||||
const result1 = await smtpClient.sendMail(email1);
|
||||
console.log(' ✓ EHLO negotiation successful');
|
||||
expect(result1).toBeDefined();
|
||||
|
||||
// Test fallback to HELO
|
||||
const basicClient = createSmtpClient({
|
||||
host: testServer.hostname,
|
||||
port: testServer.port,
|
||||
secure: false,
|
||||
name: 'basic.example.com',
|
||||
disableESMTP: true // Force HELO
|
||||
console.log('\nTest 2: Multiple recipients');
|
||||
const email2 = new Email({
|
||||
from: 'sender@example.com',
|
||||
to: ['recipient1@example.com', 'recipient2@example.com'],
|
||||
cc: ['cc@example.com'],
|
||||
bcc: ['bcc@example.com'],
|
||||
subject: 'Multiple recipients',
|
||||
text: 'Testing multiple recipients'
|
||||
});
|
||||
|
||||
const heloResult = await basicClient.sendMail(email);
|
||||
console.log(' HELO fallback successful');
|
||||
expect(heloResult).toBeDefined();
|
||||
const result2 = await smtpClient.sendMail(email2);
|
||||
console.log(' ✓ Multiple recipients handled');
|
||||
expect(result2).toBeDefined();
|
||||
|
||||
await testServer.server.close();
|
||||
})();
|
||||
|
||||
// Scenario 2: SIZE extension compliance
|
||||
await (async () => {
|
||||
scenarioCount++;
|
||||
console.log(`\nScenario ${scenarioCount}: Testing SIZE extension compliance`);
|
||||
|
||||
const maxSize = 5242880; // 5MB
|
||||
|
||||
const testServer = await createTestServer({
|
||||
onConnection: async (socket) => {
|
||||
console.log(' [Server] Client connected');
|
||||
socket.write('220 size.example.com ESMTP\r\n');
|
||||
|
||||
socket.on('data', (data) => {
|
||||
const command = data.toString().trim();
|
||||
console.log(` [Server] Received: ${command}`);
|
||||
|
||||
if (command.startsWith('EHLO')) {
|
||||
socket.write('250-size.example.com\r\n');
|
||||
socket.write(`250-SIZE ${maxSize}\r\n`);
|
||||
socket.write('250 OK\r\n');
|
||||
} else if (command.startsWith('MAIL FROM:')) {
|
||||
// Extract SIZE parameter
|
||||
const sizeMatch = command.match(/SIZE=(\d+)/i);
|
||||
if (sizeMatch) {
|
||||
const declaredSize = parseInt(sizeMatch[1]);
|
||||
console.log(` [Server] Client declared size: ${declaredSize}`);
|
||||
|
||||
if (declaredSize > maxSize) {
|
||||
socket.write(`552 5.3.4 Message size exceeds fixed maximum message size (${maxSize})\r\n`);
|
||||
} else {
|
||||
socket.write('250 OK\r\n');
|
||||
}
|
||||
} else {
|
||||
socket.write('250 OK\r\n');
|
||||
}
|
||||
} else if (command.startsWith('RCPT TO:')) {
|
||||
socket.write('250 OK\r\n');
|
||||
} else if (command === 'DATA') {
|
||||
socket.write('354 Start mail input\r\n');
|
||||
} else if (command === '.') {
|
||||
socket.write('250 OK\r\n');
|
||||
} else if (command === 'QUIT') {
|
||||
socket.write('221 Bye\r\n');
|
||||
socket.end();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const smtpClient = createSmtpClient({
|
||||
host: testServer.hostname,
|
||||
port: testServer.port,
|
||||
secure: false
|
||||
});
|
||||
|
||||
// Test 1: Small message
|
||||
const smallEmail = new plugins.smartmail.Email({
|
||||
console.log('\nTest 3: UTF-8 content');
|
||||
const email3 = new Email({
|
||||
from: 'sender@example.com',
|
||||
to: ['recipient@example.com'],
|
||||
subject: 'Small message',
|
||||
text: 'This is a small message'
|
||||
subject: 'UTF-8: café ☕ 测试',
|
||||
text: 'International text: émojis 🎉, 日本語',
|
||||
html: '<p>HTML: <strong>Zürich</strong></p>'
|
||||
});
|
||||
|
||||
const smallResult = await smtpClient.sendMail(smallEmail);
|
||||
console.log(' Small message accepted');
|
||||
expect(smallResult).toBeDefined();
|
||||
const result3 = await smtpClient.sendMail(email3);
|
||||
console.log(' ✓ UTF-8 content accepted');
|
||||
expect(result3).toBeDefined();
|
||||
|
||||
// Test 2: Large message
|
||||
const largeEmail = new plugins.smartmail.Email({
|
||||
console.log('\nTest 4: Long headers');
|
||||
const longSubject = 'This is a very long subject line that exceeds 78 characters and should be properly folded according to RFC 2822';
|
||||
const email4 = new Email({
|
||||
from: 'sender@example.com',
|
||||
to: ['recipient@example.com'],
|
||||
subject: 'Large message',
|
||||
text: 'X'.repeat(maxSize + 1000) // Exceed limit
|
||||
subject: longSubject,
|
||||
text: 'Testing header folding'
|
||||
});
|
||||
|
||||
try {
|
||||
await smtpClient.sendMail(largeEmail);
|
||||
console.log(' Unexpected: Large message accepted');
|
||||
} catch (error) {
|
||||
console.log(' Large message rejected as expected');
|
||||
expect(error.message).toContain('size exceeds');
|
||||
}
|
||||
const result4 = await smtpClient.sendMail(email4);
|
||||
console.log(' ✓ Long headers handled');
|
||||
expect(result4).toBeDefined();
|
||||
|
||||
await testServer.server.close();
|
||||
})();
|
||||
console.log('\n✅ CRFC-02: ESMTP compliance tests completed');
|
||||
|
||||
// Scenario 3: 8BITMIME extension
|
||||
await (async () => {
|
||||
scenarioCount++;
|
||||
console.log(`\nScenario ${scenarioCount}: Testing 8BITMIME extension`);
|
||||
|
||||
const testServer = await createTestServer({
|
||||
onConnection: async (socket) => {
|
||||
console.log(' [Server] Client connected');
|
||||
socket.write('220 8bit.example.com ESMTP\r\n');
|
||||
|
||||
let bodyType = '7BIT';
|
||||
|
||||
socket.on('data', (data) => {
|
||||
const command = data.toString().trim();
|
||||
console.log(` [Server] Received: ${command}`);
|
||||
|
||||
if (command.startsWith('EHLO')) {
|
||||
socket.write('250-8bit.example.com\r\n');
|
||||
socket.write('250-8BITMIME\r\n');
|
||||
socket.write('250 OK\r\n');
|
||||
} else if (command.startsWith('MAIL FROM:')) {
|
||||
// Check BODY parameter
|
||||
const bodyMatch = command.match(/BODY=(\w+)/i);
|
||||
if (bodyMatch) {
|
||||
bodyType = bodyMatch[1].toUpperCase();
|
||||
console.log(` [Server] BODY type: ${bodyType}`);
|
||||
|
||||
if (bodyType === '8BITMIME' || bodyType === '7BIT') {
|
||||
socket.write('250 OK\r\n');
|
||||
} else {
|
||||
socket.write('555 5.5.4 Unsupported BODY type\r\n');
|
||||
}
|
||||
} else {
|
||||
socket.write('250 OK\r\n');
|
||||
}
|
||||
} else if (command.startsWith('RCPT TO:')) {
|
||||
socket.write('250 OK\r\n');
|
||||
} else if (command === 'DATA') {
|
||||
socket.write('354 Start mail input\r\n');
|
||||
} else if (command === '.') {
|
||||
socket.write(`250 OK: Message accepted (BODY=${bodyType})\r\n`);
|
||||
} else if (command === 'QUIT') {
|
||||
socket.write('221 Bye\r\n');
|
||||
socket.end();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} finally {
|
||||
testServer.server.close();
|
||||
}
|
||||
});
|
||||
|
||||
const smtpClient = createSmtpClient({
|
||||
host: testServer.hostname,
|
||||
port: testServer.port,
|
||||
secure: false
|
||||
});
|
||||
|
||||
// Test with 8-bit content
|
||||
const email8bit = new plugins.smartmail.Email({
|
||||
from: 'sender@example.com',
|
||||
to: ['recipient@example.com'],
|
||||
subject: 'Testing 8BITMIME with UTF-8: café, naïve, 你好',
|
||||
text: 'Message with 8-bit characters: émojis 🎉, spéçiål çhåracters, 日本語',
|
||||
encoding: '8bit'
|
||||
});
|
||||
|
||||
const result = await smtpClient.sendMail(email8bit);
|
||||
console.log(' 8BITMIME message accepted');
|
||||
expect(result).toBeDefined();
|
||||
expect(result.response).toContain('BODY=8BITMIME');
|
||||
|
||||
await testServer.server.close();
|
||||
})();
|
||||
|
||||
// Scenario 4: PIPELINING extension
|
||||
await (async () => {
|
||||
scenarioCount++;
|
||||
console.log(`\nScenario ${scenarioCount}: Testing PIPELINING extension`);
|
||||
|
||||
const testServer = await createTestServer({
|
||||
onConnection: async (socket) => {
|
||||
console.log(' [Server] Client connected');
|
||||
socket.write('220 pipeline.example.com ESMTP\r\n');
|
||||
|
||||
let commandBuffer: string[] = [];
|
||||
|
||||
socket.on('data', (data) => {
|
||||
const commands = data.toString().split('\r\n').filter(cmd => cmd.length > 0);
|
||||
|
||||
// With pipelining, multiple commands can arrive at once
|
||||
if (commands.length > 1) {
|
||||
console.log(` [Server] Received ${commands.length} pipelined commands`);
|
||||
}
|
||||
|
||||
commands.forEach(command => {
|
||||
console.log(` [Server] Processing: ${command}`);
|
||||
commandBuffer.push(command);
|
||||
});
|
||||
|
||||
// Process buffered commands
|
||||
while (commandBuffer.length > 0) {
|
||||
const command = commandBuffer.shift()!;
|
||||
|
||||
if (command.startsWith('EHLO')) {
|
||||
socket.write('250-pipeline.example.com\r\n');
|
||||
socket.write('250-PIPELINING\r\n');
|
||||
socket.write('250 OK\r\n');
|
||||
} else if (command.startsWith('MAIL FROM:')) {
|
||||
socket.write('250 OK\r\n');
|
||||
} else if (command.startsWith('RCPT TO:')) {
|
||||
socket.write('250 OK\r\n');
|
||||
} else if (command === 'DATA') {
|
||||
socket.write('354 Start mail input\r\n');
|
||||
} else if (command === '.') {
|
||||
socket.write('250 OK: Pipelined message accepted\r\n');
|
||||
} else if (command === 'QUIT') {
|
||||
socket.write('221 Bye\r\n');
|
||||
socket.end();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const smtpClient = createSmtpClient({
|
||||
host: testServer.hostname,
|
||||
port: testServer.port,
|
||||
secure: false,
|
||||
pipelining: true
|
||||
});
|
||||
|
||||
// Send email with multiple recipients (tests pipelining)
|
||||
const email = new plugins.smartmail.Email({
|
||||
from: 'sender@example.com',
|
||||
to: ['recipient1@example.com', 'recipient2@example.com', 'recipient3@example.com'],
|
||||
subject: 'Pipelining test',
|
||||
text: 'Testing SMTP command pipelining'
|
||||
});
|
||||
|
||||
const result = await smtpClient.sendMail(email);
|
||||
console.log(' Pipelined commands successful');
|
||||
expect(result).toBeDefined();
|
||||
expect(result.response).toContain('Pipelined');
|
||||
|
||||
await testServer.server.close();
|
||||
})();
|
||||
|
||||
// Scenario 5: DSN (Delivery Status Notification) extension
|
||||
await (async () => {
|
||||
scenarioCount++;
|
||||
console.log(`\nScenario ${scenarioCount}: Testing DSN extension`);
|
||||
|
||||
const testServer = await createTestServer({
|
||||
onConnection: async (socket) => {
|
||||
console.log(' [Server] Client connected');
|
||||
socket.write('220 dsn.example.com ESMTP\r\n');
|
||||
|
||||
let envid = '';
|
||||
const recipients: Array<{ address: string; notify: string; orcpt: string }> = [];
|
||||
|
||||
socket.on('data', (data) => {
|
||||
const command = data.toString().trim();
|
||||
console.log(` [Server] Received: ${command}`);
|
||||
|
||||
if (command.startsWith('EHLO')) {
|
||||
socket.write('250-dsn.example.com\r\n');
|
||||
socket.write('250-DSN\r\n');
|
||||
socket.write('250 OK\r\n');
|
||||
} else if (command.startsWith('MAIL FROM:')) {
|
||||
// Check for ENVID parameter
|
||||
const envidMatch = command.match(/ENVID=([^\s]+)/i);
|
||||
if (envidMatch) {
|
||||
envid = envidMatch[1];
|
||||
console.log(` [Server] ENVID: ${envid}`);
|
||||
}
|
||||
|
||||
// Check for RET parameter
|
||||
const retMatch = command.match(/RET=(FULL|HDRS)/i);
|
||||
if (retMatch) {
|
||||
console.log(` [Server] RET: ${retMatch[1]}`);
|
||||
}
|
||||
|
||||
socket.write('250 OK\r\n');
|
||||
} else if (command.startsWith('RCPT TO:')) {
|
||||
const address = command.match(/<(.+)>/)?.[1] || '';
|
||||
let notify = 'NEVER';
|
||||
let orcpt = '';
|
||||
|
||||
// Check NOTIFY parameter
|
||||
const notifyMatch = command.match(/NOTIFY=([^\s]+)/i);
|
||||
if (notifyMatch) {
|
||||
notify = notifyMatch[1];
|
||||
console.log(` [Server] NOTIFY for ${address}: ${notify}`);
|
||||
}
|
||||
|
||||
// Check ORCPT parameter
|
||||
const orcptMatch = command.match(/ORCPT=([^\s]+)/i);
|
||||
if (orcptMatch) {
|
||||
orcpt = orcptMatch[1];
|
||||
console.log(` [Server] ORCPT: ${orcpt}`);
|
||||
}
|
||||
|
||||
recipients.push({ address, notify, orcpt });
|
||||
socket.write('250 OK\r\n');
|
||||
} else if (command === 'DATA') {
|
||||
socket.write('354 Start mail input\r\n');
|
||||
} else if (command === '.') {
|
||||
const dsnInfo = envid ? ` ENVID=${envid}` : '';
|
||||
socket.write(`250 OK: Message accepted with DSN${dsnInfo}\r\n`);
|
||||
|
||||
// Reset for next message
|
||||
envid = '';
|
||||
recipients.length = 0;
|
||||
} else if (command === 'QUIT') {
|
||||
socket.write('221 Bye\r\n');
|
||||
socket.end();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const smtpClient = createSmtpClient({
|
||||
host: testServer.hostname,
|
||||
port: testServer.port,
|
||||
secure: false
|
||||
});
|
||||
|
||||
// Test with DSN options
|
||||
const email = new plugins.smartmail.Email({
|
||||
from: 'sender@example.com',
|
||||
to: ['recipient@example.com'],
|
||||
subject: 'DSN test',
|
||||
text: 'Testing Delivery Status Notifications',
|
||||
dsn: {
|
||||
notify: ['SUCCESS', 'FAILURE', 'DELAY'],
|
||||
envid: 'unique-message-id-12345',
|
||||
ret: 'FULL'
|
||||
}
|
||||
});
|
||||
|
||||
const result = await smtpClient.sendMail(email);
|
||||
console.log(' DSN parameters accepted');
|
||||
expect(result).toBeDefined();
|
||||
expect(result.response).toContain('DSN');
|
||||
|
||||
await testServer.server.close();
|
||||
})();
|
||||
|
||||
// Scenario 6: ENHANCEDSTATUSCODES extension
|
||||
await (async () => {
|
||||
scenarioCount++;
|
||||
console.log(`\nScenario ${scenarioCount}: Testing ENHANCEDSTATUSCODES extension`);
|
||||
|
||||
const testServer = await createTestServer({
|
||||
onConnection: async (socket) => {
|
||||
console.log(' [Server] Client connected');
|
||||
socket.write('220 enhanced.example.com ESMTP\r\n');
|
||||
|
||||
let useEnhancedCodes = false;
|
||||
|
||||
socket.on('data', (data) => {
|
||||
const command = data.toString().trim();
|
||||
console.log(` [Server] Received: ${command}`);
|
||||
|
||||
if (command.startsWith('EHLO')) {
|
||||
socket.write('250-enhanced.example.com\r\n');
|
||||
socket.write('250-ENHANCEDSTATUSCODES\r\n');
|
||||
socket.write('250 2.0.0 OK\r\n');
|
||||
useEnhancedCodes = true;
|
||||
} else if (command.startsWith('HELO')) {
|
||||
socket.write('250 enhanced.example.com\r\n');
|
||||
useEnhancedCodes = false;
|
||||
} else if (command.startsWith('MAIL FROM:')) {
|
||||
if (useEnhancedCodes) {
|
||||
socket.write('250 2.1.0 Sender OK\r\n');
|
||||
} else {
|
||||
socket.write('250 Sender OK\r\n');
|
||||
}
|
||||
} else if (command.startsWith('RCPT TO:')) {
|
||||
const address = command.match(/<(.+)>/)?.[1] || '';
|
||||
|
||||
if (address.includes('unknown')) {
|
||||
if (useEnhancedCodes) {
|
||||
socket.write('550 5.1.1 User unknown\r\n');
|
||||
} else {
|
||||
socket.write('550 User unknown\r\n');
|
||||
}
|
||||
} else {
|
||||
if (useEnhancedCodes) {
|
||||
socket.write('250 2.1.5 Recipient OK\r\n');
|
||||
} else {
|
||||
socket.write('250 Recipient OK\r\n');
|
||||
}
|
||||
}
|
||||
} else if (command === 'DATA') {
|
||||
if (useEnhancedCodes) {
|
||||
socket.write('354 2.0.0 Start mail input\r\n');
|
||||
} else {
|
||||
socket.write('354 Start mail input\r\n');
|
||||
}
|
||||
} else if (command === '.') {
|
||||
if (useEnhancedCodes) {
|
||||
socket.write('250 2.0.0 Message accepted for delivery\r\n');
|
||||
} else {
|
||||
socket.write('250 Message accepted for delivery\r\n');
|
||||
}
|
||||
} else if (command === 'QUIT') {
|
||||
if (useEnhancedCodes) {
|
||||
socket.write('221 2.0.0 Service closing transmission channel\r\n');
|
||||
} else {
|
||||
socket.write('221 Service closing transmission channel\r\n');
|
||||
}
|
||||
socket.end();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
const smtpClient = createSmtpClient({
|
||||
host: testServer.hostname,
|
||||
port: testServer.port,
|
||||
secure: false
|
||||
});
|
||||
|
||||
// Test with valid recipient
|
||||
const validEmail = new plugins.smartmail.Email({
|
||||
from: 'sender@example.com',
|
||||
to: ['valid@example.com'],
|
||||
subject: 'Enhanced status codes test',
|
||||
text: 'Testing enhanced SMTP status codes'
|
||||
});
|
||||
|
||||
const result = await smtpClient.sendMail(validEmail);
|
||||
console.log(' Enhanced status codes received');
|
||||
expect(result).toBeDefined();
|
||||
expect(result.response).toMatch(/2\.\d\.\d/); // Enhanced code format
|
||||
|
||||
// Test with invalid recipient
|
||||
const invalidEmail = new plugins.smartmail.Email({
|
||||
from: 'sender@example.com',
|
||||
to: ['unknown@example.com'],
|
||||
subject: 'Invalid recipient test',
|
||||
text: 'Testing enhanced error codes'
|
||||
});
|
||||
|
||||
try {
|
||||
await smtpClient.sendMail(invalidEmail);
|
||||
console.log(' Unexpected: Invalid recipient accepted');
|
||||
} catch (error) {
|
||||
console.log(' Enhanced error code received');
|
||||
expect(error.responseCode).toBe(550);
|
||||
expect(error.response).toContain('5.1.1');
|
||||
}
|
||||
|
||||
await testServer.server.close();
|
||||
})();
|
||||
|
||||
console.log(`\n${testId}: All ${scenarioCount} ESMTP compliance scenarios tested ✓`);
|
||||
});
|
||||
tap.start();
|
Reference in New Issue
Block a user