taiga-mcp-server
Version:
Full-featured MCP server for Taiga project management with advanced sprint and issue tracking. Based on mcpTAIGA by adriapedralbes, enhanced with substantial modifications. Developed collaboratively with Claude Code (AI-assisted development).
431 lines (350 loc) • 12 kB
JavaScript
/**
* Pagination Functionality Tests
* Tests the pagination support for all list operations
*/
import { TaigaService } from '../src/taigaService.js';
import { fetchAllPaginated } from '../src/pagination.js';
const taigaService = new TaigaService();
// Color codes for console output
const colors = {
green: '\x1b[32m',
red: '\x1b[31m',
yellow: '\x1b[33m',
blue: '\x1b[34m',
reset: '\x1b[0m'
};
// Test results tracker
let passedTests = 0;
let failedTests = 0;
let totalTests = 0;
/**
* Print test result
*/
function printResult(testName, passed, message = '') {
totalTests++;
if (passed) {
passedTests++;
console.log(`${colors.green}✓${colors.reset} ${testName}`);
} else {
failedTests++;
console.log(`${colors.red}✗${colors.reset} ${testName}`);
if (message) {
console.log(` ${colors.red}Error: ${message}${colors.reset}`);
}
}
}
/**
* Print section header
*/
function printSection(title) {
console.log(`\n${colors.blue}${'='.repeat(60)}${colors.reset}`);
console.log(`${colors.blue}${title}${colors.reset}`);
console.log(`${colors.blue}${'='.repeat(60)}${colors.reset}\n`);
}
/**
* Test 1: fetchAllPaginated utility function with mock data
*/
async function testFetchAllPaginatedUtility() {
printSection('Test 1: fetchAllPaginated Utility Function');
try {
// Mock paginated response
let callCount = 0;
const mockFetchFunction = async (params) => {
callCount++;
const page = params.page || 1;
if (page === 1) {
return {
data: {
results: [{ id: 1 }, { id: 2 }, { id: 3 }],
next: 'page2',
count: 7
}
};
} else if (page === 2) {
return {
data: {
results: [{ id: 4 }, { id: 5 }, { id: 6 }],
next: 'page3',
count: 7
}
};
} else if (page === 3) {
return {
data: {
results: [{ id: 7 }],
next: null,
count: 7
}
};
}
};
const result = await fetchAllPaginated(mockFetchFunction, {});
printResult(
'Mock paginated fetch returns all items',
result.length === 7 && callCount === 3,
result.length !== 7 ? `Expected 7 items, got ${result.length}` : `Expected 3 calls, got ${callCount}`
);
} catch (error) {
printResult('Mock paginated fetch', false, error.message);
}
}
/**
* Test 2: fetchAllPaginated with non-paginated array response
*/
async function testFetchAllPaginatedNonPaginated() {
printSection('Test 2: Non-Paginated Array Response');
try {
const mockFetchFunction = async () => {
return {
data: [{ id: 1 }, { id: 2 }, { id: 3 }]
};
};
const result = await fetchAllPaginated(mockFetchFunction, {});
printResult(
'Non-paginated array response handled correctly',
result.length === 3,
`Expected 3 items, got ${result.length}`
);
} catch (error) {
printResult('Non-paginated array response', false, error.message);
}
}
/**
* Test 3: fetchAllPaginated with max page limit
*/
async function testFetchAllPaginatedMaxLimit() {
printSection('Test 3: Max Page Limit Safety');
try {
let callCount = 0;
const mockFetchFunction = async (params) => {
callCount++;
return {
data: {
results: [{ id: callCount }],
next: 'always_has_next', // Infinite pagination
count: 999
}
};
};
const result = await fetchAllPaginated(mockFetchFunction, {}, 5);
printResult(
'Max page limit prevents infinite loops',
callCount === 5 && result.length === 5,
`Expected 5 calls and items, got ${callCount} calls and ${result.length} items`
);
} catch (error) {
printResult('Max page limit', false, error.message);
}
}
/**
* Test 4: Real API - List projects with pagination
*/
async function testListProjectsPagination() {
printSection('Test 4: Real API - List Projects Pagination');
try {
const projects = await taigaService.listProjects();
printResult(
'List projects returns array',
Array.isArray(projects),
'Result is not an array'
);
console.log(` ${colors.yellow}→ Found ${projects.length} project(s)${colors.reset}`);
} catch (error) {
printResult('List projects pagination', false, error.message);
}
}
/**
* Test 5: Real API - List user stories with pagination
*/
async function testListUserStoriesPagination() {
printSection('Test 5: Real API - List User Stories Pagination');
try {
// First get a project
const projects = await taigaService.listProjects();
if (projects.length === 0) {
printResult('List user stories pagination', false, 'No projects available for testing');
return;
}
const projectId = projects[0].id;
const userStories = await taigaService.listUserStories(projectId);
printResult(
'List user stories returns array',
Array.isArray(userStories),
'Result is not an array'
);
console.log(` ${colors.yellow}→ Found ${userStories.length} user stor(y/ies) in project "${projects[0].name}"${colors.reset}`);
} catch (error) {
printResult('List user stories pagination', false, error.message);
}
}
/**
* Test 6: Real API - List issues with pagination
*/
async function testListIssuesPagination() {
printSection('Test 6: Real API - List Issues Pagination');
try {
const projects = await taigaService.listProjects();
if (projects.length === 0) {
printResult('List issues pagination', false, 'No projects available for testing');
return;
}
const projectId = projects[0].id;
const issues = await taigaService.listIssues(projectId);
printResult(
'List issues returns array',
Array.isArray(issues),
'Result is not an array'
);
console.log(` ${colors.yellow}→ Found ${issues.length} issue(s) in project "${projects[0].name}"${colors.reset}`);
} catch (error) {
printResult('List issues pagination', false, error.message);
}
}
/**
* Test 7: Real API - List milestones with pagination
*/
async function testListMilestonesPagination() {
printSection('Test 7: Real API - List Milestones Pagination');
try {
const projects = await taigaService.listProjects();
if (projects.length === 0) {
printResult('List milestones pagination', false, 'No projects available for testing');
return;
}
const projectId = projects[0].id;
const milestones = await taigaService.listMilestones(projectId);
printResult(
'List milestones returns array',
Array.isArray(milestones),
'Result is not an array'
);
console.log(` ${colors.yellow}→ Found ${milestones.length} milestone(s) in project "${projects[0].name}"${colors.reset}`);
} catch (error) {
printResult('List milestones pagination', false, error.message);
}
}
/**
* Test 8: Real API - List epics with pagination
*/
async function testListEpicsPagination() {
printSection('Test 8: Real API - List Epics Pagination');
try {
const projects = await taigaService.listProjects();
if (projects.length === 0) {
printResult('List epics pagination', false, 'No projects available for testing');
return;
}
const projectId = projects[0].id;
const epics = await taigaService.listEpics(projectId);
printResult(
'List epics returns array',
Array.isArray(epics),
'Result is not an array'
);
console.log(` ${colors.yellow}→ Found ${epics.length} epic(s) in project "${projects[0].name}"${colors.reset}`);
} catch (error) {
printResult('List epics pagination', false, error.message);
}
}
/**
* Test 9: Real API - List wiki pages with pagination
*/
async function testListWikiPagesPagination() {
printSection('Test 9: Real API - List Wiki Pages Pagination');
try {
const projects = await taigaService.listProjects();
if (projects.length === 0) {
printResult('List wiki pages pagination', false, 'No projects available for testing');
return;
}
const projectId = projects[0].id;
const wikiPages = await taigaService.listWikiPages(projectId);
printResult(
'List wiki pages returns array',
Array.isArray(wikiPages),
'Result is not an array'
);
console.log(` ${colors.yellow}→ Found ${wikiPages.length} wiki page(s) in project "${projects[0].name}"${colors.reset}`);
} catch (error) {
printResult('List wiki pages pagination', false, error.message);
}
}
/**
* Test 10: Real API - Get issues by milestone with pagination
*/
async function testGetIssuesByMilestonePagination() {
printSection('Test 10: Real API - Get Issues by Milestone Pagination');
try {
const projects = await taigaService.listProjects();
if (projects.length === 0) {
printResult('Get issues by milestone pagination', false, 'No projects available for testing');
return;
}
const projectId = projects[0].id;
const milestones = await taigaService.listMilestones(projectId);
if (milestones.length === 0) {
console.log(` ${colors.yellow}⚠ No milestones available for testing${colors.reset}`);
printResult('Get issues by milestone pagination (skipped)', true, 'No milestones available');
return;
}
const milestoneId = milestones[0].id;
const issues = await taigaService.getIssuesByMilestone(projectId, milestoneId);
printResult(
'Get issues by milestone returns array',
Array.isArray(issues),
'Result is not an array'
);
console.log(` ${colors.yellow}→ Found ${issues.length} issue(s) in milestone "${milestones[0].name}"${colors.reset}`);
} catch (error) {
printResult('Get issues by milestone pagination', false, error.message);
}
}
/**
* Main test runner
*/
async function runPaginationTests() {
console.log(`\n${colors.blue}╔${'═'.repeat(58)}╗${colors.reset}`);
console.log(`${colors.blue}║${' '.repeat(10)}TAIGA MCP PAGINATION TEST SUITE${' '.repeat(15)}║${colors.reset}`);
console.log(`${colors.blue}╚${'═'.repeat(58)}╝${colors.reset}\n`);
// Check authentication
if (!taigaService.isAuthenticated()) {
console.log(`${colors.red}❌ Not authenticated. Please set TAIGA_USERNAME and TAIGA_PASSWORD environment variables.${colors.reset}\n`);
process.exit(1);
}
console.log(`${colors.green}✓ Authentication configured${colors.reset}\n`);
// Run utility tests (no API calls)
await testFetchAllPaginatedUtility();
await testFetchAllPaginatedNonPaginated();
await testFetchAllPaginatedMaxLimit();
// Run real API tests
await testListProjectsPagination();
await testListUserStoriesPagination();
await testListIssuesPagination();
await testListMilestonesPagination();
await testListEpicsPagination();
await testListWikiPagesPagination();
await testGetIssuesByMilestonePagination();
// Print summary
console.log(`\n${colors.blue}${'='.repeat(60)}${colors.reset}`);
console.log(`${colors.blue}TEST SUMMARY${colors.reset}`);
console.log(`${colors.blue}${'='.repeat(60)}${colors.reset}\n`);
console.log(`Total Tests: ${totalTests}`);
console.log(`${colors.green}Passed: ${passedTests}${colors.reset}`);
console.log(`${colors.red}Failed: ${failedTests}${colors.reset}`);
console.log(`Success Rate: ${((passedTests / totalTests) * 100).toFixed(1)}%\n`);
if (failedTests === 0) {
console.log(`${colors.green}✨ All pagination tests passed!${colors.reset}\n`);
process.exit(0);
} else {
console.log(`${colors.red}❌ Some pagination tests failed${colors.reset}\n`);
process.exit(1);
}
}
// Run tests if executed directly
if (import.meta.url === `file://${process.argv[1]}`) {
runPaginationTests().catch(error => {
console.error(`${colors.red}Fatal error:${colors.reset}`, error);
process.exit(1);
});
}
export { runPaginationTests };