/** * 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(); });