complete all test cases for the disabled pages share logic, including blacklist check, route judgment, share api behavior and network call control
254 lines
8.4 KiB
JavaScript
254 lines
8.4 KiB
JavaScript
/**
|
|
* mp-share-default.js 单元测试
|
|
*
|
|
* 测试重点:
|
|
* - _DISABLED_PAGES 黑名单机制
|
|
* - _isCurrentPageDisabled 正确判断 route
|
|
* - 命中禁用列表时,mixin 的 onShareAppMessage / onShareTimeline 返回 undefined
|
|
* - 命中禁用列表时,mixin 的 onLoad / onShow 不再调网络
|
|
* - 命中禁用列表时,会调 wx.hideShareMenu
|
|
*
|
|
* 跟 util.test.js 同样的策略:
|
|
* 因为源模块里 import 了 ./http.js,直接 require 会失败,所以把"被测逻辑"
|
|
* 复制一份到本测试文件(顶部"被测源码区块"),与原文件保持同步。
|
|
* _hideShareMenu / _isCurrentPageDisabled / mixin 主体 都拿到这里跑。
|
|
*
|
|
* 运行:
|
|
* node --test tests/mp-share-default.test.js
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
const test = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
|
|
// =============================================================
|
|
// 被测源码区块(与 common/js/mp-share-default.js 保持同步)
|
|
// =============================================================
|
|
|
|
function _safeGetCurrentPage() {
|
|
try {
|
|
const pages = typeof getCurrentPages === 'function' ? getCurrentPages() : [];
|
|
return pages.length > 0 ? pages[pages.length - 1] : null;
|
|
} catch (e) {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
const _DISABLED_PAGES = new Set([
|
|
'pages_tool/webview/webview', // webview 容器,转发无意义
|
|
]);
|
|
|
|
function _isCurrentPageDisabled() {
|
|
const page = _safeGetCurrentPage();
|
|
if (!page) return false;
|
|
const route = (page.route || (page.$page && page.$page.path) || '').replace(/^\//, '');
|
|
return _DISABLED_PAGES.has(route);
|
|
}
|
|
|
|
// 模拟 wx 收集器(测试用)
|
|
let _wxCalls = [];
|
|
function resetWx() { _wxCalls = []; }
|
|
|
|
function _hideShareMenu() {
|
|
try {
|
|
if (typeof globalThis.__wx !== 'undefined' && typeof globalThis.__wx.hideShareMenu === 'function') {
|
|
globalThis.__wx.hideShareMenu({ menus: ['shareAppMessage', 'shareTimeline'] });
|
|
}
|
|
} catch (e) {
|
|
try {
|
|
if (typeof globalThis.__wx !== 'undefined' && typeof globalThis.__wx.hideShareMenu === 'function') {
|
|
globalThis.__wx.hideShareMenu();
|
|
}
|
|
} catch (e2) { /* ignore */ }
|
|
}
|
|
}
|
|
|
|
// mixin 主体(简化版,只测 _isCurrentPageDisabled / _hideShareMenu 触发逻辑)
|
|
function createMixinHandlers() {
|
|
return {
|
|
onLoad(opts) {
|
|
this.__opts = opts;
|
|
if (_isCurrentPageDisabled()) {
|
|
_hideShareMenu();
|
|
return;
|
|
}
|
|
this.__networkCalled = true;
|
|
},
|
|
onShow() {
|
|
if (this.__mpShareCache) return;
|
|
if (_isCurrentPageDisabled()) return;
|
|
this.__networkCalled = true;
|
|
},
|
|
onShareAppMessage() {
|
|
if (_isCurrentPageDisabled()) return undefined;
|
|
return { title: 'shared', path: '/x' };
|
|
},
|
|
onShareTimeline() {
|
|
if (_isCurrentPageDisabled()) return undefined;
|
|
return { title: 'shared', query: 'a=1' };
|
|
}
|
|
};
|
|
}
|
|
|
|
// =============================================================
|
|
// 工具:把全局 getCurrentPages / wx mock 起来
|
|
// =============================================================
|
|
|
|
function setCurrentRoute(route) {
|
|
globalThis.getCurrentPages = function () {
|
|
return route === null ? [] : [{ route }];
|
|
};
|
|
}
|
|
|
|
function setWxMock(mockImpl) {
|
|
resetWx();
|
|
globalThis.__wx = {
|
|
hideShareMenu(opts) {
|
|
_wxCalls.push({ method: 'hideShareMenu', opts });
|
|
if (mockImpl && mockImpl.throwWithMenus) throw new Error('not supported');
|
|
}
|
|
};
|
|
}
|
|
|
|
function clearGlobals() {
|
|
delete globalThis.getCurrentPages;
|
|
delete globalThis.__wx;
|
|
resetWx();
|
|
}
|
|
|
|
// =============================================================
|
|
// _DISABLED_PAGES 内容
|
|
// =============================================================
|
|
test('黑名单包含 webview 页面', () => {
|
|
assert.ok(_DISABLED_PAGES.has('pages_tool/webview/webview'));
|
|
});
|
|
|
|
test('黑名单不包含普通商品详情页', () => {
|
|
assert.ok(!_DISABLED_PAGES.has('pages_goods/detail'));
|
|
assert.ok(!_DISABLED_PAGES.has('pages/index/index'));
|
|
});
|
|
|
|
// =============================================================
|
|
// _isCurrentPageDisabled 行为
|
|
// =============================================================
|
|
test('_isCurrentPageDisabled: 当前页是 webview 时返回 true', () => {
|
|
setCurrentRoute('pages_tool/webview/webview');
|
|
assert.equal(_isCurrentPageDisabled(), true);
|
|
});
|
|
|
|
test('_isCurrentPageDisabled: 当前页是其他页时返回 false', () => {
|
|
setCurrentRoute('pages_goods/detail');
|
|
assert.equal(_isCurrentPageDisabled(), false);
|
|
});
|
|
|
|
test('_isCurrentPageDisabled: 当前页带前导 / 时也认得', () => {
|
|
// mp-weixin 的 page.route 不带 /,但容错一下
|
|
setCurrentRoute('/pages_tool/webview/webview');
|
|
assert.equal(_isCurrentPageDisabled(), true);
|
|
});
|
|
|
|
test('_isCurrentPageDisabled: getCurrentPages 返回空时不报错', () => {
|
|
setCurrentRoute(null);
|
|
assert.equal(_isCurrentPageDisabled(), false);
|
|
});
|
|
|
|
test('_isCurrentPageDisabled: getCurrentPages 不存在时不报错', () => {
|
|
delete globalThis.getCurrentPages;
|
|
assert.equal(_isCurrentPageDisabled(), false);
|
|
});
|
|
|
|
// =============================================================
|
|
// mixin 主体:命中禁用列表时的行为
|
|
// =============================================================
|
|
test('mixin: 命中禁用列表时 onLoad 调 wx.hideShareMenu', () => {
|
|
clearGlobals();
|
|
setCurrentRoute('pages_tool/webview/webview');
|
|
setWxMock();
|
|
const m = createMixinHandlers();
|
|
m.onLoad.call({});
|
|
assert.equal(_wxCalls.length, 1, '应该调了一次 hideShareMenu');
|
|
assert.equal(_wxCalls[0].method, 'hideShareMenu');
|
|
assert.deepEqual(_wxCalls[0].opts, { menus: ['shareAppMessage', 'shareTimeline'] });
|
|
});
|
|
|
|
test('mixin: 命中禁用列表时 onLoad 不调网络', () => {
|
|
clearGlobals();
|
|
setCurrentRoute('pages_tool/webview/webview');
|
|
setWxMock();
|
|
const ctx = {};
|
|
createMixinHandlers().onLoad.call(ctx);
|
|
assert.equal(ctx.__networkCalled, undefined, '不应触发网络拉取');
|
|
});
|
|
|
|
test('mixin: 非命中页面 onLoad 调网络(且不调 hideShareMenu)', () => {
|
|
clearGlobals();
|
|
setCurrentRoute('pages_goods/detail');
|
|
setWxMock();
|
|
const ctx = {};
|
|
createMixinHandlers().onLoad.call(ctx);
|
|
assert.equal(ctx.__networkCalled, true, '应触发网络拉取');
|
|
assert.equal(_wxCalls.length, 0, '不应调 hideShareMenu');
|
|
});
|
|
|
|
test('mixin: 命中禁用列表时 onShow 不调网络', () => {
|
|
clearGlobals();
|
|
setCurrentRoute('pages_tool/webview/webview');
|
|
setWxMock();
|
|
const ctx = { __mpShareCache: null };
|
|
createMixinHandlers().onShow.call(ctx);
|
|
assert.equal(ctx.__networkCalled, undefined);
|
|
});
|
|
|
|
test('mixin: 命中禁用列表时 onShareAppMessage 返回 undefined', () => {
|
|
setCurrentRoute('pages_tool/webview/webview');
|
|
const m = createMixinHandlers();
|
|
const r = m.onShareAppMessage.call({});
|
|
assert.equal(r, undefined);
|
|
});
|
|
|
|
test('mixin: 命中禁用列表时 onShareTimeline 返回 undefined', () => {
|
|
setCurrentRoute('pages_tool/webview/webview');
|
|
const m = createMixinHandlers();
|
|
const r = m.onShareTimeline.call({});
|
|
assert.equal(r, undefined);
|
|
});
|
|
|
|
test('mixin: 非命中页面 onShareAppMessage 返回正常分享对象', () => {
|
|
setCurrentRoute('pages_goods/detail');
|
|
const m = createMixinHandlers();
|
|
const r = m.onShareAppMessage.call({});
|
|
assert.deepEqual(r, { title: 'shared', path: '/x' });
|
|
});
|
|
|
|
// =============================================================
|
|
// wx.hideShareMenu 失败时的降级
|
|
// =============================================================
|
|
test('_hideShareMenu: wx.hideShareMenu 不存在时静默', () => {
|
|
clearGlobals();
|
|
// 不设置 globalThis.__wx
|
|
assert.doesNotThrow(() => _hideShareMenu());
|
|
});
|
|
|
|
test('_hideShareMenu: menus 参数不支持时降级到无参', () => {
|
|
clearGlobals();
|
|
let secondCall = null;
|
|
globalThis.__wx = {
|
|
hideShareMenu(opts) {
|
|
if (opts && opts.menus) {
|
|
throw new Error('not supported');
|
|
}
|
|
secondCall = opts;
|
|
}
|
|
};
|
|
_hideShareMenu();
|
|
assert.equal(secondCall, undefined, '应降级到无参调用');
|
|
});
|
|
|
|
// =============================================================
|
|
// 清理
|
|
// =============================================================
|
|
test.afterEach(() => {
|
|
clearGlobals();
|
|
});
|