package openai import ( "bytes" "encoding/json" "io" "net/http" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestAdapter_PrepareRequest(t *testing.T) { adapter := NewAdapter() req := &ChatCompletionRequest{ Model: "gpt-4", Messages: []Message{ {Role: "user", Content: "Hello"}, }, } httpReq, err := adapter.PrepareRequest(req, "test-api-key", "https://api.openai.com/v1") require.NoError(t, err) require.NotNil(t, httpReq) assert.Equal(t, "POST", httpReq.Method) assert.Equal(t, "https://api.openai.com/v1/chat/completions", httpReq.URL.String()) assert.Equal(t, "application/json", httpReq.Header.Get("Content-Type")) assert.Equal(t, "Bearer test-api-key", httpReq.Header.Get("Authorization")) // 验证请求体 var body ChatCompletionRequest err = json.NewDecoder(httpReq.Body).Decode(&body) require.NoError(t, err) assert.Equal(t, "gpt-4", body.Model) } func TestAdapter_ParseResponse(t *testing.T) { adapter := NewAdapter() resp := &ChatCompletionResponse{ ID: "chatcmpl-123", Object: "chat.completion", Created: 1234567890, Model: "gpt-4", Choices: []Choice{ { Index: 0, Message: &Message{Role: "assistant", Content: "Hello!"}, }, }, Usage: Usage{PromptTokens: 10, CompletionTokens: 5, TotalTokens: 15}, } body, err := json.Marshal(resp) require.NoError(t, err) httpResp := &http.Response{ StatusCode: 200, Body: io.NopCloser(bytes.NewReader(body)), } result, err := adapter.ParseResponse(httpResp) require.NoError(t, err) assert.Equal(t, "chatcmpl-123", result.ID) assert.Equal(t, "gpt-4", result.Model) require.Len(t, result.Choices, 1) assert.Equal(t, "Hello!", result.Choices[0].Message.Content) } func TestAdapter_ParseErrorResponse(t *testing.T) { adapter := NewAdapter() errResp := &ErrorResponse{ Error: ErrorDetail{ Message: "Invalid API key", Type: "invalid_request_error", Code: "invalid_api_key", }, } body, err := json.Marshal(errResp) require.NoError(t, err) httpResp := &http.Response{ StatusCode: 401, Body: io.NopCloser(bytes.NewReader(body)), } result, err := adapter.ParseErrorResponse(httpResp) require.NoError(t, err) assert.Equal(t, "Invalid API key", result.Error.Message) assert.Equal(t, "invalid_request_error", result.Error.Type) } func TestAdapter_ParseStreamChunk(t *testing.T) { adapter := NewAdapter() chunk := &StreamChunk{ ID: "chatcmpl-123", Object: "chat.completion.chunk", Created: 1234567890, Model: "gpt-4", Choices: []StreamChoice{ { Index: 0, Delta: Delta{Content: "Hello"}, }, }, } data, err := json.Marshal(chunk) require.NoError(t, err) result, err := adapter.ParseStreamChunk(data) require.NoError(t, err) assert.Equal(t, "chatcmpl-123", result.ID) require.Len(t, result.Choices, 1) assert.Equal(t, "Hello", result.Choices[0].Delta.Content) } func TestParseToolCallArguments(t *testing.T) { tests := []struct { name string input string wantErr bool }{ {"有效JSON", `{"key": "value"}`, false}, {"无效JSON", `not json`, true}, {"空JSON", `{}`, false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { tc := &ToolCall{ Function: FunctionCall{Arguments: tt.input}, } args, err := tc.ParseToolCallArguments() if tt.wantErr { assert.Error(t, err) } else { assert.NoError(t, err) assert.NotNil(t, args) } }) } } func TestSerializeToolCallArguments(t *testing.T) { args := map[string]interface{}{"key": "value"} result, err := SerializeToolCallArguments(args) require.NoError(t, err) assert.JSONEq(t, `{"key": "value"}`, result) } func TestValidateRequest(t *testing.T) { t.Run("有效请求", func(t *testing.T) { req := &ChatCompletionRequest{ Model: "gpt-4", Messages: []Message{{Role: "user", Content: "hello"}}, } errs := ValidateRequest(req) assert.Nil(t, errs) }) t.Run("缺少模型", func(t *testing.T) { req := &ChatCompletionRequest{ Messages: []Message{{Role: "user", Content: "hello"}}, } errs := ValidateRequest(req) assert.NotNil(t, errs) assert.Contains(t, errs["model"], "不能为空") }) t.Run("缺少消息", func(t *testing.T) { req := &ChatCompletionRequest{ Model: "gpt-4", } errs := ValidateRequest(req) assert.NotNil(t, errs) assert.Contains(t, errs["messages"], "不能为空") }) t.Run("空消息列表", func(t *testing.T) { req := &ChatCompletionRequest{ Model: "gpt-4", Messages: []Message{}, } errs := ValidateRequest(req) assert.NotNil(t, errs) }) }