统一 H5 宿主壳能力协议
新增 HostBridge 通用宿主能力服务与测试 迁移登录支付分享订阅入口到通用 HostBridge API 保留微信小程序旧接口兼容包装 补充宿主壳协议文档与项目记忆
This commit is contained in:
230
src/services/host-bridge/hostBridge.test.ts
Normal file
230
src/services/host-bridge/hostBridge.test.ts
Normal file
@@ -0,0 +1,230 @@
|
||||
/* @vitest-environment jsdom */
|
||||
|
||||
import { afterEach, describe, expect, test, vi } from 'vitest';
|
||||
|
||||
import {
|
||||
canUseHostShareGrid,
|
||||
getHostRuntime,
|
||||
isWechatMiniProgramWebViewRuntime,
|
||||
navigateHostNativePage,
|
||||
openHostShareGrid,
|
||||
openWechatMiniProgramShareGridPage,
|
||||
postWechatMiniProgramMessage,
|
||||
requestHostLogin,
|
||||
requestHostPayment,
|
||||
requestWechatMiniProgramPayment,
|
||||
requestWechatMiniProgramPhoneLogin,
|
||||
resolveHostRuntime,
|
||||
setHostShareTarget,
|
||||
} from './hostBridge';
|
||||
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
window.history.replaceState(null, '', '/');
|
||||
window.wx = undefined;
|
||||
});
|
||||
|
||||
describe('hostBridge', () => {
|
||||
test('识别微信小程序、原生 App 和普通浏览器宿主', () => {
|
||||
expect(
|
||||
getHostRuntime({
|
||||
location: { search: '?clientRuntime=wechat_mini_program' },
|
||||
}).kind,
|
||||
).toBe('wechat_mini_program');
|
||||
|
||||
expect(
|
||||
resolveHostRuntime({
|
||||
navigator: {
|
||||
userAgent:
|
||||
'Mozilla/5.0 iPhone MicroMessenger/8.0 miniProgram',
|
||||
},
|
||||
}).kind,
|
||||
).toBe('wechat_mini_program');
|
||||
|
||||
expect(
|
||||
resolveHostRuntime({
|
||||
location: { search: '?clientRuntime=native_app' },
|
||||
}).kind,
|
||||
).toBe('native_app');
|
||||
|
||||
expect(resolveHostRuntime({ location: { search: '' } }).kind).toBe(
|
||||
'browser',
|
||||
);
|
||||
});
|
||||
|
||||
test('通过微信小程序原生页请求登录', async () => {
|
||||
const navigateTo = vi.fn((options) => {
|
||||
options.success?.();
|
||||
});
|
||||
window.history.replaceState(
|
||||
null,
|
||||
'',
|
||||
'/?clientRuntime=wechat_mini_program',
|
||||
);
|
||||
window.wx = {
|
||||
miniProgram: {
|
||||
navigateTo,
|
||||
},
|
||||
};
|
||||
|
||||
const requested = await requestHostLogin();
|
||||
|
||||
expect(requested).toBe(true);
|
||||
expect(navigateTo).toHaveBeenCalledWith({
|
||||
url: '/pages/web-view/index?authAction=login&returnTo=previous',
|
||||
success: expect.any(Function),
|
||||
fail: expect.any(Function),
|
||||
});
|
||||
|
||||
await expect(requestWechatMiniProgramPhoneLogin()).resolves.toBe(true);
|
||||
});
|
||||
|
||||
test('通过微信小程序原生页请求支付', async () => {
|
||||
const navigateTo = vi.fn((options) => {
|
||||
options.success?.();
|
||||
});
|
||||
vi.spyOn(Date, 'now').mockReturnValue(123456);
|
||||
window.history.replaceState(
|
||||
null,
|
||||
'',
|
||||
'/?clientRuntime=wechat_mini_program',
|
||||
);
|
||||
window.wx = {
|
||||
miniProgram: {
|
||||
navigateTo,
|
||||
},
|
||||
};
|
||||
|
||||
const handled = await requestHostPayment({
|
||||
payload: {
|
||||
timeStamp: '1',
|
||||
nonceStr: 'nonce',
|
||||
package: 'prepay_id=1',
|
||||
signType: 'RSA',
|
||||
paySign: 'sign',
|
||||
},
|
||||
orderId: 'order-1',
|
||||
});
|
||||
|
||||
expect(handled).toBe(true);
|
||||
const url = navigateTo.mock.calls[0]?.[0].url;
|
||||
expect(url).toContain('/pages/wechat-pay/index?');
|
||||
const parsed = new URL(url, 'https://mini.test');
|
||||
expect(parsed.searchParams.get('requestId')).toBe(
|
||||
'wechat_pay_order-1_123456',
|
||||
);
|
||||
expect(parsed.searchParams.get('orderId')).toBe('order-1');
|
||||
expect(parsed.searchParams.get('payParams')).toContain('prepay_id=1');
|
||||
|
||||
await expect(
|
||||
requestWechatMiniProgramPayment(
|
||||
{
|
||||
timeStamp: '1',
|
||||
nonceStr: 'nonce',
|
||||
package: 'prepay_id=1',
|
||||
signType: 'RSA',
|
||||
paySign: 'sign',
|
||||
},
|
||||
'order-1',
|
||||
),
|
||||
).resolves.toBeUndefined();
|
||||
});
|
||||
|
||||
test('普通浏览器不处理宿主登录、支付和原生页跳转', async () => {
|
||||
await expect(requestHostLogin()).resolves.toBe(false);
|
||||
await expect(
|
||||
requestHostPayment({
|
||||
payload: {
|
||||
timeStamp: '1',
|
||||
nonceStr: 'nonce',
|
||||
package: 'prepay_id=1',
|
||||
signType: 'RSA',
|
||||
paySign: 'sign',
|
||||
},
|
||||
orderId: 'order-1',
|
||||
}),
|
||||
).resolves.toBe(false);
|
||||
await expect(navigateHostNativePage('/pages/test/index')).resolves.toBe(
|
||||
false,
|
||||
);
|
||||
await expect(
|
||||
requestHostPayment({
|
||||
payload: null,
|
||||
orderId: 'order-1',
|
||||
}),
|
||||
).resolves.toBe(false);
|
||||
});
|
||||
|
||||
test('打开微信小程序九宫切图页并补齐绝对图片地址', async () => {
|
||||
const navigateTo = vi.fn((options) => {
|
||||
options.success?.();
|
||||
});
|
||||
window.history.replaceState(
|
||||
null,
|
||||
'',
|
||||
'/?clientRuntime=wechat_mini_program',
|
||||
);
|
||||
window.wx = {
|
||||
miniProgram: {
|
||||
navigateTo,
|
||||
},
|
||||
};
|
||||
|
||||
expect(canUseHostShareGrid()).toBe(true);
|
||||
const opened = await openHostShareGrid({
|
||||
imageUrl: '/cover.png',
|
||||
title: '暖灯猫街',
|
||||
publicWorkCode: 'PZ-00000001',
|
||||
});
|
||||
|
||||
expect(opened).toBe(true);
|
||||
const url = navigateTo.mock.calls[0]?.[0].url;
|
||||
const parsed = new URL(url, 'https://mini.test');
|
||||
expect(parsed.pathname).toBe('/pages/share-grid/index');
|
||||
expect(parsed.searchParams.get('imageUrl')).toBe(
|
||||
`${window.location.origin}/cover.png`,
|
||||
);
|
||||
expect(parsed.searchParams.get('title')).toBe('暖灯猫街');
|
||||
|
||||
await expect(
|
||||
openWechatMiniProgramShareGridPage({
|
||||
imageUrl: '/cover.png',
|
||||
title: '暖灯猫街',
|
||||
publicWorkCode: 'PZ-00000001',
|
||||
}),
|
||||
).resolves.toBe(true);
|
||||
});
|
||||
|
||||
test('向微信小程序宿主同步消息', () => {
|
||||
const postMessage = vi.fn();
|
||||
window.history.replaceState(
|
||||
null,
|
||||
'',
|
||||
'/?clientRuntime=wechat_mini_program',
|
||||
);
|
||||
window.wx = {
|
||||
miniProgram: {
|
||||
postMessage,
|
||||
},
|
||||
};
|
||||
|
||||
expect(
|
||||
setHostShareTarget({
|
||||
type: 'test',
|
||||
}),
|
||||
).toBe(true);
|
||||
expect(postMessage).toHaveBeenCalledWith({
|
||||
data: {
|
||||
type: 'test',
|
||||
},
|
||||
});
|
||||
|
||||
expect(postWechatMiniProgramMessage({ type: 'compat' })).toBe(true);
|
||||
});
|
||||
|
||||
test('普通浏览器不开放微信小程序能力', () => {
|
||||
expect(isWechatMiniProgramWebViewRuntime()).toBe(false);
|
||||
expect(canUseHostShareGrid()).toBe(false);
|
||||
expect(setHostShareTarget({ type: 'test' })).toBe(false);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user