65 lines
2.8 KiB
Go
65 lines
2.8 KiB
Go
package tui
|
|
|
|
import (
|
|
"errors"
|
|
"strings"
|
|
"testing"
|
|
|
|
tea "github.com/charmbracelet/bubbletea"
|
|
|
|
"proxyctl/internal/app"
|
|
"proxyctl/internal/target"
|
|
)
|
|
|
|
type targetModule struct {
|
|
snapshot app.Snapshot
|
|
result app.Result
|
|
intents []app.Intent
|
|
}
|
|
|
|
func (m *targetModule) Snapshot() app.Snapshot { return m.snapshot }
|
|
func (m *targetModule) Dispatch(intent app.Intent) app.Result {
|
|
m.intents = append(m.intents, intent)
|
|
m.snapshot = m.result.Snapshot
|
|
return m.result
|
|
}
|
|
|
|
func TestTargetPanelShowsOnlyAvailableTargetsAndAppliesAsynchronously(t *testing.T) {
|
|
module := &targetModule{snapshot: app.Snapshot{ActiveProfile: "office", Targets: []app.TargetSnapshot{
|
|
{ID: "shell", Description: target.Description{Name: "Shell", Summary: "Exports for Bash/Zsh"}, Available: true, State: target.External, Evidence: "existing proxy"},
|
|
{ID: "apt", Description: target.Description{Name: "APT"}, Available: false},
|
|
}}}
|
|
module.result = app.Result{Snapshot: app.Snapshot{ActiveProfile: "office", Targets: []app.TargetSnapshot{{ID: "shell", Description: target.Description{Name: "Shell", Summary: "Exports for Bash/Zsh"}, Available: true, State: target.Enabled, Evidence: "matches"}}}, Notice: "Shell Target is now Enabled"}
|
|
model := NewModel(module)
|
|
view := model.View()
|
|
if !strings.Contains(view, "Shell") || strings.Contains(view, "APT") || !strings.Contains(view, "Exports for Bash/Zsh") {
|
|
t.Fatalf("Target panel:\n%s", view)
|
|
}
|
|
|
|
updated, command := model.Update(tea.KeyMsg{Type: tea.KeySpace})
|
|
model = updated.(Model)
|
|
if command == nil || !strings.Contains(model.View(), "Applying") || len(module.intents) != 0 {
|
|
t.Fatalf("operation did not expose applying state before effect:\n%s", model.View())
|
|
}
|
|
message := command()
|
|
updated, _ = model.Update(message)
|
|
model = updated.(Model)
|
|
if len(module.intents) != 1 || module.intents[0].Kind != app.SetTargetDesired || !module.intents[0].Enabled || !strings.Contains(model.View(), "Enabled") {
|
|
t.Fatalf("completed toggle = %#v\n%s", module.intents, model.View())
|
|
}
|
|
}
|
|
|
|
func TestTargetFailurePreservesTruthfulStateAndRendersRedactedError(t *testing.T) {
|
|
initial := app.Snapshot{ActiveProfile: "office", Targets: []app.TargetSnapshot{{ID: "shell", Description: target.Description{Name: "Shell"}, Available: true, State: target.Enabled}}}
|
|
module := &targetModule{snapshot: initial, result: app.Result{Snapshot: initial, Err: errors.New("permission denied for alice:REDACTED@proxy")}}
|
|
model := NewModel(module)
|
|
updated, command := model.Update(tea.KeyMsg{Type: tea.KeySpace})
|
|
model = updated.(Model)
|
|
updated, _ = model.Update(command())
|
|
model = updated.(Model)
|
|
view := model.View()
|
|
if !strings.Contains(view, "Enabled") || !strings.Contains(view, "\x1b[31mError:") || !strings.Contains(view, "REDACTED") {
|
|
t.Fatalf("failed operation rendering:\n%s", view)
|
|
}
|
|
}
|