Files
wxserver/server/test/reminder.test.js
T

132 lines
4.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const test = require('node:test')
const assert = require('node:assert')
const { useTempDb } = require('./helper')
useTempDb()
const db = require('../src/db')
const wx = require('../src/wx')
const quota = require('../src/quota')
const reminder = require('../src/reminder')
// 用「今天」为基准造数据,保证 daysUntil 落在期望值上
const TODAY = new Date()
const inDays = (n) => new Date(TODAY.getTime() + n * 86400000)
function makeAnniv(id, openid, personName, importance, offsetDays, remindDays) {
const d = inDays(offsetDays)
return {
id, openid, personId: 'p', personName, type: 'birthday',
isLunar: 0, solarYear: d.getFullYear(), solarMonth: d.getMonth() + 1, solarDay: d.getDate(),
importance, remindEnabled: 1, remindDays
}
}
function resetLogs() {
db.prepare('DELETE FROM remind_logs').run()
}
test('额度够时全部发出', async () => {
resetLogs()
quota.grant('uA', 5)
const sent = []
const restore = wx.sendSubscribeMessage
wx.sendSubscribeMessage = async (p) => { sent.push(p.data.name1.value); return { errcode: 0 } }
const items = [
makeAnniv('A1', 'uA', '甲', 'low', 0, 3),
makeAnniv('A2', 'uA', '乙', 'high', 0, 3)
]
const r = await reminder.runForUser('uA', items, TODAY)
wx.sendSubscribeMessage = restore
assert.strictEqual(r.ok, 2)
assert.strictEqual(r.skipped, 0)
assert.strictEqual(quota.getBalance('uA'), 3)
})
test('额度不足时当天优先、同级按重要程度', async () => {
resetLogs()
quota.grant('uB', 1)
const sent = []
const restore = wx.sendSubscribeMessage
wx.sendSubscribeMessage = async (p) => { sent.push(p.data.name1.value); return { errcode: 0 } }
const items = [
makeAnniv('B1', 'uB', '提前的', 'high', 3, 3), // 提前事件(daysUntil=3=remindDays
makeAnniv('B2', 'uB', '当天低', 'low', 0, 3), // 当天事件
makeAnniv('B3', 'uB', '当天高', 'high', 0, 3) // 当天事件,重要程度更高
]
const r = await reminder.runForUser('uB', items, TODAY)
wx.sendSubscribeMessage = restore
assert.strictEqual(r.ok, 1)
assert.strictEqual(r.skipped, 2)
assert.deepStrictEqual(sent, ['当天高'], '应当只发出当天且最重要的那条')
})
test('余额为 0 时不发任何请求', async () => {
resetLogs()
let called = 0
const restore = wx.sendSubscribeMessage
wx.sendSubscribeMessage = async () => { called++; return { errcode: 0 } }
const items = [makeAnniv('C1', 'uC', '丙', 'high', 0, 3)]
const r = await reminder.runForUser('uC', items, TODAY)
wx.sendSubscribeMessage = restore
assert.strictEqual(called, 0, '没额度就不该打请求')
assert.strictEqual(r.skipped, 1)
})
test('遇到 43101 立即归零并中止本用户剩余发送', async () => {
resetLogs()
quota.grant('uD', 9)
let called = 0
const restore = wx.sendSubscribeMessage
wx.sendSubscribeMessage = async () => {
called++
const e = new Error('发送订阅消息失败')
e.errcode = 43101
throw e
}
const items = [
makeAnniv('D1', 'uD', '甲', 'high', 0, 3),
makeAnniv('D2', 'uD', '乙', 'high', 0, 3),
makeAnniv('D3', 'uD', '丙', 'high', 0, 3)
]
const r = await reminder.runForUser('uD', items, TODAY)
wx.sendSubscribeMessage = restore
assert.strictEqual(called, 1, '失败一次就该停,不该继续打请求')
assert.strictEqual(quota.getBalance('uD'), 0, '余额应被归零校正')
assert.strictEqual(r.skipped, 3, '含失败那条在内全部计为 skipped')
})
test('非额度类错误只记 failed,不动余额', async () => {
resetLogs()
quota.grant('uE', 4)
const restore = wx.sendSubscribeMessage
wx.sendSubscribeMessage = async () => {
const e = new Error('网络炸了')
e.errcode = 40003
throw e
}
const items = [makeAnniv('E1', 'uE', '甲', 'high', 0, 3)]
const r = await reminder.runForUser('uE', items, TODAY)
wx.sendSubscribeMessage = restore
assert.strictEqual(r.fail, 1)
assert.strictEqual(quota.getBalance('uE'), 4, '配置/网络错误不该动余额')
})
test('skipped 会写入 remind_logs 便于排查', async () => {
resetLogs()
const items = [makeAnniv('F1', 'uF', '甲', 'high', 0, 3)]
await reminder.runForUser('uF', items, TODAY)
const row = db.prepare("SELECT * FROM remind_logs WHERE status = 'skipped'").get()
assert.ok(row, '应写入 skipped 日志')
assert.strictEqual(row.error, 'quota_exhausted')
})