package library import ( "encoding/json" "strings" "testing" ) func TestToLibraryItemFlattensColumnsAndKeepsPayload(t *testing.T) { raw := json.RawMessage(`{ "Id":"42","Name":"Arrival","Type":"Movie","ProductionYear":2016, "CommunityRating":7.9,"Genres":["Science Fiction"," Drama "], "Studios":[{"Name":"Paramount"},{"Name":" "}], "DateCreated":"2024-03-01T10:00:00Z", "ImageTags":{"Primary":"abc"} }`) item, ok := toLibraryItem(raw) if !ok { t.Fatal("expected the item to parse") } if item.ID != "42" || item.Name != "Arrival" || item.Type != "Movie" { t.Fatalf("unexpected columns: %+v", item) } if *item.ProductionYear != 2016 || *item.CommunityRating != 7.9 { t.Fatalf("unexpected numbers: %+v", item) } // Whitespace-only studio names are dropped, real ones trimmed. if len(item.Studios) != 1 || item.Studios[0] != "Paramount" { t.Fatalf("unexpected studios: %v", item.Studios) } if len(item.Genres) != 2 || item.Genres[1] != "Drama" { t.Fatalf("genres should be trimmed: %v", item.Genres) } if item.DateCreated == nil || item.DateCreated.Year() != 2024 { t.Fatalf("unexpected date: %v", item.DateCreated) } // The payload must survive byte-identical: it is what the TV receives, and it holds // fields (image tags, overview) that no column models. if string(item.Payload) != string(raw) { t.Fatal("payload was altered") } } func TestToLibraryItemRejectsUnusableRows(t *testing.T) { for name, raw := range map[string]string{ "malformed": `{"Id":`, "no id": `{"Name":"Nameless"}`, } { if _, ok := toLibraryItem(json.RawMessage(raw)); ok { t.Fatalf("%s should have been rejected", name) } } } func TestSearchTextIncludesSeriesNameSoEpisodesAreFindable(t *testing.T) { year := 2022 text := searchText(syncItem{ Name: "Good News About Hell", Type: "Episode", SeriesName: "Severance", ProductionYear: &year, Genres: []string{"Drama", "Thriller"}, }) for _, want := range []string{"Good News About Hell", "Severance", "2022", "Drama"} { if !strings.Contains(text, want) { t.Fatalf("search text %q is missing %q", text, want) } } } func TestSearchTextDoesNotRepeatTheTitleForAMovie(t *testing.T) { text := searchText(syncItem{Name: "Dune", Type: "Movie", SeriesName: "Dune"}) if strings.Count(strings.ToLower(text), "dune") != 1 { t.Fatalf("title should appear once, got %q", text) } }