soulsync/tests/imports
Broque Thomas 698ecc99f0 Import history: Clear History button now sweeps stuck 'processing' rows
Reported: Clear History button on the Import page left zombie rows
behind. Every survivor showed "⧗ Processing" status from 2-9 days ago.

Trace: `_record_in_progress` inserts a `status='processing'` row up-front
so the UI can render the in-flight import while it runs; `_finalize_result`
updates it to `completed`/`failed` when the import finishes. When the
worker is killed mid-import (server restart, crash), the row never gets
finalized — stays at `processing` forever. The clear-history endpoint's
SQL `DELETE ... WHERE status IN (...)` listed every terminal status but
omitted `processing`, so zombies survived every click.

Fix: add `processing` to the delete list, but guard against nuking
genuinely-live imports by intersecting against the worker's
`_snapshot_active()` map — any folder hash currently registered in
`_active_imports` is excluded from the delete via an `AND folder_hash
NOT IN (...)` clause. `pending_review` deliberately left out so user
still has to approve/reject those explicitly.

One endpoint touched (`/api/auto-import/clear-completed` in
web_server.py). No worker changes — guard reuses the existing
`_snapshot_active()` method that the UI poller already calls.

5 new tests in `tests/imports/test_auto_import_clear_completed_endpoint.py`:
- Zombie `processing` rows swept, live `processing` row preserved
  (folder_hash currently in `_active_imports` survives)
- Response count matches actual delete count
- Empty active-set branch (unparameterized DELETE) — pinned because
  an empty SQL `IN ()` would be a syntax error
- Worker-unavailable returns 500 (pre-existing guard not regressed)
- `pending_review` rows always survive — never auto-swept

Full pytest sweep: 2758 passed (one pre-existing flaky timing test
on `test_import_singles_parallel.py` failed under full-suite CPU load,
passes in isolation in 2.95s — unrelated to this change).
2026-05-12 12:53:37 -07:00
..
test_album_matching_exact_id.py Auto-import matching: fix Deezer source classification + bump tolerance 2026-05-09 15:53:17 -07:00
test_album_matching_helper.py Auto-import polish: real-file tag reader test, source-aware duration, pin consolation 2026-05-09 11:08:09 -07:00
test_album_search_scoring.py Auto-import: fall through to other metadata sources when primary returns no match 2026-05-12 12:32:18 -07:00
test_auto_import_clear_completed_endpoint.py Import history: Clear History button now sweeps stuck 'processing' rows 2026-05-12 12:53:37 -07:00
test_auto_import_context_shape.py Auto-import: fall through to other metadata sources when primary returns no match 2026-05-12 12:32:18 -07:00
test_auto_import_executor.py Auto-import: bounded ThreadPoolExecutor + per-candidate UI state isolation 2026-05-09 17:45:42 -07:00
test_auto_import_live_progress.py Auto-import: live per-track progress + in-progress history row 2026-05-02 22:34:09 -07:00
test_auto_import_multi_disc_matching.py Auto-import: respect disc_number in dedup + match scoring 2026-05-08 22:36:51 -07:00
test_auto_import_multi_source_fallback.py Auto-import: fall through to other metadata sources when primary returns no match 2026-05-12 12:32:18 -07:00
test_auto_import_scanner_grouping.py Auto-import: dedup on folder_hash, not path — fixes silent-skip bug 2026-05-09 14:09:19 -07:00
test_auto_import_tag_reader_real_files.py Auto-import polish: real-file tag reader test, source-aware duration, pin consolation 2026-05-09 11:08:09 -07:00
test_build_single_import_context_typed_path.py Migrate album-info builders to typed Album path 2026-05-03 22:53:12 -07:00
test_dedup_orphan_cleanup.py Prune slskd dedup orphans after import 2026-05-01 09:35:08 -07:00
test_file_integrity.py Reject broken downloads before tagging via universal integrity check 2026-05-03 08:21:01 -07:00
test_import_album.py Rehome import helpers into core/imports 2026-04-27 19:54:44 +03:00
test_import_context.py Fix Spotify source ID fallback 2026-05-02 22:02:01 +03:00
test_import_file_ops.py Broaden import and metadata test coverage 2026-04-27 19:55:07 +03:00
test_import_filename.py Rehome import helpers into core/imports 2026-04-27 19:54:44 +03:00
test_import_guards.py Rehome import helpers into core/imports 2026-04-27 19:54:44 +03:00
test_import_paths.py fix: substitute \$cdnum in download paths and skip auto disc folder when template uses it 2026-04-28 21:32:24 -07:00
test_import_pipeline.py Reject broken downloads before tagging via universal integrity check 2026-05-03 08:21:01 -07:00
test_import_resolution_single_track_context.py Move metadata helpers into package modules 2026-04-29 11:28:42 +03:00
test_import_side_effects.py Auto-import: album duration = album total + conservative re-import UPDATE path 2026-05-09 21:19:35 -07:00
test_import_singles_route_through_album_path.py Route imported singles/EPs through album_path template 2026-04-30 21:33:09 -07:00
test_import_staging.py Rehome import helpers into core/imports 2026-04-27 19:54:44 +03:00
test_lossy_copy_delete_original.py Honor lossy_copy.delete_original after successful conversion 2026-05-02 14:26:46 -07:00
test_search_match_endpoints.py Deezer search: drop advanced-syntax at endpoint, free-text + rerank wins 2026-05-10 09:36:48 -07:00