import { expect, tap } from '@git.zone/tstest/tapbundle'; import { TypedRequest } from '@api.global/typedrequest'; import { DcRouter } from '../ts/index.js'; import * as interfaces from '../ts_interfaces/index.js'; const TEST_PORT = 3201; const BASE_URL = `http://localhost:${TEST_PORT}/typedrequest`; let testDcRouter: DcRouter; let adminIdentity: interfaces.data.IIdentity; let removedQueueItemId: string | undefined; let lastEnqueueArgs: any[] | undefined; const queueItems = [ { id: 'failed-email-1', status: 'failed', attempts: 3, nextAttempt: new Date('2026-04-14T10:00:00.000Z'), lastError: '550 mailbox unavailable', processingMode: 'mta', route: undefined, createdAt: new Date('2026-04-14T09:00:00.000Z'), processingResult: { from: 'sender@example.com', to: ['recipient@example.net'], cc: ['copy@example.net'], subject: 'Older message', text: 'hello', headers: { 'x-test': '1' }, getMessageId: () => 'message-older', getAttachmentsSize: () => 64, }, }, { id: 'delivered-email-1', status: 'delivered', attempts: 1, processingMode: 'mta', route: undefined, createdAt: new Date('2026-04-14T11:00:00.000Z'), processingResult: { email: { from: 'fresh@example.com', to: ['new@example.net'], cc: [], subject: 'Newest message', }, html: '

newest

', text: 'newest', headers: { 'x-fresh': 'true' }, getMessageId: () => 'message-newer', getAttachmentsSize: () => 0, }, }, ]; tap.test('should start DCRouter with OpsServer for email API tests', async () => { testDcRouter = new DcRouter({ opsServerPort: TEST_PORT, dbConfig: { enabled: false }, }); await testDcRouter.start(); testDcRouter.emailServer = { getQueueItems: () => [...queueItems], getQueueItem: (id: string) => queueItems.find((item) => item.id === id), getQueueStats: () => ({ queueSize: 2, status: { pending: 0, processing: 1, failed: 1, deferred: 1, delivered: 1, }, }), deliveryQueue: { enqueue: async (...args: any[]) => { lastEnqueueArgs = args; return 'resent-queue-id'; }, removeItem: async (id: string) => { removedQueueItemId = id; return true; }, }, } as any; expect(testDcRouter.opsServer).toBeInstanceOf(Object); }); tap.test('should login as admin for email API tests', async () => { const loginRequest = new TypedRequest( BASE_URL, 'adminLoginWithUsernameAndPassword', ); const response = await loginRequest.fire({ username: 'admin', password: 'admin', }); adminIdentity = response.identity; expect(adminIdentity.jwt).toBeTruthy(); }); tap.test('should return queued emails through the email ops API', async () => { const request = new TypedRequest(BASE_URL, 'getAllEmails'); const response = await request.fire({ identity: adminIdentity, }); expect(response.emails.map((email) => email.id)).toEqual(['delivered-email-1', 'failed-email-1']); expect(response.emails[0].status).toEqual('delivered'); expect(response.emails[1].status).toEqual('bounced'); }); tap.test('should return email detail through the email ops API', async () => { const request = new TypedRequest(BASE_URL, 'getEmailDetail'); const response = await request.fire({ identity: adminIdentity, emailId: 'failed-email-1', }); expect(response.email?.toList).toEqual(['recipient@example.net']); expect(response.email?.cc).toEqual(['copy@example.net']); expect(response.email?.rejectionReason).toEqual('550 mailbox unavailable'); expect(response.email?.headers).toEqual({ 'x-test': '1' }); }); tap.test('should expose queue status through the stats API', async () => { const request = new TypedRequest(BASE_URL, 'getQueueStatus'); const response = await request.fire({ identity: adminIdentity, }); expect(response.queues.length).toEqual(1); expect(response.queues[0].size).toEqual(0); expect(response.queues[0].processing).toEqual(1); expect(response.queues[0].failed).toEqual(1); expect(response.queues[0].retrying).toEqual(1); expect(response.totalItems).toEqual(3); }); tap.test('should resend failed email through the admin email ops API', async () => { const request = new TypedRequest(BASE_URL, 'resendEmail'); const response = await request.fire({ identity: adminIdentity, emailId: 'failed-email-1', }); expect(response.success).toEqual(true); expect(response.newQueueId).toEqual('resent-queue-id'); expect(removedQueueItemId).toEqual('failed-email-1'); expect(lastEnqueueArgs?.[0]).toEqual(queueItems[0].processingResult); }); tap.test('should stop DCRouter after email API tests', async () => { await testDcRouter.stop(); }); tap.test('cleanup', async () => { await tap.stopForcefully(); }); export default tap.start();