import assert from 'node:assert/strict' import { readFileSync, existsSync } from 'node:fs' import { createRequire } from 'node:module' import test from 'node:test' const require = createRequire(new URL('../../web-admin/package.json', import.meta.url)) const { ref } = require('vue') const { parse, compileTemplate } = require('@vue/compiler-sfc') const pageUrl = new URL('../pages/common/wechat-official-account.vue', import.meta.url) const read = (path) => readFileSync(new URL(path, import.meta.url), 'utf8') function source() { assert.ok(existsSync(pageUrl), '缺少服务号关注引导页') return readFileSync(pageUrl, 'utf8') } function page(profiles = []) { const { descriptor } = parse(source()) const body = descriptor.scriptSetup.content.replace(/^import[^\n]+\n/gm, '') const calls = { toasts: [] } const uni = { showToast: (options) => calls.toasts.push(options) } const component = new Function('ref', 'uni', 'openWechatOfficialAccount', 'useWechatBinding', `${body}\nreturn { accountName, openAccountProfile, openingProfile, directOpenUnavailable }`)(ref, uni, (options) => profiles.push(options), () => ({})) return { ...component, calls } } test('workbench shortcut stays inside header at bottom right and has a registered route', () => { source() const workbench = read('../pages/workbench/workbench.vue') const header = workbench.slice(workbench.indexOf('')) assert.ok(header.indexOf('关注服务号') > header.indexOf('退出登录')) assert.match(header, /@click="openOfficialAccount"/) assert.match(workbench, /\.mp-header__follow\s*\{[^}]*position:\s*absolute;[^}]*right:\s*32rpx;[^}]*bottom:\s*20rpx;/) assert.match(workbench, /background:\s*#d6a343/) assert.match(workbench, /openPage\(PAGE_PATHS\.wechatOfficialAccount\)/) assert.match(read('../config/api.js'), /wechatOfficialAccount:\s*'\/pages\/common\/wechat-official-account'/) assert.match(read('../pages.json'), /"path":\s*"pages\/common\/wechat-official-account"/) }) test('guide covers all four notice types and compiles as a Vue template', () => { const content = source() for (const label of ['审批待办', '审批结果', '发放/支付完成', '证件到期提醒']) { assert.ok(content.includes(label), `未说明${label}`) } const { descriptor, errors } = parse(content) assert.deepEqual(errors, []) const result = compileTemplate({ source: descriptor.template.content, filename: 'wechat-official-account.vue', id: 'wechat-follow' }) assert.deepEqual(result.errors, []) assert.match(content, /min-height:\s*44px/) }) test('guide main action opens profile without copying and permits retry after failure', () => { const profiles = [] const p = page(profiles) p.openAccountProfile() p.openAccountProfile() assert.equal(profiles.length, 1) assert.equal(p.openingProfile.value, true) profiles[0].onUnavailable() profiles[0].onComplete() assert.equal(p.directOpenUnavailable.value, true) assert.equal(p.openingProfile.value, false) p.openAccountProfile() assert.equal(profiles.length, 2) profiles[1].onComplete() assert.equal(p.calls.toasts.length, 0, '打开主页不显示关注成功') assert.match(source(), /@click="openAccountProfile"/) })