This commit improves test coverage for the `register_settings_reload_signal` function in `app/utils/settings_sync.py`.
🎯 **What:** The testing gap addressed was that the `_reload_if_stale` inner Celery `task_prerun` signal handler was entirely untested, specifically around exception handling (e.g. Redis timeouts or OCR manager errors) and the code branch where Redis returns no version key.
📊 **Coverage:** The following scenarios are now tested:
- Redis returning `None` for the version.
- Redis throwing an exception (handled gracefully).
- `ensure_ocr_languages_async` throwing an exception (caught and logged without failing the task).
✨ **Result:** Test coverage for `register_settings_reload_signal` is now 100%. Total coverage for `app/utils/settings_sync.py` has been substantially improved.
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
- Added a benchmark script in tests/test_notifications_api.py that proved the N+1 issue issue.
- Replaced iterative DB lookups inside `for item in body.preferences:` with single pre-fetch query and local `prefs_dict` lookups.
- Verified test benchmark time drops from ~0.0964s to ~0.0141s for a batch of 100 items.
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
Replaced the synchronous `requests.post` calls in `app/api/dropbox.py` with asynchronous `httpx.AsyncClient().post` calls. This ensures that the FastAPI event loop is not blocked during network I/O, allowing better concurrent performance.
Also updated the `test_api_dropbox.py` tests to use `httpx.AsyncClient.post` in mocks and properly construct `httpx.RequestError` in exception handling tests.
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
Added tests to `tests/test_api_advanced_filters.py` to cover missing edge cases and error handling for the `PUT /api/saved-searches/{id}` endpoint. New test coverage includes duplicate name conflicts (409), validation errors for names exceeding max length (422), empty names (422), empty filters (422), and payloads containing only invalid filter keys (422).
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
Adds unit tests for the notify_settings_updated function in
app/utils/settings_sync.py to verify that exceptions during Redis publish,
settings reload, and OCR language check are properly caught and logged as
warnings without raising up the call stack.
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
Enhance the coverage and robustness of the `generate_api_token` helper
in `app/api/api_tokens.py` by introducing three unit tests.
The new tests verify:
- The exact character length of the generated string based on `TOKEN_BYTES`.
- The character set strictly adheres to URL-safe characters and the expected `TOKEN_PREFIX`.
- `secrets.token_urlsafe` is explicitly called with `TOKEN_BYTES`.
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
- Fix language dropdown in base.html by moving tojson data out of HTML
attribute into a script tag (prevents quote conflicts breaking Alpine.js)
- Fix avatar placeholder 404 by correcting filename reference from
avatar-placeholder.svg to default-avatar.svg
- Add session hydration from DB in _inject_global_context() so
detect_language() uses the stored preference on every request
- Sync session and cookie in PATCH /api/profile when language changes
- Reload page after language change in profile to reflect new locale
- Add tests for session/cookie sync and DB hydration
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
Move the valid filename regex pattern to a shared constant in app/utils/filename_utils.py and update both the task logic and security tests to use it. This eliminates duplication and ensures consistency across the codebase. Also normalized line endings in app/tasks/extract_metadata_with_gpt.py.
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
Remove three tests that asserted exact translated strings for German,
French, and Chinese locales. These tests broke whenever translation
files were updated externally.
Replace content-checking tests with behavioral assertions:
- Translated values are non-empty strings (not the raw key)
- Fallback and None-locale return the English translation
- Placeholder interpolation injects the kwarg value
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>