Skip to main content
Glama
smart-test-case-retrieval.test.tsโ€ข10.9 kB
import { describe, it } from 'node:test'; import { strict as assert } from 'node:assert'; /** * Unit tests for get_test_cases_by_suite_smart tool * * Tests the smart suite detection and filtering logic: * - Parameter validation * - Suite type detection (root vs child) * - Appropriate filtering method selection * - Error handling * - Format validation */ describe('Smart Test Case Retrieval Tool Unit Tests', () => { describe('get_test_cases_by_suite_smart Parameter Validation', () => { it('should validate required parameters', () => { const validParams = { project_key: 'MCP', suite_id: 18824, format: 'json' }; assert.ok(validParams.project_key, 'project_key should be required'); assert.ok(validParams.suite_id, 'suite_id should be required'); assert.ok(validParams.project_key.length > 0, 'project_key should not be empty'); assert.ok(validParams.suite_id > 0, 'suite_id should be positive'); }); it('should validate project_key format', () => { const validProjectKeys = ['MCP', 'AND', 'ANDROID', 'IOS']; const invalidProjectKeys = ['', '123', 'mcp', 'project-key']; validProjectKeys.forEach(key => { assert.ok(key.length > 0, `${key} should be non-empty`); assert.ok(key.match(/^[A-Z]+[A-Z0-9]*$/), `${key} should match project key pattern`); }); invalidProjectKeys.forEach(key => { if (key === '') { assert.equal(key.length, 0, 'Empty key should be invalid'); } else { assert.ok(!key.match(/^[A-Z]+[A-Z0-9]*$/), `${key} should not match project key pattern`); } }); }); it('should validate suite_id as positive integer', () => { const validSuiteIds = [1, 100, 18824, 999999]; const invalidSuiteIds = [0, -1, -100, 1.5, NaN, Infinity]; validSuiteIds.forEach(id => { assert.ok(Number.isInteger(id), `${id} should be integer`); assert.ok(id > 0, `${id} should be positive`); }); invalidSuiteIds.forEach(id => { if (Number.isNaN(id) || !Number.isFinite(id)) { assert.ok(Number.isNaN(id) || !Number.isFinite(id), `${id} should be invalid`); } else { assert.ok(id <= 0 || !Number.isInteger(id), `${id} should be invalid`); } }); }); it('should validate format parameter', () => { const validFormats = ['dto', 'json', 'string', 'markdown']; const invalidFormats = ['xml', 'yaml', 'csv', '']; validFormats.forEach(format => { assert.ok(validFormats.includes(format), `${format} should be valid format`); }); invalidFormats.forEach(format => { assert.ok(!validFormats.includes(format), `${format} should not be valid format`); }); }); it('should validate pagination parameters', () => { const validPagination = { page: 0, size: 50 }; const invalidPagination = [ { page: -1, size: 50 }, { page: 0, size: 0 }, { page: 0, size: 101 }, { page: 1.5, size: 50 }, { page: 0, size: -10 } ]; assert.ok(validPagination.page >= 0, 'page should be non-negative'); assert.ok(Number.isInteger(validPagination.page), 'page should be integer'); assert.ok(validPagination.size > 0, 'size should be positive'); assert.ok(validPagination.size <= 100, 'size should not exceed 100'); assert.ok(Number.isInteger(validPagination.size), 'size should be integer'); invalidPagination.forEach(params => { const isValidPage = Number.isInteger(params.page) && params.page >= 0; const isValidSize = Number.isInteger(params.size) && params.size > 0 && params.size <= 100; assert.ok(!isValidPage || !isValidSize, `Invalid pagination: page=${params.page}, size=${params.size}`); }); }); it('should validate include_steps parameter', () => { const validIncludeSteps = [true, false]; const invalidIncludeSteps = ['true', 'false', 1, 0, null, undefined]; validIncludeSteps.forEach(value => { assert.equal(typeof value, 'boolean', `${value} should be boolean`); }); invalidIncludeSteps.forEach(value => { assert.notEqual(typeof value, 'boolean', `${value} should not be boolean`); }); }); }); describe('Suite Type Detection Logic', () => { it('should identify root suite characteristics', () => { // Mock suite data representing a root suite const rootSuite = { id: 18824, name: 'Root Suite', parentSuiteId: null, rootSuiteId: 18824 }; const childSuite = { id: 18825, name: 'Child Suite', parentSuiteId: 18824, rootSuiteId: 18824 }; // Root suite detection logic const isRootSuite = (suite: any) => suite.id === suite.rootSuiteId; assert.ok(isRootSuite(rootSuite), 'Root suite should be detected correctly'); assert.ok(!isRootSuite(childSuite), 'Child suite should not be detected as root'); }); it('should determine appropriate filtering method', () => { const rootSuiteId = 18824; const childSuiteId = 18825; // Filtering logic const getFilterParams = (suiteId: number, isRoot: boolean) => { if (isRoot) { return { rootSuiteId: suiteId }; } else { return { suiteId: suiteId }; } }; const rootParams = getFilterParams(rootSuiteId, true); const childParams = getFilterParams(childSuiteId, false); assert.ok('rootSuiteId' in rootParams, 'Root suite should use rootSuiteId filter'); assert.ok(!('suiteId' in rootParams), 'Root suite should not use suiteId filter'); assert.ok('suiteId' in childParams, 'Child suite should use suiteId filter'); assert.ok(!('rootSuiteId' in childParams), 'Child suite should not use rootSuiteId filter'); }); }); describe('Error Handling Scenarios', () => { it('should handle non-existent suite ID', () => { const nonExistentSuiteId = 999999999; const mockSuites = [ { id: 18824, name: 'Existing Suite 1' }, { id: 18825, name: 'Existing Suite 2' } ]; const findSuite = (suiteId: number) => mockSuites.find(s => s.id === suiteId); const result = findSuite(nonExistentSuiteId); assert.equal(result, undefined, 'Non-existent suite should return undefined'); }); it('should handle invalid project key', () => { const invalidProjectKeys = ['', 'invalid-project', '123', 'lowercase']; const projectKeyPattern = /^[A-Z]+[A-Z0-9]*$/; invalidProjectKeys.forEach(key => { const isValid = key.length > 0 && projectKeyPattern.test(key); assert.ok(!isValid, `Invalid project key ${key} should be rejected`); }); }); it('should handle page size limits', () => { const maxPageSize = 100; const validSizes = [1, 10, 50, 100]; const invalidSizes = [0, -1, 101, 1000]; validSizes.forEach(size => { assert.ok(size > 0 && size <= maxPageSize, `Size ${size} should be valid`); }); invalidSizes.forEach(size => { assert.ok(size <= 0 || size > maxPageSize, `Size ${size} should be invalid`); }); }); }); describe('Response Format Validation', () => { it('should validate metadata structure', () => { const expectedMetadata = { suite: { id: 18824, name: 'Test Suite', isRootSuite: true, rootSuiteId: 18824 }, filtering: { method: 'rootSuiteId', description: 'root suite 18824 (includes all sub-suites)', parameterUsed: { rootSuiteId: 18824 } }, results: { count: 9, page: 0, size: 50, includesSteps: false } }; // Validate metadata structure assert.ok(expectedMetadata.suite, 'Metadata should include suite info'); assert.ok(expectedMetadata.filtering, 'Metadata should include filtering info'); assert.ok(expectedMetadata.results, 'Metadata should include results info'); assert.ok(typeof expectedMetadata.suite.id === 'number', 'Suite ID should be number'); assert.ok(typeof expectedMetadata.suite.name === 'string', 'Suite name should be string'); assert.ok(typeof expectedMetadata.suite.isRootSuite === 'boolean', 'isRootSuite should be boolean'); assert.ok(typeof expectedMetadata.filtering.method === 'string', 'Filtering method should be string'); assert.ok(['suiteId', 'rootSuiteId'].includes(expectedMetadata.filtering.method), 'Method should be valid'); assert.ok(typeof expectedMetadata.results.count === 'number', 'Results count should be number'); assert.ok(expectedMetadata.results.count >= 0, 'Results count should be non-negative'); }); it('should validate test case structure', () => { const mockTestCase = { id: 12345, key: 'MCP-12', name: 'Test Case Name', testSuite: { id: 18825, name: 'Child Suite' }, rootSuiteId: 18824, status: 'Active' }; assert.ok(typeof mockTestCase.id === 'number', 'Test case ID should be number'); assert.ok(typeof mockTestCase.key === 'string', 'Test case key should be string'); assert.ok(mockTestCase.key.match(/^[A-Z]+-\d+$/), 'Test case key should match pattern'); assert.ok(mockTestCase.testSuite, 'Test case should have suite info'); assert.ok(typeof mockTestCase.rootSuiteId === 'number', 'Root suite ID should be number'); }); }); describe('Performance Considerations', () => { it('should validate reasonable timeout expectations', () => { // The smart tool needs to fetch all suites for hierarchy analysis // This should complete within reasonable time limits const expectedTimeoutMs = 30000; // 30 seconds const minimumTimeoutMs = 5000; // 5 seconds assert.ok(expectedTimeoutMs >= minimumTimeoutMs, 'Timeout should be reasonable'); assert.ok(expectedTimeoutMs <= 60000, 'Timeout should not be excessive'); }); it('should validate pagination for large result sets', () => { const maxExpectedTestCases = 1000; // Reasonable upper limit const defaultPageSize = 50; const maxPages = Math.ceil(maxExpectedTestCases / defaultPageSize); assert.ok(maxPages <= 20, 'Should not require excessive pagination'); assert.ok(defaultPageSize >= 10, 'Page size should be reasonable'); }); }); });

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