mirror of
https://github.com/truewhile/MeBox.git
synced 2026-09-29 11:36:36 +08:00
136 lines
4.3 KiB
Go
136 lines
4.3 KiB
Go
package service
|
|
|
|
import (
|
|
"bytes"
|
|
"io"
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
"sync/atomic"
|
|
"testing"
|
|
"time"
|
|
|
|
"go.uber.org/zap"
|
|
|
|
"github.com/ShukeBta/MediaStationGo/internal/config"
|
|
)
|
|
|
|
func TestUniqueDiscoverArtworkURLsFiltersDuplicatesAndLimits(t *testing.T) {
|
|
urls := uniqueDiscoverArtworkURLs([]string{
|
|
"",
|
|
"/local/poster.jpg",
|
|
"https://image.tmdb.org/t/p/w500/a.jpg",
|
|
"https://image.tmdb.org/t/p/w500/a.jpg",
|
|
"https://image.tmdb.org/t/p/w500/b.jpg",
|
|
"https://image.tmdb.org/t/p/w500/c.jpg",
|
|
}, 2)
|
|
if len(urls) != 2 {
|
|
t.Fatalf("len = %d, want 2: %v", len(urls), urls)
|
|
}
|
|
if urls[0] != "https://image.tmdb.org/t/p/w500/a.jpg" || urls[1] != "https://image.tmdb.org/t/p/w500/b.jpg" {
|
|
t.Fatalf("urls = %v", urls)
|
|
}
|
|
}
|
|
|
|
func TestDiscoverArtworkURLsPrioritizePosters(t *testing.T) {
|
|
items := []ExternalMediaResult{
|
|
{PosterURL: "https://img.example/a-poster.jpg", BackdropURL: "https://img.example/a-backdrop.jpg"},
|
|
{PosterURL: "https://img.example/b-poster.jpg", BackdropURL: "https://img.example/b-backdrop.jpg"},
|
|
}
|
|
urls := externalArtworkURLs(items)
|
|
want := []string{
|
|
"https://img.example/a-poster.jpg",
|
|
"https://img.example/b-poster.jpg",
|
|
"https://img.example/a-backdrop.jpg",
|
|
"https://img.example/b-backdrop.jpg",
|
|
}
|
|
if len(urls) != len(want) {
|
|
t.Fatalf("len = %d, want %d: %v", len(urls), len(want), urls)
|
|
}
|
|
for i := range want {
|
|
if urls[i] != want[i] {
|
|
t.Fatalf("url[%d] = %q, want %q", i, urls[i], want[i])
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestDiscoverWarmExternalArtworkPrefetchesAndCaches(t *testing.T) {
|
|
proxy := NewImageProxy(&config.Config{Cache: config.CacheConfig{CacheDir: filepath.Join(t.TempDir(), "cache")}}, zap.NewNop())
|
|
var calls int32
|
|
proxy.client = &http.Client{Transport: imageRoundTripFunc(func(req *http.Request) (*http.Response, error) {
|
|
atomic.AddInt32(&calls, 1)
|
|
return &http.Response{
|
|
StatusCode: http.StatusOK,
|
|
Status: "200 OK",
|
|
Header: http.Header{"Content-Type": []string{"image/jpeg"}},
|
|
Body: io.NopCloser(bytes.NewReader(testJPEG)),
|
|
Request: req,
|
|
}, nil
|
|
})}
|
|
|
|
discover := NewDiscoverService(zap.NewNop(), nil).SetImageProxy(proxy)
|
|
poster := "https://image.tmdb.org/t/p/w500/discover-poster.jpg"
|
|
backdrop := "https://image.tmdb.org/t/p/w1280/discover-backdrop.jpg"
|
|
queued := discover.WarmExternalArtwork([]ExternalMediaResult{
|
|
{Title: "A", PosterURL: poster, BackdropURL: backdrop},
|
|
{Title: "B", PosterURL: poster},
|
|
{Title: "Local", PosterURL: "/media/poster.jpg"},
|
|
})
|
|
if queued != 2 {
|
|
t.Fatalf("queued = %d, want 2", queued)
|
|
}
|
|
for _, raw := range []string{poster, backdrop} {
|
|
_, cachePath, _, err := proxy.remoteImageCachePaths(raw)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
waitForDiscoverArtworkCache(t, &calls, 2, cachePath, raw)
|
|
}
|
|
|
|
callsAfterCache := atomic.LoadInt32(&calls)
|
|
queued = discover.WarmExternalArtwork([]ExternalMediaResult{{Title: "Cached", PosterURL: poster, BackdropURL: backdrop}})
|
|
if queued != 2 {
|
|
t.Fatalf("queued cached = %d, want 2", queued)
|
|
}
|
|
time.Sleep(150 * time.Millisecond)
|
|
if got := atomic.LoadInt32(&calls); got != callsAfterCache {
|
|
t.Fatalf("cached prefetch should not call upstream again: got %d want %d", got, callsAfterCache)
|
|
}
|
|
}
|
|
|
|
func TestDiscoverWarmArtworkNoImageProxyIsNoop(t *testing.T) {
|
|
discover := NewDiscoverService(zap.NewNop(), nil)
|
|
if got := discover.WarmMatchArtwork([]Match{{PosterURL: "https://image.tmdb.org/t/p/w500/a.jpg"}}); got != 0 {
|
|
t.Fatalf("queued = %d, want 0 without image proxy", got)
|
|
}
|
|
}
|
|
|
|
func TestTMDbDiscoverPathIncludesLatestSections(t *testing.T) {
|
|
cases := map[string]string{
|
|
"tmdb_latest_movie": "/movie/now_playing",
|
|
"latest_movie": "/movie/now_playing",
|
|
"tmdb_latest_tv": "/tv/on_the_air",
|
|
"latest_tv": "/tv/on_the_air",
|
|
"tmdb_upcoming_movie": "/movie/upcoming",
|
|
}
|
|
for key, want := range cases {
|
|
if got := tmdbDiscoverPath(key); got != want {
|
|
t.Fatalf("tmdbDiscoverPath(%q) = %q, want %q", key, got, want)
|
|
}
|
|
}
|
|
}
|
|
|
|
func waitForDiscoverArtworkCache(t *testing.T, calls *int32, wantCalls int32, cachePath, raw string) {
|
|
t.Helper()
|
|
deadline := time.Now().Add(2 * time.Second)
|
|
for time.Now().Before(deadline) {
|
|
if atomic.LoadInt32(calls) >= wantCalls {
|
|
if _, err := os.Stat(cachePath); err == nil {
|
|
return
|
|
}
|
|
}
|
|
time.Sleep(10 * time.Millisecond)
|
|
}
|
|
t.Fatalf("expected cached artwork %q after %d upstream calls: %v", raw, atomic.LoadInt32(calls), os.ErrNotExist)
|
|
}
|