- Add unit tests for DNS route generation and socket handler creation - Add unit tests for email route generation in both modes - Add integration tests for combined DNS and email configuration - Test TLS handling differences between email ports - Verify socket-handler vs traditional forwarding mode behavior - All tests pass without requiring actual port binding - Mark implementation plan as complete with full test coverage
198 lines
6.3 KiB
TypeScript
198 lines
6.3 KiB
TypeScript
import { tap, expect } from '@git.zone/tstest/tapbundle';
|
|
import { DcRouter } from '../ts/classes.dcrouter.js';
|
|
|
|
/**
|
|
* Unit tests for socket-handler functionality
|
|
* These tests focus on the configuration and route generation logic
|
|
* without actually starting services on real ports
|
|
*/
|
|
|
|
let dcRouter: DcRouter;
|
|
|
|
tap.test('DNS route generation with dnsDomain', async () => {
|
|
dcRouter = new DcRouter({
|
|
dnsDomain: 'dns.unit.test'
|
|
});
|
|
|
|
// Test the route generation directly
|
|
const dnsRoutes = (dcRouter as any).generateDnsRoutes();
|
|
|
|
expect(dnsRoutes).toBeDefined();
|
|
expect(dnsRoutes.length).toEqual(2);
|
|
|
|
// Check /dns-query route
|
|
const dnsQueryRoute = dnsRoutes[0];
|
|
expect(dnsQueryRoute.name).toEqual('dns-over-https-dns-query');
|
|
expect(dnsQueryRoute.match.ports).toEqual([443]);
|
|
expect(dnsQueryRoute.match.domains).toEqual(['dns.unit.test']);
|
|
expect(dnsQueryRoute.match.path).toEqual('/dns-query');
|
|
expect(dnsQueryRoute.action.type).toEqual('socket-handler');
|
|
expect(dnsQueryRoute.action.socketHandler).toBeDefined();
|
|
|
|
// Check /resolve route
|
|
const resolveRoute = dnsRoutes[1];
|
|
expect(resolveRoute.name).toEqual('dns-over-https-resolve');
|
|
expect(resolveRoute.match.ports).toEqual([443]);
|
|
expect(resolveRoute.match.domains).toEqual(['dns.unit.test']);
|
|
expect(resolveRoute.match.path).toEqual('/resolve');
|
|
expect(resolveRoute.action.type).toEqual('socket-handler');
|
|
expect(resolveRoute.action.socketHandler).toBeDefined();
|
|
});
|
|
|
|
tap.test('DNS route generation without dnsDomain', async () => {
|
|
dcRouter = new DcRouter({
|
|
// No dnsDomain set
|
|
});
|
|
|
|
const dnsRoutes = (dcRouter as any).generateDnsRoutes();
|
|
|
|
expect(dnsRoutes).toBeDefined();
|
|
expect(dnsRoutes.length).toEqual(0); // No routes generated
|
|
});
|
|
|
|
tap.test('Email route generation with socket-handler', async () => {
|
|
const emailConfig = {
|
|
ports: [25, 587, 465],
|
|
hostname: 'mail.unit.test',
|
|
domains: ['unit.test'],
|
|
routes: [],
|
|
useSocketHandler: true
|
|
};
|
|
|
|
dcRouter = new DcRouter({ emailConfig });
|
|
|
|
const emailRoutes = (dcRouter as any).generateEmailRoutes(emailConfig);
|
|
|
|
expect(emailRoutes).toBeDefined();
|
|
expect(emailRoutes.length).toEqual(3);
|
|
|
|
// Check all routes use socket-handler
|
|
emailRoutes.forEach((route: any) => {
|
|
expect(route.action.type).toEqual('socket-handler');
|
|
expect(route.action.socketHandler).toBeDefined();
|
|
expect(typeof route.action.socketHandler).toEqual('function');
|
|
});
|
|
|
|
// Check specific ports
|
|
const port25Route = emailRoutes.find((r: any) => r.match.ports[0] === 25);
|
|
expect(port25Route.name).toEqual('smtp-route');
|
|
|
|
const port587Route = emailRoutes.find((r: any) => r.match.ports[0] === 587);
|
|
expect(port587Route.name).toEqual('submission-route');
|
|
|
|
const port465Route = emailRoutes.find((r: any) => r.match.ports[0] === 465);
|
|
expect(port465Route.name).toEqual('smtps-route');
|
|
});
|
|
|
|
tap.test('Email route generation with traditional forwarding', async () => {
|
|
const emailConfig = {
|
|
ports: [25, 587],
|
|
hostname: 'mail.unit.test',
|
|
domains: ['unit.test'],
|
|
routes: [],
|
|
useSocketHandler: false // Traditional mode
|
|
};
|
|
|
|
dcRouter = new DcRouter({ emailConfig });
|
|
|
|
const emailRoutes = (dcRouter as any).generateEmailRoutes(emailConfig);
|
|
|
|
expect(emailRoutes).toBeDefined();
|
|
expect(emailRoutes.length).toEqual(2);
|
|
|
|
// Check all routes use forward action
|
|
emailRoutes.forEach((route: any) => {
|
|
expect(route.action.type).toEqual('forward');
|
|
expect(route.action.target).toBeDefined();
|
|
expect(route.action.target.host).toEqual('localhost');
|
|
expect(route.action.target.port).toBeGreaterThan(10000); // Internal port
|
|
});
|
|
});
|
|
|
|
tap.test('Email TLS modes are set correctly', async () => {
|
|
const emailConfig = {
|
|
ports: [25, 465],
|
|
hostname: 'mail.unit.test',
|
|
domains: ['unit.test'],
|
|
routes: [],
|
|
useSocketHandler: false
|
|
};
|
|
|
|
dcRouter = new DcRouter({ emailConfig });
|
|
|
|
const emailRoutes = (dcRouter as any).generateEmailRoutes(emailConfig);
|
|
|
|
// Port 25 should use passthrough (STARTTLS)
|
|
const port25Route = emailRoutes.find((r: any) => r.match.ports[0] === 25);
|
|
expect(port25Route.action.tls.mode).toEqual('passthrough');
|
|
|
|
// Port 465 should use terminate (implicit TLS)
|
|
const port465Route = emailRoutes.find((r: any) => r.match.ports[0] === 465);
|
|
expect(port465Route.action.tls.mode).toEqual('terminate');
|
|
expect(port465Route.action.tls.certificate).toEqual('auto');
|
|
});
|
|
|
|
tap.test('Combined DNS and email configuration', async () => {
|
|
dcRouter = new DcRouter({
|
|
dnsDomain: 'dns.combined.test',
|
|
emailConfig: {
|
|
ports: [25],
|
|
hostname: 'mail.combined.test',
|
|
domains: ['combined.test'],
|
|
routes: [],
|
|
useSocketHandler: true
|
|
}
|
|
});
|
|
|
|
// Generate both types of routes
|
|
const dnsRoutes = (dcRouter as any).generateDnsRoutes();
|
|
const emailRoutes = (dcRouter as any).generateEmailRoutes(dcRouter.options.emailConfig);
|
|
|
|
// Check DNS routes
|
|
expect(dnsRoutes.length).toEqual(2);
|
|
dnsRoutes.forEach((route: any) => {
|
|
expect(route.action.type).toEqual('socket-handler');
|
|
expect(route.match.domains).toEqual(['dns.combined.test']);
|
|
});
|
|
|
|
// Check email routes
|
|
expect(emailRoutes.length).toEqual(1);
|
|
expect(emailRoutes[0].action.type).toEqual('socket-handler');
|
|
expect(emailRoutes[0].match.ports).toEqual([25]);
|
|
});
|
|
|
|
tap.test('Socket handler functions are created correctly', async () => {
|
|
dcRouter = new DcRouter({
|
|
dnsDomain: 'dns.handler.test',
|
|
emailConfig: {
|
|
ports: [25, 465],
|
|
hostname: 'mail.handler.test',
|
|
domains: ['handler.test'],
|
|
routes: [],
|
|
useSocketHandler: true
|
|
}
|
|
});
|
|
|
|
// Test DNS socket handler creation
|
|
const dnsHandler = (dcRouter as any).createDnsSocketHandler();
|
|
expect(dnsHandler).toBeDefined();
|
|
expect(typeof dnsHandler).toEqual('function');
|
|
|
|
// Test email socket handler creation for different ports
|
|
const smtp25Handler = (dcRouter as any).createMailSocketHandler(25);
|
|
expect(smtp25Handler).toBeDefined();
|
|
expect(typeof smtp25Handler).toEqual('function');
|
|
|
|
const smtp465Handler = (dcRouter as any).createMailSocketHandler(465);
|
|
expect(smtp465Handler).toBeDefined();
|
|
expect(typeof smtp465Handler).toEqual('function');
|
|
|
|
// Handlers should be different functions
|
|
expect(smtp25Handler).not.toEqual(smtp465Handler);
|
|
});
|
|
|
|
tap.test('stop', async () => {
|
|
await tap.stopForcefully();
|
|
});
|
|
|
|
export default tap.start(); |