- 新增auth模块处理认证逻辑 - 新增security模块处理安全相关功能 - 新增user-mgmt模块管理用户相关操作 - 新增shared模块存放共享组件 - 重构admin模块,添加DTO和Guards - 为admin模块添加测试文件结构
82 lines
2.6 KiB
Plaintext
82 lines
2.6 KiB
Plaintext
import { ExecutionContext, UnauthorizedException } from '@nestjs/common';
|
|
import { AdminCoreService, AdminAuthPayload } from '../admin_core/admin_core.service';
|
|
import { AdminGuard } from './admin.guard';
|
|
|
|
describe('AdminGuard', () => {
|
|
const payload: AdminAuthPayload = {
|
|
adminId: '1',
|
|
username: 'admin',
|
|
role: 9,
|
|
iat: 1,
|
|
exp: 2,
|
|
};
|
|
|
|
const adminCoreServiceMock: Pick<AdminCoreService, 'verifyToken'> = {
|
|
verifyToken: jest.fn(),
|
|
};
|
|
|
|
const makeContext = (authorization?: any) => {
|
|
const req: any = { headers: {} };
|
|
if (authorization !== undefined) {
|
|
req.headers['authorization'] = authorization;
|
|
}
|
|
|
|
const ctx: Partial<ExecutionContext> = {
|
|
switchToHttp: () => ({
|
|
getRequest: () => req,
|
|
getResponse: () => ({} as any),
|
|
getNext: () => ({} as any),
|
|
}),
|
|
};
|
|
|
|
return { ctx: ctx as ExecutionContext, req };
|
|
};
|
|
|
|
beforeEach(() => {
|
|
jest.resetAllMocks();
|
|
});
|
|
|
|
it('should allow access with valid admin token', () => {
|
|
(adminCoreServiceMock.verifyToken as jest.Mock).mockReturnValue(payload);
|
|
|
|
const guard = new AdminGuard(adminCoreServiceMock as AdminCoreService);
|
|
const { ctx, req } = makeContext('Bearer valid');
|
|
|
|
expect(guard.canActivate(ctx)).toBe(true);
|
|
expect(adminCoreServiceMock.verifyToken).toHaveBeenCalledWith('valid');
|
|
expect(req.admin).toEqual(payload);
|
|
});
|
|
|
|
it('should deny access without token', () => {
|
|
const guard = new AdminGuard(adminCoreServiceMock as AdminCoreService);
|
|
const { ctx } = makeContext(undefined);
|
|
|
|
expect(() => guard.canActivate(ctx)).toThrow(UnauthorizedException);
|
|
});
|
|
|
|
it('should deny access with invalid Authorization format', () => {
|
|
const guard = new AdminGuard(adminCoreServiceMock as AdminCoreService);
|
|
const { ctx } = makeContext('InvalidFormat');
|
|
|
|
expect(() => guard.canActivate(ctx)).toThrow(UnauthorizedException);
|
|
});
|
|
|
|
it('should deny access when verifyToken throws (invalid/expired)', () => {
|
|
(adminCoreServiceMock.verifyToken as jest.Mock).mockImplementation(() => {
|
|
throw new UnauthorizedException('Token已过期');
|
|
});
|
|
|
|
const guard = new AdminGuard(adminCoreServiceMock as AdminCoreService);
|
|
const { ctx } = makeContext('Bearer bad');
|
|
|
|
expect(() => guard.canActivate(ctx)).toThrow(UnauthorizedException);
|
|
});
|
|
|
|
it('should deny access when Authorization header is an array', () => {
|
|
const guard = new AdminGuard(adminCoreServiceMock as AdminCoreService);
|
|
const { ctx } = makeContext(['Bearer token']);
|
|
|
|
expect(() => guard.canActivate(ctx)).toThrow(UnauthorizedException);
|
|
});
|
|
});
|