Skip to main content
Glama
linear-team.test.ts7.08 kB
import { linearClient } from '../linear.js'; import { linearTeamResourceHandler, linearTeamIssuesResourceHandler, LinearTeamDetailResponse, LinearTeamIssuesResponse, } from './linear-team.js'; // Mock the Linear client jest.mock('../linear.js', () => ({ linearClient: { team: jest.fn(), }, })); describe('Team Resources', () => { // Clear all mocks before each test beforeEach(() => { jest.clearAllMocks(); }); describe('linearTeamIssuesResourceHandler', () => { // Mock team and issues for the tests const mockTeam = { id: 'team123', name: 'Engineering', key: 'ENG', issues: jest.fn(), }; const mockIssue1 = { id: 'issue1', title: 'Fix bug', identifier: 'ENG-1', description: 'Need to fix a bug', state: Promise.resolve({ name: 'Todo' }), priority: 1, assignee: Promise.resolve({ id: 'user1', name: 'John Doe', displayName: 'Johnny', }), url: 'https://linear.app/company/issue/ENG-1', createdAt: new Date('2023-01-01'), updatedAt: new Date('2023-01-02'), }; const mockIssue2 = { id: 'issue2', title: 'Implement feature', identifier: 'ENG-2', description: null, state: Promise.resolve({ name: 'In Progress' }), priority: 2, url: 'https://linear.app/company/issue/ENG-2', createdAt: new Date('2023-01-03'), updatedAt: new Date('2023-01-04'), }; it('should return team issues when given a valid team ID', async () => { // Setup mocks (linearClient.team as jest.Mock).mockResolvedValue(mockTeam); mockTeam.issues.mockResolvedValue({ nodes: [mockIssue1, mockIssue2], }); // Call the handler const result = await linearTeamIssuesResourceHandler({ teamId: 'team123' }); // Verify the result expect(result.isError).toBe(false); expect(linearClient.team).toHaveBeenCalledWith('team123'); expect(mockTeam.issues).toHaveBeenCalledWith({ first: 50 }); // Get data from the result and check it's properly formatted expect(result.data).not.toBeNull(); // Type assertion to tell TypeScript this is the expected resource type const responseData = result.data as unknown as LinearTeamIssuesResponse; // Check team data expect(responseData.team).toMatchObject({ id: 'team123', name: 'Engineering', key: 'ENG', }); // Check issues expect(responseData.issues).toHaveLength(2); expect(responseData.issues[0]).toMatchObject({ id: 'issue1', title: 'Fix bug', identifier: 'ENG-1', description: 'Need to fix a bug', status: 'Todo', priority: 1, }); // Check null description handling expect(responseData.issues[1].description).toBeNull(); }); it('should return an error when team ID is missing', async () => { // Call the handler with no teamId const result = await linearTeamIssuesResourceHandler({}); // Verify the result expect(result.isError).toBe(true); expect(result.errorMessage).toBe('Invalid team ID'); expect(result.data).toBeNull(); expect(linearClient.team).not.toHaveBeenCalled(); }); it('should return an error when team is not found', async () => { // Setup mocks (linearClient.team as jest.Mock).mockResolvedValue(null); // Call the handler const result = await linearTeamIssuesResourceHandler({ teamId: 'nonexistent' }); // Verify the result expect(result.isError).toBe(true); expect(result.errorMessage).toBe('Team with ID nonexistent not found'); expect(result.data).toBeNull(); }); it('should handle API errors gracefully', async () => { // Setup mocks (linearClient.team as jest.Mock).mockRejectedValue(new Error('API error')); // Call the handler const result = await linearTeamIssuesResourceHandler({ teamId: 'team123' }); // Verify the result expect(result.isError).toBe(true); expect(result.errorMessage).toBe('Error: API error'); expect(result.data).toBeNull(); }); }); }); describe('linear-team resource', () => { beforeEach(() => { jest.clearAllMocks(); // Mock the team resource implementation (linearClient.team as jest.Mock).mockImplementation(teamId => { if (teamId === 'team1') { return Promise.resolve({ id: 'team1', name: 'Frontend Team', key: 'FE', description: 'Frontend development team', color: '#0000FF', icon: 'https://example.com/icon.png', members: () => Promise.resolve({ nodes: [ { id: 'user1', name: 'John Doe', displayName: 'Johnny', email: 'john@example.com' }, { id: 'user2', name: 'Jane Smith', displayName: 'Jane', email: 'jane@example.com' }, ], }), states: () => Promise.resolve({ nodes: [ { id: 'state1', name: 'Todo', color: '#FF0000', type: 'unstarted' }, { id: 'state2', name: 'In Progress', color: '#FFFF00', type: 'started' }, { id: 'state3', name: 'Done', color: '#00FF00', type: 'completed' }, ], }), createdAt: new Date('2023-01-01'), updatedAt: new Date('2023-01-02'), }); } else if (teamId === 'nonexistent') { return Promise.resolve(null); } return Promise.reject(new Error('API error')); }); }); it('should return team details for a valid team ID', async () => { const result = await linearTeamResourceHandler({ teamId: 'team1' }); expect(result.isError).toBe(false); expect(result.data).toBeDefined(); const data = result.data as LinearTeamDetailResponse; expect(data.id).toBe('team1'); expect(data.name).toBe('Frontend Team'); expect(data.key).toBe('FE'); expect(data.description).toBe('Frontend development team'); expect(data.color).toBe('#0000FF'); expect(data.icon).toBe('https://example.com/icon.png'); expect(data.members).toHaveLength(2); expect(data.members[0].name).toBe('John Doe'); expect(data.members[1].name).toBe('Jane Smith'); expect(data.states).toHaveLength(3); expect(data.states[0].name).toBe('Todo'); expect(data.states[1].name).toBe('In Progress'); expect(data.states[2].name).toBe('Done'); }); it('should handle invalid team ID', async () => { const result = await linearTeamResourceHandler({ teamId: '' }); expect(result.isError).toBe(true); expect(result.errorMessage).toBe('Invalid team ID'); expect(result.data).toBeNull(); }); it('should handle non-existent team ID', async () => { const result = await linearTeamResourceHandler({ teamId: 'nonexistent' }); expect(result.isError).toBe(true); expect(result.errorMessage).toBe('Team with ID nonexistent not found'); expect(result.data).toBeNull(); }); });

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