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'))); });