import test from "node:test"; import assert from "node:assert/strict"; import { existsSync } from "node:fs"; import { readFile } from "node:fs/promises"; import { registerHooks } from "node:module"; const functionUrl = new URL("../functions/drawCat.ts", import.meta.url); const configUrl = new URL("../functions/drawCat.yaml", import.meta.url); const state = { user: null, collections: [], updates: [], }; globalThis.__drawCatCloudMock = { database() { return { collection(name) { state.collections.push(name); return { where() { return { async getOne() { return { data: state.user }; }, async update(payload) { state.updates.push(payload); return {}; }, }; }, }; }, }; }, }; globalThis.__drawCatUtilsMock = { checkToken(received, expected) { return received === expected; }, }; registerHooks({ resolve(specifier, context, nextResolve) { if (specifier === "@lafjs/cloud") { return { url: "data:text/javascript,export default globalThis.__drawCatCloudMock", shortCircuit: true, }; } if (specifier === "@/Utils") { return { url: "data:text/javascript,export default globalThis.__drawCatUtilsMock", shortCircuit: true, }; } return nextResolve(specifier, context); }, }); let drawCat; async function getDrawCat() { if (!drawCat) { ({ default: drawCat } = await import(functionUrl)); } return drawCat; } function reset(user) { state.user = user; state.collections.length = 0; state.updates.length = 0; } async function drawWithRandom(randomValues, body) { const handler = await getDrawCat(); const originalRandom = Math.random; const values = [...randomValues]; Math.random = () => values.shift() ?? 0; try { return await handler({ body }); } finally { Math.random = originalRandom; } } test("drawCat cloud function and configuration exist", async () => { assert.equal(existsSync(functionUrl), true); assert.equal(existsSync(configUrl), true); const yaml = await readFile(configUrl, "utf8"); assert.match(yaml, /^name:\s*drawCat$/m); }); test("draws an ordinary cat with weight 150 and charges 5 film", async () => { reset({ _id: "u1", token: "secret", film: 100 }); const result = await drawWithRandom([0, 0], { uid: "u1", token: "secret", }); assert.equal(result.code, 1); assert.equal(result.data.reward, 4); assert.equal(result.data.film, 95); assert.deepEqual(result.data.catArr, [1, 2, 3, 4]); assert.deepEqual(state.updates, [ { catArr: [1, 2, 3, 4], film: 95 }, ]); }); test("draws a rare cat from the 50-weight range", async () => { reset({ _id: "u1", token: "secret", film: 100 }); const result = await drawWithRandom([750.1 / 858, 0.99], { uid: "u1", token: "secret", }); assert.equal(result.data.reward, 10); assert.deepEqual(result.data.catArr, [1, 2, 3, 10]); }); test("drawing cat 11 adds only cat 11", async () => { reset({ _id: "u1", token: "secret", film: 100 }); const result = await drawWithRandom([850.1 / 858, 0], { uid: "u1", token: "secret", }); assert.equal(result.data.reward, 11); assert.deepEqual(result.data.catArr, [1, 2, 3, 11]); assert.deepEqual(state.updates, [ { catArr: [1, 2, 3, 11], film: 95 }, ]); }); test("excludes owned cats and uses the next film cost", async () => { reset({ _id: "u1", token: "secret", film: 100, catArr: [1, 2, 3, 4], }); const result = await drawWithRandom([0, 0], { uid: "u1", token: "secret", }); assert.equal(result.data.reward, 5); assert.equal(result.data.film, 90); }); test("insufficient film does not update the user", async () => { reset({ _id: "u1", token: "secret", film: 4 }); const result = await drawWithRandom([0, 0], { uid: "u1", token: "secret", }); assert.equal(result.code, 0); assert.deepEqual(result.data, { film: 4, cost: 5 }); assert.deepEqual(state.updates, []); }); test("a completed cat pool does not charge film", async () => { reset({ _id: "u1", token: "secret", film: 100, catArr: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], }); const result = await drawWithRandom([0, 0], { uid: "u1", token: "secret", }); assert.equal(result.code, 0); assert.equal(result.msg, "已抽取所有猫咪"); assert.deepEqual(state.updates, []); }); test("gameName iaa routes drawCat to usersAd", async () => { reset({ _id: "u1", token: "secret", film: 100 }); await drawWithRandom([0, 0], { uid: "u1", token: "secret", gameName: "iaa", }); assert.equal(state.collections[0], "usersAd"); });