Skip to main content
Glama
linear_get_projects.test.ts7.61 kB
import { linearGetProjectsHandler } from './linear_get_projects.js'; import { linearClient } from '../linear.js'; // Mock the Linear client jest.mock('../linear.js', () => ({ linearClient: { projects: jest.fn(), team: jest.fn(), }, })); describe('Linear Get Projects Tool', () => { // Mock team object const mockTeam = { id: 'team123', name: Promise.resolve('Engineering'), projects: jest.fn(), }; // Mock project statuses const mockActiveStatus = { id: Promise.resolve('status1'), name: Promise.resolve('Active'), color: Promise.resolve('#00ff00'), type: Promise.resolve('started'), }; const mockCompletedStatus = { id: Promise.resolve('status2'), name: Promise.resolve('Completed'), color: Promise.resolve('#0000ff'), type: Promise.resolve('completed'), }; // Mock project team data const mockTeamData = { id: Promise.resolve('team123'), name: Promise.resolve('Engineering'), key: Promise.resolve('ENG'), }; // Mock projects const mockProject1 = { id: 'project1', name: 'Project Alpha', description: 'First test project', status: Promise.resolve(mockActiveStatus), teams: jest.fn().mockResolvedValue({ nodes: [mockTeamData], }), startDate: '2023-01-01', targetDate: '2023-12-31', url: 'https://linear.app/team/project/project1', progress: 0.5, priority: 1, color: '#ff0000', icon: '🚀', createdAt: '2023-01-01T00:00:00.000Z', updatedAt: '2023-01-02T00:00:00.000Z', }; const mockProject2 = { id: 'project2', name: 'Project Beta', description: 'Second test project', status: Promise.resolve(mockCompletedStatus), teams: jest.fn().mockResolvedValue({ nodes: [mockTeamData], }), startDate: '2023-02-01', targetDate: '2023-11-30', url: 'https://linear.app/team/project/project2', progress: 1.0, priority: 2, color: '#00ff00', icon: '📝', createdAt: '2023-02-01T00:00:00.000Z', updatedAt: '2023-02-02T00:00:00.000Z', }; const mockProject3 = { id: 'project3', name: 'Project Gamma', description: 'Third test project', status: Promise.resolve(mockActiveStatus), teams: jest.fn().mockResolvedValue({ nodes: [], }), startDate: '2023-03-01', targetDate: '2023-10-31', url: 'https://linear.app/team/project/project3', progress: 0.25, priority: 3, color: '#0000ff', icon: '🔧', createdAt: '2023-03-01T00:00:00.000Z', updatedAt: '2023-03-02T00:00:00.000Z', }; // Mock projects response const mockAllProjectsResponse = { nodes: [mockProject1, mockProject2, mockProject3], }; const mockTeamProjectsResponse = { nodes: [mockProject1, mockProject2], }; beforeEach(() => { jest.clearAllMocks(); // Setup default mocks (linearClient.projects as jest.Mock).mockResolvedValue(mockAllProjectsResponse); (linearClient.team as jest.Mock).mockResolvedValue(mockTeam); mockTeam.projects.mockResolvedValue(mockTeamProjectsResponse); }); it('should fetch all projects when no teamId is provided', async () => { const result = await linearGetProjectsHandler({}); expect(result.isError).toBeUndefined(); expect(linearClient.projects).toHaveBeenCalledWith({ first: 50, includeArchived: false, }); expect(linearClient.team).not.toHaveBeenCalled(); const parsedContent = JSON.parse(result.content[0].text); expect(parsedContent).toHaveLength(3); expect(parsedContent[0].id).toBe('project1'); expect(parsedContent[1].id).toBe('project2'); expect(parsedContent[2].id).toBe('project3'); }); it('should fetch team projects when teamId is provided', async () => { const result = await linearGetProjectsHandler({ teamId: 'team123', }); expect(result.isError).toBeUndefined(); expect(linearClient.team).toHaveBeenCalledWith('team123'); expect(mockTeam.projects).toHaveBeenCalledWith({ first: 50, includeArchived: false, }); expect(linearClient.projects).not.toHaveBeenCalled(); const parsedContent = JSON.parse(result.content[0].text); expect(parsedContent).toHaveLength(2); expect(parsedContent[0].id).toBe('project1'); expect(parsedContent[1].id).toBe('project2'); }); it('should return an error when team is not found', async () => { (linearClient.team as jest.Mock).mockResolvedValue(null); const result = await linearGetProjectsHandler({ teamId: 'nonexistent', }); expect(result.isError).toBe(true); expect(result.content[0].text).toBe('Error: Team with ID nonexistent not found'); expect(linearClient.team).toHaveBeenCalledWith('nonexistent'); expect(mockTeam.projects).not.toHaveBeenCalled(); }); it('should respect custom limit and includeArchived parameters', async () => { const result = await linearGetProjectsHandler({ limit: 10, includeArchived: true, }); expect(result.isError).toBeUndefined(); expect(linearClient.projects).toHaveBeenCalledWith({ first: 10, includeArchived: true, }); }); it('should filter projects by status', async () => { const result = await linearGetProjectsHandler({ status: 'Active', }); expect(result.isError).toBeUndefined(); const parsedContent = JSON.parse(result.content[0].text); expect(parsedContent).toHaveLength(2); expect(parsedContent[0].id).toBe('project1'); expect(parsedContent[1].id).toBe('project3'); }); it('should handle status filtering with team ID', async () => { const result = await linearGetProjectsHandler({ teamId: 'team123', status: 'Completed', }); expect(result.isError).toBeUndefined(); const parsedContent = JSON.parse(result.content[0].text); expect(parsedContent).toHaveLength(1); expect(parsedContent[0].id).toBe('project2'); expect(parsedContent[0].status).toBe('Completed'); }); it('should handle when no projects match the status filter', async () => { const result = await linearGetProjectsHandler({ status: 'Canceled', }); expect(result.isError).toBeUndefined(); const parsedContent = JSON.parse(result.content[0].text); expect(parsedContent).toHaveLength(0); }); it('should handle when projects response is null', async () => { (linearClient.projects as jest.Mock).mockResolvedValue(null); const result = await linearGetProjectsHandler({}); expect(result.isError).toBe(true); expect(result.content[0].text).toBe('Error: Failed to fetch projects'); }); it('should handle empty projects list', async () => { (linearClient.projects as jest.Mock).mockResolvedValue({ nodes: [] }); const result = await linearGetProjectsHandler({}); expect(result.isError).toBeUndefined(); const parsedContent = JSON.parse(result.content[0].text); expect(parsedContent).toHaveLength(0); }); it('should handle API errors gracefully', async () => { (linearClient.projects as jest.Mock).mockRejectedValue(new Error('API error')); const result = await linearGetProjectsHandler({}); expect(result.isError).toBe(true); expect(result.content[0].text).toBe('Error: API error'); }); it('should handle team projects API errors gracefully', async () => { mockTeam.projects.mockRejectedValue(new Error('Team API error')); const result = await linearGetProjectsHandler({ teamId: 'team123', }); expect(result.isError).toBe(true); expect(result.content[0].text).toBe('Error: Team API error'); }); });

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/magarcia/mcp-server-linearapp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server