- Add auth.RequireScope() to all handler routes for proper authorization - Add SDLC OpenAPI endpoint documentation (state, features, tasks, branches, merge, archive, orchestrator) - Add SDLC documentation guides (getting-started, cli-reference, api-reference, command-catalog) - Add artifact_test.go for SDLC artifact coverage - Add CLAUDE.md rules: auth scopes requirement, error wrapping with %w - Fix error wrapping to use %w instead of %v throughout codebase - Improve CLI merge command with conflict detection and resolution - Fix handler tests to include auth middleware for RequireScope - Add cookbook tree runner scripts for automated testing Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
105 lines
2.9 KiB
Go
105 lines
2.9 KiB
Go
package handlers
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"github.com/go-chi/chi/v5"
|
|
)
|
|
|
|
func TestProjectsHandler_RunClaude_InvalidJSON(t *testing.T) {
|
|
h := &ProjectsHandler{streams: newStreamManager()}
|
|
r := chi.NewRouter()
|
|
r.Use(testAdminAuth)
|
|
h.Mount(r)
|
|
|
|
req := httptest.NewRequest("POST", "/projects/myapp/claude", bytes.NewReader([]byte("not json")))
|
|
rec := httptest.NewRecorder()
|
|
r.ServeHTTP(rec, req)
|
|
|
|
if rec.Code != http.StatusBadRequest {
|
|
t.Errorf("status = %d, want %d", rec.Code, http.StatusBadRequest)
|
|
}
|
|
}
|
|
|
|
func TestProjectsHandler_RunClaude_NoServiceConfigured(t *testing.T) {
|
|
h := &ProjectsHandler{streams: newStreamManager()}
|
|
r := chi.NewRouter()
|
|
r.Use(testAdminAuth)
|
|
h.Mount(r)
|
|
|
|
body, _ := json.Marshal(ClaudeRequest{Prompt: "hello"})
|
|
req := httptest.NewRequest("POST", "/projects/myapp/claude", bytes.NewReader(body))
|
|
rec := httptest.NewRecorder()
|
|
r.ServeHTTP(rec, req)
|
|
|
|
if rec.Code != http.StatusInternalServerError {
|
|
t.Errorf("status = %d, want %d", rec.Code, http.StatusInternalServerError)
|
|
}
|
|
}
|
|
|
|
func TestProjectsHandler_RunShell_InvalidJSON(t *testing.T) {
|
|
h := &ProjectsHandler{streams: newStreamManager()}
|
|
r := chi.NewRouter()
|
|
r.Use(testAdminAuth)
|
|
h.Mount(r)
|
|
|
|
req := httptest.NewRequest("POST", "/projects/myapp/shell", bytes.NewReader([]byte("not json")))
|
|
rec := httptest.NewRecorder()
|
|
r.ServeHTTP(rec, req)
|
|
|
|
if rec.Code != http.StatusBadRequest {
|
|
t.Errorf("status = %d, want %d", rec.Code, http.StatusBadRequest)
|
|
}
|
|
}
|
|
|
|
func TestProjectsHandler_RunShell_NoServiceConfigured(t *testing.T) {
|
|
h := &ProjectsHandler{streams: newStreamManager()}
|
|
r := chi.NewRouter()
|
|
r.Use(testAdminAuth)
|
|
h.Mount(r)
|
|
|
|
body, _ := json.Marshal(ShellRequest{Command: "ls"})
|
|
req := httptest.NewRequest("POST", "/projects/myapp/shell", bytes.NewReader(body))
|
|
rec := httptest.NewRecorder()
|
|
r.ServeHTTP(rec, req)
|
|
|
|
if rec.Code != http.StatusInternalServerError {
|
|
t.Errorf("status = %d, want %d", rec.Code, http.StatusInternalServerError)
|
|
}
|
|
}
|
|
|
|
func TestProjectsHandler_RunGit_InvalidJSON(t *testing.T) {
|
|
h := &ProjectsHandler{streams: newStreamManager()}
|
|
r := chi.NewRouter()
|
|
r.Use(testAdminAuth)
|
|
h.Mount(r)
|
|
|
|
req := httptest.NewRequest("POST", "/projects/myapp/git", bytes.NewReader([]byte("not json")))
|
|
rec := httptest.NewRecorder()
|
|
r.ServeHTTP(rec, req)
|
|
|
|
if rec.Code != http.StatusBadRequest {
|
|
t.Errorf("status = %d, want %d", rec.Code, http.StatusBadRequest)
|
|
}
|
|
}
|
|
|
|
func TestProjectsHandler_RunGit_NoServiceConfigured(t *testing.T) {
|
|
h := &ProjectsHandler{streams: newStreamManager()}
|
|
r := chi.NewRouter()
|
|
r.Use(testAdminAuth)
|
|
h.Mount(r)
|
|
|
|
body, _ := json.Marshal(GitRequest{Args: []string{"status"}})
|
|
req := httptest.NewRequest("POST", "/projects/myapp/git", bytes.NewReader(body))
|
|
rec := httptest.NewRecorder()
|
|
r.ServeHTTP(rec, req)
|
|
|
|
if rec.Code != http.StatusInternalServerError {
|
|
t.Errorf("status = %d, want %d", rec.Code, http.StatusInternalServerError)
|
|
}
|
|
}
|