import { fireEvent, render, screen, within } from '@testing-library/react'; import { beforeEach, describe, expect, it, vi } from 'vitest'; import { MemoryRouter, Route, Routes, useLocation } from 'react-router-dom'; import { LearningSidebar } from '@/components/layout/LearningSidebar'; const fetchMyLearningCoursesMock = vi.hoisted(() => vi.fn()); const listInstalledLearningCoursesMock = vi.hoisted(() => vi.fn()); const downloadLearningCourseMock = vi.hoisted(() => vi.fn()); vi.mock('@/lib/learning', () => ({ LEARNING_LIBRARY_CHANGED_EVENT: 'makelore:learning-library-changed', fetchMyLearningCourses: fetchMyLearningCoursesMock, listInstalledLearningCourses: listInstalledLearningCoursesMock, downloadLearningCourse: downloadLearningCourseMock, })); const downloadedCourse = { id: 'course-local', origin: 'ops_large', status: 'published', title: '本机互动课', summary: null, language: 'zh-CN', contentHash: 'c'.repeat(64), archiveSha256: 'd'.repeat(64), archiveBytes: 2048, formatVersion: 1, minPlayerVersion: '1.0.0', sceneCount: 8, capabilities: { sceneKinds: ['slide'], hasAudio: false, hasWhiteboard: false, hasAgent: true }, createdAt: '2026-08-16T00:00:00Z', publishedAt: '2026-08-16T00:00:00Z', } as const; function LocationProbe() { const location = useLocation(); return {location.pathname}{location.search}; } describe('LearningSidebar', () => { beforeEach(() => { fetchMyLearningCoursesMock.mockReset(); listInstalledLearningCoursesMock.mockReset(); downloadLearningCourseMock.mockReset(); fetchMyLearningCoursesMock.mockResolvedValue([{ ...downloadedCourse, id: 'course-generated', origin: 'user_single', status: 'ready', title: '我生成的物理课', publishedAt: null }]); listInstalledLearningCoursesMock.mockResolvedValue([{ schemaVersion: 1, course: downloadedCourse, archivePath: '/tmp/course-local.zip', installedAt: '2026-08-16T00:00:00Z' }]); }); it('keeps generation and personal course cards in the existing main sidebar', async () => { render( } /> , ); const sidebarContent = screen.getByTestId('sidebar-learning-navigation'); expect(within(sidebarContent).getByRole('button', { name: '生成课程' })).toBeEnabled(); expect(await within(sidebarContent).findByText('本机互动课')).toBeInTheDocument(); expect(within(sidebarContent).getByText('我生成的物理课')).toBeInTheDocument(); expect(within(sidebarContent).getByText('已下载到本机')).toBeInTheDocument(); expect(within(sidebarContent).getByText('我生成的,待下载')).toBeInTheDocument(); fireEvent.click(within(sidebarContent).getByRole('button', { name: '生成课程' })); expect(screen.getByTestId('location-path')).toHaveTextContent('/learning?generate=1'); }); });