Files
device-voice-h5/tests/silence.test.mjs
邹进 c11d1881ef
Some checks failed
构建并部署前端到测试环境 / build-and-deploy (push) Has been cancelled
fix: 沉默期提醒每次登录都弹,有未支付延期订单时提示去支付或作废
- 频率从每天一次改为每次登录一次:重新登录后会再次提醒,同一次登录内回首页不重复
- 已过期套餐有未支付延期订单时,弹窗提示继续支付或作废
2026-11-07 21:04:12 +09:00

98 lines
5.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.
import assert from 'node:assert/strict';
import test from 'node:test';
import {
createRequestIdKeeper,
getSilenceErrorMessage,
getSilencePaymentOptions,
getSilenceReasonText,
getSilenceStatusClass,
isPaymentLink,
isSilenceFeatureDisabled,
isSilenceOrderFinal,
pickSilenceReminder,
silenceReminderKey,
validateExtensionDays
} from '../utils/silence.js';
test('延期支付方式只取 wechat、alipay 与资产允许方式的交集,支付宝优先', () => {
assert.deepEqual(getSilencePaymentOptions(['wechat', 'wallet', 'alipay']).map((item) => item.value), ['alipay', 'wechat']);
assert.deepEqual(getSilencePaymentOptions(['wallet']), []);
assert.deepEqual(getSilencePaymentOptions(undefined), []);
});
test('延期天数校验:整数且在 min~max 内', () => {
assert.equal(validateExtensionDays('30', 30, 180), '');
assert.equal(validateExtensionDays(180, 30, 180), '');
assert.equal(validateExtensionDays('29', 30, 180), '延期天数需在 30~180 天之间');
assert.equal(validateExtensionDays('181', 30, 180), '延期天数需在 30~180 天之间');
assert.equal(validateExtensionDays('12.5', 30, 180), '请输入整数天数');
assert.equal(validateExtensionDays('', 30, 180), '请输入整数天数');
});
test('request_id:同一天数与支付方式复用,任一变化或重置后生成新的', () => {
let seq = 0;
const keeper = createRequestIdKeeper(() => `id-${++seq}`);
assert.equal(keeper.get(30, 'alipay'), 'id-1');
assert.equal(keeper.get(30, 'alipay'), 'id-1');
assert.equal(keeper.get(60, 'alipay'), 'id-2');
assert.equal(keeper.get(60, 'wechat'), 'id-3');
keeper.reset();
assert.equal(keeper.get(60, 'wechat'), 'id-4');
});
test('沉默期错误码转客户提示', () => {
assert.equal(getSilenceErrorMessage({ code: 1266, data: { min_days: 30, max_days: 180 } }), '延期天数需在 30~180 天之间');
assert.equal(getSilenceErrorMessage({ code: 1265, data: { min_months: 1, max_months: 6 } }), '超过可延期期限,可延期 1~6 个月');
assert.equal(getSilenceErrorMessage({ code: 1263, data: { reason: 'not_expired' } }), '套餐沉默期尚未过期,暂不需要延期');
assert.equal(getSilenceErrorMessage({ code: 1267 }), '免费延期次数已用完');
assert.equal(getSilenceErrorMessage({ code: 1271 }), '已有未完成的延期订单,请先完成支付或等待其关闭');
assert.equal(getSilenceErrorMessage({ code: 1274 }), '延期功能暂未开放');
assert.equal(getSilenceErrorMessage({ code: 1001, msg: '参数错误' }), '参数错误');
assert.equal(getSilenceErrorMessage({ paymentResultUnknown: true }), '网络异常,请稍后在"我的延期订单"中查看结果');
assert.equal(getSilenceErrorMessage({}, '兜底'), '兜底');
assert.equal(isSilenceFeatureDisabled({ code: 1274 }), true);
assert.equal(isSilenceFeatureDisabled({ code: 1266 }), false);
});
test('资格原因、状态样式、订单终态与支付链接判断', () => {
assert.equal(getSilenceReasonText('extension_disabled'), '该套餐不支持付费延期,请联系客服');
assert.equal(getSilenceReasonText('unknown'), '当前暂不能办理延期,请联系客服');
assert.equal(getSilenceStatusClass('expired'), 'silence-expired');
assert.equal(getSilenceStatusClass('other'), '');
assert.equal(isSilenceOrderFinal('completed'), true);
assert.equal(isSilenceOrderFinal('pending_payment'), false);
assert.equal(isPaymentLink('https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?x=1'), true);
assert.equal(isPaymentLink('weixin://wxpay/bizpayurl?pr=abc'), false);
assert.equal(isPaymentLink(''), false);
});
test('首页沉默期提醒:优先已过期可延期,其次 7 天内到期的待实名,含加油包子节点', () => {
const now = Date.parse('2026-11-07T10:00:00+08:00');
const node = (id, silence, children = []) => ({ package_usage_id: id, package_name: `套餐${id}`, silence, children });
assert.equal(pickSilenceReminder([], now), null);
assert.equal(pickSilenceReminder([node(1, null)], now), null);
assert.equal(pickSilenceReminder([node(1, { silence_status: 'expired', extendable: false })], now), null);
const expired = pickSilenceReminder([
node(1, { silence_status: 'waiting', silence_deadline_at: '2026-11-09T23:59:59+08:00' }),
node(2, null, [node(3, { silence_status: 'expired', extendable: true, silence_deadline_at: '2026-11-06T23:59:59+08:00' })])
], now);
assert.equal(expired.kind, 'expired');
assert.equal(expired.packageUsageId, 3);
const waiting = pickSilenceReminder([
node(4, { silence_status: 'waiting', silence_deadline_at: '2026-11-20T23:59:59+08:00' }),
node(5, { silence_status: 'waiting', silence_deadline_at: '2026-11-12T23:59:59+08:00' }),
node(6, { silence_status: 'waiting', silence_deadline_at: '2026-11-09T23:59:59+08:00' })
], now);
assert.equal(waiting.kind, 'waiting');
assert.equal(waiting.packageUsageId, 6);
assert.equal(waiting.remainingDays, 3);
assert.equal(pickSilenceReminder([node(7, { silence_status: 'ended' })], now), null);
const keyA = silenceReminderKey('A', { packageUsageId: 3, kind: 'expired' }, 'token-1');
assert.match(keyA, /^silence_reminder:A:3:expired:/);
assert.equal(keyA, silenceReminderKey('A', { packageUsageId: 3, kind: 'expired' }, 'token-1'));
assert.notEqual(keyA, silenceReminderKey('A', { packageUsageId: 3, kind: 'expired' }, 'token-2'));
});