121 lines
4.1 KiB
JavaScript
121 lines
4.1 KiB
JavaScript
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 }]);
|
|
});
|