Files
proxy/internal/tui/dashboard_test.go
T

110 lines
5.4 KiB
Go

package tui
import (
"fmt"
"strings"
"testing"
"proxyctl/internal/app"
"proxyctl/internal/target"
)
func TestCompleteModelWideOperationsConsoleShowsStableAvailableTargetDashboard(t *testing.T) {
module := &recordingModule{snapshot: app.Snapshot{
ActiveProfile: "office",
Targets: []app.TargetSnapshot{
{ID: "shell", Description: target.Description{Name: "Shell", Summary: "Shell summary", Details: "Shell details"}, Available: true, State: target.Enabled, Evidence: "matches Active Profile"},
{ID: "apt", Description: target.Description{Name: "APT"}, Available: false, AvailabilityEvidence: "apt-config was not detected"},
{ID: "docker-client", Description: target.Description{Name: "Docker client"}, Available: true, State: target.External, Evidence: "existing settings"},
{ID: "gnome", Description: target.Description{Name: "GNOME"}, Available: true, State: target.Disabled, Evidence: "proxy mode is none"},
{ID: "docker-daemon", Description: target.Description{Name: "Docker daemon"}, Available: true, State: target.Drifted, Evidence: "managed values differ"},
},
}}
view := resizedModel(t, module, themeModeNoColor, 120, 36).View()
assertUsableFrame(t, view, 120, 36,
"proxyctl", "Active Profile: office",
"● Enabled 1", "○ Disabled 1", "◇ External 1", "! Drifted 1",
"> ● Enabled", "Shell", "State: ● Enabled", "Evidence: matches Active Profile",
)
if strings.Contains(view, "APT") || strings.Contains(view, "apt-config was not detected") {
t.Fatalf("default dashboard included an unavailable Target:\n%s", view)
}
if !sameLine(view, "Targets", "Target details") {
t.Fatalf("wide dashboard did not compose list and details side by side:\n%s", view)
}
if !(strings.Index(view, "Shell") < strings.Index(view, "Docker client") && strings.Index(view, "Docker client") < strings.Index(view, "GNOME") && strings.Index(view, "GNOME") < strings.Index(view, "Docker daemon")) {
t.Fatalf("available Target product order changed:\n%s", view)
}
}
func TestCompleteModelDashboardRevealsUnavailableEvidenceAndStructuredDetails(t *testing.T) {
module := &recordingModule{snapshot: app.Snapshot{Targets: []app.TargetSnapshot{
{ID: "shell", Description: target.Description{Name: "Shell"}, Available: true, State: target.Disabled, Evidence: "fragment absent"},
{ID: "apt", Description: target.Description{
Name: "APT", Summary: "Persistent package proxy.", Details: "Longer APT explanation.",
Scope: "package operations across privilege boundaries", Permissions: "pre-existing root write authority",
Ownership: "isolated overlay; disabling reveals the previous configuration", RestartRisk: "none",
}, Available: false, AvailabilityEvidence: "apt-config was not detected"},
{ID: "docker", Description: target.Description{Name: "Docker daemon"}, Available: true, State: target.Enabled, Evidence: "managed values match"},
}}}
model := resizedModel(t, module, themeModeNoColor, 120, 36)
model = updateKey(model, "u")
model = updateKey(model, "down")
view := model.View()
assertUsableFrame(t, view, 120, 36,
"> ○ Unavailable APT", "State: ○ Unavailable", "Evidence: apt-config was not detected",
"Affects: package operations across privilege boundaries",
"Permissions: pre-existing root write authority",
"Ownership & restoration: isolated overlay; disabling reveals the", "previous configuration",
"Restart risk: none", "Persistent package proxy.", "Longer APT explanation.",
"u: hide unavailable",
)
if !(strings.Index(view, "Shell") < strings.Index(view, "APT") && strings.Index(view, "APT") < strings.Index(view, "Docker daemon")) {
t.Fatalf("revealing unavailable Targets changed product order:\n%s", view)
}
if strings.Contains(view, "Space: toggle") {
t.Fatalf("unavailable Target exposed a mutation action:\n%s", view)
}
}
func TestCompleteModelNarrowDashboardFocusAndIndependentScrollingRetainTargetIdentity(t *testing.T) {
targets := make([]app.TargetSnapshot, 28)
for i := range targets {
targets[i] = app.TargetSnapshot{
ID: fmt.Sprintf("target-%02d", i), Description: target.Description{Name: fmt.Sprintf("Product Target %02d", i)},
Available: true, State: target.Disabled, Evidence: fmt.Sprintf("evidence-%02d", i),
}
}
targets[22].Description.Summary = "Selected identity summary"
targets[22].Description.Details = strings.Repeat("Scrollable detail line. ", 45) + "END OF TARGET DETAILS"
module := &recordingModule{snapshot: app.Snapshot{ActiveProfile: "office", Targets: targets}}
model := resizedModel(t, module, themeModeNoColor, 80, 24)
for range 22 {
model = updateKey(model, "down")
}
view := model.View()
assertUsableFrame(t, view, 80, 24, "> ○ Disabled Product Target 22", "Selected identity summary", "▶ Targets [focused]")
model = updateKey(model, "tab")
for range 70 {
model = updateKey(model, "down")
}
view = model.View()
assertUsableFrame(t, view, 80, 24,
"> ○ Disabled Product Target 22", "▶ Target details [focused]", "END OF", "TARGET DETAILS",
"↑/k ↓/j PgUp/PgDn: scroll", "Tab: focus Targets",
)
model = resize(model, 120, 36)
view = model.View()
assertUsableFrame(t, view, 120, 36, "> ○ Disabled Product Target 22", "END OF TARGET DETAILS", "▶ Target details [focused]")
if !sameLine(view, "Targets", "Target details") {
t.Fatalf("resized dashboard did not become side by side:\n%s", view)
}
model = resize(model, 80, 24)
assertUsableFrame(t, model.View(), 80, 24, "> ○ Disabled Product Target 22", "END OF", "TARGET DETAILS", "▶ Target details [focused]")
}