style(auth):优化auth模块代码规范和测试覆盖
范围:src/business/auth/ - 统一命名规范和注释格式 - 完善文件头部注释和修改记录 - 分离登录和注册业务逻辑到独立服务 - 添加缺失的测试文件(JWT守卫、控制器测试) - 清理未使用的测试文件 - 优化代码结构和依赖关系
This commit is contained in:
223
src/business/auth/register.service.spec.ts
Normal file
223
src/business/auth/register.service.spec.ts
Normal file
@@ -0,0 +1,223 @@
|
||||
/**
|
||||
* RegisterService 单元测试
|
||||
*
|
||||
* 功能描述:
|
||||
* - 测试用户注册相关的业务逻辑
|
||||
* - 验证邮箱验证功能
|
||||
* - 测试Zulip账号集成
|
||||
*
|
||||
* 最近修改:
|
||||
* - 2026-01-12: 代码分离 - 从login.service.spec.ts中分离注册相关测试
|
||||
*
|
||||
* @author moyin
|
||||
* @version 1.0.0
|
||||
* @since 2026-01-12
|
||||
* @lastModified 2026-01-12
|
||||
*/
|
||||
|
||||
import { Test, TestingModule } from '@nestjs/testing';
|
||||
import { RegisterService } from './register.service';
|
||||
import { LoginCoreService } from '../../core/login_core/login_core.service';
|
||||
import { ZulipAccountService } from '../../core/zulip_core/services/zulip_account.service';
|
||||
import { ApiKeySecurityService } from '../../core/zulip_core/services/api_key_security.service';
|
||||
|
||||
describe('RegisterService', () => {
|
||||
let service: RegisterService;
|
||||
let loginCoreService: jest.Mocked<LoginCoreService>;
|
||||
let zulipAccountService: jest.Mocked<ZulipAccountService>;
|
||||
let apiKeySecurityService: jest.Mocked<ApiKeySecurityService>;
|
||||
|
||||
const mockUser = {
|
||||
id: BigInt(1),
|
||||
username: 'testuser',
|
||||
nickname: 'Test User',
|
||||
email: 'test@example.com',
|
||||
phone: null,
|
||||
avatar_url: null,
|
||||
role: 1,
|
||||
created_at: new Date(),
|
||||
updated_at: new Date(),
|
||||
password_hash: 'hashed_password',
|
||||
github_id: null,
|
||||
is_active: true,
|
||||
last_login_at: null,
|
||||
email_verified: false,
|
||||
phone_verified: false,
|
||||
};
|
||||
|
||||
beforeEach(async () => {
|
||||
const mockLoginCoreService = {
|
||||
register: jest.fn(),
|
||||
sendEmailVerification: jest.fn(),
|
||||
verifyEmailCode: jest.fn(),
|
||||
resendEmailVerification: jest.fn(),
|
||||
deleteUser: jest.fn(),
|
||||
generateTokenPair: jest.fn(),
|
||||
};
|
||||
|
||||
const mockZulipAccountService = {
|
||||
initializeAdminClient: jest.fn(),
|
||||
createZulipAccount: jest.fn(),
|
||||
linkGameAccount: jest.fn(),
|
||||
};
|
||||
|
||||
const mockZulipAccountsService = {
|
||||
findByGameUserId: jest.fn(),
|
||||
create: jest.fn(),
|
||||
deleteByGameUserId: jest.fn(),
|
||||
};
|
||||
|
||||
const mockApiKeySecurityService = {
|
||||
storeApiKey: jest.fn(),
|
||||
};
|
||||
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
RegisterService,
|
||||
{
|
||||
provide: LoginCoreService,
|
||||
useValue: mockLoginCoreService,
|
||||
},
|
||||
{
|
||||
provide: ZulipAccountService,
|
||||
useValue: mockZulipAccountService,
|
||||
},
|
||||
{
|
||||
provide: 'ZulipAccountsService',
|
||||
useValue: mockZulipAccountsService,
|
||||
},
|
||||
{
|
||||
provide: ApiKeySecurityService,
|
||||
useValue: mockApiKeySecurityService,
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
|
||||
service = module.get<RegisterService>(RegisterService);
|
||||
loginCoreService = module.get(LoginCoreService);
|
||||
zulipAccountService = module.get(ZulipAccountService);
|
||||
apiKeySecurityService = module.get(ApiKeySecurityService);
|
||||
|
||||
// 设置默认的mock返回值
|
||||
const mockTokenPair = {
|
||||
access_token: 'mock_access_token',
|
||||
refresh_token: 'mock_refresh_token',
|
||||
expires_in: 3600,
|
||||
token_type: 'Bearer',
|
||||
};
|
||||
|
||||
loginCoreService.generateTokenPair.mockResolvedValue(mockTokenPair);
|
||||
zulipAccountService.initializeAdminClient.mockResolvedValue(true);
|
||||
zulipAccountService.createZulipAccount.mockResolvedValue({
|
||||
success: true,
|
||||
userId: 123,
|
||||
email: 'test@example.com',
|
||||
apiKey: 'mock_api_key',
|
||||
isExistingUser: false
|
||||
});
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
|
||||
describe('register', () => {
|
||||
it('should handle user registration successfully', async () => {
|
||||
loginCoreService.register.mockResolvedValue({
|
||||
user: mockUser,
|
||||
isNewUser: true
|
||||
});
|
||||
|
||||
const result = await service.register({
|
||||
username: 'testuser',
|
||||
password: 'password123',
|
||||
nickname: 'Test User',
|
||||
email: 'test@example.com'
|
||||
});
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.data?.user.username).toBe('testuser');
|
||||
expect(result.data?.is_new_user).toBe(true);
|
||||
expect(loginCoreService.register).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should handle registration failure', async () => {
|
||||
loginCoreService.register.mockRejectedValue(new Error('Registration failed'));
|
||||
|
||||
const result = await service.register({
|
||||
username: 'testuser',
|
||||
password: 'password123',
|
||||
nickname: 'Test User',
|
||||
email: 'test@example.com'
|
||||
});
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.message).toContain('Registration failed');
|
||||
});
|
||||
});
|
||||
|
||||
describe('sendEmailVerification', () => {
|
||||
it('should handle sendEmailVerification in test mode', async () => {
|
||||
loginCoreService.sendEmailVerification.mockResolvedValue({
|
||||
code: '123456',
|
||||
isTestMode: true
|
||||
});
|
||||
|
||||
const result = await service.sendEmailVerification('test@example.com');
|
||||
|
||||
expect(result.success).toBe(false); // Test mode returns false
|
||||
expect(result.data?.verification_code).toBe('123456');
|
||||
expect(result.data?.is_test_mode).toBe(true);
|
||||
expect(loginCoreService.sendEmailVerification).toHaveBeenCalledWith('test@example.com');
|
||||
});
|
||||
|
||||
it('should handle sendEmailVerification in production mode', async () => {
|
||||
loginCoreService.sendEmailVerification.mockResolvedValue({
|
||||
code: '123456',
|
||||
isTestMode: false
|
||||
});
|
||||
|
||||
const result = await service.sendEmailVerification('test@example.com');
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.data?.is_test_mode).toBe(false);
|
||||
expect(loginCoreService.sendEmailVerification).toHaveBeenCalledWith('test@example.com');
|
||||
});
|
||||
});
|
||||
|
||||
describe('verifyEmailCode', () => {
|
||||
it('should handle verifyEmailCode successfully', async () => {
|
||||
loginCoreService.verifyEmailCode.mockResolvedValue(true);
|
||||
|
||||
const result = await service.verifyEmailCode('test@example.com', '123456');
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.message).toBe('邮箱验证成功');
|
||||
expect(loginCoreService.verifyEmailCode).toHaveBeenCalledWith('test@example.com', '123456');
|
||||
});
|
||||
|
||||
it('should handle invalid verification code', async () => {
|
||||
loginCoreService.verifyEmailCode.mockResolvedValue(false);
|
||||
|
||||
const result = await service.verifyEmailCode('test@example.com', '123456');
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.message).toBe('验证码错误');
|
||||
});
|
||||
});
|
||||
|
||||
describe('resendEmailVerification', () => {
|
||||
it('should handle resendEmailVerification successfully', async () => {
|
||||
loginCoreService.resendEmailVerification.mockResolvedValue({
|
||||
code: '654321',
|
||||
isTestMode: false
|
||||
});
|
||||
|
||||
const result = await service.resendEmailVerification('test@example.com');
|
||||
|
||||
expect(result.success).toBe(true);
|
||||
expect(result.data?.is_test_mode).toBe(false);
|
||||
expect(loginCoreService.resendEmailVerification).toHaveBeenCalledWith('test@example.com');
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user