Why: the squad core has to compile without agent-native or agent-intent. Ports stay in the core; adapters and the CLI own the concrete clients. Evidence: GOWORK=off go test -count=1 ./squad/ ./store/ ./textextract/ ./schema/ passed, and the intent, sqlite, native, and cmd modules passed their own go test. Impact: core go.mod keeps error-code-system only. Nested gitlinks stay. Callers register the native backend through agent-squad/adapters/native. Refs: D1 Co-authored-by: Cursor <cursoragent@cursor.com>
75 lines
1.7 KiB
Go
75 lines
1.7 KiB
Go
package server
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
|
|
"agent-squad/squad"
|
|
"agent-squad/store"
|
|
)
|
|
|
|
func TestMissingTokenIsUnauthorized(t *testing.T) {
|
|
dir := t.TempDir()
|
|
st, err := store.New(dir)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
reg := squad.NewRoleRegistry()
|
|
engine, err := squad.NewEngine(squad.Options{
|
|
DataDir: dir, Registry: reg, Planner: &squad.MockPlanner{}, Sink: squad.NopSink{},
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
srv := New(engine, squad.NewFanoutSink(8), st)
|
|
srv.SetToken("secret")
|
|
ts := httptest.NewServer(srv.Handler())
|
|
defer ts.Close()
|
|
|
|
resp, err := http.Get(ts.URL + "/v1/roles")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
resp.Body.Close()
|
|
if resp.StatusCode != http.StatusUnauthorized {
|
|
t.Fatalf("status %d", resp.StatusCode)
|
|
}
|
|
req, _ := http.NewRequest(http.MethodGet, ts.URL+"/v1/roles", nil)
|
|
req.Header.Set("Authorization", "Bearer secret")
|
|
resp, err = http.DefaultClient.Do(req)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
resp.Body.Close()
|
|
if resp.StatusCode != http.StatusOK {
|
|
t.Fatalf("authed status %d", resp.StatusCode)
|
|
}
|
|
}
|
|
|
|
func TestPathTraversalRejected(t *testing.T) {
|
|
ts, _ := newTestServer(t)
|
|
resp, err := http.Get(ts.URL + "/v1/runs/a..b")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
resp.Body.Close()
|
|
if resp.StatusCode != http.StatusBadRequest {
|
|
t.Fatalf("status %d", resp.StatusCode)
|
|
}
|
|
}
|
|
|
|
func TestOversizedBodyIs413(t *testing.T) {
|
|
ts, _ := newTestServer(t)
|
|
body := strings.NewReader(`{"role":"x","name":"` + strings.Repeat("a", 2<<20) + `"}`)
|
|
resp, err := http.Post(ts.URL+"/v1/roles", "application/json", body)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
resp.Body.Close()
|
|
if resp.StatusCode != http.StatusRequestEntityTooLarge {
|
|
t.Fatalf("status %d", resp.StatusCode)
|
|
}
|
|
}
|