Files
frontend-miniapp/tests/unit/WechatMiniProgramBridgeService.spec.ts
lyf d94d689b40
Some checks failed
CI / verify (push) Has been cancelled
修复讲解列表返回分流
2026-07-25 02:28:38 +08:00

109 lines
5.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// @vitest-environment happy-dom
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
const target = { latitude: 22.604321, longitude: 114.058765, name: '停车场 A&B', address: '龙华区 #1' }
const setEmbeddedRuntime = () => Object.assign(window, { __wxjs_environment: 'miniprogram' })
const loadService = async () => {
vi.resetModules()
return import('@/services/WechatMiniProgramBridgeService')
}
beforeEach(() => {
vi.useFakeTimers()
vi.stubGlobal('uni', { showToast: vi.fn() })
delete (window as Window & { wx?: unknown }).wx
delete (window as Window & { __wxjs_environment?: string }).__wxjs_environment
window.history.replaceState({}, '', '/')
})
afterEach(() => {
vi.useRealTimers()
vi.unstubAllGlobals()
document.querySelectorAll('script[data-wechat-js-sdk="true"]').forEach((node) => node.remove())
})
describe('微信小程序 web-view 桥接', () => {
it('普通浏览器立即返回 not-embedded不加载 SDK', async () => {
const { openWechatMiniProgramLocation } = await loadService()
await expect(openWechatMiniProgramLocation(target)).resolves.toEqual({ status: 'not-embedded' })
expect(document.querySelector('[data-wechat-js-sdk="true"]')).toBeNull()
})
it('嵌入小程序时通过 navigateBack 返回宿主页', async () => {
setEmbeddedRuntime()
const { returnToWechatMiniProgram } = await loadService()
const navigateBack = vi.fn(({ success }) => success())
Object.assign(window, {
wx: {
miniProgram: {
getEnv: (done: (value: { miniprogram: boolean }) => void) => done({ miniprogram: true }),
navigateBack
}
}
})
await expect(returnToWechatMiniProgram()).resolves.toEqual({ status: 'returned' })
expect(navigateBack).toHaveBeenCalledWith({
delta: 1,
success: expect.any(Function),
fail: expect.any(Function)
})
})
it('等待延迟注入的 bridge 后导航到编码后的宿主页', async () => {
setEmbeddedRuntime()
const { openWechatMiniProgramLocation } = await loadService()
const result = openWechatMiniProgramLocation(target)
await vi.advanceTimersByTimeAsync(100)
const navigateTo = vi.fn(({ success }) => success())
Object.assign(window, { wx: { miniProgram: { getEnv: (done: (value: { miniprogram: boolean }) => void) => done({ miniprogram: true }), navigateTo } } })
await vi.advanceTimersByTimeAsync(100)
await expect(result).resolves.toEqual({ status: 'opened' })
expect(navigateTo).toHaveBeenCalledWith(expect.objectContaining({
url: expect.stringContaining('/pages/open-location/index?latitude=22.604321&longitude=114.058765&name=%E5%81%9C%E8%BD%A6%E5%9C%BA%20A%26B')
}))
})
it('handles getEnv false, navigate fail, page not found, and callback timeout', async () => {
setEmbeddedRuntime()
const { openWechatMiniProgramLocation } = await loadService()
Object.assign(window, { wx: { miniProgram: { getEnv: (done: (value: { miniprogram: boolean }) => void) => done({ miniprogram: false }), navigateTo: vi.fn() } } })
await expect(openWechatMiniProgramLocation(target)).resolves.toEqual({ status: 'failed', reason: 'not-in-mini-program' })
Object.assign(window, { wx: { miniProgram: { getEnv: (done: (value: { miniprogram: boolean }) => void) => done({ miniprogram: true }) } } })
await expect(openWechatMiniProgramLocation(target)).resolves.toEqual({ status: 'failed', reason: 'bridge-unavailable' })
Object.assign(window, { wx: { miniProgram: { getEnv: (done: (value: { miniprogram: boolean }) => void) => done({ miniprogram: true }), navigateTo: vi.fn(({ fail }) => fail({ errMsg: 'navigateTo:fail permission denied' })) } } })
await expect(openWechatMiniProgramLocation(target)).resolves.toEqual({ status: 'failed', reason: 'navigation-failed' })
const navigateTo = vi.fn(({ fail }) => fail({ errMsg: 'navigateTo:fail page not found' }))
Object.assign(window, { wx: { miniProgram: { getEnv: (done: (value: { miniprogram: boolean }) => void) => done({ miniprogram: true }), navigateTo } } })
await expect(openWechatMiniProgramLocation(target)).resolves.toEqual({ status: 'failed', reason: 'page-not-found' })
Object.assign(window, { wx: { miniProgram: { getEnv: (done: (value: { miniprogram: boolean }) => void) => done({ miniprogram: true }), navigateTo: vi.fn() } } })
const timeoutResult = openWechatMiniProgramLocation(target)
await vi.advanceTimersByTimeAsync(3001)
await expect(timeoutResult).resolves.toEqual({ status: 'failed', reason: 'timeout' })
})
it('deduplicates rapid calls while navigation is in flight', async () => {
setEmbeddedRuntime()
const { openWechatMiniProgramLocation } = await loadService()
let succeed: (() => void) | undefined
const navigateTo = vi.fn(({ success }) => { succeed = success })
Object.assign(window, { wx: { miniProgram: { getEnv: (done: (value: { miniprogram: boolean }) => void) => done({ miniprogram: true }), navigateTo } } })
const first = openWechatMiniProgramLocation(target)
expect(openWechatMiniProgramLocation(target)).toBe(first)
await Promise.resolve()
await Promise.resolve()
await Promise.resolve()
expect(navigateTo).toHaveBeenCalledTimes(1)
succeed?.()
await expect(first).resolves.toEqual({ status: 'opened' })
expect(navigateTo).toHaveBeenCalledTimes(1)
})
})