v0.170.0: root → Indítópult (302); Vezérlőpult at /dashboard; CLAUDE.md stale-note fix
/ now 302s to /launcher (ONE canonical URL per page — launcher body never served at /); the Vezérlőpult keeps /dashboard + its nav slot (operator ruling, reversing v0.163.0). Nav: Indítópult active on /launcher, Vezérlőpult href=/dashboard active there. Post-login default (/) and the topbar logo (/) flow through the redirect; login target unchanged. Repointed 2 dashboard-card tests /→/dashboard. Corrected the stale vacation/agent-DOWN note in CLAUDE.md (agent is up at 192.168.0.162:8443). Tests: 302 target+status, /dashboard 200, nav hrefs/active; red-proof verified.
This commit is contained in:
@@ -107,9 +107,9 @@ func TestDashboardBackupCard_ShowsLastRun(t *testing.T) {
|
||||
dumpAt := time.Date(2026, 7, 19, 3, 30, 0, 0, time.Local)
|
||||
s := newDashboardServer(t, dumpAt)
|
||||
|
||||
rec := getPage(t, s, "/")
|
||||
rec := getPage(t, s, "/dashboard") // v0.170.0: the Vezérlőpult moved from "/" to "/dashboard"
|
||||
if rec.Code != 200 {
|
||||
t.Fatalf("GET / = %d: %s", rec.Code, rec.Body.String())
|
||||
t.Fatalf("GET /dashboard = %d: %s", rec.Code, rec.Body.String())
|
||||
}
|
||||
card := backupCard(t, rec.Body.String())
|
||||
|
||||
@@ -127,9 +127,9 @@ func TestDashboardBackupCard_ShowsLastRun(t *testing.T) {
|
||||
func TestDashboardBackupCard_FreshBoxStaysHonest(t *testing.T) {
|
||||
s := newDashboardServer(t, time.Time{})
|
||||
|
||||
rec := getPage(t, s, "/")
|
||||
rec := getPage(t, s, "/dashboard") // v0.170.0: the Vezérlőpult moved from "/" to "/dashboard"
|
||||
if rec.Code != 200 {
|
||||
t.Fatalf("GET / = %d: %s", rec.Code, rec.Body.String())
|
||||
t.Fatalf("GET /dashboard = %d: %s", rec.Code, rec.Body.String())
|
||||
}
|
||||
card := backupCard(t, rec.Body.String())
|
||||
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
package web
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// v0.170.0 landing change (operator ruling, reversing v0.163.0): "/" is the Indítópult — it 302s to
|
||||
// /launcher (ONE canonical URL per page), and the Vezérlőpult keeps its own URL /dashboard.
|
||||
|
||||
// Root 302s to the launcher — the launcher body is NEVER served at "/".
|
||||
// Red-proof: revert the server.go case split (fold "/" back into the dashboard case) → "/" renders a
|
||||
// 200 dashboard and this fails on both the status and the Location.
|
||||
func TestRoot_RedirectsToLauncher(t *testing.T) {
|
||||
s := newDashboardServer(t, time.Time{})
|
||||
rec := httptest.NewRecorder()
|
||||
s.ServeHTTP(rec, httptest.NewRequest(http.MethodGet, "/", nil))
|
||||
|
||||
if rec.Code != http.StatusFound {
|
||||
t.Fatalf("GET / status = %d, want 302", rec.Code)
|
||||
}
|
||||
if loc := rec.Header().Get("Location"); loc != "/launcher" {
|
||||
t.Errorf("GET / Location = %q, want /launcher", loc)
|
||||
}
|
||||
// The launcher body must not be served at "/" (no two canonical URLs for one page).
|
||||
if strings.Contains(rec.Body.String(), "launch-tile") {
|
||||
t.Error("GET / served launcher body instead of redirecting")
|
||||
}
|
||||
}
|
||||
|
||||
// The Vezérlőpult is still served, now at /dashboard, with a 200 and its real content.
|
||||
func TestDashboard_ServedAtDashboardURL(t *testing.T) {
|
||||
s := newDashboardServer(t, time.Time{})
|
||||
rec := httptest.NewRecorder()
|
||||
s.ServeHTTP(rec, httptest.NewRequest(http.MethodGet, "/dashboard", nil))
|
||||
|
||||
if rec.Code != http.StatusOK {
|
||||
t.Fatalf("GET /dashboard status = %d, want 200", rec.Code)
|
||||
}
|
||||
if !strings.Contains(rec.Body.String(), "Vezérlőpult") {
|
||||
t.Error("/dashboard did not render the Vezérlőpult page")
|
||||
}
|
||||
}
|
||||
|
||||
// Nav hrefs + active states: Indítópult → /launcher (active on the launcher), Vezérlőpult →
|
||||
// /dashboard (active on the dashboard), and no item highlights on both.
|
||||
func TestNav_LauncherAndDashboardHrefsAndActive(t *testing.T) {
|
||||
onDashboard := renderNavFor(t, "dashboard")
|
||||
if !strings.Contains(onDashboard, `href="/dashboard" class="active"`) {
|
||||
t.Error("dashboard page: Vezérlőpult nav link is not href=/dashboard + active")
|
||||
}
|
||||
if !strings.Contains(onDashboard, `href="/launcher" class=""`) {
|
||||
t.Error("dashboard page: Indítópult nav link should NOT be active")
|
||||
}
|
||||
|
||||
onLauncher := renderNavFor(t, "launcher")
|
||||
if !strings.Contains(onLauncher, `href="/launcher" class="active"`) {
|
||||
t.Error("launcher page: Indítópult nav link is not href=/launcher + active")
|
||||
}
|
||||
if !strings.Contains(onLauncher, `href="/dashboard" class=""`) {
|
||||
t.Error("launcher page: Vezérlőpult nav link should NOT be active")
|
||||
}
|
||||
}
|
||||
@@ -363,7 +363,12 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
s.handleClaimSubmit(w, r)
|
||||
case path == "/claim/request-new-code" && r.Method == http.MethodPost:
|
||||
s.handleClaimRequestNewCode(w, r)
|
||||
case path == "/" || path == "/dashboard":
|
||||
case path == "/":
|
||||
// v0.170.0 (operator ruling reversing the v0.163.0 landing choice): the Indítópult is the
|
||||
// canonical landing page. "/" 302s to /launcher (ONE canonical URL per page — the launcher body
|
||||
// is never served AT "/"). Post-login lands on "/", so it flows here → the launcher.
|
||||
http.Redirect(w, r, "/launcher", http.StatusFound)
|
||||
case path == "/dashboard":
|
||||
s.dashboardHandler(w, r)
|
||||
case path == "/launcher":
|
||||
s.launcherHandler(w, r)
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
</div>
|
||||
<ul class="nav-links">
|
||||
<li><a href="/launcher" class="{{if eq .Page "launcher"}}active{{end}}"><svg class="ico"><use href="#i-rocket"/></svg>Indítópult</a></li>
|
||||
<li><a href="/" class="{{if eq .Page "dashboard"}}active{{end}}"><svg class="ico"><use href="#i-layout-grid"/></svg>Vezérlőpult</a></li>
|
||||
<li><a href="/dashboard" class="{{if eq .Page "dashboard"}}active{{end}}"><svg class="ico"><use href="#i-layout-grid"/></svg>Vezérlőpult</a></li>
|
||||
<li><a href="/stacks" class="{{if eq .Page "stacks"}}active{{end}}"><svg class="ico"><use href="#i-cloud"/></svg>Alkalmazások</a></li>
|
||||
{{$storageOpen := or (eq .Page "storage") (eq .Page "storage-network")}}
|
||||
<li class="nav-group{{if $storageOpen}} is-open{{end}}">
|
||||
|
||||
Reference in New Issue
Block a user