MatchMaster/server/laf-cloud/tests/login-wucai-state.test.mjs
2026-08-20 12:36:50 +08:00

376 lines
10 KiB
JavaScript

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: [],
orders: [],
idcount: [
{ _id: "69faba99b4d89b170da4bf56", count: 1 },
{ _id: "69fabaacb4d89b170da4bf57", count: 1 },
],
source: null,
sourceFails: false,
sourceCalls: 0,
};
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 === "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) {
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.orders = [];
state.idcount = [
{ _id: "69faba99b4d89b170da4bf56", count: 1 },
{ _id: "69fabaacb4d89b170da4bf57", count: 1 },
];
state.source = source;
state.sourceFails = false;
state.sourceCalls = 0;
}
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("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(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(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("missing target user with an existing order is not auto-migrated", 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, 0);
assert.equal(result.errorCode, "WUCAI_TARGET_AMBIGUOUS");
assert.equal(state.users.length, 0);
assert.equal(state.sourceCalls, 0);
});
test("legacy isWuCai record becomes type 0 only for a capable client", async () => {
reset([existingUser({ isWuCai: true })]);
const result = await login({
body: { code: "code-1", wucai_capability: 1 },
headers: {},
socket: {},
});
assert.equal(result.code, 1);
assert.equal(state.sourceCalls, 0);
assert.equal(state.users[0].wucai_type, 0);
assert.equal(state.users[0].forcedUpdate, true);
assert.equal("isWuCai" in result.data, false);
});