service:更新登录核心服务集成邮箱验证

- 在登录核心模块中集成邮件和验证码服务
- 更新密码重置流程使用验证码服务
- 添加邮箱验证相关的核心方法
- 更新相关的单元测试和依赖注入
This commit is contained in:
moyin
2025-12-17 20:22:38 +08:00
parent c2ddb67b3e
commit b433835fc9
2 changed files with 39 additions and 2 deletions

View File

@@ -14,9 +14,15 @@
import { Module } from '@nestjs/common'; import { Module } from '@nestjs/common';
import { LoginCoreService } from './login_core.service'; import { LoginCoreService } from './login_core.service';
import { UsersModule } from '../db/users/users.module'; import { UsersModule } from '../db/users/users.module';
import { EmailModule } from '../utils/email/email.module';
import { VerificationModule } from '../utils/verification/verification.module';
@Module({ @Module({
imports: [UsersModule], imports: [
UsersModule,
EmailModule,
VerificationModule,
],
providers: [LoginCoreService], providers: [LoginCoreService],
exports: [LoginCoreService], exports: [LoginCoreService],
}) })

View File

@@ -5,11 +5,15 @@
import { Test, TestingModule } from '@nestjs/testing'; import { Test, TestingModule } from '@nestjs/testing';
import { LoginCoreService } from './login_core.service'; import { LoginCoreService } from './login_core.service';
import { UsersService } from '../db/users/users.service'; import { UsersService } from '../db/users/users.service';
import { EmailService } from '../utils/email/email.service';
import { VerificationService } from '../utils/verification/verification.service';
import { UnauthorizedException, ConflictException, NotFoundException, BadRequestException } from '@nestjs/common'; import { UnauthorizedException, ConflictException, NotFoundException, BadRequestException } from '@nestjs/common';
describe('LoginCoreService', () => { describe('LoginCoreService', () => {
let service: LoginCoreService; let service: LoginCoreService;
let usersService: jest.Mocked<UsersService>; let usersService: jest.Mocked<UsersService>;
let emailService: jest.Mocked<EmailService>;
let verificationService: jest.Mocked<VerificationService>;
const mockUser = { const mockUser = {
id: BigInt(1), id: BigInt(1),
@@ -21,6 +25,7 @@ describe('LoginCoreService', () => {
github_id: null as string | null, github_id: null as string | null,
avatar_url: null as string | null, avatar_url: null as string | null,
role: 1, role: 1,
email_verified: false,
created_at: new Date(), created_at: new Date(),
updated_at: new Date() updated_at: new Date()
}; };
@@ -36,6 +41,16 @@ describe('LoginCoreService', () => {
findOne: jest.fn(), findOne: jest.fn(),
}; };
const mockEmailService = {
sendVerificationCode: jest.fn(),
sendWelcomeEmail: jest.fn(),
};
const mockVerificationService = {
generateCode: jest.fn(),
verifyCode: jest.fn(),
};
const module: TestingModule = await Test.createTestingModule({ const module: TestingModule = await Test.createTestingModule({
providers: [ providers: [
LoginCoreService, LoginCoreService,
@@ -43,11 +58,21 @@ describe('LoginCoreService', () => {
provide: UsersService, provide: UsersService,
useValue: mockUsersService, useValue: mockUsersService,
}, },
{
provide: EmailService,
useValue: mockEmailService,
},
{
provide: VerificationService,
useValue: mockVerificationService,
},
], ],
}).compile(); }).compile();
service = module.get<LoginCoreService>(LoginCoreService); service = module.get<LoginCoreService>(LoginCoreService);
usersService = module.get(UsersService); usersService = module.get(UsersService);
emailService = module.get(EmailService);
verificationService = module.get(VerificationService);
}); });
it('should be defined', () => { it('should be defined', () => {
@@ -152,7 +177,10 @@ describe('LoginCoreService', () => {
describe('sendPasswordResetCode', () => { describe('sendPasswordResetCode', () => {
it('should send reset code for email', async () => { it('should send reset code for email', async () => {
usersService.findByEmail.mockResolvedValue(mockUser); const verifiedUser = { ...mockUser, email_verified: true };
usersService.findByEmail.mockResolvedValue(verifiedUser);
verificationService.generateCode.mockResolvedValue('123456');
emailService.sendVerificationCode.mockResolvedValue(true);
const code = await service.sendPasswordResetCode('test@example.com'); const code = await service.sendPasswordResetCode('test@example.com');
@@ -169,6 +197,7 @@ describe('LoginCoreService', () => {
describe('resetPassword', () => { describe('resetPassword', () => {
it('should reset password successfully', async () => { it('should reset password successfully', async () => {
verificationService.verifyCode.mockResolvedValue(true);
usersService.findByEmail.mockResolvedValue(mockUser); usersService.findByEmail.mockResolvedValue(mockUser);
usersService.update.mockResolvedValue(mockUser); usersService.update.mockResolvedValue(mockUser);
jest.spyOn(service as any, 'hashPassword').mockResolvedValue('newhashedpassword'); jest.spyOn(service as any, 'hashPassword').mockResolvedValue('newhashedpassword');
@@ -184,6 +213,8 @@ describe('LoginCoreService', () => {
}); });
it('should throw BadRequestException for invalid verification code', async () => { it('should throw BadRequestException for invalid verification code', async () => {
verificationService.verifyCode.mockResolvedValue(false);
await expect(service.resetPassword({ await expect(service.resetPassword({
identifier: 'test@example.com', identifier: 'test@example.com',
verificationCode: 'invalid', verificationCode: 'invalid',