2026-07-29 15:26:40 +12:00
|
|
|
package api
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"encoding/json"
|
|
|
|
|
"testing"
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
"github.com/ponzischeme89/memby/server/internal/sonarr"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func TestBuildSonarrRowIncludesScheduleAndAddedState(t *testing.T) {
|
|
|
|
|
location := time.FixedZone("NZST", 12*60*60)
|
|
|
|
|
air := time.Date(2026, 7, 27, 8, 0, 0, 0, time.UTC)
|
|
|
|
|
added := time.Date(2026, 7, 27, 8, 12, 0, 0, time.UTC)
|
|
|
|
|
row, err := buildSonarrRow([]sonarr.Episode{{
|
|
|
|
|
ID: 42,
|
|
|
|
|
SeriesID: 7,
|
|
|
|
|
SeasonNumber: 2,
|
|
|
|
|
EpisodeNumber: 4,
|
|
|
|
|
Title: "The Crossing",
|
|
|
|
|
AirDateUTC: &air,
|
|
|
|
|
HasFile: true,
|
|
|
|
|
Monitored: true,
|
|
|
|
|
EpisodeFile: &sonarr.EpisodeFile{DateAdded: &added},
|
|
|
|
|
Series: sonarr.Series{
|
|
|
|
|
ID: 7,
|
|
|
|
|
Title: "Northbound",
|
|
|
|
|
Images: []sonarr.Image{
|
|
|
|
|
{CoverType: "poster"},
|
|
|
|
|
{CoverType: "fanart"},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}}, time.Date(2026, 7, 27, 21, 0, 0, 0, location), location)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
if row.ID != "sonarr-airing-today" || row.Kind != "schedule" || len(row.Items) != 1 {
|
|
|
|
|
t.Fatalf("unexpected row: %+v", row)
|
|
|
|
|
}
|
|
|
|
|
var item sonarrScheduleItem
|
|
|
|
|
if err := json.Unmarshal(row.Items[0], &item); err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
if item.ID != "sonarr:7:42" || item.MembyEpisodeCode != "S02E04" {
|
|
|
|
|
t.Fatalf("unexpected identity: %+v", item)
|
|
|
|
|
}
|
|
|
|
|
if item.MembyAvailability != "available" || item.MembyAvailabilityText != "Added at 8:12 PM" {
|
|
|
|
|
t.Fatalf("unexpected availability: %+v", item)
|
|
|
|
|
}
|
|
|
|
|
if item.ImageTags["Primary"] == "" || len(item.BackdropImageTags) != 1 {
|
|
|
|
|
t.Fatalf("artwork was not exposed: %+v", item)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestBuildPrerollScheduleSplitsTodayAndWeek(t *testing.T) {
|
|
|
|
|
location := time.FixedZone("NZST", 12*60*60)
|
|
|
|
|
now := time.Date(2026, 7, 28, 10, 0, 0, 0, location)
|
|
|
|
|
today := time.Date(2026, 7, 28, 20, 30, 0, 0, location).UTC()
|
|
|
|
|
thursday := time.Date(2026, 7, 30, 19, 0, 0, 0, location).UTC()
|
|
|
|
|
schedule := buildPrerollSchedule([]sonarr.Episode{
|
|
|
|
|
{
|
2026-08-02 22:10:19 +12:00
|
|
|
ID: 14, SeriesID: 7, SeasonNumber: 1, EpisodeNumber: 4, Title: "Tonight",
|
|
|
|
|
AirDateUTC: &today, Series: sonarr.Series{
|
|
|
|
|
ID: 7, Title: "Northbound", Images: []sonarr.Image{{CoverType: "fanart"}},
|
|
|
|
|
},
|
2026-07-29 15:26:40 +12:00
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
SeasonNumber: 2, EpisodeNumber: 1, Title: "Later",
|
|
|
|
|
AirDateUTC: &thursday, HasFile: true, Series: sonarr.Series{Title: "Harbour"},
|
|
|
|
|
},
|
|
|
|
|
}, now, location)
|
|
|
|
|
|
|
|
|
|
if len(schedule.Today) != 1 || schedule.Today[0].Series != "Northbound" ||
|
2026-08-02 22:10:19 +12:00
|
|
|
schedule.Today[0].Schedule != "8:30 PM" || schedule.Today[0].ItemID != "sonarr:7:14" ||
|
|
|
|
|
schedule.Today[0].ImageType != "backdrop" {
|
2026-07-29 15:26:40 +12:00
|
|
|
t.Fatalf("unexpected today schedule: %+v", schedule.Today)
|
|
|
|
|
}
|
|
|
|
|
if len(schedule.ThisWeek) != 1 || schedule.ThisWeek[0].EpisodeCode != "S02E01" ||
|
|
|
|
|
schedule.ThisWeek[0].Availability != "Downloaded" {
|
|
|
|
|
t.Fatalf("unexpected week schedule: %+v", schedule.ThisWeek)
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-08-02 22:10:19 +12:00
|
|
|
|
|
|
|
|
func TestBuildSonarrRowCoversFiveDaysAndUsesRelativeAirLabels(t *testing.T) {
|
|
|
|
|
location := time.FixedZone("NZST", 12*60*60)
|
|
|
|
|
now := time.Date(2026, 7, 29, 8, 0, 0, 0, location)
|
|
|
|
|
episode := func(id int, air time.Time) sonarr.Episode {
|
|
|
|
|
utc := air.UTC()
|
|
|
|
|
return sonarr.Episode{
|
|
|
|
|
ID: id, SeriesID: id, SeasonNumber: 1, EpisodeNumber: id,
|
|
|
|
|
Title: "Episode", AirDateUTC: &utc,
|
|
|
|
|
Series: sonarr.Series{ID: id, Title: "Show"},
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
row, err := buildSonarrRow([]sonarr.Episode{
|
|
|
|
|
episode(1, time.Date(2026, 7, 29, 16, 0, 0, 0, location)),
|
|
|
|
|
episode(2, time.Date(2026, 7, 30, 16, 0, 0, 0, location)),
|
|
|
|
|
episode(3, time.Date(2026, 8, 2, 16, 0, 0, 0, location)),
|
|
|
|
|
episode(4, time.Date(2026, 8, 3, 16, 0, 0, 0, location)),
|
|
|
|
|
}, now, location)
|
|
|
|
|
if err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
if row.Title != "Shows airing in the next 5 days" || len(row.Items) != 3 {
|
|
|
|
|
t.Fatalf("five-day row = %+v", row)
|
|
|
|
|
}
|
|
|
|
|
labels := make([]string, 0, len(row.Items))
|
|
|
|
|
dayLabels := make([]string, 0, len(row.Items))
|
|
|
|
|
for _, raw := range row.Items {
|
|
|
|
|
var item sonarrScheduleItem
|
|
|
|
|
if err := json.Unmarshal(raw, &item); err != nil {
|
|
|
|
|
t.Fatal(err)
|
|
|
|
|
}
|
|
|
|
|
labels = append(labels, item.MembyAirLabel)
|
|
|
|
|
dayLabels = append(dayLabels, item.MembyAirDayLabel)
|
|
|
|
|
}
|
|
|
|
|
want := []string{
|
|
|
|
|
"In 8 hours (4:00 PM)",
|
|
|
|
|
"Tomorrow: 4:00 PM",
|
|
|
|
|
"Sunday: 4:00 PM",
|
|
|
|
|
}
|
|
|
|
|
for i := range want {
|
|
|
|
|
if labels[i] != want[i] {
|
|
|
|
|
t.Fatalf("labels = %#v, want %#v", labels, want)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
wantDays := []string{"Today", "Tomorrow", "Sunday"}
|
|
|
|
|
for i := range wantDays {
|
|
|
|
|
if dayLabels[i] != wantDays[i] {
|
|
|
|
|
t.Fatalf("day labels = %#v, want %#v", dayLabels, wantDays)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|