feat(tmdb): add GetCompany and GetNetwork for logo path resolution
This commit is contained in:
@@ -544,6 +544,32 @@ func (c *Client) DiscoverPage(ctx context.Context, mediaType string, params Disc
|
||||
return normalizeMoviePage(resp), nil
|
||||
}
|
||||
|
||||
// GetCompany fetches a TMDB company (production studio) by ID. Used to
|
||||
// resolve logo paths for the bundled discovery studios.
|
||||
func (c *Client) GetCompany(ctx context.Context, id int) (*Company, error) {
|
||||
if id <= 0 {
|
||||
return nil, fmt.Errorf("tmdb: invalid company id: %d", id)
|
||||
}
|
||||
var company Company
|
||||
if err := c.doGet(ctx, fmt.Sprintf("/company/%d", id), &company); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &company, nil
|
||||
}
|
||||
|
||||
// GetNetwork fetches a TMDB TV network by ID. Used to resolve logo paths
|
||||
// for the bundled discovery networks.
|
||||
func (c *Client) GetNetwork(ctx context.Context, id int) (*Network, error) {
|
||||
if id <= 0 {
|
||||
return nil, fmt.Errorf("tmdb: invalid network id: %d", id)
|
||||
}
|
||||
var network Network
|
||||
if err := c.doGet(ctx, fmt.Sprintf("/network/%d", id), &network); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &network, nil
|
||||
}
|
||||
|
||||
// buildDiscoverQuery composes the TMDB discover query string (without the
|
||||
// leading "?" and without page or api_key — doGet handles those).
|
||||
func buildDiscoverQuery(mediaType string, params DiscoverParams) string {
|
||||
|
||||
@@ -379,6 +379,71 @@ func TestDiscoverPageDefaultsToPage1(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetCompany(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.URL.Path != "/company/420" {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, _ = w.Write([]byte(`{"id":420,"name":"Marvel Studios","logo_path":"/hUze.png"}`))
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
client := NewClient("test-key", 1000)
|
||||
client.SetBaseURL(server.URL)
|
||||
|
||||
company, err := client.GetCompany(context.Background(), 420)
|
||||
if err != nil {
|
||||
t.Fatalf("GetCompany: %v", err)
|
||||
}
|
||||
if company.ID != 420 || company.Name != "Marvel Studios" || company.LogoPath != "/hUze.png" {
|
||||
t.Errorf("company = %+v", company)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetCompanyMissingLogoReturnsEmpty(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, _ = w.Write([]byte(`{"id":420,"name":"Marvel Studios","logo_path":null}`))
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
client := NewClient("test-key", 1000)
|
||||
client.SetBaseURL(server.URL)
|
||||
|
||||
company, err := client.GetCompany(context.Background(), 420)
|
||||
if err != nil {
|
||||
t.Fatalf("GetCompany: %v", err)
|
||||
}
|
||||
if company.LogoPath != "" {
|
||||
t.Errorf("logo_path = %q, want empty for null", company.LogoPath)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetNetwork(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.URL.Path != "/network/213" {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
_, _ = w.Write([]byte(`{"id":213,"name":"Netflix","logo_path":"/wuU9.png"}`))
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
client := NewClient("test-key", 1000)
|
||||
client.SetBaseURL(server.URL)
|
||||
|
||||
network, err := client.GetNetwork(context.Background(), 213)
|
||||
if err != nil {
|
||||
t.Fatalf("GetNetwork: %v", err)
|
||||
}
|
||||
if network.ID != 213 || network.Name != "Netflix" || network.LogoPath != "/wuU9.png" {
|
||||
t.Errorf("network = %+v", network)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSearchMediaMovie(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.URL.Path != "/search/movie" {
|
||||
|
||||
@@ -86,6 +86,20 @@ type ExternalIDs struct {
|
||||
TVDBID int `json:"tvdb_id"`
|
||||
}
|
||||
|
||||
// Company is the decoded payload of TMDB's /company/{id} endpoint.
|
||||
type Company struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
LogoPath string `json:"logo_path"`
|
||||
}
|
||||
|
||||
// Network is the decoded payload of TMDB's /network/{id} endpoint.
|
||||
type Network struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
LogoPath string `json:"logo_path"`
|
||||
}
|
||||
|
||||
// Collection is the decoded payload of TMDB's /collection/{id} endpoint.
|
||||
// TMDB collections only contain movies (franchises, sagas), so each Part is
|
||||
// implicitly a movie. The Parts slice preserves TMDB's ordering, which is
|
||||
|
||||
Reference in New Issue
Block a user