Files
Genarrative/apps/mobile-shell/src/host-bridge/dispatch.test.ts
T
kdletters ae3cdf4e69 收紧移动壳角标真实结果
移动 iOS 角标改为请求 badge 权限后调用 Expo Notifications

角标设置以 setBadgeCountAsync 返回值作为成功依据

测试和门禁覆盖权限拒绝与系统拒绝设置失败

文档和项目记忆同步角标能力边界
2026-06-20 18:00:51 +08:00

125 lines
2.8 KiB
TypeScript

import { describe, expect, test, vi } from 'vitest';
import {
HOST_BRIDGE_EXPO_MOBILE_IOS_CAPABILITIES,
HOST_BRIDGE_METHODS,
HOST_BRIDGE_PROTOCOL,
HOST_BRIDGE_VERSION,
type HostBridgeMethod,
type HostBridgeRequest,
} from '../../../../packages/shared/src/contracts/hostBridge';
import {
dispatchMobileHostBridgeRequest,
resetMobileHostBridgeDispatchForTest,
} from './dispatch';
vi.mock('expo-clipboard', () => ({
getStringAsync: vi.fn(),
setStringAsync: vi.fn(),
}));
vi.mock('expo-document-picker', () => ({
getDocumentAsync: vi.fn(),
}));
vi.mock('expo-file-system', () => ({
File: class TestFile {},
Paths: {
cache: 'file:///cache/',
},
}));
vi.mock('expo-haptics', () => ({
ImpactFeedbackStyle: {
Heavy: 'heavy',
Light: 'light',
Medium: 'medium',
},
impactAsync: vi.fn(),
}));
vi.mock('expo-image-picker', () => ({
PermissionStatus: {
DENIED: 'denied',
GRANTED: 'granted',
},
launchCameraAsync: vi.fn(),
launchImageLibraryAsync: vi.fn(),
requestCameraPermissionsAsync: vi.fn(),
requestMediaLibraryPermissionsAsync: vi.fn(),
}));
vi.mock('expo-linking', () => ({
canOpenURL: vi.fn(),
openURL: vi.fn(),
}));
vi.mock('expo-network', () => ({
getNetworkStateAsync: vi.fn(),
NetworkStateType: {
CELLULAR: 'CELLULAR',
ETHERNET: 'ETHERNET',
NONE: 'NONE',
WIFI: 'WIFI',
},
}));
vi.mock('expo-notifications', () => ({
AndroidImportance: {
DEFAULT: 'default',
},
getPermissionsAsync: vi.fn(),
IosAuthorizationStatus: {
PROVISIONAL: 3,
},
requestPermissionsAsync: vi.fn(),
scheduleNotificationAsync: vi.fn(),
setNotificationChannelAsync: vi.fn(),
setNotificationHandler: vi.fn(),
}));
vi.mock('expo-sharing', () => ({
isAvailableAsync: vi.fn(),
shareAsync: vi.fn(),
}));
vi.mock('react-native', () => ({
Appearance: {
getColorScheme: vi.fn(),
},
Platform: {
OS: 'android',
},
}));
function request(method: HostBridgeMethod): HostBridgeRequest {
return {
bridge: HOST_BRIDGE_PROTOCOL,
version: HOST_BRIDGE_VERSION,
id: `dispatch-${method}`,
method,
};
}
const IOS_UNDECLARED_HOST_BRIDGE_METHODS = HOST_BRIDGE_METHODS.filter(
(method) => !HOST_BRIDGE_EXPO_MOBILE_IOS_CAPABILITIES.includes(method),
);
describe('mobile HostBridge dispatch', () => {
test.each(IOS_UNDECLARED_HOST_BRIDGE_METHODS)(
'%s 未被移动壳声明时明确返回 unsupported',
async (method) => {
resetMobileHostBridgeDispatchForTest();
const response = await dispatchMobileHostBridgeRequest(request(method));
expect(response.ok).toBe(false);
if (response.ok) {
throw new Error(`${method} unexpectedly succeeded`);
}
expect(response.error.code).toBe('unsupported_method');
expect(response.error.message).toContain(method);
},
);
});