// @ts-nocheck import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest'; import { render, cleanup, waitFor } from '@testing-library/svelte'; vi.mock('../lib/client', async (importOriginal) => { const actual = await importOriginal(); return { ...actual, listProjects: vi.fn(), listDatasets: vi.fn(), listRuns: vi.fn(), getAIUsage: vi.fn() }; }); import ProjectsPage from '../pages/ProjectsPage.svelte'; import { listProjects, listDatasets, listRuns, getAIUsage } from '../lib/client'; beforeEach(() => { vi.mocked(listProjects).mockReset().mockResolvedValue({ items: [ { id: 'pA', name: '项目A', description: null, draft_code: '', draft_generation: 1, created_at: '2026-01-01T00:00:00Z', updated_at: '2026-01-01T00:00:00Z' }, { id: 'pB', name: '项目B', description: null, draft_code: '', draft_generation: 0, created_at: '2026-01-01T00:00:00Z', updated_at: '2026-01-01T00:00:00Z' } ]}); vi.mocked(listDatasets).mockReset().mockResolvedValue({ items: [{ id: 'd1' }, { id: 'd2' }, { id: 'd3' }] }); vi.mocked(listRuns).mockReset().mockResolvedValue({ items: [ { id: 'r1', project_id: 'pA', status: 'succeeded', created_at: '2026-02-01T00:00:00Z', result: { equity: [{ equity: 100 }, { equity: 101 }, { equity: 112 }] } }, { id: 'r2', project_id: 'pB', status: 'succeeded', created_at: '2026-02-01T00:00:00Z', result: null } ]}); vi.mocked(getAIUsage).mockReset().mockResolvedValue({ totals: { input_tokens: 500, output_tokens: 200, requests: 2 } }); }); afterEach(() => cleanup()); // round6 旅程重排:首页去 4 张大卡,改为「问候 + 一行指标摘要(小字) // + 新建主 CTA + 项目卡列表(名称/状态 badge/迷你 sparkline)」。 describe('ProjectsPage journey round6 (greeting + metrics summary + project cards)', () => { it('renders a one-line metrics summary, not 4 big cards', async () => { render(ProjectsPage); await waitFor(() => expect(vi.mocked(getAIUsage)).toHaveBeenCalled()); await waitFor(() => expect(document.querySelector('[data-testid="metrics-summary"]')).toBeTruthy()); expect(document.querySelectorAll('[data-testid="metric-card"]').length).toBe(0); const summary = document.querySelector('[data-testid="metrics-summary"]')!.textContent!.replace(/\s+/g, ' '); expect(summary).toContain('2 个项目'); expect(summary).toContain('3 个数据集'); expect(summary).toContain('2 次回测'); expect(summary).toContain('AI 请求 2'); }); it('renders project cards with status badge and inline sparkline for equity runs', async () => { render(ProjectsPage); await waitFor(() => expect(vi.mocked(listRuns)).toHaveBeenCalled()); await waitFor(() => expect(document.querySelector('[data-testid="sparkline"]')).toBeTruthy()); const linkA = document.querySelector('[data-testid="project-link"]'); expect(linkA).toBeTruthy(); expect(linkA!.textContent).toContain('项目A'); // 项目B has a succeeded run without equity → “完成” badge, no sparkline const cardB = [...document.querySelectorAll('[role="listitem"]')].find((n) => n.textContent!.includes('项目B'))!; expect(cardB.querySelector('[data-testid="sparkline"]')).toBeNull(); expect(cardB.textContent).toContain('完成'); }); });