import { tap, expect } from '@git.zone/tstest/tapbundle'; import { createHttpsTerminateRoute, createCompleteHttpsServer, createHttpRoute, } from '../ts/proxies/smart-proxy/utils/route-helpers.js'; import { mergeRouteConfigs, cloneRoute, routeMatchesPath, } from '../ts/proxies/smart-proxy/utils/route-utils.js'; import { validateRoutes, validateRouteConfig, } from '../ts/proxies/smart-proxy/utils/route-validator.js'; import type { IRouteConfig } from '../ts/proxies/smart-proxy/models/route-types.js'; tap.test('route creation - createHttpsTerminateRoute produces correct structure', async () => { const route = createHttpsTerminateRoute('secure.example.com', { host: '127.0.0.1', port: 8443 }); expect(route).toHaveProperty('match'); expect(route).toHaveProperty('action'); expect(route.action.type).toEqual('forward'); expect(route.action.tls).toBeDefined(); expect(route.action.tls!.mode).toEqual('terminate'); expect(route.match.domains).toEqual('secure.example.com'); }); tap.test('route creation - createCompleteHttpsServer returns redirect and main route', async () => { const routes = createCompleteHttpsServer('app.example.com', { host: '127.0.0.1', port: 3000 }); expect(routes).toBeArray(); expect(routes.length).toBeGreaterThanOrEqual(2); // Should have an HTTP→HTTPS redirect and an HTTPS route const hasRedirect = routes.some((r) => r.action.type === 'forward' && r.action.redirect !== undefined); const hasHttps = routes.some((r) => r.action.tls?.mode === 'terminate'); expect(hasRedirect || hasHttps).toBeTrue(); }); tap.test('route validation - validateRoutes on a set of routes', async () => { const routes: IRouteConfig[] = [ createHttpRoute('a.com', { host: '127.0.0.1', port: 3000 }), createHttpRoute('b.com', { host: '127.0.0.1', port: 4000 }), ]; const result = validateRoutes(routes); expect(result.valid).toBeTrue(); expect(result.errors).toHaveLength(0); }); tap.test('route validation - validateRoutes catches invalid route in set', async () => { const routes: any[] = [ createHttpRoute('valid.com', { host: '127.0.0.1', port: 3000 }), { match: { ports: 80 } }, // missing action ]; const result = validateRoutes(routes); expect(result.valid).toBeFalse(); expect(result.errors.length).toBeGreaterThan(0); }); tap.test('path matching - routeMatchesPath with exact path', async () => { const route = createHttpRoute('example.com', { host: '127.0.0.1', port: 3000 }); route.match.path = '/api'; expect(routeMatchesPath(route, '/api')).toBeTrue(); expect(routeMatchesPath(route, '/other')).toBeFalse(); }); tap.test('path matching - route without path matches everything', async () => { const route = createHttpRoute('example.com', { host: '127.0.0.1', port: 3000 }); // No path set, should match any path expect(routeMatchesPath(route, '/anything')).toBeTrue(); expect(routeMatchesPath(route, '/')).toBeTrue(); }); tap.test('route merging - mergeRouteConfigs combines routes', async () => { const base = createHttpRoute('example.com', { host: '127.0.0.1', port: 3000 }); base.priority = 10; base.name = 'base-route'; const merged = mergeRouteConfigs(base, { priority: 50, name: 'merged-route', }); expect(merged.priority).toEqual(50); expect(merged.name).toEqual('merged-route'); // Original route fields should be preserved expect(merged.match.domains).toEqual('example.com'); expect(merged.action.targets![0].host).toEqual('127.0.0.1'); }); tap.test('route merging - mergeRouteConfigs does not mutate original', async () => { const base = createHttpRoute('example.com', { host: '127.0.0.1', port: 3000 }); base.name = 'original'; const merged = mergeRouteConfigs(base, { name: 'changed' }); expect(base.name).toEqual('original'); expect(merged.name).toEqual('changed'); }); tap.test('route cloning - cloneRoute produces independent copy', async () => { const original = createHttpRoute('example.com', { host: '127.0.0.1', port: 3000 }); original.priority = 42; original.name = 'original-route'; const cloned = cloneRoute(original); // Should be equal in value expect(cloned.match.domains).toEqual('example.com'); expect(cloned.priority).toEqual(42); expect(cloned.name).toEqual('original-route'); expect(cloned.action.targets![0].host).toEqual('127.0.0.1'); expect(cloned.action.targets![0].port).toEqual(3000); // Should be independent - modifying clone shouldn't affect original cloned.name = 'cloned-route'; cloned.priority = 99; expect(original.name).toEqual('original-route'); expect(original.priority).toEqual(42); }); export default tap.start();