test: decouple unit tests from mock fixtures

This commit is contained in:
zetaloop
2026-03-01 22:30:05 +08:00
parent 9e64fb1201
commit 6ee14f6eef
2 changed files with 231 additions and 21 deletions
+17 -7
View File
@@ -1,18 +1,25 @@
import { createPaidOrder } from "@/lib/api/orders" import { createPaidOrder } from "@/lib/api/orders"
import { useAuthStore } from "@/store/auth" import { describe, expect, it, vi } from "vitest"
import { describe, expect, it } from "vitest"
describe("lib/api/orders", () => { describe("lib/api/orders", () => {
it("returns { decision: { ok:false, error:{code,msg} } } when unauthenticated", async () => { 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( try {
createPaidOrder({ const res = await createPaidOrder({
playerId: "1005", playerId: "1005",
serviceId: "5001", serviceId: "5001",
quantity: 1, quantity: 1,
}), })
)
expect(res).toEqual({ expect(res).toEqual({
decision: { decision: {
@@ -20,5 +27,8 @@ describe("lib/api/orders", () => {
error: { code: 401, msg: "请先登录" }, error: { code: 401, msg: "请先登录" },
}, },
}) })
} finally {
vi.unstubAllGlobals()
}
}) })
}) })
+208 -8
View File
@@ -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 type { SearchCatalogData } from "@/lib/search/search-catalog"
import { searchCatalog } from "@/lib/search/search-catalog" import { searchCatalog } from "@/lib/search/search-catalog"
import { describe, expect, it } from "vitest" 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 = { const data: SearchCatalogData = {
players: mockPlayers, players,
shops: mockShops, shops,
services: mockServices, services,
} }
describe("searchCatalog", () => { describe("searchCatalog", () => {
@@ -46,7 +246,7 @@ describe("searchCatalog", () => {
it("returns all items when q is empty", () => { it("returns all items when q is empty", () => {
const res = searchCatalog({ limit: 50 }, data) 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.limit).toBe(2)
expect(res.meta.offset).toBe(0) expect(res.meta.offset).toBe(0)
expect(res.items.length).toBe(2) 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", () => { it("offset skips items", () => {