Files
koc-loop/tests/wecom-notifier.test.mjs
ABAPPLO e2a93e22cf feat: 任务模型物理合并,发布+回收并为单任务双阶段
- tasks 新增 recovery_enabled/recovery_due_at/recovery_instructions/recovery_example_images,回收挂自己名下(先发布后交截图),不再置 complete
- 存量 screenshot_collect 迁移并入父任务后删除(mysql/0020 含 DELETE,生产执行前务必备份)
- 新 action task_enable_recovery:ghost 面板一键开通回收,截止默认=发布截止
- 企微催办双阶段(待发布/截图待提交);超期自动释放仅发布阶段
- admin 删 groupTaskMasters 聚合改单卡双面板;portal 详情页回收截图区块+批次回收进度
- 测试 309 全绿 + Playwright E2E 20/20
2026-09-24 15:52:45 +08:00

78 lines
2.2 KiB
JavaScript

import assert from "node:assert/strict";
import test from "node:test";
import {
computeDueCutoff,
runDueSoonWecomNotifications,
} from "../lib/wecom-notifier-service.ts";
test("computeDueCutoff advances by dueDays and crosses month/year", () => {
assert.equal(computeDueCutoff("2026-08-18", 3), "2026-08-21");
assert.equal(computeDueCutoff("2026-08-30", 3), "2026-09-02");
assert.equal(computeDueCutoff("2026-12-30", 3), "2027-01-02");
assert.equal(computeDueCutoff("2026-08-18", 0), "2026-08-18");
assert.equal(computeDueCutoff("2026-08-18", 10), "2026-08-28");
});
test("computeDueCutoff returns input unchanged when malformed", () => {
assert.equal(computeDueCutoff("not-a-date", 3), "not-a-date");
});
function captureDb() {
const executed = [];
const db = {
prepare(sql) {
const statement = (values) => ({
async all() {
executed.push({ sql, values });
return { results: [] };
},
async first() {
executed.push({ sql, values });
return null;
},
});
return {
bind(...values) {
return statement(values);
},
...statement([]),
};
},
};
return { db, executed };
}
const NOTIFY_CONFIG = {
corpId: "",
agentId: "",
secret: "",
robotWebhook: "",
dueDays: 3,
};
test("runDueSoonWecomNotifications filters by taskId when given", async () => {
const { db, executed } = captureDb();
const now = Date.UTC(2026, 7, 18, 2, 0, 0);
const summary = await runDueSoonWecomNotifications(
db,
NOTIFY_CONFIG,
undefined,
now,
"task-9",
);
assert.equal(executed.length, 1);
assert.match(executed[0].sql, /AND t\.id = \?/);
assert.deepEqual(executed[0].values, ["2026-08-21", "2026-08-21", "task-9"]);
assert.equal(summary.dueSoonAttempted, 0);
assert.equal(summary.digestSent, false);
});
test("runDueSoonWecomNotifications keeps global scan without taskId", async () => {
const { db, executed } = captureDb();
const now = Date.UTC(2026, 7, 18, 2, 0, 0);
await runDueSoonWecomNotifications(db, NOTIFY_CONFIG, undefined, now);
assert.equal(executed.length, 1);
assert.ok(!/AND t\.id = \?/.test(executed[0].sql));
assert.deepEqual(executed[0].values, ["2026-08-21", "2026-08-21"]);
});