test: add unit test for mp-share-default module
complete all test cases for the disabled pages share logic, including blacklist check, route judgment, share api behavior and network call control
This commit is contained in:
253
tests/mp-share-default.test.js
Normal file
253
tests/mp-share-default.test.js
Normal file
@@ -0,0 +1,253 @@
|
||||
/**
|
||||
* 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();
|
||||
});
|
||||
Reference in New Issue
Block a user