import { tap, expect } from '@push.rocks/tapbundle'; import * as plugins from '../ts/plugins.js'; import type { IForwardConfig, ForwardingType } from '../ts/smartproxy/types/forwarding.types.js'; // First, import the components directly to avoid issues with compiled modules import { ForwardingHandlerFactory } from '../ts/smartproxy/forwarding/forwarding.factory.js'; import { createDomainConfig } from '../ts/smartproxy/forwarding/domain-config.js'; import { DomainManager } from '../ts/smartproxy/forwarding/domain-manager.js'; import { httpOnly, tlsTerminateToHttp, tlsTerminateToHttps, sniPassthrough } from '../ts/smartproxy/types/forwarding.types.js'; const helpers = { httpOnly, tlsTerminateToHttp, tlsTerminateToHttps, sniPassthrough }; tap.test('ForwardingHandlerFactory - apply defaults based on type', async () => { // HTTP-only defaults const httpConfig: IForwardConfig = { type: 'http-only', target: { host: 'localhost', port: 3000 } }; const expandedHttpConfig = ForwardingHandlerFactory.applyDefaults(httpConfig); expect(expandedHttpConfig.http?.enabled).toEqual(true); // HTTPS-passthrough defaults const passthroughConfig: IForwardConfig = { type: 'https-passthrough', target: { host: 'localhost', port: 443 } }; const expandedPassthroughConfig = ForwardingHandlerFactory.applyDefaults(passthroughConfig); expect(expandedPassthroughConfig.https?.forwardSni).toEqual(true); expect(expandedPassthroughConfig.http?.enabled).toEqual(false); // HTTPS-terminate-to-http defaults const terminateToHttpConfig: IForwardConfig = { type: 'https-terminate-to-http', target: { host: 'localhost', port: 3000 } }; const expandedTerminateToHttpConfig = ForwardingHandlerFactory.applyDefaults(terminateToHttpConfig); expect(expandedTerminateToHttpConfig.http?.enabled).toEqual(true); expect(expandedTerminateToHttpConfig.http?.redirectToHttps).toEqual(true); expect(expandedTerminateToHttpConfig.acme?.enabled).toEqual(true); expect(expandedTerminateToHttpConfig.acme?.maintenance).toEqual(true); // HTTPS-terminate-to-https defaults const terminateToHttpsConfig: IForwardConfig = { type: 'https-terminate-to-https', target: { host: 'localhost', port: 8443 } }; const expandedTerminateToHttpsConfig = ForwardingHandlerFactory.applyDefaults(terminateToHttpsConfig); expect(expandedTerminateToHttpsConfig.http?.enabled).toEqual(true); expect(expandedTerminateToHttpsConfig.http?.redirectToHttps).toEqual(true); expect(expandedTerminateToHttpsConfig.acme?.enabled).toEqual(true); expect(expandedTerminateToHttpsConfig.acme?.maintenance).toEqual(true); }); tap.test('ForwardingHandlerFactory - validate configuration', async () => { // Valid configuration const validConfig: IForwardConfig = { type: 'http-only', target: { host: 'localhost', port: 3000 } }; expect(() => ForwardingHandlerFactory.validateConfig(validConfig)).not.toThrow(); // Invalid configuration - missing target const invalidConfig1: any = { type: 'http-only' }; expect(() => ForwardingHandlerFactory.validateConfig(invalidConfig1)).toThrow(); // Invalid configuration - invalid port const invalidConfig2: IForwardConfig = { type: 'http-only', target: { host: 'localhost', port: 0 } }; expect(() => ForwardingHandlerFactory.validateConfig(invalidConfig2)).toThrow(); // Invalid configuration - HTTP disabled for HTTP-only const invalidConfig3: IForwardConfig = { type: 'http-only', target: { host: 'localhost', port: 3000 }, http: { enabled: false } }; expect(() => ForwardingHandlerFactory.validateConfig(invalidConfig3)).toThrow(); // Invalid configuration - HTTP enabled for HTTPS passthrough const invalidConfig4: IForwardConfig = { type: 'https-passthrough', target: { host: 'localhost', port: 443 }, http: { enabled: true } }; expect(() => ForwardingHandlerFactory.validateConfig(invalidConfig4)).toThrow(); }); tap.test('DomainManager - manage domain configurations', async () => { const domainManager = new DomainManager(); // Add a domain configuration await domainManager.addDomainConfig( createDomainConfig('example.com', helpers.httpOnly('localhost', 3000)) ); // Check that the configuration was added const configs = domainManager.getDomainConfigs(); expect(configs.length).toEqual(1); expect(configs[0].domains[0]).toEqual('example.com'); expect(configs[0].forwarding.type).toEqual('http-only'); // Find a handler for a domain const handler = domainManager.findHandlerForDomain('example.com'); expect(handler).toBeDefined(); // Remove a domain configuration const removed = domainManager.removeDomainConfig('example.com'); expect(removed).toBeTrue(); // Check that the configuration was removed const configsAfterRemoval = domainManager.getDomainConfigs(); expect(configsAfterRemoval.length).toEqual(0); // Check that no handler exists anymore const handlerAfterRemoval = domainManager.findHandlerForDomain('example.com'); expect(handlerAfterRemoval).toBeUndefined(); }); tap.test('DomainManager - support wildcard domains', async () => { const domainManager = new DomainManager(); // Add a wildcard domain configuration await domainManager.addDomainConfig( createDomainConfig('*.example.com', helpers.httpOnly('localhost', 3000)) ); // Find a handler for a subdomain const handler = domainManager.findHandlerForDomain('test.example.com'); expect(handler).toBeDefined(); // Find a handler for a different domain (should not match) const noHandler = domainManager.findHandlerForDomain('example.org'); expect(noHandler).toBeUndefined(); }); tap.test('Helper Functions - create http-only forwarding config', async () => { const config = helpers.httpOnly('localhost', 3000); expect(config.type).toEqual('http-only'); expect(config.target.host).toEqual('localhost'); expect(config.target.port).toEqual(3000); expect(config.http?.enabled).toBeTrue(); }); tap.test('Helper Functions - create https-terminate-to-http config', async () => { const config = helpers.tlsTerminateToHttp('localhost', 3000); expect(config.type).toEqual('https-terminate-to-http'); expect(config.target.host).toEqual('localhost'); expect(config.target.port).toEqual(3000); expect(config.http?.redirectToHttps).toBeTrue(); expect(config.acme?.enabled).toBeTrue(); expect(config.acme?.maintenance).toBeTrue(); }); tap.test('Helper Functions - create https-terminate-to-https config', async () => { const config = helpers.tlsTerminateToHttps('localhost', 8443); expect(config.type).toEqual('https-terminate-to-https'); expect(config.target.host).toEqual('localhost'); expect(config.target.port).toEqual(8443); expect(config.http?.redirectToHttps).toBeTrue(); expect(config.acme?.enabled).toBeTrue(); expect(config.acme?.maintenance).toBeTrue(); }); tap.test('Helper Functions - create https-passthrough config', async () => { const config = helpers.sniPassthrough('localhost', 443); expect(config.type).toEqual('https-passthrough'); expect(config.target.host).toEqual('localhost'); expect(config.target.port).toEqual(443); expect(config.https?.forwardSni).toBeTrue(); }); export default tap.start();