test: 添加完整测试套件(52 个文件,326 个用例)

基于 Vitest 搭建测试基础设施,覆盖后端纯函数、API 路由、
前端 hooks、UI 组件和页面级集成测试。
This commit is contained in:
2026-02-28 20:19:14 +08:00
parent 11eeec868e
commit 3ccd1262f9
59 changed files with 8131 additions and 3 deletions
@@ -0,0 +1,64 @@
import { describe, it, expect, vi, beforeEach } from "vitest";
import { prismaMock, resetPrismaMock } from "@/__tests__/helpers/prisma-mock";
import { createRequest, parseJsonResponse } from "@/__tests__/helpers/api-test-utils";
import { TEST_RESTAURANT } from "@/__tests__/helpers/fixtures";
import { GET } from "./route";
const mockCtx = { params: Promise.resolve({}) };
beforeEach(() => {
resetPrismaMock();
});
describe("GET /api/user/achievements", () => {
it("returns 401 when no userId", async () => {
const req = createRequest("/api/user/achievements");
const res = await GET(req, mockCtx);
expect(res.status).toBe(401);
});
it("returns stats and records", async () => {
prismaMock.decision.findMany.mockResolvedValue([
{
id: "dec-1",
userId: "user-1",
roomId: "room-1",
restaurantName: "测试餐厅",
restaurantData: JSON.stringify(TEST_RESTAURANT),
matchType: "unanimous",
participants: 2,
createdAt: new Date("2025-01-01"),
},
] as never);
prismaMock.weekendPlan.findMany.mockResolvedValue([
{
id: "plan-1",
planData: JSON.stringify({
days: [{ date: "周六", items: [{ activity: "逛公园" }] }],
}),
status: "completed",
roomId: "bb-room-1",
createdAt: new Date("2025-01-01"),
},
] as never);
prismaMock.blindBoxRoom.findMany.mockResolvedValue([
{ id: "bb-room-1", name: "周末", code: "ABC123" },
] as never);
const req = createRequest("/api/user/achievements?userId=user-1");
const res = await GET(req, mockCtx);
const { status, data } = await parseJsonResponse(res);
expect(status).toBe(200);
expect(data.stats.totalDecisions).toBe(1);
expect(data.stats.totalContracts).toBe(1);
expect(data.stats.completedContracts).toBe(1);
expect(data.stats.completionRate).toBe(100);
expect(data.decisions).toHaveLength(1);
expect(data.contracts).toHaveLength(1);
expect(data.contracts[0].roomName).toBe("周末");
});
});