150 lines
4.4 KiB
TypeScript
150 lines
4.4 KiB
TypeScript
import { expect, tap } from '@git.zone/tstest/tapbundle';
|
|
import { DcRouter } from '../ts/index.js';
|
|
import { TypedRequest } from '@api.global/typedrequest';
|
|
import * as interfaces from '../ts_interfaces/index.js';
|
|
import * as net from 'node:net';
|
|
|
|
let testDcRouter: DcRouter;
|
|
let adminIdentity: interfaces.data.IIdentity;
|
|
const testAdminPassword = 'test-admin-password';
|
|
let opsServerPort: number;
|
|
|
|
async function getFreePort(): Promise<number> {
|
|
return await new Promise<number>((resolve, reject) => {
|
|
const server = net.createServer();
|
|
server.once('error', reject);
|
|
server.listen(0, '127.0.0.1', () => {
|
|
const address = server.address();
|
|
const port = typeof address === 'object' && address ? address.port : 0;
|
|
server.close(() => resolve(port));
|
|
});
|
|
});
|
|
}
|
|
|
|
function typedRequestUrl(): string {
|
|
return `http://127.0.0.1:${opsServerPort}/typedrequest`;
|
|
}
|
|
|
|
tap.test('should start DCRouter with OpsServer', async () => {
|
|
process.env.DCROUTER_ADMIN_PASSWORD = testAdminPassword;
|
|
opsServerPort = await getFreePort();
|
|
testDcRouter = new DcRouter({
|
|
// Minimal config for testing
|
|
opsServerPort,
|
|
dbConfig: { enabled: false },
|
|
});
|
|
|
|
await testDcRouter.start();
|
|
expect(testDcRouter.opsServer).toBeInstanceOf(Object);
|
|
});
|
|
|
|
tap.test('should login as admin', async () => {
|
|
const loginRequest = new TypedRequest<interfaces.requests.IReq_AdminLoginWithUsernameAndPassword>(
|
|
typedRequestUrl(),
|
|
'adminLoginWithUsernameAndPassword'
|
|
);
|
|
|
|
const response = await loginRequest.fire({
|
|
username: 'admin',
|
|
password: testAdminPassword,
|
|
});
|
|
|
|
expect(response).toHaveProperty('identity');
|
|
const responseIdentity = response.identity;
|
|
if (!responseIdentity) {
|
|
throw new Error('Expected admin login response to include identity');
|
|
}
|
|
adminIdentity = responseIdentity;
|
|
});
|
|
|
|
tap.test('should respond to health status request', async () => {
|
|
const healthRequest = new TypedRequest<interfaces.requests.IReq_GetHealthStatus>(
|
|
typedRequestUrl(),
|
|
'getHealthStatus'
|
|
);
|
|
|
|
const response = await healthRequest.fire({
|
|
identity: adminIdentity,
|
|
detailed: false,
|
|
});
|
|
|
|
expect(response).toHaveProperty('health');
|
|
expect(response.health.healthy).toBeTrue();
|
|
expect(response.health.services).toHaveProperty('OpsServer');
|
|
});
|
|
|
|
tap.test('should respond to server statistics request', async () => {
|
|
const statsRequest = new TypedRequest<interfaces.requests.IReq_GetServerStatistics>(
|
|
typedRequestUrl(),
|
|
'getServerStatistics'
|
|
);
|
|
|
|
const response = await statsRequest.fire({
|
|
identity: adminIdentity,
|
|
includeHistory: false,
|
|
});
|
|
|
|
expect(response).toHaveProperty('stats');
|
|
expect(response.stats).toHaveProperty('uptime');
|
|
expect(response.stats).toHaveProperty('cpuUsage');
|
|
expect(response.stats).toHaveProperty('memoryUsage');
|
|
});
|
|
|
|
tap.test('should respond to configuration request', async () => {
|
|
const configRequest = new TypedRequest<interfaces.requests.IReq_GetConfiguration>(
|
|
typedRequestUrl(),
|
|
'getConfiguration'
|
|
);
|
|
|
|
const response = await configRequest.fire({
|
|
identity: adminIdentity,
|
|
});
|
|
|
|
expect(response).toHaveProperty('config');
|
|
expect(response.config).toHaveProperty('system');
|
|
expect(response.config).toHaveProperty('smartProxy');
|
|
expect(response.config).toHaveProperty('email');
|
|
expect(response.config).toHaveProperty('dns');
|
|
expect(response.config).toHaveProperty('tls');
|
|
expect(response.config).toHaveProperty('cache');
|
|
expect(response.config).toHaveProperty('radius');
|
|
expect(response.config).toHaveProperty('remoteIngress');
|
|
});
|
|
|
|
tap.test('should handle log retrieval request', async () => {
|
|
const logsRequest = new TypedRequest<interfaces.requests.IReq_GetRecentLogs>(
|
|
typedRequestUrl(),
|
|
'getRecentLogs'
|
|
);
|
|
|
|
const response = await logsRequest.fire({
|
|
identity: adminIdentity,
|
|
limit: 10,
|
|
});
|
|
|
|
expect(response).toHaveProperty('logs');
|
|
expect(response).toHaveProperty('total');
|
|
expect(response).toHaveProperty('hasMore');
|
|
expect(response.logs).toBeArray();
|
|
});
|
|
|
|
tap.test('should reject unauthenticated requests', async () => {
|
|
const healthRequest = new TypedRequest<interfaces.requests.IReq_GetHealthStatus>(
|
|
typedRequestUrl(),
|
|
'getHealthStatus'
|
|
);
|
|
|
|
try {
|
|
await healthRequest.fire({} as any);
|
|
expect(true).toBeFalse(); // Should not reach here
|
|
} catch (error) {
|
|
expect(error).toBeTruthy();
|
|
}
|
|
});
|
|
|
|
tap.test('should stop DCRouter', async () => {
|
|
await testDcRouter.stop();
|
|
});
|
|
|
|
export default tap.start();
|