/** * 登录功能端到端测试 */ import { Test, TestingModule } from '@nestjs/testing'; import { INestApplication } from '@nestjs/common'; import * as request from 'supertest'; import { AppModule } from '../../src/app.module'; describe('Login (e2e)', () => { let app: INestApplication; beforeEach(async () => { const moduleFixture: TestingModule = await Test.createTestingModule({ imports: [AppModule], }).compile(); app = moduleFixture.createNestApplication(); await app.init(); }); afterEach(async () => { await app.close(); }); describe('/auth/register (POST)', () => { it('should register a new user', () => { return request(app.getHttpServer()) .post('/auth/register') .send({ username: 'testuser' + Date.now(), password: 'password123', nickname: '测试用户', email: `test${Date.now()}@example.com` }) .expect(201) .expect((res) => { expect(res.body.success).toBe(true); expect(res.body.data.user.username).toBeDefined(); expect(res.body.data.access_token).toBeDefined(); }); }); it('should return error for invalid password', () => { return request(app.getHttpServer()) .post('/auth/register') .send({ username: 'testuser', password: '123', // 密码太短 nickname: '测试用户' }) .expect(400); }); }); describe('/auth/login (POST)', () => { it('should login with valid credentials', async () => { // 先注册用户 const username = 'logintest' + Date.now(); await request(app.getHttpServer()) .post('/auth/register') .send({ username, password: 'password123', nickname: '登录测试用户' }); // 然后登录 return request(app.getHttpServer()) .post('/auth/login') .send({ identifier: username, password: 'password123' }) .expect(200) .expect((res) => { expect(res.body.success).toBe(true); expect(res.body.data.user.username).toBe(username); expect(res.body.data.access_token).toBeDefined(); }); }); it('should return error for invalid credentials', () => { return request(app.getHttpServer()) .post('/auth/login') .send({ identifier: 'nonexistent', password: 'wrongpassword' }) .expect(200) // 业务层返回200,但success为false .expect((res) => { expect(res.body.success).toBe(false); expect(res.body.error_code).toBe('LOGIN_FAILED'); }); }); }); describe('/auth/github (POST)', () => { it('should handle GitHub OAuth login', () => { return request(app.getHttpServer()) .post('/auth/github') .send({ github_id: 'github' + Date.now(), username: 'githubuser' + Date.now(), nickname: 'GitHub用户', email: `github${Date.now()}@example.com`, avatar_url: 'https://avatars.githubusercontent.com/u/123456' }) .expect(200) .expect((res) => { expect(res.body.success).toBe(true); expect(res.body.data.user.username).toBeDefined(); expect(res.body.data.is_new_user).toBe(true); }); }); }); describe('/auth/forgot-password (POST)', () => { it('should send password reset code', async () => { // 先注册用户 const email = `reset${Date.now()}@example.com`; await request(app.getHttpServer()) .post('/auth/register') .send({ username: 'resettest' + Date.now(), password: 'password123', nickname: '重置测试用户', email }); // 发送重置验证码 return request(app.getHttpServer()) .post('/auth/forgot-password') .send({ identifier: email }) .expect(200) .expect((res) => { expect(res.body.success).toBe(true); expect(res.body.data.verification_code).toMatch(/^\d{6}$/); }); }); }); describe('/auth/reset-password (POST)', () => { it('should reset password with valid code', async () => { // 先注册用户 const email = `resetpwd${Date.now()}@example.com`; await request(app.getHttpServer()) .post('/auth/register') .send({ username: 'resetpwdtest' + Date.now(), password: 'password123', nickname: '重置密码测试用户', email }); // 获取验证码 const codeResponse = await request(app.getHttpServer()) .post('/auth/forgot-password') .send({ identifier: email }); const verificationCode = codeResponse.body.data.verification_code; // 重置密码 return request(app.getHttpServer()) .post('/auth/reset-password') .send({ identifier: email, verification_code: verificationCode, new_password: 'newpassword123' }) .expect(200) .expect((res) => { expect(res.body.success).toBe(true); expect(res.body.message).toBe('密码重置成功'); }); }); }); });