## Purpose

定义前端组件测试基础设施和覆盖要求，确保所有 React 组件的渲染、交互和状态流转行为经过验证。

## Requirements

### Requirement: jsdom 测试环境配置
项目 SHALL 通过 `tests/setup.ts` preload 脚本为组件测试提供 jsdom DOM 环境，包含 TDesign 组件所需的浏览器 API polyfill。

#### Scenario: 组件测试可以渲染 React 组件
- **WHEN** 组件测试文件使用 `@testing-library/react` 的 `render` 函数渲染组件
- **THEN** 组件 SHALL 在 jsdom 环境中正常渲染，可通过 `screen` 查询 DOM 元素

#### Scenario: TDesign 组件依赖的浏览器 API 可用
- **WHEN** 组件测试渲染使用了 TDesign 组件（Table、Drawer、Skeleton 等）的业务组件
- **THEN** jsdom 环境 SHALL 提供 `ResizeObserver`、`IntersectionObserver`、`window.matchMedia` 等 polyfill，不因缺失 API 而抛错

#### Scenario: recharts 图表组件被 mock
- **WHEN** 组件测试渲染包含 recharts 图表的组件
- **THEN** recharts 模块 SHALL 被 mock 为简单占位元素，不依赖 SVG 渲染能力

### Requirement: 组件测试使用 @testing-library/react
项目 SHALL 使用 `@testing-library/react` 作为组件测试工具，遵循"测试用户行为而非实现细节"的原则。

#### Scenario: 通过用户可见内容查询元素
- **WHEN** 测试需要查找页面元素
- **THEN** 测试 SHALL 优先使用 `getByText`、`getByRole`、`getByLabelText` 等语义化查询，而非 CSS 选择器或 testId

#### Scenario: 通过用户交互触发行为
- **WHEN** 测试需要模拟用户操作
- **THEN** 测试 SHALL 使用 `fireEvent` 或 `userEvent` 模拟点击、输入等操作，而非直接调用组件内部方法

### Requirement: 所有前端组件 SHALL 有组件测试覆盖
项目 SHALL 为 `src/web/components/` 下的每个组件和 `src/web/app.tsx` 提供对应的组件测试文件。

#### Scenario: 纯展示组件测试
- **WHEN** 组件为纯展示组件（如 StatusDot、SummaryCards）
- **THEN** 测试 SHALL 验证给定 props 时渲染正确的文本和结构，以及 null/空数据时的条件渲染

#### Scenario: 交互组件测试
- **WHEN** 组件包含用户交互（如 TargetDetailDrawer 的 Tab 切换、RefreshCountdown 的按钮点击）
- **THEN** 测试 SHALL 验证交互触发正确的回调函数调用和参数传递

#### Scenario: 条件渲染测试
- **WHEN** 组件根据 loading/error/empty 状态展示不同内容（如 OverviewTab）
- **THEN** 测试 SHALL 覆盖所有条件分支：loading skeleton、正常数据渲染、空数据占位

#### Scenario: 数据驱动组件测试
- **WHEN** 组件接收列表数据渲染（如 TargetBoard 的分组、HistoryTab 的表格）
- **THEN** 测试 SHALL 验证数据正确映射到 UI 元素，包括空列表和多项数据的情况

### Requirement: 组件测试的 Mock 边界
组件测试 SHALL 只 mock 系统边界（网络请求），不 mock 内部实现。

#### Scenario: Mock fetch 而非 React Query
- **WHEN** 组件通过 `@tanstack/react-query` 发起数据请求
- **THEN** 测试 SHALL mock `globalThis.fetch` 返回预设响应，使用真实的 `QueryClientProvider` 包裹组件

#### Scenario: 不 mock TDesign 组件
- **WHEN** 业务组件使用 TDesign 组件
- **THEN** 测试 SHALL 真实渲染 TDesign 组件，验证 props 传递和集成行为的正确性

### Requirement: 组件测试文件组织
组件测试文件 SHALL 位于 `tests/web/components/` 目录下，文件名与组件名对应。

#### Scenario: 测试文件命名
- **WHEN** 为 `src/web/components/TargetBoard.tsx` 编写组件测试
- **THEN** 测试文件 SHALL 位于 `tests/web/components/TargetBoard.test.tsx`

#### Scenario: App 组件测试位置
- **WHEN** 为 `src/web/app.tsx` 编写组件测试
- **THEN** 测试文件 SHALL 位于 `tests/web/components/App.test.tsx`
