122 lines
5.8 KiB
Go
122 lines
5.8 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", "Profile: office",
|
|
"> ● Enabled", "Shell", "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 TestCompleteModelFailedProgressSupplementsTruthfulTargetState(t *testing.T) {
|
|
for _, state := range []target.State{target.Enabled, target.Disabled, target.External, target.Drifted} {
|
|
t.Run(string(state), func(t *testing.T) {
|
|
module := &recordingModule{snapshot: app.Snapshot{Targets: []app.TargetSnapshot{{
|
|
ID: "shell", Description: target.Description{Name: "Shell"}, Available: true, State: state,
|
|
}}}}
|
|
model := resizedModel(t, module, themeModeNoColor, 120, 36)
|
|
model.operation.progress["shell"] = app.TargetProgressFailed
|
|
view := model.View()
|
|
wantState := targetStateLabel(state)
|
|
if !strings.Contains(view, "> "+wantState+" ! Failed Shell") {
|
|
t.Fatalf("failed progress replaced truthful %s state instead of supplementing it:\n%s", state, 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", "○ Unavailable", "apt-config was not detected",
|
|
"Persistent package proxy.", "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].Evidence = strings.Repeat("Scrollable evidence line. ", 45) + "END OF TARGET EVIDENCE"
|
|
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", "▶ 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 EVIDENCE",
|
|
"↑/↓: Scroll", "Tab: Targets",
|
|
)
|
|
|
|
model = resize(model, 120, 36)
|
|
view = model.View()
|
|
assertUsableFrame(t, view, 120, 36, "> ○ Disabled Product Target 22", "END OF TARGET", "EVIDENCE", "▶ 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 EVIDENCE", "▶ Target details [focused]")
|
|
}
|