furniture-3d-system-Wu/tests/api/feedbacks.test.ts
WuYongJie 75db836d29 feat(3D核心功能): 完成所有必需实现任务
- 文件上传验证: ModelUploader组件增强、上传API错误处理
- GLTF解析器: 增强节点提取和元数据
- 板材编辑: PanelEditor客户端验证 + panels API服务端验证
- 装配步骤编辑: 修复未使用代码,添加预览按钮
- 装配动画播放: AssemblyPlayer步骤导航边界检查优化
- 分享链接: 完整CRUD API(创建、获取、删除),含验证和过期检查

跳过可选测试任务以加快MVP开发
2025-12-22 16:18:13 +08:00

416 lines
12 KiB
TypeScript

/**
* 反馈系统 API 集成测试
*
* 测试范围:
* - 反馈创建
* - 反馈查询
* - 反馈更新
* - 反馈分配
* - 反馈状态管理
*/
import { describe, it, expect, beforeAll, afterAll } from '@jest/globals';
import { PrismaClient, FeedbackStatus, FeedbackPriority } from '@prisma/client';
import { setupTestEnvironment, cleanDatabase } from '../helpers/test-utils';
const prisma = new PrismaClient();
describe('反馈系统 API 测试', () => {
let testEnv: any;
beforeAll(async () => {
await cleanDatabase();
testEnv = await setupTestEnvironment();
});
afterAll(async () => {
await cleanDatabase();
await prisma.$disconnect();
});
describe('反馈创建', () => {
it('应该能创建产品反馈', async () => {
const feedback = await prisma.feedback.create({
data: {
title: '模型尺寸错误',
description: '沙发长度与实际尺寸不符',
category: '尺寸错误',
priority: FeedbackPriority.HIGH,
productId: testEnv.product.id,
submitterId: testEnv.users.designer.id
}
});
expect(feedback).toBeDefined();
expect(feedback.title).toBe('模型尺寸错误');
expect(feedback.status).toBe(FeedbackStatus.PENDING);
expect(feedback.priority).toBe(FeedbackPriority.HIGH);
});
it('应该能创建带 SKU 的反馈', async () => {
const feedback = await prisma.feedback.create({
data: {
title: 'SKU 图片错误',
description: '红色款式图片显示错误',
category: '图片错误',
priority: FeedbackPriority.MEDIUM,
productId: testEnv.product.id,
skuId: testEnv.sku.id,
submitterId: testEnv.users.designer.id
}
});
expect(feedback.skuId).toBe(testEnv.sku.id);
});
it('应该能添加问题截图', async () => {
const feedback = await prisma.feedback.create({
data: {
title: '材质显示异常',
description: '布艺材质渲染不正确',
category: '材质错误',
priority: FeedbackPriority.LOW,
productId: testEnv.product.id,
submitterId: testEnv.users.designer.id,
images: [
'https://example.com/screenshot1.png',
'https://example.com/screenshot2.png'
]
}
});
expect(feedback.images).toHaveLength(2);
});
});
describe('反馈查询', () => {
beforeAll(async () => {
// 创建测试数据
await prisma.feedback.create({
data: {
title: '查询测试反馈1',
description: '测试描述',
category: '模型错误',
priority: FeedbackPriority.HIGH,
status: FeedbackStatus.PENDING,
productId: testEnv.product.id,
submitterId: testEnv.users.designer.id
}
});
await prisma.feedback.create({
data: {
title: '查询测试反馈2',
description: '测试描述',
category: '尺寸错误',
priority: FeedbackPriority.MEDIUM,
status: FeedbackStatus.IN_PROGRESS,
productId: testEnv.product.id,
submitterId: testEnv.users.designer.id,
assigneeId: testEnv.users.teamLeader.id
}
});
});
it('应该能查询所有反馈', async () => {
const feedbacks = await prisma.feedback.findMany({
include: {
submitter: {
select: {
id: true,
name: true,
email: true
}
},
product: {
select: {
id: true,
name: true,
modelNumber: true
}
}
}
});
expect(feedbacks.length).toBeGreaterThan(0);
});
it('应该能按状态筛选', async () => {
const pendingFeedbacks = await prisma.feedback.findMany({
where: {
status: FeedbackStatus.PENDING
}
});
pendingFeedbacks.forEach(feedback => {
expect(feedback.status).toBe(FeedbackStatus.PENDING);
});
});
it('应该能按优先级筛选', async () => {
const highPriorityFeedbacks = await prisma.feedback.findMany({
where: {
priority: FeedbackPriority.HIGH
}
});
highPriorityFeedbacks.forEach(feedback => {
expect(feedback.priority).toBe(FeedbackPriority.HIGH);
});
});
it('应该能查询指定产品的反馈', async () => {
const productFeedbacks = await prisma.feedback.findMany({
where: {
productId: testEnv.product.id
}
});
expect(productFeedbacks.length).toBeGreaterThan(0);
productFeedbacks.forEach(feedback => {
expect(feedback.productId).toBe(testEnv.product.id);
});
});
it('应该能查询我提交的反馈', async () => {
const myFeedbacks = await prisma.feedback.findMany({
where: {
submitterId: testEnv.users.designer.id
}
});
expect(myFeedbacks.length).toBeGreaterThan(0);
myFeedbacks.forEach(feedback => {
expect(feedback.submitterId).toBe(testEnv.users.designer.id);
});
});
it('应该能查询分配给我的反馈', async () => {
const assignedFeedbacks = await prisma.feedback.findMany({
where: {
assigneeId: testEnv.users.teamLeader.id
}
});
assignedFeedbacks.forEach(feedback => {
expect(feedback.assigneeId).toBe(testEnv.users.teamLeader.id);
});
});
});
describe('反馈分配', () => {
it('应该能分配反馈给处理者', async () => {
const feedback = await prisma.feedback.create({
data: {
title: '待分配反馈',
description: '测试分配功能',
category: '其他',
priority: FeedbackPriority.MEDIUM,
productId: testEnv.product.id,
submitterId: testEnv.users.designer.id
}
});
const updatedFeedback = await prisma.feedback.update({
where: { id: feedback.id },
data: {
assigneeId: testEnv.users.teamLeader.id,
status: FeedbackStatus.IN_PROGRESS
}
});
expect(updatedFeedback.assigneeId).toBe(testEnv.users.teamLeader.id);
expect(updatedFeedback.status).toBe(FeedbackStatus.IN_PROGRESS);
});
it('应该能重新分配反馈', async () => {
const feedback = await prisma.feedback.create({
data: {
title: '重新分配测试',
description: '测试重新分配',
category: '其他',
priority: FeedbackPriority.LOW,
productId: testEnv.product.id,
submitterId: testEnv.users.designer.id,
assigneeId: testEnv.users.teamLeader.id
}
});
const updatedFeedback = await prisma.feedback.update({
where: { id: feedback.id },
data: {
assigneeId: testEnv.users.admin.id
}
});
expect(updatedFeedback.assigneeId).toBe(testEnv.users.admin.id);
});
});
describe('反馈状态管理', () => {
it('应该能更新反馈状态', async () => {
const feedback = await prisma.feedback.create({
data: {
title: '状态测试反馈',
description: '测试状态更新',
category: '其他',
priority: FeedbackPriority.MEDIUM,
productId: testEnv.product.id,
submitterId: testEnv.users.designer.id
}
});
// PENDING -> IN_PROGRESS
let updated = await prisma.feedback.update({
where: { id: feedback.id },
data: { status: FeedbackStatus.IN_PROGRESS }
});
expect(updated.status).toBe(FeedbackStatus.IN_PROGRESS);
// IN_PROGRESS -> RESOLVED
updated = await prisma.feedback.update({
where: { id: feedback.id },
data: {
status: FeedbackStatus.RESOLVED,
resolution: '问题已修复',
resolvedAt: new Date()
}
});
expect(updated.status).toBe(FeedbackStatus.RESOLVED);
expect(updated.resolution).toBe('问题已修复');
expect(updated.resolvedAt).toBeDefined();
});
it('应该能关闭反馈', async () => {
const feedback = await prisma.feedback.create({
data: {
title: '待关闭反馈',
description: '测试关闭功能',
category: '其他',
priority: FeedbackPriority.LOW,
productId: testEnv.product.id,
submitterId: testEnv.users.designer.id,
status: FeedbackStatus.RESOLVED
}
});
const closedFeedback = await prisma.feedback.update({
where: { id: feedback.id },
data: { status: FeedbackStatus.CLOSED }
});
expect(closedFeedback.status).toBe(FeedbackStatus.CLOSED);
});
});
describe('反馈评论', () => {
it('应该能添加评论', async () => {
const feedback = await prisma.feedback.create({
data: {
title: '评论测试反馈',
description: '测试评论功能',
category: '其他',
priority: FeedbackPriority.MEDIUM,
productId: testEnv.product.id,
submitterId: testEnv.users.designer.id
}
});
const comments = [
{
userId: testEnv.users.teamLeader.id,
content: '我来处理这个问题',
createdAt: new Date().toISOString()
}
];
const updatedFeedback = await prisma.feedback.update({
where: { id: feedback.id },
data: { comments }
});
expect(updatedFeedback.comments).toBeDefined();
expect(Array.isArray(updatedFeedback.comments)).toBe(true);
});
it('应该能追加评论', async () => {
const feedback = await prisma.feedback.create({
data: {
title: '追加评论测试',
description: '测试追加评论',
category: '其他',
priority: FeedbackPriority.LOW,
productId: testEnv.product.id,
submitterId: testEnv.users.designer.id,
comments: [
{
userId: testEnv.users.teamLeader.id,
content: '第一条评论',
createdAt: new Date().toISOString()
}
]
}
});
const existingComments = feedback.comments as any[];
const newComments = [
...existingComments,
{
userId: testEnv.users.designer.id,
content: '第二条评论',
createdAt: new Date().toISOString()
}
];
const updatedFeedback = await prisma.feedback.update({
where: { id: feedback.id },
data: { comments: newComments }
});
const comments = updatedFeedback.comments as any[];
expect(comments).toHaveLength(2);
});
});
describe('反馈统计', () => {
it('应该能统计各状态的反馈数量', async () => {
const statusCounts = await prisma.feedback.groupBy({
by: ['status'],
_count: true
});
expect(statusCounts.length).toBeGreaterThan(0);
statusCounts.forEach(item => {
expect(item.status).toBeDefined();
expect(item._count).toBeGreaterThan(0);
});
});
it('应该能统计各优先级的反馈数量', async () => {
const priorityCounts = await prisma.feedback.groupBy({
by: ['priority'],
_count: true
});
expect(priorityCounts.length).toBeGreaterThan(0);
priorityCounts.forEach(item => {
expect(item.priority).toBeDefined();
expect(item._count).toBeGreaterThan(0);
});
});
it('应该能统计各分类的反馈数量', async () => {
const categoryCounts = await prisma.feedback.groupBy({
by: ['category'],
_count: true
});
expect(categoryCounts.length).toBeGreaterThan(0);
categoryCounts.forEach(item => {
expect(item.category).toBeDefined();
expect(item._count).toBeGreaterThan(0);
});
});
});
});