Files
readest/apps/readest-app/src/__tests__/utils/permission.test.ts
T
Huang Xin 9202864846 fix: real fix for library-save storage-permission crash + narrowed view-transition filter (#4943)
* fix(library): request storage permission when saving to a custom folder

On Android a custom library folder on shared storage needs All Files Access.
The import/settings/migrate paths request it, but the library-save path
(updateBook/updateBooks -> saveLibraryBooks) did not, so on a device without
the permission every save failed with EACCES; because callers (sync, imports)
don't await/catch it, it surfaced as an unhandled-rejection crash (Sentry
READEST-A). saveLibraryBooks now catches a storage-permission error, requests
the permission through the existing flow, and retries once. It prompts at most
once per session so background saves don't repeatedly open system settings; a
still-denied save is logged rather than crashing (the user was already shown
the All Files Access screen).

Fixes READEST-A

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(sentry): drop only the benign hidden-tab View Transition error

The View Transition API skips a transition when the tab is hidden; that
unhandled rejection is expected browser behavior and pure noise, so it is
dropped in before_send. A transition timeout abort (READEST-9) is NOT dropped:
a slow DOM update can signal a real performance problem, so it stays visible.

Fixes READEST-7

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 18:30:32 +02:00

24 lines
888 B
TypeScript

import { describe, test, expect } from 'vitest';
import { isStoragePermissionError } from '@/utils/permission';
describe('isStoragePermissionError', () => {
test('detects Android EACCES / permission-denied save failures', () => {
expect(
isStoragePermissionError(
new Error(
'Failed to save library.json: failed to open file at path: ' +
'/storage/emulated/0/Readest/Books/library.json.bak with error: ' +
'Permission denied (os error 13)',
),
),
).toBe(true);
expect(isStoragePermissionError('EACCES: permission denied')).toBe(true);
});
test('ignores unrelated errors', () => {
expect(isStoragePermissionError(new Error('disk full'))).toBe(false);
expect(isStoragePermissionError(new Error('JSON parse error'))).toBe(false);
expect(isStoragePermissionError(undefined)).toBe(false);
});
});