248 lines
8.2 KiB
TypeScript
248 lines
8.2 KiB
TypeScript
|
import { tap, expect } from '@push.rocks/tapbundle';
|
||
|
import * as plugins from '../ts/plugins.js';
|
||
|
import * as paths from '../ts/paths.js';
|
||
|
|
||
|
// Import the components we want to test
|
||
|
import { EmailValidator } from '../ts/email/classes.emailvalidator.js';
|
||
|
import { TemplateManager } from '../ts/email/classes.templatemanager.js';
|
||
|
import { Email } from '../ts/mta/classes.email.js';
|
||
|
|
||
|
// Ensure test directories exist
|
||
|
paths.ensureDirectories();
|
||
|
|
||
|
tap.test('EmailValidator - should validate email formats correctly', async (tools) => {
|
||
|
const validator = new EmailValidator();
|
||
|
|
||
|
// Test valid email formats
|
||
|
expect(validator.isValidFormat('user@example.com')).toBeTrue();
|
||
|
expect(validator.isValidFormat('firstname.lastname@example.com')).toBeTrue();
|
||
|
expect(validator.isValidFormat('user+tag@example.com')).toBeTrue();
|
||
|
|
||
|
// Test invalid email formats
|
||
|
expect(validator.isValidFormat('user@')).toBeFalse();
|
||
|
expect(validator.isValidFormat('@example.com')).toBeFalse();
|
||
|
expect(validator.isValidFormat('user@example')).toBeFalse();
|
||
|
expect(validator.isValidFormat('user.example.com')).toBeFalse();
|
||
|
});
|
||
|
|
||
|
tap.test('EmailValidator - should perform comprehensive validation', async (tools) => {
|
||
|
const validator = new EmailValidator();
|
||
|
|
||
|
// Test basic validation (syntax-only)
|
||
|
const basicResult = await validator.validate('user@example.com', { checkSyntaxOnly: true });
|
||
|
expect(basicResult.isValid).toBeTrue();
|
||
|
expect(basicResult.details.formatValid).toBeTrue();
|
||
|
|
||
|
// We can't reliably test MX validation in all environments, but the function should run
|
||
|
const mxResult = await validator.validate('user@example.com', { checkMx: true });
|
||
|
expect(typeof mxResult.isValid).toEqual('boolean');
|
||
|
expect(typeof mxResult.hasMx).toEqual('boolean');
|
||
|
});
|
||
|
|
||
|
tap.test('EmailValidator - should detect invalid emails', async (tools) => {
|
||
|
const validator = new EmailValidator();
|
||
|
|
||
|
const invalidResult = await validator.validate('invalid@@example.com', { checkSyntaxOnly: true });
|
||
|
expect(invalidResult.isValid).toBeFalse();
|
||
|
expect(invalidResult.details.formatValid).toBeFalse();
|
||
|
});
|
||
|
|
||
|
tap.test('TemplateManager - should register and retrieve templates', async (tools) => {
|
||
|
const templateManager = new TemplateManager({
|
||
|
from: 'test@example.com'
|
||
|
});
|
||
|
|
||
|
// Register a custom template
|
||
|
templateManager.registerTemplate({
|
||
|
id: 'test-template',
|
||
|
name: 'Test Template',
|
||
|
description: 'A test template',
|
||
|
from: 'test@example.com',
|
||
|
subject: 'Test Subject: {{name}}',
|
||
|
bodyHtml: '<p>Hello, {{name}}!</p>',
|
||
|
bodyText: 'Hello, {{name}}!',
|
||
|
category: 'test'
|
||
|
});
|
||
|
|
||
|
// Get the template back
|
||
|
const template = templateManager.getTemplate('test-template');
|
||
|
expect(template).toBeTruthy();
|
||
|
expect(template.id).toEqual('test-template');
|
||
|
expect(template.subject).toEqual('Test Subject: {{name}}');
|
||
|
|
||
|
// List templates
|
||
|
const templates = templateManager.listTemplates();
|
||
|
expect(templates.length > 0).toBeTrue();
|
||
|
expect(templates.some(t => t.id === 'test-template')).toBeTrue();
|
||
|
});
|
||
|
|
||
|
tap.test('TemplateManager - should create smartmail from template', async (tools) => {
|
||
|
const templateManager = new TemplateManager({
|
||
|
from: 'test@example.com'
|
||
|
});
|
||
|
|
||
|
// Register a template
|
||
|
templateManager.registerTemplate({
|
||
|
id: 'welcome-test',
|
||
|
name: 'Welcome Test',
|
||
|
description: 'A welcome test template',
|
||
|
from: 'welcome@example.com',
|
||
|
subject: 'Welcome, {{name}}!',
|
||
|
bodyHtml: '<p>Hello, {{name}}! Welcome to our service.</p>',
|
||
|
bodyText: 'Hello, {{name}}! Welcome to our service.',
|
||
|
category: 'test'
|
||
|
});
|
||
|
|
||
|
// Create smartmail from template
|
||
|
const smartmail = await templateManager.createSmartmail('welcome-test', {
|
||
|
name: 'John Doe'
|
||
|
});
|
||
|
|
||
|
expect(smartmail).toBeTruthy();
|
||
|
expect(smartmail.options.from).toEqual('welcome@example.com');
|
||
|
expect(smartmail.getSubject()).toEqual('Welcome, John Doe!');
|
||
|
expect(smartmail.getBody(true).indexOf('Hello, John Doe!') > -1).toBeTrue();
|
||
|
});
|
||
|
|
||
|
tap.test('Email - should handle template variables', async (tools) => {
|
||
|
// Create email with variables
|
||
|
const email = new Email({
|
||
|
from: 'sender@example.com',
|
||
|
to: 'recipient@example.com',
|
||
|
subject: 'Hello {{name}}!',
|
||
|
text: 'Welcome, {{name}}! Your order #{{orderId}} has been processed.',
|
||
|
html: '<p>Welcome, <strong>{{name}}</strong>! Your order #{{orderId}} has been processed.</p>',
|
||
|
variables: {
|
||
|
name: 'John Doe',
|
||
|
orderId: '12345'
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// Test variable substitution
|
||
|
expect(email.getSubjectWithVariables()).toEqual('Hello John Doe!');
|
||
|
expect(email.getTextWithVariables()).toEqual('Welcome, John Doe! Your order #12345 has been processed.');
|
||
|
expect(email.getHtmlWithVariables().indexOf('<strong>John Doe</strong>') > -1).toBeTrue();
|
||
|
|
||
|
// Test with additional variables
|
||
|
const additionalVars = {
|
||
|
name: 'Jane Smith', // Override existing variable
|
||
|
status: 'shipped' // Add new variable
|
||
|
};
|
||
|
|
||
|
expect(email.getSubjectWithVariables(additionalVars)).toEqual('Hello Jane Smith!');
|
||
|
|
||
|
// Add a new variable
|
||
|
email.setVariable('trackingNumber', 'TRK123456');
|
||
|
expect(email.getTextWithVariables().indexOf('12345') > -1).toBeTrue();
|
||
|
|
||
|
// Update multiple variables at once
|
||
|
email.setVariables({
|
||
|
orderId: '67890',
|
||
|
status: 'delivered'
|
||
|
});
|
||
|
|
||
|
expect(email.getTextWithVariables().indexOf('67890') > -1).toBeTrue();
|
||
|
});
|
||
|
|
||
|
tap.test('Email and Smartmail compatibility - should convert between formats', async (tools) => {
|
||
|
// Create a Smartmail instance
|
||
|
const smartmail = new plugins.smartmail.Smartmail({
|
||
|
from: 'smartmail@example.com',
|
||
|
subject: 'Test Subject',
|
||
|
body: '<p>This is a test email.</p>',
|
||
|
creationObjectRef: {
|
||
|
orderId: '12345'
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// Add recipient and attachment
|
||
|
smartmail.addRecipient('recipient@example.com');
|
||
|
|
||
|
const attachment = await plugins.smartfile.SmartFile.fromString(
|
||
|
'test.txt',
|
||
|
'This is a test attachment',
|
||
|
'utf8',
|
||
|
);
|
||
|
|
||
|
smartmail.addAttachment(attachment);
|
||
|
|
||
|
// Convert to Email
|
||
|
const resolvedSmartmail = await smartmail;
|
||
|
const email = Email.fromSmartmail(resolvedSmartmail);
|
||
|
|
||
|
// Verify first conversion (Smartmail to Email)
|
||
|
expect(email.from).toEqual('smartmail@example.com');
|
||
|
expect(email.to.indexOf('recipient@example.com') > -1).toBeTrue();
|
||
|
expect(email.subject).toEqual('Test Subject');
|
||
|
expect(email.html?.indexOf('This is a test email') > -1).toBeTrue();
|
||
|
expect(email.attachments.length).toEqual(1);
|
||
|
|
||
|
// Convert back to Smartmail
|
||
|
const convertedSmartmail = await email.toSmartmail();
|
||
|
|
||
|
// Verify second conversion (Email back to Smartmail) with simplified assertions
|
||
|
expect(convertedSmartmail.options.from).toEqual('smartmail@example.com');
|
||
|
expect(Array.isArray(convertedSmartmail.options.to)).toBeTrue();
|
||
|
expect(convertedSmartmail.options.to.length).toEqual(1);
|
||
|
expect(convertedSmartmail.getSubject()).toEqual('Test Subject');
|
||
|
expect(convertedSmartmail.getBody(true).indexOf('This is a test email') > -1).toBeTrue();
|
||
|
expect(convertedSmartmail.attachments.length).toEqual(1);
|
||
|
});
|
||
|
|
||
|
tap.test('Email - should validate email addresses', async (tools) => {
|
||
|
// Attempt to create an email with invalid addresses
|
||
|
let errorThrown = false;
|
||
|
|
||
|
try {
|
||
|
const email = new Email({
|
||
|
from: 'invalid-email',
|
||
|
to: 'recipient@example.com',
|
||
|
subject: 'Test',
|
||
|
text: 'Test'
|
||
|
});
|
||
|
} catch (error) {
|
||
|
errorThrown = true;
|
||
|
expect(error.message.indexOf('Invalid sender email address') > -1).toBeTrue();
|
||
|
}
|
||
|
|
||
|
expect(errorThrown).toBeTrue();
|
||
|
|
||
|
// Attempt with invalid recipient
|
||
|
errorThrown = false;
|
||
|
|
||
|
try {
|
||
|
const email = new Email({
|
||
|
from: 'sender@example.com',
|
||
|
to: 'invalid-recipient',
|
||
|
subject: 'Test',
|
||
|
text: 'Test'
|
||
|
});
|
||
|
} catch (error) {
|
||
|
errorThrown = true;
|
||
|
expect(error.message.indexOf('Invalid recipient email address') > -1).toBeTrue();
|
||
|
}
|
||
|
|
||
|
expect(errorThrown).toBeTrue();
|
||
|
|
||
|
// Valid email should not throw
|
||
|
let validEmail: Email;
|
||
|
try {
|
||
|
validEmail = new Email({
|
||
|
from: 'sender@example.com',
|
||
|
to: 'recipient@example.com',
|
||
|
subject: 'Test',
|
||
|
text: 'Test'
|
||
|
});
|
||
|
|
||
|
expect(validEmail).toBeTruthy();
|
||
|
expect(validEmail.from).toEqual('sender@example.com');
|
||
|
} catch (error) {
|
||
|
expect(error === undefined).toBeTrue(); // This should not happen
|
||
|
}
|
||
|
});
|
||
|
|
||
|
tap.test('stop', async () => {
|
||
|
tap.stopForcefully();
|
||
|
})
|
||
|
|
||
|
export default tap.start();
|