permissions_test.go

 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}