"""A track that silently fails to download leaves a 0-byte placeholder but the adapter still reports the full count; the pipeline must reject it (incomplete) rather than import a broken album. (Motivated by Bruno Mars "24K Magic" track 1 downloading as 0 bytes.)""" import os from lyra_worker.adapters.fakes import FakeQobuz from lyra_worker.claim import claim_next from lyra_worker.pipeline import run_pipeline from lyra_worker.types import DownloadResult from tests.conftest import insert_request class _ZeroByteTrackFake(FakeQobuz): """Stages (n-1) real tracks + one 0-byte placeholder but reports the full count n.""" def download(self, candidate, dest, on_progress): os.makedirs(dest, exist_ok=True) n = candidate.track_count for i in range(n - 1): with open(os.path.join(dest, f"{i + 1:02d} Track.flac"), "wb") as fh: fh.write(b"audio") with open(os.path.join(dest, f"{n:02d} Dead.flac"), "wb") as fh: fh.write(b"") # the silently-skipped track return DownloadResult(ok=True, path=dest, track_count=n) def test_zero_byte_track_fails_completeness(conn): job_id = insert_request(conn, artist="Radiohead", album="In Rainbows") claim_next(conn) run_pipeline(conn, job_id, [_ZeroByteTrackFake()], dest_root="/tmp/lib-zbt") with conn.cursor() as cur: cur.execute('SELECT state, error FROM "Job" WHERE id = %s', (job_id,)) state, error = cur.fetchone() assert state == "needs_attention" assert error == "incomplete download" # nothing was imported with conn.cursor() as cur: cur.execute('SELECT count(*) FROM "LibraryItem" WHERE artist = %s', ("Radiohead",)) assert cur.fetchone()[0] == 0