Files
gongxue-base/apps/server/src/auth/auth.service.spec.ts

51 lines
1.7 KiB
TypeScript

import * as bcrypt from 'bcryptjs';
import { AuthService } from './auth.service';
describe('AuthService — authentication boundaries', () => {
it('marks the preset 超管 role as super admin in the JWT payload', async () => {
const userRepo = {
findOne: jest.fn().mockResolvedValue({
id: 1,
username: 'admin',
name: '管理员',
passwordHash: await bcrypt.hash('secret', 4),
isActive: true,
roles: [{ name: '超管', status: 1 }],
}),
save: jest.fn(),
};
const jwtService = { sign: jest.fn().mockReturnValue('token') };
const rbacService = {
getUserPermissions: jest.fn().mockResolvedValue(['attendance:create']),
};
const service = new AuthService(userRepo as never, jwtService as never, rbacService as never);
await service.login({ username: 'admin', password: 'secret' }, '127.0.0.1');
expect(jwtService.sign).toHaveBeenCalledWith(expect.objectContaining({ isSuperAdmin: true }));
});
it('rejects an archived user even when the password is valid', async () => {
const userRepo = {
findOne: jest.fn().mockResolvedValue({
id: 2,
username: 'archived',
passwordHash: await bcrypt.hash('secret', 4),
isActive: true,
isArchived: true,
roles: [],
}),
save: jest.fn(),
};
const service = new AuthService(
userRepo as never,
{ sign: jest.fn() } as never,
{ getUserPermissions: jest.fn() } as never,
);
await expect(
service.login({ username: 'archived', password: 'secret' }, '192.0.2.10'),
).rejects.toThrow('账号已失效');
expect(userRepo.save).not.toHaveBeenCalled();
});
});