import { RbacService } from './rbac.service'; describe('RbacService seedData', () => { it('migrates the legacy teacher role and replaces broad permissions with the teaching matrix', async () => { const permissions = [ { id: 1, code: 'profile:view', name: '查看个人资料', group: 'profile' }, { id: 2, code: 'notification:view', name: '查看通知', group: 'notification' }, { id: 3, code: 'student:view', name: '查看学生', group: 'student' }, { id: 4, code: 'class:view', name: '查看班级', group: 'class' }, { id: 5, code: 'schedule:view', name: '查看排课', group: 'schedule' }, { id: 6, code: 'attendance:view', name: '查看考勤', group: 'attendance' }, { id: 7, code: 'attendance:create', name: '新增考勤', group: 'attendance' }, { id: 8, code: 'teacher-workspace:view', name: '教师工作台', group: 'teacher-workspace' }, { id: 9, code: 'room:view', name: '查看宿舍', group: 'room' }, { id: 10, code: 'schedule:create', name: '新增排课', group: 'schedule' }, ]; const teacherRole = { id: 1, name: '老师', code: 'teacher', description: '旧角色', isSystem: true, status: 1, permissions: [permissions[2], permissions[3], permissions[8]], }; const permRepo = { findOne: jest.fn( async ({ where }: any) => permissions.find((permission) => permission.code === where.code) ?? null, ), create: jest.fn((value) => value), save: jest.fn(async (value) => value), find: jest.fn(async () => permissions), }; const roleRepo = { findOne: jest.fn(async ({ where }: any) => where.code === 'teacher' || where.name === '老师' ? teacherRole : null, ), create: jest.fn((value) => ({ ...value, permissions: [] })), save: jest.fn(async (value) => value), find: jest.fn(async () => [teacherRole]), }; const userRepo = { count: jest.fn(async () => 1), create: jest.fn(), save: jest.fn() }; const service = new RbacService( permRepo as never, roleRepo as never, userRepo as never, {} as never, {} as never, {} as never, {} as never, {} as never, ); await service.seedData(); expect(teacherRole.name).toBe('任课老师'); expect(teacherRole.permissions.map((permission) => permission.code)).toEqual( expect.arrayContaining([ 'profile:view', 'teacher-workspace:view', 'schedule:view', 'attendance:create', ]), ); expect(teacherRole.permissions.map((permission) => permission.code)).not.toContain( 'schedule:create', ); expect(teacherRole.permissions.map((permission) => permission.code)).not.toContain('student:view'); expect(teacherRole.permissions.map((permission) => permission.code)).not.toContain('class:view'); expect(teacherRole.permissions.map((permission) => permission.code)).not.toContain('room:view'); }); }); describe('RbacService legacy role consolidation', () => { it('moves users from duplicate accommodation roles before deleting the duplicates', async () => { const permissions = [ { id: 1, code: 'profile:view', name: '查看个人资料', group: 'profile' }, { id: 2, code: 'room:view', name: '查看宿舍', group: 'room' }, { id: 3, code: 'expense:view', name: '查看费用', group: 'expense' }, { id: 4, code: 'student:basic-view', name: '学生基础信息', group: 'student-scope' }, ]; const targetRole: any = { id: 10, name: '住宿运营管理员', code: 'accommodation_operations', description: '', isSystem: true, status: 1, permissions: [], users: [], }; const legacyRole: any = { id: 11, name: '财务', code: 'finance', description: '', isSystem: true, status: 1, permissions: [], users: [{ id: 21 }], }; const user: any = { id: 21, roles: [legacyRole] }; const permRepo = { findOne: jest.fn(async ({ where }: any) => permissions.find((item) => item.code === where.code) ?? null), create: jest.fn((value) => value), save: jest.fn(async (value) => value), find: jest.fn(async () => permissions), }; const roleRepo = { findOne: jest.fn(async () => targetRole), create: jest.fn((value) => ({ ...value, permissions: [] })), save: jest.fn(async (value) => value), find: jest.fn(async () => [targetRole, legacyRole]), remove: jest.fn(async (value) => value), }; const userRepo = { count: jest.fn(async () => 1), findOne: jest.fn(async () => user), save: jest.fn(async (value) => value), }; const service = new RbacService( permRepo as never, roleRepo as never, userRepo as never, {} as never, {} as never, {} as never, {} as never, {} as never, ); await service.seedData(); expect(user.roles).toEqual([targetRole]); expect(userRepo.save).toHaveBeenCalledWith(user); expect(roleRepo.remove).toHaveBeenCalledWith(legacyRole); }); });