MatchMaster/server/laf-cloud/tests/draw-cat.test.mjs
2026-07-30 12:22:02 +08:00

200 lines
4.7 KiB
JavaScript

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");
});