435 lines
13 KiB
Markdown
435 lines
13 KiB
Markdown
# 系统初始化向导集成测试用例
|
||
|
||
**创建日期**: 2026-02-15
|
||
**版本**: v1.0
|
||
**优先级**: P0
|
||
**测试类型**: E2E 集成测试
|
||
|
||
---
|
||
|
||
## 一、测试概述
|
||
|
||
### 1.1 测试目标
|
||
|
||
验证系统初始化向导功能的完整流程,包括:
|
||
- 超级管理员首次登录自动进入向导模式
|
||
- 项目创建流程(手动创建/从集团同步)
|
||
- 用户选择器功能(搜索、创建用户)
|
||
- 角色模板配置
|
||
- 向导完成后正确进入系统
|
||
|
||
### 1.2 测试范围
|
||
|
||
| 模块 | 功能点 | 测试类型 |
|
||
|------|--------|----------|
|
||
| 认证 | 登录、权限获取 | API + UI |
|
||
| 向导 | 项目创建、角色配置 | UI |
|
||
| 用户 | 创建用户、用户选择 | API + UI |
|
||
| 项目 | 项目编号生成 | API |
|
||
| 权限 | 菜单动态加载 | UI |
|
||
|
||
### 1.3 前置条件
|
||
|
||
1. 数据库已清理到初始状态(仅保留 admin 用户和系统项目数据)
|
||
2. 后端服务全部启动(Gateway、Auth、MDM、OPS)
|
||
3. 前端服务启动
|
||
4. 浏览器清除 LocalStorage
|
||
|
||
---
|
||
|
||
## 二、测试用例
|
||
|
||
### TC-WIZARD-001: 超级管理员首次登录进入向导模式
|
||
|
||
**测试权限**: 超级管理员 (admin)
|
||
|
||
**前置条件**:
|
||
- 数据库中无业务项目
|
||
- admin 用户仅有 SUPER_ADMIN 角色,关联系统项目
|
||
|
||
**测试步骤**:
|
||
|
||
| 步骤 | 操作 | 期望结果 |
|
||
|------|------|----------|
|
||
| 1 | 访问 http://localhost:5175/ | 显示登录页面 |
|
||
| 2 | 输入用户名 `admin`,密码 `admin123`,点击登录 | 登录成功,自动跳转到 `/setup-wizard` |
|
||
| 3 | 检查页面标题 | 显示"欢迎使用 Ether 智慧物业管理平台" |
|
||
| 4 | 检查步骤条 | 显示3个步骤:创建项目、角色配置、完成设置 |
|
||
|
||
**验证方法**:
|
||
```javascript
|
||
// API 验证
|
||
const response = await fetch('/api/v1/auth/user-permissions', {
|
||
headers: { 'Authorization': `Bearer ${token}` }
|
||
});
|
||
const data = await response.json();
|
||
// 验证 isSystemAdmin
|
||
assert(data.projects.some(p => p.isSystem === true));
|
||
// 验证 needSetupWizard
|
||
assert(data.projects.filter(p => !p.isSystem).length === 0);
|
||
```
|
||
|
||
**API 测试**:
|
||
```bash
|
||
# 登录获取 token
|
||
TOKEN=$(curl -s -X POST http://localhost:8080/api/v1/auth/login \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"username":"admin","password":"admin123"}' \
|
||
| jq -r '.data.accessToken')
|
||
|
||
# 验证权限响应
|
||
curl -s http://localhost:8080/api/v1/auth/user-permissions \
|
||
-H "Authorization: Bearer $TOKEN" | jq '{
|
||
projects: .data.projects,
|
||
isSystem: [.data.projects[].isSystem]
|
||
}'
|
||
```
|
||
|
||
---
|
||
|
||
### TC-WIZARD-002: 创建方式切换
|
||
|
||
**测试权限**: 超级管理员
|
||
|
||
**前置条件**: 已进入向导页面
|
||
|
||
**测试步骤**:
|
||
|
||
| 步骤 | 操作 | 期望结果 |
|
||
|------|------|----------|
|
||
| 1 | 检查默认选中 | 默认选中"手动创建" |
|
||
| 2 | 点击"从集团同步" | 显示"功能开发中,敬请期待"提示 |
|
||
| 3 | "下一步"按钮状态 | 按钮禁用 |
|
||
| 4 | 切换回"手动创建" | 表单正常显示,"下一步"按钮可用 |
|
||
|
||
---
|
||
|
||
### TC-WIZARD-003: 省市区下拉选择
|
||
|
||
**测试权限**: 超级管理员
|
||
|
||
**前置条件**: 已进入向导页面,选择"手动创建"
|
||
|
||
**测试步骤**:
|
||
|
||
| 步骤 | 操作 | 期望结果 |
|
||
|------|------|----------|
|
||
| 1 | 检查省份字段 | 显示"上海市",禁用状态 |
|
||
| 2 | 检查城市字段 | 显示"上海市",禁用状态 |
|
||
| 3 | 点击区县下拉框 | 显示上海16个区选项 |
|
||
| 4 | 选择"浦东新区" | 区县字段显示"浦东新区" |
|
||
|
||
**验证数据**:
|
||
```javascript
|
||
const SHANGHAI_DISTRICTS = [
|
||
'黄浦区', '徐汇区', '长宁区', '静安区', '普陀区',
|
||
'虹口区', '杨浦区', '闵行区', '宝山区', '嘉定区',
|
||
'浦东新区', '金山区', '松江区', '青浦区', '奉贤区', '崇明区'
|
||
];
|
||
// 验证下拉选项数量
|
||
assert(dropdownOptions.length === 16);
|
||
```
|
||
|
||
---
|
||
|
||
### TC-WIZARD-004: 用户选择器 - 创建用户
|
||
|
||
**测试权限**: 超级管理员
|
||
|
||
**前置条件**: 已进入向导页面,选择"手动创建"
|
||
|
||
**测试步骤**:
|
||
|
||
| 步骤 | 操作 | 期望结果 |
|
||
|------|------|----------|
|
||
| 1 | 点击"项目负责人"输入框 | 弹出"选择负责人"对话框 |
|
||
| 2 | 检查对话框按钮 | "确定"和"取消"按钮显示中文 |
|
||
| 3 | 点击"创建用户"按钮 | 弹出"创建用户"对话框 |
|
||
| 4 | 输入用户名 `test_manager` | - |
|
||
| 5 | 输入姓名 `测试负责人` | - |
|
||
| 6 | 输入手机号 `13800138001` | - |
|
||
| 7 | 密码留空 | 显示"留空将自动生成随机密码"提示 |
|
||
| 8 | 点击"确定" | 显示"用户创建成功"弹窗,显示生成的密码 |
|
||
| 9 | 点击"我已保存" | 用户自动选中,输入框显示"测试负责人 (13800138001)" |
|
||
|
||
**API 验证**:
|
||
```bash
|
||
# 创建用户 API 测试
|
||
curl -s -X POST http://localhost:8080/api/v1/auth/users \
|
||
-H "Content-Type: application/json" \
|
||
-H "Authorization: Bearer $TOKEN" \
|
||
-d '{
|
||
"username": "test_manager",
|
||
"realName": "测试负责人",
|
||
"phone": "13800138001",
|
||
"userType": "ENTERPRISE"
|
||
}' | jq '{
|
||
id: .data.id,
|
||
username: .data.username,
|
||
generatedPassword: .data.generatedPassword
|
||
}'
|
||
```
|
||
|
||
**验证点**:
|
||
- 用户类型为 `ENTERPRISE`(非 PROJECT)
|
||
- 返回 `generatedPassword` 字段
|
||
- 密码为12位随机字符
|
||
|
||
---
|
||
|
||
### TC-WIZARD-005: 用户选择器 - 搜索用户
|
||
|
||
**测试权限**: 超级管理员
|
||
|
||
**前置条件**: 系统中已有用户
|
||
|
||
**测试步骤**:
|
||
|
||
| 步骤 | 操作 | 期望结果 |
|
||
|------|------|----------|
|
||
| 1 | 点击"项目负责人"输入框 | 弹出"选择负责人"对话框 |
|
||
| 2 | 在搜索框输入"测试" | 显示匹配的用户列表 |
|
||
| 3 | 检查用户列表项 | 显示头像、姓名、手机号 |
|
||
| 4 | 点击"选择"按钮 | 用户选中,对话框关闭 |
|
||
|
||
---
|
||
|
||
### TC-WIZARD-006: 角色配置 - 查看权限详情
|
||
|
||
**测试权限**: 超级管理员
|
||
|
||
**前置条件**: 已完成项目信息填写,进入步骤2
|
||
|
||
**测试步骤**:
|
||
|
||
| 步骤 | 操作 | 期望结果 |
|
||
|------|------|----------|
|
||
| 1 | 检查角色模板列表 | 显示6个角色模板 |
|
||
| 2 | 检查角色说明 | 项目负责人显示"负责项目整体管理,拥有最高权限..." |
|
||
| 3 | 点击权限数量链接 | 弹出权限详情对话框 |
|
||
| 4 | 检查权限分组 | 权限按模块分组显示(用户管理、角色管理等) |
|
||
| 5 | 检查滚动区域 | 权限列表固定高度,超出部分滚动 |
|
||
|
||
**角色模板验证**:
|
||
```javascript
|
||
const expectedTemplates = [
|
||
{ code: 'PROJECT_MANAGER', name: '项目负责人' },
|
||
{ code: 'PROPERTY_MANAGER', name: '物业经理' },
|
||
{ code: 'CUSTOMER_SERVICE', name: '客服人员' },
|
||
{ code: 'MAINTENANCE', name: '维修人员' },
|
||
{ code: 'SECURITY', name: '安保人员' },
|
||
{ code: 'OWNER', name: '业主' }
|
||
];
|
||
```
|
||
|
||
---
|
||
|
||
### TC-WIZARD-007: 完成向导 - 项目编号自动生成
|
||
|
||
**测试权限**: 超级管理员
|
||
|
||
**前置条件**: 已完成项目信息和角色配置
|
||
|
||
**测试步骤**:
|
||
|
||
| 步骤 | 操作 | 期望结果 |
|
||
|------|------|----------|
|
||
| 1 | 点击"完成初始化"按钮 | 显示加载状态 |
|
||
| 2 | 等待完成 | 显示"初始化完成!"成功页面 |
|
||
| 3 | 检查项目编号 | 显示格式为 `PRJ{YYYYMM}{序号}`,如 `PRJ202602001` |
|
||
| 4 | 检查创建的角色 | 显示已创建的角色列表 |
|
||
|
||
**项目编号验证**:
|
||
```javascript
|
||
// 验证编号格式
|
||
const codePattern = /^PRJ\d{6}\d{3}$/;
|
||
assert(codePattern.test(projectCode));
|
||
// 验证编号递增
|
||
// 第二个项目应为 PRJ202602002
|
||
```
|
||
|
||
**API 验证**:
|
||
```bash
|
||
# 验证项目创建
|
||
curl -s http://localhost:8080/api/v1/mdm/projects \
|
||
-H "Authorization: Bearer $TOKEN" | jq '.data[0] | {
|
||
name, code, managerName
|
||
}'
|
||
```
|
||
|
||
---
|
||
|
||
### TC-WIZARD-008: 完成向导 - 进入系统
|
||
|
||
**测试权限**: 超级管理员
|
||
|
||
**前置条件**: 向导已完成,显示成功页面
|
||
|
||
**测试步骤**:
|
||
|
||
| 步骤 | 操作 | 期望结果 |
|
||
|------|------|----------|
|
||
| 1 | 点击"进入系统"按钮 | 页面跳转到首页 |
|
||
| 2 | 检查 URL | 不再是 `/setup-wizard` 或 `/no-project` |
|
||
| 3 | 检查侧边菜单 | 显示项目相关的菜单项 |
|
||
| 4 | 检查项目选择器 | 显示刚创建的项目 |
|
||
|
||
**验证方法**:
|
||
```javascript
|
||
// 验证权限已刷新
|
||
const permissionStore = usePermissionStore();
|
||
assert(permissionStore.hasProjects === true);
|
||
assert(permissionStore.needSetupWizard === false);
|
||
assert(permissionStore.menus.length > 0);
|
||
```
|
||
|
||
---
|
||
|
||
## 三、数据清理脚本
|
||
|
||
### 3.1 清理到初始状态
|
||
|
||
```sql
|
||
-- MDM 数据库
|
||
DELETE FROM mdm_project WHERE id != '00000000-0000-0000-0000-000000000000';
|
||
|
||
-- Auth 数据库
|
||
DELETE FROM auth_user_role WHERE project_id != '00000000-0000-0000-0000-000000000000';
|
||
DELETE FROM auth_role_permission WHERE role_id IN (
|
||
SELECT id FROM auth_role WHERE project_id != '00000000-0000-0000-0000-000000000000'
|
||
);
|
||
DELETE FROM auth_role WHERE project_id != '00000000-0000-0000-0000-000000000000';
|
||
DELETE FROM auth_permission WHERE project_id != '00000000-0000-0000-0000-000000000000';
|
||
DELETE FROM auth_user WHERE username != 'admin';
|
||
```
|
||
|
||
### 3.2 Shell 脚本
|
||
|
||
```bash
|
||
#!/bin/bash
|
||
# reset-test-data.sh - 重置测试数据到初始状态
|
||
|
||
PGPASSWORD=ether123 psql -h localhost -U ether -d ether_mdm -c \
|
||
"DELETE FROM mdm_project WHERE id != '00000000-0000-0000-0000-000000000000';"
|
||
|
||
PGPASSWORD=ether123 psql -h localhost -U ether -d ether_auth -c \
|
||
"DELETE FROM auth_user_role WHERE project_id != '00000000-0000-0000-0000-000000000000';
|
||
DELETE FROM auth_role_permission WHERE role_id IN (SELECT id FROM auth_role WHERE project_id != '00000000-0000-0000-0000-000000000000');
|
||
DELETE FROM auth_role WHERE project_id != '00000000-0000-0000-0000-000000000000';
|
||
DELETE FROM auth_permission WHERE project_id != '00000000-0000-0000-0000-000000000000';
|
||
DELETE FROM auth_user WHERE username != 'admin';"
|
||
|
||
echo "Test data reset complete!"
|
||
```
|
||
|
||
---
|
||
|
||
## 四、E2E 自动化测试脚本
|
||
|
||
### 4.1 Puppeteer 测试脚本
|
||
|
||
```typescript
|
||
// e2e/setup-wizard.test.ts
|
||
import puppeteer from 'puppeteer';
|
||
|
||
describe('Setup Wizard E2E Tests', () => {
|
||
let browser: puppeteer.Browser;
|
||
let page: puppeteer.Page;
|
||
|
||
beforeAll(async () => {
|
||
browser = await puppeteer.launch({ headless: false });
|
||
page = await browser.newPage();
|
||
});
|
||
|
||
afterAll(async () => {
|
||
await browser.close();
|
||
});
|
||
|
||
beforeEach(async () => {
|
||
// 清除 localStorage
|
||
await page.goto('http://localhost:5175/');
|
||
await page.evaluate(() => localStorage.clear());
|
||
});
|
||
|
||
test('TC-WIZARD-001: 超级管理员首次登录进入向导模式', async () => {
|
||
// 登录
|
||
await page.goto('http://localhost:5175/login');
|
||
await page.type('input[placeholder="请输入用户名"]', 'admin');
|
||
await page.type('input[placeholder="请输入密码"]', 'admin123');
|
||
await page.click('button[type="submit"]');
|
||
|
||
// 等待跳转
|
||
await page.waitForNavigation();
|
||
|
||
// 验证 URL
|
||
expect(page.url()).toContain('/setup-wizard');
|
||
|
||
// 验证页面标题
|
||
const title = await page.$eval('.wizard-header h1', el => el.textContent);
|
||
expect(title).toContain('欢迎使用 Ether 智慧物业管理平台');
|
||
});
|
||
|
||
test('TC-WIZARD-004: 用户选择器 - 创建用户', async () => {
|
||
// 假设已在向导页面
|
||
await page.click('.user-selector input');
|
||
await page.waitForSelector('.ant-modal');
|
||
|
||
// 点击创建用户
|
||
await page.click('button:has-text("创建用户")');
|
||
|
||
// 填写表单
|
||
await page.type('#username', 'e2e_test_user');
|
||
await page.type('#realName', 'E2E测试用户');
|
||
await page.type('#phone', '13900139000');
|
||
|
||
// 提交
|
||
await page.click('.ant-modal button[type="submit"]');
|
||
|
||
// 验证密码弹窗
|
||
await page.waitForSelector('.ant-modal-content:has-text("用户创建成功")');
|
||
const password = await page.$eval('.generated-password', el => el.textContent);
|
||
expect(password).toHaveLength(12);
|
||
});
|
||
|
||
test('TC-WIZARD-007: 完成向导 - 项目编号自动生成', async () => {
|
||
// 完成向导流程...
|
||
|
||
// 验证项目编号
|
||
const projectCode = await page.$eval('.project-code-display .code', el => el.textContent);
|
||
expect(projectCode).toMatch(/^PRJ\d{6}\d{3}$/);
|
||
});
|
||
});
|
||
```
|
||
|
||
---
|
||
|
||
## 五、已知问题与修复记录
|
||
|
||
### 5.1 已修复问题
|
||
|
||
| 问题编号 | 描述 | 修复方案 | 修复日期 |
|
||
|----------|------|----------|----------|
|
||
| BUG-001 | 超级管理员登录后显示"暂无项目权限" | 修复 `isSystem` 字段序列化问题 | 2026-02-15 |
|
||
| BUG-002 | 创建用户时 userType 使用 PROJECT | 改为 ENTERPRISE | 2026-02-15 |
|
||
| BUG-003 | 对话框按钮显示英文 | 添加 ok-text/cancel-text | 2026-02-15 |
|
||
| BUG-004 | 自动生成密码未显示 | 添加密码显示弹窗 | 2026-02-15 |
|
||
| BUG-005 | 项目编号显示"-" | 从 MDM 响应获取生成的编号 | 2026-02-15 |
|
||
| BUG-006 | 向导完成后跳转到无项目页面 | 修复 hasProjects 计算逻辑 | 2026-02-15 |
|
||
|
||
---
|
||
|
||
## 六、执行记录
|
||
|
||
| 执行日期 | 执行人 | 结果 | 备注 |
|
||
|----------|--------|------|------|
|
||
| 2026-02-15 | AI Assistant | 通过 | 首次完整测试 |
|
||
| | | | |
|
||
|
||
---
|
||
|
||
## 七、版本历史
|
||
|
||
| 版本 | 日期 | 修改内容 | 修改人 |
|
||
|------|------|----------|--------|
|
||
| v1.0 | 2026-02-15 | 初始版本 | AI Assistant |
|