"""Round 18: the 2026-07-02 "New backlog" batch. 1. Visualizer: gray-mode color slider pref + mode persists across launches. 2. External file drops insert at the drop position in a playlist. 3. Renaming artist/album/album_artist moves the file to keep the music folder organized (Artist/Album, Unknown Artist fallback). """ from PyQt6.QtCore import QObject, pyqtSignal from PyQt6.QtGui import QColor from lintunes import theme from lintunes.preferences import Preferences from lintunes.gui.visualizer import ( VisualizerWidget, MODE_ON, MODE_DIM, MODE_OFF) class _FakePlayer(QObject): audio_buffer = pyqtSignal(object) playing_changed = pyqtSignal(bool) track_changed = pyqtSignal(object) def __init__(self): super().__init__() self._playing = False def is_playing(self): return self._playing # -------------------------------------------------------------------------- # 1. Visualizer: gray color pref + persistent mode # -------------------------------------------------------------------------- class TestVisualizerModePersistence: def test_no_prefs_defaults_on(self, qapp): vis = VisualizerWidget(_FakePlayer()) assert vis._mode == MODE_ON def test_saved_mode_restored(self, qapp, tmp_path): prefs = Preferences(tmp_path) prefs.set("visualizer_mode", MODE_DIM) vis = VisualizerWidget(_FakePlayer(), prefs) assert vis._mode == MODE_DIM def test_saved_off_restored_and_stays_idle(self, qapp, tmp_path): prefs = Preferences(tmp_path) prefs.set("visualizer_mode", MODE_OFF) vis = VisualizerWidget(_FakePlayer(), prefs) assert vis._mode == MODE_OFF vis._on_playing_changed(True) # playback starts assert not vis._timer.isActive() def test_bogus_saved_mode_falls_back_to_on(self, qapp, tmp_path): prefs = Preferences(tmp_path) prefs.set("visualizer_mode", "sparkle") # hand-edited prefs file vis = VisualizerWidget(_FakePlayer(), prefs) assert vis._mode == MODE_ON def test_click_persists_mode_to_disk(self, qapp, tmp_path): prefs = Preferences(tmp_path) vis = VisualizerWidget(_FakePlayer(), prefs) vis.mousePressEvent(None) # on -> dim assert prefs.get("visualizer_mode") == MODE_DIM # A fresh Preferences (= next launch) sees it too. assert Preferences(tmp_path).get("visualizer_mode") == MODE_DIM class TestVisualizerGrayColor: def test_default_gray_resolves_for_visualizer_key(self, qapp): value = theme.default_gray("color_visualizer_gray") assert isinstance(value, int) assert 0 <= value <= 255 def test_slider_pref_drives_dim_color(self, qapp, tmp_path): prefs = Preferences(tmp_path) prefs.set("color_visualizer_gray", 100) vis = VisualizerWidget(_FakePlayer(), prefs) vis._mode = MODE_DIM assert vis._bar_color() == QColor(100, 100, 100) def test_unset_pref_keeps_derived_color(self, qapp, tmp_path): prefs = Preferences(tmp_path) with_prefs = VisualizerWidget(_FakePlayer(), prefs) without = VisualizerWidget(_FakePlayer()) with_prefs._mode = MODE_DIM without._mode = MODE_DIM assert with_prefs._bar_color() == without._bar_color() def test_on_mode_ignores_gray_pref(self, qapp, tmp_path): prefs = Preferences(tmp_path) prefs.set("color_visualizer_gray", 100) vis = VisualizerWidget(_FakePlayer(), prefs) assert vis._mode == MODE_ON assert vis._bar_color() == QColor(vis.palette().highlight().color()) def test_visualizer_row_in_preferences_dialog(self, qapp): from lintunes.gui.preferences_dialog import _COLOR_ROWS assert "color_visualizer_gray" in [key for key, _label in _COLOR_ROWS]