锁定移动图片权限请求失败边界
移动文件桥接把相册权限请求失败转为结构化 host_error 移动文件桥接把相机权限请求失败转为结构化 host_error 移动文件单测覆盖权限请求失败不启动原生选择器 移动壳配置检查反查权限请求失败边界
This commit is contained in:
@@ -303,6 +303,26 @@ describe('mobile HostBridge file actions', () => {
|
||||
expect(imageLibraryMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('rejects image import before picker launch when library permission request fails', async () => {
|
||||
libraryPermissionMock.mockRejectedValueOnce(new Error('native permission failed'));
|
||||
|
||||
await expect(importImageFile()).rejects.toMatchObject({
|
||||
code: 'host_error',
|
||||
message: 'photo library permission unavailable',
|
||||
});
|
||||
expect(imageLibraryMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('rejects image capture before camera launch when camera permission request fails', async () => {
|
||||
cameraPermissionMock.mockRejectedValueOnce(new Error('native permission failed'));
|
||||
|
||||
await expect(captureImageFile()).rejects.toMatchObject({
|
||||
code: 'host_error',
|
||||
message: 'camera permission unavailable',
|
||||
});
|
||||
expect(cameraMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('imports audio and exports binary files through controlled payloads', async () => {
|
||||
fileBase64Data.set('file:///picked/voice.mp3', MP3_BASE64);
|
||||
fileSizes.set('file:///picked/voice.mp3', Buffer.byteLength('ID3\x04\x00\x00\x00\x00\x00\x10'));
|
||||
|
||||
@@ -270,7 +270,15 @@ export async function exportMobileHostBridgeImageFile(
|
||||
}
|
||||
|
||||
export async function importImageFile(): Promise<FileImportImageResult> {
|
||||
const permission = await ImagePicker.requestMediaLibraryPermissionsAsync();
|
||||
let permission: ImagePicker.MediaLibraryPermissionResponse;
|
||||
try {
|
||||
permission = await ImagePicker.requestMediaLibraryPermissionsAsync();
|
||||
} catch {
|
||||
throw {
|
||||
code: 'host_error',
|
||||
message: 'photo library permission unavailable',
|
||||
} satisfies HostBridgeError;
|
||||
}
|
||||
if (permission.status !== ImagePicker.PermissionStatus.GRANTED) {
|
||||
throw {
|
||||
code: 'host_error',
|
||||
@@ -301,7 +309,15 @@ export async function importMobileHostBridgeImageFile(
|
||||
}
|
||||
|
||||
export async function captureImageFile(): Promise<FileImportImageResult> {
|
||||
const permission = await ImagePicker.requestCameraPermissionsAsync();
|
||||
let permission: ImagePicker.CameraPermissionResponse;
|
||||
try {
|
||||
permission = await ImagePicker.requestCameraPermissionsAsync();
|
||||
} catch {
|
||||
throw {
|
||||
code: 'host_error',
|
||||
message: 'camera permission unavailable',
|
||||
} satisfies HostBridgeError;
|
||||
}
|
||||
if (permission.status !== ImagePicker.PermissionStatus.GRANTED) {
|
||||
throw {
|
||||
code: 'host_error',
|
||||
|
||||
Reference in New Issue
Block a user