148 lines
4.3 KiB
Go
148 lines
4.3 KiB
Go
package routes
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
func newCommonRoutesTestRouter() *gin.Engine {
|
|
gin.SetMode(gin.TestMode)
|
|
r := gin.New()
|
|
RegisterCommonRoutes(r)
|
|
return r
|
|
}
|
|
|
|
func TestCommonRoutes_ClaudeCodeBootstrap(t *testing.T) {
|
|
r := newCommonRoutesTestRouter()
|
|
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest(http.MethodGet, "/api/claude_cli/bootstrap", nil)
|
|
r.ServeHTTP(w, req)
|
|
|
|
if w.Code != http.StatusOK {
|
|
t.Fatalf("status = %d, want %d", w.Code, http.StatusOK)
|
|
}
|
|
|
|
var body struct {
|
|
ClientData any `json:"client_data"`
|
|
AdditionalModelOptions []map[string]any `json:"additional_model_options"`
|
|
AdditionalModelCosts map[string]map[string]any `json:"additional_model_costs"`
|
|
}
|
|
if err := json.Unmarshal(w.Body.Bytes(), &body); err != nil {
|
|
t.Fatalf("unmarshal response: %v", err)
|
|
}
|
|
if body.ClientData != nil {
|
|
t.Fatalf("client_data = %#v, want nil", body.ClientData)
|
|
}
|
|
if body.AdditionalModelOptions == nil || len(body.AdditionalModelOptions) != 0 {
|
|
t.Fatalf("additional_model_options = %#v, want empty array", body.AdditionalModelOptions)
|
|
}
|
|
if body.AdditionalModelCosts == nil || len(body.AdditionalModelCosts) != 0 {
|
|
t.Fatalf("additional_model_costs = %#v, want empty object", body.AdditionalModelCosts)
|
|
}
|
|
}
|
|
|
|
func TestCommonRoutes_ClaudeCodePolicyLimits(t *testing.T) {
|
|
r := newCommonRoutesTestRouter()
|
|
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest(http.MethodGet, "/api/claude_code/policy_limits", nil)
|
|
r.ServeHTTP(w, req)
|
|
|
|
if w.Code != http.StatusOK {
|
|
t.Fatalf("status = %d, want %d", w.Code, http.StatusOK)
|
|
}
|
|
|
|
var body struct {
|
|
Restrictions map[string]struct {
|
|
Allowed bool `json:"allowed"`
|
|
} `json:"restrictions"`
|
|
}
|
|
if err := json.Unmarshal(w.Body.Bytes(), &body); err != nil {
|
|
t.Fatalf("unmarshal response: %v", err)
|
|
}
|
|
if body.Restrictions == nil || len(body.Restrictions) != 0 {
|
|
t.Fatalf("restrictions = %#v, want empty object", body.Restrictions)
|
|
}
|
|
}
|
|
|
|
func TestCommonRoutes_GrowthBookJSONRoutes(t *testing.T) {
|
|
r := newCommonRoutesTestRouter()
|
|
|
|
testCases := []struct {
|
|
name string
|
|
method string
|
|
path string
|
|
}{
|
|
{name: "features", method: http.MethodGet, path: "/api/features/sdk-zAZezfDKGoZuXXKe"},
|
|
{name: "eval", method: http.MethodPost, path: "/api/eval/sdk-zAZezfDKGoZuXXKe"},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest(tc.method, tc.path, strings.NewReader(`{"attributes":{}}`))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
r.ServeHTTP(w, req)
|
|
|
|
if w.Code != http.StatusOK {
|
|
t.Fatalf("status = %d, want %d", w.Code, http.StatusOK)
|
|
}
|
|
if got := w.Header().Get("x-sse-support"); got != "enabled" {
|
|
t.Fatalf("x-sse-support = %q, want %q", got, "enabled")
|
|
}
|
|
|
|
var body struct {
|
|
Features map[string]any `json:"features"`
|
|
DateUpdated string `json:"dateUpdated"`
|
|
}
|
|
if err := json.Unmarshal(w.Body.Bytes(), &body); err != nil {
|
|
t.Fatalf("unmarshal response: %v", err)
|
|
}
|
|
if body.Features == nil || len(body.Features) != 0 {
|
|
t.Fatalf("features = %#v, want empty object", body.Features)
|
|
}
|
|
if body.DateUpdated != claudeCodeGrowthBookDateUpdated {
|
|
t.Fatalf("dateUpdated = %q, want %q", body.DateUpdated, claudeCodeGrowthBookDateUpdated)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCommonRoutes_GrowthBookSSERoutes(t *testing.T) {
|
|
r := newCommonRoutesTestRouter()
|
|
|
|
testPaths := []string{
|
|
"/sub/sdk-zAZezfDKGoZuXXKe",
|
|
"/sub/features/sdk-zAZezfDKGoZuXXKe",
|
|
}
|
|
|
|
for _, path := range testPaths {
|
|
t.Run(path, func(t *testing.T) {
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest(http.MethodGet, path, nil)
|
|
r.ServeHTTP(w, req)
|
|
|
|
if w.Code != http.StatusOK {
|
|
t.Fatalf("status = %d, want %d", w.Code, http.StatusOK)
|
|
}
|
|
if got := w.Header().Get("Content-Type"); !strings.HasPrefix(got, "text/event-stream") {
|
|
t.Fatalf("Content-Type = %q, want text/event-stream*", got)
|
|
}
|
|
|
|
body := w.Body.String()
|
|
if !strings.Contains(body, "event:features") {
|
|
t.Fatalf("SSE body missing features event: %q", body)
|
|
}
|
|
if !strings.Contains(body, `"dateUpdated":"`+claudeCodeGrowthBookDateUpdated+`"`) {
|
|
t.Fatalf("SSE body missing dateUpdated payload: %q", body)
|
|
}
|
|
})
|
|
}
|
|
}
|