|
@@ -1,142 +0,0 @@
|
|
|
-import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
|
|
|
-import { AuthService, User, UserService } from '../../src/auth.service.js';
|
|
|
|
|
-import { EnableStatus } from '@d8d/shared-types';
|
|
|
|
|
-
|
|
|
|
|
-describe('认证服务', () => {
|
|
|
|
|
- let authService: AuthService;
|
|
|
|
|
- let mockUserService: UserService;
|
|
|
|
|
-
|
|
|
|
|
- const mockUser: User = {
|
|
|
|
|
- id: 1,
|
|
|
|
|
- username: 'testuser',
|
|
|
|
|
- nickname: '测试用户',
|
|
|
|
|
- isDisabled: EnableStatus.ENABLED,
|
|
|
|
|
- roles: [{ name: 'user' }]
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- beforeEach(() => {
|
|
|
|
|
- mockUserService = {
|
|
|
|
|
- getUserByUsername: vi.fn(),
|
|
|
|
|
- verifyPassword: vi.fn(),
|
|
|
|
|
- createUser: vi.fn()
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
- authService = new AuthService(mockUserService);
|
|
|
|
|
- vi.stubEnv('JWT_SECRET', 'test-secret');
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- describe('登录', () => {
|
|
|
|
|
- it('应该成功登录', async () => {
|
|
|
|
|
- vi.mocked(mockUserService.getUserByUsername).mockResolvedValue(mockUser);
|
|
|
|
|
- vi.mocked(mockUserService.verifyPassword).mockResolvedValue(true);
|
|
|
|
|
-
|
|
|
|
|
- const result = await authService.login('testuser', 'password');
|
|
|
|
|
-
|
|
|
|
|
- expect(result.token).toBeDefined();
|
|
|
|
|
- expect(result.user).toEqual(mockUser);
|
|
|
|
|
- expect(mockUserService.getUserByUsername).toHaveBeenCalledWith('testuser');
|
|
|
|
|
- expect(mockUserService.verifyPassword).toHaveBeenCalledWith(mockUser, 'password');
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- it('用户不存在时应该抛出错误', async () => {
|
|
|
|
|
- vi.mocked(mockUserService.getUserByUsername).mockResolvedValue(null);
|
|
|
|
|
-
|
|
|
|
|
- await expect(authService.login('nonexistent', 'password'))
|
|
|
|
|
- .rejects
|
|
|
|
|
- .toThrow('用户不存在');
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- it('用户被禁用时应该抛出错误', async () => {
|
|
|
|
|
- const disabledUser = { ...mockUser, isDisabled: EnableStatus.DISABLED };
|
|
|
|
|
- vi.mocked(mockUserService.getUserByUsername).mockResolvedValue(disabledUser);
|
|
|
|
|
-
|
|
|
|
|
- await expect(authService.login('testuser', 'password'))
|
|
|
|
|
- .rejects
|
|
|
|
|
- .toThrow('用户账户已被禁用');
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- it('密码错误时应该抛出错误', async () => {
|
|
|
|
|
- vi.mocked(mockUserService.getUserByUsername).mockResolvedValue(mockUser);
|
|
|
|
|
- vi.mocked(mockUserService.verifyPassword).mockResolvedValue(false);
|
|
|
|
|
-
|
|
|
|
|
- await expect(authService.login('testuser', 'wrongpassword'))
|
|
|
|
|
- .rejects
|
|
|
|
|
- .toThrow('密码错误');
|
|
|
|
|
- });
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- describe('生成token', () => {
|
|
|
|
|
- it('应该成功生成token', () => {
|
|
|
|
|
- const token = authService.generateToken(mockUser);
|
|
|
|
|
-
|
|
|
|
|
- expect(token).toBeDefined();
|
|
|
|
|
- expect(typeof token).toBe('string');
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- it('应该使用自定义过期时间生成token', () => {
|
|
|
|
|
- const token = authService.generateToken(mockUser, '2h');
|
|
|
|
|
-
|
|
|
|
|
- expect(token).toBeDefined();
|
|
|
|
|
- });
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- describe('验证token', () => {
|
|
|
|
|
- it('应该成功验证token', () => {
|
|
|
|
|
- const token = authService.generateToken(mockUser);
|
|
|
|
|
- const payload = authService.verifyToken(token);
|
|
|
|
|
-
|
|
|
|
|
- expect(payload.id).toBe(mockUser.id);
|
|
|
|
|
- expect(payload.username).toBe(mockUser.username);
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- it('无效token应该抛出错误', () => {
|
|
|
|
|
- const invalidToken = 'invalid.token.here';
|
|
|
|
|
-
|
|
|
|
|
- expect(() => {
|
|
|
|
|
- authService.verifyToken(invalidToken);
|
|
|
|
|
- }).toThrow('无效的token');
|
|
|
|
|
- });
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- describe('权限验证', () => {
|
|
|
|
|
- it('应该验证用户有权限', () => {
|
|
|
|
|
- const hasPermission = authService.hasPermission(mockUser, 'user');
|
|
|
|
|
-
|
|
|
|
|
- expect(hasPermission).toBe(true);
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- it('应该验证用户没有权限', () => {
|
|
|
|
|
- const hasPermission = authService.hasPermission(mockUser, 'admin');
|
|
|
|
|
-
|
|
|
|
|
- expect(hasPermission).toBe(false);
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- it('应该验证用户有任意一个权限', () => {
|
|
|
|
|
- const hasAnyPermission = authService.hasAnyPermission(mockUser, ['user', 'admin']);
|
|
|
|
|
-
|
|
|
|
|
- expect(hasAnyPermission).toBe(true);
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- it('应该验证用户没有任意一个权限', () => {
|
|
|
|
|
- const hasAnyPermission = authService.hasAnyPermission(mockUser, ['admin', 'superuser']);
|
|
|
|
|
-
|
|
|
|
|
- expect(hasAnyPermission).toBe(false);
|
|
|
|
|
- });
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- describe('登出', () => {
|
|
|
|
|
- it('应该成功登出', async () => {
|
|
|
|
|
- const token = authService.generateToken(mockUser);
|
|
|
|
|
-
|
|
|
|
|
- await expect(authService.logout(token)).resolves.toBeUndefined();
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- it('无效token登出时应该抛出错误', async () => {
|
|
|
|
|
- const invalidToken = 'invalid.token.here';
|
|
|
|
|
-
|
|
|
|
|
- await expect(authService.logout(invalidToken))
|
|
|
|
|
- .rejects
|
|
|
|
|
- .toThrow('无效的token');
|
|
|
|
|
- });
|
|
|
|
|
- });
|
|
|
|
|
-});
|
|
|