server/laf-cloud/tests/daily-task-v2.test.mjs

93 lines
4.8 KiB
JavaScript

import test from "node:test";
import assert from "node:assert/strict";
import { registerHooks } from "node:module";
const configUrl = new URL("../functions/dailyTaskConfig.ts", import.meta.url);
const serviceUrl = new URL("../functions/dailyTaskService.ts", import.meta.url);
registerHooks({
resolve(specifier, context, nextResolve) {
if (specifier === "@/dailyTaskConfig") return { url: configUrl.href, shortCircuit: true };
return nextResolve(specifier, context);
},
});
const { getDayKey, getDayEndsAt, getWeekKey, getWeekEndsAt, refreshTaskData, mergeClientProgress, claimDaily, claimWeekly } = await import(serviceUrl);
test("uses Shanghai natural day and Monday week keys", () => {
assert.equal(getDayKey(Date.parse("2026-09-06T15:59:59Z")), "2026-09-06");
assert.equal(getDayKey(Date.parse("2026-09-06T16:00:00Z")), "2026-09-07");
assert.equal(getDayEndsAt(Date.parse("2026-09-06T16:00:00Z")), Date.parse("2026-09-08T00:00:00+08:00"));
assert.equal(getWeekKey(Date.parse("2026-09-06T16:00:00Z")), "2026-09-07");
assert.equal(getWeekEndsAt(Date.parse("2026-09-06T16:00:00Z")), Date.parse("2026-09-14T00:00:00+08:00"));
});
test("returns current server time and refreshes it on repeated reads", () => {
const firstNow = Date.parse("2026-09-07T04:00:00Z");
const secondNow = firstNow + 5000;
const first = refreshTaskData(null, "user-time", 20, firstNow).data;
const second = refreshTaskData(JSON.stringify(first), "user-time", 20, secondNow);
assert.equal(second.changed, false);
assert.equal(second.data.serverNow, secondNow);
assert.equal(second.data.dayEndsAt, Date.parse("2026-09-08T00:00:00+08:00"));
assert.equal(second.data.weekEndsAt, Date.parse("2026-09-14T00:00:00+08:00"));
});
test("migrates legacy tasks into five v2 stages totaling twenty stars", () => {
const legacy = JSON.stringify({ levelPass: { value: 3, state: 1 } });
const result = refreshTaskData(legacy, "user-1", 20, Date.parse("2026-09-04T04:00:00Z"));
assert.equal(result.changed, true);
assert.equal(result.data.version, 2);
assert.equal(result.data.dailyTasks.length, 5);
assert.equal(result.data.dailyTasks.reduce((sum, task) => sum + task.stars, 0), 20);
assert.deepEqual(result.data.dailyTasks.map(task => task.locked), [false, true, true, true, true]);
});
test("keeps the same selection during a day and avoids previous slot tasks next day", () => {
const first = refreshTaskData(null, "user-2", 20, Date.parse("2026-09-04T04:00:00Z")).data;
const same = refreshTaskData(JSON.stringify(first), "user-2", 20, Date.parse("2026-09-04T14:00:00Z"));
assert.equal(same.changed, false);
assert.deepEqual(same.data.dailyTasks.map(task => task.taskId), first.dailyTasks.map(task => task.taskId));
const next = refreshTaskData(JSON.stringify(first), "user-2", 20, Date.parse("2026-09-05T04:00:00Z")).data;
next.dailyTasks.forEach((task, index) => assert.notEqual(task.taskId, first.dailyTasks[index].taskId));
});
test("locked stages accumulate but cannot be claimed before the previous reward", () => {
const data = refreshTaskData(null, "user-3", 20, Date.parse("2026-09-04T04:00:00Z")).data;
const submitted = structuredClone(data);
submitted.dailyTasks[0].value = submitted.dailyTasks[0].target;
submitted.dailyTasks[1].value = submitted.dailyTasks[1].target;
mergeClientProgress(data, submitted);
assert.equal(data.dailyTasks[1].state, 1);
assert.equal(data.dailyTasks[1].locked, true);
assert.equal(claimDaily(data, data.dailyTasks[1].taskId).ok, false);
assert.equal(claimDaily(data, data.dailyTasks[0].taskId).ok, true);
assert.equal(data.dailyTasks[1].locked, false);
});
test("daily claims add stars once and weekly tiers claim independently", () => {
const data = refreshTaskData(null, "user-4", 20, Date.parse("2026-09-04T04:00:00Z")).data;
for (const task of data.dailyTasks) {
task.value = task.target;
task.state = 1;
task.locked = false;
assert.equal(claimDaily(data, task.taskId).ok, true);
}
assert.equal(data.weeklyStars, 20);
assert.equal(claimDaily(data, data.dailyTasks[0].taskId).ok, false);
data.weeklyStars = 140;
const high = claimWeekly(data, "weekly_140");
assert.equal(high.ok, true);
assert.equal(data.weeklyRewards.find(item => item.rewardId === "weekly_35").state, 0);
});
test("daily reset preserves stars while weekly reset clears them", () => {
const friday = refreshTaskData(null, "user-5", 20, Date.parse("2026-09-04T04:00:00Z")).data;
friday.weeklyStars = 70;
const saturday = refreshTaskData(JSON.stringify(friday), "user-5", 20, Date.parse("2026-09-05T04:00:00Z")).data;
assert.equal(saturday.weeklyStars, 70);
const monday = refreshTaskData(JSON.stringify(saturday), "user-5", 20, Date.parse("2026-09-07T04:00:00Z")).data;
assert.equal(monday.weeklyStars, 0);
assert.ok(monday.weeklyRewards.every(reward => reward.state === 0));
});