* feat(jellycompat): install web assets at runtime * fix(jellycompat): recover stale web operation locks * fix(jellycompat): harden web component management * feat(admin): refine compat settings and restart status * chore(dev): add hot-reload docker compose stack * fix(dev): include npm in hot-reload backend * feat(admin): refine Jellyfin compatibility settings * feat(settings): improve jellyfin proxy summary * feat(settings): improve jellyfin web controls * fix(settings): update jellyfin web removal status * fix(settings): enable jellyfin web after install * feat(jellycompat): auto-select web ui version * test(api): update rate limit handler setup * feat(jellycompat): refine web ui install onboarding * fix(jellycompat): address web ui install review issues * fix(onboarding): mirror jellyfin api runtime status * fix(admin): remove global restart banner * fix(settings): gate restart required tracking * fix(jellyfin): ignore live settings for restart status * fix(jellyfin): avoid restart for live compat settings * fix(subtitles): normalize AI language codes * fix(catalog): support partial title search tokens * feat(branding): add white-label customization * Add push relay engineering plan - Document relay API contracts, APNs/FCM behavior, auth, storage, and ops - Capture implementation plan, provider references, decisions, and README --------- Co-authored-by: Quick <31828688+Quick104@users.noreply.github.com>
88 lines
2.7 KiB
Go
88 lines
2.7 KiB
Go
package handlers
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"github.com/Silo-Server/silo-server/internal/config"
|
|
)
|
|
|
|
func TestAdminServerStatusClearsAfterProcessRestart(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
restartStatus := NewServerRestartStatusTracker()
|
|
restartStatus.MarkRequired("settings")
|
|
|
|
handler := &AdminHandler{RestartStatus: restartStatus}
|
|
req := httptest.NewRequest(http.MethodGet, "/admin/server/status", nil)
|
|
rec := httptest.NewRecorder()
|
|
handler.HandleGetServerStatus(rec, req)
|
|
|
|
if rec.Code != http.StatusOK {
|
|
t.Fatalf("status = %d, body = %s", rec.Code, rec.Body.String())
|
|
}
|
|
var resp adminServerStatusResponse
|
|
if err := json.NewDecoder(rec.Body).Decode(&resp); err != nil {
|
|
t.Fatalf("decode response: %v", err)
|
|
}
|
|
if !resp.RestartRequired {
|
|
t.Fatal("RestartRequired = false, want true")
|
|
}
|
|
|
|
restartedHandler := &AdminHandler{RestartStatus: NewServerRestartStatusTracker()}
|
|
rec = httptest.NewRecorder()
|
|
restartedHandler.HandleGetServerStatus(rec, req)
|
|
|
|
if rec.Code != http.StatusOK {
|
|
t.Fatalf("status after restart = %d, body = %s", rec.Code, rec.Body.String())
|
|
}
|
|
if err := json.NewDecoder(rec.Body).Decode(&resp); err != nil {
|
|
t.Fatalf("decode response after restart: %v", err)
|
|
}
|
|
if resp.RestartRequired {
|
|
t.Fatal("RestartRequired = true after new process tracker, want false")
|
|
}
|
|
}
|
|
|
|
func TestAdminServerStatusDoesNotPromoteLiveJellyfinIdentitySettings(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
cfg, err := config.LoadFromDB(map[string]string{
|
|
"jellyfin_compat.enabled": "true",
|
|
"jellyfin_compat.listen": ":8096",
|
|
"jellyfin_compat.public_url": "http://127.0.0.1:8096",
|
|
"jellyfin_compat.server_name": "Silo",
|
|
"jellyfin_compat.emulated_server_version": "10.11.0",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("LoadFromDB: %v", err)
|
|
}
|
|
|
|
handler := &AdminHandler{
|
|
Config: cfg,
|
|
RestartStatus: NewServerRestartStatusTracker(),
|
|
SettingsRepo: &fakeServerSettingsStore{values: map[string]string{
|
|
"jellyfin_compat.public_url": "https://compat.example.test",
|
|
"jellyfin_compat.server_name": "Silo Compat",
|
|
"jellyfin_compat.emulated_server_version": "10.11.6",
|
|
}},
|
|
}
|
|
req := httptest.NewRequest(http.MethodGet, "/admin/server/status", nil)
|
|
rec := httptest.NewRecorder()
|
|
|
|
handler.HandleGetServerStatus(rec, req)
|
|
|
|
if rec.Code != http.StatusOK {
|
|
t.Fatalf("status = %d, body = %s", rec.Code, rec.Body.String())
|
|
}
|
|
var resp adminServerStatusResponse
|
|
if err := json.NewDecoder(rec.Body).Decode(&resp); err != nil {
|
|
t.Fatalf("decode response: %v", err)
|
|
}
|
|
if resp.RestartRequired {
|
|
t.Fatal("RestartRequired = true, want false for live Jellyfin identity settings")
|
|
}
|
|
}
|