mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-07-03 03:04:26 +08:00
- Introduced `ClaudeCodeSessionID` resolution logic, preferring headers over payload metadata. - Added `ClaudeCodePromptCache` to map sessions to stable prompt cache keys. - Refactored existing logic to integrate `ClaudeCodePromptCache` for session-based handling. - Included extensive unit tests to validate session ID extraction, cache reuse, and header prioritization.
62 lines
2.1 KiB
Go
62 lines
2.1 KiB
Go
package helps
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
func TestExtractClaudeCodeSessionIDFromPayloadJSON(t *testing.T) {
|
|
payload := []byte(`{"metadata":{"user_id":"{\"device_id\":\"d\",\"session_id\":\"cache-session-1\"}"}}`)
|
|
got := ExtractClaudeCodeSessionID(context.Background(), payload, nil)
|
|
if got != "cache-session-1" {
|
|
t.Fatalf("ExtractClaudeCodeSessionID() = %q, want cache-session-1", got)
|
|
}
|
|
}
|
|
|
|
func TestExtractClaudeCodeSessionIDFromHeader(t *testing.T) {
|
|
recorder := httptest.NewRecorder()
|
|
ginCtx, _ := gin.CreateTestContext(recorder)
|
|
ginCtx.Request = httptest.NewRequest(http.MethodPost, "/v1/messages", nil)
|
|
ginCtx.Request.Header.Set(ClaudeCodeSessionHeader, "header-session-1")
|
|
ctx := context.WithValue(context.Background(), "gin", ginCtx)
|
|
|
|
got := ExtractClaudeCodeSessionID(ctx, []byte(`{"model":"gpt-5.4"}`), nil)
|
|
if got != "header-session-1" {
|
|
t.Fatalf("ExtractClaudeCodeSessionID() = %q, want header-session-1", got)
|
|
}
|
|
}
|
|
|
|
func TestClaudeCodePromptCacheStableAcrossRequests(t *testing.T) {
|
|
ctx := context.Background()
|
|
payload := []byte(`{"metadata":{"user_id":"{\"session_id\":\"cache-session-2\"}"}}`)
|
|
first, ok, err := ClaudeCodePromptCache(ctx, "grok-composer-2.5-fast", payload, nil)
|
|
if err != nil {
|
|
t.Fatalf("ClaudeCodePromptCache first error: %v", err)
|
|
}
|
|
if !ok || first.ID == "" {
|
|
t.Fatalf("ClaudeCodePromptCache first = %#v, ok=%v, want cached id", first, ok)
|
|
}
|
|
second, ok, err := ClaudeCodePromptCache(ctx, "grok-composer-2.5-fast", payload, nil)
|
|
if err != nil {
|
|
t.Fatalf("ClaudeCodePromptCache second error: %v", err)
|
|
}
|
|
if !ok || second.ID != first.ID {
|
|
t.Fatalf("second cache id = %q, want %q", second.ID, first.ID)
|
|
}
|
|
}
|
|
|
|
func TestExtractClaudeCodeSessionIDPrefersHeaderOverPayload(t *testing.T) {
|
|
payload := []byte(`{"metadata":{"user_id":"{"session_id":"payload-session"}"}}`)
|
|
headers := http.Header{}
|
|
headers.Set(ClaudeCodeSessionHeader, "header-session")
|
|
|
|
got := ExtractClaudeCodeSessionID(context.Background(), payload, headers)
|
|
if got != "header-session" {
|
|
t.Fatalf("ExtractClaudeCodeSessionID() = %q, want header-session", got)
|
|
}
|
|
}
|