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
@@ -3,6 +3,7 @@ package api
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/ponzischeme89/memby/server/internal/library"
|
||||
)
|
||||
@@ -42,6 +43,40 @@ func TestReachabilityAlertsAreDistinctAndSelfExplaining(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// The deployment notice is published by the gateway that is about to stop, and read by a
|
||||
// television that may not hear anything else for several minutes. Everything it needs to
|
||||
// render, and to be ordered against the news around it, has to travel with it.
|
||||
func TestDeploymentAlertIsSelfContained(t *testing.T) {
|
||||
at := time.Date(2026, 8, 5, 21, 30, 15, 0, time.UTC)
|
||||
|
||||
alert := deploymentAlert(at)
|
||||
|
||||
if alert.Kind != alertKindDeploying {
|
||||
t.Errorf("kind = %q, want %q", alert.Kind, alertKindDeploying)
|
||||
}
|
||||
if alert.Label == "" || alert.Title == "" || alert.Message == "" {
|
||||
t.Errorf("alert has nothing to render: %+v", alert)
|
||||
}
|
||||
// mergeAlerts orders by this, and an alert with no timestamp sorts last — behind the
|
||||
// library and reachability news it is most likely to arrive beside.
|
||||
if alert.AiredAt != "2026-08-05T21:30:15Z" {
|
||||
t.Errorf("airedAt = %q, want the publishing moment", alert.AiredAt)
|
||||
}
|
||||
// A second deployment must be a second banner: TVs dedupe by id for the life of the
|
||||
// install, so reusing one would silently skip the notice on every set that saw it.
|
||||
if later := deploymentAlert(at.Add(time.Minute)); later.ID == alert.ID {
|
||||
t.Errorf("two deployments share id %q", alert.ID)
|
||||
}
|
||||
}
|
||||
|
||||
// The window has to outlast the part of a deployment where nothing can be published: the
|
||||
// image build, the swap, and the gap before the new container answers.
|
||||
func TestDeploymentAlertOutlivesTheOutage(t *testing.T) {
|
||||
if deploymentAlertWindow < 10*time.Minute {
|
||||
t.Errorf("window %s is shorter than a build and a swap", deploymentAlertWindow)
|
||||
}
|
||||
}
|
||||
|
||||
// A sync that changed nothing must be silent: the import is scheduled, most passes find
|
||||
// nothing, and an hourly "no news" banner would train viewers to ignore the real ones.
|
||||
func TestAnnounceLibrarySyncIgnoresAQuietPass(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user