d58dc2a251
Introduce Draft → Confirm → Commit flow for WeChat schedule intents behind feature flags, plus h5_tasks dual-write/read aggregation and rollout scripts so reminders and automations get explicit user confirmation before persisting. Co-authored-by: Cursor <cursoragent@cursor.com>
103 lines
2.6 KiB
JavaScript
103 lines
2.6 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
import { attachUnifiedTaskSync } from './task-unified-sync.mjs';
|
|
|
|
test('attachUnifiedTaskSync wraps scheduled task create when enabled', async () => {
|
|
const syncCalls = [];
|
|
const scheduledTaskService = {
|
|
async createTask(payload) {
|
|
return {
|
|
id: 'task-1',
|
|
userId: payload.userId,
|
|
title: payload.title,
|
|
taskSpec: payload.taskSpec,
|
|
recurrence: 'daily',
|
|
hour: 6,
|
|
minute: 0,
|
|
nextRunAt: 5000,
|
|
timezone: 'Asia/Shanghai',
|
|
notifyChannel: 'both',
|
|
sourceChannel: payload.sourceChannel,
|
|
};
|
|
},
|
|
};
|
|
const taskUnifiedService = {
|
|
async syncFromCommit(payload) {
|
|
syncCalls.push(payload);
|
|
return { id: 'unified-1' };
|
|
},
|
|
};
|
|
|
|
attachUnifiedTaskSync({
|
|
scheduleService: {},
|
|
scheduledTaskService,
|
|
taskUnifiedService,
|
|
pool: { async query() { return [[]]; } },
|
|
env: { H5_UNIFIED_TASKS_ENABLED: '1' },
|
|
});
|
|
|
|
await scheduledTaskService.createTask({
|
|
userId: 'user-1',
|
|
title: '每日新闻',
|
|
taskSpec: 'news',
|
|
sourceChannel: 'wechat',
|
|
});
|
|
|
|
assert.equal(syncCalls.length, 1);
|
|
assert.equal(syncCalls[0].kind, 'scheduled_task');
|
|
});
|
|
|
|
test('attachUnifiedTaskSync syncs lifecycle on markTaskSucceeded', async () => {
|
|
const lifecycleCalls = [];
|
|
const scheduledTaskService = {
|
|
async markTaskSucceeded(task) {
|
|
return {
|
|
...task,
|
|
status: 'active',
|
|
nextRunAt: 9000,
|
|
lastRunAt: 8000,
|
|
};
|
|
},
|
|
};
|
|
attachUnifiedTaskSync({
|
|
scheduleService: {},
|
|
scheduledTaskService,
|
|
taskUnifiedService: {
|
|
async syncLegacyLifecycle(payload) {
|
|
lifecycleCalls.push(payload);
|
|
},
|
|
},
|
|
pool: { async query() { return [[]]; } },
|
|
env: { H5_UNIFIED_TASKS_ENABLED: '1' },
|
|
});
|
|
await scheduledTaskService.markTaskSucceeded({
|
|
id: 'task-1',
|
|
userId: 'user-1',
|
|
recurrence: 'daily',
|
|
});
|
|
assert.equal(lifecycleCalls.length, 1);
|
|
assert.equal(lifecycleCalls[0].status, 'active');
|
|
});
|
|
|
|
test('attachUnifiedTaskSync is noop when feature disabled', async () => {
|
|
const syncCalls = [];
|
|
const scheduledTaskService = {
|
|
async createTask() {
|
|
return { id: 'task-1' };
|
|
},
|
|
};
|
|
attachUnifiedTaskSync({
|
|
scheduleService: {},
|
|
scheduledTaskService,
|
|
taskUnifiedService: {
|
|
async syncFromCommit() {
|
|
syncCalls.push(true);
|
|
},
|
|
},
|
|
pool: { async query() { return [[]]; } },
|
|
env: { H5_UNIFIED_TASKS_ENABLED: '0' },
|
|
});
|
|
await scheduledTaskService.createTask({ userId: 'user-1' });
|
|
assert.equal(syncCalls.length, 0);
|
|
});
|