Skip to main content
Glama
regression-prevention-relationships-workflows.e2e.test.ts6.91 kB
/** * Split: Regression Prevention E2E – Relationships & Workflows slice */ import { describe, it, expect, beforeAll, afterAll } from 'vitest'; import { callUniversalTool, callTasksTool, callNotesTool, validateTestEnvironment, } from '../utils/enhanced-tool-caller.js'; import { E2EAssertions } from '../utils/assertions.js'; import type { McpToolResponse } from '../utils/assertions.js'; import { testDataGenerator } from '../fixtures/index.js'; import { extractRecordId, createTestRecord, cleanupTestRecords, } from '../utils/error-handling-utils.js'; import { startTestSuite, endTestSuite } from '../utils/logger.js'; describe.skipIf( !process.env.ATTIO_API_KEY || process.env.SKIP_E2E_TESTS === 'true' )('Regression Prevention – Relationships & Workflows', () => { const testRecordIds: string[] = []; const T45 = 45000, T60 = 60000; let prevForceRealApi: string | undefined; beforeAll(async () => { startTestSuite('regression-prevention-relationships-workflows'); const validation = await validateTestEnvironment(); if (!validation.valid) console.warn( '⚠️ Regression prevention test warnings:', validation.warnings ); // Ensure create + read operate against the same backend. // In E2E mode the system prefers mocks for create, while reads hit real API. // Force real API for this suite when an API key is available to keep CRUD consistent. prevForceRealApi = process.env.FORCE_REAL_API; if (process.env.ATTIO_API_KEY) { process.env.FORCE_REAL_API = 'true'; } }); afterAll(async () => { if (testRecordIds.length > 0) await cleanupTestRecords(testRecordIds); // Restore environment if (prevForceRealApi === undefined) delete process.env.FORCE_REAL_API; else process.env.FORCE_REAL_API = prevForceRealApi; endTestSuite(); }); it( 'preserves core CRUD workflow integrity', async () => { let recordId: string | undefined; const companyData = testDataGenerator.companies.basicCompany(); const createResponse = (await callUniversalTool('create-record', { resource_type: 'companies', record_data: companyData, } as any)) as McpToolResponse; E2EAssertions.expectMcpSuccess(createResponse); recordId = extractRecordId(createResponse as McpToolResponse); expect(recordId).toBeDefined(); if (!recordId) return; testRecordIds.push(recordId); const readResponse = (await callUniversalTool('get-record-details', { resource_type: 'companies', record_id: recordId, } as any)) as McpToolResponse; E2EAssertions.expectMcpSuccess(readResponse); // get-record-details returns data in content array, just verify success expect(readResponse.content).toBeDefined(); expect( Array.isArray(readResponse.content) ? readResponse.content.length > 0 : readResponse.content ).toBeTruthy(); const updateResponse = (await callUniversalTool('update-record', { resource_type: 'companies', record_id: recordId, record_data: { description: 'Updated for CRUD workflow test' }, } as any)) as McpToolResponse; E2EAssertions.expectMcpSuccess(updateResponse); const verifyResponse = (await callUniversalTool('get-record-details', { resource_type: 'companies', record_id: recordId, } as any)) as McpToolResponse; E2EAssertions.expectMcpSuccess(verifyResponse); // Verify the response is valid (updated description verification would require parsing) expect(verifyResponse.content).toBeDefined(); expect( Array.isArray(verifyResponse.content) ? verifyResponse.content.length > 0 : verifyResponse.content ).toBeTruthy(); console.error('✅ Core CRUD workflow integrity preserved'); }, T45 ); it( 'preserves cross-resource relationship integrity', async () => { const companyData = testDataGenerator.companies.basicCompany(); const companyId = await createTestRecord( (resourceType, data) => callUniversalTool('create-record', { resource_type: resourceType as any, record_data: data, }), 'companies', companyData ); if (!companyId) { console.error( '⏭️ Skipping relationship test - could not create company' ); return; } testRecordIds.push(companyId); const taskResponse = await callTasksTool('create-record', { resource_type: 'tasks', record_data: { content: 'Relationship integrity test task', recordId: companyId, targetObject: 'companies', }, } as any); expect(taskResponse).toBeDefined(); const noteResponse = await callNotesTool('create-note', { resource_type: 'companies', record_id: companyId, title: 'Relationship integrity test note', content: 'Testing cross-resource relationships', format: 'markdown', } as any); expect(noteResponse).toBeDefined(); const companyCheck = (await callUniversalTool('get-record-details', { resource_type: 'companies', record_id: companyId, } as any)) as McpToolResponse; E2EAssertions.expectMcpSuccess(companyCheck); // Verify company details are returned successfully expect(companyCheck.content).toBeDefined(); expect( Array.isArray(companyCheck.content) ? companyCheck.content.length > 0 : companyCheck.content ).toBeTruthy(); console.error('✅ Cross-resource relationship integrity preserved'); }, T60 ); it( 'preserves data validation rules', async () => { const validationTests = [ { name: 'Required field validation', test: async () => { const response = await callUniversalTool('create-record', { resource_type: 'companies', record_data: { /* intentionally missing required fields to assert validation */ }, } as any); return response; }, }, { name: 'Data type validation', test: async () => { const response = await callUniversalTool('search-records', { resource_type: 'companies', query: 'validation-test', limit: 5, } as any); return response; }, }, ]; for (const validationTest of validationTests) { const result = await validationTest.test(); expect(result).toBeDefined(); console.error(`✅ ${validationTest.name} preserved`); } console.error('✅ Data validation rules preservation validated'); }, T45 ); });

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/kesslerio/attio-mcp-server'

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