/**
* Tests for fetch-parent-record-name utility
*
* Tests fetching parent record names for different object types.
*/
import { describe, it, expect, beforeEach } from 'vitest';
import { fetchParentRecordNames } from '../../../src/utils/fetch-parent-record-name.js';
import { createMockAttioClient } from '../../helpers/mock-attio-client.js';
describe('fetchParentRecordNames', () => {
let mockClient: ReturnType<typeof createMockAttioClient>;
beforeEach(() => {
mockClient = createMockAttioClient();
});
describe('People records', () => {
it('should fetch person name with full_name', async () => {
mockClient.mockResponse('GET', '/objects/people/records/person-123', {
data: {
data: {
id: { record_id: 'person-123' },
values: {
name: [
{ full_name: 'John Doe', first_name: 'John', last_name: 'Doe' },
],
},
},
},
});
const result = await fetchParentRecordNames(mockClient as any, [
{ parent_object: 'people', parent_record_id: 'person-123' },
]);
expect(result.get('people:person-123')).toBe('John Doe');
});
it('should construct name from first_name and last_name if full_name missing', async () => {
mockClient.mockResponse('GET', '/objects/people/records/person-456', {
data: {
data: {
id: { record_id: 'person-456' },
values: {
name: [{ first_name: 'Jane', last_name: 'Smith' }],
},
},
},
});
const result = await fetchParentRecordNames(mockClient as any, [
{ parent_object: 'people', parent_record_id: 'person-456' },
]);
expect(result.get('people:person-456')).toBe('Jane Smith');
});
it('should handle person with only first_name', async () => {
mockClient.mockResponse('GET', '/objects/people/records/person-789', {
data: {
data: {
id: { record_id: 'person-789' },
values: {
name: [{ first_name: 'Madonna' }],
},
},
},
});
const result = await fetchParentRecordNames(mockClient as any, [
{ parent_object: 'people', parent_record_id: 'person-789' },
]);
expect(result.get('people:person-789')).toBe('Madonna');
});
});
describe('Company records', () => {
it('should fetch company name', async () => {
mockClient.mockResponse('GET', '/objects/companies/records/company-123', {
data: {
data: {
id: { record_id: 'company-123' },
values: {
name: [{ value: 'Acme Corp' }],
},
},
},
});
const result = await fetchParentRecordNames(mockClient as any, [
{ parent_object: 'companies', parent_record_id: 'company-123' },
]);
expect(result.get('companies:company-123')).toBe('Acme Corp');
});
});
describe('Fund records', () => {
it('should fetch fund name', async () => {
mockClient.mockResponse('GET', '/objects/funds/records/fund-123', {
data: {
data: {
id: { record_id: 'fund-123' },
values: {
name: [{ value: 'HeyHo I' }],
},
},
},
});
const result = await fetchParentRecordNames(mockClient as any, [
{ parent_object: 'funds', parent_record_id: 'fund-123' },
]);
expect(result.get('funds:fund-123')).toBe('HeyHo I');
});
});
describe('List entry records', () => {
it('should fetch investment opportunity display_name', async () => {
mockClient.mockResponse(
'GET',
'/lists/investment_opportunities/entries/opp-123',
{
data: {
data: {
id: { entry_id: 'opp-123' },
entry_values: {
display_name: [{ value: 'Series A - TechCo' }],
},
},
},
}
);
const result = await fetchParentRecordNames(mockClient as any, [
{
parent_object: 'investment_opportunities',
parent_record_id: 'opp-123',
},
]);
expect(result.get('investment_opportunities:opp-123')).toBe(
'Series A - TechCo'
);
});
it('should fetch lp opportunity name', async () => {
mockClient.mockResponse(
'GET',
'/lists/lp_opportunities/entries/lp-123',
{
data: {
data: {
id: { entry_id: 'lp-123' },
entry_values: {
name: [{ value: 'John Doe - HeyHo I' }],
},
},
},
}
);
const result = await fetchParentRecordNames(mockClient as any, [
{ parent_object: 'lp_opportunities', parent_record_id: 'lp-123' },
]);
expect(result.get('lp_opportunities:lp-123')).toBe('John Doe - HeyHo I');
});
});
describe('Multiple records', () => {
it('should fetch multiple records in parallel', async () => {
mockClient.mockResponse('GET', '/objects/people/records/person-1', {
data: {
data: {
id: { record_id: 'person-1' },
values: {
name: [{ full_name: 'Person One' }],
},
},
},
});
mockClient.mockResponse('GET', '/objects/companies/records/company-1', {
data: {
data: {
id: { record_id: 'company-1' },
values: {
name: [{ value: 'Company One' }],
},
},
},
});
const result = await fetchParentRecordNames(mockClient as any, [
{ parent_object: 'people', parent_record_id: 'person-1' },
{ parent_object: 'companies', parent_record_id: 'company-1' },
]);
expect(result.get('people:person-1')).toBe('Person One');
expect(result.get('companies:company-1')).toBe('Company One');
});
it('should deduplicate fetch requests', async () => {
mockClient.mockResponse(
'GET',
'/objects/companies/records/company-dup',
{
data: {
data: {
id: { record_id: 'company-dup' },
values: {
name: [{ value: 'Duplicate Co' }],
},
},
},
}
);
const result = await fetchParentRecordNames(mockClient as any, [
{ parent_object: 'companies', parent_record_id: 'company-dup' },
{ parent_object: 'companies', parent_record_id: 'company-dup' },
{ parent_object: 'companies', parent_record_id: 'company-dup' },
]);
expect(result.get('companies:company-dup')).toBe('Duplicate Co');
});
});
describe('Error handling', () => {
it('should handle unknown object types gracefully', async () => {
const result = await fetchParentRecordNames(mockClient as any, [
{ parent_object: 'unknown_type', parent_record_id: 'id-123' },
]);
expect(result.get('unknown_type:id-123')).toBeUndefined();
});
it('should handle API errors gracefully', async () => {
mockClient.mockResponse('GET', '/objects/companies/records/error-id', {
error: {
statusCode: 404,
message: 'Not found',
},
});
const result = await fetchParentRecordNames(mockClient as any, [
{ parent_object: 'companies', parent_record_id: 'error-id' },
]);
expect(result.get('companies:error-id')).toBeUndefined();
});
it('should continue fetching other records if one fails', async () => {
mockClient.mockResponse('GET', '/objects/companies/records/bad-id', {
error: {
statusCode: 500,
message: 'Server error',
},
});
mockClient.mockResponse('GET', '/objects/companies/records/good-id', {
data: {
data: {
id: { record_id: 'good-id' },
values: {
name: [{ value: 'Good Company' }],
},
},
},
});
const result = await fetchParentRecordNames(mockClient as any, [
{ parent_object: 'companies', parent_record_id: 'bad-id' },
{ parent_object: 'companies', parent_record_id: 'good-id' },
]);
expect(result.get('companies:bad-id')).toBeUndefined();
expect(result.get('companies:good-id')).toBe('Good Company');
});
});
describe('Empty inputs', () => {
it('should handle empty array', async () => {
const result = await fetchParentRecordNames(mockClient as any, []);
expect(result.size).toBe(0);
});
it('should handle missing name values', async () => {
mockClient.mockResponse('GET', '/objects/companies/records/no-name', {
data: {
data: {
id: { record_id: 'no-name' },
values: {},
},
},
});
const result = await fetchParentRecordNames(mockClient as any, [
{ parent_object: 'companies', parent_record_id: 'no-name' },
]);
expect(result.get('companies:no-name')).toBeUndefined();
});
});
});