App v0.2.26 and gateway 0.1.20
Client: seek controls, Bazarr subtitle download and cast panel in the player; MDBList ratings strip; episode and schedule detail pages; series pace estimate; what's new panel; install-permission onboarding step; synced per-profile preferences; Emby outage banner. Gateway: rebuilt admin console (one fragment per page), preference history and restore, merged Continue Watching, Emby health probe, subtitle selection and Bazarr download, structured request logging with per-request identity, and embedded build version. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
2675e6d82b
commit
4a4df7a73c
@@ -0,0 +1,96 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ponzischeme89/memby/server/internal/radarr"
|
||||
"github.com/ponzischeme89/memby/server/internal/sonarr"
|
||||
)
|
||||
|
||||
func TestSeriesLifecycleTag(t *testing.T) {
|
||||
cases := map[string]lifecycleTag{
|
||||
"continuing": {Status: "continuing", Label: "CONTINUING"},
|
||||
"Continuing": {Status: "continuing", Label: "CONTINUING"},
|
||||
"upcoming": {Status: "upcoming", Label: "UPCOMING"},
|
||||
"ended": {Status: "ended", Label: "ENDED"},
|
||||
"deleted": {Status: "deleted", Label: "REMOVED"},
|
||||
// No tag at all rather than an invented one.
|
||||
"": {},
|
||||
"unknown": {},
|
||||
}
|
||||
for status, want := range cases {
|
||||
if got := seriesLifecycleTag(status); got != want {
|
||||
t.Fatalf("seriesLifecycleTag(%q) = %+v, want %+v", status, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMovieLifecycleTag(t *testing.T) {
|
||||
cases := map[string]lifecycleTag{
|
||||
"announced": {Status: "announced", Label: "ANNOUNCED"},
|
||||
"inCinemas": {Status: "incinemas", Label: "IN CINEMAS"},
|
||||
"released": {Status: "released", Label: "RELEASED"},
|
||||
"tba": {Status: "tba", Label: "TBA"},
|
||||
"deleted": {Status: "deleted", Label: "REMOVED"},
|
||||
"": {},
|
||||
}
|
||||
for status, want := range cases {
|
||||
if got := movieLifecycleTag(status); got != want {
|
||||
t.Fatalf("movieLifecycleTag(%q) = %+v, want %+v", status, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestScheduleRowsCarryLifecycle(t *testing.T) {
|
||||
now := time.Date(2026, 8, 4, 12, 0, 0, 0, time.UTC)
|
||||
airs := now.Add(3 * time.Hour)
|
||||
series := buildSonarrRowForTest(t, sonarr.Episode{
|
||||
ID: 7, SeriesID: 3, SeasonNumber: 2, EpisodeNumber: 4, AirDateUTC: &airs,
|
||||
Monitored: true, Series: sonarr.Series{ID: 3, Title: "Severance", Status: "continuing"},
|
||||
}, now)
|
||||
if series.MembyLifecycle != "continuing" || series.MembyLifecycleText != "CONTINUING" {
|
||||
t.Fatalf("sonarr card lifecycle = %q/%q", series.MembyLifecycle, series.MembyLifecycleText)
|
||||
}
|
||||
|
||||
digital := now.Add(24 * time.Hour)
|
||||
movie := buildRadarrRowForTest(t, radarr.Movie{
|
||||
ID: 11, Title: "Dune", DigitalRelease: &digital, Monitored: true, Status: "inCinemas",
|
||||
}, now)
|
||||
if movie.MembyLifecycle != "incinemas" || movie.MembyLifecycleText != "IN CINEMAS" {
|
||||
t.Fatalf("radarr card lifecycle = %q/%q", movie.MembyLifecycle, movie.MembyLifecycleText)
|
||||
}
|
||||
}
|
||||
|
||||
func buildSonarrRowForTest(t *testing.T, episode sonarr.Episode, now time.Time) sonarrScheduleItem {
|
||||
t.Helper()
|
||||
row, err := buildSonarrRow([]sonarr.Episode{episode}, now, time.UTC, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("buildSonarrRow: %v", err)
|
||||
}
|
||||
if len(row.Items) != 1 {
|
||||
t.Fatalf("expected one card, got %d", len(row.Items))
|
||||
}
|
||||
var item sonarrScheduleItem
|
||||
if err := json.Unmarshal(row.Items[0], &item); err != nil {
|
||||
t.Fatalf("decode card: %v", err)
|
||||
}
|
||||
return item
|
||||
}
|
||||
|
||||
func buildRadarrRowForTest(t *testing.T, movie radarr.Movie, now time.Time) radarrScheduleItem {
|
||||
t.Helper()
|
||||
row, err := buildRadarrRow([]radarr.Movie{movie}, now, time.UTC)
|
||||
if err != nil {
|
||||
t.Fatalf("buildRadarrRow: %v", err)
|
||||
}
|
||||
if len(row.Items) != 1 {
|
||||
t.Fatalf("expected one card, got %d", len(row.Items))
|
||||
}
|
||||
var item radarrScheduleItem
|
||||
if err := json.Unmarshal(row.Items[0], &item); err != nil {
|
||||
t.Fatalf("decode card: %v", err)
|
||||
}
|
||||
return item
|
||||
}
|
||||
Reference in New Issue
Block a user