锁定移动扫码失败响应

移动扫码失败统一返回稳定 host_error

移动扫码 overlay 不再向 H5 透出相机权限细节

移动壳测试和配置检查反查扫码失败边界
This commit is contained in:
2026-06-20 13:09:51 +08:00
parent 1f4d662054
commit c381f9a3eb
6 changed files with 16 additions and 16 deletions
+3 -3
View File
@@ -2286,8 +2286,7 @@ for (const snippet of [
'describe(\'QrScannerOverlay\'',
'scanQrCode()',
'requestCameraPermissionsAsync',
"message: 'camera permission denied'",
"message: 'camera permission unavailable'",
"message: 'qr scanner unavailable'",
"message: 'qr scan cancelled'",
"test('logs and rejects the active scan when camera permission request fails'",
"'mobile QR scanner permission request failed'",
@@ -2344,6 +2343,7 @@ for (const scannerSnippet of [
'ok(request, await scanQrCode())',
'normalizeHostBridgeQrCodeValue',
"hostBridgeError('cancelled', 'qr scan cancelled')",
"hostBridgeError('host_error', 'qr scanner unavailable')",
]) {
if (!scannerSource.includes(scannerSnippet)) {
throw new Error(`mobile shell QR scanner module missing ${scannerSnippet}`);
@@ -2357,7 +2357,7 @@ for (const scannerTestSnippet of [
'cancelQrCodeScan',
'failQrCodeScan',
'qr scanner already active',
'camera permission denied',
'qr scanner unavailable',
'qr scan cancelled',
'PZ-00000001',
]) {
@@ -1782,7 +1782,7 @@ describe('handleMobileHostBridgeMessage', () => {
});
});
test('scanner.scanQrCode 取消和权限拒绝返回明确错误', async () => {
test('scanner.scanQrCode 取消和扫描失败返回明确错误', async () => {
const cancelledResponse = send(request('scanner.scanQrCode'));
cancelQrCodeScan();
@@ -1792,11 +1792,11 @@ describe('handleMobileHostBridgeMessage', () => {
});
const deniedResponse = send(request('scanner.scanQrCode'));
failQrCodeScan('camera permission denied');
failQrCodeScan();
expect(expectFailed(await deniedResponse).error).toEqual({
code: 'host_error',
message: 'camera permission denied',
message: 'qr scanner unavailable',
});
});
@@ -113,21 +113,21 @@ describe('mobile QR scanner helpers', () => {
});
});
test('fails the pending scan with a host_error message', async () => {
test('fails the pending scan with a stable host_error message', async () => {
const pendingScan = scanQrCode();
failQrCodeScan('camera permission denied');
failQrCodeScan();
await expect(pendingScan).rejects.toEqual({
code: 'host_error',
message: 'camera permission denied',
message: 'qr scanner unavailable',
});
});
test('ignores completion, cancellation and failure without a pending scan', () => {
expect(completeQrCodeScan('PZ-1')).toBe(false);
expect(() => cancelQrCodeScan()).not.toThrow();
expect(() => failQrCodeScan('camera permission denied')).not.toThrow();
expect(() => failQrCodeScan()).not.toThrow();
});
test('wraps the scanner result in the HostBridge response shape', async () => {
+2 -2
View File
@@ -101,12 +101,12 @@ export function cancelQrCodeScan() {
clearPendingQrScan();
}
export function failQrCodeScan(message: string) {
export function failQrCodeScan() {
if (!pendingQrScan) {
return;
}
pendingQrScan.reject(hostBridgeError('host_error', message));
pendingQrScan.reject(hostBridgeError('host_error', 'qr scanner unavailable'));
clearPendingQrScan();
}
@@ -113,7 +113,7 @@ describe('QrScannerOverlay', () => {
await expect(scanPromise).rejects.toMatchObject({
code: 'host_error',
message: 'camera permission denied',
message: 'qr scanner unavailable',
});
expect(overlayHarness.cameraViewProps.current).toBeNull();
});
@@ -128,7 +128,7 @@ describe('QrScannerOverlay', () => {
await expect(scanPromise).rejects.toMatchObject({
code: 'host_error',
message: 'camera permission unavailable',
message: 'qr scanner unavailable',
});
expect(warnSpy).toHaveBeenCalledWith(
'mobile QR scanner permission request failed',
@@ -44,7 +44,7 @@ export function QrScannerOverlay() {
return;
}
if (!permission.granted) {
failQrCodeScan('camera permission denied');
failQrCodeScan();
return;
}
setHasPermission(true);
@@ -52,7 +52,7 @@ export function QrScannerOverlay() {
.catch((error: unknown) => {
if (!disposed) {
logQrScannerPermissionFailure(error);
failQrCodeScan('camera permission unavailable');
failQrCodeScan();
}
});