66de1dc396
- client: 全部页面接入 onShareAppMessage/onShareTimeline 分享钩子 - client: login 页增强、profile 订阅展示优化 - client/stores: 订阅字段扁平结构映射为 subInfo(plan/expiresAt/startDate) - server: auth 路由 JWT 无效/过期统一返回 401 未授权响应 - server: models/tests 同步更新
218 lines
6.3 KiB
JavaScript
Executable File
218 lines
6.3 KiB
JavaScript
Executable File
/**
|
|
* 认证 API 集成测试
|
|
*/
|
|
|
|
const request = require('supertest')
|
|
const mongoose = require('mongoose')
|
|
const app = require('../../src/index')
|
|
const User = require('../../src/models/User')
|
|
const Admin = require('../../src/models/Admin')
|
|
|
|
describe('Auth API', () => {
|
|
beforeAll(async () => {
|
|
// 连接测试数据库
|
|
const mongoURI = process.env.MONGODB_URI || 'mongodb://localhost:27017/wdkj_test'
|
|
if (mongoose.connection.readyState === 0) {
|
|
await mongoose.connect(mongoURI)
|
|
}
|
|
// 确保唯一索引已构建(dropDatabase 后 mongoose 不会自动重建)
|
|
await mongoose.connection.syncIndexes()
|
|
})
|
|
|
|
afterAll(async () => {
|
|
// 清理并关闭连接
|
|
if (mongoose.connection.readyState !== 0) {
|
|
// 防呆:只允许在测试库中 dropDatabase
|
|
if (mongoose.connection.name === 'wdkj') {
|
|
throw new Error('[安全] 不允许对生产数据库 wdkj 执行 dropDatabase')
|
|
}
|
|
await mongoose.connection.dropDatabase()
|
|
await mongoose.connection.close()
|
|
}
|
|
})
|
|
|
|
beforeEach(async () => {
|
|
// 每个测试前清空集合
|
|
await User.deleteMany({})
|
|
await Admin.deleteMany({})
|
|
})
|
|
|
|
describe('POST /api/auth/login', () => {
|
|
test('新用户应该成功注册', async () => {
|
|
const response = await request(app)
|
|
.post('/api/auth/login')
|
|
.send({
|
|
openid: 'new_user_openid',
|
|
userInfo: {
|
|
nickName: '新用户',
|
|
avatarUrl: 'https://example.com/avatar.jpg'
|
|
}
|
|
})
|
|
|
|
expect(response.status).toBe(200)
|
|
expect(response.body.success).toBe(true)
|
|
expect(response.body.data.isNewUser).toBe(true)
|
|
expect(response.body.data.openid).toBe('new_user_openid')
|
|
expect(response.body.data.token).toBeDefined()
|
|
})
|
|
|
|
test('老用户应该成功登录', async () => {
|
|
// 先创建一个用户
|
|
await User.create({
|
|
openid: 'existing_user_openid',
|
|
nickName: '老用户',
|
|
totalScore: 100
|
|
})
|
|
|
|
const response = await request(app)
|
|
.post('/api/auth/login')
|
|
.send({
|
|
openid: 'existing_user_openid',
|
|
userInfo: {
|
|
nickName: '老用户新名字'
|
|
}
|
|
})
|
|
|
|
expect(response.status).toBe(200)
|
|
expect(response.body.success).toBe(true)
|
|
expect(response.body.data.isNewUser).toBe(false)
|
|
expect(response.body.data.openid).toBe('existing_user_openid')
|
|
})
|
|
|
|
test('缺少 openid 应该返回错误', async () => {
|
|
const response = await request(app)
|
|
.post('/api/auth/login')
|
|
.send({
|
|
userInfo: {
|
|
nickName: '测试用户'
|
|
}
|
|
})
|
|
|
|
expect(response.status).toBe(400)
|
|
expect(response.body.success).toBe(false)
|
|
})
|
|
})
|
|
|
|
describe('POST /api/auth/admin/login', () => {
|
|
beforeEach(async () => {
|
|
// 创建测试管理员
|
|
const admin = new Admin({
|
|
username: 'testadmin',
|
|
password: 'password123',
|
|
role: 'super_admin',
|
|
status: 'active'
|
|
})
|
|
await admin.save()
|
|
})
|
|
|
|
test('管理员应该成功登录', async () => {
|
|
const response = await request(app)
|
|
.post('/api/auth/admin/login')
|
|
.send({
|
|
username: 'testadmin',
|
|
password: 'password123'
|
|
})
|
|
|
|
expect(response.status).toBe(200)
|
|
expect(response.body.success).toBe(true)
|
|
expect(response.body.data.token).toBeDefined()
|
|
expect(response.body.data.username).toBe('testadmin')
|
|
expect(response.body.data.role).toBe('super_admin')
|
|
})
|
|
|
|
test('错误的密码应该返回401', async () => {
|
|
const response = await request(app)
|
|
.post('/api/auth/admin/login')
|
|
.send({
|
|
username: 'testadmin',
|
|
password: 'wrongpassword'
|
|
})
|
|
|
|
expect(response.status).toBe(401)
|
|
expect(response.body.success).toBe(false)
|
|
})
|
|
|
|
test('不存在的用户应该返回401', async () => {
|
|
const response = await request(app)
|
|
.post('/api/auth/admin/login')
|
|
.send({
|
|
username: 'nonexistent',
|
|
password: 'password123'
|
|
})
|
|
|
|
expect(response.status).toBe(401)
|
|
expect(response.body.success).toBe(false)
|
|
})
|
|
|
|
test('禁用的账户应该返回403', async () => {
|
|
// 创建禁用的管理员
|
|
const disabledAdmin = new Admin({
|
|
username: 'disabled',
|
|
password: 'password123',
|
|
role: 'viewer',
|
|
status: 'inactive'
|
|
})
|
|
await disabledAdmin.save()
|
|
|
|
const response = await request(app)
|
|
.post('/api/auth/admin/login')
|
|
.send({
|
|
username: 'disabled',
|
|
password: 'password123'
|
|
})
|
|
|
|
expect(response.status).toBe(403)
|
|
expect(response.body.success).toBe(false)
|
|
})
|
|
})
|
|
|
|
describe('GET /api/auth/me', () => {
|
|
let userToken
|
|
let testUser
|
|
|
|
beforeEach(async () => {
|
|
// 创建测试用户并获取token
|
|
testUser = await User.create({
|
|
openid: 'test_user_openid',
|
|
nickName: '测试用户',
|
|
totalScore: 500
|
|
})
|
|
|
|
// 登录获取token
|
|
const loginResponse = await request(app)
|
|
.post('/api/auth/login')
|
|
.send({ openid: 'test_user_openid' })
|
|
|
|
userToken = loginResponse.body.data.token
|
|
})
|
|
|
|
test('应该返回当前用户信息', async () => {
|
|
const response = await request(app)
|
|
.get('/api/auth/me')
|
|
.set('Authorization', `Bearer ${userToken}`)
|
|
|
|
expect(response.status).toBe(200)
|
|
expect(response.body.success).toBe(true)
|
|
expect(response.body.data.openid).toBe('test_user_openid')
|
|
expect(response.body.data.nickName).toBe('测试用户')
|
|
})
|
|
|
|
test('缺少 token 应该返回401', async () => {
|
|
const response = await request(app)
|
|
.get('/api/auth/me')
|
|
|
|
expect(response.status).toBe(401)
|
|
expect(response.body.success).toBe(false)
|
|
})
|
|
|
|
test('不存在的用户应该返回401', async () => {
|
|
const response = await request(app)
|
|
.get('/api/auth/me')
|
|
.set('Authorization', 'Bearer invalid_token')
|
|
|
|
expect(response.status).toBe(401)
|
|
expect(response.body.success).toBe(false)
|
|
})
|
|
})
|
|
})
|