feat(03-01): HTTP handler POST /hook with validation and body size limit
- handleHook validates POST method (405 on others) - MaxBytesReader limits body to 64KB (400 on overflow) - JSON decode errors return 400 - Valid payloads update registry via processHookEvent - 4 tests cover OK, method not allowed, bad JSON, body too large Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
75
hook_test.go
75
hook_test.go
@@ -1,6 +1,9 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@@ -225,3 +228,75 @@ func TestUpdateFromHookClearsWaitingSince(t *testing.T) {
|
||||
t.Errorf("WaitingSince should be nil after returning to Working, got %v", list[0].WaitingSince)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleHookPostOK(t *testing.T) {
|
||||
d := newTestDaemon(t)
|
||||
|
||||
body := `{
|
||||
"session_id": "sess-1",
|
||||
"hook_event_name": "Notification",
|
||||
"notification_type": "permission_prompt",
|
||||
"cwd": "/home/user/project"
|
||||
}`
|
||||
|
||||
req := httptest.NewRequest(http.MethodPost, "/hook", strings.NewReader(body))
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
d.handleHook(w, req)
|
||||
|
||||
if w.Code != http.StatusOK {
|
||||
t.Fatalf("status = %d, want 200", w.Code)
|
||||
}
|
||||
|
||||
list := d.registry.List()
|
||||
if len(list) != 1 {
|
||||
t.Fatalf("registry len = %d, want 1", len(list))
|
||||
}
|
||||
if list[0].WaitType != "permission" {
|
||||
t.Errorf("WaitType = %q, want %q", list[0].WaitType, "permission")
|
||||
}
|
||||
if list[0].State != "Needs Input" {
|
||||
t.Errorf("State = %q, want %q", list[0].State, "Needs Input")
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleHookMethodNotAllowed(t *testing.T) {
|
||||
d := newTestDaemon(t)
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/hook", nil)
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
d.handleHook(w, req)
|
||||
|
||||
if w.Code != http.StatusMethodNotAllowed {
|
||||
t.Errorf("status = %d, want 405", w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleHookBadJSON(t *testing.T) {
|
||||
d := newTestDaemon(t)
|
||||
|
||||
req := httptest.NewRequest(http.MethodPost, "/hook", strings.NewReader("not json"))
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
d.handleHook(w, req)
|
||||
|
||||
if w.Code != http.StatusBadRequest {
|
||||
t.Errorf("status = %d, want 400", w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleHookBodyTooLarge(t *testing.T) {
|
||||
d := newTestDaemon(t)
|
||||
|
||||
// 65KB body exceeds the 64KB limit
|
||||
bigBody := strings.Repeat("x", 65*1024)
|
||||
req := httptest.NewRequest(http.MethodPost, "/hook", strings.NewReader(bigBody))
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
d.handleHook(w, req)
|
||||
|
||||
if w.Code != http.StatusBadRequest {
|
||||
t.Errorf("status = %d, want 400", w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user