3e3ad89645
- golangci-lint: errcheck on resp.Body.Close in Lidarr client + revive unused-parameter in delete_test.go - coverage: 2 error-branch tests added to lidarrquarantine.Service (DeleteFile + DeleteViaLidarr track-not-found paths) bring per-package coverage to 81.4% (target >=80%) - search/tracks.test.ts: same TrackMenu name-collision fix T13 applied to TrackRow.test.ts — exact-string button match instead of regex
215 lines
6.3 KiB
Go
215 lines
6.3 KiB
Go
package lidarr
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"testing"
|
|
)
|
|
|
|
func TestLookupAlbumByMBID_HappyPath(t *testing.T) {
|
|
body, err := os.ReadFile("testdata/album_lookup_by_mbid.json")
|
|
if err != nil {
|
|
t.Fatalf("read fixture: %v", err)
|
|
}
|
|
c, srv := newTestClient(func(w http.ResponseWriter, r *http.Request) {
|
|
if r.URL.Path != "/api/v1/album" {
|
|
t.Errorf("path = %q, want /api/v1/album", r.URL.Path)
|
|
}
|
|
if got := r.URL.Query().Get("foreignAlbumId"); got != "3a2c2c8c-7e6f-4f8a-b1d2-9a8b6c4e3f1d" {
|
|
t.Errorf("foreignAlbumId = %q", got)
|
|
}
|
|
if got := r.Header.Get("X-Api-Key"); got != "key123" {
|
|
t.Errorf("X-Api-Key = %q, want key123", got)
|
|
}
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusOK)
|
|
_, _ = w.Write(body)
|
|
})
|
|
defer srv.Close()
|
|
|
|
got, err := c.LookupAlbumByMBID(context.Background(), "3a2c2c8c-7e6f-4f8a-b1d2-9a8b6c4e3f1d")
|
|
if err != nil {
|
|
t.Fatalf("LookupAlbumByMBID: %v", err)
|
|
}
|
|
if got.ID != 42 || got.Title != "Music Has The Right To Children" {
|
|
t.Errorf("got = %+v", got)
|
|
}
|
|
}
|
|
|
|
func TestLookupAlbumByMBID_EmptyArrayReturnsErrNotFound(t *testing.T) {
|
|
c, srv := newTestClient(func(w http.ResponseWriter, _ *http.Request) {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusOK)
|
|
_, _ = w.Write([]byte("[]"))
|
|
})
|
|
defer srv.Close()
|
|
|
|
_, err := c.LookupAlbumByMBID(context.Background(), "x")
|
|
if !errors.Is(err, ErrNotFound) {
|
|
t.Errorf("err = %v, want ErrNotFound", err)
|
|
}
|
|
}
|
|
|
|
func TestLookupAlbumByMBID_AuthFailed(t *testing.T) {
|
|
c, srv := newTestClient(func(w http.ResponseWriter, _ *http.Request) {
|
|
w.WriteHeader(http.StatusUnauthorized)
|
|
})
|
|
defer srv.Close()
|
|
|
|
_, err := c.LookupAlbumByMBID(context.Background(), "x")
|
|
if !errors.Is(err, ErrAuthFailed) {
|
|
t.Errorf("err = %v, want ErrAuthFailed", err)
|
|
}
|
|
}
|
|
|
|
func TestLookupAlbumByMBID_5xxReturnsErrServerError(t *testing.T) {
|
|
c, srv := newTestClient(func(w http.ResponseWriter, _ *http.Request) {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
})
|
|
defer srv.Close()
|
|
|
|
_, err := c.LookupAlbumByMBID(context.Background(), "x")
|
|
if !errors.Is(err, ErrServerError) {
|
|
t.Errorf("err = %v, want ErrServerError", err)
|
|
}
|
|
}
|
|
|
|
func TestLookupAlbumByMBID_BadJSON(t *testing.T) {
|
|
c, srv := newTestClient(func(w http.ResponseWriter, _ *http.Request) {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusOK)
|
|
_, _ = w.Write([]byte("not json"))
|
|
})
|
|
defer srv.Close()
|
|
|
|
_, err := c.LookupAlbumByMBID(context.Background(), "x")
|
|
if !errors.Is(err, ErrInvalidPayload) {
|
|
t.Errorf("err = %v, want ErrInvalidPayload", err)
|
|
}
|
|
}
|
|
|
|
func TestLookupAlbumByMBID_EmptyMBIDRejected(t *testing.T) {
|
|
c, srv := newTestClient(func(http.ResponseWriter, *http.Request) {
|
|
t.Error("server should not be called with empty mbid")
|
|
})
|
|
defer srv.Close()
|
|
|
|
if _, err := c.LookupAlbumByMBID(context.Background(), ""); err == nil {
|
|
t.Error("err = nil, want empty-mbid rejection")
|
|
}
|
|
}
|
|
|
|
func TestLookupArtistByMBID_EmptyArrayReturnsErrNotFound(t *testing.T) {
|
|
c, srv := newTestClient(func(w http.ResponseWriter, _ *http.Request) {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusOK)
|
|
_, _ = w.Write([]byte("[]"))
|
|
})
|
|
defer srv.Close()
|
|
|
|
_, err := c.LookupArtistByMBID(context.Background(), "x")
|
|
if !errors.Is(err, ErrNotFound) {
|
|
t.Errorf("err = %v, want ErrNotFound", err)
|
|
}
|
|
}
|
|
|
|
func TestLookupArtistByMBID_EmptyMBIDRejected(t *testing.T) {
|
|
c, srv := newTestClient(func(http.ResponseWriter, *http.Request) {
|
|
t.Error("server should not be called with empty mbid")
|
|
})
|
|
defer srv.Close()
|
|
|
|
if _, err := c.LookupArtistByMBID(context.Background(), ""); err == nil {
|
|
t.Error("err = nil, want empty-mbid rejection")
|
|
}
|
|
}
|
|
|
|
func TestLookupArtistByMBID_HappyPath(t *testing.T) {
|
|
body, err := os.ReadFile("testdata/artist_lookup_by_mbid.json")
|
|
if err != nil {
|
|
t.Fatalf("read fixture: %v", err)
|
|
}
|
|
c, srv := newTestClient(func(w http.ResponseWriter, r *http.Request) {
|
|
if r.URL.Path != "/api/v1/artist" {
|
|
t.Errorf("path = %q, want /api/v1/artist", r.URL.Path)
|
|
}
|
|
if got := r.URL.Query().Get("mbId"); got != "069b64b6-7884-4f6a-94cc-e4c1d6c87a01" {
|
|
t.Errorf("mbId = %q", got)
|
|
}
|
|
w.Header().Set("Content-Type", "application/json")
|
|
w.WriteHeader(http.StatusOK)
|
|
_, _ = w.Write(body)
|
|
})
|
|
defer srv.Close()
|
|
|
|
got, err := c.LookupArtistByMBID(context.Background(), "069b64b6-7884-4f6a-94cc-e4c1d6c87a01")
|
|
if err != nil {
|
|
t.Fatalf("LookupArtistByMBID: %v", err)
|
|
}
|
|
if got.ID != 7 || got.ArtistName != "Boards of Canada" {
|
|
t.Errorf("got = %+v", got)
|
|
}
|
|
}
|
|
|
|
func TestDeleteAlbum_PassesBothFlags(t *testing.T) {
|
|
var captured *http.Request
|
|
c, srv := newTestClient(func(w http.ResponseWriter, r *http.Request) {
|
|
captured = r
|
|
w.WriteHeader(http.StatusOK)
|
|
})
|
|
defer srv.Close()
|
|
|
|
if err := c.DeleteAlbum(context.Background(), 42, true, true); err != nil {
|
|
t.Fatalf("DeleteAlbum: %v", err)
|
|
}
|
|
if captured == nil || captured.Method != http.MethodDelete {
|
|
t.Fatalf("method = %v, want DELETE", captured)
|
|
}
|
|
if captured.URL.Path != "/api/v1/album/42" {
|
|
t.Errorf("path = %q", captured.URL.Path)
|
|
}
|
|
if got := captured.URL.Query().Get("deleteFiles"); got != "true" {
|
|
t.Errorf("deleteFiles = %q", got)
|
|
}
|
|
if got := captured.URL.Query().Get("addImportListExclusion"); got != "true" {
|
|
t.Errorf("addImportListExclusion = %q", got)
|
|
}
|
|
}
|
|
|
|
func TestDeleteAlbum_5xxReturnsErrServerError(t *testing.T) {
|
|
c, srv := newTestClient(func(w http.ResponseWriter, _ *http.Request) {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
})
|
|
defer srv.Close()
|
|
|
|
err := c.DeleteAlbum(context.Background(), 42, true, true)
|
|
if !errors.Is(err, ErrServerError) {
|
|
t.Errorf("err = %v, want ErrServerError", err)
|
|
}
|
|
}
|
|
|
|
func TestDeleteAlbum_NetworkErrorReturnsErrUnreachable(t *testing.T) {
|
|
srv := httptest.NewServer(http.HandlerFunc(func(http.ResponseWriter, *http.Request) {}))
|
|
srv.Close() // server is closed; client should fail to connect
|
|
c := NewClient(srv.URL, "key123")
|
|
|
|
err := c.DeleteAlbum(context.Background(), 42, true, true)
|
|
if !errors.Is(err, ErrUnreachable) {
|
|
t.Errorf("err = %v, want ErrUnreachable", err)
|
|
}
|
|
}
|
|
|
|
func TestDeleteAlbum_ZeroIDRejected(t *testing.T) {
|
|
c, srv := newTestClient(func(_ http.ResponseWriter, _ *http.Request) {
|
|
t.Error("server should not be called with zero id")
|
|
})
|
|
defer srv.Close()
|
|
|
|
if err := c.DeleteAlbum(context.Background(), 0, true, true); err == nil {
|
|
t.Error("err = nil, want zero-id rejection")
|
|
}
|
|
}
|