Posters stored by the previous build (the downloaded bytes, for real images Radarr's 333x500 copy) were reused as they were for 30 days. Posters now live in posters-v2/; older folders are deleted at startup. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
124 lines
3.9 KiB
Go
124 lines
3.9 KiB
Go
package ui
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
|
|
"git.stinnesbeck.com/nils/arr-tui/internal/trakt"
|
|
)
|
|
|
|
func TestPostersOnDisk(t *testing.T) {
|
|
d := &diskCache{dir: t.TempDir()}
|
|
if _, ok := d.readPoster("k", false); ok {
|
|
t.Fatal("empty cache returned a poster")
|
|
}
|
|
d.writePoster("k", false, []byte("SMALL"))
|
|
d.writePoster("k", true, []byte("LARGE"))
|
|
if data, ok := d.readPoster("k", false); !ok || string(data) != "SMALL" {
|
|
t.Errorf("small: %q %v", data, ok)
|
|
}
|
|
if data, ok := d.readPoster("k", true); !ok || string(data) != "LARGE" {
|
|
t.Errorf("large copies are kept apart: %q %v", data, ok)
|
|
}
|
|
if info, _ := os.Stat(filepath.Dir(d.posterPath("k", false))); info.Mode().Perm() != 0o700 {
|
|
t.Errorf("directory mode %v", info.Mode().Perm())
|
|
}
|
|
|
|
// Too old: not used, and pruned.
|
|
old := time.Now().Add(-posterTTL - time.Hour)
|
|
_ = os.Chtimes(d.posterPath("k", false), old, old)
|
|
if _, ok := d.readPoster("k", false); ok {
|
|
t.Error("an expired poster was used")
|
|
}
|
|
d.prunePosters()
|
|
if _, err := os.Stat(d.posterPath("k", false)); !os.IsNotExist(err) {
|
|
t.Error("an expired poster was not pruned")
|
|
}
|
|
if _, ok := d.readPoster("k", true); !ok {
|
|
t.Error("a fresh poster was pruned")
|
|
}
|
|
|
|
// Off: nothing is read or written.
|
|
off := &diskCache{}
|
|
off.writePoster("k", false, []byte("x"))
|
|
if _, ok := off.readPoster("k", false); ok {
|
|
t.Error("cache without a directory returned a poster")
|
|
}
|
|
}
|
|
|
|
func TestPrunePostersKeepsTheNewestWithinTheCap(t *testing.T) {
|
|
d := &diskCache{dir: t.TempDir()}
|
|
big := make([]byte, posterCacheCap/2+1) // two of these do not fit
|
|
for i, key := range []string{"oldest", "middle", "newest"} {
|
|
d.writePoster(key, false, big)
|
|
at := time.Now().Add(time.Duration(i-3) * time.Hour)
|
|
_ = os.Chtimes(d.posterPath(key, false), at, at)
|
|
}
|
|
d.prunePosters()
|
|
for key, want := range map[string]bool{"oldest": false, "middle": false, "newest": true} {
|
|
if _, ok := d.readPoster(key, false); ok != want {
|
|
t.Errorf("%s kept: %v, want %v", key, ok, want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestPeopleOnDisk(t *testing.T) {
|
|
d := &diskCache{dir: t.TempDir()}
|
|
all := map[string]savedPeople{
|
|
"movie:tmdb:1": {Saved: time.Now(), Cast: []trakt.Person{{Name: "A", Role: "B"}}, Leaders: []trakt.Person{{Name: "C"}}},
|
|
"movie:tmdb:2": {Saved: time.Now().Add(-peopleTTL - time.Hour), Cast: []trakt.Person{{Name: "Old"}}},
|
|
"show:tvdb:3": {Saved: time.Now()}, // Trakt had no cast: remembered as such
|
|
}
|
|
if err := d.savePeople(all); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
got := d.loadPeople()
|
|
if len(got) != 2 || got["movie:tmdb:1"].Cast[0].Role != "B" || got["movie:tmdb:1"].Leaders[0].Name != "C" {
|
|
t.Errorf("loaded %+v", got)
|
|
}
|
|
if _, ok := got["show:tvdb:3"]; !ok {
|
|
t.Error("an empty cast was not kept")
|
|
}
|
|
// A damaged file is ignored.
|
|
_ = os.WriteFile(d.peoplePath(), []byte("{not json"), 0o600)
|
|
if len(d.loadPeople()) != 0 {
|
|
t.Error("damaged file")
|
|
}
|
|
}
|
|
|
|
func TestPeopleCacheKeepsTheNewest(t *testing.T) {
|
|
a := newTestApp(t)
|
|
for i := 0; i < maxPeopleSaved+5; i++ {
|
|
a.remember(trakt.Ref{Kind: trakt.Movies, TMDB: i + 1}.Key(), trakt.People{})
|
|
a.people.saved[trakt.Ref{Kind: trakt.Movies, TMDB: i + 1}.Key()] = time.Unix(int64(i), 0)
|
|
}
|
|
a.people.timer.Stop()
|
|
if len(a.people.done) != maxPeopleSaved {
|
|
t.Errorf("%d casts kept", len(a.people.done))
|
|
}
|
|
if _, ok := a.people.done["movie:tmdb:1"]; ok {
|
|
t.Error("the oldest cast was kept")
|
|
}
|
|
if !a.people.dirty || len(a.peopleSnapshot()) != maxPeopleSaved {
|
|
t.Error("new casts must be written")
|
|
}
|
|
}
|
|
|
|
func TestPostersOfOlderVersionsAreDropped(t *testing.T) {
|
|
d := &diskCache{dir: t.TempDir()}
|
|
old := filepath.Join(d.dir, "posters", "abc.img")
|
|
if err := writeAtomic(old, []byte("v1")); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
d.writePoster("k", true, []byte("v2"))
|
|
d.prunePosters()
|
|
if _, err := os.Stat(old); !os.IsNotExist(err) {
|
|
t.Error("a poster of the old format was kept")
|
|
}
|
|
if data, ok := d.readPoster("k", true); !ok || string(data) != "v2" {
|
|
t.Error("the current poster was dropped")
|
|
}
|
|
}
|