Add web server, SSE handlers, and UI

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-05-31 11:53:21 -04:00
parent f243f3004e
commit 0318aeb08d
5 changed files with 483 additions and 1 deletions
+71
View File
@@ -0,0 +1,71 @@
package web
import (
"net/http"
"net/http/httptest"
"path/filepath"
"strings"
"testing"
"antidrift/internal/domain"
"antidrift/internal/session"
"github.com/gin-gonic/gin"
)
func newTestServer(t *testing.T) *Server {
t.Helper()
gin.SetMode(gin.TestMode)
path := filepath.Join(t.TempDir(), "state.json")
ctrl, err := session.New(path)
if err != nil {
t.Fatalf("controller: %v", err)
}
return NewServer(ctrl)
}
func post(t *testing.T, r http.Handler, path, body string) *httptest.ResponseRecorder {
t.Helper()
req := httptest.NewRequest(http.MethodPost, path, strings.NewReader(body))
req.Header.Set("Content-Type", "application/json")
w := httptest.NewRecorder()
r.ServeHTTP(w, req)
return w
}
func TestPlanningThenCommitmentReachesActive(t *testing.T) {
s := newTestServer(t)
r := s.Router()
if w := post(t, r, "/planning", ""); w.Code != http.StatusOK {
t.Fatalf("/planning code %d", w.Code)
}
body := `{"next_action":"Build web","success_condition":"web tests pass","timebox_secs":1500}`
if w := post(t, r, "/commitment", body); w.Code != http.StatusOK {
t.Fatalf("/commitment code %d body %s", w.Code, w.Body.String())
}
if s.ctrl.State().RuntimeState != domain.RuntimeActive {
t.Fatalf("expected Active, got %s", s.ctrl.State().RuntimeState)
}
}
func TestCommitmentRejectsInvalidInput(t *testing.T) {
s := newTestServer(t)
r := s.Router()
_ = post(t, r, "/planning", "")
body := `{"next_action":"","success_condition":"x","timebox_secs":1500}`
w := post(t, r, "/commitment", body)
if w.Code != http.StatusBadRequest {
t.Fatalf("expected 400, got %d", w.Code)
}
}
func TestIllegalTransitionReturns409(t *testing.T) {
s := newTestServer(t)
r := s.Router()
// /complete from Locked is illegal.
w := post(t, r, "/complete", "")
if w.Code != http.StatusConflict {
t.Fatalf("expected 409, got %d", w.Code)
}
}