diff options
| author | Craig Jennings <c@cjennings.net> | 2026-07-06 17:14:58 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-07-06 17:14:58 -0500 |
| commit | e74bb871ac0aa7ab6e63cd39759b8850f1181ffe (patch) | |
| tree | b974964c460dbba843ad2a8f891e360b9e31824e /tests/test-music-config--art-cache-key.el | |
| parent | 0a7afa70fa9c2c20771696b303c9cae4aa7c58a2 (diff) | |
| download | dotemacs-e74bb871ac0aa7ab6e63cd39759b8850f1181ffe.tar.gz dotemacs-e74bb871ac0aa7ab6e63cd39759b8850f1181ffe.zip | |
feat(music): cover-art fetch and cache for the player (fancy UI phase 2)
Phase 2 gives each track a local cover-image path so phase 3's GUI has art to draw. A radio station uses its logo, a local file a sibling cover image, and anything without either falls back to a shipped vinyl placeholder.
I consolidated the .m3u parse into one richer cj/music--m3u-entries that reads :name, :uuid, and :favicon per station. Phase 1's cj/music--m3u-labels is now a thin projection of it, so names and art share a single cached disk read. New stations capture their favicon into a #RADIOBROWSERFAVICON line at creation, so most need no lookup later. A legacy station with only a UUID resolves its favicon through a byuuid call.
The render path never touches the network. cj/music-art--for-track reads only the cache and returns the placeholder until art exists. cj/music-art--ensure does the blocking fetch off that path. A fetched response is validated as an actual image before it's cached, so an HTML error page or an empty body becomes the placeholder, not a poisoned cache entry. Only http and https URLs are fetched, so an external favicon field can't reach a file:// resource. Art lands under data/music-art/, keyed by UUID or a file hash. cj/music-clear-art-cache empties it, with no automatic expiry.
The pure helpers carry the tests: the parser, the cache key, the favicon URL, and the image validation, each with Normal, Boundary, and Error cases. The fetch, the byuuid lookup, and the placeholder fallback are verified live against a real station. Local files use a sibling cover image for now. Embedded-tag extraction is deferred. The full suite is green.
Diffstat (limited to 'tests/test-music-config--art-cache-key.el')
| -rw-r--r-- | tests/test-music-config--art-cache-key.el | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/tests/test-music-config--art-cache-key.el b/tests/test-music-config--art-cache-key.el new file mode 100644 index 00000000..0ef82a21 --- /dev/null +++ b/tests/test-music-config--art-cache-key.el @@ -0,0 +1,54 @@ +;;; test-music-config--art-cache-key.el --- Tests for cover-art cache key -*- coding: utf-8; lexical-binding: t; -*- +;; +;; Author: Craig Jennings <c@cjennings.net> +;; +;;; Commentary: +;; Unit tests for `cj/music-art--cache-key': the stable cache-file basename for +;; a track. A url with a known #RADIOBROWSERUUID keys on the uuid (so the same +;; station shares one cached logo); any other url keys on a hash of its address; +;; a file keys on a hash of its path. +;; +;;; Code: + +(require 'ert) + +(defvar-keymap cj/custom-keymap :doc "Stub keymap for testing") + +(let ((emms-dir (car (file-expand-wildcards + (expand-file-name "elpa/emms-*" user-emacs-directory))))) + (when emms-dir (add-to-list 'load-path emms-dir))) + +(require 'emms) +(require 'music-config) + +(ert-deftest test-music-config--art-cache-key-normal-uuid () + "Normal: a url with a UUID in the entries keys on the UUID." + (let ((track (emms-track 'url "https://ck.somafm.com/gs")) + (entries '(("https://ck.somafm.com/gs" :name "GS" :uuid "uuid-42" :favicon nil)))) + (should (string= (cj/music-art--cache-key track entries) "uuid-42")))) + +(ert-deftest test-music-config--art-cache-key-boundary-url-no-uuid () + "Boundary: a url with no UUID keys on a stable url- hash, not the raw URL." + (let* ((url "https://ck2.example.net/live") + (track (emms-track 'url url)) + (key (cj/music-art--cache-key track nil))) + (should (string-prefix-p "url-" key)) + (should (string= key (concat "url-" (sha1 url)))))) + +(ert-deftest test-music-config--art-cache-key-normal-file () + "Normal: a file keys on a file- hash of its path." + (let* ((path "/music/Kind of Blue/01.flac") + (track (emms-track 'file path))) + (should (string= (cj/music-art--cache-key track nil) + (concat "file-" (sha1 path)))))) + +(ert-deftest test-music-config--art-cache-key-boundary-empty-uuid-falls-to-hash () + "Boundary: an empty-string UUID is treated as absent, so the url hashes." + (let* ((url "https://ck3.example.net/x") + (track (emms-track 'url url)) + (entries (list (list url :name "X" :uuid "" :favicon nil)))) + (should (string= (cj/music-art--cache-key track entries) + (concat "url-" (sha1 url)))))) + +(provide 'test-music-config--art-cache-key) +;;; test-music-config--art-cache-key.el ends here |
