fix: accept unchanged profile saves before Wucai migration

This commit is contained in:
COMPUTER\EDY
2026-10-12 16:43:16 +08:00
parent ca9c8d22e2
commit 7c1852cefd
2 changed files with 122 additions and 1 deletions
+2 -1
View File
@@ -46,7 +46,8 @@ export default async function (ctx: FunctionContext) {
}
//console.log(data);
let res2 = await db.collection(dbname).where({ _id: uid }).update(data);
if (res2.ok && res2.updated == 1) {
// 同值保存不会增加 updated;匹配到用户且操作成功也属于保存成功。
if (res2.ok && (res2.updated == 1 || res2.matched == 1)) {
return { code: 1, data: null, msg: "用户数据更新成功" }
} else {
return { code: 0, data: null, msg: "用户数据更新失败" }
+120
View File
@@ -0,0 +1,120 @@
import test from "node:test";
import assert from "node:assert/strict";
import { registerHooks } from "node:module";
const state = { user: null, failUpdate: false, loseMatch: false, legacyResult: false, results: [] };
const profile = { useravatar: "2", username: "player", useravatarIcon: "1", userCat: "3" };
globalThis.__userDataSaveCloudMock = {
database() {
return {
collection() {
return {
where(query) {
return {
async getOne() {
return { data: state.user?._id === query._id ? structuredClone(state.user) : null };
},
async update(payload) {
if (state.loseMatch) state.user = null;
const matched = state.user?._id === query._id ? 1 : 0;
const updated = !state.failUpdate && matched
&& Object.entries(payload).some(([key, value]) => state.user[key] !== value) ? 1 : 0;
if (updated) Object.assign(state.user, payload);
const result = { ok: !state.failUpdate, updated, ...(!state.legacyResult ? { matched } : {}) };
state.results.push(result);
return result;
},
};
},
};
},
};
},
};
globalThis.__userDataSaveUtilsMock = {
checkToken(received, expected) { return received === expected; },
};
registerHooks({
resolve(specifier, context, nextResolve) {
if (specifier === "@lafjs/cloud") {
return { url: "data:text/javascript,export default globalThis.__userDataSaveCloudMock", shortCircuit: true };
}
if (specifier === "@/Utils") {
return { url: "data:text/javascript,export default globalThis.__userDataSaveUtilsMock", shortCircuit: true };
}
return nextResolve(specifier, context);
},
});
const { default: userData } = await import(new URL("../functions/userData.ts", import.meta.url));
function reset() {
state.user = { _id: "user-1", token: "token-1", useravatar: "0", username: "user", useravatarIcon: "0", userCat: "1" };
state.failUpdate = false;
state.loseMatch = false;
state.legacyResult = false;
state.results = [];
}
function save(extra = {}) {
return userData({ body: {
uid: "user-1", token: "token-1", action: "save", userData: JSON.stringify(profile), ...extra,
} });
}
test("saving changed and then identical profile data both succeeds", async () => {
reset();
const first = await save();
const repeated = await save();
assert.deepEqual(state.results, [
{ ok: true, matched: 1, updated: 1 },
{ ok: true, matched: 1, updated: 0 },
]);
assert.equal(first.code, 1);
assert.equal(repeated.code, 1);
assert.deepEqual(state.user, { _id: "user-1", token: "token-1", ...profile });
});
test("a missing uid is rejected without updating", async () => {
reset();
assert.equal((await save({ uid: undefined })).code, 0);
assert.equal(state.results.length, 0);
});
test("an unknown user is not mistaken for an unchanged successful save", async () => {
reset();
const before = structuredClone(state.user);
assert.equal((await save({ uid: "missing-user" })).code, 0);
assert.deepEqual(state.user, before);
});
test("losing the matching user during the update remains a failure", async () => {
reset();
state.loseMatch = true;
assert.equal((await save()).code, 0);
assert.deepEqual(state.results, [{ ok: true, matched: 0, updated: 0 }]);
});
test("an explicitly failed database update remains a failure", async () => {
reset();
state.failUpdate = true;
const before = structuredClone(state.user);
assert.equal((await save()).code, 0);
assert.deepEqual(state.results, [{ ok: false, matched: 1, updated: 0 }]);
assert.deepEqual(state.user, before);
});
test("an invalid token prevents all writes", async () => {
reset();
assert.equal((await save({ token: "wrong-token" })).code, 0);
assert.equal(state.results.length, 0);
});
test("legacy update results with only ok and updated still succeed", async () => {
reset();
state.legacyResult = true;
assert.equal((await save()).code, 1);
assert.deepEqual(state.results, [{ ok: true, updated: 1 }]);
});