package app_test import ( "context" "errors" "path/filepath" "strings" "testing" "proxyctl/internal/app" "proxyctl/internal/profile" "proxyctl/internal/target" ) type fakeTarget struct { available bool state target.State setErr error setState target.State confirmation string calls []bool } func (f *fakeTarget) ID() string { return "shell" } func (f *fakeTarget) Description() target.Description { return target.Description{Name: "Shell", Summary: "Shell summary", Details: "Shell details"} } func (f *fakeTarget) Availability(context.Context) target.Availability { return target.Availability{Available: f.available, Evidence: "fake detection"} } func (f *fakeTarget) Inspect(context.Context, *profile.Profile) target.Inspection { return target.Inspection{State: f.state, Evidence: "actual state"} } func (f *fakeTarget) Confirmation(bool) string { return f.confirmation } func (f *fakeTarget) SetDesired(_ context.Context, enabled bool, _ *profile.Profile) target.OperationResult { f.calls = append(f.calls, enabled) if f.setErr == nil { if f.setState != "" { f.state = f.setState } else if enabled { f.state = target.Enabled } else { f.state = target.Disabled } } return target.OperationResult{Inspection: target.Inspection{State: f.state, Evidence: "re-inspected actual state"}, Err: f.setErr} } func TestApplicationTargetSeamRequiresActiveProfileAndReturnsTruthfulResults(t *testing.T) { adapter := &fakeTarget{available: true, state: target.External} application, err := app.NewWithTargets(profile.NewFileStore(filepath.Join(t.TempDir(), "profiles.json")), []target.Target{adapter}) if err != nil { t.Fatal(err) } if result := application.Dispatch(app.Intent{Kind: app.RefreshTargets}); result.Err != nil { t.Fatal(result.Err) } initial := application.Snapshot() if len(initial.Targets) != 1 || initial.Targets[0].State != target.External || initial.Targets[0].Description.Summary != "Shell summary" { t.Fatalf("initial Target snapshot = %#v", initial.Targets) } result := application.Dispatch(app.Intent{Kind: app.ApplyProfileToTarget, TargetID: "shell"}) if result.Err == nil || !strings.Contains(result.Err.Error(), "Profile management") || len(adapter.calls) != 0 || result.Snapshot.Targets[0].State != target.External { t.Fatalf("enable without Active Profile = %#v, calls=%v", result, adapter.calls) } createAndActivate(t, application) result = application.Dispatch(app.Intent{Kind: app.ApplyProfileToTarget, TargetID: "shell"}) if result.Err != nil || result.Snapshot.Targets[0].State != target.Enabled || len(adapter.calls) != 1 { t.Fatalf("enable result = %#v", result) } adapter.setErr = errors.New("permission denied") adapter.state = target.Drifted result = application.Dispatch(app.Intent{Kind: app.RestoreOriginal, TargetID: "shell"}) if result.Err == nil || result.Snapshot.Targets[0].State != target.Drifted || result.Snapshot.Targets[0].Evidence != "actual state" { t.Fatalf("failed operation not truthful: %#v", result) } } func TestApplicationRequiresTargetConfirmationBeforeMutation(t *testing.T) { adapter := &fakeTarget{available: true, state: target.Disabled, confirmation: "Docker will restart immediately and may disrupt running work."} application, err := app.NewWithTargets(profile.NewFileStore(filepath.Join(t.TempDir(), "profiles.json")), []target.Target{targetWithID{fakeTarget: adapter, id: "docker-daemon"}}) if err != nil { t.Fatal(err) } createAndActivate(t, application) refreshApplicationTargets(t, application) warning := application.Dispatch(app.Intent{Kind: app.EnableTarget, TargetID: "docker-daemon"}) if warning.ConfirmationRequest == nil || warning.Err != nil || len(adapter.calls) != 0 || warning.Snapshot.Targets[0].State != target.Disabled { t.Fatalf("unconfirmed result = %#v, calls=%v", warning, adapter.calls) } adapter.confirmation = "Updated restart warning after state changed." stale := application.Dispatch(app.Intent{Kind: app.EnableTarget, TargetID: "docker-daemon", Confirm: true, ConfirmationToken: warning.ConfirmationRequest.Token}) if stale.ConfirmationRequest == nil || stale.ConfirmationRequest.Token == warning.ConfirmationRequest.Token || len(adapter.calls) != 0 { t.Fatalf("stale confirmation was accepted = %#v, calls=%v", stale, adapter.calls) } confirmed := application.Dispatch(app.Intent{Kind: app.EnableTarget, TargetID: "docker-daemon", Confirm: true, ConfirmationToken: stale.ConfirmationRequest.Token}) if confirmed.Err != nil || len(adapter.calls) != 1 || confirmed.Snapshot.Targets[0].State != target.Enabled { t.Fatalf("confirmed result = %#v, calls=%v", confirmed, adapter.calls) } } type authorityTarget struct { *fakeTarget allowed bool reason string } func (t *authorityTarget) MutationAuthority(context.Context) target.Check { return target.Check{Name: "mutation authority", OK: t.allowed, Evidence: t.reason} } func TestApplicationDisablesMutationWhenCurrentProcessLacksAuthority(t *testing.T) { adapter := &authorityTarget{fakeTarget: &fakeTarget{available: true, state: target.Disabled}, reason: "requires elevated authority"} application, err := app.NewWithTargets(profile.NewFileStore(filepath.Join(t.TempDir(), "profiles.json")), []target.Target{adapter}) if err != nil { t.Fatal(err) } createAndActivate(t, application) refreshApplicationTargets(t, application) snapshot := application.Snapshot() if snapshot.Targets[0].PrimaryAction.Available || snapshot.Targets[0].PrimaryAction.DisabledReason != adapter.reason { t.Fatalf("authority policy = %#v", snapshot.Targets[0].PrimaryAction) } result := application.Dispatch(app.Intent{Kind: app.EnableTarget, TargetID: adapter.ID()}) if result.Err == nil || !strings.Contains(result.Err.Error(), adapter.reason) || len(adapter.calls) != 0 { t.Fatalf("blocked mutation result = %#v calls=%v", result, adapter.calls) } } type targetWithID struct { *fakeTarget id string } func (t targetWithID) ID() string { return t.id } func TestTargetMutationReportsLoggingFailureAfterKeepingAppliedState(t *testing.T) { adapter := &fakeTarget{available: true, state: target.Disabled} logger := &recordingLog{err: errors.New("log device full")} application, err := app.NewWithTargetsAndRuntime(profile.NewFileStore(filepath.Join(t.TempDir(), "profiles.json")), []target.Target{adapter}, nil, logger) if err != nil { t.Fatal(err) } createAndActivate(t, application) refreshApplicationTargets(t, application) result := application.Dispatch(app.Intent{Kind: app.EnableTarget, TargetID: adapter.ID()}) if result.Err == nil || !strings.Contains(result.Err.Error(), "operation log") || result.Snapshot.Targets[0].State != target.Enabled { t.Fatalf("logging failure result = %#v", result) } if len(logger.entries) != 1 { t.Fatalf("log attempts = %#v", logger.entries) } } func TestApplicationHidesUnavailableTargetButKeepsExplanation(t *testing.T) { adapter := &fakeTarget{available: false, state: target.Disabled} application, err := app.NewWithTargets(profile.NewFileStore(filepath.Join(t.TempDir(), "profiles.json")), []target.Target{adapter}) if err != nil { t.Fatal(err) } if result := application.Dispatch(app.Intent{Kind: app.RefreshTargets}); result.Err != nil { t.Fatal(result.Err) } got := application.Snapshot().Targets[0] if got.Available || got.AvailabilityEvidence != "fake detection" { t.Fatalf("unavailable Target = %#v", got) } } func refreshApplicationTargets(t *testing.T, application *app.Application) { t.Helper() if result := application.Dispatch(app.Intent{Kind: app.RefreshTargets}); result.Err != nil { t.Fatal(result.Err) } } func createAndActivate(t *testing.T, application *app.Application) { t.Helper() if result := application.Dispatch(app.Intent{Kind: app.CreateProfile, Profile: profile.Profile{Name: "office", SingleURL: "http://proxy.example:8080"}}); result.Err != nil { t.Fatal(result.Err) } if result := application.Dispatch(app.Intent{Kind: app.ActivateProfile, Name: "office"}); result.Err != nil { t.Fatal(result.Err) } }