refactor(docs): 简化README结构,更新技术栈和项目结构描述
This commit is contained in:
261
backend/tests/integration/auth.test.js
Normal file
261
backend/tests/integration/auth.test.js
Normal file
@@ -0,0 +1,261 @@
|
||||
const request = require('supertest');
|
||||
const testSequelize = require('../test-database');
|
||||
|
||||
// 创建测试专用的User模型
|
||||
const { DataTypes } = require('sequelize');
|
||||
const User = testSequelize.define('User', {
|
||||
id: {
|
||||
type: DataTypes.INTEGER,
|
||||
primaryKey: true,
|
||||
autoIncrement: true,
|
||||
comment: '用户ID'
|
||||
},
|
||||
nickname: {
|
||||
type: DataTypes.STRING(50),
|
||||
allowNull: false,
|
||||
comment: '用户昵称'
|
||||
},
|
||||
phone: {
|
||||
type: DataTypes.STRING(20),
|
||||
allowNull: true,
|
||||
unique: true,
|
||||
comment: '手机号码'
|
||||
},
|
||||
password_hash: {
|
||||
type: DataTypes.STRING(255),
|
||||
allowNull: true,
|
||||
comment: '密码哈希值'
|
||||
},
|
||||
user_type: {
|
||||
type: DataTypes.ENUM('buyer', 'trader', 'supplier', 'driver', 'staff', 'admin'),
|
||||
allowNull: false,
|
||||
defaultValue: 'buyer',
|
||||
comment: '用户类型'
|
||||
}
|
||||
}, {
|
||||
tableName: 'users',
|
||||
timestamps: true,
|
||||
createdAt: 'created_at',
|
||||
updatedAt: 'updated_at'
|
||||
});
|
||||
|
||||
// 创建测试专用的app实例
|
||||
const createTestApp = () => {
|
||||
// 确保测试环境
|
||||
process.env.NODE_ENV = 'test';
|
||||
|
||||
// 导入app但不启动服务器
|
||||
const app = require('../../src/main');
|
||||
return app;
|
||||
};
|
||||
|
||||
describe('Authentication Integration Tests', () => {
|
||||
let app;
|
||||
let testUser;
|
||||
let authToken;
|
||||
|
||||
beforeAll(async () => {
|
||||
// 创建测试app
|
||||
app = createTestApp();
|
||||
|
||||
// 同步测试数据库
|
||||
await testSequelize.sync({ force: true });
|
||||
|
||||
// 创建测试用户 - 使用User模型中实际存在的字段
|
||||
testUser = await User.create({
|
||||
nickname: 'Test User', // 必填字段
|
||||
phone: '13800138000', // 可选字段
|
||||
password_hash: 'testpassword123', // 可选字段
|
||||
user_type: 'buyer' // 必填字段,默认值
|
||||
});
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
// 清理测试数据
|
||||
if (testUser) {
|
||||
await testUser.destroy();
|
||||
}
|
||||
|
||||
// 关闭测试数据库连接
|
||||
await testSequelize.close();
|
||||
});
|
||||
|
||||
describe('POST /api/auth/login', () => {
|
||||
it('应该成功登录并返回token', async () => {
|
||||
const response = await request(app)
|
||||
.post('/api/auth/login')
|
||||
.send({
|
||||
username: '13800138000', // 使用phone登录
|
||||
password: 'testpassword123'
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
expect(response.body.success).toBe(true);
|
||||
expect(response.body.message).toBe('登录成功');
|
||||
expect(response.body.data).toHaveProperty('access_token');
|
||||
expect(response.body.data).toHaveProperty('user');
|
||||
expect(response.body.data.user.username).toBe('Test User');
|
||||
expect(response.body.data.user).not.toHaveProperty('password');
|
||||
|
||||
// 保存token用于后续测试
|
||||
authToken = response.body.data.access_token;
|
||||
|
||||
// 保存token用于后续测试
|
||||
authToken = response.body.data.access_token;
|
||||
});
|
||||
|
||||
it('应该在用户名不存在时返回错误', async () => {
|
||||
const response = await request(app)
|
||||
.post('/api/auth/login')
|
||||
.send({
|
||||
username: 'nonexistent',
|
||||
password: 'testpassword123'
|
||||
})
|
||||
.expect(401);
|
||||
|
||||
expect(response.body.success).toBe(false);
|
||||
expect(response.body.message).toBe('用户名或密码错误');
|
||||
});
|
||||
|
||||
it('应该在密码错误时返回错误', async () => {
|
||||
const response = await request(app)
|
||||
.post('/api/auth/login')
|
||||
.send({
|
||||
username: '13800138000',
|
||||
password: 'wrongpassword'
|
||||
})
|
||||
.expect(401);
|
||||
|
||||
expect(response.body.success).toBe(false);
|
||||
expect(response.body.message).toBe('用户名或密码错误');
|
||||
});
|
||||
|
||||
it('应该在缺少参数时返回错误', async () => {
|
||||
const response = await request(app)
|
||||
.post('/api/auth/login')
|
||||
.send({
|
||||
username: '13800138000'
|
||||
// 缺少password
|
||||
})
|
||||
.expect(400);
|
||||
|
||||
expect(response.body.success).toBe(false);
|
||||
expect(response.body.message).toBe('用户名和密码不能为空');
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /api/auth/logout', () => {
|
||||
it('应该成功登出', async () => {
|
||||
// 先登录获取token
|
||||
const loginResponse = await request(app)
|
||||
.post('/api/auth/login')
|
||||
.send({
|
||||
username: '13800138000',
|
||||
password: 'testpassword123'
|
||||
});
|
||||
|
||||
const token = loginResponse.body.data.access_token;
|
||||
|
||||
const response = await request(app)
|
||||
.post('/api/auth/logout')
|
||||
.set('Authorization', `Bearer ${token}`)
|
||||
.expect(200);
|
||||
|
||||
expect(response.body.success).toBe(true);
|
||||
expect(response.body.message).toBe('登出成功');
|
||||
});
|
||||
|
||||
it('应该在没有认证时也能成功登出', async () => {
|
||||
const response = await request(app)
|
||||
.post('/api/auth/logout')
|
||||
.expect(401); // 因为没有提供token,应该返回401
|
||||
|
||||
expect(response.body.success).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('GET /api/auth/current', () => {
|
||||
it('应该返回当前用户信息', async () => {
|
||||
// 先登录获取token
|
||||
const loginResponse = await request(app)
|
||||
.post('/api/auth/login')
|
||||
.send({
|
||||
username: '13800138000',
|
||||
password: 'testpassword123'
|
||||
});
|
||||
|
||||
const token = loginResponse.body.data.access_token;
|
||||
|
||||
const response = await request(app)
|
||||
.get('/api/auth/current')
|
||||
.set('Authorization', `Bearer ${token}`)
|
||||
.expect(200);
|
||||
|
||||
expect(response.body.success).toBe(true);
|
||||
expect(response.body.data).toHaveProperty('id');
|
||||
expect(response.body.data).toHaveProperty('username');
|
||||
expect(response.body.data).not.toHaveProperty('password');
|
||||
});
|
||||
|
||||
it('应该在没有认证时返回错误', async () => {
|
||||
const response = await request(app)
|
||||
.get('/api/auth/current')
|
||||
.expect(401);
|
||||
|
||||
expect(response.body.success).toBe(false);
|
||||
});
|
||||
|
||||
it('应该在token无效时返回错误', async () => {
|
||||
const response = await request(app)
|
||||
.get('/api/auth/current')
|
||||
.set('Authorization', 'Bearer invalid_token')
|
||||
.expect(401);
|
||||
|
||||
expect(response.body.success).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /api/auth/mini-program/login', () => {
|
||||
it('应该成功进行小程序登录', async () => {
|
||||
const response = await request(app)
|
||||
.post('/api/auth/mini-program/login')
|
||||
.send({
|
||||
phone: '13900139000',
|
||||
code: '123456',
|
||||
miniProgramType: 'client'
|
||||
})
|
||||
.expect(200);
|
||||
|
||||
expect(response.body.success).toBe(true);
|
||||
expect(response.body.message).toBe('登录成功');
|
||||
expect(response.body.data).toHaveProperty('token');
|
||||
expect(response.body.data).toHaveProperty('userInfo');
|
||||
});
|
||||
|
||||
it('应该在验证码错误时返回错误', async () => {
|
||||
const response = await request(app)
|
||||
.post('/api/auth/mini-program/login')
|
||||
.send({
|
||||
phone: '13900139000',
|
||||
code: '000000', // 错误的验证码
|
||||
miniProgramType: 'client'
|
||||
})
|
||||
.expect(400);
|
||||
|
||||
expect(response.body.success).toBe(false);
|
||||
expect(response.body.message).toBe('验证码错误');
|
||||
});
|
||||
|
||||
it('应该在缺少参数时返回错误', async () => {
|
||||
const response = await request(app)
|
||||
.post('/api/auth/mini-program/login')
|
||||
.send({
|
||||
phone: '13900139000'
|
||||
// 缺少code和miniProgramType
|
||||
})
|
||||
.expect(400);
|
||||
|
||||
expect(response.body.success).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user