feat: implement mcpd core server framework with Fastify
Add Fastify server with config validation (Zod), health/healthz endpoints, auth middleware (Bearer token + session lookup), security plugins (CORS, Helmet, rate limiting), error handler, audit logging, and graceful shutdown. 36 tests passing. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
81
src/mcpd/tests/config.test.ts
Normal file
81
src/mcpd/tests/config.test.ts
Normal file
@@ -0,0 +1,81 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { McpdConfigSchema, loadConfigFromEnv } from '../src/config/index.js';
|
||||
|
||||
describe('McpdConfigSchema', () => {
|
||||
it('requires databaseUrl', () => {
|
||||
expect(() => McpdConfigSchema.parse({})).toThrow();
|
||||
});
|
||||
|
||||
it('provides defaults with minimal input', () => {
|
||||
const config = McpdConfigSchema.parse({ databaseUrl: 'postgresql://localhost/test' });
|
||||
expect(config.port).toBe(3000);
|
||||
expect(config.host).toBe('0.0.0.0');
|
||||
expect(config.logLevel).toBe('info');
|
||||
expect(config.corsOrigins).toEqual(['*']);
|
||||
expect(config.rateLimitMax).toBe(100);
|
||||
expect(config.rateLimitWindowMs).toBe(60_000);
|
||||
});
|
||||
|
||||
it('validates full config', () => {
|
||||
const config = McpdConfigSchema.parse({
|
||||
port: 4000,
|
||||
host: '127.0.0.1',
|
||||
databaseUrl: 'postgresql://localhost/test',
|
||||
logLevel: 'debug',
|
||||
corsOrigins: ['http://localhost:3000'],
|
||||
rateLimitMax: 50,
|
||||
rateLimitWindowMs: 30_000,
|
||||
});
|
||||
expect(config.port).toBe(4000);
|
||||
expect(config.logLevel).toBe('debug');
|
||||
});
|
||||
|
||||
it('rejects invalid log level', () => {
|
||||
expect(() => McpdConfigSchema.parse({
|
||||
databaseUrl: 'postgresql://localhost/test',
|
||||
logLevel: 'verbose',
|
||||
})).toThrow();
|
||||
});
|
||||
|
||||
it('rejects zero port', () => {
|
||||
expect(() => McpdConfigSchema.parse({
|
||||
databaseUrl: 'postgresql://localhost/test',
|
||||
port: 0,
|
||||
})).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('loadConfigFromEnv', () => {
|
||||
it('loads config from environment variables', () => {
|
||||
const config = loadConfigFromEnv({
|
||||
DATABASE_URL: 'postgresql://localhost/test',
|
||||
MCPD_PORT: '4000',
|
||||
MCPD_HOST: '127.0.0.1',
|
||||
MCPD_LOG_LEVEL: 'debug',
|
||||
});
|
||||
expect(config.port).toBe(4000);
|
||||
expect(config.host).toBe('127.0.0.1');
|
||||
expect(config.databaseUrl).toBe('postgresql://localhost/test');
|
||||
expect(config.logLevel).toBe('debug');
|
||||
});
|
||||
|
||||
it('uses defaults for missing env vars', () => {
|
||||
const config = loadConfigFromEnv({
|
||||
DATABASE_URL: 'postgresql://localhost/test',
|
||||
});
|
||||
expect(config.port).toBe(3000);
|
||||
expect(config.host).toBe('0.0.0.0');
|
||||
});
|
||||
|
||||
it('parses CORS origins from comma-separated string', () => {
|
||||
const config = loadConfigFromEnv({
|
||||
DATABASE_URL: 'postgresql://localhost/test',
|
||||
MCPD_CORS_ORIGINS: 'http://a.com, http://b.com',
|
||||
});
|
||||
expect(config.corsOrigins).toEqual(['http://a.com', 'http://b.com']);
|
||||
});
|
||||
|
||||
it('throws when DATABASE_URL is missing', () => {
|
||||
expect(() => loadConfigFromEnv({})).toThrow();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user