package providers
import (
"context"
"encoding/json"
"io"
"net/http"
"net/http/httptest"
"reflect"
"testing"
)
func TestAniListMapsMatch(t *testing.T) {
var gotMethod string
var gotBody []byte
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
gotMethod = r.Method
gotBody, _ = io.ReadAll(r.Body)
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"data":{"Page":{"media":[
{"id": 12345,
"title": {"romaji": "Romaji Name", "english": "", "native": "Native Name"},
"description": "A bold start
and a line & more.",
"coverImage": {"large": "https://img/anime.jpg"},
"startDate": {"year": 2001}},
{"id": 6789,
"title": {"romaji": "", "english": "", "native": "Native Only"},
"description": "Native.",
"coverImage": {"large": "https://img/native.jpg"},
"startDate": {"year": 2004}}
]}}}`))
}))
t.Cleanup(srv.Close)
p := NewAniList()
p.BaseURL = srv.URL
cands, err := p.Search(context.Background(), Query{Title: " something ", Year: 2001})
if err != nil {
t.Fatalf("Search: %v", err)
}
want := []Candidate{
{
Provider: "anilist",
ExternalID: "anime/12345",
Title: "Romaji Name", // english empty, falls back to romaji
Year: 2001,
Description: "A bold startand a line & more.", // tags stripped, entity decoded
CoverURL: "https://img/anime.jpg",
},
{
Provider: "anilist",
ExternalID: "anime/6789",
Title: "Native Only", // both english and romaji empty
Year: 2004,
Description: "Native.",
CoverURL: "https://img/native.jpg",
},
}
if !reflect.DeepEqual(cands, want) {
t.Errorf("candidates = %+v, want %+v", cands, want)
}
if gotMethod != http.MethodPost {
t.Errorf("method = %s, want POST", gotMethod)
}
var body struct {
Query string `json:"query"`
Variables struct {
Search string `json:"search"`
IsAdult bool `json:"isAdult"`
Year string `json:"year"`
} `json:"variables"`
}
if err := json.Unmarshal(gotBody, &body); err != nil {
t.Fatalf("request body: %v", err)
}
if body.Variables.Search != "something" {
t.Errorf("search = %q, want trimmed title", body.Variables.Search)
}
if !body.Variables.IsAdult {
t.Errorf("isAdult = false, want true")
}
if body.Variables.Year != "2001%" {
t.Errorf("year = %q, want 2001%%", body.Variables.Year)
}
}
func TestAniListEmptyResultIsNotError(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"data":{"Page":{"media":[]}}}`))
}))
t.Cleanup(srv.Close)
p := NewAniList()
p.BaseURL = srv.URL
cands, err := p.Search(context.Background(), Query{Title: "nothing"})
if err != nil {
t.Fatalf("Search: %v", err)
}
if len(cands) != 0 {
t.Errorf("got %d candidates, want 0", len(cands))
}
}
func TestAniListBlankTitleSkipsRequest(t *testing.T) {
var calls int
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
calls++
}))
t.Cleanup(srv.Close)
p := NewAniList()
p.BaseURL = srv.URL
cands, err := p.Search(context.Background(), Query{Title: " "})
if err != nil {
t.Fatalf("Search: %v", err)
}
if cands != nil {
t.Errorf("got %v, want nil", cands)
}
if calls != 0 {
t.Errorf("server got %d requests, want 0", calls)
}
}
func TestAniListErrorsArrayIsError(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"errors":[{"message":"Not Found."}]}`))
}))
t.Cleanup(srv.Close)
p := NewAniList()
p.BaseURL = srv.URL
if _, err := p.Search(context.Background(), Query{Title: "x"}); err == nil {
t.Fatal("Search: got nil error, want error")
}
}