Files
device-voice-h5/tests/silence-guard.test.mjs
邹进 37b650d41e
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 5m3s
feat: 沉默期已过期待延期时全局拦截,除绑定手机号与延期支付页外都跳转延期页
2026-11-08 16:41:53 +09:00

73 lines
3.7 KiB
JavaScript

import assert from 'node:assert/strict';
import test from 'node:test';
import { createSilenceGuard, isSilenceGuardAllowed, pagePathOf, silenceExtensionUrl } from '../utils/silence-guard.js';
const expiredItems = [{ package_usage_id: 45016, package_name: '套餐', silence: { silence_status: 'expired', extendable: true } }];
const okItems = [{ package_usage_id: 1, silence: { silence_status: 'ended' } }];
const setup = (items) => {
let clock = 0;
const calls = [];
const state = { items, session: { token: 't', identifier: 'A' } };
const guard = createSilenceGuard({
getSession: () => state.session,
loadPackageHistory: async (identifier) => { calls.push(identifier); return { items: state.items }; },
now: () => clock
});
return { guard, calls, state, advance: (ms) => { clock += ms; } };
};
test('只有绑定手机号、首页、登录授权与延期支付相关页面不拦截', () => {
for (const url of ['/pages/bind/bind?fromLogin=true', 'pages/index/index', '/pages/login/login', '/pages/silence-extension/silence-extension?package_usage_id=1',
'/pages/silence-payment/silence-payment', '/pages/silence-orders/detail?id=3', '/pages/alipay-payment/alipay-payment']) {
assert.equal(isSilenceGuardAllowed(url), true, url);
}
for (const url of ['/pages/change-phone/change-phone', '/pages/package-order/package-order', '/pages/switch/switch', '/pages/order-list/order-list',
'/pages/my-wallet/my-wallet', '/pages/device-exchange/device-exchange', '/pages/asset-package-history/asset-package-history', '/pages/notifications/notifications']) {
assert.equal(isSilenceGuardAllowed(url), false, url);
}
assert.equal(pagePathOf('/pages/a/b?x=1'), 'pages/a/b');
assert.equal(silenceExtensionUrl({ packageUsageId: 45016 }), '/pages/silence-extension/silence-extension?package_usage_id=45016');
});
test('沉默期已过期待延期时拦截,且每次都重新查询,延期完成后立即放行', async () => {
const { guard, calls, state } = setup(expiredItems);
assert.equal(guard.isKnownPass(), false);
assert.equal((await guard.resolveBlock()).packageUsageId, 45016);
assert.equal((await guard.resolveBlock()).packageUsageId, 45016);
assert.equal(calls.length, 2);
state.items = okItems;
assert.equal(await guard.resolveBlock(), null);
assert.equal(guard.isKnownPass(), true);
});
test('不需要延期时缓存放行结果 5 分钟,换资产或换登录重新检查', async () => {
const { guard, calls, state, advance } = setup(okItems);
assert.equal(await guard.resolveBlock(), null);
assert.equal(guard.isKnownPass(), true);
await guard.resolveBlock();
assert.equal(calls.length, 1);
advance(5 * 60 * 1000);
assert.equal(guard.isKnownPass(), false);
state.session = { token: 't', identifier: 'B' };
assert.equal(guard.isKnownPass(), false);
state.items = expiredItems;
assert.equal((await guard.resolveBlock()).packageUsageId, 45016);
});
test('未登录不拦截;查询失败放行但不缓存', async () => {
const anon = createSilenceGuard({ getSession: () => ({ token: '', identifier: '' }), loadPackageHistory: async () => { throw new Error('x'); } });
assert.equal(anon.isKnownPass(), true);
assert.equal(await anon.resolveBlock(), null);
const origError = console.error; console.error = () => {};
const failing = createSilenceGuard({ getSession: () => ({ token: 't', identifier: 'A' }), loadPackageHistory: async () => { throw new Error('x'); } });
assert.equal(await failing.resolveBlock(), null);
assert.equal(failing.isKnownPass(), false);
console.error = origError;
});
test('不可延期的过期套餐不拦截(无法办理延期)', async () => {
const { guard } = setup([{ package_usage_id: 2, silence: { silence_status: 'expired', extendable: false } }]);
assert.equal(await guard.resolveBlock(), null);
});