import React from 'react'; import { describe, expect, test } from 'bun:test'; import { renderToStaticMarkup } from 'react-dom/server'; import { I18nProvider } from '@/lib/i18n'; import { ReasoningTimelineBlock } from './ReasoningPart'; // A reasoning text whose summary (first 120 chars) fits in the header but // whose expanded body content should only appear when the disclosure is open. const LONG_REASONING = 'First thought about the task at hand and how to approach it carefully.\n' + 'This second line goes into much deeper detail about the internal reasoning ' + 'process that should remain hidden in the collapsed header view.'; // A long text that should render the collapsible header with a label const LONG_JUSTIFICATION = 'Sorting by activity first because the active session needs immediate attention.\n' + 'Secondary sort by last updated timestamp ensures a stable deterministic ordering ' + 'when multiple sessions have the same activity state.'; describe('ReasoningTimelineBlock', () => { test('renders reasoning traces behind an accessible collapsed disclosure by default', () => { const markup = renderToStaticMarkup( , ); // Accessible toggle row is rendered expect(markup).toContain('role="button"'); expect(markup).toContain('aria-expanded="false"'); expect(markup).toContain('aria-label="Expand reasoning trace"'); // Summary preview (beginning of text) is visible in the header expect(markup).toContain('First thought'); // Historical collapsed blocks do not mount the expanded body, avoiding a // first-frame flash when Activity reveals previously hidden rows. expect(markup).not.toContain('data-message-text-export-source'); }); test('renders "Justification" label for justification variant when pre-expanded and not streaming', () => { const markup = renderToStaticMarkup( , ); // Label shown in expanded header should be "Justification" not "Thinking" expect(markup).toContain('Justification'); expect(markup).not.toContain('Thinking'); }); test('renders "Thinking" label for thinking variant when pre-expanded and not streaming', () => { const markup = renderToStaticMarkup( , ); // Label shown in expanded header should be "Thinking" expect(markup).toContain('Thinking'); }); test('header summary is a truncated excerpt from the beginning', () => { const markup = renderToStaticMarkup( , ); // Deep body content beyond 120 chars should be cut from the summary span expect(markup).not.toContain('remain hidden in the collapsed header view'); // The ellipsis character marks that the text was truncated expect(markup).toContain('…'); }); });