Skip to main content
Glama

Backlog MCP Server

backlog.test.ts12.8 kB
import { fetchFromBacklog } from '../backlogApi.js'; import { endpoints } from '../endpoints.js'; import { config } from 'dotenv'; /** * Backlog API テスト * * 実際の環境でテストを実行する際の注意点: * * 1. 環境変数の設定 * - TEST_PROJECT_ID: テスト用プロジェクトのID * - TEST_PROJECT_KEY: テスト用プロジェクトのキー * - BACKLOG_DOMAIN: BacklogのドメインURL * - BACKLOG_API_KEY: BacklogのAPIキー * * 2. スキップされているテストについて * - 実際の環境に合わせてスキップを解除する場合は、以下の点に注意してください: * - getIssuesテスト: Backlog APIでは、projectIdパラメータを使用 * - createIssueテスト: 実際の環境に合わせて有効なissueTypeIdを設定する必要があります * - getWikiPagesテスト: Wikiの機能が制限されている場合はスキップしたままにしてください * * 3. APIの仕様変更に対応するため、定期的なテストの実行と更新が重要です */ // 環境変数の読み込み config(); // テスト用の定数 // 実際の環境のプロジェクト情報を設定 const TEST_PROJECT_ID = process.env.TEST_PROJECT_ID; const TEST_PROJECT_KEY = process.env.TEST_PROJECT_KEY; const TEST_PROJECT_ID_OR_KEY = TEST_PROJECT_KEY; // プロジェクトキーを優先的に使用 // 課題タイプIDとプライオリティID(実際の環境に合わせて設定) const TEST_ISSUE_TYPE_ID = '841492'; // 実際の環境で有効なissueTypeIdに変更してください const TEST_PRIORITY_ID = '2'; // 実際の環境で有効なpriorityIdに変更してください describe('Backlog API Tests', () => { // スペース情報の取得テスト describe('getSpaces', () => { it('should fetch space information successfully', async () => { const endpoint = endpoints.find(e => e.name === 'getSpaces'); expect(endpoint).toBeDefined(); const result = await fetchFromBacklog(endpoint!.path, {}); expect(result).toBeDefined(); expect(result.spaceKey).toBeDefined(); // 詳細なログ出力(デバッグ用) console.log('スペース情報:', JSON.stringify(result, null, 2)); }); }); // プロジェクト一覧のテスト describe('getProjects', () => { it('should fetch project list successfully', async () => { const endpoint = endpoints.find(e => e.name === 'getProjects'); expect(endpoint).toBeDefined(); const result = await fetchFromBacklog(endpoint!.path, {}); expect(Array.isArray(result)).toBe(true); // 指定したプロジェクトが存在するか確認 const testProject = result.find((project: any) => project.projectKey === TEST_PROJECT_KEY || project.id.toString() === TEST_PROJECT_ID ); expect(testProject).toBeDefined(); // プロジェクト情報の詳細ログ(デバッグ用) if (testProject) { console.log('テスト用プロジェクト情報:', JSON.stringify(testProject, null, 2)); // 課題タイプ情報を取得(createIssueテスト用) if (testProject.id) { try { const issueTypes = await fetchFromBacklog(`projects/${testProject.id}/issueTypes`, {}); console.log('利用可能な課題タイプ:', JSON.stringify(issueTypes, null, 2)); } catch (error) { console.error('課題タイプの取得に失敗:', error); } } } }); }); // 課題一覧のテスト describe('getIssues', () => { // 課題一覧の取得テストはスキップ test.skip('should fetch issues successfully', async () => { // テスト実装 }); // 存在しないプロジェクトIDのテストもスキップ test.skip('should handle non-existent project ID', async () => { // テスト実装 }); // projectIdのバリデーションテスト test('should validate project ID format', async () => { const endpoint = endpoints.find(e => e.path === 'issues'); expect(endpoint).toBeDefined(); expect(endpoint!.schema).toBeDefined(); // 無効なprojectIdでエラーになることを確認 await expect( endpoint!.schema.parseAsync({ projectId: -1 }) ).rejects.toThrow(); // 有効なprojectIdは通過することを確認 await expect( endpoint!.schema.parseAsync({ projectId: 123 }) ).resolves.toEqual({ projectId: 123 }); // 有効なprojectIdOrKeyも通過することを確認 await expect( endpoint!.schema.parseAsync({ projectIdOrKey: "TEST" }) ).resolves.toEqual({ projectIdOrKey: "TEST" }); }); }); // 特定の課題情報のテスト describe('getIssue', () => { /** * テスト用の課題IDを取得するヘルパー関数 * projectIdパラメータを使用して課題リストを取得 */ async function getFirstIssueId(): Promise<number | null> { try { const issues = await fetchFromBacklog('issues', { projectId: TEST_PROJECT_ID, count: 1 }); if (Array.isArray(issues) && issues.length > 0) { return issues[0].id; } } catch (error) { console.error('課題IDの取得に失敗:', error); } return null; } it('should fetch issue with valid ID', async () => { // 実際の課題IDを動的に取得 const validIssueId = await getFirstIssueId(); if (!validIssueId) { console.warn('テスト用の課題が見つからないためスキップします'); return; } const endpoint = endpoints.find(e => e.name === 'getIssue'); expect(endpoint).toBeDefined(); const result = await fetchFromBacklog(endpoint!.path, { issueId: validIssueId }); expect(result.id).toBeDefined(); console.log('取得した課題情報:', JSON.stringify(result, null, 2)); }); it('should handle non-existent issue ID', async () => { const endpoint = endpoints.find(e => e.name === 'getIssue'); expect(endpoint).toBeDefined(); await expect( fetchFromBacklog(endpoint!.path, { issueId: '999999' }) ).rejects.toThrow(); }); it('should validate issue ID format', async () => { const endpoint = endpoints.find(e => e.name === 'getIssue'); expect(endpoint).toBeDefined(); // issueIdはstring型またはnumber型を許容するため、オブジェクトでテスト await expect( endpoint!.schema.parseAsync({ issueId: {} }) ).rejects.toThrow(); }); }); // 課題の追加テスト describe('createIssue', () => { // 課題タイプIDを動的に取得するヘルパー関数 async function getFirstIssueTypeId() { try { const issueTypes = await fetchFromBacklog(`projects/${TEST_PROJECT_ID}/issueTypes`, {}); if (Array.isArray(issueTypes) && issueTypes.length > 0) { return issueTypes[0].id.toString(); } } catch (error) { console.error('課題タイプIDの取得に失敗:', error); } return null; } // プライオリティIDを動的に取得するヘルパー関数 async function getFirstPriorityId() { try { const priorities = await fetchFromBacklog('priorities', {}); if (Array.isArray(priorities) && priorities.length > 0) { return priorities[0].id.toString(); } } catch (error) { console.error('プライオリティIDの取得に失敗:', error); } return null; } it('should create issue with required parameters', async () => { // 実際の環境で有効な課題タイプIDとプライオリティIDを取得 const issueTypeId = await getFirstIssueTypeId() || TEST_ISSUE_TYPE_ID; const priorityId = await getFirstPriorityId() || TEST_PRIORITY_ID; const endpoint = endpoints.find(e => e.name === 'createIssue'); expect(endpoint).toBeDefined(); const params = { projectId: TEST_PROJECT_ID, summary: 'テスト課題 ' + new Date().toISOString(), issueTypeId, priorityId, method: 'POST' }; const result = await fetchFromBacklog(endpoint!.path, params); expect(result.id).toBeDefined(); console.log('作成した課題:', JSON.stringify(result, null, 2)); }); it('should create issue with optional parameters', async () => { // 実際の環境で有効な課題タイプIDとプライオリティIDを取得 const issueTypeId = await getFirstIssueTypeId() || TEST_ISSUE_TYPE_ID; const priorityId = await getFirstPriorityId() || TEST_PRIORITY_ID; const endpoint = endpoints.find(e => e.name === 'createIssue'); expect(endpoint).toBeDefined(); const params = { projectId: TEST_PROJECT_ID, summary: 'テスト課題(詳細あり) ' + new Date().toISOString(), issueTypeId, priorityId, description: '詳細な説明\n複数行のテキスト\n' + new Date().toISOString(), method: 'POST' }; const result = await fetchFromBacklog(endpoint!.path, params); expect(result.id).toBeDefined(); expect(result.description).toBe(params.description); console.log('詳細付きで作成した課題:', JSON.stringify(result, null, 2)); }); it('should validate required parameters', async () => { const endpoint = endpoints.find(e => e.name === 'createIssue'); expect(endpoint).toBeDefined(); await expect( endpoint!.schema.parseAsync({ projectId: TEST_PROJECT_ID }) ).rejects.toThrow(); }); it('should handle invalid project ID', async () => { const endpoint = endpoints.find(e => e.name === 'createIssue'); expect(endpoint).toBeDefined(); const params = { projectId: '999999', summary: 'テスト課題', issueTypeId: TEST_ISSUE_TYPE_ID, priorityId: TEST_PRIORITY_ID, method: 'POST' }; await expect( fetchFromBacklog(endpoint!.path, params) ).rejects.toThrow(); }); }); // Wikiページ一覧のテスト describe('getWikiPages', () => { // Wikiの機能が制限されている場合があるため注意 it('should fetch wiki pages with valid project ID', async () => { const endpoint = endpoints.find(e => e.name === 'getWikiPages'); expect(endpoint).toBeDefined(); try { // Wikiページ一覧の取得にはprojectIdOrKeyパラメータを使用 const result = await fetchFromBacklog(endpoint!.path, { projectIdOrKey: TEST_PROJECT_KEY }); expect(Array.isArray(result)).toBe(true); console.log(`プロジェクト ${TEST_PROJECT_KEY} のWikiページ数:`, result.length); } catch (error: any) { // Wikiが無効な場合はテストをスキップ if (error.message && error.message.includes('featureRestrictedError')) { console.warn('Wikiの機能が制限されているためスキップします'); return; } throw error; } }); it('should handle non-existent project ID', async () => { const endpoint = endpoints.find(e => e.name === 'getWikiPages'); expect(endpoint).toBeDefined(); await expect( fetchFromBacklog(endpoint!.path, { projectIdOrKey: '999999' }) ).rejects.toThrow(); }); }); // ユーザー一覧のテスト describe('getUsers', () => { it('should fetch user list successfully', async () => { const endpoint = endpoints.find(e => e.name === 'getUsers'); expect(endpoint).toBeDefined(); const result = await fetchFromBacklog(endpoint!.path, {}); expect(Array.isArray(result)).toBe(true); console.log('ユーザー数:', result.length); if (result.length > 0) { console.log('最初のユーザー:', JSON.stringify(result[0], null, 2)); } }); }); // Webhook一覧のテスト describe('getWebhooks', () => { it('should fetch webhook list successfully', async () => { const endpoint = endpoints.find(e => e.name === 'getWebhooks'); expect(endpoint).toBeDefined(); const result = await fetchFromBacklog(`projects/${TEST_PROJECT_KEY}/webhooks`, {}); expect(Array.isArray(result)).toBe(true); console.log(`プロジェクト ${TEST_PROJECT_KEY} のWebhook数:`, result.length); }); }); });

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/tmhr1850/backlog-mcp-server'

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