0dbe326d8b
- gofmt -s on system.go, system_cron.go, api.go - rename unused r → _ in 3 fetcher_test.go HTTP handlers - TrackRow +queue test uses /add .* to queue/i (track-aware aria-label from #377) - /library/artists page test mocks likes + tanstack-query (ArtistCard now embeds LikeButton) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
110 lines
3.0 KiB
Go
110 lines
3.0 KiB
Go
package coverart
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestFetcher_Success(t *testing.T) {
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if !strings.Contains(r.URL.Path, "/release/abc-123/front-500") {
|
|
http.Error(w, "wrong path", http.StatusBadRequest)
|
|
return
|
|
}
|
|
w.Header().Set("Content-Type", "image/jpeg")
|
|
_, _ = w.Write([]byte("FAKE_JPEG"))
|
|
}))
|
|
defer srv.Close()
|
|
|
|
f := NewFetcher(FetcherConfig{
|
|
BaseURL: srv.URL,
|
|
UserAgent: "Minstrel/test (https://example.com)",
|
|
MinPeriod: 0,
|
|
HTTPClient: srv.Client(),
|
|
})
|
|
|
|
body, err := f.Fetch(context.Background(), "abc-123")
|
|
if err != nil {
|
|
t.Fatalf("Fetch: %v", err)
|
|
}
|
|
if string(body) != "FAKE_JPEG" {
|
|
t.Errorf("body = %q, want FAKE_JPEG", string(body))
|
|
}
|
|
}
|
|
|
|
func TestFetcher_NotFound(t *testing.T) {
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
|
http.Error(w, "not found", http.StatusNotFound)
|
|
}))
|
|
defer srv.Close()
|
|
f := NewFetcher(FetcherConfig{BaseURL: srv.URL, UserAgent: "test", MinPeriod: 0, HTTPClient: srv.Client()})
|
|
_, err := f.Fetch(context.Background(), "missing")
|
|
if !errors.Is(err, ErrNotFound) {
|
|
t.Errorf("err = %v, want ErrNotFound", err)
|
|
}
|
|
}
|
|
|
|
func TestFetcher_5xxIsTransient(t *testing.T) {
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
|
http.Error(w, "boom", http.StatusInternalServerError)
|
|
}))
|
|
defer srv.Close()
|
|
f := NewFetcher(FetcherConfig{BaseURL: srv.URL, UserAgent: "test", MinPeriod: 0, HTTPClient: srv.Client()})
|
|
_, err := f.Fetch(context.Background(), "any")
|
|
if !errors.Is(err, ErrTransient) {
|
|
t.Errorf("err = %v, want ErrTransient", err)
|
|
}
|
|
}
|
|
|
|
func TestFetcher_SendsUserAgent(t *testing.T) {
|
|
var seen string
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
seen = r.Header.Get("User-Agent")
|
|
_, _ = w.Write([]byte("ok"))
|
|
}))
|
|
defer srv.Close()
|
|
f := NewFetcher(FetcherConfig{
|
|
BaseURL: srv.URL,
|
|
UserAgent: "Minstrel/0.1 (https://example.org)",
|
|
MinPeriod: 0,
|
|
HTTPClient: srv.Client(),
|
|
})
|
|
_, _ = f.Fetch(context.Background(), "ua-test")
|
|
if seen != "Minstrel/0.1 (https://example.org)" {
|
|
t.Errorf("UA = %q", seen)
|
|
}
|
|
}
|
|
|
|
func TestFetcher_RateLimitSpacesCalls(t *testing.T) {
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
|
|
_, _ = w.Write([]byte("ok"))
|
|
}))
|
|
defer srv.Close()
|
|
f := NewFetcher(FetcherConfig{
|
|
BaseURL: srv.URL,
|
|
UserAgent: "test",
|
|
MinPeriod: 150 * time.Millisecond,
|
|
HTTPClient: srv.Client(),
|
|
})
|
|
start := time.Now()
|
|
_, _ = f.Fetch(context.Background(), "a")
|
|
_, _ = f.Fetch(context.Background(), "b")
|
|
elapsed := time.Since(start)
|
|
if elapsed < 150*time.Millisecond {
|
|
t.Errorf("two calls in %v — rate limiter not enforcing", elapsed)
|
|
}
|
|
}
|
|
|
|
func TestFetcher_EmptyMBID(t *testing.T) {
|
|
f := NewFetcher(FetcherConfig{UserAgent: "test", MinPeriod: 0})
|
|
_, err := f.Fetch(context.Background(), "")
|
|
if err == nil {
|
|
t.Error("expected error for empty mbid")
|
|
}
|
|
}
|