meetingSections.test.ts3.0 KBView on GitHub
import {
  locateQuote,
  meetingTabs,
  type MeetingSections,
} from '@/modules/meetings/detail/meeting-sections';

/**
 * Clicking a citation must land on the tab that CONTAINS it. Landing anywhere else shows the
 * reader a page without the sentence they clicked, which reads as a fabricated citation even
 * though the quote is real and one tab away.
 */

const sections = (over: Partial<MeetingSections> = {}): MeetingSections => ({
  transcript: '',
  notes: '',
  'ai-notes': '',
  ...over,
});

describe('meetingTabs', () => {
  it('always offers the transcript, even with nothing in it', () => {
    expect(meetingTabs(sections())).toEqual(['transcript']);
  });

  it('offers a note tab only when that note kind holds something', () => {
    expect(meetingTabs(sections({ 'ai-notes': 'summary' }))).toEqual(['transcript', 'ai-notes']);
    expect(meetingTabs(sections({ notes: 'mine', 'ai-notes': 'theirs' }))).toEqual([
      'transcript',
      'notes',
      'ai-notes',
    ]);
  });

  it('treats whitespace-only notes as absent', () => {
    expect(meetingTabs(sections({ notes: '   \n ' }))).toEqual(['transcript']);
  });
});

describe('locateQuote', () => {
  it('opens the tab holding the quote', () => {
    const s = sections({
      transcript: '[00:00:10] Bob: pricing is the last open item',
      'ai-notes': 'Legal review is the blocker.',
    });
    const found = locateQuote(s, meetingTabs(s), 'Legal review is the blocker');

    expect(found.tab).toBe('ai-notes');
    expect(found.offset).toBe(0);
  });

  it('prefers the transcript when the notes restate it', () => {
    const s = sections({
      transcript: '[00:00:10] Bob: pricing is the last open item',
      'ai-notes': 'Pricing is the last open item.',
    });
    expect(locateQuote(s, meetingTabs(s), 'pricing is the last open item').tab).toBe('transcript');
  });

  it('finds a quote the agent re-punctuated', () => {
    const s = sections({ transcript: "[00:00:10] Bob: we'll need legal to sign off, first" });
    const found = locateQuote(s, meetingTabs(s), 'we will need legal to sign off first');

    expect(found.tab).toBe('transcript');
    expect(found.offset).not.toBeNull();
  });

  it('reports an offset that points at the quote in the raw text', () => {
    const s = sections({ transcript: '[00:00:10] Bob: pricing is the last open item' });
    const found = locateQuote(s, meetingTabs(s), 'the last open item');

    expect(s.transcript.slice(found.offset!)).toBe('the last open item');
  });

  it('falls back to the first tab with content when there is no quote', () => {
    const s = sections({ 'ai-notes': 'Recap of the call.' });
    expect(locateQuote(s, meetingTabs(s), null)).toEqual({ tab: 'ai-notes', offset: null });
  });

  it('falls back rather than landing on a tab that does not hold the quote', () => {
    const s = sections({ transcript: 'a totally unrelated conversation about logistics' });
    expect(locateQuote(s, meetingTabs(s), 'zzz nothing like this was ever said zzz')).toEqual({
      tab: 'transcript',
      offset: null,
    });
  });
});