package radarr import ( "context" "encoding/json" "net/http" "net/http/httptest" "strings" "testing" "time" ) func TestCalendarUsesV3APIAndKeepsKeyInHeader(t *testing.T) { var gotQuery string upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/api/v3/calendar" { t.Errorf("path = %q", r.URL.Path) } if got := r.Header.Get("X-Api-Key"); got != "secret" { t.Errorf("X-Api-Key = %q", got) } if r.URL.Query().Get("unmonitored") != "true" { t.Errorf("missing unmonitored flag: %s", r.URL.RawQuery) } if got := r.URL.Query().Get("start"); got != "2026-07-01T00:00:00Z" { t.Errorf("start = %q", got) } gotQuery = r.URL.RawQuery w.Header().Set("Content-Type", "application/json") _, _ = w.Write([]byte(`[{"id":7,"title":"Arrival","digitalRelease":"2026-08-01T00:00:00Z"}]`)) })) defer upstream.Close() client := New(upstream.URL, "secret", time.Second) movies, err := client.Calendar( context.Background(), time.Date(2026, 7, 1, 0, 0, 0, 0, time.UTC), time.Date(2026, 8, 4, 0, 0, 0, 0, time.UTC), ) if err != nil { t.Fatal(err) } if len(movies) != 1 || movies[0].ID != 7 || movies[0].DigitalRelease == nil { t.Fatalf("unexpected movies: %+v", movies) } if gotQuery == "" || strings.Contains(gotQuery, "secret") { t.Fatalf("API key leaked into query: %q", gotQuery) } } func TestAddRequestedUsesDefaultsAndStartsSearch(t *testing.T) { upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch r.URL.Path { case "/api/v3/rootfolder": _, _ = w.Write([]byte(`[{"path":"/movies"}]`)) case "/api/v3/qualityprofile": _, _ = w.Write([]byte(`[{"id":4}]`)) case "/api/v3/movie": var body map[string]any if err := json.NewDecoder(r.Body).Decode(&body); err != nil { t.Fatal(err) } if body["monitored"] != true || body["rootFolderPath"] != "/movies" || body["qualityProfileId"] != float64(4) { t.Errorf("unexpected add body: %#v", body) } options := body["addOptions"].(map[string]any) if options["searchForMovie"] != true { t.Errorf("movie search was not enabled: %#v", body) } _, _ = w.Write([]byte(`{"id":9,"tmdbId":22,"title":"Arrival"}`)) default: t.Fatalf("unexpected path %s", r.URL.Path) } })) defer upstream.Close() added, err := New(upstream.URL, "secret", time.Second).AddRequested( context.Background(), Movie{TMDBID: 22, Title: "Arrival"}, ) if err != nil { t.Fatal(err) } if added.ID != 9 { t.Fatalf("unexpected movie: %+v", added) } }