Files
memind/wechat-admin.test.mjs
john 9b4a25799f Add smart ACK provider for WeChat MP replies
Replace fixed ackText with a rule-based AckProvider that picks
response templates by message type and intent (translate, summary,
rewrite, poster, ppt, mindmap, code, search, schedule). Pure sync,
zero I/O, auto-falls back to config.ackText on any error.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-26 15:19:03 +08:00

77 lines
3.2 KiB
JavaScript

import assert from 'node:assert/strict';
import test from 'node:test';
import { createWechatAdminService } from './wechat-admin.mjs';
test('wechat admin service lists and manages balance alerts', async () => {
const queries = [];
const pool = {
async query(sql, params = []) {
queries.push(sql);
if (sql.includes('FROM h5_balance_alert_subscriptions s')) {
return [[{ id: 'alert-1', user_id: 'user-1', username: 'alice', display_name: 'Alice', threshold_cents: 2000, channel: 'wechat', status: 'active', next_run_at: 1, last_run_at: null, last_notified_balance_cents: null, attempts: 0, last_error: null, source_text: '余额低于 20 元提醒我', created_at: 1, updated_at: 1 }]];
}
if (sql.includes('INSERT INTO h5_balance_alert_subscriptions')) {
return [{ affectedRows: 1 }, []];
}
if (sql.includes("UPDATE h5_balance_alert_subscriptions SET status = 'cancelled'")) {
return [{ affectedRows: 1 }, []];
}
if (sql.includes("UPDATE h5_balance_alert_subscriptions SET status = 'active'")) {
return [{ affectedRows: 1 }, []];
}
return [[]];
},
};
const service = createWechatAdminService(pool, { config: { enabled: true } });
const listed = await service.listBalanceAlerts();
assert.equal(listed.balanceAlerts.length, 1);
const created = await service.createBalanceAlert({ userId: 'user-1', thresholdCents: 2000, sourceText: '余额低于 20 元提醒我' });
assert.equal(created.ok, true);
assert.ok(queries.some((sql) => sql.includes('h5_balance_alert_subscriptions')));
});
test('wechat admin service creates multi-channel notification for all users', async () => {
const queries = [];
const wechatSent = [];
const pool = {
async query(sql) {
queries.push(sql);
if (sql.includes('SELECT id') && sql.includes('FROM h5_users')) {
return [[{ id: 'user-1' }, { id: 'user-2' }], []];
}
if (sql.includes('INSERT INTO h5_user_notifications')) {
return [{ affectedRows: 1 }, []];
}
if (sql.includes('FROM h5_user_notifications n')) {
return [[{ id: 'n1', user_id: 'user-1', username: 'john', display_name: 'John', channel: 'web', notification_type: 'manual', title: '测试通知', body: '这是一条网页端测试消息', status: 'unread', read_at: null, created_at: 1, updated_at: 1 }], []];
}
return [[], []];
},
};
const service = createWechatAdminService(pool, {
config: { enabled: true },
sendWechatTextToUser: async (userId, text) => {
wechatSent.push({ userId, text });
},
});
const created = await service.createWebNotification({
audience: 'all',
channels: ['web', 'wechat'],
notificationType: 'manual',
title: '测试通知',
body: '这是一条网页端测试消息',
});
assert.equal(created.ok, true);
assert.equal(created.created, 2);
assert.equal(created.wechatSent, 2);
assert.equal(created.targets, 2);
assert.equal(wechatSent.length, 2);
const listed = await service.listWebNotifications({ status: 'unread', limit: 10 });
assert.equal(listed.notifications.length, 1);
assert.equal(listed.notifications[0].title, '测试通知');
assert.ok(queries.some((sql) => sql.includes('h5_user_notifications')));
});