Files
Assistant/cmd/creator-web/server_test.go
T
m 6a5550b7b0
CI / test (push) Failing after 15m2s
feat: show Creator continuity in Domovoy
2026-08-16 15:51:18 +03:00

96 lines
3.5 KiB
Go

package main
import (
"io"
"net/http"
"net/http/httptest"
"strings"
"testing"
)
func TestGatewayForwardsOnlyCreatorAllowlist(t *testing.T) {
upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/v1/creator/tasks/task-1" || r.URL.RawQuery != "session_id=session-1&workspace_id=workspace-1" {
t.Fatalf("unexpected upstream target %s?%s", r.URL.Path, r.URL.RawQuery)
}
if r.Header.Get("Authorization") != "Bearer bounded-session" {
t.Fatal("authorization header was not forwarded")
}
w.Header().Set("Content-Type", "application/json")
_, _ = io.WriteString(w, `{"TaskID":"task-1"}`)
}))
defer upstream.Close()
handler, err := newHandler(upstream.URL, upstream.URL, upstream.Client())
if err != nil {
t.Fatal(err)
}
request := httptest.NewRequest(http.MethodGet, "/api/tasks/task-1?session_id=session-1&workspace_id=workspace-1", nil)
request.Header.Set("Authorization", "Bearer bounded-session")
response := httptest.NewRecorder()
handler.ServeHTTP(response, request)
if response.Code != http.StatusOK || !strings.Contains(response.Body.String(), "task-1") {
t.Fatalf("response = %d %s", response.Code, response.Body.String())
}
}
func TestGatewayDeniesInternalAndMutationRoutes(t *testing.T) {
handler, err := newHandler("http://core-runtime:8080", "http://continuity-runtime:8081", http.DefaultClient)
if err != nil {
t.Fatal(err)
}
for _, test := range []struct{ method, path string }{
{http.MethodPost, "/api/tasks/task-1"},
{http.MethodGet, "/api/principal-bindings/actor/principal"},
{http.MethodPost, "/api/focus-task-commits"},
{http.MethodPost, "/api/prospective-items/item-1"},
{http.MethodGet, "/api/tasks/../../healthz"},
} {
request := httptest.NewRequest(test.method, test.path, nil)
response := httptest.NewRecorder()
handler.ServeHTTP(response, request)
if response.Code != http.StatusNotFound {
t.Fatalf("%s %s returned %d", test.method, test.path, response.Code)
}
}
}
func TestGatewayRoutesProspectiveItemToContinuity(t *testing.T) {
continuity := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/v1/creator/prospective-items/item-1" {
t.Fatalf("unexpected Continuity target %s", r.URL.Path)
}
if r.Header.Get("Authorization") != "Bearer bounded-session" {
t.Fatal("authorization header was not forwarded")
}
_, _ = io.WriteString(w, `{"ID":"item-1"}`)
}))
defer continuity.Close()
handler, err := newHandler("http://core-runtime.invalid", continuity.URL, continuity.Client())
if err != nil {
t.Fatal(err)
}
request := httptest.NewRequest(http.MethodGet, "/api/prospective-items/item-1", nil)
request.Header.Set("Authorization", "Bearer bounded-session")
response := httptest.NewRecorder()
handler.ServeHTTP(response, request)
if response.Code != http.StatusOK || !strings.Contains(response.Body.String(), "item-1") {
t.Fatalf("response = %d %s", response.Code, response.Body.String())
}
}
func TestConsoleAndSecurityHeaders(t *testing.T) {
handler, err := newHandler("http://core-runtime:8080", "http://continuity-runtime:8081", http.DefaultClient)
if err != nil {
t.Fatal(err)
}
request := httptest.NewRequest(http.MethodGet, "/", nil)
response := httptest.NewRecorder()
handler.ServeHTTP(response, request)
if response.Code != http.StatusOK || !strings.Contains(response.Body.String(), "Домовой") {
t.Fatalf("console response = %d", response.Code)
}
if response.Header().Get("Content-Security-Policy") == "" {
t.Fatal("content security policy is missing")
}
}