7 "github.com/stretchr/testify/assert"
10func TestPermissionService_AllowedCommands(t *testing.T) {
19 name: "tool in allowlist",
20 allowedTools: []string{"bash", "view"},
26 name: "tool:action in allowlist",
27 allowedTools: []string{"bash:execute", "edit:create"},
33 name: "tool not in allowlist",
34 allowedTools: []string{"view", "ls"},
40 name: "tool:action not in allowlist",
41 allowedTools: []string{"bash:read", "edit:create"},
47 name: "empty allowlist",
48 allowedTools: []string{},
55 for _, tt := range tests {
56 t.Run(tt.name, func(t *testing.T) {
57 service := NewPermissionService("/tmp", false, tt.allowedTools)
59 // Create a channel to capture the permission request
60 // Since we're testing the allowlist logic, we need to simulate the request
61 ps := service.(*permissionService)
63 // Test the allowlist logic directly
64 commandKey := tt.toolName + ":" + tt.action
66 for _, cmd := range ps.allowedTools {
67 if cmd == commandKey || cmd == tt.toolName {
73 if allowed != tt.expected {
74 t.Errorf("expected %v, got %v for tool %s action %s with allowlist %v",
75 tt.expected, allowed, tt.toolName, tt.action, tt.allowedTools)
81func TestPermissionService_SkipMode(t *testing.T) {
82 service := NewPermissionService("/tmp", true, []string{})
84 result := service.Request(CreatePermissionRequest{
85 SessionID: "test-session",
88 Description: "test command",
93 t.Error("expected permission to be granted in skip mode")
97func TestPermissionService_SequentialProperties(t *testing.T) {
98 t.Run("Sequential permission requests with persistent grants", func(t *testing.T) {
99 service := NewPermissionService("/tmp", false, []string{})
101 req1 := CreatePermissionRequest{
102 SessionID: "session1",
103 ToolName: "file_tool",
104 Description: "Read file",
106 Params: map[string]string{"file": "test.txt"},
107 Path: "/tmp/test.txt",
111 var wg sync.WaitGroup
114 events := service.Subscribe(t.Context())
118 result1 = service.Request(req1)
121 var permissionReq PermissionRequest
124 permissionReq = event.Payload
125 service.GrantPersistent(permissionReq)
128 assert.True(t, result1, "First request should be granted")
130 // Second identical request should be automatically approved due to persistent permission
131 req2 := CreatePermissionRequest{
132 SessionID: "session1",
133 ToolName: "file_tool",
134 Description: "Read file again",
136 Params: map[string]string{"file": "test.txt"},
137 Path: "/tmp/test.txt",
139 result2 := service.Request(req2)
140 assert.True(t, result2, "Second request should be auto-approved")
142 t.Run("Sequential requests with temporary grants", func(t *testing.T) {
143 service := NewPermissionService("/tmp", false, []string{})
145 req := CreatePermissionRequest{
146 SessionID: "session2",
147 ToolName: "file_tool",
148 Description: "Write file",
150 Params: map[string]string{"file": "test.txt"},
151 Path: "/tmp/test.txt",
154 events := service.Subscribe(t.Context())
156 var wg sync.WaitGroup
159 result1 = service.Request(req)
162 var permissionReq PermissionRequest
164 permissionReq = event.Payload
166 service.Grant(permissionReq)
168 assert.True(t, result1, "First request should be granted")
173 result2 = service.Request(req)
177 permissionReq = event.Payload
178 service.Deny(permissionReq)
180 assert.False(t, result2, "Second request should be denied")
182 t.Run("Concurrent requests with different outcomes", func(t *testing.T) {
183 service := NewPermissionService("/tmp", false, []string{})
185 events := service.Subscribe(t.Context())
187 var wg sync.WaitGroup
188 results := make([]bool, 0)
190 requests := []CreatePermissionRequest{
192 SessionID: "concurrent1",
195 Path: "/tmp/file1.txt",
196 Description: "First concurrent request",
199 SessionID: "concurrent2",
202 Path: "/tmp/file2.txt",
203 Description: "Second concurrent request",
206 SessionID: "concurrent3",
209 Path: "/tmp/file3.txt",
210 Description: "Third concurrent request",
214 for i, req := range requests {
216 go func(index int, request CreatePermissionRequest) {
218 results = append(results, service.Request(request))
224 switch event.Payload.ToolName {
226 service.Grant(event.Payload)
228 service.GrantPersistent(event.Payload)
230 service.Deny(event.Payload)
235 for _, result := range results {
241 assert.Equal(t, 2, grantedCount, "Should have 2 granted and 1 denied")
242 secondReq := requests[1]
243 secondReq.Description = "Repeat of second request"
244 result := service.Request(secondReq)
245 assert.True(t, result, "Repeated request should be auto-approved due to persistent permission")
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list