package internal import ( "encoding/json" "io" "net/http" "net/http/httptest" "strings" "testing" ) func TestAuthenticateByNameSuccess(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost { t.Fatalf("expected POST, got %s", r.Method) } if r.URL.Path != "/Users/AuthenticateByName" { t.Fatalf("unexpected path %q", r.URL.Path) } if got := r.Header.Get("Content-Type"); got != "application/json" { t.Fatalf("unexpected content type %q", got) } if got := r.Header.Get("Authorization"); !strings.Contains(got, `MediaBrowser Client="Pegasus"`) { t.Fatalf("unexpected auth header %q", got) } body, err := io.ReadAll(r.Body) if err != nil { t.Fatalf("read body failed: %v", err) } var in map[string]string if err := json.Unmarshal(body, &in); err != nil { t.Fatalf("decode body failed: %v", err) } if in["Username"] != "brad" || in["Pw"] != "hunter2" { t.Fatalf("unexpected auth payload %#v", in) } w.Header().Set("Content-Type", "application/json") _, _ = w.Write([]byte(`{"AccessToken":"abc123","User":{"Id":"u1","Name":"brad"}}`)) })) defer srv.Close() j := &Jellyfin{BaseURL: srv.URL, Client: srv.Client()} out, err := j.AuthenticateByName("brad", "hunter2") if err != nil { t.Fatalf("AuthenticateByName failed: %v", err) } if out.AccessToken != "abc123" || out.User.Name != "brad" || out.User.Id != "u1" { t.Fatalf("unexpected auth response %#v", out) } } func TestAuthenticateByNameLoginFailure(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusUnauthorized) _, _ = w.Write([]byte("nope")) })) defer srv.Close() j := &Jellyfin{BaseURL: srv.URL, Client: srv.Client()} _, err := j.AuthenticateByName("brad", "bad") if err == nil || !strings.Contains(err.Error(), "login failed") { t.Fatalf("expected login failed error, got %v", err) } } func TestAuthenticateByNameBadJSON(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) _, _ = w.Write([]byte("{not-json")) })) defer srv.Close() j := &Jellyfin{BaseURL: srv.URL, Client: srv.Client()} _, err := j.AuthenticateByName("brad", "pw") if err == nil { t.Fatalf("expected decode error") } } func TestAuthenticateByNameRequestError(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})) baseURL := srv.URL srv.Close() // force client request error j := &Jellyfin{BaseURL: baseURL, Client: &http.Client{}} _, err := j.AuthenticateByName("brad", "pw") if err == nil { t.Fatalf("expected transport error") } } func TestNewJellyfinReadsEnv(t *testing.T) { t.Setenv("JELLYFIN_URL", "http://example.invalid") j := NewJellyfin() if j.BaseURL != "http://example.invalid" { t.Fatalf("unexpected base url %q", j.BaseURL) } if j.Client == nil { t.Fatalf("expected default client") } }