Add branch lifecycle commands (branch, merge, archive) to the SDLC CLI. Introduce orchestrator handler and service for multi-step SDLC workflows. Expand skeleton template with 15 Claude commands covering the full feature lifecycle. Extend classifier rules, error types, and executor port for branch operations. Split rules.go and classifier_test.go to stay within 500-line limit. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
101 lines
3.0 KiB
Go
101 lines
3.0 KiB
Go
package handlers
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"github.com/orchard9/rdev/internal/sdlc"
|
|
)
|
|
|
|
func TestSDLCHandler_CreateBranch(t *testing.T) {
|
|
exec := &testSDLCExecutor{}
|
|
_, router := setupSDLCHandler(exec)
|
|
|
|
req := httptest.NewRequest(http.MethodPost, "/projects/test-project/sdlc/features/auth-flow/branches", nil)
|
|
w := httptest.NewRecorder()
|
|
router.ServeHTTP(w, req)
|
|
|
|
if w.Code != http.StatusCreated {
|
|
t.Errorf("expected status 201, got %d: %s", w.Code, w.Body.String())
|
|
}
|
|
}
|
|
|
|
func TestSDLCHandler_CreateBranch_FeatureNotFound(t *testing.T) {
|
|
exec := &testSDLCExecutor{err: sdlc.ErrFeatureNotFound}
|
|
_, router := setupSDLCHandler(exec)
|
|
|
|
req := httptest.NewRequest(http.MethodPost, "/projects/test-project/sdlc/features/nonexistent/branches", nil)
|
|
w := httptest.NewRecorder()
|
|
router.ServeHTTP(w, req)
|
|
|
|
if w.Code != http.StatusNotFound {
|
|
t.Errorf("expected status 404, got %d: %s", w.Code, w.Body.String())
|
|
}
|
|
}
|
|
|
|
func TestSDLCHandler_CreateBranch_AlreadyExists(t *testing.T) {
|
|
exec := &testSDLCExecutor{err: sdlc.ErrBranchExists}
|
|
_, router := setupSDLCHandler(exec)
|
|
|
|
req := httptest.NewRequest(http.MethodPost, "/projects/test-project/sdlc/features/auth-flow/branches", nil)
|
|
w := httptest.NewRecorder()
|
|
router.ServeHTTP(w, req)
|
|
|
|
if w.Code != http.StatusBadRequest {
|
|
t.Errorf("expected status 400, got %d: %s", w.Code, w.Body.String())
|
|
}
|
|
}
|
|
|
|
func TestSDLCHandler_GetBranchStatus(t *testing.T) {
|
|
exec := &testSDLCExecutor{}
|
|
_, router := setupSDLCHandler(exec)
|
|
|
|
req := httptest.NewRequest(http.MethodGet, "/projects/test-project/sdlc/features/auth-flow/branches", nil)
|
|
w := httptest.NewRecorder()
|
|
router.ServeHTTP(w, req)
|
|
|
|
if w.Code != http.StatusOK {
|
|
t.Errorf("expected status 200, got %d: %s", w.Code, w.Body.String())
|
|
}
|
|
}
|
|
|
|
func TestSDLCHandler_GetBranchStatus_NotFound(t *testing.T) {
|
|
exec := &testSDLCExecutor{err: sdlc.ErrBranchNotFound}
|
|
_, router := setupSDLCHandler(exec)
|
|
|
|
req := httptest.NewRequest(http.MethodGet, "/projects/test-project/sdlc/features/auth-flow/branches", nil)
|
|
w := httptest.NewRecorder()
|
|
router.ServeHTTP(w, req)
|
|
|
|
if w.Code != http.StatusNotFound {
|
|
t.Errorf("expected status 404, got %d: %s", w.Code, w.Body.String())
|
|
}
|
|
}
|
|
|
|
func TestSDLCHandler_SyncBranch(t *testing.T) {
|
|
exec := &testSDLCExecutor{}
|
|
_, router := setupSDLCHandler(exec)
|
|
|
|
req := httptest.NewRequest(http.MethodPost, "/projects/test-project/sdlc/features/auth-flow/branches/sync", nil)
|
|
w := httptest.NewRecorder()
|
|
router.ServeHTTP(w, req)
|
|
|
|
if w.Code != http.StatusOK {
|
|
t.Errorf("expected status 200, got %d: %s", w.Code, w.Body.String())
|
|
}
|
|
}
|
|
|
|
func TestSDLCHandler_SyncBranch_BranchNotFound(t *testing.T) {
|
|
exec := &testSDLCExecutor{err: sdlc.ErrBranchNotFound}
|
|
_, router := setupSDLCHandler(exec)
|
|
|
|
req := httptest.NewRequest(http.MethodPost, "/projects/test-project/sdlc/features/auth-flow/branches/sync", nil)
|
|
w := httptest.NewRecorder()
|
|
router.ServeHTTP(w, req)
|
|
|
|
if w.Code != http.StatusNotFound {
|
|
t.Errorf("expected status 404, got %d: %s", w.Code, w.Body.String())
|
|
}
|
|
}
|