Files
Bellhop/internal/arr/radarr_test.go
prosolis 206b378d93 Session 3: Radarr/Sonarr/Lidarr clients with add-on-search
Adds internal/arr with a shared HTTP layer and per-service clients that
look up candidates and POST the chosen one back with monitored=true and
search-on-add enabled. Lidarr requires metadata_profile_id, now part of
ArrConfig and validated when lidarr is set.
2026-05-24 20:22:50 -07:00

97 lines
3.0 KiB
Go

package arr
import (
"context"
"encoding/json"
"io"
"net/http"
"net/http/httptest"
"testing"
"bellhop/internal/config"
)
func TestRadarrSearch(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if got := r.Header.Get("X-Api-Key"); got != "secret" {
t.Errorf("api key header = %q, want secret", got)
}
if r.URL.Path != "/api/v3/movie/lookup" {
t.Errorf("path = %q", r.URL.Path)
}
if r.URL.Query().Get("term") != "dune" {
t.Errorf("term = %q", r.URL.Query().Get("term"))
}
w.Header().Set("Content-Type", "application/json")
_, _ = io.WriteString(w, `[
{"title":"Dune","year":2021,"tmdbId":438631,"titleSlug":"dune-2021"},
{"title":"Dune: Part Two","year":2024,"tmdbId":693134,"titleSlug":"dune-part-two-2024"}
]`)
}))
defer srv.Close()
r := NewRadarr(&config.ArrConfig{URL: srv.URL, APIKey: "secret", QualityProfileID: 6, RootFolder: "/movies"})
results, err := r.Search(context.Background(), "dune")
if err != nil {
t.Fatalf("search: %v", err)
}
if len(results) != 2 {
t.Fatalf("got %d results, want 2", len(results))
}
if results[0].Title != "Dune" || results[0].Year != 2021 {
t.Errorf("first result = %+v", results[0])
}
}
func TestRadarrAdd(t *testing.T) {
var got map[string]any
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost || r.URL.Path != "/api/v3/movie" {
t.Errorf("unexpected %s %s", r.Method, r.URL.Path)
}
if err := json.NewDecoder(r.Body).Decode(&got); err != nil {
t.Fatalf("decode body: %v", err)
}
w.WriteHeader(http.StatusCreated)
_, _ = io.WriteString(w, `{"id":42}`)
}))
defer srv.Close()
r := NewRadarr(&config.ArrConfig{URL: srv.URL, APIKey: "k", QualityProfileID: 6, RootFolder: "/movies"})
res := makeResult("Dune", 2021, `{"title":"Dune","year":2021,"tmdbId":438631,"titleSlug":"dune-2021"}`)
if err := r.Add(context.Background(), res); err != nil {
t.Fatalf("add: %v", err)
}
if got["qualityProfileId"].(float64) != 6 {
t.Errorf("qualityProfileId = %v", got["qualityProfileId"])
}
if got["rootFolderPath"] != "/movies" {
t.Errorf("rootFolderPath = %v", got["rootFolderPath"])
}
if got["monitored"] != true {
t.Errorf("monitored = %v", got["monitored"])
}
if got["tmdbId"].(float64) != 438631 {
t.Errorf("tmdbId not preserved from lookup: %v", got["tmdbId"])
}
opts := got["addOptions"].(map[string]any)
if opts["searchForMovie"] != true {
t.Errorf("addOptions.searchForMovie = %v", opts["searchForMovie"])
}
}
func TestRadarrAddError(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusBadRequest)
_, _ = io.WriteString(w, `{"error":"already exists"}`)
}))
defer srv.Close()
r := NewRadarr(&config.ArrConfig{URL: srv.URL, APIKey: "k", QualityProfileID: 1, RootFolder: "/m"})
err := r.Add(context.Background(), makeResult("X", 0, `{"title":"X"}`))
if err == nil {
t.Fatal("expected error, got nil")
}
}