110 lines
4.8 KiB
TypeScript
110 lines
4.8 KiB
TypeScript
// @vitest-environment jsdom
|
|
import '../../test/dom-setup';
|
|
import '../../i18n';
|
|
import { describe, expect, it } from 'vitest';
|
|
import { screen } from '@testing-library/react';
|
|
import { renderWithProviders } from '../../test/render-helpers';
|
|
import { DelegateLiveConsole } from './DelegateLiveConsole';
|
|
import type { DelegateStreamEntry } from '../../hooks/useJobStream';
|
|
|
|
function entry(o: Partial<DelegateStreamEntry> = {}): DelegateStreamEntry {
|
|
return {
|
|
delegateRunId: 'r1', parentRunId: null, depth: 1, description: 'tweet 3 を深掘り',
|
|
status: 'running', text: '論点を整理しています', currentTool: null, ...o,
|
|
};
|
|
}
|
|
|
|
describe('DelegateLiveConsole', () => {
|
|
it('streams が空なら何も描画しない', () => {
|
|
const { container } = renderWithProviders(<DelegateLiveConsole streams={{}} />);
|
|
expect(container.firstChild).toBeNull();
|
|
});
|
|
it('実行中の delegate カードを description + ライブ文字つきで描画', () => {
|
|
renderWithProviders(<DelegateLiveConsole streams={{ r1: entry() }} />);
|
|
expect(screen.getByText('tweet 3 を深掘り')).toBeTruthy();
|
|
expect(screen.getByText(/論点を整理しています/)).toBeTruthy();
|
|
});
|
|
it('currentTool があるとツール実行中を表示', () => {
|
|
renderWithProviders(<DelegateLiveConsole streams={{ r1: entry({ text: '', currentTool: 'WebFetch' }) }} />);
|
|
expect(screen.getByText(/WebFetch/)).toBeTruthy();
|
|
});
|
|
it('完了した run は表示しない(履歴は概要に委ねる)— running だけ残す', () => {
|
|
const streams = {
|
|
done1: entry({ delegateRunId: 'done1', description: '完了したやつ', status: 'success' }),
|
|
run1: entry({ delegateRunId: 'run1', description: '走ってるやつ', status: 'running' }),
|
|
};
|
|
renderWithProviders(<DelegateLiveConsole streams={streams} />);
|
|
expect(screen.queryByText('完了したやつ')).toBeNull();
|
|
expect(screen.getByText('走ってるやつ')).toBeTruthy();
|
|
});
|
|
it('全 run が完了済みなら何も描画しない', () => {
|
|
const streams = {
|
|
done1: entry({ delegateRunId: 'done1', status: 'success' }),
|
|
done2: entry({ delegateRunId: 'done2', status: 'aborted' }),
|
|
};
|
|
const { container } = renderWithProviders(<DelegateLiveConsole streams={streams} />);
|
|
expect(container.firstChild).toBeNull();
|
|
});
|
|
it('入れ子(parentRunId あり)を子としてインデント描画', () => {
|
|
const streams = {
|
|
r1: entry({ delegateRunId: 'r1', description: '親', depth: 1 }),
|
|
r2: entry({ delegateRunId: 'r2', parentRunId: 'r1', description: '子', depth: 2 }),
|
|
};
|
|
renderWithProviders(<DelegateLiveConsole streams={streams} />);
|
|
expect(screen.getByText('親')).toBeTruthy();
|
|
expect(screen.getByText('子')).toBeTruthy();
|
|
});
|
|
|
|
// --- Task 8: originJobId によるパーティション ---
|
|
|
|
it('originJobId=null の親エントリと originJobId あり のサブタスクエントリを両方描画し、見出しを表示する', () => {
|
|
const streams: Record<string, DelegateStreamEntry> = {
|
|
'run-parent': entry({
|
|
delegateRunId: 'run-parent',
|
|
description: 'Parent delegate run',
|
|
text: 'parent text output',
|
|
originJobId: null,
|
|
}),
|
|
'run-sub': entry({
|
|
delegateRunId: 'run-sub',
|
|
description: 'Subtask delegate run',
|
|
text: 'subtask text output',
|
|
originJobId: 'sub1',
|
|
}),
|
|
};
|
|
renderWithProviders(<DelegateLiveConsole streams={streams} />);
|
|
expect(screen.getByText('parent text output')).toBeTruthy();
|
|
expect(screen.getByText('subtask text output')).toBeTruthy();
|
|
// 'delegateRuns.subtaskSectionHeading' = 'Delegate runs in subtasks'
|
|
expect(screen.getByText('Delegate runs in subtasks')).toBeTruthy();
|
|
});
|
|
|
|
it('サブタスクエントリが無ければ subtaskSectionHeading を描画しない', () => {
|
|
const streams: Record<string, DelegateStreamEntry> = {
|
|
'run-parent': entry({
|
|
delegateRunId: 'run-parent',
|
|
description: 'Only parent run',
|
|
text: 'parent only',
|
|
originJobId: null,
|
|
}),
|
|
};
|
|
renderWithProviders(<DelegateLiveConsole streams={streams} />);
|
|
expect(screen.getByText('parent only')).toBeTruthy();
|
|
expect(screen.queryByText('Delegate runs in subtasks')).toBeNull();
|
|
});
|
|
|
|
it('サブタスクのみの場合も subtaskSectionHeading を表示する', () => {
|
|
const streams: Record<string, DelegateStreamEntry> = {
|
|
'run-sub-only': entry({
|
|
delegateRunId: 'run-sub-only',
|
|
description: 'Sub only run',
|
|
text: 'sub only text',
|
|
originJobId: 'job42',
|
|
}),
|
|
};
|
|
renderWithProviders(<DelegateLiveConsole streams={streams} />);
|
|
expect(screen.getByText('sub only text')).toBeTruthy();
|
|
expect(screen.getByText('Delegate runs in subtasks')).toBeTruthy();
|
|
});
|
|
});
|