144 lines
4.9 KiB
JavaScript
144 lines
4.9 KiB
JavaScript
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,/);
|
|
});
|