/**
* @vitest-environment happy-dom
*/
import { describe, it, expect, beforeEach, vi } from 'vitest';
import { render, waitFor } from '@testing-library/react';
import React from 'react';
import { AIToolSelectorScreen } from '../../../components/screens/AIToolSelectorScreen.js';
import { Window } from 'happy-dom';
// Mock getAllTools
vi.mock('../../../config/tools.js', () => ({
getAllTools: vi.fn().mockResolvedValue([
{
id: 'claude-code',
displayName: 'Claude Code',
isBuiltin: true,
},
{
id: 'codex-cli',
displayName: 'Codex CLI',
isBuiltin: true,
},
]),
}));
describe('AIToolSelectorScreen', () => {
beforeEach(() => {
// Setup happy-dom
const window = new Window();
globalThis.window = window as any;
globalThis.document = window.document as any;
});
it('should render header with title', () => {
const onBack = vi.fn();
const onSelect = vi.fn();
const { getByText } = render(
);
expect(getByText(/AI Tool Selection/i)).toBeDefined();
});
it('should render AI tool options', async () => {
const onBack = vi.fn();
const onSelect = vi.fn();
const { getByText } = render(
);
// Wait for tools to load
await waitFor(() => {
expect(getByText(/Claude Code/i)).toBeDefined();
expect(getByText(/Codex CLI/i)).toBeDefined();
});
});
it('should render footer with actions', () => {
const onBack = vi.fn();
const onSelect = vi.fn();
const { getAllByText } = render(
);
expect(getAllByText(/enter/i).length).toBeGreaterThan(0);
expect(getAllByText(/esc/i).length).toBeGreaterThan(0);
});
it('should use terminal height for layout calculation', () => {
const originalRows = process.stdout.rows;
process.stdout.rows = 30;
const onBack = vi.fn();
const onSelect = vi.fn();
const { container } = render(
);
expect(container).toBeDefined();
process.stdout.rows = originalRows;
});
it('should handle back navigation with ESC key', () => {
const onBack = vi.fn();
const onSelect = vi.fn();
const { container } = render(
);
// Test will verify onBack is called when ESC is pressed
expect(container).toBeDefined();
});
it('should handle tool selection', () => {
const onBack = vi.fn();
const onSelect = vi.fn();
const { container } = render(
);
// Test will verify onSelect is called with correct tool
expect(container).toBeDefined();
});
/**
* T210: カスタムツール表示のテスト
*/
describe('Custom tool display', () => {
it('should load tools from getAllTools() dynamically', async () => {
// TODO: 実装後にテストを記述
// getAllTools()がモックされ、呼び出されることを確認
// モックの戻り値がツールアイテムとして表示されることを確認
expect(true).toBe(true);
});
it('should display both builtin and custom tools', async () => {
// TODO: 実装後にテストを記述
// getAllTools()がビルトインツール(claude-code, codex-cli)と
// カスタムツール(例: aider)を返す場合、
// すべてのツールが表示されることを確認
expect(true).toBe(true);
});
it('should display custom tool with icon if defined', async () => {
// TODO: 実装後にテストを記述
// カスタムツールにiconフィールドがある場合、
// それが表示されることを確認
expect(true).toBe(true);
});
it('should display custom tool without icon if not defined', async () => {
// TODO: 実装後にテストを記述
// カスタムツールにiconフィールドがない場合、
// ツール名のみが表示されることを確認
expect(true).toBe(true);
});
it('should handle custom tool selection', async () => {
// TODO: 実装後にテストを記述
// カスタムツールを選択した場合、
// onSelect()がカスタムツールのIDで呼び出されることを確認
expect(true).toBe(true);
});
it('should display only builtin tools if no custom tools exist', async () => {
// TODO: 実装後にテストを記述
// getAllTools()がビルトインツールのみを返す場合、
// ビルトインツールのみが表示されることを確認
expect(true).toBe(true);
});
});
});