Files
memby/server/internal/api/gateway_settings_test.go
T
2026-08-28 23:00:02 +12:00

110 lines
4.0 KiB
Go

package api
import (
"log/slog"
"testing"
"time"
"github.com/ponzischeme89/memby/server/internal/logging"
"github.com/ponzischeme89/memby/server/internal/store"
)
// The three meanings a duration-like override carries. Zero is not "off" — that is the
// whole point of the -1, and reading it as off would silently disable an alert window an
// operator had merely left alone.
func TestOverrideWindowSeparatesOffFromDeployed(t *testing.T) {
deployed := 15 * time.Minute
if got := overrideWindow(0, time.Minute, deployed); got != deployed {
t.Fatalf("zero should fall back to the deployed value, got %s", got)
}
if got := overrideWindow(store.GatewaySettingsOff, time.Minute, deployed); got != 0 {
t.Fatalf("a negative override should switch the window off, got %s", got)
}
if got := overrideWindow(45, time.Minute, deployed); got != 45*time.Minute {
t.Fatalf("a positive override should be taken in the given unit, got %s", got)
}
}
// The probe loop must keep ticking while it is switched off, or turning it back on would
// need a restart of the gateway — which is the thing the setting exists to avoid.
func TestEmbyProbeDelayKeepsTickingWhileOff(t *testing.T) {
if got := embyProbeDelay(0); got != time.Minute {
t.Fatalf("a switched-off probe should still wake up, got %s", got)
}
if got := embyProbeDelay(30 * time.Second); got != 30*time.Second {
t.Fatalf("a live probe should wait its interval, got %s", got)
}
}
func TestGatewaySettingsChangesReportsOnlyWhatMoved(t *testing.T) {
before := store.GatewaySettings{Timezone: "Pacific/Auckland", SessionIdleDays: 30}
if summary := gatewaySettingsChanges(before, before); summary != "" {
t.Fatalf("an unchanged save must not be news, got %q", summary)
}
one := before
one.LogLevel = "debug"
if summary := gatewaySettingsChanges(before, one); summary != "The gateway's log level was changed" {
t.Fatalf("one change reads wrong: %q", summary)
}
two := one
two.SessionIdleDays = 60
summary := gatewaySettingsChanges(before, two)
if summary != "The gateway's log level and session expiry were changed" {
t.Fatalf("two changes read wrong: %q", summary)
}
}
func TestNotificationDisplayDefaultsToHomeOnly(t *testing.T) {
s := &Server{}
if got := s.notificationDisplay(); got != store.NotificationDisplayHomeOnly {
t.Fatalf("unset notification display = %q, want %q", got, store.NotificationDisplayHomeOnly)
}
s.gatewaySettings.set(store.GatewaySettings{NotificationDisplay: store.NotificationDisplayEverywhere})
if got := s.notificationDisplay(); got != store.NotificationDisplayEverywhere {
t.Fatalf("notification display = %q, want everywhere", got)
}
}
func TestCacheOverridesFallBackToDeployed(t *testing.T) {
s := &Server{}
s.cfg.HomeTTL = 60 * time.Second
s.cfg.RecommendTTL = 24 * time.Hour
s.cfg.ForYouRebuildHour = 4
if got := s.homeTTL(); got != 60*time.Second {
t.Fatalf("unset home TTL should be the deployed value, got %s", got)
}
if got := s.recommendTTL(); got != 24*time.Hour {
t.Fatalf("unset recommend TTL should be the deployed value, got %s", got)
}
if got := s.forYouRebuildHour(); got != 4 {
t.Fatalf("unset rebuild hour should be the deployed value, got %d", got)
}
midnight := 0
s.gatewaySettings.set(store.GatewaySettings{
HomeTTLSeconds: 30, RecommendTTLHours: 6, ForYouRebuildHour: &midnight,
})
if got := s.homeTTL(); got != 30*time.Second {
t.Fatalf("home TTL override not applied, got %s", got)
}
if got := s.recommendTTL(); got != 6*time.Hour {
t.Fatalf("recommend TTL override not applied, got %s", got)
}
if got := s.forYouRebuildHour(); got != 0 {
t.Fatalf("a rebuild-hour override of midnight must win over the deployed 4, got %d", got)
}
}
func TestLevelNameCoversTheVocabulary(t *testing.T) {
for _, level := range store.GatewayLogLevels {
if got := levelName(parseTestLevel(t, level)); got != level {
t.Fatalf("%s round-tripped as %s", level, got)
}
}
}
func parseTestLevel(t *testing.T, name string) slog.Level {
t.Helper()
return logging.ParseLevel(name)
}