mirror of
https://github.com/modelcontextprotocol/servers.git
synced 2026-04-17 15:43:24 +02:00
Removed ~29 tests that were adding noise rather than coverage: - Registration boilerplate tests (16): redundant with registrations.test.ts - Redundant role/type checks (3): consolidated into behavioral tests - "Should not throw" tests (6): consolidated into single lifecycle test - Constant identity tests (2): provided no safety net - expect(true).toBe(true) test (1): replaced with actual assertion - Weak capability test (1): removed, handler check already exists Strengthened remaining tests: - Resource templates test now verifies specific resource names - File resources test now asserts registerResource was called Test count: 124 → 95 (29 removed) Coverage unchanged at ~71% Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
180 lines
6.5 KiB
TypeScript
180 lines
6.5 KiB
TypeScript
import { describe, it, expect, vi } from 'vitest';
|
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
import { registerSimplePrompt } from '../prompts/simple.js';
|
|
import { registerArgumentsPrompt } from '../prompts/args.js';
|
|
import { registerPromptWithCompletions } from '../prompts/completions.js';
|
|
import { registerEmbeddedResourcePrompt } from '../prompts/resource.js';
|
|
|
|
// Helper to capture registered prompt handlers
|
|
function createMockServer() {
|
|
const handlers: Map<string, Function> = new Map();
|
|
const configs: Map<string, any> = new Map();
|
|
|
|
const mockServer = {
|
|
registerPrompt: vi.fn((name: string, config: any, handler: Function) => {
|
|
handlers.set(name, handler);
|
|
configs.set(name, config);
|
|
}),
|
|
} as unknown as McpServer;
|
|
|
|
return { mockServer, handlers, configs };
|
|
}
|
|
|
|
describe('Prompts', () => {
|
|
describe('simple-prompt', () => {
|
|
it('should return fixed message with no arguments', () => {
|
|
const { mockServer, handlers } = createMockServer();
|
|
registerSimplePrompt(mockServer);
|
|
|
|
const handler = handlers.get('simple-prompt')!;
|
|
const result = handler();
|
|
|
|
expect(result).toEqual({
|
|
messages: [
|
|
{
|
|
role: 'user',
|
|
content: {
|
|
type: 'text',
|
|
text: 'This is a simple prompt without arguments.',
|
|
},
|
|
},
|
|
],
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('args-prompt', () => {
|
|
it('should include city in message', () => {
|
|
const { mockServer, handlers } = createMockServer();
|
|
registerArgumentsPrompt(mockServer);
|
|
|
|
const handler = handlers.get('args-prompt')!;
|
|
const result = handler({ city: 'San Francisco' });
|
|
|
|
expect(result.messages[0].content.text).toBe("What's weather in San Francisco?");
|
|
});
|
|
|
|
it('should include city and state in message', () => {
|
|
const { mockServer, handlers } = createMockServer();
|
|
registerArgumentsPrompt(mockServer);
|
|
|
|
const handler = handlers.get('args-prompt')!;
|
|
const result = handler({ city: 'San Francisco', state: 'California' });
|
|
|
|
expect(result.messages[0].content.text).toBe(
|
|
"What's weather in San Francisco, California?"
|
|
);
|
|
});
|
|
|
|
it('should handle city only (optional state omitted)', () => {
|
|
const { mockServer, handlers } = createMockServer();
|
|
registerArgumentsPrompt(mockServer);
|
|
|
|
const handler = handlers.get('args-prompt')!;
|
|
const result = handler({ city: 'New York' });
|
|
|
|
expect(result.messages[0].content.text).toBe("What's weather in New York?");
|
|
expect(result.messages[0].content.text).not.toContain(',');
|
|
expect(result.messages[0].role).toBe('user');
|
|
expect(result.messages[0].content.type).toBe('text');
|
|
});
|
|
});
|
|
|
|
describe('completable-prompt', () => {
|
|
it('should generate promotion message with department and name', () => {
|
|
const { mockServer, handlers } = createMockServer();
|
|
registerPromptWithCompletions(mockServer);
|
|
|
|
const handler = handlers.get('completable-prompt')!;
|
|
const result = handler({ department: 'Engineering', name: 'Alice' });
|
|
|
|
expect(result.messages[0].content.text).toBe(
|
|
'Please promote Alice to the head of the Engineering team.'
|
|
);
|
|
});
|
|
|
|
it('should work with different departments', () => {
|
|
const { mockServer, handlers } = createMockServer();
|
|
registerPromptWithCompletions(mockServer);
|
|
|
|
const handler = handlers.get('completable-prompt')!;
|
|
|
|
const salesResult = handler({ department: 'Sales', name: 'David' });
|
|
expect(salesResult.messages[0].content.text).toContain('Sales');
|
|
expect(salesResult.messages[0].content.text).toContain('David');
|
|
expect(salesResult.messages[0].role).toBe('user');
|
|
|
|
const marketingResult = handler({ department: 'Marketing', name: 'Grace' });
|
|
expect(marketingResult.messages[0].content.text).toContain('Marketing');
|
|
expect(marketingResult.messages[0].content.text).toContain('Grace');
|
|
});
|
|
});
|
|
|
|
describe('resource-prompt', () => {
|
|
it('should return text resource reference', () => {
|
|
const { mockServer, handlers } = createMockServer();
|
|
registerEmbeddedResourcePrompt(mockServer);
|
|
|
|
const handler = handlers.get('resource-prompt')!;
|
|
const result = handler({ resourceType: 'Text', resourceId: '1' });
|
|
|
|
expect(result.messages).toHaveLength(2);
|
|
expect(result.messages[0].content.text).toContain('Text');
|
|
expect(result.messages[0].content.text).toContain('1');
|
|
expect(result.messages[1].content.type).toBe('resource');
|
|
expect(result.messages[1].content.resource.uri).toContain('text/1');
|
|
});
|
|
|
|
it('should return blob resource reference', () => {
|
|
const { mockServer, handlers } = createMockServer();
|
|
registerEmbeddedResourcePrompt(mockServer);
|
|
|
|
const handler = handlers.get('resource-prompt')!;
|
|
const result = handler({ resourceType: 'Blob', resourceId: '5' });
|
|
|
|
expect(result.messages[0].content.text).toContain('Blob');
|
|
expect(result.messages[1].content.resource.uri).toContain('blob/5');
|
|
});
|
|
|
|
it('should reject invalid resource type', () => {
|
|
const { mockServer, handlers } = createMockServer();
|
|
registerEmbeddedResourcePrompt(mockServer);
|
|
|
|
const handler = handlers.get('resource-prompt')!;
|
|
expect(() => handler({ resourceType: 'Invalid', resourceId: '1' })).toThrow(
|
|
'Invalid resourceType'
|
|
);
|
|
});
|
|
|
|
it('should reject invalid resource ID', () => {
|
|
const { mockServer, handlers } = createMockServer();
|
|
registerEmbeddedResourcePrompt(mockServer);
|
|
|
|
const handler = handlers.get('resource-prompt')!;
|
|
expect(() => handler({ resourceType: 'Text', resourceId: '-1' })).toThrow(
|
|
'Invalid resourceId'
|
|
);
|
|
expect(() => handler({ resourceType: 'Text', resourceId: '0' })).toThrow(
|
|
'Invalid resourceId'
|
|
);
|
|
expect(() => handler({ resourceType: 'Text', resourceId: 'abc' })).toThrow(
|
|
'Invalid resourceId'
|
|
);
|
|
});
|
|
|
|
it('should include both intro text and resource messages', () => {
|
|
const { mockServer, handlers } = createMockServer();
|
|
registerEmbeddedResourcePrompt(mockServer);
|
|
|
|
const handler = handlers.get('resource-prompt')!;
|
|
const result = handler({ resourceType: 'Text', resourceId: '3' });
|
|
|
|
expect(result.messages).toHaveLength(2);
|
|
expect(result.messages[0].role).toBe('user');
|
|
expect(result.messages[0].content.type).toBe('text');
|
|
expect(result.messages[1].role).toBe('user');
|
|
expect(result.messages[1].content.type).toBe('resource');
|
|
});
|
|
});
|
|
});
|