crm-sync-href.test.ts2.8 KBView on GitHub /**
* `getCrmSyncHref` — the "view in CRM" link's href on a deal's CRM tab.
*
* The bug this pins: Christopher Grittner (Hey Telo) reported that clicking "Attio ↗" on
* conversation ead71af5-9ed1-4477-9c29-1554cc3b9488 opened a blank new tab instead of Attio.
* Root cause: the backend never resolved a `dealUrl`/`accountUrl` for this Attio deal (no
* write path stamped a workspace slug onto it), and BOTH renderers of this badge
* (`ConversationOverviewCard.tsx`, `conversationFieldRenderers.tsx`) fell back to the
* literal string `'#'` as the anchor's href. With `target="_blank"`, an `href="#"` resolves
* relative to the CURRENT page — so clicking it opened a new tab at this same
* mail.cedarcopilot.com conversation URL, doing a fresh SPA boot (the blank/spinner page in
* the customer's recording) instead of navigating to Attio.
*
* `getCrmSyncHref` is the single source both components now call — this test proves it
* returns `undefined` (render a non-clickable badge) rather than `'#'` (render a broken
* live link) when no URL was computed.
*/
import { getCrmSyncHref, type ExternalCrmIntegrationMetadata } from '@/modules/crm/types';
function attioEntry(
overrides: Partial<ExternalCrmIntegrationMetadata> = {},
): ExternalCrmIntegrationMetadata {
return {
type: 'external_crm',
provider: 'attio',
dealId: '6cef2a3a-6a98-4248-a16f-aff384af1cb5',
accountId: '792d6de7-4208-42ed-9a10-5e606cae1b7d',
...overrides,
};
}
describe('getCrmSyncHref', () => {
it('returns undefined (never "#") when the backend computed no dealUrl/accountUrl', () => {
// Chris's exact data shape: a real linked Attio deal with no dealUrl/accountUrl,
// because the backend never resolved a workspace slug for it.
const entry = attioEntry();
expect(getCrmSyncHref(entry)).toBeUndefined();
expect(getCrmSyncHref(entry)).not.toBe('#');
});
it('returns null-safe undefined for no linked deal at all', () => {
expect(getCrmSyncHref(null)).toBeUndefined();
});
it('prefers dealUrl, falling back to accountUrl', () => {
expect(
getCrmSyncHref(attioEntry({ dealUrl: 'https://app.attio.com/hey-telo/records/deals/d1' })),
).toBe('https://app.attio.com/hey-telo/records/deals/d1');
expect(
getCrmSyncHref(attioEntry({ accountUrl: 'https://app.attio.com/hey-telo/records/companies/a1' })),
).toBe('https://app.attio.com/hey-telo/records/companies/a1');
});
it('once the backend resolves the real Attio URL, returns exactly that (the fixed end state)', () => {
const entry = attioEntry({
dealUrl: 'https://app.attio.com/hey-telo/records/deals/6cef2a3a-6a98-4248-a16f-aff384af1cb5',
});
expect(getCrmSyncHref(entry)).toBe(
'https://app.attio.com/hey-telo/records/deals/6cef2a3a-6a98-4248-a16f-aff384af1cb5',
);
});
});