feat: 重构业务模块架构

- 新增auth模块处理认证逻辑
- 新增security模块处理安全相关功能
- 新增user-mgmt模块管理用户相关操作
- 新增shared模块存放共享组件
- 重构admin模块,添加DTO和Guards
- 为admin模块添加测试文件结构
This commit is contained in:
moyin
2025-12-24 18:04:30 +08:00
parent 85d488a508
commit 47a738067a
35 changed files with 3667 additions and 227 deletions

81
src/business/admin/tests Normal file
View File

@@ -0,0 +1,81 @@
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);
});
});