update
This commit is contained in:
@ -6,7 +6,6 @@ import {
|
||||
// Route helpers
|
||||
createHttpRoute,
|
||||
createHttpsTerminateRoute,
|
||||
createStaticFileRoute,
|
||||
createApiRoute,
|
||||
createWebSocketRoute,
|
||||
createHttpToHttpsRedirect,
|
||||
@ -43,7 +42,6 @@ import {
|
||||
import {
|
||||
// Route patterns
|
||||
createApiGatewayRoute,
|
||||
createStaticFileServerRoute,
|
||||
createWebSocketRoute as createWebSocketPattern,
|
||||
createLoadBalancerRoute as createLbPattern,
|
||||
addRateLimiting,
|
||||
@ -145,28 +143,16 @@ tap.test('Route Validation - validateRouteAction', async () => {
|
||||
expect(validForwardResult.valid).toBeTrue();
|
||||
expect(validForwardResult.errors.length).toEqual(0);
|
||||
|
||||
// Valid redirect action
|
||||
const validRedirectAction: IRouteAction = {
|
||||
type: 'redirect',
|
||||
redirect: {
|
||||
to: 'https://example.com',
|
||||
status: 301
|
||||
// Valid socket-handler action
|
||||
const validSocketAction: IRouteAction = {
|
||||
type: 'socket-handler',
|
||||
socketHandler: (socket, context) => {
|
||||
socket.end();
|
||||
}
|
||||
};
|
||||
const validRedirectResult = validateRouteAction(validRedirectAction);
|
||||
expect(validRedirectResult.valid).toBeTrue();
|
||||
expect(validRedirectResult.errors.length).toEqual(0);
|
||||
|
||||
// Valid static action
|
||||
const validStaticAction: IRouteAction = {
|
||||
type: 'static',
|
||||
static: {
|
||||
root: '/var/www/html'
|
||||
}
|
||||
};
|
||||
const validStaticResult = validateRouteAction(validStaticAction);
|
||||
expect(validStaticResult.valid).toBeTrue();
|
||||
expect(validStaticResult.errors.length).toEqual(0);
|
||||
const validSocketResult = validateRouteAction(validSocketAction);
|
||||
expect(validSocketResult.valid).toBeTrue();
|
||||
expect(validSocketResult.errors.length).toEqual(0);
|
||||
|
||||
// Invalid action (missing target)
|
||||
const invalidAction: IRouteAction = {
|
||||
@ -177,24 +163,14 @@ tap.test('Route Validation - validateRouteAction', async () => {
|
||||
expect(invalidResult.errors.length).toBeGreaterThan(0);
|
||||
expect(invalidResult.errors[0]).toInclude('Target is required');
|
||||
|
||||
// Invalid action (missing redirect configuration)
|
||||
const invalidRedirectAction: IRouteAction = {
|
||||
type: 'redirect'
|
||||
// Invalid action (missing socket handler)
|
||||
const invalidSocketAction: IRouteAction = {
|
||||
type: 'socket-handler'
|
||||
};
|
||||
const invalidRedirectResult = validateRouteAction(invalidRedirectAction);
|
||||
expect(invalidRedirectResult.valid).toBeFalse();
|
||||
expect(invalidRedirectResult.errors.length).toBeGreaterThan(0);
|
||||
expect(invalidRedirectResult.errors[0]).toInclude('Redirect configuration is required');
|
||||
|
||||
// Invalid action (missing static root)
|
||||
const invalidStaticAction: IRouteAction = {
|
||||
type: 'static',
|
||||
static: {} as any // Testing invalid static config without required 'root' property
|
||||
};
|
||||
const invalidStaticResult = validateRouteAction(invalidStaticAction);
|
||||
expect(invalidStaticResult.valid).toBeFalse();
|
||||
expect(invalidStaticResult.errors.length).toBeGreaterThan(0);
|
||||
expect(invalidStaticResult.errors[0]).toInclude('Static file root directory is required');
|
||||
const invalidSocketResult = validateRouteAction(invalidSocketAction);
|
||||
expect(invalidSocketResult.valid).toBeFalse();
|
||||
expect(invalidSocketResult.errors.length).toBeGreaterThan(0);
|
||||
expect(invalidSocketResult.errors[0]).toInclude('Socket handler function is required');
|
||||
});
|
||||
|
||||
tap.test('Route Validation - validateRouteConfig', async () => {
|
||||
@ -253,26 +229,25 @@ tap.test('Route Validation - hasRequiredPropertiesForAction', async () => {
|
||||
const forwardRoute = createHttpRoute('example.com', { host: 'localhost', port: 3000 });
|
||||
expect(hasRequiredPropertiesForAction(forwardRoute, 'forward')).toBeTrue();
|
||||
|
||||
// Redirect action
|
||||
// Socket handler action (redirect functionality)
|
||||
const redirectRoute = createHttpToHttpsRedirect('example.com');
|
||||
expect(hasRequiredPropertiesForAction(redirectRoute, 'redirect')).toBeTrue();
|
||||
expect(hasRequiredPropertiesForAction(redirectRoute, 'socket-handler')).toBeTrue();
|
||||
|
||||
// Static action
|
||||
const staticRoute = createStaticFileRoute('example.com', '/var/www/html');
|
||||
expect(hasRequiredPropertiesForAction(staticRoute, 'static')).toBeTrue();
|
||||
|
||||
// Block action
|
||||
const blockRoute: IRouteConfig = {
|
||||
// Socket handler action
|
||||
const socketRoute: IRouteConfig = {
|
||||
match: {
|
||||
domains: 'blocked.example.com',
|
||||
domains: 'socket.example.com',
|
||||
ports: 80
|
||||
},
|
||||
action: {
|
||||
type: 'block'
|
||||
type: 'socket-handler',
|
||||
socketHandler: (socket, context) => {
|
||||
socket.end();
|
||||
}
|
||||
},
|
||||
name: 'Block Route'
|
||||
name: 'Socket Handler Route'
|
||||
};
|
||||
expect(hasRequiredPropertiesForAction(blockRoute, 'block')).toBeTrue();
|
||||
expect(hasRequiredPropertiesForAction(socketRoute, 'socket-handler')).toBeTrue();
|
||||
|
||||
// Missing required properties
|
||||
const invalidForwardRoute: IRouteConfig = {
|
||||
@ -345,20 +320,22 @@ tap.test('Route Utilities - mergeRouteConfigs', async () => {
|
||||
expect(actionMergedRoute.action.target.host).toEqual('new-host.local');
|
||||
expect(actionMergedRoute.action.target.port).toEqual(5000);
|
||||
|
||||
// Test replacing action with different type
|
||||
// Test replacing action with socket handler
|
||||
const typeChangeOverride: Partial<IRouteConfig> = {
|
||||
action: {
|
||||
type: 'redirect',
|
||||
redirect: {
|
||||
to: 'https://example.com',
|
||||
status: 301
|
||||
type: 'socket-handler',
|
||||
socketHandler: (socket, context) => {
|
||||
socket.write('HTTP/1.1 301 Moved Permanently\r\n');
|
||||
socket.write('Location: https://example.com\r\n');
|
||||
socket.write('\r\n');
|
||||
socket.end();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const typeChangedRoute = mergeRouteConfigs(baseRoute, typeChangeOverride);
|
||||
expect(typeChangedRoute.action.type).toEqual('redirect');
|
||||
expect(typeChangedRoute.action.redirect.to).toEqual('https://example.com');
|
||||
expect(typeChangedRoute.action.type).toEqual('socket-handler');
|
||||
expect(typeChangedRoute.action.socketHandler).toBeDefined();
|
||||
expect(typeChangedRoute.action.target).toBeUndefined();
|
||||
});
|
||||
|
||||
@ -705,9 +682,8 @@ tap.test('Route Helpers - createHttpToHttpsRedirect', async () => {
|
||||
|
||||
expect(route.match.domains).toEqual('example.com');
|
||||
expect(route.match.ports).toEqual(80);
|
||||
expect(route.action.type).toEqual('redirect');
|
||||
expect(route.action.redirect.to).toEqual('https://{domain}:443{path}');
|
||||
expect(route.action.redirect.status).toEqual(301);
|
||||
expect(route.action.type).toEqual('socket-handler');
|
||||
expect(route.action.socketHandler).toBeDefined();
|
||||
|
||||
const validationResult = validateRouteConfig(route);
|
||||
expect(validationResult.valid).toBeTrue();
|
||||
@ -741,7 +717,7 @@ tap.test('Route Helpers - createCompleteHttpsServer', async () => {
|
||||
// HTTP redirect route
|
||||
expect(routes[1].match.domains).toEqual('example.com');
|
||||
expect(routes[1].match.ports).toEqual(80);
|
||||
expect(routes[1].action.type).toEqual('redirect');
|
||||
expect(routes[1].action.type).toEqual('socket-handler');
|
||||
|
||||
const validation1 = validateRouteConfig(routes[0]);
|
||||
const validation2 = validateRouteConfig(routes[1]);
|
||||
@ -749,24 +725,8 @@ tap.test('Route Helpers - createCompleteHttpsServer', async () => {
|
||||
expect(validation2.valid).toBeTrue();
|
||||
});
|
||||
|
||||
tap.test('Route Helpers - createStaticFileRoute', async () => {
|
||||
const route = createStaticFileRoute('example.com', '/var/www/html', {
|
||||
serveOnHttps: true,
|
||||
certificate: 'auto',
|
||||
indexFiles: ['index.html', 'index.htm', 'default.html']
|
||||
});
|
||||
|
||||
expect(route.match.domains).toEqual('example.com');
|
||||
expect(route.match.ports).toEqual(443);
|
||||
expect(route.action.type).toEqual('static');
|
||||
expect(route.action.static.root).toEqual('/var/www/html');
|
||||
expect(route.action.static.index).toInclude('index.html');
|
||||
expect(route.action.static.index).toInclude('default.html');
|
||||
expect(route.action.tls.mode).toEqual('terminate');
|
||||
|
||||
const validationResult = validateRouteConfig(route);
|
||||
expect(validationResult.valid).toBeTrue();
|
||||
});
|
||||
// createStaticFileRoute has been removed - static file serving should be handled by
|
||||
// external servers (nginx/apache) behind the proxy
|
||||
|
||||
tap.test('Route Helpers - createApiRoute', async () => {
|
||||
const route = createApiRoute('api.example.com', '/v1', { host: 'localhost', port: 3000 }, {
|
||||
@ -874,34 +834,8 @@ tap.test('Route Patterns - createApiGatewayRoute', async () => {
|
||||
expect(result.valid).toBeTrue();
|
||||
});
|
||||
|
||||
tap.test('Route Patterns - createStaticFileServerRoute', async () => {
|
||||
// Create static file server route
|
||||
const staticRoute = createStaticFileServerRoute(
|
||||
'static.example.com',
|
||||
'/var/www/html',
|
||||
{
|
||||
useTls: true,
|
||||
cacheControl: 'public, max-age=7200'
|
||||
}
|
||||
);
|
||||
|
||||
// Validate route configuration
|
||||
expect(staticRoute.match.domains).toEqual('static.example.com');
|
||||
expect(staticRoute.action.type).toEqual('static');
|
||||
|
||||
// Check static configuration
|
||||
if (staticRoute.action.static) {
|
||||
expect(staticRoute.action.static.root).toEqual('/var/www/html');
|
||||
|
||||
// Check cache control headers if they exist
|
||||
if (staticRoute.action.static.headers) {
|
||||
expect(staticRoute.action.static.headers['Cache-Control']).toEqual('public, max-age=7200');
|
||||
}
|
||||
}
|
||||
|
||||
const result = validateRouteConfig(staticRoute);
|
||||
expect(result.valid).toBeTrue();
|
||||
});
|
||||
// createStaticFileServerRoute has been removed - static file serving should be handled by
|
||||
// external servers (nginx/apache) behind the proxy
|
||||
|
||||
tap.test('Route Patterns - createWebSocketPattern', async () => {
|
||||
// Create WebSocket route pattern
|
||||
|
Reference in New Issue
Block a user