package providers import ( "context" "net/http" "net/http/httptest" "sync/atomic" "testing" ) // tpdbSrv answers scene searches from one handler, recording the last request. func tpdbSrv(t *testing.T, fn func(r *http.Request) (string, int)) *httptest.Server { t.Helper() srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { body, status := fn(r) w.Header().Set("Content-Type", "application/json") w.WriteHeader(status) _, _ = w.Write([]byte(body)) })) t.Cleanup(srv.Close) return srv } func TestThePornDBMapsMatch(t *testing.T) { var gotPath string srv := tpdbSrv(t, func(r *http.Request) (string, int) { gotPath = r.URL.Path return `{"data":[ {"id": "abc-123", "title": "A Scene", "date": "2021-05-04", "description": "

A fine scene.

", "image": "https://cdn.example.com/a.jpg", "site": {"name": "Some Site"}, "performers": [{"name": "Someone"}]} ]}`, http.StatusOK }) p := NewThePornDB("secret-key") p.BaseURL = srv.URL cands, err := p.Search(context.Background(), Query{Title: "A Scene", Year: 2021}) if err != nil { t.Fatalf("Search: %v", err) } if gotPath != "/scenes" { t.Errorf("path = %q, want /scenes", gotPath) } if len(cands) != 1 { t.Fatalf("got %d candidates, want 1", len(cands)) } c := cands[0] if c.Provider != "theporndb" || c.ExternalID != "scene/abc-123" { t.Errorf("id = %q (provider %q), want scene/abc-123", c.ExternalID, c.Provider) } if c.Title != "A Scene" { t.Errorf("Title = %q", c.Title) } if c.Year != 2021 { t.Errorf("Year = %d, want 2021 parsed from date", c.Year) } if c.Description != "A fine scene." { t.Errorf("Description = %q (HTML should be stripped)", c.Description) } if c.CoverURL != "https://cdn.example.com/a.jpg" { t.Errorf("CoverURL = %q", c.CoverURL) } } func TestThePornDBUsesBearerAuth(t *testing.T) { var gotAuth string srv := tpdbSrv(t, func(r *http.Request) (string, int) { gotAuth = r.Header.Get("Authorization") return `{"data":[]}`, http.StatusOK }) p := NewThePornDB("secret-key") p.BaseURL = srv.URL if _, err := p.Search(context.Background(), Query{Title: "A Scene"}); err != nil { t.Fatalf("Search: %v", err) } if gotAuth != "Bearer secret-key" { t.Errorf("Authorization = %q, want %q", gotAuth, "Bearer secret-key") } } func TestThePornDBYearOnlySentWhenSet(t *testing.T) { var gotYear string srv := tpdbSrv(t, func(r *http.Request) (string, int) { gotYear = r.URL.Query().Get("year") return `{"data":[]}`, http.StatusOK }) p := NewThePornDB("secret-key") p.BaseURL = srv.URL if _, err := p.Search(context.Background(), Query{Title: "A Scene"}); err != nil { t.Fatalf("Search: %v", err) } if gotYear != "" { t.Errorf("year sent without being set: %q", gotYear) } if _, err := p.Search(context.Background(), Query{Title: "A Scene", Year: 2021}); err != nil { t.Fatalf("Search: %v", err) } if gotYear != "2021" { t.Errorf("year = %q, want 2021", gotYear) } } func TestThePornDBEmptyResultsAreNotAnError(t *testing.T) { srv := tpdbSrv(t, func(_ *http.Request) (string, int) { return `{"data":[]}`, http.StatusOK }) p := NewThePornDB("secret-key") p.BaseURL = srv.URL cands, err := p.Search(context.Background(), Query{Title: "Nothing At All Like This"}) if err != nil { t.Fatalf("Search: %v", err) } if len(cands) != 0 { t.Errorf("got %d candidates, want 0", len(cands)) } } func TestThePornDBNonOKIsAnError(t *testing.T) { srv := tpdbSrv(t, func(_ *http.Request) (string, int) { return `{"message":"nope"}`, http.StatusUnauthorized }) p := NewThePornDB("secret-key") p.BaseURL = srv.URL if _, err := p.Search(context.Background(), Query{Title: "A Scene"}); err == nil { t.Error("Search returned nil error on a 401") } } func TestThePornDBWithoutTitleOrKeyDoesNotCallOut(t *testing.T) { var hits int32 srv := tpdbSrv(t, func(_ *http.Request) (string, int) { atomic.AddInt32(&hits, 1) return `{"data":[{"id":"1","title":"Unwanted"}]}`, http.StatusOK }) keyed := NewThePornDB("secret-key") keyed.BaseURL = srv.URL for _, q := range []Query{{}, {Title: " "}} { cands, err := keyed.Search(context.Background(), q) if err != nil { t.Fatalf("Search(%+v): %v", q, err) } if len(cands) != 0 { t.Errorf("Search(%+v) returned %d candidates, want 0", q, len(cands)) } } keyless := NewThePornDB("") keyless.BaseURL = srv.URL if _, err := keyless.Search(context.Background(), Query{Title: "A Scene"}); err != nil { t.Fatalf("Search without key: %v", err) } if n := atomic.LoadInt32(&hits); n != 0 { t.Errorf("server hit %d times with no title or no key, want 0", n) } }