package shared import ( "io" "net/http" "net/http/httptest" "sync" "testing" "git.agentview.dev/profit/golangLAKEHOUSE/internal/langfuse" ) // TestLangfuseMiddleware_NilClientPassthrough locks the // "no client → no-op" contract. Every daemon calls shared.Run; // operators who don't set LANGFUSE_URL must not see middleware // failures, latency, or behavior change of any kind. func TestLangfuseMiddleware_NilClientPassthrough(t *testing.T) { mw := langfuseMiddleware("test-service", nil) called := false h := mw(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { called = true w.WriteHeader(http.StatusTeapot) // distinctive code })) srv := httptest.NewServer(h) defer srv.Close() resp, err := http.Get(srv.URL + "/anything") if err != nil { t.Fatalf("GET: %v", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusTeapot { t.Errorf("expected 418 (handler ran), got %d", resp.StatusCode) } if !called { t.Error("handler should have run via passthrough") } } // TestLangfuseMiddleware_HealthBypassed locks the /health-exempt // rule (per langfuseMiddleware's doc comment): LB probes must not // emit traces or the trace volume drowns out real signal. func TestLangfuseMiddleware_HealthBypassed(t *testing.T) { var ( mu sync.Mutex captured []string // ingestion endpoint payloads ) // Mock Langfuse ingestion endpoint that records every batch. lfMock := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { body, _ := io.ReadAll(r.Body) mu.Lock() captured = append(captured, string(body)) mu.Unlock() w.WriteHeader(http.StatusOK) })) defer lfMock.Close() lf := langfuse.New(lfMock.URL, "test-pk", "test-sk", nil) mw := langfuseMiddleware("test-service", lf) h := mw(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) })) srv := httptest.NewServer(h) defer srv.Close() resp, err := http.Get(srv.URL + "/health") if err != nil { t.Fatalf("GET /health: %v", err) } resp.Body.Close() _ = lf.Close() // force flush mu.Lock() defer mu.Unlock() if len(captured) > 0 { t.Errorf("expected zero ingestion calls for /health, got %d (%v)", len(captured), captured) } } // TestLangfuseMiddleware_RealRequestEmitted locks the happy path: // a real request through an authed route produces ingestion events // (trace + span). We don't decode the payload here — the // internal/langfuse client tests already verify the wire format. // What this test asserts is the wiring: middleware → client → POST. func TestLangfuseMiddleware_RealRequestEmitted(t *testing.T) { var ( mu sync.Mutex captured int ) lfMock := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { _, _ = io.ReadAll(r.Body) mu.Lock() captured++ mu.Unlock() w.WriteHeader(http.StatusOK) })) defer lfMock.Close() lf := langfuse.New(lfMock.URL, "test-pk", "test-sk", nil) mw := langfuseMiddleware("test-service", lf) h := mw(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) })) srv := httptest.NewServer(h) defer srv.Close() resp, err := http.Get(srv.URL + "/api/data") if err != nil { t.Fatalf("GET /api/data: %v", err) } resp.Body.Close() _ = lf.Close() // force flush — sends the queued trace + span mu.Lock() defer mu.Unlock() if captured == 0 { t.Error("expected at least one ingestion call after real request") } } // TestLangfuseMiddleware_StatusCaptured locks the status-writer // wrapping: when the handler returns 500, the middleware must see // 500 in the span output (otherwise error traces all show 200 and // debugging gets harder). func TestLangfuseMiddleware_StatusCaptured(t *testing.T) { mw := langfuseMiddleware("test-service", nil) // nil client; just exercise wrapping called := false h := mw(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { called = true http.Error(w, "boom", http.StatusInternalServerError) })) srv := httptest.NewServer(h) defer srv.Close() resp, err := http.Get(srv.URL + "/api/fail") if err != nil { t.Fatalf("GET: %v", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusInternalServerError { t.Errorf("expected 500, got %d", resp.StatusCode) } if !called { t.Error("handler should have run") } }