import test from "node:test"; import assert from "node:assert/strict"; import { registerHooks } from "node:module"; const functionUrl = new URL("../functions/login.ts", import.meta.url); const migrationUrl = new URL("../functions/wucaiMigration.ts", import.meta.url); const state = { users: [], usersAd: [], abConfigs: [], orders: [], idcount: [ { _id: "69faba99b4d89b170da4bf56", count: 1 }, { _id: "69fabaacb4d89b170da4bf57", count: 1 }, ], source: null, sourceFails: false, sourceCalls: 0, failABUpdate: false, }; function clone(value) { return value == null ? value : JSON.parse(JSON.stringify(value)); } function documents(name) { if (name === "users") return state.users; if (name === "usersAd") return state.usersAd; if (name === "ab_config") return state.abConfigs; if (name === "order") return state.orders; if (name === "idcount") return state.idcount; return []; } function matches(document, query) { return Object.keys(query).every(key => document[key] === query[key]); } function collection(name) { const api = { field() { return api; }, where(query) { return { async get() { return { data: documents(name).filter(item => matches(item, query)).map(clone) }; }, async getOne() { return { data: clone(documents(name).find(item => matches(item, query)) || null) }; }, async update(payload) { if (state.failABUpdate && Object.keys(payload).length === 1 && payload.abTests) { throw new Error("abTests update failed"); } const matched = documents(name).filter(item => matches(item, query)); matched.forEach(item => Object.assign(item, clone(payload))); return { updated: matched.length }; }, }; }, async add(payload) { const document = { _id: `user-${state.users.length + 1}`, ...clone(payload) }; documents(name).push(document); return { id: document._id }; }, async get() { return { data: documents(name).map(clone) }; }, }; return api; } globalThis.__loginWucaiCloudMock = { database() { return { collection }; }, async fetch() { return { data: { openid: "openid-1", session_key: "session-1", unionid: "union-1", }, }; }, }; globalThis.require = () => ({}); globalThis.fetch = async () => { state.sourceCalls++; if (state.sourceFails) { throw new Error("source unavailable"); } return { ok: true, async json() { return { data: clone(state.source) }; }, }; }; registerHooks({ resolve(specifier, context, nextResolve) { if (specifier === "@lafjs/cloud") { return { url: "data:text/javascript,export default globalThis.__loginWucaiCloudMock", shortCircuit: true, }; } if (specifier === "./wucaiMigration") { return { url: migrationUrl.href, shortCircuit: true }; } if (specifier === "@/jungleConfig") { return { url: "data:text/javascript,export const unused = true", shortCircuit: true }; } if (specifier === "ip2region") { return { url: "data:text/javascript,export default class Ip2region { search() { return null; } }", shortCircuit: true, }; } return nextResolve(specifier, context); }, }); const { default: login } = await import(functionUrl); function reset(users = [], source = null) { state.users = clone(users); state.usersAd = []; state.abConfigs = []; state.orders = []; state.idcount = [ { _id: "69faba99b4d89b170da4bf56", count: 1 }, { _id: "69fabaacb4d89b170da4bf57", count: 1 }, ]; state.source = source; state.sourceFails = false; state.sourceCalls = 0; state.failABUpdate = false; } function abConfig(layer, extra = {}) { return { experimentId: `exp_layer_${layer}_001`, layer: String(layer), name: `Layer ${layer}`, enabled: true, resetAssignments: false, resetVersion: 0, variants: [{ group: "A", ratio: 50 }, { group: "B", ratio: 50 }], ...extra, }; } function existingUser(extra = {}) { return { _id: "u1", openid: "openid-1", unionid: "union-1", session_key: "old-session", token: "old-token", onlyId: 1, levelAmount: 0, coinAmount: 0, healthAmount: 5, healthtimestamp: 0, freezeAmount: 3, hammerAmount: 3, magicAmount: 3, userPowerTime: 0, monthCardReward: 0, monthCardTime: 0, rebornGiftCount: 0, rebornGiftTime: 0, pay_user: false, starter_pack: 0, starter_packState: 0, winStreak: 0, passCheck: null, endLevelNum: 0, totalLevel: 0, userLevel: 0, film: 0, careerAmount: 0, headArr: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17], catArr: [1, 2, 3], ...extra, }; } test("ordinary legacy login initializes wucai_type -1 without reading Wucai", async () => { reset(); const result = await login({ body: { code: "code-1" }, headers: {}, socket: {} }); assert.equal(result.code, 1); assert.equal(state.sourceCalls, 0); assert.equal(state.users[0].wucai_type, -1); assert.equal("isWuCai" in state.users[0], false); }); test("new users receive all managed layers without affecting enabled assignments", async () => { reset(); state.abConfigs = [ abConfig(1, { enabled: false }), abConfig(2), ]; const result = await login({ body: { code: "code-1" }, headers: {}, socket: {} }); assert.equal(result.code, 1); assert.deepEqual(Object.keys(result.data.abTests).sort(), ["layer_1", "layer_2", "layer_3"]); assert.equal(result.data.abTests.layer_1.experimentId, "exp_layer_1_001"); assert.equal(result.data.abTests.layer_1.enabled, false); assert.equal(result.data.abTests.layer_1.group, "Default"); assert.equal(result.data.abTests.layer_2.experimentId, "exp_layer_2_001"); assert.match(result.data.abTests.layer_2.group, /^[AB]$/); assert.equal(result.data.abTests.layer_3.experimentId, null); assert.equal(result.data.abTests.layer_3.name, null); assert.equal(result.data.abTests.layer_3.enabled, false); assert.equal(result.data.abTests.layer_3.group, "Default"); assert.equal(result.data.abTests.layer_3.appliedResetVersion, 0); assert.deepEqual(state.users[0].abTests, result.data.abTests); }); test("existing users keep groups per layer while disabled and missing layers become Default", async () => { reset([existingUser({ wucai_type: -1, abTests: { layer_1: { experimentId: "exp_layer_1_001", layer: "1", name: "Old Layer 1", enabled: true, group: "B", assignedAt: 100, appliedResetVersion: 7, }, layer_2: { experimentId: "exp_layer_2_001", layer: "2", name: "Old Layer 2", enabled: true, group: "A", assignedAt: 200, appliedResetVersion: 0, }, layer_3: { experimentId: "exp_layer_3_001", layer: "3", name: "Removed Layer", enabled: true, group: "C", assignedAt: 250, appliedResetVersion: 0, }, layer_4: { experimentId: "exp_layer_4_001", layer: "4", name: "Future Layer", enabled: true, group: "H", assignedAt: 300, appliedResetVersion: 0, }, }, })]); state.abConfigs = [ abConfig(1, { experimentId: "exp_layer_1_002", name: "New Layer 1" }), abConfig(2, { enabled: false, resetAssignments: true, resetVersion: 101 }), ]; const result = await login({ body: { code: "code-1" }, headers: {}, socket: {} }); assert.equal(result.code, 1); assert.equal(result.data.abTests.layer_1.group, "B"); assert.equal(result.data.abTests.layer_1.experimentId, "exp_layer_1_002"); assert.equal(result.data.abTests.layer_1.name, "New Layer 1"); assert.equal(result.data.abTests.layer_1.assignedAt, 100); assert.equal(result.data.abTests.layer_1.appliedResetVersion, 7); assert.equal(result.data.abTests.layer_2.group, "Default"); assert.equal(result.data.abTests.layer_2.enabled, false); assert.notEqual(result.data.abTests.layer_2.assignedAt, 200); assert.equal(result.data.abTests.layer_3.group, "Default"); assert.equal(result.data.abTests.layer_3.experimentId, null); assert.notEqual(result.data.abTests.layer_3.assignedAt, 250); assert.equal(result.data.abTests.layer_4.group, "H"); assert.equal(result.data.abTests.layer_4.assignedAt, 300); assert.deepEqual(state.users[0].abTests, result.data.abTests); }); test("an active reset version reassigns each existing user only once", async () => { reset([existingUser({ wucai_type: -1, abTests: { layer_1: { experimentId: "exp_layer_1_001", layer: "1", name: "Layer 1", enabled: true, group: "B", assignedAt: 100, appliedResetVersion: 0, }, layer_2: { experimentId: "exp_layer_2_001", layer: "2", name: "Layer 2", enabled: true, group: "B", assignedAt: 200, appliedResetVersion: 0, }, }, })]); state.abConfigs = [ abConfig(1, { resetAssignments: true, resetVersion: 101, variants: [{ group: "A", ratio: 95 }, { group: "B", ratio: 5 }], }), abConfig(2), ]; const first = await login({ body: { code: "code-1" }, headers: {}, socket: {} }); const assignedAt = first.data.abTests.layer_1.assignedAt; const second = await login({ body: { code: "code-1" }, headers: {}, socket: {} }); assert.equal(first.data.abTests.layer_1.group, "A"); assert.equal(first.data.abTests.layer_1.appliedResetVersion, 101); assert.notEqual(assignedAt, 100); assert.equal(second.data.abTests.layer_1.group, "A"); assert.equal(second.data.abTests.layer_1.assignedAt, assignedAt); assert.equal(second.data.abTests.layer_1.appliedResetVersion, 101); assert.equal(second.data.abTests.layer_2.group, "B"); assert.equal(second.data.abTests.layer_2.assignedAt, 200); }); test("users who miss a reset window keep their old group after the switch closes", async () => { reset([existingUser({ wucai_type: -1, abTests: { layer_1: { experimentId: "exp_layer_1_001", layer: "1", name: "Layer 1", enabled: true, group: "B", assignedAt: 100, appliedResetVersion: 0, }, }, })]); state.abConfigs = [abConfig(1, { resetAssignments: false, resetVersion: 101, variants: [{ group: "A", ratio: 95 }, { group: "B", ratio: 5 }], })]; const result = await login({ body: { code: "code-1" }, headers: {}, socket: {} }); assert.equal(result.data.abTests.layer_1.group, "B"); assert.equal(result.data.abTests.layer_1.assignedAt, 100); assert.equal(result.data.abTests.layer_1.appliedResetVersion, 0); }); test("Default remains sticky until an active reset version is available", async () => { reset([existingUser({ wucai_type: -1, abTests: { layer_1: { experimentId: "exp_layer_1_001", layer: "1", name: "Layer 1", enabled: true, group: "DEFAULT", assignedAt: 100, appliedResetVersion: 0, }, }, })]); state.abConfigs = [abConfig(1, { resetAssignments: false, resetVersion: 101, variants: [{ group: "A", ratio: 95 }, { group: "B", ratio: 5 }], })]; const beforeReset = await login({ body: { code: "code-1" }, headers: {}, socket: {} }); state.abConfigs[0].resetAssignments = true; const afterReset = await login({ body: { code: "code-1" }, headers: {}, socket: {} }); assert.equal(beforeReset.data.abTests.layer_1.group, "Default"); assert.equal(beforeReset.data.abTests.layer_1.assignedAt, 100); assert.equal(afterReset.data.abTests.layer_1.group, "A"); assert.equal(afterReset.data.abTests.layer_1.appliedResetVersion, 101); assert.notEqual(afterReset.data.abTests.layer_1.assignedAt, 100); }); test("broken AB data is repaired without blocking login when persistence fails", async () => { reset([existingUser({ wucai_type: -1, abTests: "not-json" })]); state.failABUpdate = true; const result = await login({ body: { code: "code-1" }, headers: {}, socket: {} }); assert.equal(result.code, 1); assert.deepEqual(Object.keys(result.data.abTests).sort(), ["layer_1", "layer_2", "layer_3"]); assert.equal(result.data.abTests.layer_1.group, "Default"); assert.equal(state.users[0].abTests, "not-json"); }); test("ordinary usersAd login does not create migration fields", async () => { reset(); const result = await login({ body: { code: "code-1", gameName: "iaa" }, headers: {}, socket: {}, }); assert.equal(result.code, 1); assert.equal(state.usersAd.length, 1); assert.equal("wucai_type" in state.usersAd[0], false); assert.equal("abTests" in state.usersAd[0], false); assert.equal("abTests" in result.data, false); assert.equal(state.sourceCalls, 0); }); test("new Wucai account migrates source data and returns type 0", async () => { reset([], { levelAmount: 0, coinAmount: 100, freezeAmount: 0, hammerAmount: 1, magicAmount: 2, pay_user: true, }); const result = await login({ body: { code: "code-1", from: "wucai", wucai_capability: 1 }, headers: {}, socket: {}, }); assert.equal(result.code, 1); assert.equal(result.data.isFirst, true); assert.equal(state.sourceCalls, 1); assert.equal(state.users[0].wucai_type, 0); assert.equal(state.users[0].coinAmount, 100); assert.equal(state.users[0].freezeAmount, 0); assert.equal(state.users[0].pay_user, true); assert.equal(state.users[0].forcedUpdate, true); assert.equal(result.data.wucai_type, 0); }); test("an existing pristine level-zero account also auto-migrates", async () => { reset([existingUser({ wucai_type: -1 })], { levelAmount: 6, coinAmount: 123, freezeAmount: 4, }); const result = await login({ body: { code: "code-1", from: "wucai", wucai_capability: 1 }, headers: {}, socket: {}, }); assert.equal(result.code, 1); assert.equal(state.users[0].wucai_type, 0); assert.equal(state.users[0].levelAmount, 6); assert.equal(state.users[0].coinAmount, 123); assert.equal(state.users[0].forcedUpdate, true); }); test("meaningful target enters type 1 without being overwritten", async () => { reset([existingUser({ unionid: undefined, coinAmount: 9, wucai_type: -1 })], { levelAmount: 8, coinAmount: 500, freezeAmount: 6, }); const result = await login({ body: { code: "code-1", from: "wucai", wucai_capability: 1 }, headers: {}, socket: {}, }); assert.equal(result.code, 1); assert.equal(state.users[0].wucai_type, 1); assert.equal(state.users[0].coinAmount, 9); assert.equal(state.users[0].unionid, "union-1"); assert.equal(result.data.wucai_preview.coinAmount, 500); assert.equal("token" in result.data.wucai_preview, false); }); test("type 1 ordinary login refreshes the Wucai preview", async () => { reset([existingUser({ coinAmount: 9, wucai_type: 1 })], { levelAmount: 10, coinAmount: 777, }); const result = await login({ body: { code: "code-1", wucai_capability: 1 }, headers: {}, socket: {}, }); assert.equal(result.code, 1); assert.equal(state.sourceCalls, 1); assert.equal(result.data.wucai_type, 1); assert.equal(result.data.wucai_preview.coinAmount, 777); }); test("type 0 ordinary login keeps the popup state without reading Wucai", async () => { reset([existingUser({ wucai_type: 0, forcedUpdate: false })], { coinAmount: 999 }); const result = await login({ body: { code: "code-1", wucai_capability: 1 }, headers: {}, socket: {}, }); assert.equal(result.code, 1); assert.equal(result.data.wucai_type, 0); assert.equal(state.sourceCalls, 0); }); test("type 1 source failure does not reset or overwrite target progress", async () => { reset([existingUser({ wucai_type: 1, coinAmount: 42 })]); state.sourceFails = true; const result = await login({ body: { code: "code-1", wucai_capability: 1 }, headers: {}, socket: {}, }); assert.equal(result.code, 0); assert.equal(result.errorCode, "WUCAI_SOURCE_UNAVAILABLE"); assert.equal(state.users[0].wucai_type, 1); assert.equal(state.users[0].coinAmount, 42); }); test("old clients cannot bypass pending states", async () => { reset([existingUser({ wucai_type: 1, coinAmount: 42 })], { levelAmount: 2 }); const result = await login({ body: { code: "code-1" }, headers: {}, socket: {}, }); assert.equal(result.code, 0); assert.equal(result.errorCode, "WUCAI_CLIENT_UPGRADE_REQUIRED"); assert.equal(state.sourceCalls, 0); assert.equal(state.users[0].wucai_type, 1); }); test("terminal states ignore later Wucai entry", async () => { reset([existingUser({ wucai_type: 2 })], { coinAmount: 999 }); const result = await login({ body: { code: "code-1", from: "wucai", wucai_capability: 1 }, headers: {}, socket: {}, }); assert.equal(result.code, 1); assert.equal(result.data.wucai_type, 2); assert.equal(state.sourceCalls, 0); }); test("source failure creates or updates nothing", async () => { reset(); state.sourceFails = true; const result = await login({ body: { code: "code-1", from: "wucai", wucai_capability: 1 }, headers: {}, socket: {}, }); assert.equal(result.code, 0); assert.equal(result.errorCode, "WUCAI_SOURCE_UNAVAILABLE"); assert.equal(state.users.length, 0); assert.equal(state.idcount[0].count, 1); }); test("new Wucai target ignores orphan orders and auto-migrates", async () => { reset([], { levelAmount: 1 }); state.orders.push({ openid: "openid-1", state: 1 }); const result = await login({ body: { code: "code-1", from: "wucai", wucai_capability: 1 }, headers: {}, socket: {}, }); assert.equal(result.code, 1); assert.equal(result.data.wucai_type, 0); assert.equal(state.users.length, 1); assert.equal(state.users[0].levelAmount, 1); assert.equal(state.sourceCalls, 1); }); test("an existing target with an order is still not auto-overwritten", async () => { reset([existingUser({ wucai_type: -1 })], { levelAmount: 8, coinAmount: 500 }); state.orders.push({ openid: "openid-1", state: 1 }); const result = await login({ body: { code: "code-1", from: "wucai", wucai_capability: 1 }, headers: {}, socket: {}, }); assert.equal(result.code, 1); assert.equal(result.data.wucai_type, 1); assert.equal(state.users[0].levelAmount, 0); assert.equal(state.users[0].coinAmount, 0); assert.equal(state.sourceCalls, 1); }); test("deprecated isWuCai does not affect migration state", async () => { reset([existingUser({ isWuCai: true })]); const result = await login({ body: { code: "code-1" }, headers: {}, socket: {}, }); assert.equal(result.code, 1); assert.equal(state.sourceCalls, 0); assert.equal(state.users[0].wucai_type, -1); assert.equal("forcedUpdate" in state.users[0], false); assert.equal("isWuCai" in result.data, false); }); test("deprecated isWuCai cannot bypass the progress choice", async () => { reset([existingUser({ isWuCai: true, coinAmount: 9 })], { levelAmount: 8, coinAmount: 500, }); const result = await login({ body: { code: "code-1", from: "wucai", wucai_capability: 1 }, headers: {}, socket: {}, }); assert.equal(result.code, 1); assert.equal(state.sourceCalls, 1); assert.equal(state.users[0].wucai_type, 1); assert.equal(state.users[0].coinAmount, 9); }); test("paid level-zero target must choose progress", async () => { reset([existingUser({ wucai_type: -1, pay_user: true })], { levelAmount: 8, coinAmount: 500, }); const result = await login({ body: { code: "code-1", from: "wucai", wucai_capability: 1 }, headers: {}, socket: {}, }); assert.equal(result.code, 1); assert.equal(state.sourceCalls, 1); assert.equal(state.users[0].wucai_type, 1); assert.equal(state.users[0].pay_user, true); });