154 lines
8.5 KiB
JavaScript
154 lines
8.5 KiB
JavaScript
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import { readFile } from "node:fs/promises";
|
|
|
|
test("client stores migration state and exposes all transfer actions", async () => {
|
|
const [gameManager, gameConfig, utils, miniGameSdk] = await Promise.all([
|
|
readFile(new URL("../../../assets/Script/GameManager.ts", import.meta.url), "utf8"),
|
|
readFile(new URL("../../../assets/Script/module/Config/GameConfig.ts", import.meta.url), "utf8"),
|
|
readFile(new URL("../../../assets/Script/module/Pay/Utils.ts", import.meta.url), "utf8"),
|
|
readFile(new URL("../../../assets/Script/Sdk/MiniGameSdk.ts", import.meta.url), "utf8"),
|
|
]);
|
|
|
|
assert.match(gameConfig, /wucai_type:\s*number/);
|
|
assert.match(gameConfig, /wucai_type:\s*-1/);
|
|
assert.match(gameConfig, /wucai_preview:\s*any/);
|
|
assert.match(gameConfig, /wucai_reward_popup_pending:\s*boolean/);
|
|
assert.match(gameManager, /GM_INFO\.wucai_type\s*=\s*Number\.isInteger/);
|
|
assert.match(gameManager, /GM_INFO\.wucai_preview\s*=\s*data\.data\.wucai_preview \|\| null/);
|
|
assert.match(gameManager, /GM_INFO\.wucai_reward_popup_pending\s*=/);
|
|
assert.match(gameManager, /GM_INFO\.wucai_type === 1/);
|
|
assert.match(utils, /"claim_reward"\s*\|\s*"choose_wucai"\s*\|\s*"choose_current"\s*\|\s*"ack_reward_popup"/);
|
|
assert.match(utils, /Utils\.POST\("wucaiTransfer"/);
|
|
assert.match(utils, /action === "claim_reward"[\s\S]*GM_INFO\.coin = coinAmount/);
|
|
assert.match(utils, /StorageMessage\.setStorage\("coin"/);
|
|
assert.match(utils, /StorageMessage\.setStorage\("prop"/);
|
|
assert.match(utils, /action === "choose_wucai" \|\| action === "choose_current"[\s\S]*MiniGameSdk\.API\.reboot\(\)/);
|
|
assert.match(miniGameSdk, /userSet\(\{ transferred_from_wucai: transferred \}\)/);
|
|
});
|
|
|
|
test("Wucai transfer analytics report the final choice and both archive levels", async () => {
|
|
const [gameManager, utils, miniGameSdk] = await Promise.all([
|
|
readFile(new URL("../../../assets/Script/GameManager.ts", import.meta.url), "utf8"),
|
|
readFile(new URL("../../../assets/Script/module/Pay/Utils.ts", import.meta.url), "utf8"),
|
|
readFile(new URL("../../../assets/Script/Sdk/MiniGameSdk.ts", import.meta.url), "utf8"),
|
|
]);
|
|
|
|
assert.match(miniGameSdk, /shushu_Track\("transfer_from_wucai",\s*\{/);
|
|
assert.match(miniGameSdk, /already_xiaoxiao:\s*alreadyXiaoxiao/);
|
|
assert.match(miniGameSdk, /choose_xiaoxiao:\s*chooseXiaoxiao/);
|
|
assert.match(miniGameSdk, /wucai_level:\s*toCurrentLevel\(wucaiLevelAmount\)/);
|
|
assert.match(miniGameSdk, /xiaoxiao_level:\s*toCurrentLevel\(xiaoxiaoLevelAmount\)/);
|
|
assert.match(miniGameSdk, /levelAmount !== null[\s\S]*level \+ 1[\s\S]*-1/);
|
|
|
|
const updateIndex = gameManager.indexOf("update(dt)");
|
|
const loginIndex = gameManager.indexOf("this.loginShushuOnce();", updateIndex);
|
|
const pendingChoiceIndex = gameManager.indexOf("GM_INFO.wucai_type === 1", updateIndex);
|
|
assert.ok(updateIndex >= 0 && loginIndex > updateIndex && pendingChoiceIndex > loginIndex);
|
|
assert.match(gameManager, /loginShushuOnce\(\)[\s\S]*shushu_Login\(\)/);
|
|
assert.match(gameManager, /const transferred = wucaiType === 0 \|\| wucaiType === 2 \|\| wucaiType === 3/);
|
|
assert.match(gameManager, /shushu_userSetTransferredFromWucai\(transferred\)/);
|
|
assert.match(gameManager, /shushu_TrackWucaiTransfer\(0, 0, this\.autoWucaiLevelAmount, null\)/);
|
|
assert.match(utils, /action === "choose_current" \? 1 : 0/);
|
|
assert.match(utils, /res\.code === 1 && isProgressChoice && wasPendingChoice/);
|
|
assert.match(utils, /shushu_TrackWucaiTransfer\([\s\S]*wucaiLevelAmount,[\s\S]*xiaoxiaoLevelAmount/);
|
|
assert.match(utils, /shushu_userSetTransferredFromWucai\(true\)/);
|
|
});
|
|
|
|
test("new-user registration is independent of local cache and does not wait for analytics login", async () => {
|
|
const gameManager = await readFile(
|
|
new URL("../../../assets/Script/GameManager.ts", import.meta.url),
|
|
"utf8"
|
|
);
|
|
|
|
assert.doesNotMatch(gameManager, /pendingRegisterEvent/);
|
|
assert.match(gameManager, /if \(data\.data\.isFirst === true\)\s*\{[\s\S]*?this\.setFirstInfo\(\);\s*\}/);
|
|
assert.equal((gameManager.match(/this\.setFirstInfo\(\);/g) || []).length, 1);
|
|
|
|
const analyticsInitIndex = gameManager.indexOf("MiniGameSdk.API.shushu_Init();");
|
|
const loginRequestIndex = gameManager.indexOf("Utils.getUserInfo(", analyticsInitIndex);
|
|
const cacheBranchIndex = gameManager.indexOf("this.getUserDataToLocal(data.data);", loginRequestIndex);
|
|
const registerIndex = gameManager.indexOf("this.setFirstInfo();", cacheBranchIndex);
|
|
const loginMethodIndex = gameManager.indexOf("private loginShushuOnce()");
|
|
assert.ok(analyticsInitIndex >= 0);
|
|
assert.ok(loginRequestIndex > analyticsInitIndex);
|
|
assert.ok(cacheBranchIndex > loginRequestIndex);
|
|
assert.ok(registerIndex > cacheBranchIndex);
|
|
assert.ok(loginMethodIndex > registerIndex);
|
|
});
|
|
|
|
test("a completed progress choice shows the Home reward popup once after reboot", async () => {
|
|
const [transfer, home, gameManager] = await Promise.all([
|
|
readFile(new URL("../../../assets/Transfer/script/Transfer.ts", import.meta.url), "utf8"),
|
|
readFile(new URL("../../../assets/Script/JiaZai.ts", import.meta.url), "utf8"),
|
|
readFile(new URL("../../../assets/Script/GameManager.ts", import.meta.url), "utf8"),
|
|
]);
|
|
|
|
assert.match(gameManager, /wucai_reward_popup_pending\s*=\s*[\s\S]*data\.data\.wucai_reward_popup_pending === true/);
|
|
assert.match(home, /wucaiType === 0[\s\S]*wucai_reward_popup_pending === true/);
|
|
assert.match(transfer, /this\.submit\("ack_reward_popup"\)/);
|
|
assert.match(transfer, /action === "claim_reward" \|\| action === "ack_reward_popup"[\s\S]*this\.node\.active = false/);
|
|
assert.match(transfer, /action === "claim_reward"[\s\S]*home\.updateCoin\(\)/);
|
|
});
|
|
|
|
test("Home automatic popups wait until the Wucai Transfer popup closes", async () => {
|
|
const [transfer, home] = await Promise.all([
|
|
readFile(new URL("../../../assets/Transfer/script/Transfer.ts", import.meta.url), "utf8"),
|
|
readFile(new URL("../../../assets/Script/JiaZai.ts", import.meta.url), "utf8"),
|
|
]);
|
|
|
|
assert.match(home, /isWucaiTransferBlockingPopups\(\)/);
|
|
assert.match(home, /deferHomePopupWhileTransfer\("order"/);
|
|
assert.match(home, /deferHomePopupWhileTransfer\("monthlyReward"/);
|
|
assert.match(home, /deferHomePopupWhileTransfer\("monthlyCard"/);
|
|
assert.match(home, /deferHomePopupWhileTransfer\("starterPack"/);
|
|
assert.match(home, /deferHomePopupWhileTransfer\("share"/);
|
|
assert.match(home, /deferHomePopupWhileTransfer\("passCheck"/);
|
|
assert.match(home, /"jungleTreasure"[\s\S]*initializeJungleTreasureEntryFromLogin/);
|
|
assert.match(home, /resumeDeferredHomePopups\(\)/);
|
|
assert.match(transfer, /this\.node\.active = false;[\s\S]*this\.notifyHomeTransferClosed\(\)/);
|
|
assert.match(transfer, /home\.resumeDeferredHomePopups\(\)/);
|
|
});
|
|
|
|
test("Home Transfer reward glows rotate continuously", async () => {
|
|
const transfer = await readFile(
|
|
new URL("../../../assets/Transfer/script/Transfer.ts", import.meta.url),
|
|
"utf8"
|
|
);
|
|
|
|
for (const nodeName of ["coin_guang", "hammer_guang", "magic_guang", "ice_guang"]) {
|
|
assert.match(transfer, new RegExp(nodeName));
|
|
}
|
|
assert.match(transfer, /cc\.rotateBy\(5, 360\)\.repeatForever\(\)/);
|
|
assert.match(transfer, /this\.playHomePopupAnimation\(\)/);
|
|
assert.match(transfer, /homeRewardContent\.scale = 0\.8/);
|
|
assert.match(transfer, /scale: 1\.05[\s\S]*scale: 1/);
|
|
});
|
|
|
|
test("forcedUpdate is acknowledged only from the completed load gate", async () => {
|
|
const gameManager = await readFile(
|
|
new URL("../../../assets/Script/GameManager.ts", import.meta.url),
|
|
"utf8"
|
|
);
|
|
|
|
const updateIndex = gameManager.indexOf("update(dt)");
|
|
const clearIndex = gameManager.indexOf("Utils.setForcedUpdate(");
|
|
assert.ok(updateIndex >= 0);
|
|
assert.ok(clearIndex > updateIndex);
|
|
assert.match(gameManager, /data\.forcedUpdate === true[\s\S]*this\.applyForcedProgress\(data\)/);
|
|
assert.match(gameManager, /data\.data\.forcedUpdate === true[\s\S]*effectivePowerTime/);
|
|
assert.match(gameManager, /data\.data\.forcedUpdate === true[\s\S]*StorageMessage\.setStorage\("health"/);
|
|
assert.match(gameManager, /winStreak !== undefined && data\.data\.winStreak !== null/);
|
|
});
|
|
|
|
test("forcedUpdate backend requires a token and checks the update result", async () => {
|
|
const source = await readFile(
|
|
new URL("../functions/setForcedUpdate.ts", import.meta.url),
|
|
"utf8"
|
|
);
|
|
|
|
assert.match(source, /!res\.data \|\| !res\.data\.token \|\| !token1/);
|
|
assert.match(source, /res1\.ok !== false && res1\.updated !== 0/);
|
|
assert.doesNotMatch(source, /if \(res\.ok && res1\.updated/);
|
|
});
|