Skip to main content
Glama
relationship-utils.test.tsβ€’11 kB
/** * Tests for relationship utility functions */ import { RelationshipType, createPeopleByCompanyFilter, createCompaniesByPeopleFilter, createRecordsByListFilter, createPeopleByCompanyListFilter, createCompaniesByPeopleListFilter, createRecordsByNotesFilter, } from '../../src/utils/relationship-utils'; import { ResourceType, FilterConditionType } from '../../src/types/attio'; import { ListEntryFilters } from '../../src/api/operations/index'; import { FilterValidationError } from '../../src/errors/api-errors'; // Helper function to safely extract first filter with runtime validation function getFirstFilterSafely(result: any) { expect(result).toBeDefined(); expect(result.filters).toBeDefined(); expect(result.filters).toHaveLength(1); if (!result.filters || result.filters.length === 0) { throw new Error( 'Expected filters array to be defined and contain at least one filter' ); } return result.filters[0]; } describe('Relationship Utilities', () => { describe('createPeopleByCompanyFilter', () => { it('should create a valid relationship filter for people by company', () => { // Create a sample company filter const companyFilter: ListEntryFilters = { filters: [ { attribute: { slug: 'industry' }, condition: FilterConditionType.EQUALS, value: 'Technology', }, ], matchAny: false, }; // Generate the relationship filter const result = createPeopleByCompanyFilter(companyFilter); // Verify the structure expect(result).toBeDefined(); const relationshipFilter = getFirstFilterSafely(result); expect(relationshipFilter.attribute.slug).toBe('$relationship'); expect(relationshipFilter.condition).toBe(FilterConditionType.EQUALS); // Check the relationship configuration const relationshipValue = relationshipFilter.value as any; expect(relationshipValue.type).toBe(RelationshipType.WORKS_AT); expect(relationshipValue.target.object).toBe('companies'); expect(relationshipValue.target.filter).toEqual(companyFilter); }); it('should throw an error if company filter is invalid', () => { // Test with an empty filter const emptyFilter = { filters: [] }; // Expect it to throw a FilterValidationError expect(() => createPeopleByCompanyFilter(emptyFilter)).toThrow( FilterValidationError ); }); }); describe('createCompaniesByPeopleFilter', () => { it('should create a valid relationship filter for companies by people', () => { // Create a sample people filter const peopleFilter: ListEntryFilters = { filters: [ { attribute: { slug: 'job_title' }, condition: FilterConditionType.CONTAINS, value: 'Engineer', }, ], matchAny: false, }; // Generate the relationship filter const result = createCompaniesByPeopleFilter(peopleFilter); // Verify the structure expect(result).toBeDefined(); const relationshipFilter = getFirstFilterSafely(result); expect(relationshipFilter.attribute.slug).toBe('$relationship'); expect(relationshipFilter.condition).toBe(FilterConditionType.EQUALS); // Check the relationship configuration const relationshipValue = relationshipFilter.value as any; expect(relationshipValue.type).toBe(RelationshipType.EMPLOYS); expect(relationshipValue.target.object).toBe('people'); expect(relationshipValue.target.filter).toEqual(peopleFilter); }); it('should throw an error if people filter is invalid', () => { // Test with an empty filter const emptyFilter = { filters: [] }; // Expect it to throw a FilterValidationError expect(() => createCompaniesByPeopleFilter(emptyFilter)).toThrow( FilterValidationError ); }); }); describe('createRecordsByListFilter', () => { it('should create a valid filter for records by list ID', () => { const listId = 'list_abc123'; const resourceType = ResourceType.PEOPLE; // Generate the relationship filter const result = createRecordsByListFilter(resourceType, listId); // Verify the structure expect(result).toBeDefined(); const relationshipFilter = getFirstFilterSafely(result); expect(relationshipFilter.attribute.slug).toBe('$relationship'); expect(relationshipFilter.condition).toBe(FilterConditionType.EQUALS); // Check the relationship configuration const relationshipValue = relationshipFilter.value as any; expect(relationshipValue.type).toBe(RelationshipType.BELONGS_TO_LIST); expect(relationshipValue.target.object).toBe('lists'); // Check the target filter (should be an equals filter on list_id) const targetFilter = relationshipValue.target.filter; expect(targetFilter.filters).toHaveLength(1); expect(targetFilter.filters[0].attribute.slug).toBe('list_id'); expect(targetFilter.filters[0].condition).toBe( FilterConditionType.EQUALS ); expect(targetFilter.filters[0].value).toBe(listId); }); it('should throw an error if list ID is empty', () => { // Test with an empty list ID const emptyListId = ''; const resourceType = ResourceType.PEOPLE; // Expect it to throw a FilterValidationError expect(() => createRecordsByListFilter(resourceType, emptyListId) ).toThrow(FilterValidationError); }); }); describe('createPeopleByCompanyListFilter', () => { it('should create a valid filter for people by company list', () => { const listId = 'list_abc123'; // Generate the relationship filter const result = createPeopleByCompanyListFilter(listId); // Verify the structure is a nested relationship filter expect(result).toBeDefined(); const relationshipFilter = getFirstFilterSafely(result); expect(relationshipFilter.attribute.slug).toBe('$relationship'); expect(relationshipFilter.condition).toBe(FilterConditionType.EQUALS); // Check the relationship configuration (people who work at companies) const relationshipValue = relationshipFilter.value as any; expect(relationshipValue.type).toBe(RelationshipType.WORKS_AT); expect(relationshipValue.target.object).toBe('companies'); // Check that the target filter is another relationship filter (companies in list) const targetFilter = relationshipValue.target.filter; expect(targetFilter.filters).toHaveLength(1); expect(targetFilter.filters[0].attribute.slug).toBe('$relationship'); // Check the nested relationship (company belongs to list) const nestedRelationship = targetFilter.filters[0].value as any; expect(nestedRelationship.type).toBe(RelationshipType.BELONGS_TO_LIST); expect(nestedRelationship.target.object).toBe('lists'); // Check the list ID filter const listFilter = nestedRelationship.target.filter; expect(listFilter.filters[0].attribute.slug).toBe('list_id'); expect(listFilter.filters[0].value).toBe(listId); }); it('should throw an error if list ID is empty', () => { // Test with an empty list ID const emptyListId = ''; // Expect it to throw a FilterValidationError expect(() => createPeopleByCompanyListFilter(emptyListId)).toThrow( FilterValidationError ); }); }); describe('createCompaniesByPeopleListFilter', () => { it('should create a valid filter for companies by people list', () => { const listId = 'list_xyz789'; // Generate the relationship filter const result = createCompaniesByPeopleListFilter(listId); // Verify the structure is a nested relationship filter expect(result).toBeDefined(); const relationshipFilter = getFirstFilterSafely(result); expect(relationshipFilter.attribute.slug).toBe('$relationship'); expect(relationshipFilter.condition).toBe(FilterConditionType.EQUALS); // Check the relationship configuration (companies that employ people) const relationshipValue = relationshipFilter.value as any; expect(relationshipValue.type).toBe(RelationshipType.EMPLOYS); expect(relationshipValue.target.object).toBe('people'); // Check that the target filter is another relationship filter (people in list) const targetFilter = relationshipValue.target.filter; expect(targetFilter.filters).toHaveLength(1); expect(targetFilter.filters[0].attribute.slug).toBe('$relationship'); // Check the nested relationship (person belongs to list) const nestedRelationship = targetFilter.filters[0].value as any; expect(nestedRelationship.type).toBe(RelationshipType.BELONGS_TO_LIST); expect(nestedRelationship.target.object).toBe('lists'); // Check the list ID filter const listFilter = nestedRelationship.target.filter; expect(listFilter.filters[0].attribute.slug).toBe('list_id'); expect(listFilter.filters[0].value).toBe(listId); }); it('should throw an error if list ID is empty', () => { // Test with an empty list ID const emptyListId = ''; // Expect it to throw a FilterValidationError expect(() => createCompaniesByPeopleListFilter(emptyListId)).toThrow( FilterValidationError ); }); }); describe('createRecordsByNotesFilter', () => { it('should create a valid filter for records by note content', () => { const searchText = 'follow up next quarter'; const resourceType = ResourceType.PEOPLE; // Generate the relationship filter const result = createRecordsByNotesFilter(resourceType, searchText); // Verify the structure expect(result).toBeDefined(); const relationshipFilter = getFirstFilterSafely(result); expect(relationshipFilter.attribute.slug).toBe('$relationship'); expect(relationshipFilter.condition).toBe(FilterConditionType.EQUALS); // Check the relationship configuration const relationshipValue = relationshipFilter.value as any; expect(relationshipValue.type).toBe(RelationshipType.HAS_NOTE); // Check the note content filter const noteFilter = relationshipValue.target.filter; expect(noteFilter.filters).toHaveLength(1); expect(noteFilter.filters[0].attribute.slug).toBe('note_content'); expect(noteFilter.filters[0].condition).toBe( FilterConditionType.CONTAINS ); expect(noteFilter.filters[0].value).toBe(searchText); }); it('should throw an error if search text is empty', () => { // Test with an empty search text const emptySearchText = ''; const resourceType = ResourceType.PEOPLE; // Expect it to throw a FilterValidationError expect(() => createRecordsByNotesFilter(resourceType, emptySearchText) ).toThrow(FilterValidationError); }); }); });

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