1package dialog
2
3import (
4 "testing"
5
6 tea "charm.land/bubbletea/v2"
7 "github.com/charmbracelet/crush/internal/permission"
8 "github.com/charmbracelet/crush/internal/ui/common"
9 "github.com/charmbracelet/crush/internal/ui/styles"
10 "github.com/stretchr/testify/require"
11)
12
13func newTestPermissions(t *testing.T) *Permissions {
14 t.Helper()
15 s := styles.CharmtonePantera()
16 com := &common.Common{Styles: &s}
17 perm := permission.PermissionRequest{
18 ID: "perm-test",
19 ToolCallID: "tool-call-test",
20 ToolName: "bash",
21 }
22 return NewPermissions(com, perm)
23}
24
25// TestPermissions_ActionKeysResolve verifies that action keys produce the
26// correct permission response.
27func TestPermissions_ActionKeysResolve(t *testing.T) {
28 t.Parallel()
29
30 tests := []struct {
31 key tea.KeyPressMsg
32 action PermissionAction
33 }{
34 {keyMsg('a'), PermissionAllow},
35 {keyMsg('A'), PermissionAllow},
36 {keyMsg('d'), PermissionDeny},
37 {keyMsg('D'), PermissionDeny},
38 {keyMsg('s'), PermissionAllowForSession},
39 {keyMsg('S'), PermissionAllowForSession},
40 }
41
42 for _, tc := range tests {
43 p := newTestPermissions(t)
44 action := p.HandleMsg(tc.key)
45 resp, ok := action.(ActionPermissionResponse)
46 require.Truef(t, ok, "key %q should produce ActionPermissionResponse", tc.key.Text)
47 require.Equal(t, tc.action, resp.Action)
48 }
49}
50
51// TestPermissions_NavigationCyclesOptions verifies that tab and arrow keys
52// cycle through the three permission options.
53func TestPermissions_NavigationCyclesOptions(t *testing.T) {
54 t.Parallel()
55
56 p := newTestPermissions(t)
57 require.Equal(t, 0, p.selectedOption)
58
59 // Tab cycles forward.
60 p.HandleMsg(tea.KeyPressMsg{Code: tea.KeyTab})
61 require.Equal(t, 1, p.selectedOption)
62
63 p.HandleMsg(tea.KeyPressMsg{Code: tea.KeyTab})
64 require.Equal(t, 2, p.selectedOption)
65
66 // Wrap around.
67 p.HandleMsg(tea.KeyPressMsg{Code: tea.KeyTab})
68 require.Equal(t, 0, p.selectedOption)
69
70 // Left cycles backward.
71 p.HandleMsg(keyMsg('h'))
72 require.Equal(t, 2, p.selectedOption)
73}
74
75// TestPermissions_EnterConfirmsSelection verifies that enter confirms the
76// currently selected option.
77func TestPermissions_EnterConfirmsSelection(t *testing.T) {
78 t.Parallel()
79
80 p := newTestPermissions(t)
81 p.selectedOption = 1 // Allow for session.
82
83 action := p.HandleMsg(tea.KeyPressMsg{Code: tea.KeyEnter})
84 resp, ok := action.(ActionPermissionResponse)
85 require.True(t, ok)
86 require.Equal(t, PermissionAllowForSession, resp.Action)
87}
88
89// TestPermissions_EscapeDenies verifies that escape denies the request.
90func TestPermissions_EscapeDenies(t *testing.T) {
91 t.Parallel()
92
93 p := newTestPermissions(t)
94 action := p.HandleMsg(tea.KeyPressMsg{Code: tea.KeyEscape})
95 resp, ok := action.(ActionPermissionResponse)
96 require.True(t, ok)
97 require.Equal(t, PermissionDeny, resp.Action)
98}