feat: 实现角色定义系统
- 创建角色定义基类 RoleDefinition - 实现管理员角色 AdminRole - 实现普通用户角色 UserRole - 实现测试用户角色 TestRole - 实现角色工厂 RoleFactory - 添加完整的单元测试 - 更新 vitest 配置以包含角色定义测试 所有角色统一使用密码: Test@123
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { AdminRole } from '../admin.role';
|
||||
|
||||
describe('AdminRole', () => {
|
||||
it('should have admin credentials', () => {
|
||||
expect(AdminRole.name).toBe('admin');
|
||||
expect(AdminRole.displayName).toBe('超级管理员');
|
||||
expect(AdminRole.credentials.username).toBe('admin');
|
||||
expect(AdminRole.credentials.password).toBe('Test@123');
|
||||
});
|
||||
|
||||
it('should have all permissions', () => {
|
||||
expect(AdminRole.permissions).toContain('user:*');
|
||||
expect(AdminRole.permissions).toContain('role:*');
|
||||
expect(AdminRole.permissions).toContain('menu:*');
|
||||
expect(AdminRole.cannotAccess).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('should be able to create all resources', () => {
|
||||
expect(AdminRole.expectedBehaviors.canCreate).toContain('user');
|
||||
expect(AdminRole.expectedBehaviors.canCreate).toContain('role');
|
||||
expect(AdminRole.expectedBehaviors.canCreate).toContain('menu');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,30 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import type { RoleDefinition } from '../base.role';
|
||||
|
||||
describe('RoleDefinition', () => {
|
||||
it('should define required role properties', () => {
|
||||
const role: RoleDefinition = {
|
||||
name: 'test',
|
||||
displayName: '测试角色',
|
||||
credentials: {
|
||||
username: 'testuser',
|
||||
password: 'Test@123'
|
||||
},
|
||||
permissions: ['test:read', 'test:write'],
|
||||
cannotAccess: ['/admin'],
|
||||
expectedBehaviors: {
|
||||
canCreate: ['test'],
|
||||
canRead: ['test'],
|
||||
canUpdate: ['test'],
|
||||
canDelete: []
|
||||
}
|
||||
};
|
||||
|
||||
expect(role.name).toBe('test');
|
||||
expect(role.displayName).toBe('测试角色');
|
||||
expect(role.credentials.username).toBe('testuser');
|
||||
expect(role.credentials.password).toBe('Test@123');
|
||||
expect(role.permissions).toHaveLength(2);
|
||||
expect(role.cannotAccess).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,28 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { RoleFactory } from '../role-factory';
|
||||
|
||||
describe('RoleFactory', () => {
|
||||
it('should get admin role', () => {
|
||||
const role = RoleFactory.getRole('admin');
|
||||
expect(role.name).toBe('admin');
|
||||
expect(role.credentials.username).toBe('admin');
|
||||
});
|
||||
|
||||
it('should get user role', () => {
|
||||
const role = RoleFactory.getRole('user');
|
||||
expect(role.name).toBe('user');
|
||||
expect(role.credentials.username).toBe('normaluser');
|
||||
});
|
||||
|
||||
it('should throw error for unknown role', () => {
|
||||
expect(() => RoleFactory.getRole('unknown')).toThrow("Role 'unknown' not found");
|
||||
});
|
||||
|
||||
it('should get all roles', () => {
|
||||
const roles = RoleFactory.getAllRoles();
|
||||
expect(roles).toHaveLength(3);
|
||||
expect(roles.map(r => r.name)).toContain('admin');
|
||||
expect(roles.map(r => r.name)).toContain('user');
|
||||
expect(roles.map(r => r.name)).toContain('test');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,25 @@
|
||||
import type { RoleDefinition } from './base.role';
|
||||
|
||||
export const AdminRole: RoleDefinition = {
|
||||
name: 'admin',
|
||||
displayName: '超级管理员',
|
||||
credentials: {
|
||||
username: 'admin',
|
||||
password: 'Test@123'
|
||||
},
|
||||
permissions: [
|
||||
'user:*',
|
||||
'role:*',
|
||||
'menu:*',
|
||||
'config:*',
|
||||
'log:read',
|
||||
'dict:*'
|
||||
],
|
||||
cannotAccess: [],
|
||||
expectedBehaviors: {
|
||||
canCreate: ['user', 'role', 'menu', 'config', 'dict'],
|
||||
canRead: ['user', 'role', 'menu', 'config', 'dict', 'log'],
|
||||
canUpdate: ['user', 'role', 'menu', 'config', 'dict'],
|
||||
canDelete: ['user', 'role', 'menu', 'config', 'dict']
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,16 @@
|
||||
export interface RoleDefinition {
|
||||
name: string;
|
||||
displayName: string;
|
||||
credentials: {
|
||||
username: string;
|
||||
password: string;
|
||||
};
|
||||
permissions: string[];
|
||||
cannotAccess: string[];
|
||||
expectedBehaviors: {
|
||||
canCreate: string[];
|
||||
canRead: string[];
|
||||
canUpdate: string[];
|
||||
canDelete: string[];
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import type { RoleDefinition } from './base.role';
|
||||
import { AdminRole } from './admin.role';
|
||||
import { UserRole } from './user.role';
|
||||
import { TestRole } from './test.role';
|
||||
|
||||
export class RoleFactory {
|
||||
private static roles: Map<string, RoleDefinition> = new Map([
|
||||
['admin', AdminRole],
|
||||
['user', UserRole],
|
||||
['test', TestRole]
|
||||
]);
|
||||
|
||||
static getRole(roleName: string): RoleDefinition {
|
||||
const role = this.roles.get(roleName);
|
||||
if (!role) {
|
||||
throw new Error(`Role '${roleName}' not found`);
|
||||
}
|
||||
return role;
|
||||
}
|
||||
|
||||
static getAllRoles(): RoleDefinition[] {
|
||||
return Array.from(this.roles.values());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import type { RoleDefinition } from './base.role';
|
||||
|
||||
export const TestRole: RoleDefinition = {
|
||||
name: 'test',
|
||||
displayName: '测试用户',
|
||||
credentials: {
|
||||
username: 'e2e_test_user',
|
||||
password: 'Test@123'
|
||||
},
|
||||
permissions: [
|
||||
'test:read',
|
||||
'test:write'
|
||||
],
|
||||
cannotAccess: [
|
||||
'/user-management',
|
||||
'/role-management'
|
||||
],
|
||||
expectedBehaviors: {
|
||||
canCreate: ['test'],
|
||||
canRead: ['test'],
|
||||
canUpdate: ['test'],
|
||||
canDelete: []
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,26 @@
|
||||
import type { RoleDefinition } from './base.role';
|
||||
|
||||
export const UserRole: RoleDefinition = {
|
||||
name: 'user',
|
||||
displayName: '普通用户',
|
||||
credentials: {
|
||||
username: 'normaluser',
|
||||
password: 'Test@123'
|
||||
},
|
||||
permissions: [
|
||||
'user:read:self',
|
||||
'user:update:self'
|
||||
],
|
||||
cannotAccess: [
|
||||
'/user-management',
|
||||
'/role-management',
|
||||
'/menu-management',
|
||||
'/system-config'
|
||||
],
|
||||
expectedBehaviors: {
|
||||
canCreate: [],
|
||||
canRead: ['self'],
|
||||
canUpdate: ['self'],
|
||||
canDelete: []
|
||||
}
|
||||
};
|
||||
@@ -8,13 +8,16 @@ export default defineConfig({
|
||||
globals: true,
|
||||
environment: 'jsdom',
|
||||
setupFiles: ['./src/test/setup.ts'],
|
||||
// 明确指定只包含单元测试文件
|
||||
include: ['src/test/**/*.{test,spec}.{js,ts,jsx,tsx}'],
|
||||
// 明确指定包含单元测试文件和角色定义测试
|
||||
include: [
|
||||
'src/test/**/*.{test,spec}.{js,ts,jsx,tsx}',
|
||||
'e2e/role-based-tests/**/__tests__/*.{test,spec}.{js,ts,jsx,tsx}'
|
||||
],
|
||||
// 明确排除E2E测试文件
|
||||
exclude: [
|
||||
'node_modules/',
|
||||
'dist/',
|
||||
'e2e/**/*',
|
||||
'e2e/**/*.spec.ts',
|
||||
'**/*.d.ts',
|
||||
'**/*.config.*',
|
||||
'**/mockData',
|
||||
|
||||
Reference in New Issue
Block a user