package ui import ( "testing" "git.stinnesbeck.com/nils/arr-tui/internal/arr" "git.stinnesbeck.com/nils/arr-tui/internal/sonarr" ) func sampleReleases() []arr.Release { return []arr.Release{ {GUID: "rej-big", Size: 40 << 30, AgeMinutes: 60, QualityWeight: 2000, Rejections: []string{"no space"}}, {GUID: "ok-720", Size: 4 << 30, AgeMinutes: 600, QualityWeight: 1000, Approved: true}, {GUID: "ok-1080", Size: 8 << 30, AgeMinutes: 100, QualityWeight: 1800, Approved: true}, {GUID: "ok-1080-score", Size: 6 << 30, AgeMinutes: 900, QualityWeight: 1800, CustomFormatScore: 50, Approved: true}, } } func guids(rs []arr.Release) []string { out := make([]string, len(rs)) for i, r := range rs { out[i] = r.GUID } return out } func equal(a, b []string) bool { if len(a) != len(b) { return false } for i := range a { if a[i] != b[i] { return false } } return true } func TestVisibleReleasesSort(t *testing.T) { all := sampleReleases() tests := []struct { name string hide bool mode int want []string }{ {"best: approved first, score, quality", false, sortBest, []string{"ok-1080-score", "ok-1080", "ok-720", "rej-big"}}, {"size desc", false, sortSize, []string{"rej-big", "ok-1080", "ok-1080-score", "ok-720"}}, {"newest first", false, sortAge, []string{"rej-big", "ok-1080", "ok-720", "ok-1080-score"}}, {"hide rejected", true, sortBest, []string{"ok-1080-score", "ok-1080", "ok-720"}}, } for _, tc := range tests { if got := guids(visibleReleases(all, tc.hide, tc.mode, attrFilter{})); !equal(got, tc.want) { t.Errorf("%s: got %v, want %v", tc.name, got, tc.want) } } if all[0].GUID != "rej-big" { t.Error("visibleReleases must not reorder its input") } } func TestReleaseMark(t *testing.T) { tests := map[string]arr.Release{ "[green]✓[-]": {Approved: true}, "[red]✗[-]": {Rejected: true, Rejections: []string{"x"}}, "[yellow]~[-]": {Rejected: true, TemporarilyRejected: true}, } for want, r := range tests { if got := releaseMark(r); got != want { t.Errorf("releaseMark(%+v) = %q, want %q", r, got, want) } } } func TestFormatSizeAndAge(t *testing.T) { sizes := map[int64]string{0: "-", 2048: "2 KB", 5 << 20: "5 MB", 3<<30 + 1<<29: "3.5 GB"} for in, want := range sizes { if got := formatSize(in); got != want { t.Errorf("formatSize(%d) = %q, want %q", in, got, want) } } ages := map[float64]string{5: "5m", 120: "2h", 47 * 60: "47h", 3 * 24 * 60: "3d"} for in, want := range ages { if got := formatReleaseAge(in); got != want { t.Errorf("formatReleaseAge(%v) = %q, want %q", in, got, want) } } } func TestSummarizeSeasons(t *testing.T) { eps := []sonarr.Episode{ {SeasonNumber: 1, EpisodeNumber: 1, HasFile: true}, {SeasonNumber: 1, EpisodeNumber: 2}, {SeasonNumber: 0, EpisodeNumber: 1}, {SeasonNumber: 2, EpisodeNumber: 1}, } got := summarizeSeasons(eps) want := []seasonSummary{{2, 1, 0}, {1, 2, 1}, {0, 1, 0}} if len(got) != len(want) { t.Fatalf("got %+v", got) } for i := range want { if got[i] != want[i] { t.Errorf("season %d: got %+v, want %+v", i, got[i], want[i]) } } if seasonLabel(0) != "Specials" || seasonLabel(3) != "Season 3" { t.Error("seasonLabel") } } func TestVisibleReleasesAttrFilter(t *testing.T) { rel := func(guid, title string) arr.Release { return arr.Release{GUID: guid, Title: title} } all := []arr.Release{ rel("a", "Movie.2160p.DV.x265-G"), rel("b", "Movie.1080p.x264-G"), rel("c", "Movie.1080p.x265-G"), } got := guids(visibleReleases(all, false, sortBest, attrFilter{res: "1080p", codec: "x265"})) if !equal(got, []string{"c"}) { t.Errorf("1080p x265 = %v", got) } got = guids(visibleReleases(all, false, sortBest, attrFilter{hdr: "DV"})) if !equal(got, []string{"a"}) { t.Errorf("DV = %v", got) } }