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 = { verifyToken: jest.fn(), }; const makeContext = (authorization?: any) => { const req: any = { headers: {} }; if (authorization !== undefined) { req.headers['authorization'] = authorization; } const ctx: Partial = { 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); }); });