From 6ee14f6eef9148d9cab61253aeae7780c336ec8b Mon Sep 17 00:00:00 2001 From: zetaloop Date: Sun, 1 Mar 2026 22:30:05 +0800 Subject: [PATCH] test: decouple unit tests from mock fixtures --- tests/orders-api.test.ts | 36 +++--- tests/search-catalog.test.ts | 216 +++++++++++++++++++++++++++++++++-- 2 files changed, 231 insertions(+), 21 deletions(-) diff --git a/tests/orders-api.test.ts b/tests/orders-api.test.ts index 414f8df..40ded67 100644 --- a/tests/orders-api.test.ts +++ b/tests/orders-api.test.ts @@ -1,24 +1,34 @@ import { createPaidOrder } from "@/lib/api/orders" -import { useAuthStore } from "@/store/auth" -import { describe, expect, it } from "vitest" +import { describe, expect, it, vi } from "vitest" describe("lib/api/orders", () => { it("returns { decision: { ok:false, error:{code,msg} } } when unauthenticated", async () => { - useAuthStore.getState().logout() + vi.stubGlobal( + "fetch", + vi.fn( + async () => + new Response(JSON.stringify({ code: 401, msg: "请先登录" }), { + status: 401, + headers: { "Content-Type": "application/json" }, + }), + ), + ) - const res = await Promise.resolve( - createPaidOrder({ + try { + const res = await createPaidOrder({ playerId: "1005", serviceId: "5001", quantity: 1, - }), - ) + }) - expect(res).toEqual({ - decision: { - ok: false, - error: { code: 401, msg: "请先登录" }, - }, - }) + expect(res).toEqual({ + decision: { + ok: false, + error: { code: 401, msg: "请先登录" }, + }, + }) + } finally { + vi.unstubAllGlobals() + } }) }) diff --git a/tests/search-catalog.test.ts b/tests/search-catalog.test.ts index 5e09647..eb16878 100644 --- a/tests/search-catalog.test.ts +++ b/tests/search-catalog.test.ts @@ -1,14 +1,214 @@ -import { mockPlayers } from "@/lib/mock/players" -import { mockServices } from "@/lib/mock/services" -import { mockShops } from "@/lib/mock/shops" import type { SearchCatalogData } from "@/lib/search/search-catalog" import { searchCatalog } from "@/lib/search/search-catalog" import { describe, expect, it } from "vitest" +const createdAt = "2025-01-01T00:00:00.000Z" + +const players: SearchCatalogData["players"] = [ + { + id: "1006", + user: { + id: "2006", + username: "u1006", + nickname: "Winter", + avatar: "/avatars/u1006.png", + role: "player", + createdAt, + }, + rating: 4.8, + totalOrders: 120, + completionRate: 0.98, + status: "available", + games: ["王者荣耀"], + services: [ + { + id: "s-1006-wzry", + playerId: "1006", + gameId: "g-wzry", + gameName: "王者荣耀", + title: "王者荣耀陪练", + description: "", + price: 30, + unit: "局", + availability: ["weekends"], + }, + ], + shopId: "3002", + tags: ["moba"], + }, + { + id: "1007", + user: { + id: "2007", + username: "u1007", + nickname: "u7", + avatar: "/avatars/u1007.png", + role: "player", + createdAt, + }, + rating: 4.0, + totalOrders: 20, + completionRate: 0.9, + status: "busy", + games: ["英雄联盟"], + services: [ + { + id: "s-1007-lol", + playerId: "1007", + gameId: "g-lol", + gameName: "英雄联盟", + title: "英雄联盟陪练", + description: "", + price: 18, + unit: "局", + availability: ["weekdays"], + }, + ], + shopId: "3003", + tags: [], + }, + { + id: "1008", + user: { + id: "2008", + username: "u1008", + nickname: "Ace", + avatar: "/avatars/u1008.png", + role: "player", + createdAt, + }, + rating: 4.7, + totalOrders: 80, + completionRate: 0.97, + status: "available", + games: ["CS2"], + services: [ + { + id: "s-1008-cs2", + playerId: "1008", + gameId: "g-cs2", + gameName: "CS2", + title: "CS2代练", + description: "", + price: 10, + unit: "局", + availability: ["weekends"], + }, + ], + shopId: "3001", + tags: ["fps"], + }, + { + id: "1009", + user: { + id: "2009", + username: "u1009", + nickname: "u9", + avatar: "/avatars/u1009.png", + role: "player", + createdAt, + }, + rating: 3.5, + totalOrders: 5, + completionRate: 0.85, + status: "offline", + games: ["英雄联盟"], + services: [ + { + id: "s-1009-lol", + playerId: "1009", + gameId: "g-lol", + gameName: "英雄联盟", + title: "英雄联盟陪练", + description: "", + price: 12, + unit: "局", + availability: ["weekends"], + }, + ], + shopId: "3003", + tags: [], + }, +] + +const shops: SearchCatalogData["shops"] = [ + { + id: "3001", + owner: { + id: "4001", + username: "owner3001", + nickname: "Owner 3001", + avatar: "/avatars/owner3001.png", + role: "owner", + createdAt, + }, + name: "CS2 Hub", + description: "", + rating: 4.6, + totalOrders: 300, + playerCount: 1, + commissionType: "fixed", + commissionValue: 0, + allowMultiShop: false, + allowIndependentOrders: true, + dispatchMode: "manual", + announcements: [], + templateConfig: { sections: [] }, + }, + { + id: "3002", + owner: { + id: "4002", + username: "owner3002", + nickname: "Owner 3002", + avatar: "/avatars/owner3002.png", + role: "owner", + createdAt, + }, + name: "Yuki Studio", + description: "", + rating: 4.2, + totalOrders: 50, + playerCount: 1, + commissionType: "fixed", + commissionValue: 0, + allowMultiShop: false, + allowIndependentOrders: true, + dispatchMode: "manual", + announcements: [], + templateConfig: { sections: [] }, + }, + { + id: "3003", + owner: { + id: "4003", + username: "owner3003", + nickname: "Owner 3003", + avatar: "/avatars/owner3003.png", + role: "owner", + createdAt, + }, + name: "Quiet Shop", + description: "", + rating: 3.8, + totalOrders: 10, + playerCount: 2, + commissionType: "fixed", + commissionValue: 0, + allowMultiShop: false, + allowIndependentOrders: true, + dispatchMode: "manual", + announcements: [], + templateConfig: { sections: [] }, + }, +] + +const services: SearchCatalogData["services"] = players.flatMap((p) => p.services) + const data: SearchCatalogData = { - players: mockPlayers, - shops: mockShops, - services: mockServices, + players, + shops, + services, } describe("searchCatalog", () => { @@ -46,7 +246,7 @@ describe("searchCatalog", () => { it("returns all items when q is empty", () => { const res = searchCatalog({ limit: 50 }, data) - expect(res.meta.total).toBe(mockPlayers.length + mockShops.length) + expect(res.meta.total).toBe(players.length + shops.length) }) }) @@ -194,7 +394,7 @@ describe("searchCatalog", () => { expect(res.meta.limit).toBe(2) expect(res.meta.offset).toBe(0) expect(res.items.length).toBe(2) - expect(res.meta.total).toBe(mockPlayers.length + mockShops.length) + expect(res.meta.total).toBe(players.length + shops.length) }) it("offset skips items", () => {