soulsync/tests
BoulderBadgeDad 0514931140 Auto-wishlist airing: run at a fixed daily 1am, not a rolling 24h interval
The job shipped as a 24h 'schedule' because the system-automation seeder only armed
next_run for interval specs — a 'daily_time' spec sat idle and never fired. The
interval fired reliably but drifted with every restart (5min after startup, then
+24h) instead of a fixed wall-clock time, which is worse for 'today's airings' (you
want it queued overnight).

Fix, the robust way:
- Seeder now arms timed system triggers (daily/weekly/monthly) via next_run_at, not
  just interval ones. Event-based triggers still return None and are left alone.
- Spec -> daily_time {time:'01:00'} for fresh installs.
- _fix_airing_automation_schedule migrates the existing 24h-interval row to daily
  01:00 (the seeder only creates rows, never updates a drifted trigger). Idempotent.

_finish_run already reschedules daily_time to the next 1am, so it stays pinned.
2026-06-21 11:41:34 -07:00
..
artists
automation Auto-wishlist airing: run at a fixed daily 1am, not a rolling 24h interval 2026-06-21 11:41:34 -07:00
blocklist
database Preserve Navidrome album cover art 2026-05-25 19:51:38 -07:00
discovery Remove old auto-acting Quality Scanner tool (replaced by Quality Upgrade Finder job) 2026-06-13 12:14:45 -07:00
downloads
enrichment
imports Fix import artist override and verification review 2026-06-11 01:28:31 +02:00
library
matching
media_server Navidrome: pin music-folder selection by id, not name (survives renames) 2026-06-04 11:47:31 -07:00
metadata Multi-artist tags: Search → Download Now finally knows its metadata source (Netti93) 2026-06-09 17:20:16 -07:00
playback
playlists
radio
repair_jobs
search Multi-artist tags: Search → Download Now finally knows its metadata source (Netti93) 2026-06-09 17:20:16 -07:00
static
stats
streaming Stream button: the player never learns its stream is ready (2.6.5 regression) 2026-06-06 12:43:20 -07:00
sync Fix #792: 'reconcile' playlist sync mode (edit in place, keep image/description) 2026-06-04 15:15:49 -07:00
text
tools
watchlist
webui
wishlist Wishlist: manual "add to wishlist" now skips already-owned tracks (#825) 2026-06-09 10:55:45 -07:00
conftest.py tests: isolate the VIDEO database too (never open the real video_library.db) 2026-06-19 23:02:38 -07:00
test_acoustid_error_reporting.py
test_acoustid_normalize_angle_annotations.py
test_acoustid_scanner.py
test_acoustid_skip_logic.py
test_acoustid_version_mismatch.py
test_admin_gating.py
test_album_bundle.py
test_album_bundle_dispatch.py
test_album_completeness_job.py
test_album_mbid_consistency.py
test_amazon_outage.py
test_archive_pipeline.py
test_aria2_adapter.py
test_art_apply.py
test_art_preservation.py
test_artist_album_list_cache_nonspotify.py
test_artist_albums_cache_poisoning.py Artist pages: stop watchlist probes from poisoning the album-list cache 2026-06-07 09:49:30 -07:00
test_artist_catalog_disambiguation.py
test_artist_db_record_endpoint.py Artist detail: "DB Record" inspector — everything the DB knows about an artist 2026-06-11 16:57:48 -07:00
test_artist_export.py
test_artist_full_detail_source_id.py
test_artist_sync_stale_guard.py
test_artist_top_tracks_clients.py
test_atomic_audio_save.py Import: atomic tag saves so an interrupted/OOM save can't destroy the file (#819) 2026-06-08 13:46:28 -07:00
test_audiodb_worker_stuck_track.py
test_auth_proxy.py
test_auth_usage_throttle.py
test_auto_sync_js.py
test_canonical_alternates.py
test_canonical_columns_migration.py
test_canonical_db.py
test_canonical_manual_lock.py
test_canonical_orchestration.py
test_canonical_resolver.py
test_canonical_version.py
test_canonical_version_job.py
test_config_save_retry.py
test_content_filter_regex.py
test_context_qualifier_match.py
test_cover_art_targets.py
test_create_finding_dedup_counter.py
test_credentials_endpoints.py
test_dashboard_events.py
test_database_io_resilience.py
test_database_update_health.py
test_database_update_reconcile_hook.py
test_db_genres_json_normalization.py
test_db_integrity.py
test_db_isolation_guard.py tests: isolate the VIDEO database too (never open the real video_library.db) 2026-06-19 23:02:38 -07:00
test_db_migration_ledger.py
test_db_watchlist_amazon_id_migration.py
test_dead_file_cleaner_guard.py
test_debug_info_services.py
test_dedupe_source_ids.py
test_deezer_worker_artist_id_guard.py
test_discogs_collection_id_tagging.py
test_discogs_collection_source.py
test_discogs_id_typing.py
test_discogs_track_count.py
test_discover_section_controller_js.py
test_download_orchestrator_soundcloud.py
test_download_origins.py
test_download_plugin_conformance.py
test_downloads_pagination.py
test_duplicate_detector_mount_paths.py
test_duplicate_detector_slskd_dedup.py
test_duplicate_keep.py
test_embed_known_source_ids.py
test_empty_folder_cleaner.py
test_enrichment_art_preservation.py
test_enrichment_artist_id_guard.py
test_enrichment_services.py
test_existing_album_folder.py
test_expired_download_cleaner.py Expired Cleaner: rename the safety toggle to dry_run (default ON), matching Re-tag 2026-06-07 22:13:30 -07:00
test_featured_artist_completion.py
test_genius_backoff.py
test_hifi_default_push.py
test_hifi_instance_methods.py
test_hls_parsing.py
test_image_cache.py
test_import_album_match_endpoint.py
test_import_singles_parallel.py Restore soulsync logger state between parallel-imports tests 2026-05-01 08:45:17 -07:00
test_import_tag_preservation.py
test_integrity_failure_marks_task_failed.py
test_issue_837_find_add_preserves_playlist.py
test_jellyfin_album_thumb.py
test_launch_lock_gate.py
test_lb_series_detect.py
test_library_disk_usage.py
test_library_reorganize.py
test_library_reorganize_orchestrator.py
test_library_retag_job.py
test_library_stream_fallback.py
test_library_tag_payload.py
test_library_track_identity.py
test_lidarr_download_client.py
test_liked_songs_playlist.py
test_listenbrainz_manager.py
test_listening_stats_batch_queries.py
test_login_endpoints.py
test_login_gate.py
test_login_provisioning.py
test_lyrics_reembed_from_sidecar.py Fix CI: drop dead RetagDeps tests + pointless f-string 2026-06-04 12:53:05 -07:00
test_m3u_track_resolution.py
test_manual_library_match.py
test_manual_pick_no_auto_retry.py
test_manual_search_endpoint.py
test_matching_engine_cjk.py
test_member_login_password.py
test_memory_tracker.py
test_metadata_cache_table_recreate.py
test_mirrored_custom_name.py
test_missing_cover_art.py
test_missing_lyrics_job.py Lyrics Filler: convert track duration ms→s for LRClib (exact-match was silently defeated) 2026-06-07 19:45:10 -07:00
test_navidrome_cover_url.py
test_navidrome_self_heal.py
test_navidrome_stream_url.py
test_orphan_file_detector.py
test_path_resolve_confusables.py Delete: resolve the real on-disk file when DB metadata uses curly quotes (#833) 2026-06-09 22:28:53 -07:00
test_personalized_api.py
test_personalized_generators_curated.py
test_personalized_generators_singletons.py
test_personalized_generators_variants.py
test_personalized_manager.py Personalized pipeline: auto-refresh stale snapshots after watchlist scan 2026-05-15 20:53:03 -07:00
test_personalized_playlists_id_gate.py
test_pin_rate_limit.py
test_playlist_edit.py
test_playlist_materialize.py
test_playlist_materialize_service.py
test_playlist_reconcile.py
test_playlist_sources_adapters.py Fix: auto-sync capped public Spotify playlists at 100 tracks (#838) 2026-06-10 18:31:43 -07:00
test_profile_context.py
test_profile_password.py
test_profile_recovery.py
test_profile_spotify_resolution.py
test_provenance_id_persistence.py
test_prowlarr_client.py
test_qobuz_credential_sync.py
test_qobuz_playlists.py
test_recommendation_sources.py
test_release_dates.py
test_reorganize_alternate_edition.py
test_reorganize_canonical_source.py
test_reorganize_db_methods.py
test_reorganize_deleted_quarantine.py
test_reorganize_orphan_format_handling.py
test_reorganize_queue.py
test_reorganize_runner.py
test_reorganize_tag_source.py
test_reorganize_unknown_artist_hint.py
test_repair_worker_album_fill.py
test_repair_worker_unresolvable_folder_error.py
test_replaygain_filler_job.py
test_replaygain_summary_parse.py Fix: ReplayGain wrote same +52 dB gain to every track 2026-05-03 19:08:35 -07:00
test_request_cleanup_timer.py
test_resolve_mirrored_playlist.py
test_resolve_secret.py
test_retag_planner.py Library re-tag (1/3): pure planner — match source tracklist + per-field tag diff 2026-06-04 08:50:40 -07:00
test_reverse_proxy_mode.py
test_runtime_state.py
test_scan_wait_action.py
test_script_split_integrity.py
test_search_tracks_relevance.py
test_server_playlist_append_mode.py
test_service_credentials.py
test_settings_redaction.py
test_similar_artists_status_codes.py
test_similar_artists_worker.py
test_socketio_cors.py
test_soulseek_album_fallback.py
test_soulseek_album_poll_stall.py
test_soulseek_search_throttle.py
test_soundcloud_client.py
test_source_ids_registry.py
test_source_title.py
test_spa_deep_linking.py
test_spotify_free_metadata.py
test_spotify_free_status.py
test_spotify_public_api.py
test_spotify_token_cache.py
test_spotify_unavailable_reason.py Spotify: log WHY a request was skipped, not a catch-all "Not authenticated" 2026-06-06 09:40:52 -07:00
test_staging_album_provenance.py
test_stale_guard.py
test_stats_automations_esc_js.py
test_status_engine_fallback.py
test_subtitle_qualifier_match.py
test_sync_discovery_scan_events.py
test_tag_writer_multi_artist.py
test_tag_writer_placeholder_guard.py
test_tidal_album_tracks.py
test_tidal_auth_instructions.py
test_tidal_auth_redirect_uri.py
test_tidal_collection_tracks.py
test_tidal_favorite_albums_artists.py
test_tidal_playlist_batch_chunking.py
test_tidal_qualifier_filter.py
test_tidal_rate_limit_backoff.py
test_tidal_search_shortening.py
test_title_match_guard.py Fix #769: playlist sync matched wrong same-artist track with high confidence 2026-06-02 09:14:26 -07:00
test_tool_progress_events.py
test_torrent_cleanup_orphan.py
test_torrent_client_adapters.py
test_torrent_stall.py
test_torrent_usenet_plugins.py
test_track_artist_matching.py
test_track_number_repair.py
test_track_repair_canonical.py
test_track_search_single_query.py
test_unknown_artist_fixer.py
test_usenet_client_adapters.py
test_verification_admin_gate.py
test_verification_status_backfill.py
test_verification_tag_roundtrip.py
test_video_api.py video downloads: live tracking on the grabbed result + movie detail, redesigned cards 2026-06-20 09:41:05 -07:00
test_video_auto_wishlist_airing.py Video auto-wishlist: store the show poster too (last field the manual add had) 2026-06-21 10:27:01 -07:00
test_video_automations_builder.py video automations: working builder + New Automation button (own builder, not music's) 2026-06-19 23:02:52 -07:00
test_video_backfill.py video enrichment: keyless workers read 'Disabled' (not 'Not configured') when off 2026-06-18 23:29:22 -07:00
test_video_cache.py video: real TTL+LRU cache (thread-safe) + cache search — the kettui way 2026-06-15 13:02:24 -07:00
test_video_calendar_scope.py video calendar: watchlist-driven by default + an 'All library' toggle 2026-06-20 14:07:40 -07:00
test_video_database.py Video watchlist: strip dirty titles when sorting (leading-space fix) 2026-06-21 08:52:49 -07:00
test_video_detail_yt_reset.py video downloads: header 'Auto' picks ONE best across all sources; fix YT playlist leak 2026-06-20 10:48:55 -07:00
test_video_download_auto.py Video downloads: best-in-class post-process pipeline 2026-06-21 01:44:35 -07:00
test_video_download_config.py video downloads (phase 3): source mode + hybrid chain (soulseek/torrent/usenet only) 2026-06-19 00:15:13 -07:00
test_video_download_events.py video automations: post-download scan chain (parity with music's batch→scan→update) 2026-06-20 14:47:00 -07:00
test_video_download_pipeline.py video downloads Phase C: auto-retry + alternate-query requery 2026-06-19 17:12:44 -07:00
test_video_download_tracking.py Video: live per-episode download tracking + auto-wishlist today's airings 2026-06-21 02:27:08 -07:00
test_video_enrichment.py video enrichment: add a GLOBAL 'Retry all failed' (all workers, all kinds) 2026-06-20 14:15:18 -07:00
test_video_enrichment_manager.py video enrichment: add a GLOBAL 'Retry all failed' (all workers, all kinds) 2026-06-20 14:15:18 -07:00
test_video_import_page.py Video downloads: best-in-class post-process pipeline 2026-06-21 01:44:35 -07:00
test_video_importer.py Video downloads: best-in-class post-process pipeline 2026-06-21 01:44:35 -07:00
test_video_library_paths.py Video downloads: best-in-class post-process pipeline 2026-06-21 01:44:35 -07:00
test_video_manual_import.py Video downloads: best-in-class post-process pipeline 2026-06-21 01:44:35 -07:00
test_video_mediainfo.py Video downloads: best-in-class post-process pipeline 2026-06-21 01:44:35 -07:00
test_video_organization.py Video downloads: best-in-class post-process pipeline 2026-06-21 01:44:35 -07:00
test_video_person_watchlist.py video: add 'Add to Watchlist' button to person detail pages 2026-06-20 13:50:34 -07:00
test_video_quality_eval.py Video quality: recognize plain WEB + accept resolution-only releases 2026-06-21 02:11:40 -07:00
test_video_quality_profile.py video quality profile: loose resolution cutoff + movie/episode size split 2026-06-19 10:40:53 -07:00
test_video_release_parse.py Video quality: recognize plain WEB + accept resolution-only releases 2026-06-21 02:11:40 -07:00
test_video_retry.py video downloads Phase C: auto-retry + alternate-query requery 2026-06-19 17:12:44 -07:00
test_video_scan_scope.py video scan: harden library scope + pause ALL enrichers during any scan 2026-06-20 13:24:57 -07:00
test_video_scanner.py video scan: show a 'cleaning up' phase during the deep-scan prune 2026-06-20 13:44:35 -07:00
test_video_search_pipeline.py video search: each source returns its own results (was identical) 2026-06-19 13:56:04 -07:00
test_video_server_resolution.py Video side: own server connection (Plex/Jellyfin), music-style picker, isolated 2026-06-15 16:42:22 -07:00
test_video_side_shell.py Video downloads: best-in-class post-process pipeline 2026-06-21 01:44:35 -07:00
test_video_sidecars.py Video downloads: best-in-class post-process pipeline 2026-06-21 01:44:35 -07:00
test_video_slskd_search.py video search: REAL slskd search for the Soulseek source (was mocked) 2026-06-19 14:16:44 -07:00
test_video_subtitles.py Video downloads: best-in-class post-process pipeline 2026-06-21 01:44:35 -07:00
test_video_upsert_preserve.py video scan: only FULL resets enrichment; incremental/deep preserve it 2026-06-20 15:06:44 -07:00
test_video_wishlist_clear.py video wishlist: add a 'Clear all' button (movies / TV / YouTube) 2026-06-20 16:42:57 -07:00
test_video_youtube.py Playlist count: show the TRUE total + load ~200 (was capped at ~100 via yt-dlp) 2026-06-17 21:40:56 -07:00
test_video_youtube_enrichment.py video enrichment: fix DeArrow retry (was a silent no-op) 2026-06-20 12:52:06 -07:00
test_video_youtube_quality.py video downloads: separate YouTube quality profile (yt-dlp) 2026-06-19 10:45:38 -07:00
test_watchlist_album_match.py
test_watchlist_auto_download.py
test_watchlist_bulk_add.py
test_watchlist_itunes_id_repair.py
test_watchlist_itunes_match.py
test_watchlist_scan_history.py
test_watchlist_scanner_scan.py
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 Split metadata source and Spotify status 2026-05-02 22:02:00 +03:00
test_wishlist_pagination.py
test_worker_artist_disambiguation.py
test_worker_artist_match_gate.py
test_worker_existing_id_marks_matched.py
test_worker_utils_album_track_count.py
test_ws_connect_gate.py
test_yield_policy.py
test_youtube_ffmpeg_no_eager_download.py ffmpeg gate also covers is_available — fixes the actual leak path 2026-05-08 15:46:31 -07:00
test_youtube_js_runtime.py
test_youtube_search_dash_query.py
test_youtube_sync_idempotent_endpoints.py
test_youtube_track_meta.py