package pages import ( "testing" ) // ── matchSurface tests ────────────────────────────────────── func TestMatchSurface_StaticRoot(t *testing.T) { surfaces := []any{ map[string]any{"path": "/", "title": "Dashboard"}, map[string]any{"path": "/submit", "title": "Submit"}, } s, params := matchSurface(surfaces, "/") if s == nil { t.Fatal("expected match for /") } if s["title"] != "Dashboard" { t.Errorf("expected Dashboard, got %v", s["title"]) } if len(params) != 0 { t.Errorf("expected no params, got %v", params) } } func TestMatchSurface_StaticPath(t *testing.T) { surfaces := []any{ map[string]any{"path": "/", "title": "Dashboard"}, map[string]any{"path": "/submit", "title": "Submit"}, map[string]any{"path": "/monitor", "title": "Monitor"}, } s, _ := matchSurface(surfaces, "/submit") if s == nil { t.Fatal("expected match for /submit") } if s["title"] != "Submit" { t.Errorf("expected Submit, got %v", s["title"]) } } func TestMatchSurface_ParamPath(t *testing.T) { surfaces := []any{ map[string]any{"path": "/", "title": "Dashboard"}, map[string]any{"path": "/:id", "title": "Detail"}, } s, params := matchSurface(surfaces, "/abc123") if s == nil { t.Fatal("expected match for /:id") } if s["title"] != "Detail" { t.Errorf("expected Detail, got %v", s["title"]) } if params["id"] != "abc123" { t.Errorf("expected id=abc123, got %v", params["id"]) } } func TestMatchSurface_MultiSegmentParam(t *testing.T) { surfaces := []any{ map[string]any{"path": "/monitor", "title": "Monitor"}, map[string]any{"path": "/monitor/:id", "title": "Instance Detail"}, } s, params := matchSurface(surfaces, "/monitor/inst-42") if s == nil { t.Fatal("expected match for /monitor/:id") } if s["title"] != "Instance Detail" { t.Errorf("expected Instance Detail, got %v", s["title"]) } if params["id"] != "inst-42" { t.Errorf("expected id=inst-42, got %v", params["id"]) } } func TestMatchSurface_NoMatch(t *testing.T) { surfaces := []any{ map[string]any{"path": "/", "title": "Dashboard"}, map[string]any{"path": "/submit", "title": "Submit"}, } s, _ := matchSurface(surfaces, "/nonexistent/deep") if s != nil { t.Errorf("expected no match, got %v", s) } } func TestMatchSurface_StaticPreferredOverParam(t *testing.T) { surfaces := []any{ map[string]any{"path": "/:id", "title": "Detail"}, map[string]any{"path": "/new", "title": "New"}, } s, params := matchSurface(surfaces, "/new") if s == nil { t.Fatal("expected match for /new") } if s["title"] != "New" { t.Errorf("expected static match 'New', got %v", s["title"]) } if len(params) != 0 { t.Errorf("expected no params for static match, got %v", params) } } func TestMatchSurface_EmptySurfaces(t *testing.T) { s, _ := matchSurface([]any{}, "/") if s != nil { t.Errorf("expected no match for empty surfaces, got %v", s) } } // ── splitPath tests ───────────────────────────────────────── func TestSplitPath(t *testing.T) { tests := []struct { input string want int }{ {"/", 0}, {"/submit", 1}, {"/monitor/:id", 2}, {"/:id/edit", 2}, } for _, tt := range tests { parts := splitPath(tt.input) if len(parts) != tt.want { t.Errorf("splitPath(%q) = %d parts, want %d", tt.input, len(parts), tt.want) } } } // ── findNavSurface tests ──────────────────────────────────── func TestFindNavSurface_ExplicitNav(t *testing.T) { surfaces := []any{ map[string]any{"path": "/", "title": "Dashboard"}, map[string]any{"path": "/monitor", "title": "Monitor", "nav": true}, } s := findNavSurface(surfaces) if s == nil { t.Fatal("expected nav surface") } if s["title"] != "Monitor" { t.Errorf("expected Monitor, got %v", s["title"]) } } func TestFindNavSurface_FallbackRoot(t *testing.T) { surfaces := []any{ map[string]any{"path": "/submit", "title": "Submit"}, map[string]any{"path": "/", "title": "Dashboard"}, } s := findNavSurface(surfaces) if s == nil { t.Fatal("expected nav surface") } if s["title"] != "Dashboard" { t.Errorf("expected Dashboard, got %v", s["title"]) } } func TestFindNavSurface_NoMatch(t *testing.T) { surfaces := []any{ map[string]any{"path": "/submit", "title": "Submit"}, map[string]any{"path": "/admin", "title": "Admin"}, } s := findNavSurface(surfaces) if s != nil { t.Errorf("expected nil, got %v", s) } } // ── evaluateAccess tests ──────────────────────────────────── // Note: evaluateAccess depends on gin.Context which is hard to unit test // without a full Gin setup. These are covered via handler integration tests. // The matchSurface + splitPath + findNavSurface functions above are the // pure-logic components that benefit most from unit testing.