- Rename local-proxy to mcplocal with HTTP server, LLM pipeline, mcpd discovery - Add LLM pre-processing: token estimation, filter cache, metrics, Gemini CLI + DeepSeek providers - Add mcpd auth (login/logout) and MCP proxy endpoints - Update CLI: dual URLs (mcplocalUrl/mcpdUrl), auth commands, --direct flag - Add tiered health monitoring, shell completions, e2e integration tests - 57 test files, 597 tests passing Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
115 lines
3.8 KiB
TypeScript
115 lines
3.8 KiB
TypeScript
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
import { mkdtempSync, rmSync } from 'node:fs';
|
|
import { join } from 'node:path';
|
|
import { tmpdir } from 'node:os';
|
|
import { createConfigCommand } from '../../src/commands/config.js';
|
|
import { loadConfig, saveConfig, DEFAULT_CONFIG } from '../../src/config/index.js';
|
|
|
|
let tempDir: string;
|
|
let output: string[];
|
|
|
|
function log(...args: string[]) {
|
|
output.push(args.join(' '));
|
|
}
|
|
|
|
beforeEach(() => {
|
|
tempDir = mkdtempSync(join(tmpdir(), 'mcpctl-config-test-'));
|
|
output = [];
|
|
});
|
|
|
|
afterEach(() => {
|
|
rmSync(tempDir, { recursive: true, force: true });
|
|
});
|
|
|
|
function makeCommand() {
|
|
return createConfigCommand({
|
|
configDeps: { configDir: tempDir },
|
|
log,
|
|
});
|
|
}
|
|
|
|
describe('config view', () => {
|
|
it('outputs default config as JSON', async () => {
|
|
const cmd = makeCommand();
|
|
await cmd.parseAsync(['view'], { from: 'user' });
|
|
expect(output).toHaveLength(1);
|
|
const parsed = JSON.parse(output[0]) as Record<string, unknown>;
|
|
expect(parsed['mcplocalUrl']).toBe('http://localhost:3200');
|
|
expect(parsed['mcpdUrl']).toBe('http://localhost:3100');
|
|
});
|
|
|
|
it('outputs config as YAML with --output yaml', async () => {
|
|
const cmd = makeCommand();
|
|
await cmd.parseAsync(['view', '-o', 'yaml'], { from: 'user' });
|
|
expect(output[0]).toContain('mcplocalUrl:');
|
|
});
|
|
});
|
|
|
|
describe('config set', () => {
|
|
it('sets mcplocalUrl', async () => {
|
|
const cmd = makeCommand();
|
|
await cmd.parseAsync(['set', 'mcplocalUrl', 'http://new:9000'], { from: 'user' });
|
|
expect(output[0]).toContain('mcplocalUrl');
|
|
const config = loadConfig({ configDir: tempDir });
|
|
expect(config.mcplocalUrl).toBe('http://new:9000');
|
|
});
|
|
|
|
it('sets mcpdUrl', async () => {
|
|
const cmd = makeCommand();
|
|
await cmd.parseAsync(['set', 'mcpdUrl', 'http://remote:3100'], { from: 'user' });
|
|
const config = loadConfig({ configDir: tempDir });
|
|
expect(config.mcpdUrl).toBe('http://remote:3100');
|
|
});
|
|
|
|
it('maps daemonUrl to mcplocalUrl for backward compat', async () => {
|
|
const cmd = makeCommand();
|
|
await cmd.parseAsync(['set', 'daemonUrl', 'http://legacy:3000'], { from: 'user' });
|
|
const config = loadConfig({ configDir: tempDir });
|
|
expect(config.mcplocalUrl).toBe('http://legacy:3000');
|
|
});
|
|
|
|
it('sets cacheTTLMs as integer', async () => {
|
|
const cmd = makeCommand();
|
|
await cmd.parseAsync(['set', 'cacheTTLMs', '60000'], { from: 'user' });
|
|
const config = loadConfig({ configDir: tempDir });
|
|
expect(config.cacheTTLMs).toBe(60000);
|
|
});
|
|
|
|
it('sets registries as comma-separated list', async () => {
|
|
const cmd = makeCommand();
|
|
await cmd.parseAsync(['set', 'registries', 'official,glama'], { from: 'user' });
|
|
const config = loadConfig({ configDir: tempDir });
|
|
expect(config.registries).toEqual(['official', 'glama']);
|
|
});
|
|
|
|
it('sets outputFormat', async () => {
|
|
const cmd = makeCommand();
|
|
await cmd.parseAsync(['set', 'outputFormat', 'json'], { from: 'user' });
|
|
const config = loadConfig({ configDir: tempDir });
|
|
expect(config.outputFormat).toBe('json');
|
|
});
|
|
});
|
|
|
|
describe('config path', () => {
|
|
it('shows config file path', async () => {
|
|
const cmd = makeCommand();
|
|
await cmd.parseAsync(['path'], { from: 'user' });
|
|
expect(output[0]).toContain(tempDir);
|
|
expect(output[0]).toContain('config.json');
|
|
});
|
|
});
|
|
|
|
describe('config reset', () => {
|
|
it('resets to defaults', async () => {
|
|
// First set a custom value
|
|
saveConfig({ ...DEFAULT_CONFIG, mcplocalUrl: 'http://custom' }, { configDir: tempDir });
|
|
|
|
const cmd = makeCommand();
|
|
await cmd.parseAsync(['reset'], { from: 'user' });
|
|
expect(output[0]).toContain('reset');
|
|
|
|
const config = loadConfig({ configDir: tempDir });
|
|
expect(config.mcplocalUrl).toBe(DEFAULT_CONFIG.mcplocalUrl);
|
|
});
|
|
});
|