Skip to main content
Glama
timeframe-search.test.tsβ€’6.62 kB
/** * Integration tests for timeframe search functionality (Issue #475) * Tests the parameter conversion and validation logic */ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; import { UniversalSearchService } from '../../../../src/services/UniversalSearchService.js'; import { UniversalResourceType } from '../../../../src/handlers/tool-configs/universal/types.js'; import type { UniversalSearchParams } from '../../../../src/handlers/tool-configs/universal/types.js'; // Mock external dependencies vi.mock('../../../../src/api/attio-client.js'); vi.mock('../../../../src/objects/companies/index.js', () => ({ advancedSearchCompanies: vi.fn().mockResolvedValue([]), })); vi.mock('../../../../src/objects/people/index.js', () => ({ advancedSearchPeople: vi.fn().mockResolvedValue({ results: [] }), })); describe('Timeframe Search Integration', () => { const mockDate = new Date('2023-08-15T12:00:00.000Z'); beforeEach(() => { vi.useFakeTimers(); vi.setSystemTime(mockDate); vi.clearAllMocks(); // Mock the companies search function const mockCompanies = vi.fn().mockResolvedValue([]); vi.doMock('../../../../src/objects/companies/index.js', () => ({ advancedSearchCompanies: mockCompanies, })); // Mock the people search function const mockPeople = vi.fn().mockResolvedValue({ results: [] }); vi.doMock('../../../../src/objects/people/index.js', () => ({ advancedSearchPeople: mockPeople, })); }); afterEach(() => { vi.useRealTimers(); }); describe('Date Parameter Validation', () => { it('should throw error for invalid date format', async () => { const params: UniversalSearchParams = { resource_type: UniversalResourceType.COMPANIES, date_from: 'invalid-date-format', date_to: '2023-08-10T23:59:59Z', }; await expect( UniversalSearchService.searchRecords(params) ).rejects.toThrow('Date parameter validation failed'); }); it('should throw error for invalid date range', async () => { const params: UniversalSearchParams = { resource_type: UniversalResourceType.COMPANIES, date_from: '2023-08-15T12:00:00Z', // After end date date_to: '2023-08-10T23:59:59Z', }; await expect( UniversalSearchService.searchRecords(params) ).rejects.toThrow('Date parameter validation failed'); }); }); describe('Valid Timeframe Processing', () => { it('should successfully process valid timeframe parameters', async () => { const params: UniversalSearchParams = { resource_type: UniversalResourceType.COMPANIES, timeframe: 'last_7_days', date_field: 'created_at', }; // Should not throw error and should return results (even if empty) const results = await UniversalSearchService.searchRecords(params); expect(Array.isArray(results)).toBe(true); }); it('should successfully process valid absolute date range', async () => { const params: UniversalSearchParams = { resource_type: UniversalResourceType.PEOPLE, date_from: '2023-08-01T00:00:00Z', date_to: '2023-08-15T23:59:59Z', date_field: 'updated_at', }; // Should not throw error and should return results (even if empty) const results = await UniversalSearchService.searchRecords(params); expect(Array.isArray(results)).toBe(true); }); it('should prioritize timeframe over absolute dates', async () => { const params: UniversalSearchParams = { resource_type: UniversalResourceType.COMPANIES, timeframe: 'yesterday', // Should take precedence date_from: '2023-08-01T00:00:00Z', // Should be ignored date_to: '2023-08-10T23:59:59Z', // Should be ignored }; // Should not throw error - timeframe should override absolute dates const results = await UniversalSearchService.searchRecords(params); expect(Array.isArray(results)).toBe(true); }); }); describe('Fallback to Regular Search', () => { it('should perform regular search when no timeframe parameters provided', async () => { const params: UniversalSearchParams = { resource_type: UniversalResourceType.COMPANIES, query: 'tech company', // No timeframe parameters }; const results = await UniversalSearchService.searchRecords(params); // Should fall back to regular company search and return results expect(Array.isArray(results)).toBe(true); }); }); describe('API Path Structure Validation', () => { it('should build correct API path structure for timeframe queries', async () => { // Import the createTimeframeQuery function to test directly const { createTimeframeQuery } = await import( '../../../../src/utils/filters/builders/query-api.js' ); // Test companies path structure const companiesConfig = { resourceType: 'companies', attribute: 'created_at', startDate: '2023-08-01T00:00:00.000Z', endDate: '2023-08-15T23:59:59.999Z', operator: 'between' as const, }; const companiesFilter = createTimeframeQuery(companiesConfig); expect(companiesFilter.filter.path).toEqual([ ['companies', 'created_at'], ]); expect(companiesFilter.filter.constraints).toEqual({ $gte: '2023-08-01T00:00:00.000Z', $lte: '2023-08-15T23:59:59.999Z', }); // Test people path structure const peopleConfig = { resourceType: 'people', attribute: 'created_at', startDate: '2023-08-01T00:00:00.000Z', endDate: '2023-08-15T23:59:59.999Z', operator: 'between' as const, }; const peopleFilter = createTimeframeQuery(peopleConfig); expect(peopleFilter.filter.path).toEqual([['people', 'created_at']]); expect(peopleFilter.filter.constraints).toEqual({ $gte: '2023-08-01T00:00:00.000Z', $lte: '2023-08-15T23:59:59.999Z', }); // Test backwards compatibility (without resourceType) const legacyConfig = { attribute: 'created_at', startDate: '2023-08-01T00:00:00.000Z', endDate: '2023-08-15T23:59:59.999Z', operator: 'between' as const, }; const legacyFilter = createTimeframeQuery(legacyConfig); expect(legacyFilter.filter.path).toEqual([['created_at']]); expect(legacyFilter.filter.constraints).toEqual({ $gte: '2023-08-01T00:00:00.000Z', $lte: '2023-08-15T23:59:59.999Z', }); }); }); });

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