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',
    );
  });
});