93 lines
4.8 KiB
JavaScript
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));
|
|
});
|