refactor(docs): 简化README结构,更新技术栈和项目结构描述

This commit is contained in:
2025-09-20 15:19:59 +08:00
parent cec08f89e2
commit b8c9e5c959
54 changed files with 14343 additions and 6124 deletions

View 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);
});
});
});