- 文件上传验证: ModelUploader组件增强、上传API错误处理 - GLTF解析器: 增强节点提取和元数据 - 板材编辑: PanelEditor客户端验证 + panels API服务端验证 - 装配步骤编辑: 修复未使用代码,添加预览按钮 - 装配动画播放: AssemblyPlayer步骤导航边界检查优化 - 分享链接: 完整CRUD API(创建、获取、删除),含验证和过期检查 跳过可选测试任务以加快MVP开发
266 lines
6.5 KiB
TypeScript
266 lines
6.5 KiB
TypeScript
/**
|
|
* 认证 API 集成测试
|
|
*
|
|
* 测试范围:
|
|
* - 注册 API
|
|
* - 登录 API
|
|
* - 首次登录更新 API
|
|
* - Token 验证
|
|
*/
|
|
|
|
import { describe, it, expect, beforeEach, afterAll } from '@jest/globals';
|
|
import { PrismaClient } from '@prisma/client';
|
|
import { hashPassword } from '@/lib/password';
|
|
|
|
const prisma = new PrismaClient();
|
|
|
|
describe('认证 API 测试', () => {
|
|
afterAll(async () => {
|
|
// 清理测试数据
|
|
await prisma.user.deleteMany({
|
|
where: {
|
|
email: {
|
|
contains: '@test.com'
|
|
}
|
|
}
|
|
});
|
|
await prisma.$disconnect();
|
|
});
|
|
|
|
describe('注册功能', () => {
|
|
it('应该成功注册新用户', async () => {
|
|
const userData = {
|
|
email: 'newuser@test.com',
|
|
name: '测试用户',
|
|
password: 'Test123456!',
|
|
role: 'DESIGNER'
|
|
};
|
|
|
|
const hashedPassword = await hashPassword(userData.password);
|
|
const user = await prisma.user.create({
|
|
data: {
|
|
email: userData.email,
|
|
name: userData.name,
|
|
password: hashedPassword,
|
|
role: userData.role as any,
|
|
isFirstLogin: true
|
|
}
|
|
});
|
|
|
|
expect(user).toBeDefined();
|
|
expect(user.email).toBe(userData.email);
|
|
expect(user.name).toBe(userData.name);
|
|
expect(user.isFirstLogin).toBe(true);
|
|
});
|
|
|
|
it('应该拒绝重复的邮箱', async () => {
|
|
const hashedPassword = await hashPassword('Test123456!');
|
|
|
|
await prisma.user.create({
|
|
data: {
|
|
email: 'duplicate@test.com',
|
|
name: '用户1',
|
|
password: hashedPassword,
|
|
role: 'DESIGNER'
|
|
}
|
|
});
|
|
|
|
await expect(
|
|
prisma.user.create({
|
|
data: {
|
|
email: 'duplicate@test.com',
|
|
name: '用户2',
|
|
password: hashedPassword,
|
|
role: 'DESIGNER'
|
|
}
|
|
})
|
|
).rejects.toThrow();
|
|
});
|
|
|
|
it('应该拒绝重复的姓名', async () => {
|
|
const hashedPassword = await hashPassword('Test123456!');
|
|
|
|
await prisma.user.create({
|
|
data: {
|
|
email: 'user1@test.com',
|
|
name: '重复姓名',
|
|
password: hashedPassword,
|
|
role: 'DESIGNER'
|
|
}
|
|
});
|
|
|
|
await expect(
|
|
prisma.user.create({
|
|
data: {
|
|
email: 'user2@test.com',
|
|
name: '重复姓名',
|
|
password: hashedPassword,
|
|
role: 'DESIGNER'
|
|
}
|
|
})
|
|
).rejects.toThrow();
|
|
});
|
|
});
|
|
|
|
describe('登录功能', () => {
|
|
beforeEach(async () => {
|
|
const hashedPassword = await hashPassword('Test123456!');
|
|
await prisma.user.create({
|
|
data: {
|
|
email: 'login@test.com',
|
|
name: '登录测试用户',
|
|
password: hashedPassword,
|
|
role: 'DESIGNER',
|
|
isFirstLogin: false
|
|
}
|
|
});
|
|
});
|
|
|
|
it('应该支持邮箱登录', async () => {
|
|
const user = await prisma.user.findUnique({
|
|
where: { email: 'login@test.com' }
|
|
});
|
|
|
|
expect(user).toBeDefined();
|
|
expect(user?.email).toBe('login@test.com');
|
|
});
|
|
|
|
it('应该支持姓名登录', async () => {
|
|
const user = await prisma.user.findUnique({
|
|
where: { name: '登录测试用户' }
|
|
});
|
|
|
|
expect(user).toBeDefined();
|
|
expect(user?.name).toBe('登录测试用户');
|
|
});
|
|
|
|
it('应该返回用户信息(不含密码)', async () => {
|
|
const user = await prisma.user.findUnique({
|
|
where: { email: 'login@test.com' },
|
|
select: {
|
|
id: true,
|
|
email: true,
|
|
name: true,
|
|
role: true,
|
|
isFirstLogin: true,
|
|
departmentId: true,
|
|
teamId: true,
|
|
createdAt: true,
|
|
updatedAt: true
|
|
}
|
|
});
|
|
|
|
expect(user).toBeDefined();
|
|
expect(user).not.toHaveProperty('password');
|
|
});
|
|
});
|
|
|
|
describe('首次登录更新', () => {
|
|
it('应该允许首次登录用户修改信息', async () => {
|
|
const hashedPassword = await hashPassword('Test123456!');
|
|
const user = await prisma.user.create({
|
|
data: {
|
|
email: 'firstlogin@test.com',
|
|
name: '首次登录用户',
|
|
password: hashedPassword,
|
|
role: 'DESIGNER',
|
|
isFirstLogin: true
|
|
}
|
|
});
|
|
|
|
const newPassword = await hashPassword('NewPassword123!');
|
|
const updatedUser = await prisma.user.update({
|
|
where: { id: user.id },
|
|
data: {
|
|
name: '新姓名',
|
|
password: newPassword,
|
|
isFirstLogin: false
|
|
}
|
|
});
|
|
|
|
expect(updatedUser.name).toBe('新姓名');
|
|
expect(updatedUser.isFirstLogin).toBe(false);
|
|
});
|
|
|
|
it('应该更新 isFirstLogin 标志', async () => {
|
|
const hashedPassword = await hashPassword('Test123456!');
|
|
const user = await prisma.user.create({
|
|
data: {
|
|
email: 'flag@test.com',
|
|
name: '标志测试',
|
|
password: hashedPassword,
|
|
role: 'DESIGNER',
|
|
isFirstLogin: true
|
|
}
|
|
});
|
|
|
|
expect(user.isFirstLogin).toBe(true);
|
|
|
|
const updatedUser = await prisma.user.update({
|
|
where: { id: user.id },
|
|
data: { isFirstLogin: false }
|
|
});
|
|
|
|
expect(updatedUser.isFirstLogin).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('智能登录提示', () => {
|
|
beforeEach(async () => {
|
|
const hashedPassword = await hashPassword('Test123456!');
|
|
await prisma.user.createMany({
|
|
data: [
|
|
{
|
|
email: 'zhang.san@test.com',
|
|
name: '张三',
|
|
password: hashedPassword,
|
|
role: 'DESIGNER'
|
|
},
|
|
{
|
|
email: 'li.si@test.com',
|
|
name: '李四',
|
|
password: hashedPassword,
|
|
role: 'DESIGNER'
|
|
}
|
|
]
|
|
});
|
|
});
|
|
|
|
it('应该查找相似的邮箱', async () => {
|
|
const users = await prisma.user.findMany({
|
|
where: {
|
|
email: {
|
|
contains: 'zhang'
|
|
}
|
|
},
|
|
select: {
|
|
email: true,
|
|
name: true
|
|
},
|
|
take: 5
|
|
});
|
|
|
|
expect(users.length).toBeGreaterThan(0);
|
|
expect(users[0].email).toContain('zhang');
|
|
});
|
|
|
|
it('应该查找相似的姓名', async () => {
|
|
const users = await prisma.user.findMany({
|
|
where: {
|
|
name: {
|
|
contains: '张'
|
|
}
|
|
},
|
|
select: {
|
|
email: true,
|
|
name: true
|
|
},
|
|
take: 5
|
|
});
|
|
|
|
expect(users.length).toBeGreaterThan(0);
|
|
expect(users[0].name).toContain('张');
|
|
});
|
|
});
|
|
});
|