import test from "node:test"; import assert from "node:assert/strict"; import { readFile } from "node:fs/promises"; import { registerHooks } from "node:module"; const state = { user: null }; globalThis.__rebornGiftCloudMock = { database() { return { collection() { return { where(query) { return { async getOne() { return { data: state.user?._id === query._id ? state.user : null }; }, async update(payload) { if (state.user?._id !== query._id) { return { updated: 0 }; } Object.assign(state.user, payload); return { updated: 1 }; }, }; }, }; }, }; }, }; globalThis.__rebornGiftUtilsMock = { checkToken(received, expected) { return received === expected; }, }; registerHooks({ resolve(specifier, context, nextResolve) { if (specifier === "@lafjs/cloud") { return { url: "data:text/javascript,export default globalThis.__rebornGiftCloudMock", shortCircuit: true }; } if (specifier === "@/Utils") { return { url: "data:text/javascript,export default globalThis.__rebornGiftUtilsMock", shortCircuit: true }; } return nextResolve(specifier, context); }, }); const [{ default: rebornGift }, { default: canRebornGift }, { default: userData }] = await Promise.all([ import(new URL("../functions/rebornGift.ts", import.meta.url)), import(new URL("../functions/canRebornGift.ts", import.meta.url)), import(new URL("../functions/userData.ts", import.meta.url)), ]); function resetUser(count = 0) { state.user = { _id: "user-1", token: "token-1", rebornGiftTime: 1_700_000_000_000, rebornGiftCount: count, }; } function request(handler) { return handler({ body: { uid: "user-1", token: "token-1" } }); } test("reborn gift can be recorded repeatedly even for a legacy limited user", async () => { resetUser(1); const first = await request(rebornGift); const second = await request(rebornGift); assert.equal(first.code, 1); assert.equal(second.code, 1); assert.equal(first.data.rebornGiftCount, 0); assert.equal(second.data.rebornGiftCount, 0); assert.equal(state.user.rebornGiftCount, 0); }); test("reborn gift availability never rejects based on the legacy count", async () => { resetUser(99); const result = await request(canRebornGift); assert.equal(result.code, 1); assert.equal(result.data.rebornGiftCount, 0); }); test("user data normalizes the legacy count to an unlimited state", async () => { resetUser(12); const result = await userData({ body: { action: "read", uid: "user-1", token: "token-1" } }); assert.equal(result.code, 1); assert.equal(result.data.rebornGiftCount, 0); }); test("client keeps the reborn gift available and reopens it after each loss", async () => { const [gameManager, revive, utils] = await Promise.all([ readFile(new URL("../../../assets/Script/GameManager.ts", import.meta.url), "utf8"), readFile(new URL("../../../assets/Script/Revive.ts", import.meta.url), "utf8"), readFile(new URL("../../../assets/Script/module/Pay/Utils.ts", import.meta.url), "utf8"), ]); assert.match(gameManager, /setRevive\(\)[\s\S]*?GM_INFO\.revive\s*=\s*0/); assert.match(revive, /init\(\)[\s\S]*?this\.node\.active\s*=\s*true/); assert.match(revive, /if \(this\.onShowListener\)[\s\S]*?wx\.offShow\(this\.onShowListener\)/); assert.doesNotMatch(revive, /GM_INFO\.revive\s*={1,3}\s*1/); assert.doesNotMatch(revive, /GM_INFO\.revive\s*==={0,1}\s*1/); assert.match(utils, /Utils\.POST\("canRebornGift"/); }); test("payment recovery paths never restore the removed one-purchase flag", async () => { const [login, iosGetPayInfo] = await Promise.all([ readFile(new URL("../functions/login.ts", import.meta.url), "utf8"), readFile(new URL("../functions/wx/iosgetPayInfo.ts", import.meta.url), "utf8"), ]); assert.doesNotMatch(`${login}\n${iosGetPayInfo}`, /rebornGiftCount:\s*1/); assert.match(login, /case "reborn_Gift":[\s\S]*?rebornGiftCount:\s*0/); assert.match(iosGetPayInfo, /case "reborn_Gift":[\s\S]*?rebornGiftCount:\s*0/); }); test("reborn gift grants 30 seconds while regular revival remains at 20", async () => { const map = await readFile(new URL("../../../assets/Script/Map.ts", import.meta.url), "utf8"); const regularRevive = map.slice( map.indexOf(" runRewive(data) {"), map.indexOf(" //执行复活函数具体执行状态改变操作"), ); const giftRevive = map.slice( map.indexOf(" runRewiveCopy() {"), map.indexOf(" //上传数数游戏完成事件"), ); assert.match(regularRevive, /timeNumber\s*=\s*21/); assert.match(regularRevive, /add_Time\s*\+=\s*20/); assert.match(giftRevive, /timeNumber\s*=\s*31/); assert.match(giftRevive, /add_Time\s*\+=\s*30/); assert.match(giftRevive, /getTimeMargi3\(30,/); });