mxrelay-consumer/tests/client.test.ts
2025-08-18 22:22:04 +07:00

131 lines
No EOL
3.7 KiB
TypeScript

import { SMTPOverWSClient, ConnectionState, MessagePriority } from '../src/index';
describe('SMTPOverWSClient', () => {
let client: SMTPOverWSClient;
beforeEach(() => {
client = new SMTPOverWSClient({
url: 'ws://localhost:3000/smtp',
apiKey: 'test-api-key'
});
});
afterEach(async () => {
if (client) {
await client.shutdown();
}
});
describe('constructor', () => {
it('should create client with default configuration', () => {
expect(client.getConnectionState()).toBe(ConnectionState.DISCONNECTED);
expect(client.getQueueSize()).toBe(0);
});
it('should throw error for missing URL', () => {
expect(() => {
new SMTPOverWSClient({
url: '',
apiKey: 'test-key'
});
}).toThrow('URL is required');
});
it('should throw error for missing API key', () => {
expect(() => {
new SMTPOverWSClient({
url: 'ws://localhost:3000',
apiKey: ''
});
}).toThrow('API key is required');
});
});
describe('sendSMTPCommand', () => {
it('should queue message and return promise', async () => {
const promise = client.sendSMTPCommand('EHLO example.com\\r\\n');
expect(client.getQueueSize()).toBe(1);
expect(promise).toBeInstanceOf(Promise);
// Clean up
client.clearQueue();
});
it('should respect priority ordering', async () => {
// Queue messages with different priorities
const lowPromise = client.sendSMTPCommand('LOW', { priority: MessagePriority.LOW });
const highPromise = client.sendSMTPCommand('HIGH', { priority: MessagePriority.HIGH });
const normalPromise = client.sendSMTPCommand('NORMAL', { priority: MessagePriority.NORMAL });
expect(client.getQueueSize()).toBe(3);
// Clean up
client.clearQueue();
});
it('should reject when client is shutting down', async () => {
const shutdownPromise = client.shutdown();
await expect(client.sendSMTPCommand('TEST')).rejects.toThrow('Client is shutting down');
await shutdownPromise;
});
it('should reject when queue is full', async () => {
const smallQueueClient = new SMTPOverWSClient({
url: 'ws://localhost:3000/smtp',
apiKey: 'test-key',
maxQueueSize: 2
});
// Fill queue
smallQueueClient.sendSMTPCommand('MSG1');
smallQueueClient.sendSMTPCommand('MSG2');
// This should fail
await expect(smallQueueClient.sendSMTPCommand('MSG3')).rejects.toThrow('Queue is full');
await smallQueueClient.shutdown();
});
});
describe('statistics', () => {
it('should provide initial statistics', () => {
const stats = client.getStats();
expect(stats).toEqual({
messagesQueued: 0,
messagesProcessed: 0,
messagesFailed: 0,
reconnectionAttempts: 0,
totalConnections: 0,
averageResponseTime: 0,
queueSize: 0,
connectionUptime: 0
});
});
});
describe('queue management', () => {
it('should clear queue', () => {
client.sendSMTPCommand('MSG1');
client.sendSMTPCommand('MSG2');
expect(client.getQueueSize()).toBe(2);
client.clearQueue();
expect(client.getQueueSize()).toBe(0);
});
});
describe('shutdown', () => {
it('should shutdown gracefully', async () => {
await expect(client.shutdown()).resolves.toBeUndefined();
expect(client.getConnectionState()).toBe(ConnectionState.DISCONNECTED);
});
it('should timeout if shutdown takes too long', async () => {
await expect(client.shutdown(100)).resolves.toBeUndefined();
});
});
});