Skip to main content
Glama
suite-tools.test.tsโ€ข11.6 kB
import { describe, it } from 'node:test'; import { strict as assert } from 'node:assert'; /** * Unit tests for suite-related MCP tools * * Tests the following tools: * - list_test_suites * - get_tcm_suite_by_id * - get_root_suites * - get_suite_hierarchy * - get_all_subsuites * - get_tcm_test_suites_by_project * - get_all_tcm_test_case_suites_by_project */ describe('Suite Tools Unit Tests', () => { describe('list_test_suites Tool', () => { it('should validate required parameters', () => { const validParams = { project_key: 'MCP', format: 'json', page: 0, size: 50 }; assert.ok(validParams.project_key, 'project_key should be required'); assert.ok(validParams.project_key.length > 0, 'project_key should not be empty'); }); it('should validate pagination parameters', () => { const validPagination = { page: 0, size: 50, page_token: 'optional-token' }; assert.ok(validPagination.page >= 0, 'page should be non-negative'); assert.ok(validPagination.size > 0, 'size should be positive'); assert.ok(validPagination.size <= 1000, 'size should not exceed maximum'); }); it('should validate format parameter', () => { const validFormats = ['dto', 'json', 'string']; const invalidFormat = 'xml'; assert.ok(validFormats.includes('json'), 'json should be valid format'); assert.ok(!validFormats.includes(invalidFormat), 'xml should not be valid format'); }); it('should structure pagination response correctly', () => { const mockResponse = { items: [ { id: 18815, title: 'Treatment ON', parentSuiteId: 18814 } ], _meta: { nextPageToken: 'token123' }, pagination: { currentPage: 0, pageSize: 50, hasNextPage: true, nextPageToken: 'token123' } }; assert.ok(Array.isArray(mockResponse.items), 'items should be array'); assert.ok(mockResponse.pagination, 'pagination info should be present'); assert.equal(mockResponse.pagination.hasNextPage, !!mockResponse._meta.nextPageToken, 'hasNextPage should match token presence'); }); }); describe('get_tcm_suite_by_id Tool', () => { it('should validate required parameters', () => { const validParams = { project_key: 'MCP', suite_id: 17470, format: 'json' }; assert.ok(validParams.project_key, 'project_key should be required'); assert.ok(validParams.suite_id > 0, 'suite_id should be positive integer'); }); it('should validate suite_id parameter type', () => { const validSuiteId = 17470; const invalidSuiteId = 'not-a-number'; assert.equal(typeof validSuiteId, 'number', 'suite_id should be number'); assert.notEqual(typeof invalidSuiteId, 'number', 'string should not be valid suite_id'); }); it('should handle only_root_suites parameter', () => { const params = { project_key: 'MCP', suite_id: 17470, only_root_suites: false }; assert.equal(typeof params.only_root_suites, 'boolean', 'only_root_suites should be boolean'); }); it('should structure suite response with hierarchy', () => { const mockSuiteResponse = { id: 17470, title: 'Budget', description: null, parentSuiteId: 17468, relativePosition: 1, rootSuiteId: 17441, rootSuiteName: '10. Meal Planner', parentSuiteName: 'Settings', treeNames: '10. Meal Planner > Settings > Budget' }; assert.ok(mockSuiteResponse.id, 'suite should have id'); assert.ok(mockSuiteResponse.title, 'suite should have title'); assert.ok(mockSuiteResponse.rootSuiteId, 'suite should have rootSuiteId'); assert.ok(mockSuiteResponse.treeNames, 'suite should have hierarchy path'); }); }); describe('get_root_suites Tool', () => { it('should validate required parameters', () => { const validParams = { project_key: 'MCP', format: 'json' }; assert.ok(validParams.project_key, 'project_key should be required'); assert.ok(validParams.project_key.length > 0, 'project_key should not be empty'); }); it('should identify root suites correctly', () => { const mockSuites = [ { id: 1, title: 'Root Suite 1', parentSuiteId: null }, { id: 2, title: 'Child Suite', parentSuiteId: 1 }, { id: 3, title: 'Root Suite 2', parentSuiteId: null } ]; const rootSuites = mockSuites.filter(suite => suite.parentSuiteId === null); assert.equal(rootSuites.length, 2, 'should find 2 root suites'); assert.ok(rootSuites.every(suite => suite.parentSuiteId === null), 'all root suites should have null parentSuiteId'); }); }); describe('get_suite_hierarchy Tool', () => { it('should validate required parameters', () => { const validParams = { project_key: 'MCP', max_depth: 5, format: 'json' }; assert.ok(validParams.project_key, 'project_key should be required'); assert.ok(validParams.max_depth > 0, 'max_depth should be positive'); assert.ok(validParams.max_depth <= 10, 'max_depth should not exceed maximum'); }); it('should validate max_depth parameter', () => { const validDepth = 5; const invalidDepthZero = 0; const invalidDepthTooHigh = 11; assert.ok(validDepth > 0 && validDepth <= 10, 'depth 5 should be valid'); assert.ok(invalidDepthZero <= 0, 'depth 0 should be invalid'); assert.ok(invalidDepthTooHigh > 10, 'depth 11 should exceed maximum'); }); it('should handle root_suite_id parameter', () => { const params = { project_key: 'MCP', root_suite_id: 18659 }; assert.ok(params.root_suite_id > 0, 'root_suite_id should be positive when provided'); }); }); describe('get_all_subsuites Tool', () => { it('should validate required parameters', () => { const validParams = { project_key: 'MCP', root_suite_id: 1079, include_root: true, format: 'json' }; assert.ok(validParams.project_key, 'project_key should be required'); assert.ok(validParams.root_suite_id > 0, 'root_suite_id should be positive'); }); it('should validate pagination parameters', () => { const validPagination = { page: 0, size: 50 }; assert.ok(validPagination.page >= 0, 'page should be non-negative'); assert.ok(validPagination.size > 0, 'size should be positive'); assert.ok(validPagination.size <= 1000, 'size should not exceed maximum'); }); it('should handle include_root parameter', () => { const params = { project_key: 'MCP', root_suite_id: 1079, include_root: true }; assert.equal(typeof params.include_root, 'boolean', 'include_root should be boolean'); }); }); describe('get_tcm_test_suites_by_project Tool', () => { it('should validate required parameters', () => { const validParams = { project_key: 'MCP', max_page_size: 100, format: 'json' }; assert.ok(validParams.project_key, 'project_key should be required'); assert.ok(validParams.max_page_size > 0, 'max_page_size should be positive'); assert.ok(validParams.max_page_size <= 1000, 'max_page_size should not exceed maximum'); }); it('should handle page_token parameter', () => { const params = { project_key: 'MCP', page_token: 'abc123token' }; assert.equal(typeof params.page_token, 'string', 'page_token should be string when provided'); }); it('should validate max_page_size against configured limit', () => { const MAX_PAGE_SIZE = 100; // Simulated config value const validSize = 50; const invalidSize = 150; assert.ok(validSize <= MAX_PAGE_SIZE, 'valid size should not exceed limit'); assert.ok(invalidSize > MAX_PAGE_SIZE, 'invalid size should exceed limit'); }); }); describe('Suite Response Validation', () => { it('should validate suite object structure', () => { const mockSuite = { id: 17470, title: 'Budget', description: null, parentSuiteId: 17468, relativePosition: 1 }; assert.ok(typeof mockSuite.id === 'number', 'id should be number'); assert.ok(typeof mockSuite.title === 'string', 'title should be string'); assert.ok(mockSuite.parentSuiteId === null || typeof mockSuite.parentSuiteId === 'number', 'parentSuiteId should be number or null'); }); it('should validate enriched suite with hierarchy', () => { const enrichedSuite = { id: 17470, title: 'Budget', parentSuiteId: 17468, rootSuiteId: 17441, level: 2, path: '10. Meal Planner > Settings > Budget' }; assert.ok(enrichedSuite.rootSuiteId, 'enriched suite should have rootSuiteId'); assert.ok(typeof enrichedSuite.level === 'number', 'level should be number'); assert.ok(enrichedSuite.path, 'enriched suite should have path'); }); it('should validate paged suite response', () => { const pagedResponse = { items: [ { id: 1, title: 'Suite 1' }, { id: 2, title: 'Suite 2' } ], _meta: { nextPageToken: 'token123', totalElements: 1188, currentPage: 0, pageSize: 50 } }; assert.ok(Array.isArray(pagedResponse.items), 'items should be array'); assert.ok(pagedResponse._meta, 'response should have metadata'); assert.ok(typeof pagedResponse._meta.totalElements === 'number', 'totalElements should be number'); }); }); describe('Error Handling', () => { it('should handle missing project_key', () => { const invalidParams = { suite_id: 17470, format: 'json' }; assert.ok(!invalidParams.hasOwnProperty('project_key'), 'should detect missing project_key'); }); it('should handle invalid suite_id', () => { const invalidSuiteId = -1; const validSuiteId = 17470; assert.ok(invalidSuiteId <= 0, 'negative suite_id should be invalid'); assert.ok(validSuiteId > 0, 'positive suite_id should be valid'); }); it('should handle invalid format', () => { const validFormats = ['dto', 'json', 'string', 'markdown']; const invalidFormat = 'xml'; assert.ok(!validFormats.includes(invalidFormat), 'xml should not be valid format'); }); it('should provide helpful error messages', () => { const MAX_PAGE_SIZE = 100; const requestedSize = 200; const errorMessage = `โŒ Error: Requested page size (${requestedSize}) exceeds configured maximum (${MAX_PAGE_SIZE}). Set MAX_PAGE_SIZE environment variable to increase the limit.`; assert.ok(errorMessage.includes('exceeds configured maximum'), 'Error should explain the limit'); assert.ok(errorMessage.includes('MAX_PAGE_SIZE environment variable'), 'Error should mention configuration'); }); }); });

Latest Blog Posts

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/maksimsarychau/mcp-zebrunner'

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