Backend: cover cache and web API changes
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -820,6 +820,41 @@ class TestCoverDownscaling:
|
||||
# The untouched original still comes back, because colour extraction wants it.
|
||||
assert art == (folder / "cover.jpg").read_bytes()
|
||||
|
||||
def test_store_cover_also_writes_a_smaller_baseline_thumbnail(self, tmp_path: Path) -> None:
|
||||
from PIL import Image
|
||||
|
||||
from musicmouse.library.cache import THUMB_COVER_PX, LibraryCache
|
||||
|
||||
cache = LibraryCache(tmp_path)
|
||||
cache.prepare()
|
||||
cache.store_cover("abc123", self._jpeg((2400, 1800)))
|
||||
with Image.open(cache.thumb_path("abc123")) as thumb:
|
||||
assert max(thumb.size) == THUMB_COVER_PX
|
||||
assert thumb.format == "JPEG"
|
||||
assert "progressive" not in thumb.info
|
||||
assert abs(thumb.width / thumb.height - 2400 / 1800) < 0.02
|
||||
|
||||
def test_thumbnails_are_backfilled_for_covers_stored_without_one(
|
||||
self, tmp_path: Path
|
||||
) -> None:
|
||||
from PIL import Image
|
||||
|
||||
from musicmouse.library.cache import THUMB_COVER_PX, LibraryCache
|
||||
|
||||
cache = LibraryCache(tmp_path)
|
||||
cache.prepare()
|
||||
cache.cover_path("old").write_bytes(self._jpeg((384, 384)))
|
||||
assert not cache.thumb_path("old").exists()
|
||||
|
||||
assert cache.shrink_stored_covers() == 0 # nothing oversized...
|
||||
with Image.open(cache.thumb_path("old")) as thumb: # ...but the thumb appeared
|
||||
assert max(thumb.size) == THUMB_COVER_PX
|
||||
# Steady state: the thumbnail is not regenerated, and is not mistaken for a cover.
|
||||
before = cache.thumb_path("old").stat().st_mtime_ns
|
||||
assert cache.shrink_stored_covers() == 0
|
||||
assert cache.thumb_path("old").stat().st_mtime_ns == before
|
||||
assert not cache.thumb_path("old.thumb").exists()
|
||||
|
||||
def test_covers_written_by_an_older_version_are_migrated(self, tmp_path: Path) -> None:
|
||||
"""The scanner reuses an unchanged album without re-reading its tags, so a
|
||||
cover stored before the limit existed would otherwise never be rewritten."""
|
||||
|
||||
@@ -90,6 +90,7 @@ async def test_library_lists_every_album_with_its_tracks(client: Client) -> None
|
||||
async def test_a_missing_cover_is_a_404_not_an_error(client: Client) -> None:
|
||||
album = await album_by_title(client, "Fuchs")
|
||||
assert album["has_cover"] is False
|
||||
assert album["cover_v"] == 0
|
||||
assert (await client.get(f"/api/albums/{album['id']}/cover")).status_code == 404
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user