arnaucube
arnaucube/jellyfin-toolsPublic Self-hosted repository
jellyfin-tools/jellyfin-year-review/internal/source/snapshot_test.go
jellyfin-year-review/internal/source/snapshot_test.goRaw
 1package source
 2
 3import (
 4	"os"
 5	"path/filepath"
 6	"testing"
 7	"time"
 8
 9	"reelreview/internal/model"
10)
11
12func TestJellystatRawRows(t *testing.T) {
13	path := filepath.Join(t.TempDir(), "rows.jsonl")
14	row := `{"Id":"record1","UserId":"AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA","NowPlayingItemId":"series","EpisodeId":"episode","PlaybackDuration":"1800","ActivityDateInserted":"2025-05-01T19:00:00Z","DeviceName":"TV","Client":"Jellyfin"}`
15	if e := os.WriteFile(path, []byte(row+"\n"+row+"\n"), 0600); e != nil {
16		t.Fatal(e)
17	}
18	s, e := Jellystat(path, []model.User{{ID: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}}, nil, time.Now(), "test coverage")
19	if e != nil {
20		t.Fatal(e)
21	}
22	if len(s.Playback) != 1 || s.Playback[0].ItemID != "episode" || s.Playback[0].Exact || s.Playback[0].Seconds != 1800 {
23		t.Fatalf("incorrect raw source semantics %+v", s)
24	}
25	if e := os.WriteFile(path, []byte(`{"results":[{}],"TotalDuration":1800}`), 0600); e != nil {
26		t.Fatal(e)
27	}
28	if _, e := Jellystat(path, nil, nil, time.Now(), "test"); e == nil {
29		t.Fatal("grouped API result accepted")
30	}
31}
32func TestInvalidSource(t *testing.T) {
33	s := model.Snapshot{Version: 1, CapturedAt: time.Now(), Source: "test", Coverage: "test", Users: []model.User{{ID: "../escape"}}}
34	if Validate(&s) == nil {
35		t.Fatal("invalid user ID")
36	}
37	s.Users = nil
38	s.Playback = []model.Playback{{ID: "x", UserID: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", ItemID: "x", Seconds: -1}}
39	if Validate(&s) == nil {
40		t.Fatal("negative seconds")
41	}
42}
43
44func TestPlaybackReportingImportsRejected(t *testing.T) {
45	path := filepath.Join(t.TempDir(), "rows.jsonl")
46	row := `{"Id":"record1","UserId":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","NowPlayingItemId":"film","PlaybackDuration":1800,"ActivityDateInserted":"2025-05-01T19:00:00Z","imported":true}`
47	if e := os.WriteFile(path, []byte(row), 0600); e != nil {
48		t.Fatal(e)
49	}
50	if _, err := Jellystat(path, nil, nil, time.Now(), "test"); err == nil {
51		t.Fatal("prohibited plugin import accepted")
52	}
53}