Skip to content

Commit 139ba1c

Browse files
fix: 修复默认联网模式的状态,新增部分测试案例、参数提取器修复模型选择 (#54)
Co-authored-by: wangbochao.vendor <15830881993@163.com>
1 parent 8e10a78 commit 139ba1c

20 files changed

Lines changed: 4520 additions & 233 deletions

File tree

docker/docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ x-share-env: &lazy-env
44
WEB_CONSOLE_ENDPOINT: ${WEB_CONSOLE_ENDPOINT:-http://127.0.0.1:30382} # 平台登录的ip+port(例如:http://10.210.0.49:5002),密码重置时给用户发送邮件时使用,供用户跳转到该应用
55
MIGRATION_ENABLED: 'true' # 当表结构有更新时,是否自动执行数据库迁移操作
66
RESET_PASSWORD_TOKEN_EXPIRY_HOURS: ${RESET_PASSWORD_TOKEN_EXPIRY_HOURS:-24} # 重置密码过期时间
7-
INTERNET_FEATURES_ENABLED: ${INTERNET_FEATURES_ENABLED:-false} # 互联网功能开关,默认false(关闭状态),设置为true时启用相关功能
7+
INTERNET_FEATURES_ENABLED: ${INTERNET_FEATURES_ENABLED:-true} # 互联网功能开关,默认true(开启状态),设置为false时关闭相关功能
88
# tidb
99
DB_USERNAME: root
1010
DB_PASSWORD: ''

front/.env.example

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
FRONTEND_DEPLOY_STAGE=DEVELOPMENT
22
NEXT_PUBLIC_EDITION=SELF_HOSTED
3-
FRONTEND_CORE_API=http://10.210.0.49:5022/console/api
4-
FRONTEND_APP_API=http://10.210.0.49:5022/api
3+
FRONTEND_CORE_API=https://112.111.7.69:30382/console/api
4+
FRONTEND_APP_API=https://112.111.7.69:30382/api
55

66
# SENTRY
77
NEXT_PUBLIC_SENTRY_DSN=

front/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,5 @@ package-lock.json
5353
pnpm-lock.yaml
5454

5555
.favorites.json
56+
57+
.env

front/README_TEST.md

Lines changed: 371 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,371 @@
1+
# Jest 单元测试文档
2+
3+
## ✅ 测试结果
4+
5+
```
6+
✅ Test Suites: 3 passed, 3 total
7+
✅ Tests: 46 passed, 46 total
8+
⏱️ Time: ~50s
9+
```
10+
11+
## 📁 项目结构(源文件和测试文件分离)
12+
13+
```
14+
front/
15+
├── __mocks__/ ← Mock文件目录
16+
│ ├── fileMock.js ← 静态文件Mock
17+
│ └── next-navigation.ts ← Next.js路由Mock
18+
19+
├── __tests__/ ← 测试文件目录(和app平级)✨
20+
│ ├── bind_phone/
21+
│ │ └── normalForm.test.tsx ← 绑定手机号登录测试(10个测试)
22+
│ └── register/
23+
│ ├── captcha.test.tsx ← 验证码组件测试(14个测试)
24+
│ └── phone.test.tsx ← 注册页面测试(22个测试)
25+
26+
├── app/ ← 源代码目录
27+
│ ├── bind_phone/
28+
│ │ ├── normalForm.tsx ← 绑定手机号登录源文件
29+
│ │ ├── page.tsx
30+
│ │ └── page.module.scss
31+
│ └── register/
32+
│ ├── captcha.tsx ← 验证码组件源文件
33+
│ ├── phone.tsx ← 注册页面源文件
34+
│ └── ...
35+
36+
├── infrastructure/ ← API和基础设施
37+
├── shared/ ← 共享工具
38+
├── jest.config.js ← Jest配置文件
39+
├── jest.setup.js ← Jest环境设置
40+
└── test-utils.tsx ← 测试工具函数
41+
```
42+
43+
## 🎯 关键特点
44+
45+
### ✨ 源文件和测试文件完全分离
46+
47+
- **源文件**: `app/` 目录下
48+
- **测试文件**: `__tests__/` 目录下(和 `app/` 平级)
49+
- **Mock文件**: `__mocks__/` 目录下(统一管理)
50+
51+
### 🔗 目录镜像关系
52+
53+
| 源文件 | 测试文件 |
54+
|--------|---------|
55+
| `app/bind_phone/normalForm.tsx` | `__tests__/bind_phone/normalForm.test.tsx` |
56+
| `app/register/captcha.tsx` | `__tests__/register/captcha.test.tsx` |
57+
| `app/register/phone.tsx` | `__tests__/register/phone.test.tsx` |
58+
59+
## 📊 测试覆盖详情
60+
61+
### 1. normalForm.test.tsx - 绑定手机号登录 (10个测试)
62+
63+
✅ 渲染测试
64+
- 正确渲染所有表单元素
65+
- 手机号输入框限制11位
66+
67+
✅ 表单验证测试
68+
- 空表单验证错误
69+
- 无效手机号格式错误
70+
71+
✅ 功能测试
72+
- 成功提交流程(API调用、保存token、页面跳转)
73+
- 登录失败处理
74+
- Loading状态显示
75+
- 参数验证(openid/provider)
76+
- 验证码功能集成
77+
78+
### 2. captcha.test.tsx - 验证码组件 (14个测试)
79+
80+
✅ 渲染测试
81+
- 正确渲染输入框和按钮
82+
83+
✅ 交互测试
84+
- 用户输入
85+
- 按钮点击
86+
87+
✅ 倒计时功能
88+
- 开始倒计时
89+
- 倒计时期间按钮禁用
90+
- 倒计时结束恢复
91+
92+
✅ 状态测试
93+
- Loading状态
94+
- 错误状态显示
95+
- 错误清除
96+
97+
✅ 配置测试
98+
- 自定义倒计时秒数
99+
- 自定义样式
100+
- Label和Required支持
101+
102+
### 3. phone.test.tsx - 注册页面 (22个测试)
103+
104+
✅ 渲染测试
105+
- 所有必填字段正确渲染
106+
- 输入框限制和属性
107+
108+
✅ 表单验证测试
109+
- 用户名:30位以内英文数字
110+
- 邮箱:格式验证
111+
- 密码:
112+
- 长度8-30位
113+
- 必须包含小写字母
114+
- 必须包含大写字母
115+
- 必须包含数字
116+
- 必须包含特殊符号
117+
- 确认密码:与密码一致
118+
- 手机号:中国大陆格式
119+
120+
✅ 功能测试
121+
- 成功注册流程(加密、API调用、消息提示、跳转)
122+
- 注册失败处理
123+
- Loading状态
124+
- URL参数自动填充
125+
- 验证码集成
126+
127+
## 🚀 使用方法
128+
129+
### 运行所有测试
130+
```bash
131+
cd front
132+
npm test
133+
```
134+
135+
### 监听模式(开发推荐)
136+
```bash
137+
npm run test:watch
138+
```
139+
140+
### 生成覆盖率报告
141+
```bash
142+
npm run test:coverage
143+
```
144+
145+
### CI环境运行
146+
```bash
147+
npm run test:ci
148+
```
149+
150+
## 🔧 测试配置说明
151+
152+
### jest.config.js
153+
```javascript
154+
{
155+
testEnvironment: 'jest-environment-jsdom', // 浏览器环境
156+
testMatch: [
157+
'**/__tests__/**/*.[jt]s?(x)', // 匹配__tests__目录
158+
],
159+
moduleNameMapper: {
160+
'^@/(.*)$': '<rootDir>/$1', // @别名支持
161+
},
162+
}
163+
```
164+
165+
### jest.setup.js
166+
- Mock浏览器API(IntersectionObserver, ResizeObserver, matchMedia)
167+
- Mock localStorage
168+
- 过滤无用的警告信息
169+
170+
## 📝 编写新测试
171+
172+
### 步骤1:确定源文件位置
173+
```
174+
app/auth/login/LoginForm.tsx
175+
```
176+
177+
### 步骤2:在__tests__下创建镜像目录
178+
```
179+
__tests__/auth/login/LoginForm.test.tsx
180+
```
181+
182+
### 步骤3:使用@别名导入源文件
183+
```typescript
184+
import LoginForm from '@/app/auth/login/LoginForm'
185+
```
186+
187+
### 步骤4:编写测试
188+
```typescript
189+
describe('LoginForm', () => {
190+
test('应该正确渲染', () => {
191+
render(<LoginForm />)
192+
expect(screen.getByText('登录')).toBeInTheDocument()
193+
})
194+
})
195+
```
196+
197+
## 🎨 测试模式
198+
199+
### 模式1:AAA模式(Arrange-Act-Assert)
200+
201+
```typescript
202+
test('用户登录成功', async () => {
203+
// Arrange - 准备
204+
const user = userEvent.setup()
205+
render(<LoginForm />)
206+
207+
// Act - 执行
208+
await user.type(screen.getByPlaceholderText('用户名'), 'testuser')
209+
await user.click(screen.getByRole('button', { name: '登录' }))
210+
211+
// Assert - 断言
212+
await waitFor(() => {
213+
expect(mockLogin).toHaveBeenCalled()
214+
})
215+
})
216+
```
217+
218+
### 模式2:Mock外部依赖
219+
220+
```typescript
221+
// Mock API
222+
jest.mock('@/infrastructure/api/common', () => ({
223+
login: jest.fn(),
224+
}))
225+
226+
// Mock Next.js路由
227+
jest.mock('next/navigation', () => ({
228+
useRouter: jest.fn(),
229+
}))
230+
```
231+
232+
### 模式3:测试异步操作
233+
234+
```typescript
235+
test('异步操作', async () => {
236+
await user.click(button)
237+
238+
await waitFor(() => {
239+
expect(screen.getByText('成功')).toBeInTheDocument()
240+
})
241+
})
242+
```
243+
244+
## 💡 最佳实践
245+
246+
### ✅ DO - 推荐做法
247+
248+
1. **测试用户行为,而非实现细节**
249+
```typescript
250+
// ✅ 好
251+
expect(screen.getByText('登录成功')).toBeInTheDocument()
252+
253+
// ❌ 不好
254+
expect(component.state.isLoggedIn).toBe(true)
255+
```
256+
257+
2. **使用语义化查询**
258+
```typescript
259+
// ✅ 好
260+
screen.getByRole('button', { name: '登录' })
261+
262+
// ❌ 不好
263+
screen.getByTestId('login-button')
264+
```
265+
266+
3. **每个测试只测一件事**
267+
```typescript
268+
// ✅ 好
269+
test('应该显示错误消息', () => {})
270+
test('应该禁用按钮', () => {})
271+
272+
// ❌ 不好
273+
test('表单功能', () => {
274+
// 测试渲染、验证、提交、错误...
275+
})
276+
```
277+
278+
4. **保持测试独立**
279+
```typescript
280+
beforeEach(() => {
281+
jest.clearAllMocks() // 每个测试前清理
282+
})
283+
```
284+
285+
### ❌ DON'T - 避免的做法
286+
287+
1. ❌ 不要测试第三方库的功能
288+
2. ❌ 不要在测试中使用真实的API
289+
3. ❌ 不要让测试互相依赖
290+
4. ❌ 不要忽略异步操作
291+
292+
## 🔍 常见问题
293+
294+
### Q1: 测试文件放在哪里?
295+
**A**: 放在 `front/__tests__/` 目录下,与 `app/` 平级,保持目录镜像结构。
296+
297+
### Q2: 如何导入源文件?
298+
**A**: 使用@别名:`import Component from '@/app/path/to/Component'`
299+
300+
### Q3: 如何Mock API?
301+
**A**: 使用 `jest.mock('@/infrastructure/api/common', () => ({...}))`
302+
303+
### Q4: 如何测试异步操作?
304+
**A**: 使用 `await waitFor(() => { expect(...) })`
305+
306+
### Q5: 如何处理警告?
307+
**A**: 在 `jest.setup.js` 中过滤,已配置常见警告过滤。
308+
309+
## 📚 测试文件说明
310+
311+
### normalForm.test.tsx
312+
测试**绑定手机号登录**功能:
313+
- 表单渲染和验证
314+
- 登录成功/失败流程
315+
- OAuth参数处理
316+
- 验证码集成
317+
318+
### phone.test.tsx
319+
测试**用户注册**功能:
320+
- 所有表单字段验证
321+
- 密码复杂度要求
322+
- 注册成功/失败流程
323+
- 数据加密
324+
- 消息提示
325+
326+
### captcha.test.tsx
327+
测试**验证码组件**功能:
328+
- 倒计时逻辑
329+
- 按钮状态管理
330+
- 错误处理
331+
- 自定义配置
332+
333+
## 🎓 学习资源
334+
335+
- [Jest官方文档](https://jestjs.io/)
336+
- [React Testing Library](https://testing-library.com/react)
337+
- [Testing Library 最佳实践](https://kentcdodds.com/blog/common-mistakes-with-react-testing-library)
338+
339+
## 📦 依赖包
340+
341+
```json
342+
{
343+
"devDependencies": {
344+
"jest": "^30.2.0",
345+
"@testing-library/react": "latest",
346+
"@testing-library/jest-dom": "latest",
347+
"@testing-library/user-event": "latest",
348+
"jest-environment-jsdom": "latest",
349+
"@swc/jest": "latest",
350+
"identity-obj-proxy": "latest"
351+
}
352+
}
353+
```
354+
355+
## ✨ 总结
356+
357+
**完整的测试环境已配置完成!**
358+
359+
- ✅ 46个测试全部通过
360+
- ✅ 源文件和测试文件完全分离
361+
- ✅ 测试文件在 `front/__tests__/` 下(和 `app/` 平级)
362+
- ✅ 清晰的目录结构
363+
- ✅ 完善的测试覆盖
364+
365+
**项目结构清晰,易于维护!** 🚀
366+
367+
---
368+
369+
**最后更新**: 2024-11-18
370+
**测试状态**: ✅ 全部通过
371+

front/__mocks__/fileMock.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = 'test-file-stub'

0 commit comments

Comments
 (0)