soulsync/tests
Broque Thomas 6cdcf778f3 Lift /api/automations/* into core/automation/
Routes moved to thin parse-args/jsonify handlers; logic now lives in
three focused modules under core/automation/. 436 lines deleted from
web_server.py; 53 added back as wrappers.

Module split:
- core/automation/api.py — CRUD + run + history helpers. Each function
  takes (database, automation_engine, ...) explicitly and returns
  (response_body, http_status). Includes signal cycle detection
  preflight checks for create + update.
- core/automation/progress.py — owns the in-memory progress state dict
  + lock (mirroring the original web_server.py globals as module-level
  shared state so all callers see one view), init/update/history
  helpers, and the WebSocket emit loop.
- core/automation/signals.py — collect_known_signals for the builder
  autocomplete.

Out of scope (deferred):
- _register_automation_handlers — the 23+ action handler closures stay
  in web_server.py because each one is tightly coupled to feature-
  specific implementations (wishlist, watchlist, library scan, etc.).
- Worker functions (_process_wishlist_automatically, etc.) — belong
  with their feature lifts.
- _run_sync_task / _run_playlist_discovery_worker — sync + discovery
  PRs.

Behavior preserved 1:1:
- Same route response shapes + status codes
- Same JSON field hydration (trigger_config, action_config,
  notify_config, last_result, then_actions)
- Same backward-compat: empty then_actions + notify_type set →
  synthesize then_actions from notify_type/notify_config
- Same signal cycle detection behavior on create + update
- Same system-automation protection on delete + duplicate
- Same reschedule/cancel logic on toggle + bulk-toggle + update
- Same progress state shape (status, progress, phase, current_item,
  log capped at 50, started_at/finished_at, action_type)
- Same emit-on-finish socketio push from update_progress
- Same emit loop semantics (1s tick, snapshot active states, reap
  finished after window)

Pre-existing bugs preserved (will fix in follow-up PRs):
- emit_progress_loop uses naive datetime.now() against tz-aware
  started_at/finished_at, so the timeout-zombie check raises
  TypeError → caught → never fires, and the cleanup-after-window
  check raises → caught → state is reaped on FIRST tick regardless
  of the window. Tests document this behavior so the next PR can
  flip them to the corrected expectation.

Tests: 72 new under tests/automation/ (signals 10, progress 24,
api 38). Full suite: 861 passing (was 789). Ruff clean.
2026-04-27 18:05:14 -07:00
..
automation Lift /api/automations/* into core/automation/ 2026-04-27 18:05:14 -07:00
imports Tighten metadata and import safety 2026-04-27 20:28:05 +03:00
metadata Tighten metadata and import safety 2026-04-27 20:28:05 +03:00
search Search lift: pre-merge parity polish for cin's review 2026-04-27 15:32:48 -07:00
stats Lift /api/stats/* and /api/listening-stats/* into core/stats/ 2026-04-27 14:27:03 -07:00
conftest.py Remove emojis from all Python log and print statements 2026-04-11 21:11:02 -07:00
test_acoustid_scanner.py Fix null-pointer error in acoustid_scanner 2026-04-17 19:17:24 +03:00
test_album_completeness_job.py Fix DummyConfigManager position in album completeness job test 2026-04-27 19:55:06 +03:00
test_auth_usage_throttle.py test: auth last_used_at write throttle 2026-04-19 15:22:24 -07:00
test_content_filter_regex.py Fix watchlist content filters: live false positives + auto-scan bypass 2026-04-21 19:16:25 -07:00
test_dashboard_events.py Realign test file names 2026-04-17 21:25:01 +03:00
test_discogs_track_count.py Discogs: count rows with empty type_ as real tracks too 2026-04-25 08:27:44 -07:00
test_downloads_pagination.py Lift shared runtime state into core 2026-04-27 19:54:44 +03:00
test_library_reorganize.py Fix CI test failures from incomplete dummy config and encoding 2026-04-19 13:04:55 -07:00
test_library_reorganize_orchestrator.py Reorganize: fix moved-count + status/total UX issues from PR #377 review 2026-04-25 09:07:44 -07:00
test_listening_stats_batch_queries.py test: listening stats worker batched query paths 2026-04-19 15:22:25 -07:00
test_missing_cover_art.py Fix CI test failures from incomplete dummy config and encoding 2026-04-19 13:04:55 -07:00
test_reorganize_db_methods.py Reorganize queue: race + dedupe fixes from kettui review 2026-04-26 08:40:24 -07:00
test_reorganize_queue.py Reorganize queue: race + dedupe fixes from kettui review 2026-04-26 08:40:24 -07:00
test_reorganize_runner.py Library reorganize: FIFO queue with live status panel 2026-04-25 18:01:32 -07:00
test_repair_worker_album_fill.py Fix CI test failures from incomplete dummy config and encoding 2026-04-19 13:04:55 -07:00
test_request_cleanup_timer.py test: api/request periodic cleanup timer 2026-04-19 15:22:25 -07:00
test_runtime_state.py Tighten metadata and import safety 2026-04-27 20:28:05 +03:00
test_script_split_integrity.py Unify artist detail: route source artists to standalone page, retire inline Artists page 2026-04-22 17:00:52 -07:00
test_socketio_cors.py Socket.IO CORS: handle self-review nits 2026-04-26 19:24:43 -07:00
test_spa_deep_linking.py Rename Search page id from 'downloads' to 'search', bump to 2.43 2026-04-22 13:22:49 -07:00
test_sync_discovery_scan_events.py Realign test file names 2026-04-17 21:25:01 +03:00
test_tidal_search_shortening.py Reject Tidal streams that silently downgrade from the requested quality 2026-04-24 13:12:30 -07:00
test_tidal_stream_tier_verification.py Reject Tidal streams that silently downgrade from the requested quality 2026-04-24 13:12:30 -07:00
test_tool_progress_events.py Realign test file names 2026-04-17 21:25:01 +03:00
test_track_number_repair.py Fix CI test failures from incomplete dummy config and encoding 2026-04-19 13:04:55 -07:00
test_track_search_single_query.py test: api_search_tracks single-query track search 2026-04-19 15:22:24 -07:00
test_unknown_artist_fixer.py Fix test using old deezer_track_id column name 2026-04-20 21:11:45 -07:00
test_watchlist_scanner_scan.py Move the import flows and related post-processing pipelines into separate modules 2026-04-27 19:54:43 +03:00
test_websocket_client_transport.py Repoint websocket transport test to core.js after split 2026-04-22 11:30:39 -07:00
test_websocket_infrastructure.py Realign test file names 2026-04-17 21:25:01 +03:00
test_wishlist_pagination.py test: wishlist SQL pagination and category filter 2026-04-19 15:22:24 -07:00
test_worker_existing_id_marks_matched.py test: enrichment worker re-processing fix and migration backfill 2026-04-19 15:22:24 -07:00
test_worker_utils_album_track_count.py Fix Album Completeness job reporting zero findings for every album 2026-04-24 12:39:41 -07:00