Skip to main content
Glama
people.integration.test.ts13.1 kB
import { describe, it, expect } from '@jest/globals'; import { executeToolWithRetry, generateTestPersonData, cleanupTestData, } from '../utils/test-helpers.ts'; import { entitySchemaValidator } from '../utils/schema-validator.ts'; import { ErrorTestUtils, createErrorTestCases } from '../utils/error-handling.ts'; import { TEST_CONFIG } from '../setup.ts'; describe('People Tools Integration Tests', () => { const createdPeople: number[] = []; afterEach(async () => { // Clean up created people for (const personId of createdPeople) { await cleanupTestData('person', personId); } createdPeople.length = 0; }); describe('list-people', () => { it('should list all people', async () => { const result = await executeToolWithRetry('list-people', {}); expect(result).toBeDefined(); expect(Array.isArray(result)).toBe(true); // Validate schema for each person if (result.length > 0) { result.forEach((person: any) => { entitySchemaValidator.validatePerson(person); }); } }); it('should list people with pagination', async () => { const result = await executeToolWithRetry('list-people', { page: 1, 'per-page': 10, }); expect(result).toBeDefined(); expect(Array.isArray(result)).toBe(true); expect(result.length).toBeLessThanOrEqual(10); }); it('should filter people by department', async () => { const result = await executeToolWithRetry('list-people', { department_id: 1, }); expect(result).toBeDefined(); expect(Array.isArray(result)).toBe(true); // Validate that all returned people have the expected department result.forEach((person: any) => { if (person.department && person.department.department_id) { expect(person.department.department_id).toBe(1); } }); }); it('should filter people by active status', async () => { const result = await executeToolWithRetry('list-people', { active: 1, // Active people }); expect(result).toBeDefined(); expect(Array.isArray(result)).toBe(true); // Validate that all returned people are active result.forEach((person: any) => { expect(person.active).toBe(1); }); }); it('should filter people by employee type', async () => { const result = await executeToolWithRetry('list-people', { employee_type: 1, // Full-time employees }); expect(result).toBeDefined(); expect(Array.isArray(result)).toBe(true); // Validate that all returned people have the expected employee type result.forEach((person: any) => { expect(person.employee_type).toBe(1); }); }); }); describe('get-person', () => { it('should get a specific person by ID', async () => { // First, get a person ID from the list const people = await executeToolWithRetry('list-people', { 'per-page': 1 }); if (people.length === 0) { console.warn('No people found to test get-person'); return; } const personId = people[0].people_id; const result = await executeToolWithRetry('get-person', { people_id: personId, }); expect(result).toBeDefined(); expect(result.people_id).toBe(personId); // Validate schema entitySchemaValidator.validatePerson(result); }); it('should handle string person ID', async () => { const people = await executeToolWithRetry('list-people', { 'per-page': 1 }); if (people.length === 0) { console.warn('No people found to test get-person with string ID'); return; } const personId = people[0].people_id.toString(); const result = await executeToolWithRetry('get-person', { people_id: personId, }); expect(result).toBeDefined(); expect(result.people_id).toBe(parseInt(personId)); }); }); describe('create-person', () => { it('should create a new person', async () => { if (!TEST_CONFIG.enableRealApiCalls) { console.warn('Skipping create-person test - real API calls disabled'); return; } const personData = generateTestPersonData(); const result = await executeToolWithRetry('create-person', personData); expect(result).toBeDefined(); expect(result.people_id).toBeDefined(); expect(result.name).toBe(personData.name); expect(result.email).toBe(personData.email); // Track for cleanup createdPeople.push(result.people_id); // Validate schema entitySchemaValidator.validatePerson(result); }); it('should create person with all optional fields', async () => { if (!TEST_CONFIG.enableRealApiCalls) { console.warn('Skipping create-person with optional fields test - real API calls disabled'); return; } const personData = generateTestPersonData({ job_title: 'Senior Developer', department_id: 1, notes: 'Test person with all fields', auto_email: 1, employee_type: 1, start_date: '2024-01-01', default_hourly_rate: '75.00', }); const result = await executeToolWithRetry('create-person', personData); expect(result).toBeDefined(); expect(result.people_id).toBeDefined(); expect(result.job_title).toBe(personData.job_title); expect(result.employee_type).toBe(personData.employee_type); // Track for cleanup createdPeople.push(result.people_id); // Validate schema entitySchemaValidator.validatePerson(result); }); }); describe('update-person', () => { it('should update an existing person', async () => { const personData = { name: 'Update Test Person', email: `update-test-${Date.now()}@example.com`, employee_type: 1, active: 1, }; const created = await executeToolWithRetry('create-person', personData); expect(created.people_id).toBeDefined(); const updatedName = `Updated ${personData.name}`; const result = await executeToolWithRetry('update-person', { people_id: created.people_id, name: updatedName, job_title: 'Updated Title', }); expect(result).toBeDefined(); // For real API, we may need to fetch the updated person to verify changes if (process.env.TEST_REAL_API === 'true') { const updatedPerson = await executeToolWithRetry('get-person', { people_id: created.people_id, }); expect(updatedPerson.people_id).toBe(created.people_id); expect(updatedPerson.name).toBe(updatedName); expect(updatedPerson.job_title).toBe('Updated Title'); } else { expect(result.people_id).toBe(created.people_id); expect(result.name).toBe(updatedName); expect(result.job_title).toBe('Updated Title'); } // Track for cleanup createdPeople.push(created.people_id); }); it('should update person with partial data', async () => { const personData = { name: 'Partial Update Test Person', email: `partial-update-test-${Date.now()}@example.com`, employee_type: 1, active: 1, }; const created = await executeToolWithRetry('create-person', personData); expect(created.people_id).toBeDefined(); const result = await executeToolWithRetry('update-person', { people_id: created.people_id, job_title: 'Lead Developer', }); expect(result).toBeDefined(); // For real API, we may need to fetch the updated person to verify changes if (process.env.TEST_REAL_API === 'true') { const updatedPerson = await executeToolWithRetry('get-person', { people_id: created.people_id, }); expect(updatedPerson.people_id).toBe(created.people_id); expect(updatedPerson.job_title).toBe('Lead Developer'); expect(updatedPerson.name).toBe(personData.name); // Should remain unchanged } else { expect(result.people_id).toBe(created.people_id); expect(result.job_title).toBe('Lead Developer'); expect(result.name).toBe(personData.name); // Should remain unchanged } // Track for cleanup createdPeople.push(created.people_id); }); }); describe('delete-person', () => { it('should delete (archive) a person', async () => { if (!TEST_CONFIG.enableRealApiCalls) { console.warn('Skipping delete-person test - real API calls disabled'); return; } // First create a person const personData = generateTestPersonData(); const created = await executeToolWithRetry('create-person', personData); // Delete the person const result = await executeToolWithRetry('delete-person', { people_id: created.people_id, }); expect(result).toBeDefined(); expect(result.success).toBe(true); expect(result.message).toContain('archived'); // Verify person is no longer accessible (or is archived) try { await executeToolWithRetry('get-person', { people_id: created.people_id, }); // If we get here, the person still exists (might be archived) console.warn('Person still exists after deletion - may be archived instead'); } catch (error) { // Expected if person is truly deleted expect(error).toBeDefined(); } }); }); describe('Error Handling', () => { const errorTestCases = createErrorTestCases('person'); errorTestCases.forEach(({ name, test }) => { it(name, async () => { const validParams = generateTestPersonData(); await test('get-person', validParams); }); }); it('should handle invalid people_id in get-person', async () => { await ErrorTestUtils.testNotFoundError( 'get-person', { people_id: 999999999, }, 'people' ); }); it('should handle invalid data in create-person', async () => { await ErrorTestUtils.testValidationError('create-person', { name: '', // Empty name email: 'invalid-email', // Invalid email }); }); it('should handle missing required fields in create-person', async () => { await ErrorTestUtils.testValidationError('create-person', { // Missing name email: 'test@example.com', }); }); it('should handle duplicate email in create-person', async () => { // Skip this test for real API as it may not enforce duplicate email validation if (process.env.TEST_REAL_API === 'true') { console.warn('Skipping duplicate email test - real API may not enforce this validation'); return; } const personData = { name: 'Duplicate Email Test Person', email: 'duplicate@example.com', employee_type: 1, active: 1, }; // Create first person const first = await executeToolWithRetry('create-person', personData); createdPeople.push(first.people_id); // Attempt to create second person with same email await ErrorTestUtils.testValidationError('create-person', personData, 'duplicate email'); }); }); describe('Performance Tests', () => { it('should handle concurrent requests', async () => { if (TEST_CONFIG.skipSlowTests) { console.warn('Skipping performance test - slow tests disabled'); return; } const requests = Array.from({ length: 5 }, () => executeToolWithRetry('list-people', { 'per-page': 5 }) ); const results = await Promise.all(requests); expect(results).toHaveLength(5); results.forEach((result) => { expect(Array.isArray(result)).toBe(true); }); }); }); describe('Data Validation', () => { it('should validate person data structure', async () => { const people = await executeToolWithRetry('list-people', { 'per-page': 5 }); people.forEach((person: any) => { expect(person).toBeDefined(); expect(person.people_id).toBeDefined(); expect(person.name).toBeDefined(); expect(typeof person.name).toBe('string'); expect(person.name.length).toBeGreaterThan(0); // Validate schema const validation = entitySchemaValidator.validatePerson(person); expect(validation.isValid).toBe(true); }); }); it('should handle null values in person data', async () => { const people = await executeToolWithRetry('list-people', { 'per-page': 5 }); people.forEach((person: any) => { // These fields can be null according to the schema if (person.email !== null) { expect(typeof person.email).toBe('string'); } if (person.job_title !== null) { expect(typeof person.job_title).toBe('string'); } if (person.notes !== null) { expect(typeof person.notes).toBe('string'); } }); }); }); });

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/asachs01/float-mcp'

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