package server import ( "bytes" "encoding/json" "net/http" "net/http/httptest" "testing" ) func postFreeformCreate(t *testing.T, srv *Server, token string, body map[string]any) *httptest.ResponseRecorder { t.Helper() raw, _ := json.Marshal(body) req := httptest.NewRequest(http.MethodPost, "/api/v1/freeform-documents", bytes.NewReader(raw)) withBearerAuth(req, token) w := httptest.NewRecorder() srv.Routes().ServeHTTP(w, req) return w } func TestCreateFreeformDoc_RejectsMissingProjectID(t *testing.T) { srv := newTestServer(t) token := loginTestAdmin(t, srv) w := postFreeformCreate(t, srv, token, map[string]any{ "project_id": 0, "title": "x", "content_markdown": "# x\n", }) if w.Code != http.StatusBadRequest { t.Fatalf("want 400 got %d %s", w.Code, w.Body.String()) } if !bytes.Contains(w.Body.Bytes(), []byte("project_id")) { t.Fatalf("want project_id error, got %s", w.Body.String()) } } func TestCreateFreeformDoc_RejectsDirectProjectShared(t *testing.T) { srv := newTestServer(t) token := loginTestAdmin(t, srv) w := postFreeformCreate(t, srv, token, map[string]any{ "project_id": 1, "title": "x", "content_markdown": "# x\n", "space": "project_shared", }) if w.Code != http.StatusBadRequest { t.Fatalf("want 400 got %d %s", w.Code, w.Body.String()) } if !bytes.Contains(w.Body.Bytes(), []byte("my_private")) { t.Fatalf("want my_private-only error, got %s", w.Body.String()) } } func TestCreateFreeformDoc_FailClosedWhenAuthorizerNil(t *testing.T) { srv := newTestServer(t) srv.cfg.AllowInMemory = false srv.setOverrideAuthorizer(nil) token := loginTestAdmin(t, srv) w := postFreeformCreate(t, srv, token, map[string]any{ "project_id": 1, "title": "x", "content_markdown": "# x\n", "space": "my_private", }) if w.Code != http.StatusForbidden && w.Code != http.StatusUnauthorized { t.Fatalf("fail-closed authorizer=nil want 403/401 got %d %s", w.Code, w.Body.String()) } }