@yeepay/awesome-components-mcp
Version:
MCP server providing access to awesome-components documentation and integration guides with dual-mode operation: direct fetch and GitLab MCP instruction generation
159 lines (129 loc) • 5.64 kB
text/typescript
/**
* Integration tests for Get Components Guide MCP Tool - GitLab MCP Instruction Mode
* These tests verify the tool's behavior when generating GitLab MCP instructions
*/
// Mock the GitLab client module
const mockFetchGitLabFileContentSafe = jest.fn();
const mockFetchExternalUrl = jest.fn();
jest.mock('../../services/gitlabClient', () => ({
fetchGitLabFileContentSafe: mockFetchGitLabFileContentSafe,
GitLabError: class GitLabError extends Error {
constructor(message: string, public statusCode?: number, public url?: string) {
super(message);
this.name = 'GitLabError';
}
}
}));
// Mock config with GitLab MCP settings
jest.mock('../../config', () => ({
config: {
urls: {
gitlabBase: 'https://gitlab.yeepay.com/awesome/awesome-components/-/raw/main/'
},
auth: {
gitlabToken: 'test-token'
},
internalGitlabHost: 'gitlab.yeepay.com',
internalGuidesProjectId: 'awesome%2Fawesome-components'
}
}));
import { getComponentsGuideTool } from '../../tools/getComponentsGuide';
describe('Get Components Guide Tool - GitLab MCP Instruction Mode', () => {
beforeEach(() => {
jest.clearAllMocks();
jest.spyOn(console, 'log').mockImplementation(() => {});
jest.spyOn(console, 'error').mockImplementation(() => {});
});
afterEach(() => {
jest.restoreAllMocks();
});
describe('GitLab MCP instruction generation for internal paths', () => {
it('should generate GitLab MCP instruction for relative path', async () => {
const result = await getComponentsGuideTool({
path: 'yeepay/dynamicpassword/llms.txt'
});
expect(result.content).toHaveLength(1);
expect(result.content[0].text).toContain('# Component Guide - GitLab MCP Instruction');
expect(result.content[0].text).toContain('get_file_contents');
expect(result.content[0].text).toContain('awesome%2Fawesome-components');
expect(result.content[0].text).toContain('yeepay/dynamicpassword/llms.txt');
expect(result.isError).toBeUndefined();
// Parse the JSON instruction from the response
const jsonMatch = result.content[0].text.match(/```json\n([\s\S]*?)\n```/);
expect(jsonMatch).toBeTruthy();
const instruction = JSON.parse(jsonMatch![1]);
expect(instruction).toEqual({
action_type: 'mcp_call',
tool_name: 'get_file_contents',
parameters: {
project_id: 'awesome%2Fawesome-components',
file_path: 'yeepay/dynamicpassword/llms.txt',
ref: 'main'
}
});
});
it('should generate GitLab MCP instruction for internal URL', async () => {
const internalUrl = 'https://gitlab.yeepay.com/awesome/awesome-components/-/raw/main/yeepay/component/llms.txt';
const result = await getComponentsGuideTool({
path: internalUrl
});
expect(result.content).toHaveLength(1);
expect(result.content[0].text).toContain('# Component Guide - GitLab MCP Instruction');
// Parse the JSON instruction
const jsonMatch = result.content[0].text.match(/```json\n([\s\S]*?)\n```/);
const instruction = JSON.parse(jsonMatch![1]);
expect(instruction.parameters.file_path).toBe('awesome/awesome-components/-/raw/main/yeepay/component/llms.txt');
});
// Note: This test would require a separate test file with different config mock
// For now, we'll test the URL encoding logic in the main test
});
describe('External URL handling', () => {
it('should handle external URL with direct HTTP GET', async () => {
const externalUrl = 'https://external-gitlab.com/project/-/raw/main/component/llms.txt';
const mockContent = '# External Component\n\nThis is external content.';
// Mock fetch for external URL
global.fetch = jest.fn().mockResolvedValueOnce({
ok: true,
status: 200,
text: jest.fn().mockResolvedValueOnce(mockContent)
} as any);
const result = await getComponentsGuideTool({
path: externalUrl
});
expect(result.content).toHaveLength(1);
expect(result.content[0].text).toContain('# Component Guide: External Component');
expect(result.content[0].text).toContain('This is external content.');
expect(result.content[0].text).toContain(externalUrl);
expect(result.isError).toBeUndefined();
expect(global.fetch).toHaveBeenCalledWith(externalUrl, {
headers: {
'User-Agent': 'awesome-components-mcp/1.0.0'
}
});
});
it('should handle external URL fetch errors', async () => {
const externalUrl = 'https://external-gitlab.com/project/-/raw/main/component/llms.txt';
// Mock fetch failure
global.fetch = jest.fn().mockResolvedValueOnce({
ok: false,
status: 404,
statusText: 'Not Found'
} as any);
const result = await getComponentsGuideTool({
path: externalUrl
});
expect(result.content[0].text).toContain('Error: Component Guide Not Found');
expect(result.content[0].text).toContain('Failed to fetch external URL (status: 404)');
expect(result.isError).toBe(true);
});
});
describe('Configuration validation', () => {
it('should generate GitLab MCP instruction when properly configured', async () => {
// The main config mock already has proper GitLab MCP settings
const result = await getComponentsGuideTool({
path: 'component/guide.txt'
});
expect(result.content[0].text).toContain('# Component Guide - GitLab MCP Instruction');
});
});
});