147 lines
4.7 KiB
TypeScript
147 lines
4.7 KiB
TypeScript
import { tap, expect } from '@git.zone/tstest/tapbundle';
|
|
import { DcRouter } from '../ts/classes.dcrouter.js';
|
|
import * as plugins from '../ts/plugins.js';
|
|
|
|
let dcRouter: DcRouter;
|
|
|
|
tap.test('should NOT instantiate DNS server when dnsNsDomains is not set', async () => {
|
|
dcRouter = new DcRouter({
|
|
smartProxyConfig: {
|
|
routes: []
|
|
}
|
|
});
|
|
|
|
await dcRouter.start();
|
|
|
|
// Check that DNS server is not created
|
|
expect((dcRouter as any).dnsServer).toBeUndefined();
|
|
|
|
await dcRouter.stop();
|
|
});
|
|
|
|
tap.test('should generate DNS routes when dnsNsDomains is set', async () => {
|
|
// This test checks the route generation logic WITHOUT starting the full DcRouter
|
|
// Starting DcRouter would require DNS port 53 and cause conflicts
|
|
|
|
dcRouter = new DcRouter({
|
|
dnsNsDomains: ['ns1.test.local', 'ns2.test.local'],
|
|
dnsScopes: ['test.local'],
|
|
smartProxyConfig: {
|
|
routes: []
|
|
}
|
|
});
|
|
|
|
// Check routes are generated correctly (without starting)
|
|
const generatedRoutes = (dcRouter as any).generateDnsRoutes();
|
|
expect(generatedRoutes.length).toEqual(2); // /dns-query and /resolve
|
|
|
|
// Check that routes have socket-handler action
|
|
generatedRoutes.forEach((route: any) => {
|
|
expect(route.action.type).toEqual('socket-handler');
|
|
expect(route.action.socketHandler).toBeDefined();
|
|
});
|
|
|
|
// Verify routes target the primary nameserver
|
|
const dnsQueryRoute = generatedRoutes.find((r: any) => r.name === 'dns-over-https-dns-query');
|
|
expect(dnsQueryRoute).toBeDefined();
|
|
expect(dnsQueryRoute.match.domains).toContain('ns1.test.local');
|
|
});
|
|
|
|
tap.test('should create DNS routes with correct configuration', async () => {
|
|
dcRouter = new DcRouter({
|
|
dnsNsDomains: ['ns1.example.com', 'ns2.example.com'],
|
|
dnsScopes: ['example.com'],
|
|
smartProxyConfig: {
|
|
routes: []
|
|
}
|
|
});
|
|
|
|
// Access the private method to generate routes
|
|
const dnsRoutes = (dcRouter as any).generateDnsRoutes();
|
|
|
|
expect(dnsRoutes.length).toEqual(2);
|
|
|
|
// Check first route (dns-query) - uses primary nameserver (first in array)
|
|
const dnsQueryRoute = dnsRoutes.find((r: any) => r.name === 'dns-over-https-dns-query');
|
|
expect(dnsQueryRoute).toBeDefined();
|
|
expect(dnsQueryRoute.match.ports).toContain(443);
|
|
expect(dnsQueryRoute.match.domains).toContain('ns1.example.com');
|
|
expect(dnsQueryRoute.match.path).toEqual('/dns-query');
|
|
|
|
// Check second route (resolve)
|
|
const resolveRoute = dnsRoutes.find((r: any) => r.name === 'dns-over-https-resolve');
|
|
expect(resolveRoute).toBeDefined();
|
|
expect(resolveRoute.match.ports).toContain(443);
|
|
expect(resolveRoute.match.domains).toContain('ns1.example.com');
|
|
expect(resolveRoute.match.path).toEqual('/resolve');
|
|
});
|
|
|
|
tap.test('DNS socket handler should be created correctly', async () => {
|
|
// This test verifies the socket handler creation WITHOUT starting the full router
|
|
dcRouter = new DcRouter({
|
|
dnsNsDomains: ['ns1.test.local', 'ns2.test.local'],
|
|
dnsScopes: ['test.local'],
|
|
smartProxyConfig: {
|
|
routes: []
|
|
}
|
|
});
|
|
|
|
// Get the socket handler (this doesn't require DNS server to be started)
|
|
const socketHandler = (dcRouter as any).createDnsSocketHandler();
|
|
expect(socketHandler).toBeDefined();
|
|
expect(typeof socketHandler).toEqual('function');
|
|
|
|
// Create a mock socket to test the handler behavior without DNS server
|
|
const mockSocket = new plugins.net.Socket();
|
|
let socketEnded = false;
|
|
|
|
mockSocket.end = () => {
|
|
socketEnded = true;
|
|
return mockSocket;
|
|
};
|
|
|
|
// When DNS server is not initialized, the handler should end the socket
|
|
try {
|
|
await socketHandler(mockSocket);
|
|
} catch (error) {
|
|
// Expected - DNS server not initialized
|
|
}
|
|
|
|
// Socket should be ended because DNS server wasn't started
|
|
expect(socketEnded).toEqual(true);
|
|
});
|
|
|
|
tap.test('DNS routes should only be generated when dnsNsDomains is configured', async () => {
|
|
// Test without DNS configuration - should return empty routes
|
|
dcRouter = new DcRouter({
|
|
smartProxyConfig: {
|
|
routes: []
|
|
}
|
|
});
|
|
|
|
const routesWithoutDns = (dcRouter as any).generateDnsRoutes();
|
|
expect(routesWithoutDns.length).toEqual(0);
|
|
|
|
// Test with DNS configuration - should return routes
|
|
const dcRouterWithDns = new DcRouter({
|
|
dnsNsDomains: ['ns1.example.com'],
|
|
dnsScopes: ['example.com'],
|
|
smartProxyConfig: {
|
|
routes: []
|
|
}
|
|
});
|
|
|
|
const routesWithDns = (dcRouterWithDns as any).generateDnsRoutes();
|
|
expect(routesWithDns.length).toEqual(2);
|
|
|
|
// Verify socket handler can be created
|
|
const socketHandler = (dcRouterWithDns as any).createDnsSocketHandler();
|
|
expect(socketHandler).toBeDefined();
|
|
expect(typeof socketHandler).toEqual('function');
|
|
});
|
|
|
|
tap.test('stop', async () => {
|
|
await tap.stopForcefully();
|
|
});
|
|
|
|
export default tap.start(); |