jellyfin-tools/jellyfin-year-review/internal/generate/platforms_test.go
jellyfin-year-review/internal/generate/platforms_test.goRaw
1package generate
2
3import (
4 "reflect"
5 "testing"
6
7 "reelreview/internal/model"
8)
9
10func TestPlatformsCountDistinctEligibleTitles(t *testing.T) {
11 s := fixture()
12 s.Users = append(s.Users, model.User{ID: bob, Name: "Bob"})
13 s.Items[0].Studios = []string{"Netflix", "NETFLIX", "Unrelated studio"}
14 s.Items = append(s.Items,
15 model.Item{ID: "series", Title: "Show", Type: "Series", Studios: []string{"HBO Max", "HBO"}},
16 model.Item{ID: "e1", Type: "Episode", SeriesID: "series"},
17 model.Item{ID: "e2", Type: "Episode", SeriesID: "series"},
18 model.Item{ID: "apple", Type: "Movie", Studios: []string{"Apple Original Films"}},
19 model.Item{ID: "unknown", Type: "Movie", Studios: []string{"Warner Bros. Pictures"}},
20 model.Item{ID: "shared", Type: "Movie", Platforms: []string{" Netflix ", "netflix", "AppleTV", "Apple TV+"}},
21 model.Item{ID: "excluded", Type: "Movie", Platforms: []string{"Hulu"}},
22 )
23 for i, item := range []string{"film", "film", "e1", "e2", "e1", "apple", "unknown", "shared", "excluded"} {
24 p := play(item+string(rune('a'+i)), "2025-03-01T12:00:00Z", "2025-03-01T13:00:00Z")
25 p.ItemID = item
26 if item == "excluded" {
27 p.UserID = bob
28 }
29 s.Playback = append(s.Playback, p)
30 }
31 outside := play("outside", "2024-03-01T12:00:00Z", "2024-03-01T13:00:00Z")
32 outside.ItemID = "excluded"
33 short := play("short", "2025-03-01T12:00:00Z", "2025-03-01T12:00:30Z")
34 short.ItemID = "excluded"
35 s.Playback = append(s.Playback, outside, short)
36 want := []model.Platform{{Name: "Apple TV+", Movies: 2}, {Name: "Netflix", Movies: 2}, {Name: "HBO", Shows: 1}, {Name: "Other", Movies: 1}}
37 if got := compute(t, s, DefaultConfig(2025))[0].Platforms; !reflect.DeepEqual(got, want) {
38 t.Fatalf("platforms = %+v, want %+v", got, want)
39 }
40}
41
42func TestPlatformMetadataAndEmptyHistory(t *testing.T) {
43 for _, tc := range []struct {
44 name string
45 item model.Item
46 want []string
47 }{
48 {"explicit overrides studios", model.Item{Platforms: []string{" Custom Service ", "custom service"}, Studios: []string{"Netflix"}}, []string{"Custom Service"}},
49 {"blank explicit uses studios", model.Item{Platforms: []string{" "}, Studios: []string{"amazon prime video"}}, []string{"Prime Video"}},
50 {"missing metadata", model.Item{}, []string{}},
51 {"no guessed Disney availability", model.Item{Studios: []string{"Walt Disney Pictures"}}, []string{}},
52 } {
53 t.Run(tc.name, func(t *testing.T) {
54 if got := itemPlatforms(tc.item); !reflect.DeepEqual(got, tc.want) {
55 t.Fatalf("platforms = %v, want %v", got, tc.want)
56 }
57 })
58 }
59 if got := compute(t, fixture(), DefaultConfig(2025))[0].Platforms; len(got) != 0 {
60 t.Fatalf("empty history produced counts: %+v", got)
61 }
62}
63
64// Other stays last even when most watched titles lack platform metadata.
65func TestPlatformsKeepOtherLast(t *testing.T) {
66 movies := []model.Content{{ID: "a"}, {ID: "b"}, {ID: "c"}, {ID: "netflix"}}
67 items := map[string]model.Item{"netflix": {Studios: []string{"Netflix"}}}
68 want := []model.Platform{{Name: "Netflix", Movies: 1}, {Name: "Other", Movies: 3}}
69 if got := platforms(movies, nil, items); !reflect.DeepEqual(got, want) {
70 t.Fatalf("platforms = %+v, want %+v", got, want)
71 }
72}