platformservice/test/test.smartmail.ts

248 lines
8.2 KiB
TypeScript
Raw Permalink Normal View History

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
2025-05-08 01:13:54 +00:00
import { EmailValidator } from '../ts/mail/core/classes.emailvalidator.js';
import { TemplateManager } from '../ts/mail/core/classes.templatemanager.js';
import { Email } from '../ts/mail/core/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();