From 306df618bdf84ff9cca42c84b99cef723a61cb52 Mon Sep 17 00:00:00 2001 From: kdletters Date: Sat, 20 Jun 2026 11:52:53 +0800 Subject: [PATCH] =?UTF-8?q?=E9=94=81=E5=AE=9A=E7=A7=BB=E5=8A=A8=E7=9B=B8?= =?UTF-8?q?=E5=86=8C=E6=9D=83=E9=99=90=E6=8B=92=E7=BB=9D=E8=BE=B9=E7=95=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 移动文件单测覆盖相册权限拒绝不启动 picker 移动壳配置检查反查相册权限拒绝测试 --- apps/mobile-shell/scripts/check-config.mjs | 3 +++ apps/mobile-shell/src/host-bridge/files.test.ts | 15 +++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/apps/mobile-shell/scripts/check-config.mjs b/apps/mobile-shell/scripts/check-config.mjs index 17c913a24..4526e3b18 100644 --- a/apps/mobile-shell/scripts/check-config.mjs +++ b/apps/mobile-shell/scripts/check-config.mjs @@ -2078,6 +2078,9 @@ for (const snippet of [ 'exportAudioFile({', "code: 'unsupported_capability'", "code: 'cancelled'", + 'rejects image import before picker launch when library permission is denied', + "message: 'photo library permission denied'", + 'expect(imageLibraryMock).not.toHaveBeenCalled()', "message: 'camera permission denied'", "mediaTypes: ['images']", "options: { encoding: 'base64' }", diff --git a/apps/mobile-shell/src/host-bridge/files.test.ts b/apps/mobile-shell/src/host-bridge/files.test.ts index dd80582af..136cccaa0 100644 --- a/apps/mobile-shell/src/host-bridge/files.test.ts +++ b/apps/mobile-shell/src/host-bridge/files.test.ts @@ -288,6 +288,21 @@ describe('mobile HostBridge file actions', () => { expect(cameraMock).not.toHaveBeenCalled(); }); + test('rejects image import before picker launch when library permission is denied', async () => { + libraryPermissionMock.mockResolvedValueOnce({ + status: ImagePicker.PermissionStatus.DENIED, + granted: false, + canAskAgain: false, + expires: 'never', + }); + + await expect(importImageFile()).rejects.toMatchObject({ + code: 'host_error', + message: 'photo library permission denied', + }); + expect(imageLibraryMock).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'));