125 lines
3.7 KiB
TypeScript
125 lines
3.7 KiB
TypeScript
|
|
import { describe, it, expect } from 'vitest';
|
||
|
|
import {
|
||
|
|
CreateMcpServerSchema,
|
||
|
|
UpdateMcpServerSchema,
|
||
|
|
CreateMcpProfileSchema,
|
||
|
|
UpdateMcpProfileSchema,
|
||
|
|
} from '../src/validation/index.js';
|
||
|
|
|
||
|
|
describe('CreateMcpServerSchema', () => {
|
||
|
|
it('validates valid input', () => {
|
||
|
|
const result = CreateMcpServerSchema.parse({
|
||
|
|
name: 'my-server',
|
||
|
|
description: 'A test server',
|
||
|
|
transport: 'STDIO',
|
||
|
|
});
|
||
|
|
expect(result.name).toBe('my-server');
|
||
|
|
expect(result.envTemplate).toEqual([]);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('rejects empty name', () => {
|
||
|
|
expect(() => CreateMcpServerSchema.parse({ name: '' })).toThrow();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('rejects name with spaces', () => {
|
||
|
|
expect(() => CreateMcpServerSchema.parse({ name: 'my server' })).toThrow();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('rejects uppercase name', () => {
|
||
|
|
expect(() => CreateMcpServerSchema.parse({ name: 'MyServer' })).toThrow();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('allows hyphens in name', () => {
|
||
|
|
const result = CreateMcpServerSchema.parse({ name: 'my-mcp-server' });
|
||
|
|
expect(result.name).toBe('my-mcp-server');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('defaults transport to STDIO', () => {
|
||
|
|
const result = CreateMcpServerSchema.parse({ name: 'test' });
|
||
|
|
expect(result.transport).toBe('STDIO');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('validates envTemplate entries', () => {
|
||
|
|
const result = CreateMcpServerSchema.parse({
|
||
|
|
name: 'test',
|
||
|
|
envTemplate: [
|
||
|
|
{ name: 'API_KEY', description: 'The key', isSecret: true },
|
||
|
|
],
|
||
|
|
});
|
||
|
|
expect(result.envTemplate).toHaveLength(1);
|
||
|
|
expect(result.envTemplate[0]?.isSecret).toBe(true);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('rejects invalid transport', () => {
|
||
|
|
expect(() => CreateMcpServerSchema.parse({ name: 'test', transport: 'HTTP' })).toThrow();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('rejects invalid repository URL', () => {
|
||
|
|
expect(() => CreateMcpServerSchema.parse({ name: 'test', repositoryUrl: 'not-a-url' })).toThrow();
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
describe('UpdateMcpServerSchema', () => {
|
||
|
|
it('allows partial updates', () => {
|
||
|
|
const result = UpdateMcpServerSchema.parse({ description: 'updated' });
|
||
|
|
expect(result.description).toBe('updated');
|
||
|
|
expect(result.transport).toBeUndefined();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('allows empty object', () => {
|
||
|
|
const result = UpdateMcpServerSchema.parse({});
|
||
|
|
expect(Object.keys(result)).toHaveLength(0);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('allows nullable fields', () => {
|
||
|
|
const result = UpdateMcpServerSchema.parse({ packageName: null, dockerImage: null });
|
||
|
|
expect(result.packageName).toBeNull();
|
||
|
|
expect(result.dockerImage).toBeNull();
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
describe('CreateMcpProfileSchema', () => {
|
||
|
|
it('validates valid input', () => {
|
||
|
|
const result = CreateMcpProfileSchema.parse({
|
||
|
|
name: 'readonly',
|
||
|
|
serverId: 'server-123',
|
||
|
|
});
|
||
|
|
expect(result.name).toBe('readonly');
|
||
|
|
expect(result.permissions).toEqual([]);
|
||
|
|
expect(result.envOverrides).toEqual({});
|
||
|
|
});
|
||
|
|
|
||
|
|
it('rejects empty name', () => {
|
||
|
|
expect(() => CreateMcpProfileSchema.parse({ name: '', serverId: 'x' })).toThrow();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('accepts permissions array', () => {
|
||
|
|
const result = CreateMcpProfileSchema.parse({
|
||
|
|
name: 'admin',
|
||
|
|
serverId: 'x',
|
||
|
|
permissions: ['read', 'write', 'delete'],
|
||
|
|
});
|
||
|
|
expect(result.permissions).toHaveLength(3);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('accepts envOverrides', () => {
|
||
|
|
const result = CreateMcpProfileSchema.parse({
|
||
|
|
name: 'staging',
|
||
|
|
serverId: 'x',
|
||
|
|
envOverrides: { API_URL: 'https://staging.example.com' },
|
||
|
|
});
|
||
|
|
expect(result.envOverrides['API_URL']).toBe('https://staging.example.com');
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
describe('UpdateMcpProfileSchema', () => {
|
||
|
|
it('allows partial updates', () => {
|
||
|
|
const result = UpdateMcpProfileSchema.parse({ permissions: ['read'] });
|
||
|
|
expect(result.permissions).toEqual(['read']);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('allows empty object', () => {
|
||
|
|
expect(UpdateMcpProfileSchema.parse({})).toBeDefined();
|
||
|
|
});
|
||
|
|
});
|