Files
whale-town-end/src/business/auth/register.service.spec.ts
moyin 9f4d291619 style(auth): 优化auth模块代码规范
范围: src/business/auth/
- register.service.ts: 清理未使用的导入TokenPair,增强userId非空验证
- register.service.spec.ts: 清理未使用的变量apiKeySecurityService
2026-01-15 14:17:38 +08:00

222 lines
6.8 KiB
TypeScript

/**
* RegisterService 单元测试
*
* 功能描述:
* - 测试用户注册相关的业务逻辑
* - 验证邮箱验证功能
* - 测试Zulip账号集成
*
* 最近修改:
* - 2026-01-15: 代码规范优化 - 清理未使用的变量apiKeySecurityService (修改者: moyin)
* - 2026-01-12: 代码分离 - 从login.service.spec.ts中分离注册相关测试
*
* @author moyin
* @version 1.0.1
* @since 2026-01-12
* @lastModified 2026-01-15
*/
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>;
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);
// 设置默认的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');
});
});
});