144 lines
3.7 KiB
TypeScript
144 lines
3.7 KiB
TypeScript
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(); |