Files
device-voice-h5/tests/silence.test.mjs
邹进 d13be3580f
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 19m17s
feat: 延期微信支付在微信内直接拉起
- 微信支付下单带 app_type;拿到 pay_config 后与套餐购买一样拉起微信支付,继续支付同样处理
- 微信内打开时支付方式默认微信;取消支付保留同一请求号,再次确认不重复建单
2026-11-07 21:57:26 +09:00

108 lines
5.8 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,
silenceReminderRepeats,
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), []);
assert.deepEqual(getSilencePaymentOptions(['alipay', 'wechat'], true).map((item) => item.value), ['wechat', 'alipay']);
});
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'));
});
test('只有已过期未延期的提醒每次回首页都弹,待实名提醒每次登录一次', () => {
assert.equal(silenceReminderRepeats({ kind: 'expired' }), true);
assert.equal(silenceReminderRepeats({ kind: 'expired', pendingOrderNo: 'SE1' }), true);
assert.equal(silenceReminderRepeats({ kind: 'waiting' }), false);
assert.equal(silenceReminderRepeats(null), false);
});