58 lines
2.5 KiB
JavaScript
58 lines
2.5 KiB
JavaScript
import assert from 'node:assert/strict'
|
|
import { readFileSync } from 'node:fs'
|
|
import { runInNewContext } from 'node:vm'
|
|
import test from 'node:test'
|
|
|
|
function page(wx, bridgeReady = true) {
|
|
const html = readFileSync(new URL('../../backend/app/templates/wechat-binding-mobile.html', import.meta.url), 'utf8')
|
|
const script = html.match(/<script nonce="__NONCE__">([\s\S]*?)<\/script>/)[1]
|
|
const nodes = Object.fromEntries(['return-button', 'return-hint', 'wechat-sdk'].map(id => [id, { textContent: '', handlers: {}, addEventListener(name, fn) { this.handlers[name] = fn } }]))
|
|
const timers = [], events = {}, calls = []
|
|
const window = { WeixinJSBridge: bridgeReady ? {} : undefined, wx: wx === false ? undefined : { miniProgram: { navigateBack: args => calls.push(args), ...wx } } }
|
|
runInNewContext(script, { window, document: { getElementById: id => nodes[id], addEventListener: (name, fn) => { events[name] = fn } },
|
|
setTimeout: fn => { timers.push(fn); return timers.length }, clearTimeout() {} })
|
|
return { nodes, timers, events, calls, window }
|
|
}
|
|
|
|
test('mobile callback bridge returns to previous page without a login token or home redirect', () => {
|
|
const p = page({})
|
|
assert.equal(p.calls.length, 1)
|
|
assert.equal(p.calls[0].delta, 1)
|
|
p.nodes['return-button'].handlers.click()
|
|
assert.equal(p.calls.length, 1)
|
|
})
|
|
|
|
test('missing SDK keeps manual return hint and loaded SDK can recover', () => {
|
|
const p = page(false)
|
|
p.timers.forEach(fn => fn())
|
|
assert.match(p.nodes['return-hint'].textContent, /左上角/)
|
|
p.window.wx = { miniProgram: { navigateBack: args => p.calls.push(args) } }
|
|
p.nodes['wechat-sdk'].handlers.load()
|
|
assert.equal(p.calls.length, 1)
|
|
})
|
|
|
|
test('bridge failure or silent timeout permits retry with return button', () => {
|
|
for (const failure of ['fail', 'timeout']) {
|
|
const p = page({})
|
|
if (failure === 'fail') p.calls[0].fail(); else p.timers.forEach(fn => fn())
|
|
assert.match(p.nodes['return-hint'].textContent, /左上角/)
|
|
p.nodes['return-button'].handlers.click()
|
|
assert.equal(p.calls.length, 2)
|
|
}
|
|
})
|
|
|
|
|
|
test('late WeixinJSBridge readiness never queues duplicate navigation', () => {
|
|
const p = page({}, false)
|
|
p.nodes['wechat-sdk'].handlers.load()
|
|
p.nodes['return-button'].handlers.click()
|
|
p.timers.forEach(fn => fn())
|
|
assert.equal(p.calls.length, 0)
|
|
p.window.WeixinJSBridge = {}
|
|
p.events.WeixinJSBridgeReady()
|
|
assert.equal(p.calls.length, 1)
|
|
p.timers.forEach(fn => fn())
|
|
p.events.WeixinJSBridgeReady()
|
|
assert.equal(p.calls.length, 1)
|
|
})
|