This commit is contained in:
87
tests/unit/WechatMiniProgramBridgeService.spec.ts
Normal file
87
tests/unit/WechatMiniProgramBridgeService.spec.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
// @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('等待延迟注入的 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)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user