import { expect, tap } from '@push.rocks/tapbundle'; import { SmartProxy } from '../ts/proxies/smart-proxy/index.js'; let smartProxy: SmartProxy; tap.test('should create SmartProxy with top-level ACME configuration', async () => { smartProxy = new SmartProxy({ // Top-level ACME configuration acme: { email: 'test@example.com', useProduction: false, port: 80, renewThresholdDays: 30 }, routes: [{ name: 'example.com', match: { domains: 'example.com', ports: 443 }, action: { type: 'forward', target: { host: 'localhost', port: 8080 }, tls: { mode: 'terminate', certificate: 'auto' // Uses top-level ACME config } } }] }); expect(smartProxy).toBeInstanceOf(SmartProxy); expect(smartProxy.settings.acme?.email).toEqual('test@example.com'); expect(smartProxy.settings.acme?.useProduction).toEqual(false); }); tap.test('should support route-level ACME configuration', async () => { const proxy = new SmartProxy({ routes: [{ name: 'custom.com', match: { domains: 'custom.com', ports: 443 }, action: { type: 'forward', target: { host: 'localhost', port: 8080 }, tls: { mode: 'terminate', certificate: 'auto', acme: { // Route-specific ACME config email: 'custom@example.com', useProduction: true } } } }] }); expect(proxy).toBeInstanceOf(SmartProxy); }); tap.test('should use top-level ACME as defaults and allow route overrides', async () => { const proxy = new SmartProxy({ acme: { email: 'default@example.com', useProduction: false }, routes: [{ name: 'default-route', match: { domains: 'default.com', ports: 443 }, action: { type: 'forward', target: { host: 'localhost', port: 8080 }, tls: { mode: 'terminate', certificate: 'auto' // Uses top-level defaults } } }, { name: 'custom-route', match: { domains: 'custom.com', ports: 443 }, action: { type: 'forward', target: { host: 'localhost', port: 8081 }, tls: { mode: 'terminate', certificate: 'auto', acme: { // Override for this route email: 'special@example.com', useProduction: true } } } }] }); expect(proxy.settings.acme?.email).toEqual('default@example.com'); }); tap.test('should validate ACME configuration warnings', async () => { // Test missing email let errorThrown = false; try { const proxy = new SmartProxy({ routes: [{ name: 'no-email', match: { domains: 'test.com', ports: 443 }, action: { type: 'forward', target: { host: 'localhost', port: 8080 }, tls: { mode: 'terminate', certificate: 'auto' // No ACME email configured } } }] }); await proxy.start(); } catch (error) { errorThrown = true; expect(error.message).toInclude('ACME email is required'); } expect(errorThrown).toBeTrue(); }); tap.test('should support accountEmail alias', async () => { const proxy = new SmartProxy({ acme: { accountEmail: 'account@example.com', // Using alias useProduction: false }, routes: [{ name: 'alias-test', match: { domains: 'alias.com', ports: 443 }, action: { type: 'forward', target: { host: 'localhost', port: 8080 }, tls: { mode: 'terminate', certificate: 'auto' } } }] }); expect(proxy.settings.acme?.email).toEqual('account@example.com'); }); tap.start();