209 lines
5.8 KiB
TypeScript
209 lines
5.8 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';
|
||
|
|
|
||
|
|
const TEST_PORT = 3200;
|
||
|
|
const TEST_URL = `http://localhost:${TEST_PORT}/typedrequest`;
|
||
|
|
|
||
|
|
let testDcRouter: DcRouter;
|
||
|
|
let adminIdentity: interfaces.data.IIdentity;
|
||
|
|
|
||
|
|
// ============================================================================
|
||
|
|
// Setup — db disabled, handlers return graceful fallbacks
|
||
|
|
// ============================================================================
|
||
|
|
|
||
|
|
tap.test('should start DCRouter with OpsServer', async () => {
|
||
|
|
testDcRouter = new DcRouter({
|
||
|
|
opsServerPort: TEST_PORT,
|
||
|
|
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>(
|
||
|
|
TEST_URL,
|
||
|
|
'adminLoginWithUsernameAndPassword'
|
||
|
|
);
|
||
|
|
|
||
|
|
const response = await loginRequest.fire({
|
||
|
|
username: 'admin',
|
||
|
|
password: 'admin',
|
||
|
|
});
|
||
|
|
|
||
|
|
expect(response).toHaveProperty('identity');
|
||
|
|
adminIdentity = response.identity;
|
||
|
|
});
|
||
|
|
|
||
|
|
// ============================================================================
|
||
|
|
// Security Profile endpoints (graceful fallbacks when resolver unavailable)
|
||
|
|
// ============================================================================
|
||
|
|
|
||
|
|
tap.test('should return empty profiles list when resolver not initialized', async () => {
|
||
|
|
const req = new TypedRequest<interfaces.requests.IReq_GetSecurityProfiles>(
|
||
|
|
TEST_URL,
|
||
|
|
'getSecurityProfiles'
|
||
|
|
);
|
||
|
|
|
||
|
|
const response = await req.fire({
|
||
|
|
identity: adminIdentity,
|
||
|
|
});
|
||
|
|
|
||
|
|
expect(response.profiles).toBeArray();
|
||
|
|
expect(response.profiles.length).toEqual(0);
|
||
|
|
});
|
||
|
|
|
||
|
|
tap.test('should return null for single profile when resolver not initialized', async () => {
|
||
|
|
const req = new TypedRequest<interfaces.requests.IReq_GetSecurityProfile>(
|
||
|
|
TEST_URL,
|
||
|
|
'getSecurityProfile'
|
||
|
|
);
|
||
|
|
|
||
|
|
const response = await req.fire({
|
||
|
|
identity: adminIdentity,
|
||
|
|
id: 'nonexistent',
|
||
|
|
});
|
||
|
|
|
||
|
|
expect(response.profile).toEqual(null);
|
||
|
|
});
|
||
|
|
|
||
|
|
tap.test('should return failure for create profile when resolver not initialized', async () => {
|
||
|
|
const req = new TypedRequest<interfaces.requests.IReq_CreateSecurityProfile>(
|
||
|
|
TEST_URL,
|
||
|
|
'createSecurityProfile'
|
||
|
|
);
|
||
|
|
|
||
|
|
const response = await req.fire({
|
||
|
|
identity: adminIdentity,
|
||
|
|
name: 'TEST',
|
||
|
|
security: { ipAllowList: ['*'] },
|
||
|
|
});
|
||
|
|
|
||
|
|
expect(response.success).toBeFalse();
|
||
|
|
expect(response.message).toBeTruthy();
|
||
|
|
});
|
||
|
|
|
||
|
|
tap.test('should return empty profile usage when resolver not initialized', async () => {
|
||
|
|
const req = new TypedRequest<interfaces.requests.IReq_GetSecurityProfileUsage>(
|
||
|
|
TEST_URL,
|
||
|
|
'getSecurityProfileUsage'
|
||
|
|
);
|
||
|
|
|
||
|
|
const response = await req.fire({
|
||
|
|
identity: adminIdentity,
|
||
|
|
id: 'nonexistent',
|
||
|
|
});
|
||
|
|
|
||
|
|
expect(response.routes).toBeArray();
|
||
|
|
expect(response.routes.length).toEqual(0);
|
||
|
|
});
|
||
|
|
|
||
|
|
// ============================================================================
|
||
|
|
// Network Target endpoints (graceful fallbacks when resolver unavailable)
|
||
|
|
// ============================================================================
|
||
|
|
|
||
|
|
tap.test('should return empty targets list when resolver not initialized', async () => {
|
||
|
|
const req = new TypedRequest<interfaces.requests.IReq_GetNetworkTargets>(
|
||
|
|
TEST_URL,
|
||
|
|
'getNetworkTargets'
|
||
|
|
);
|
||
|
|
|
||
|
|
const response = await req.fire({
|
||
|
|
identity: adminIdentity,
|
||
|
|
});
|
||
|
|
|
||
|
|
expect(response.targets).toBeArray();
|
||
|
|
expect(response.targets.length).toEqual(0);
|
||
|
|
});
|
||
|
|
|
||
|
|
tap.test('should return null for single target when resolver not initialized', async () => {
|
||
|
|
const req = new TypedRequest<interfaces.requests.IReq_GetNetworkTarget>(
|
||
|
|
TEST_URL,
|
||
|
|
'getNetworkTarget'
|
||
|
|
);
|
||
|
|
|
||
|
|
const response = await req.fire({
|
||
|
|
identity: adminIdentity,
|
||
|
|
id: 'nonexistent',
|
||
|
|
});
|
||
|
|
|
||
|
|
expect(response.target).toEqual(null);
|
||
|
|
});
|
||
|
|
|
||
|
|
tap.test('should return failure for create target when resolver not initialized', async () => {
|
||
|
|
const req = new TypedRequest<interfaces.requests.IReq_CreateNetworkTarget>(
|
||
|
|
TEST_URL,
|
||
|
|
'createNetworkTarget'
|
||
|
|
);
|
||
|
|
|
||
|
|
const response = await req.fire({
|
||
|
|
identity: adminIdentity,
|
||
|
|
name: 'TEST',
|
||
|
|
host: '127.0.0.1',
|
||
|
|
port: 443,
|
||
|
|
});
|
||
|
|
|
||
|
|
expect(response.success).toBeFalse();
|
||
|
|
expect(response.message).toBeTruthy();
|
||
|
|
});
|
||
|
|
|
||
|
|
tap.test('should return empty target usage when resolver not initialized', async () => {
|
||
|
|
const req = new TypedRequest<interfaces.requests.IReq_GetNetworkTargetUsage>(
|
||
|
|
TEST_URL,
|
||
|
|
'getNetworkTargetUsage'
|
||
|
|
);
|
||
|
|
|
||
|
|
const response = await req.fire({
|
||
|
|
identity: adminIdentity,
|
||
|
|
id: 'nonexistent',
|
||
|
|
});
|
||
|
|
|
||
|
|
expect(response.routes).toBeArray();
|
||
|
|
expect(response.routes.length).toEqual(0);
|
||
|
|
});
|
||
|
|
|
||
|
|
// ============================================================================
|
||
|
|
// Auth rejection
|
||
|
|
// ============================================================================
|
||
|
|
|
||
|
|
tap.test('should reject unauthenticated profile requests', async () => {
|
||
|
|
const req = new TypedRequest<interfaces.requests.IReq_GetSecurityProfiles>(
|
||
|
|
TEST_URL,
|
||
|
|
'getSecurityProfiles'
|
||
|
|
);
|
||
|
|
|
||
|
|
try {
|
||
|
|
await req.fire({} as any);
|
||
|
|
expect(true).toBeFalse();
|
||
|
|
} catch (error) {
|
||
|
|
expect(error).toBeTruthy();
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
tap.test('should reject unauthenticated target requests', async () => {
|
||
|
|
const req = new TypedRequest<interfaces.requests.IReq_GetNetworkTargets>(
|
||
|
|
TEST_URL,
|
||
|
|
'getNetworkTargets'
|
||
|
|
);
|
||
|
|
|
||
|
|
try {
|
||
|
|
await req.fire({} as any);
|
||
|
|
expect(true).toBeFalse();
|
||
|
|
} catch (error) {
|
||
|
|
expect(error).toBeTruthy();
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
// ============================================================================
|
||
|
|
// Cleanup
|
||
|
|
// ============================================================================
|
||
|
|
|
||
|
|
tap.test('should stop DCRouter', async () => {
|
||
|
|
await testDcRouter.stop();
|
||
|
|
});
|
||
|
|
|
||
|
|
export default tap.start();
|