08ea5fbe98
添加用户管理视图、API和状态管理文件
255 lines
6.4 KiB
TypeScript
255 lines
6.4 KiB
TypeScript
import { testDataGenerator, UserData } from './test-data';
|
|
|
|
export class TestDataManager {
|
|
private request: APIRequestContext;
|
|
private authToken: string;
|
|
private testData: Map<string, any[]> = new Map();
|
|
|
|
constructor(request: APIRequestContext, authToken: string) {
|
|
this.request = request;
|
|
this.authToken = authToken;
|
|
}
|
|
|
|
async createTestUser(overrides: Partial<User> = {}): Promise<User> {
|
|
const userData = TestDataFactory.generateUser(overrides);
|
|
|
|
const response = await this.request.post('/api/sys/user', {
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Authorization': `Bearer ${this.authToken}`
|
|
},
|
|
data: userData
|
|
});
|
|
|
|
const body = await response.json();
|
|
const user = body.data || body;
|
|
|
|
this.addTestData('user', user);
|
|
return user;
|
|
}
|
|
|
|
async createTestUserFromGenerator(overrides: Partial<UserData> = {}): Promise<UserData> {
|
|
const userData = testDataGenerator.generateUserData(overrides);
|
|
|
|
const response = await this.request.post('/api/sys/user', {
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Authorization': `Bearer ${this.authToken}`
|
|
},
|
|
data: userData
|
|
});
|
|
|
|
const body = await response.json();
|
|
const user = body.data || body;
|
|
|
|
this.addTestData('user', user);
|
|
return user;
|
|
}
|
|
|
|
async createTestRole(overrides: Partial<Role> = {}): Promise<Role> {
|
|
const roleData = TestDataFactory.generateRole(overrides);
|
|
|
|
const response = await this.request.post('/api/sys/role', {
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Authorization': `Bearer ${this.authToken}`
|
|
},
|
|
data: roleData
|
|
});
|
|
|
|
const body = await response.json();
|
|
const role = body.data || body;
|
|
|
|
this.addTestData('role', role);
|
|
return role;
|
|
}
|
|
|
|
async createTestMenu(overrides: Partial<Menu> = {}): Promise<Menu> {
|
|
const menuData = TestDataFactory.generateMenu(overrides);
|
|
|
|
const response = await this.request.post('/api/sys/menu', {
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Authorization': `Bearer ${this.authToken}`
|
|
},
|
|
data: menuData
|
|
});
|
|
|
|
const body = await response.json();
|
|
const menu = body.data || body;
|
|
|
|
this.addTestData('menu', menu);
|
|
return menu;
|
|
}
|
|
|
|
async getTestUser(username: string): Promise<User | null> {
|
|
const response = await this.request.get(`/api/sys/user/username/${username}`, {
|
|
headers: {
|
|
'Authorization': `Bearer ${this.authToken}`
|
|
}
|
|
});
|
|
|
|
if (response.status() === 200) {
|
|
const body = await response.json();
|
|
return body.data || body;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
async updateTestUser(userId: number | string, updates: Partial<User>): Promise<User> {
|
|
const response = await this.request.put('/api/sys/user', {
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Authorization': `Bearer ${this.authToken}`
|
|
},
|
|
data: { id: userId, ...updates }
|
|
});
|
|
|
|
const body = await response.json();
|
|
return body.data || body;
|
|
}
|
|
|
|
async deleteTestUser(userId: number | string): Promise<void> {
|
|
await this.request.delete(`/api/sys/user/${userId}`, {
|
|
headers: {
|
|
'Authorization': `Bearer ${this.authToken}`
|
|
}
|
|
});
|
|
|
|
this.removeTestData('user', userId);
|
|
}
|
|
|
|
async deleteTestRole(roleId: number | string): Promise<void> {
|
|
await this.request.delete(`/api/sys/role/${roleId}`, {
|
|
headers: {
|
|
'Authorization': `Bearer ${this.authToken}`
|
|
}
|
|
});
|
|
|
|
this.removeTestData('role', roleId);
|
|
}
|
|
|
|
async deleteTestMenu(menuId: number | string): Promise<void> {
|
|
await this.request.delete(`/api/sys/menu/${menuId}`, {
|
|
headers: {
|
|
'Authorization': `Bearer ${this.authToken}`
|
|
}
|
|
});
|
|
|
|
this.removeTestData('menu', menuId);
|
|
}
|
|
|
|
async cleanup(): Promise<void> {
|
|
const cleanupPromises: Promise<void>[] = [];
|
|
|
|
for (const [type, items] of this.testData) {
|
|
for (const item of items) {
|
|
if (item.id) {
|
|
switch (type) {
|
|
case 'user':
|
|
cleanupPromises.push(this.deleteTestUser(item.id));
|
|
break;
|
|
case 'role':
|
|
cleanupPromises.push(this.deleteTestRole(item.id));
|
|
break;
|
|
case 'menu':
|
|
cleanupPromises.push(this.deleteTestMenu(item.id));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
await Promise.all(cleanupPromises);
|
|
this.testData.clear();
|
|
}
|
|
|
|
private addTestData(type: string, data: any): void {
|
|
if (!this.testData.has(type)) {
|
|
this.testData.set(type, []);
|
|
}
|
|
this.testData.get(type)!.push(data);
|
|
}
|
|
|
|
private removeTestData(type: string, id: number | string): void {
|
|
const items = this.testData.get(type);
|
|
if (items) {
|
|
const index = items.findIndex(item => item.id === id);
|
|
if (index !== -1) {
|
|
items.splice(index, 1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
export class TestDataFactory {
|
|
static generateUser(overrides: Partial<User> = {}): User {
|
|
const timestamp = Date.now();
|
|
return {
|
|
username: `e2e_test_user_${timestamp}`,
|
|
password: 'Test@123456',
|
|
realName: 'E2E测试用户',
|
|
email: `e2e_${timestamp}@example.com`,
|
|
phone: '13800138000',
|
|
status: 1,
|
|
gender: 1,
|
|
...overrides
|
|
};
|
|
}
|
|
|
|
static generateRole(overrides: Partial<Role> = {}): Role {
|
|
const timestamp = Date.now();
|
|
return {
|
|
roleName: `E2E测试角色_${timestamp}`,
|
|
roleCode: `e2e_test_role_${timestamp}`,
|
|
description: 'E2E测试角色描述',
|
|
status: 1,
|
|
...overrides
|
|
};
|
|
}
|
|
|
|
static generateMenu(overrides: Partial<Menu> = {}): Menu {
|
|
const timestamp = Date.now();
|
|
return {
|
|
name: `E2E测试菜单_${timestamp}`,
|
|
code: `e2e_test_menu_${timestamp}`,
|
|
path: `/e2e-test-menu-${timestamp}`,
|
|
icon: 'SettingOutlined',
|
|
sortOrder: 10,
|
|
status: 1,
|
|
parentId: 0,
|
|
...overrides
|
|
};
|
|
}
|
|
}
|
|
|
|
export interface User {
|
|
id?: number | string;
|
|
username: string;
|
|
password?: string;
|
|
realName?: string;
|
|
email?: string;
|
|
phone?: string;
|
|
status?: number;
|
|
gender?: number;
|
|
}
|
|
|
|
export interface Role {
|
|
id?: number | string;
|
|
roleName: string;
|
|
roleCode: string;
|
|
description?: string;
|
|
status?: number;
|
|
}
|
|
|
|
export interface Menu {
|
|
id?: number | string;
|
|
name: string;
|
|
code: string;
|
|
path?: string;
|
|
icon?: string;
|
|
sortOrder?: number;
|
|
status?: number;
|
|
parentId?: number | string;
|
|
}
|