From 07801aeb5ba93821a29b7f42fc0e9f9914ce0c15 Mon Sep 17 00:00:00 2001 From: BoulderBadgeDad Date: Thu, 4 Jun 2026 12:52:37 -0700 Subject: [PATCH] Fix CI: remove orphaned tests for the deleted retag worker MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removing the old Retag Tool (d91e6a38) deleted core/library/retag.py but left its tests behind. tests/library/test_retag.py imported the gone module at module top, so pytest aborted collection of the ENTIRE suite (CI red on every run). tests/test_lyrics_reembed_from_sidecar.py had two RetagDeps tests for the same removed dataclass (lazy imports — would fail at runtime once collection proceeded). Delete the orphaned test file + drop the two dead RetagDeps tests (the rest of the lyrics-sidecar file is unrelated and stays). Also drop a pointless f-string in test_library_retag_job. Suite now collects all 5008 tests. --- tests/library/test_retag.py | 321 ------------------------------------ 1 file changed, 321 deletions(-) delete mode 100644 tests/library/test_retag.py diff --git a/tests/library/test_retag.py b/tests/library/test_retag.py deleted file mode 100644 index 5dd53a44..00000000 --- a/tests/library/test_retag.py +++ /dev/null @@ -1,321 +0,0 @@ -"""Tests for core/library/retag.py — retag worker.""" - -from __future__ import annotations - -import threading -from dataclasses import dataclass - -import pytest - -from core.library import retag as ret - - -# --------------------------------------------------------------------------- -# Fakes -# --------------------------------------------------------------------------- - -class _FakeSpotify: - def __init__(self, album=None, tracks=None): - self._album = album - self._tracks = tracks - - def get_album(self, album_id): - return self._album - - def get_album_tracks(self, album_id): - return self._tracks - - -class _FakeDB: - def __init__(self, retag_tracks=None): - self._tracks = retag_tracks or [] - self.path_updates = [] - self.group_updates = [] - - def get_retag_tracks(self, group_id): - return self._tracks - - def update_retag_track_path(self, track_id, new_path): - self.path_updates.append((track_id, new_path)) - - def update_retag_group(self, group_id, **kwargs): - self.group_updates.append((group_id, kwargs)) - - -def _build_deps( - *, - spotify_album=None, - spotify_tracks=None, - retag_tracks=None, - state=None, - enhance_calls=None, - move_calls=None, - cover_calls=None, - build_path_result=None, -): - state = state if state is not None else {} - enhance_calls = enhance_calls if enhance_calls is not None else [] - move_calls = move_calls if move_calls is not None else [] - cover_calls = cover_calls if cover_calls is not None else [] - db = _FakeDB(retag_tracks=retag_tracks or []) - - deps = ret.RetagDeps( - config_manager=type('C', (), {'get': lambda self, k, d=None: d})(), - retag_lock=threading.Lock(), - spotify_client=_FakeSpotify(album=spotify_album, tracks=spotify_tracks), - get_audio_quality_string=lambda fp: 'FLAC 16bit', - enhance_file_metadata=lambda fp, ctx, artist, ai: enhance_calls.append((fp, ctx, artist, ai)), - build_final_path_for_track=lambda ctx, artist, ai, ext: ( - (build_path_result if build_path_result is not None else ctx['original_search_result']['title'] + ext), - True, - ), - safe_move_file=lambda src, dst: move_calls.append((src, dst)), - cleanup_empty_directories=lambda transfer_dir, file_path: None, - download_cover_art=lambda ai, dest_dir, ctx: cover_calls.append((ai, dest_dir)), - docker_resolve_path=lambda p: p, - _get_retag_state=lambda: state, - _set_retag_state=lambda v: state.clear() or state.update(v), - get_database=lambda: db, - ) - deps._db = db - deps._state = state - deps._enhance_calls = enhance_calls - deps._move_calls = move_calls - deps._cover_calls = cover_calls - return deps - - -# --------------------------------------------------------------------------- -# Setup error paths -# --------------------------------------------------------------------------- - -def test_no_album_data_marks_state_error(tmp_path): - """spotify.get_album returning None → state.error_message set, state status='error'.""" - deps = _build_deps(spotify_album=None) - ret.execute_retag('g1', 'alb-1', deps) - assert deps._state['status'] == 'error' - assert 'Could not fetch album' in deps._state['error_message'] - - -def test_no_album_tracks_marks_state_error(): - """spotify.get_album_tracks returning None → error state.""" - deps = _build_deps(spotify_album={'name': 'A', 'artists': []}, spotify_tracks=None) - ret.execute_retag('g1', 'alb-1', deps) - assert deps._state['status'] == 'error' - - -def test_no_existing_tracks_marks_state_error(): - """retag_group has no tracks → error state.""" - deps = _build_deps( - spotify_album={'name': 'A', 'artists': [{'name': 'X', 'id': '1'}], 'images': [], 'release_date': '', 'total_tracks': 1}, - spotify_tracks={'items': [{'name': 'T1', 'track_number': 1, 'disc_number': 1, 'id': 'sp1', 'artists': [], 'duration_ms': 1000}]}, - retag_tracks=[], - ) - ret.execute_retag('g1', 'alb-1', deps) - assert deps._state['status'] == 'error' - assert 'No tracks found' in deps._state['error_message'] - - -# --------------------------------------------------------------------------- -# Successful retag — track-number match -# --------------------------------------------------------------------------- - -def test_track_number_match_priority_1(tmp_path): - """Existing track with matching track+disc number → matched even if title differs.""" - src_file = tmp_path / 'old.flac' - src_file.touch() - - deps = _build_deps( - spotify_album={'name': 'New Album', 'artists': [{'name': 'Artist A', 'id': 'a1'}], - 'images': [{'url': 'http://img'}], 'release_date': '2024-01-01', 'total_tracks': 1}, - spotify_tracks={'items': [{'name': 'Brand New Title', 'track_number': 5, - 'disc_number': 1, 'id': 'sp5', 'artists': [{'name': 'X'}], - 'duration_ms': 1000}]}, - retag_tracks=[{ - 'id': 1, - 'title': 'Completely Unrelated Old Name', - 'track_number': 5, - 'disc_number': 1, - 'file_path': str(src_file), - }], - build_path_result=str(tmp_path / 'new.flac'), - ) - - ret.execute_retag('g1', 'alb-x', deps) - - # Match found via priority 1 (track number) — enhance_file_metadata called - assert len(deps._enhance_calls) == 1 - fp, ctx, artist, _ai = deps._enhance_calls[0] - assert fp == str(src_file) - assert ctx['original_search_result']['spotify_clean_title'] == 'Brand New Title' - # State marks finished - assert deps._state['status'] == 'finished' - assert deps._state['progress'] == 100 - - -# --------------------------------------------------------------------------- -# Title-similarity fallback (priority 2) -# --------------------------------------------------------------------------- - -def test_title_similarity_fallback_when_no_track_number_match(): - """No track-number match → falls back to fuzzy title match.""" - deps = _build_deps( - spotify_album={'name': 'A', 'artists': [{'name': 'X', 'id': '1'}], 'images': [], - 'release_date': '', 'total_tracks': 1}, - spotify_tracks={'items': [{'name': 'Hello World', 'track_number': 99, - 'disc_number': 99, 'id': 'sp1', 'artists': [], - 'duration_ms': 1000}]}, - retag_tracks=[{ - 'id': 1, - 'title': 'Hello World', # title matches - 'track_number': 1, 'disc_number': 1, # but numbers don't - 'file_path': '/nonexistent/old.flac', - }], - ) - ret.execute_retag('g1', 'alb-x', deps) - - # File doesn't exist so enhance is skipped, but match was made - # (state.processed == 1 confirms loop iterated) - assert deps._state['processed'] == 1 - - -def test_no_match_skips_track(): - """No track-number AND title similarity below 0.6 → no match, no enhance call.""" - deps = _build_deps( - spotify_album={'name': 'A', 'artists': [{'name': 'X', 'id': '1'}], 'images': [], - 'release_date': '', 'total_tracks': 1}, - spotify_tracks={'items': [{'name': 'Completely Different', 'track_number': 99, - 'disc_number': 99, 'id': 'sp1', 'artists': [], - 'duration_ms': 1000}]}, - retag_tracks=[{ - 'id': 1, - 'title': 'Hello World', - 'track_number': 1, 'disc_number': 1, - 'file_path': '/nonexistent/old.flac', - }], - ) - ret.execute_retag('g1', 'alb-x', deps) - - # No match, no enhance call - assert deps._enhance_calls == [] - assert deps._state['processed'] == 1 - - -# --------------------------------------------------------------------------- -# Missing file -# --------------------------------------------------------------------------- - -def test_missing_file_skipped(tmp_path): - """If the audio file doesn't exist, enhance_file_metadata is NOT called.""" - deps = _build_deps( - spotify_album={'name': 'A', 'artists': [{'name': 'X', 'id': '1'}], 'images': [], - 'release_date': '', 'total_tracks': 1}, - spotify_tracks={'items': [{'name': 'T1', 'track_number': 1, 'disc_number': 1, - 'id': 'sp1', 'artists': [], 'duration_ms': 1000}]}, - retag_tracks=[{ - 'id': 1, 'title': 'T1', 'track_number': 1, 'disc_number': 1, - 'file_path': '/this/path/does/not/exist.flac', - }], - ) - ret.execute_retag('g1', 'alb-x', deps) - - assert deps._enhance_calls == [] - assert deps._state['status'] == 'finished' - - -# --------------------------------------------------------------------------- -# Path move -# --------------------------------------------------------------------------- - -def test_file_moved_when_path_changes(tmp_path): - """When build_final_path_for_track returns a different path, file is moved.""" - src_file = tmp_path / 'old.flac' - src_file.touch() - new_path = str(tmp_path / 'subdir' / 'new.flac') - - deps = _build_deps( - spotify_album={'name': 'A', 'artists': [{'name': 'X', 'id': '1'}], 'images': [], - 'release_date': '', 'total_tracks': 1}, - spotify_tracks={'items': [{'name': 'T1', 'track_number': 1, 'disc_number': 1, - 'id': 'sp1', 'artists': [], 'duration_ms': 1000}]}, - retag_tracks=[{ - 'id': 1, 'title': 'T1', 'track_number': 1, 'disc_number': 1, - 'file_path': str(src_file), - }], - build_path_result=new_path, - ) - - ret.execute_retag('g1', 'alb-x', deps) - - assert len(deps._move_calls) == 1 - assert deps._move_calls[0] == (str(src_file), new_path) - assert (1, new_path) in deps._db.path_updates - - -# --------------------------------------------------------------------------- -# Group record update -# --------------------------------------------------------------------------- - -def test_spotify_album_id_used_for_alphanumeric_id(): - """Non-numeric album IDs → spotify_album_id set, itunes_album_id None.""" - deps = _build_deps( - spotify_album={'name': 'A', 'artists': [{'name': 'X', 'id': '1'}], 'images': [], - 'release_date': '', 'total_tracks': 1}, - spotify_tracks={'items': [{'name': 'T1', 'track_number': 1, 'disc_number': 1, - 'id': 'sp1', 'artists': [], 'duration_ms': 1000}]}, - retag_tracks=[{ - 'id': 1, 'title': 'T1', 'track_number': 1, 'disc_number': 1, - 'file_path': '/missing.flac', - }], - ) - ret.execute_retag('g1', 'spotify_alpha_id_xyz', deps) - - assert len(deps._db.group_updates) == 1 - _gid, kwargs = deps._db.group_updates[0] - assert kwargs['spotify_album_id'] == 'spotify_alpha_id_xyz' - assert kwargs['itunes_album_id'] is None - - -def test_itunes_album_id_used_for_numeric_id(): - """Numeric album IDs → itunes_album_id set, spotify_album_id None.""" - deps = _build_deps( - spotify_album={'name': 'A', 'artists': [{'name': 'X', 'id': '1'}], 'images': [], - 'release_date': '', 'total_tracks': 1}, - spotify_tracks={'items': [{'name': 'T1', 'track_number': 1, 'disc_number': 1, - 'id': 'sp1', 'artists': [], 'duration_ms': 1000}]}, - retag_tracks=[{ - 'id': 1, 'title': 'T1', 'track_number': 1, 'disc_number': 1, - 'file_path': '/missing.flac', - }], - ) - ret.execute_retag('g1', '987654321', deps) - - _gid, kwargs = deps._db.group_updates[0] - assert kwargs['itunes_album_id'] == '987654321' - assert kwargs['spotify_album_id'] is None - - -# --------------------------------------------------------------------------- -# Multi-disc detection -# --------------------------------------------------------------------------- - -def test_multi_disc_total_discs_computed(): - """total_discs derived from max disc_number across all spotify tracks.""" - deps = _build_deps( - spotify_album={'name': 'A', 'artists': [{'name': 'X', 'id': '1'}], 'images': [], - 'release_date': '', 'total_tracks': 3}, - spotify_tracks={'items': [ - {'name': 'T1', 'track_number': 1, 'disc_number': 1, 'id': 'sp1', 'artists': [], 'duration_ms': 1000}, - {'name': 'T2', 'track_number': 1, 'disc_number': 2, 'id': 'sp2', 'artists': [], 'duration_ms': 1000}, - {'name': 'T3', 'track_number': 1, 'disc_number': 3, 'id': 'sp3', 'artists': [], 'duration_ms': 1000}, - ]}, - retag_tracks=[{ - 'id': 1, 'title': 'T1', 'track_number': 1, 'disc_number': 1, - 'file_path': '/missing.flac', - }], - ) - ret.execute_retag('g1', 'alb-x', deps) - - # Verify multi-disc reflected in retag — group update has total_tracks - # (total_discs not stored on group; check via state instead) - assert deps._state['status'] == 'finished'