import { fireEvent, render, screen } from '@testing-library/react'; import { beforeEach, describe, expect, it } from 'vitest'; import { MemoryRouter, Route, Routes, useLocation } from 'react-router-dom'; import { ModuleSwitcher } from '@/components/layout/ModuleSwitcher'; import { ModuleSelection } from '@/pages/ModuleSelection'; import { useAuthStore } from '@/stores/auth'; import { useOpencodeStore } from '@/stores/opencode'; function LocationProbe() { const location = useLocation(); return {location.pathname}; } describe('AI module navigation', () => { beforeEach(() => { useAuthStore.setState({ user: { username: 'zhangsan@example.com', userId: 'user-1', tenantId: null, deptId: null, authorities: [] }, }); useOpencodeStore.setState({ activeProject: null }); }); it('shows the three module choices and routes enabled modules from the chooser', async () => { render( } /> } /> , ); expect(screen.getByTestId('ai-module-selection-page')).toBeInTheDocument(); expect(screen.getByRole('heading', { name: '今天,想创作什么?' })).toBeInTheDocument(); expect(screen.getByRole('heading', { name: '今天,想创作什么?' })).toHaveClass('whitespace-nowrap'); expect(screen.getByText('zhangsan,欢迎回来!')).toBeInTheDocument(); expect(screen.getByTestId('ai-module-option-programming')).toHaveClass('module-option-card'); expect(screen.queryByText('先选一个入口。进入后,你还可以从左下角随时切换到其他模块。')).not.toBeInTheDocument(); expect(screen.queryByText('选择创作空间。你可以随时从侧边栏切换。')).not.toBeInTheDocument(); expect(screen.getByAltText('Makelore')).toHaveClass('h-8', 'w-40', 'object-cover'); expect(screen.getByAltText('Makelore').closest('header')).toHaveClass('absolute', 'inset-x-0', 'top-0', 'h-16'); expect(screen.getByTestId('module-selection-drag-region')).toHaveClass('drag-region'); expect(screen.getByText('Code 编程')).toBeInTheDocument(); expect(screen.getByAltText('游戏创作工作台')).toBeInTheDocument(); expect(screen.getByTestId('ai-module-option-programming')).toHaveTextContent('把创意编程变成可运行的产品、游戏或工具'); expect(screen.getByText('Canvas 设计')).toBeInTheDocument(); expect(screen.getByAltText('数位板设计创作')).toBeInTheDocument(); expect(screen.getByTestId('ai-module-option-painting')).toHaveTextContent('用灵感描绘色彩缤纷的世界'); const learningOption = screen.getByTestId('ai-module-option-learning'); expect(learningOption).toBeDisabled(); expect(learningOption).toHaveClass('module-option-card-disabled'); expect(learningOption).toHaveTextContent('Learning 学习'); expect(learningOption).toHaveTextContent('用顶尖的方法解锁万物规律'); expect(learningOption).toHaveTextContent('暂未开放'); expect(screen.getByAltText('数学科技宇宙')).toBeInTheDocument(); fireEvent.click(screen.getByTestId('ai-module-option-painting')); expect(await screen.findByTestId('location-path')).toHaveTextContent('/image-canvas'); }); it('routes AI programming from the chooser to the project conversation entry', async () => { render( } /> } /> , ); fireEvent.click(screen.getByTestId('ai-module-option-programming')); expect(await screen.findByTestId('location-path')).toHaveTextContent('/opencode-chat'); }); it('keeps the current module active and switches from the Sidebar entry', async () => { render( } /> , ); expect(screen.getByTestId('sidebar-module-switcher-trigger')).toHaveAttribute('aria-expanded', 'false'); expect(screen.getByTestId('sidebar-module-switcher-trigger')).toHaveTextContent('绘画 Canvas'); expect(screen.queryByTestId('sidebar-module-painting')).not.toBeInTheDocument(); fireEvent.click(screen.getByTestId('sidebar-module-switcher-trigger')); expect(screen.getByTestId('sidebar-module-switcher-menu')).toBeInTheDocument(); expect(screen.getByTestId('sidebar-module-painting')).toHaveAttribute('aria-current', 'page'); expect(screen.getByTestId('sidebar-module-programming')).not.toHaveAttribute('aria-current'); const learningModule = screen.getByTestId('sidebar-module-learning'); expect(learningModule).toBeDisabled(); expect(learningModule).toHaveTextContent('学习 Learning'); expect(learningModule).toHaveTextContent('AI 学习'); expect(learningModule).not.toHaveAttribute('aria-current'); fireEvent.click(learningModule); expect(screen.getByTestId('location-path')).toHaveTextContent('/image-canvas'); fireEvent.click(screen.getByTestId('sidebar-module-programming')); expect(await screen.findByTestId('location-path')).toHaveTextContent('/opencode-chat'); }); });