122 lines · 4.9 KB · Go
RawDownload
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)	}} func TestClaudeCodeExecutionScopeAcceptsLowercaseHeaderMapKeys(t *testing.T) {	headers := http.Header{		"x-claude-code-session-id": []string{"lower-session"},		"x-claude-code-agent-id":   []string{"lower-agent"},	} 	scope, ok := ClaudeCodeExecutionScope(context.Background(), nil, headers)	if !ok || scope != "claude:lower-session:agent:lower-agent" {		t.Fatalf("lowercase header scope = %q, %v", scope, ok)	}} func TestClaudeCodeExecutionScopeIsolatesAgents(t *testing.T) {	rootHeaders := http.Header{}	rootHeaders.Set(ClaudeCodeSessionHeader, "session-agents")	childAHeaders := rootHeaders.Clone()	childAHeaders.Set(ClaudeCodeAgentHeader, "agent-a")	childBHeaders := rootHeaders.Clone()	childBHeaders.Set(ClaudeCodeAgentHeader, "agent-b") 	rootScope, ok := ClaudeCodeExecutionScope(context.Background(), nil, rootHeaders)	if !ok || rootScope != "claude:session-agents:agent:main" {		t.Fatalf("root scope = %q, %v", rootScope, ok)	}	childAScope, ok := ClaudeCodeExecutionScope(context.Background(), nil, childAHeaders)	if !ok || childAScope != "claude:session-agents:agent:agent-a" {		t.Fatalf("child A scope = %q, %v", childAScope, ok)	}	childBScope, ok := ClaudeCodeExecutionScope(context.Background(), nil, childBHeaders)	if !ok || childBScope != "claude:session-agents:agent:agent-b" {		t.Fatalf("child B scope = %q, %v", childBScope, ok)	}	if rootScope == childAScope || childAScope == childBScope || rootScope == childBScope {		t.Fatalf("agent scopes are not isolated: root=%q a=%q b=%q", rootScope, childAScope, childBScope)	}} func TestClaudeCodePromptCacheDeterministicAndAgentScoped(t *testing.T) {	rootHeaders := http.Header{}	rootHeaders.Set(ClaudeCodeSessionHeader, "session-cache-agents")	childHeaders := rootHeaders.Clone()	childHeaders.Set(ClaudeCodeAgentHeader, "agent-a") 	rootFirst, ok, errFirst := ClaudeCodePromptCache(context.Background(), "gpt-5.4", nil, rootHeaders)	if errFirst != nil || !ok {		t.Fatalf("root first cache = %#v, %v, %v", rootFirst, ok, errFirst)	}	rootSecond, ok, errSecond := ClaudeCodePromptCache(context.Background(), "gpt-5.4", nil, rootHeaders)	if errSecond != nil || !ok || rootSecond.ID != rootFirst.ID {		t.Fatalf("root second cache = %#v, %v, %v; want ID %q", rootSecond, ok, errSecond, rootFirst.ID)	}	child, ok, errChild := ClaudeCodePromptCache(context.Background(), "gpt-5.4", nil, childHeaders)	if errChild != nil || !ok || child.ID == rootFirst.ID {		t.Fatalf("child cache = %#v, %v, %v; root ID %q", child, ok, errChild, rootFirst.ID)	}	otherModel, ok, errModel := ClaudeCodePromptCache(context.Background(), "gpt-5.5", nil, rootHeaders)	if errModel != nil || !ok || otherModel.ID == rootFirst.ID {		t.Fatalf("other model cache = %#v, %v, %v; root ID %q", otherModel, ok, errModel, rootFirst.ID)	}}