a54210b0d1
新增共享 HostBridge 公开主站 origin 和默认 URL 常量 移动壳启动 URL、分享和 WebView 策略改为引用共享主站来源 桌面壳配置检查反查 Rust WEB_APP_ORIGIN 与共享契约一致 同步原生壳方案和共享决策记录
112 lines
3.7 KiB
TypeScript
112 lines
3.7 KiB
TypeScript
import { describe, expect, test } from 'vitest';
|
|
|
|
import {
|
|
HOST_BRIDGE_PUBLIC_WEB_ORIGIN,
|
|
HOST_BRIDGE_PUBLIC_WEB_URL,
|
|
HOST_BRIDGE_VERSION,
|
|
} from '../../../../packages/shared/src/contracts/hostBridge';
|
|
import {
|
|
ALLOWED_PRODUCTION_WEB_ORIGIN,
|
|
DEFAULT_MOBILE_SHELL_WEB_URL,
|
|
buildMobileShellUrl,
|
|
resolveMobileShellBaseWebUrl,
|
|
} from './url';
|
|
|
|
describe('buildMobileShellUrl', () => {
|
|
test('默认 H5 地址指向真实主站', () => {
|
|
expect(DEFAULT_MOBILE_SHELL_WEB_URL).toBe(HOST_BRIDGE_PUBLIC_WEB_URL);
|
|
expect(ALLOWED_PRODUCTION_WEB_ORIGIN).toBe(HOST_BRIDGE_PUBLIC_WEB_ORIGIN);
|
|
});
|
|
|
|
test('为 H5 附加原生移动壳上下文', () => {
|
|
const url = new URL(
|
|
buildMobileShellUrl('https://app.genarrative.world/works/detail?work=PZ-1', {
|
|
platform: 'ios',
|
|
hostVersion: '0.1.0',
|
|
capabilities: ['host.getRuntime', 'share.open'],
|
|
}),
|
|
);
|
|
|
|
expect(url.searchParams.get('clientRuntime')).toBe('native_app');
|
|
expect(url.searchParams.get('clientType')).toBe('native_app');
|
|
expect(url.searchParams.get('hostShell')).toBe('expo_mobile');
|
|
expect(url.searchParams.get('hostPlatform')).toBe('ios');
|
|
expect(url.searchParams.get('hostVersion')).toBe('0.1.0');
|
|
expect(url.searchParams.get('bridgeVersion')).toBe(
|
|
HOST_BRIDGE_VERSION.toString(),
|
|
);
|
|
expect(url.searchParams.get('hostCapabilities')).toBe(
|
|
'host.getRuntime,share.open',
|
|
);
|
|
expect(url.searchParams.get('work')).toBe('PZ-1');
|
|
});
|
|
|
|
test('支持按平台注入不同能力清单', () => {
|
|
const iosUrl = new URL(
|
|
buildMobileShellUrl('https://app.genarrative.world/', {
|
|
platform: 'ios',
|
|
hostVersion: '0.1.0',
|
|
capabilities: ['host.getRuntime', 'app.setBadgeCount'],
|
|
}),
|
|
);
|
|
const androidUrl = new URL(
|
|
buildMobileShellUrl('https://app.genarrative.world/', {
|
|
platform: 'android',
|
|
hostVersion: '0.1.0',
|
|
capabilities: ['host.getRuntime'],
|
|
}),
|
|
);
|
|
|
|
expect(iosUrl.searchParams.get('hostCapabilities')).toBe(
|
|
'host.getRuntime,app.setBadgeCount',
|
|
);
|
|
expect(androidUrl.searchParams.get('hostCapabilities')).toBe(
|
|
'host.getRuntime',
|
|
);
|
|
});
|
|
|
|
test('移动壳基准 URL 只接受生产主站和本机开发入口', () => {
|
|
expect(
|
|
resolveMobileShellBaseWebUrl('https://app.genarrative.world/path'),
|
|
).toBe(
|
|
'https://app.genarrative.world/path',
|
|
);
|
|
expect(resolveMobileShellBaseWebUrl(' http://127.0.0.1:3000/ ')).toBe(
|
|
'http://127.0.0.1:3000/',
|
|
);
|
|
expect(resolveMobileShellBaseWebUrl('http://localhost:3000/')).toBe(
|
|
'http://localhost:3000/',
|
|
);
|
|
expect(resolveMobileShellBaseWebUrl('https://example.com/path')).toBe(
|
|
DEFAULT_MOBILE_SHELL_WEB_URL,
|
|
);
|
|
expect(resolveMobileShellBaseWebUrl('http://192.168.1.2:3000/')).toBe(
|
|
DEFAULT_MOBILE_SHELL_WEB_URL,
|
|
);
|
|
expect(resolveMobileShellBaseWebUrl('javascript:alert(1)')).toBe(
|
|
DEFAULT_MOBILE_SHELL_WEB_URL,
|
|
);
|
|
expect(resolveMobileShellBaseWebUrl('/relative/path')).toBe(
|
|
DEFAULT_MOBILE_SHELL_WEB_URL,
|
|
);
|
|
expect(resolveMobileShellBaseWebUrl('')).toBe(DEFAULT_MOBILE_SHELL_WEB_URL);
|
|
expect(resolveMobileShellBaseWebUrl(null)).toBe(
|
|
DEFAULT_MOBILE_SHELL_WEB_URL,
|
|
);
|
|
});
|
|
|
|
test('非法启动 URL 回退到默认 H5 地址并继续附加宿主上下文', () => {
|
|
const url = new URL(
|
|
buildMobileShellUrl('javascript:alert(1)', {
|
|
platform: 'android',
|
|
hostVersion: '0.1.0',
|
|
capabilities: ['host.getRuntime'],
|
|
}),
|
|
);
|
|
|
|
expect(url.toString().startsWith(DEFAULT_MOBILE_SHELL_WEB_URL)).toBe(true);
|
|
expect(url.searchParams.get('clientRuntime')).toBe('native_app');
|
|
expect(url.searchParams.get('hostShell')).toBe('expo_mobile');
|
|
});
|
|
});
|