draft-body.test.ts2.1 KBView on GitHub
/**
 * Draft body classification + plain-text extraction.
 *
 * These cover the whitespace bug: plain-text draft bodies that happen to contain
 * angle brackets were being classified as HTML, run through the sanitizer, and
 * rendered with `dangerouslySetInnerHTML` — which collapses every newline and eats
 * the bracketed span along the way.
 */
import { isHtmlBody, draftPlainText } from '@/modules/cedar-os/src/components/renderers/DraftBody';

describe('isHtmlBody', () => {
  it('treats bracketed placeholders and addresses in prose as plain text', () => {
    expect(isHtmlBody('Hi <name>,\n\nThanks for the time today.')).toBe(false);
    expect(isHtmlBody('Reach me at <<email>> any time.')).toBe(false);
    expect(isHtmlBody('Ask <HR Manager> to confirm headcount.')).toBe(false);
    expect(isHtmlBody('Budget is < 10k and > 5k.')).toBe(false);
  });

  it('treats ordinary prose as plain text', () => {
    expect(isHtmlBody('Best,\nJesse')).toBe(false);
    expect(isHtmlBody('')).toBe(false);
  });

  it('detects real HTML bodies', () => {
    expect(isHtmlBody('<p>Hi there</p>')).toBe(true);
    expect(isHtmlBody('Line one<br />Line two')).toBe(true);
    expect(isHtmlBody('Line one<br>Line two')).toBe(true);
    expect(isHtmlBody('<div>Hi</div><div>Bye</div>')).toBe(true);
    expect(isHtmlBody('See <a href="https://cedarcopilot.com">the docs</a>.')).toBe(true);
    expect(isHtmlBody('<img src="https://example.com/logo.png">')).toBe(true);
  });
});

describe('draftPlainText', () => {
  it('leaves plain-text bodies — brackets included — intact', () => {
    const body = 'Hi <name>,\n\nGood speaking today.\n\nBest,\nJesse';
    expect(draftPlainText(body)).toBe(body);
  });

  it('turns HTML block boundaries into newlines', () => {
    expect(draftPlainText('<p>Hi there</p><p>Best,<br />Jesse</p>')).toBe('Hi there\n\nBest,\nJesse');
  });

  it('decodes entities and trims runs of blank lines', () => {
    expect(draftPlainText('<p>Fisher&nbsp;&amp; Co.</p><p></p><p></p><p>Bye</p>')).toBe(
      'Fisher & Co.\n\nBye',
    );
  });

  it('returns an empty string for empty content', () => {
    expect(draftPlainText('')).toBe('');
  });
});