1package modes
2
3import (
4 "errors"
5 "testing"
6
7 "github.com/patriceckhart/zot/packages/agent/tools"
8 "github.com/patriceckhart/zot/packages/core"
9 "github.com/patriceckhart/zot/packages/tui"
10)
11
12type testPowerShellStore struct {
13 SettingsStore
14 values []bool
15 err error
16}
17
18func (s *testPowerShellStore) SetPowerShell(value bool) error {
19 if s.err != nil {
20 return s.err
21 }
22 s.values = append(s.values, value)
23 return nil
24}
25
26func TestPowerShellSettingLiveToggle(t *testing.T) {
27 cwd := t.TempDir()
28 sb := tools.NewSandbox(cwd)
29 store := &testPowerShellStore{}
30 read := &tools.ReadTool{CWD: cwd}
31 original := core.Registry{"read": read, "custom": read}
32 i := &Interactive{
33 cfg: InteractiveConfig{CWD: cwd, Sandbox: sb, SettingsStore: store},
34 agent: core.NewAgent(nil, "", "", original),
35 }
36 for _, value := range []bool{true, false} {
37 i.applyPowerShellSetting(value, "windows")
38 if i.statusErr != "" {
39 t.Fatal(i.statusErr)
40 }
41 if i.cfg.PowerShellEnabled == nil || *i.cfg.PowerShellEnabled != value {
42 t.Fatal("preference not updated")
43 }
44 if (i.agent.Tools["powershell"] != nil) != value {
45 t.Fatal("live registry not updated")
46 }
47 if value {
48 ps := i.agent.Tools["powershell"].(*tools.PowerShellTool)
49 if ps.CWD != cwd || ps.Sandbox != sb {
50 t.Fatal("tool lost session context")
51 }
52 }
53 if i.agent.Tools["custom"] != read || i.agent.Tools["read"] != read {
54 t.Fatal("unrelated tools changed")
55 }
56 if original["powershell"] != nil {
57 t.Fatal("original registry mutated")
58 }
59 }
60 if len(store.values) != 2 || !store.values[0] || store.values[1] {
61 t.Fatalf("saved: %v", store.values)
62 }
63}
64
65func TestPowerShellSettingFailurePreservesState(t *testing.T) {
66 store := &testPowerShellStore{err: errors.New("save failed")}
67 i := &Interactive{
68 cfg: InteractiveConfig{SettingsStore: store},
69 agent: core.NewAgent(nil, "", "", core.Registry{}),
70 settingsDialog: newSettingsDialog(),
71 }
72 i.settingsDialog.Open(i.appendPowerShellSetting(nil, "windows"))
73 action := i.settingsDialog.HandleKey(tui.Key{Kind: tui.KeyEnter})
74 if !action.Toggle || !action.Value {
75 t.Fatal("dialog did not enable")
76 }
77 i.applyPowerShellSetting(action.Value, "windows")
78 if i.statusErr != "settings: save failed" {
79 t.Fatalf("error: %s", i.statusErr)
80 }
81 if i.cfg.PowerShellEnabled != nil || i.agent.Tools["powershell"] != nil || i.settingsDialog.items[0].value {
82 t.Fatal("failed save changed state")
83 }
84}
85
86func TestPowerShellSettingPlatformAndOverrides(t *testing.T) {
87 for _, tc := range []struct {
88 name, goos string
89 cfg InteractiveConfig
90 custom bool
91 }{
92 {"non-Windows", "darwin", InteractiveConfig{}, false},
93 {"no tools", "windows", InteractiveConfig{NoTools: true}, false},
94 {"explicit tools", "windows", InteractiveConfig{ToolSelectionExplicit: true}, false},
95 {"custom tool", "windows", InteractiveConfig{}, true},
96 } {
97 t.Run(tc.name, func(t *testing.T) {
98 store := &testPowerShellStore{}
99 tc.cfg.SettingsStore = store
100 reg := core.Registry{}
101 if tc.custom {
102 reg["powershell"] = &tools.ReadTool{}
103 }
104 i := &Interactive{cfg: tc.cfg, agent: core.NewAgent(nil, "", "", reg)}
105 items := i.appendPowerShellSetting(nil, tc.goos)
106 if tc.goos != "windows" {
107 if len(items) != 0 {
108 t.Fatal("setting shown on non-Windows")
109 }
110 } else if len(items) != 1 || !items[0].disabled || items[0].hint == "" {
111 t.Fatalf("setting: %+v", items)
112 }
113 i.applyPowerShellSetting(true, tc.goos)
114 if i.statusErr == "" || len(store.values) != 0 || i.cfg.PowerShellEnabled != nil {
115 t.Fatal("override not respected")
116 }
117 if i.agent.Tools["powershell"] != reg["powershell"] {
118 t.Fatal("registry changed")
119 }
120 })
121 }
122}
123
124func TestPowerShellSettingReflectsPreference(t *testing.T) {
125 for _, enabled := range []bool{true, false} {
126 i := &Interactive{cfg: InteractiveConfig{PowerShellEnabled: &enabled}}
127 items := i.appendPowerShellSetting(nil, "windows")
128 if len(items) != 1 || items[0].value != enabled || items[0].disabled {
129 t.Fatalf("setting: %+v", items)
130 }
131 }
132}