160 lines
4.0 KiB
Go
160 lines
4.0 KiB
Go
package api
|
|
|
|
import (
|
|
"os"
|
|
"testing"
|
|
|
|
"git.wisehodl.dev/jay/aicli/config"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestParseResponse(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
body string
|
|
protocol config.APIProtocol
|
|
want string
|
|
wantErr bool
|
|
errContains string
|
|
}{
|
|
{
|
|
name: "openai success",
|
|
body: `{"choices":[{"message":{"content":"This is the response text."}}]}`,
|
|
protocol: config.ProtocolOpenAI,
|
|
want: "This is the response text.",
|
|
},
|
|
{
|
|
name: "openai empty choices",
|
|
body: `{"choices":[]}`,
|
|
protocol: config.ProtocolOpenAI,
|
|
wantErr: true,
|
|
errContains: "empty choices array",
|
|
},
|
|
{
|
|
name: "openai no choices field",
|
|
body: `{"result":"ok"}`,
|
|
protocol: config.ProtocolOpenAI,
|
|
wantErr: true,
|
|
errContains: "no choices in response",
|
|
},
|
|
{
|
|
name: "openai invalid choice format",
|
|
body: `{"choices":["invalid"]}`,
|
|
protocol: config.ProtocolOpenAI,
|
|
wantErr: true,
|
|
errContains: "invalid choice format",
|
|
},
|
|
{
|
|
name: "openai no message field",
|
|
body: `{"choices":[{"text":"wrong structure"}]}`,
|
|
protocol: config.ProtocolOpenAI,
|
|
wantErr: true,
|
|
errContains: "no message in choice",
|
|
},
|
|
{
|
|
name: "openai no content field",
|
|
body: `{"choices":[{"message":{"role":"assistant"}}]}`,
|
|
protocol: config.ProtocolOpenAI,
|
|
wantErr: true,
|
|
errContains: "no content in message",
|
|
},
|
|
{
|
|
name: "ollama success",
|
|
body: `{"response":"This is the Ollama response."}`,
|
|
protocol: config.ProtocolOllama,
|
|
want: "This is the Ollama response.",
|
|
},
|
|
{
|
|
name: "ollama no response field",
|
|
body: `{"model":"llama3"}`,
|
|
protocol: config.ProtocolOllama,
|
|
wantErr: true,
|
|
errContains: "no response field in ollama response",
|
|
},
|
|
{
|
|
name: "malformed json",
|
|
body: `{invalid json`,
|
|
protocol: config.ProtocolOpenAI,
|
|
wantErr: true,
|
|
errContains: "parse response",
|
|
},
|
|
{
|
|
name: "openai multiline content",
|
|
body: `{"choices":[{"message":{"content":"Line 1\nLine 2\nLine 3"}}]}`,
|
|
protocol: config.ProtocolOpenAI,
|
|
want: "Line 1\nLine 2\nLine 3",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got, err := parseResponse([]byte(tt.body), tt.protocol)
|
|
if tt.wantErr {
|
|
assert.Error(t, err)
|
|
if tt.errContains != "" {
|
|
assert.Contains(t, err.Error(), tt.errContains)
|
|
}
|
|
return
|
|
}
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, tt.want, got)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestParseResponseWithTestdata(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
file string
|
|
protocol config.APIProtocol
|
|
want string
|
|
wantErr bool
|
|
errContains string
|
|
}{
|
|
{
|
|
name: "openai success from file",
|
|
file: "testdata/openai_success.json",
|
|
protocol: config.ProtocolOpenAI,
|
|
want: "This is the response text.",
|
|
},
|
|
{
|
|
name: "openai empty choices from file",
|
|
file: "testdata/openai_empty_choices.json",
|
|
protocol: config.ProtocolOpenAI,
|
|
wantErr: true,
|
|
errContains: "empty choices array",
|
|
},
|
|
{
|
|
name: "ollama success from file",
|
|
file: "testdata/ollama_success.json",
|
|
protocol: config.ProtocolOllama,
|
|
want: "This is the Ollama response.",
|
|
},
|
|
{
|
|
name: "ollama no response from file",
|
|
file: "testdata/ollama_no_response.json",
|
|
protocol: config.ProtocolOllama,
|
|
wantErr: true,
|
|
errContains: "no response field",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
body, err := os.ReadFile(tt.file)
|
|
assert.NoError(t, err, "failed to read test file")
|
|
|
|
got, err := parseResponse(body, tt.protocol)
|
|
if tt.wantErr {
|
|
assert.Error(t, err)
|
|
if tt.errContains != "" {
|
|
assert.Contains(t, err.Error(), tt.errContains)
|
|
}
|
|
return
|
|
}
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, tt.want, got)
|
|
})
|
|
}
|
|
}
|