Skip to main content
Glama
record-management-relationships.e2e.test.ts6.48 kB
/** * Split: Record Management E2E – Relationships slice */ import { describe, it, expect, beforeAll, afterAll, beforeEach, vi, } from 'vitest'; import { E2ETestBase } from '../setup.js'; import { E2EAssertions } from '../utils/assertions.js'; import { CompanyFactory, PersonFactory, TaskFactory, } from '../fixtures/index.js'; import type { McpToolResponse } from '../types/index.js'; import { callUniversalTool, callTasksTool, callNotesTool, validateTestEnvironment, getToolMigrationStats, } from '../utils/enhanced-tool-caller.js'; import { startTestSuite, endTestSuite } from '../utils/logger.js'; function asToolResponse(response: unknown): McpToolResponse { return response as McpToolResponse; } const T45 = 45000, T60 = 60000; describe.skipIf( !process.env.ATTIO_API_KEY || process.env.SKIP_E2E_TESTS === 'true' )('Record Management E2E – Relationships', () => { let prevForceRealApi: string | undefined; beforeAll(async () => { startTestSuite('record-management-relationships'); const envValidation = await validateTestEnvironment(); if (!envValidation.valid) console.warn('⚠️ Test environment warnings:', envValidation.warnings); console.error('📊 Tool migration stats:', getToolMigrationStats()); await E2ETestBase.setup({ requiresRealApi: false, cleanupAfterTests: true, timeout: 120000, }); // Ensure consistent backend for create + read prevForceRealApi = process.env.FORCE_REAL_API; if (process.env.ATTIO_API_KEY) process.env.FORCE_REAL_API = 'true'; console.error('🚀 Starting Record Management E2E – Relationships'); }, T60); afterAll(async () => { // Restore environment if (prevForceRealApi === undefined) delete process.env.FORCE_REAL_API; else process.env.FORCE_REAL_API = prevForceRealApi; endTestSuite(); console.error('✅ Record Management E2E – Relationships completed'); }, T60); beforeEach(() => { vi.clearAllMocks(); }); it( 'validates record relationships across types', async () => { // Ensure we have a company, a person and a task to relate const companyResp = asToolResponse( await callUniversalTool('create-record', { resource_type: 'companies', record_data: CompanyFactory.create() as any, }) ); E2EAssertions.expectMcpSuccess(companyResp); const company = E2EAssertions.expectMcpData(companyResp)!; const companyId = (company as any).id?.record_id; const personResp = asToolResponse( await callUniversalTool('create-record', { resource_type: 'people', record_data: PersonFactory.create() as any, }) ); E2EAssertions.expectMcpSuccess(personResp); const person = E2EAssertions.expectMcpData(personResp)!; const personId = (person as any).id?.record_id; const taskData = TaskFactory.create(); const taskCreate = asToolResponse( await callTasksTool('create-record', { resource_type: 'tasks', record_data: { content: 'Relationship validation task', due_date: taskData.due_date, }, }) ); E2EAssertions.expectMcpSuccess(taskCreate); const task = E2EAssertions.expectMcpData(taskCreate)!; const taskId = (task as any).id?.task_id; expect(companyId && personId && taskId).toBeTruthy(); if (taskId && companyId) { // Use correct schema for linking: recordIds expects an array const linkResponse = asToolResponse( await callTasksTool('update-record', { resource_type: 'tasks', record_id: taskId, record_data: { recordIds: [companyId] }, }) ); expect(linkResponse).toBeDefined(); } if (companyId) { const companyNote = asToolResponse( await callNotesTool('create-note', { resource_type: 'companies', record_id: companyId, title: 'Company relationship note', content: 'Testing cross-resource relationships', format: 'markdown', }) ); expect(companyNote).toBeDefined(); } if (personId) { const personNote = asToolResponse( await callNotesTool('create-note', { resource_type: 'people', record_id: personId, title: 'Person relationship note', content: 'Testing cross-resource relationships', format: 'markdown', }) ); expect(personNote).toBeDefined(); } console.error('✅ Cross-resource relationship validation completed'); }, T60 ); it( 'validates data consistency across operations', async () => { const companyResp = asToolResponse( await callUniversalTool('create-record', { resource_type: 'companies', record_data: CompanyFactory.create() as any, }) ); E2EAssertions.expectMcpSuccess(companyResp); const company = E2EAssertions.expectMcpData(companyResp)!; const companyId = (company as any).id?.record_id; if (!companyId) { console.error( '⏭️ Skipping consistency validation - invalid company ID' ); return; } const detailsResponse = asToolResponse( await callUniversalTool('get-record-details', { resource_type: 'companies', record_id: companyId, }) ); const noteResponse = asToolResponse( await callNotesTool('create-note', { resource_type: 'companies', record_id: companyId, title: 'Consistency validation note', content: 'Testing data consistency', format: 'markdown', }) ); const taskData2 = TaskFactory.create(); const taskResponse = asToolResponse( await callTasksTool('create-record', { resource_type: 'tasks', record_data: { content: 'Consistency validation task', due_date: taskData2.due_date, recordId: companyId, targetObject: 'companies', }, }) ); expect(detailsResponse).toBeDefined(); expect(noteResponse).toBeDefined(); expect(taskResponse).toBeDefined(); console.error( '✅ Data consistency validation across operations completed' ); }, 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