Files
Carlos Florêncio 3a95a43990 fix: vscode (#279)
2026-02-24 23:01:41 +00:00

154 lines
3.7 KiB
Go

package api
import (
"io"
"net/http"
"net/http/httptest"
"net/url"
"strconv"
"sync"
"testing"
"github.com/kandev/kandev/internal/agentctl/server/process"
)
func TestHandleVscodeProxy_ProxiesRequest(t *testing.T) {
var mu sync.Mutex
var receivedPath, receivedMethod string
mock := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
mu.Lock()
receivedPath = r.URL.Path
receivedMethod = r.Method
mu.Unlock()
w.WriteHeader(http.StatusOK)
}))
defer mock.Close()
port := mustParsePort(t, mock.URL)
s := newTestServer(t)
s.procMgr.SetVscodeForTest(process.VscodeStatusRunning, port)
// Use a real HTTP server so Gin's responseWriter gets a real http.ResponseWriter
ts := httptest.NewServer(s.router)
defer ts.Close()
resp, err := http.Get(ts.URL + "/api/v1/vscode/proxy/some/path")
if err != nil {
t.Fatalf("request failed: %v", err)
}
defer resp.Body.Close() //nolint:errcheck
_, _ = io.Copy(io.Discard, resp.Body)
if resp.StatusCode != http.StatusOK {
t.Errorf("expected 200, got %d", resp.StatusCode)
}
mu.Lock()
defer mu.Unlock()
if receivedPath != "/some/path" {
t.Errorf("expected path /some/path, got %q", receivedPath)
}
if receivedMethod != http.MethodGet {
t.Errorf("expected GET, got %q", receivedMethod)
}
}
func TestHandleVscodeProxy_RootPath(t *testing.T) {
var mu sync.Mutex
var receivedPath string
mock := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
mu.Lock()
receivedPath = r.URL.Path
mu.Unlock()
w.WriteHeader(http.StatusOK)
}))
defer mock.Close()
port := mustParsePort(t, mock.URL)
s := newTestServer(t)
s.procMgr.SetVscodeForTest(process.VscodeStatusRunning, port)
ts := httptest.NewServer(s.router)
defer ts.Close()
resp, err := http.Get(ts.URL + "/api/v1/vscode/proxy")
if err != nil {
t.Fatalf("request failed: %v", err)
}
defer resp.Body.Close() //nolint:errcheck
_, _ = io.Copy(io.Discard, resp.Body)
if resp.StatusCode != http.StatusOK {
t.Errorf("expected 200, got %d", resp.StatusCode)
}
mu.Lock()
defer mu.Unlock()
if receivedPath != "/" {
t.Errorf("expected root path /, got %q", receivedPath)
}
}
func TestHandleVscodeProxy_OriginHeader(t *testing.T) {
var mu sync.Mutex
var receivedOrigin string
mock := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
mu.Lock()
receivedOrigin = r.Header.Get("Origin")
mu.Unlock()
w.WriteHeader(http.StatusOK)
}))
defer mock.Close()
port := mustParsePort(t, mock.URL)
s := newTestServer(t)
s.procMgr.SetVscodeForTest(process.VscodeStatusRunning, port)
ts := httptest.NewServer(s.router)
defer ts.Close()
req, _ := http.NewRequest(http.MethodGet, ts.URL+"/api/v1/vscode/proxy/test", nil)
req.Header.Set("Origin", "http://different-host:9999")
resp, err := http.DefaultClient.Do(req)
if err != nil {
t.Fatalf("request failed: %v", err)
}
defer resp.Body.Close() //nolint:errcheck
_, _ = io.Copy(io.Discard, resp.Body)
mu.Lock()
defer mu.Unlock()
expected := "http://127.0.0.1:" + strconv.Itoa(port)
if receivedOrigin != expected {
t.Errorf("expected Origin %q, got %q", expected, receivedOrigin)
}
}
func TestHandleVscodeProxy_NotRunning(t *testing.T) {
s := newTestServer(t)
req := httptest.NewRequest(http.MethodGet, "/api/v1/vscode/proxy/foo", nil)
w := httptest.NewRecorder()
s.router.ServeHTTP(w, req)
if w.Code != http.StatusServiceUnavailable {
t.Errorf("expected 503, got %d", w.Code)
}
}
func mustParsePort(t *testing.T, rawURL string) int {
t.Helper()
u, err := url.Parse(rawURL)
if err != nil {
t.Fatalf("failed to parse URL: %v", err)
}
port, err := strconv.Atoi(u.Port())
if err != nil {
t.Fatalf("failed to parse port: %v", err)
}
return port
}