sql-talk
Version:
SQL Talk - 自然言語をSQLに変換するMCPサーバー(安全性保護・SSHトンネル対応) / SQL Talk - MCP Server for Natural Language to SQL conversion with safety guards and SSH tunnel support
65 lines (52 loc) • 1.82 kB
text/typescript
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import { SshTunnelManager } from '../../src/database/ssh-tunnel.js';
import { SshTunnelConfig } from '../../src/types/index.js';
describe('SshTunnelManager', () => {
let manager: SshTunnelManager;
beforeEach(() => {
manager = SshTunnelManager.getInstance();
});
afterEach(async () => {
await manager.closeAllTunnels();
});
it('should be a singleton', () => {
const instance1 = SshTunnelManager.getInstance();
const instance2 = SshTunnelManager.getInstance();
expect(instance1).toBe(instance2);
});
it('should reject disabled tunnel', async () => {
const config: SshTunnelConfig = {
enabled: false,
host: 'localhost',
username: 'test',
remote_host: 'localhost',
remote_port: 5432
};
await expect(manager.createTunnel('test-tunnel', config))
.rejects.toThrow('SSH tunnel is not enabled');
});
it('should reject missing authentication', async () => {
const config: SshTunnelConfig = {
enabled: true,
host: 'localhost',
username: 'test',
remote_host: 'localhost',
remote_port: 5432
};
await expect(manager.createTunnel('test-tunnel', config))
.rejects.toThrow('SSH authentication method not specified');
});
it('should get tunnel status', () => {
const status = manager.getTunnelStatus('nonexistent-tunnel');
expect(status.exists).toBe(false);
expect(status.localPort).toBeUndefined();
});
it('should get active tunnel count', () => {
const count = manager.getActiveTunnelCount();
expect(count).toBe(0);
});
it('should handle closing non-existent tunnel', async () => {
await expect(manager.closeTunnel('nonexistent-tunnel'))
.resolves.not.toThrow();
});
});