From 6a98ea0f21ab368841d84587a82fa19a7b143a27 Mon Sep 17 00:00:00 2001 From: Brad Anderson Date: Mon, 27 Jul 2026 23:36:56 -0700 Subject: [PATCH] fix: clear lyrics-review cache on job status change renderLyricsReview was caching its job ID only in the done path, allowing stale data to persist when switching between done/running/failed jobs. Now clears the cache in the failed and not-done branches so a previously- viewed done job always re-fetches when re-selected. Regression test: test_lyrics_review_cache_clears_on_job_status_change verifies both branches clear the cache key before rendering placeholders. --- src/songtrace/static/index.html | 2 ++ tests/test_web.py | 17 +++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/songtrace/static/index.html b/src/songtrace/static/index.html index 846b976..8d07dd3 100644 --- a/src/songtrace/static/index.html +++ b/src/songtrace/static/index.html @@ -872,10 +872,12 @@ function buildLyricsReview(data) { async function renderLyricsReview(job) { const box = document.getElementById("lyrics-review"); if (job.status === "failed") { + delete box.dataset.jobId; box.replaceChildren(emptyNote("job failed — nothing to review")); return; } if (job.status !== "done") { + delete box.dataset.jobId; box.replaceChildren(emptyNote("waiting for this song to finish…")); return; } diff --git a/tests/test_web.py b/tests/test_web.py index 4821819..8c3b0e9 100644 --- a/tests/test_web.py +++ b/tests/test_web.py @@ -433,6 +433,23 @@ def test_index_lyrics_review_uses_endash_for_time_ranges(): assert "–" in body +def test_lyrics_review_cache_clears_on_job_status_change(): + """Regression: switching between done/failed/running jobs must clear the + cache so a previously-viewed done job re-fetches when re-selected.""" + html = _index_html() + body = _fn_body(html, "renderLyricsReview") + # The "failed" branch must clear the cache before rendering the placeholder + assert re.search( + r'if\s*\(\s*job\.status\s*===\s*"failed"\s*\)\s*\{[^}]*' + r'delete\s+box\.dataset\.jobId', + body, re.S), "failed branch must delete cache key" + # The "not done" (queued/running) branch must clear the cache before rendering + assert re.search( + r'if\s*\(\s*job\.status\s*!==\s*"done"\s*\)\s*\{[^}]*' + r'delete\s+box\.dataset\.jobId', + body, re.S), "not done branch must delete cache key" + + def test_index_has_copy_path_control(): assert "copy-path" in _index_html()