yao/agent/context/context_test.go
Max 8dca4719c0 Remove deprecated agent API files and refactor agent loading logic
- Deleted obsolete agent API files (agent.go, api.go, api_test.go, types.go) to streamline the codebase.
- Refactored the agent loading logic to initialize the API instance correctly, ensuring proper integration with the new structure.
- Updated context handling to improve clarity and maintainability across the agent's functionality.
- Enhanced error handling and cache management in the agent's initialization process.
2025-11-11 11:23:20 +08:00

289 lines
8 KiB
Go

package context
import (
"net/http"
"net/http/httptest"
"testing"
"github.com/gin-gonic/gin"
"github.com/stretchr/testify/assert"
)
func TestNewOpenAPI(t *testing.T) {
gin.SetMode(gin.TestMode)
tests := []struct {
name string
queryParams map[string]string
routeParams map[string]string
headers map[string]string
expectedChatID string
expectedAssistant string
expectedLocale string
expectedTheme string
expectedClientType string
expectedReferer string
expectedAccept Accept
}{
{
name: "Parse all query parameters",
queryParams: map[string]string{
"assistant_id": "ast456",
"chat_id": "chat123",
"locale": "zh-CN",
"theme": "Dark",
"referer": RefererProcess,
"accept": string(AcceptStandard),
},
routeParams: map[string]string{
"assistant_id": "route-ast",
},
headers: map[string]string{
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)",
},
expectedChatID: "chat123",
expectedAssistant: "ast456",
expectedLocale: "zh-cn",
expectedTheme: "dark",
expectedClientType: "macos",
expectedReferer: RefererProcess,
expectedAccept: AcceptStandard,
},
{
name: "Default values with no parameters",
queryParams: map[string]string{},
headers: map[string]string{
"User-Agent": "Mozilla/5.0",
},
expectedChatID: "",
expectedAssistant: "",
expectedLocale: "",
expectedTheme: "",
expectedClientType: "web",
expectedReferer: RefererAPI,
expectedAccept: AcceptWebCUI,
},
{
name: "Android client type detection",
queryParams: map[string]string{},
headers: map[string]string{
"User-Agent": "Mozilla/5.0 (Linux; Android 10)",
},
expectedClientType: "android",
expectedReferer: RefererAPI,
expectedAccept: AccepNativeCUI,
},
{
name: "iOS client type detection",
queryParams: map[string]string{},
headers: map[string]string{
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 14_0)",
},
expectedClientType: "ios",
expectedReferer: RefererAPI,
expectedAccept: AccepNativeCUI,
},
{
name: "Windows desktop client type detection",
queryParams: map[string]string{},
headers: map[string]string{
"User-Agent": "Mozilla/5.0 (Windows NT 10.0)",
},
expectedClientType: "windows",
expectedReferer: RefererAPI,
expectedAccept: AcceptDesktopCUI,
},
{
name: "Agent client type detection",
queryParams: map[string]string{},
headers: map[string]string{
"User-Agent": "Yao-Agent/1.0",
},
expectedClientType: "agent",
expectedReferer: RefererAPI,
expectedAccept: AcceptStandard,
},
{
name: "JSSDK client type detection",
queryParams: map[string]string{},
headers: map[string]string{
"User-Agent": "Yao-JSSDK/2.0",
},
expectedClientType: "jssdk",
expectedReferer: RefererAPI,
expectedAccept: AcceptStandard,
},
{
name: "Custom headers for referer and accept",
queryParams: map[string]string{},
headers: map[string]string{
"User-Agent": "Mozilla/5.0",
"X-Yao-Referer": RefererMCP,
"X-Yao-Accept": string(AcceptDesktopCUI),
},
expectedClientType: "web",
expectedReferer: RefererMCP,
expectedAccept: AcceptDesktopCUI,
},
{
name: "Query parameters override headers",
queryParams: map[string]string{
"referer": RefererJSSDK,
"accept": string(AcceptStandard),
},
headers: map[string]string{
"User-Agent": "Mozilla/5.0",
"X-Yao-Referer": RefererMCP,
"X-Yao-Accept": string(AcceptDesktopCUI),
},
expectedClientType: "web",
expectedReferer: RefererJSSDK,
expectedAccept: AcceptStandard,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Create test server
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
// Build query string
req, _ := http.NewRequest("GET", "http://example.com/test", nil)
q := req.URL.Query()
for key, value := range tt.queryParams {
q.Add(key, value)
}
req.URL.RawQuery = q.Encode()
// Set headers
for key, value := range tt.headers {
req.Header.Set(key, value)
}
c.Request = req
// Set route params
for key, value := range tt.routeParams {
c.Params = append(c.Params, gin.Param{Key: key, Value: value})
}
// Call NewGin
ctx := NewOpenAPI(c, nil)
// Assertions
assert.Equal(t, tt.expectedChatID, ctx.ChatID, "ChatID mismatch")
assert.Equal(t, tt.expectedAssistant, ctx.AssistantID, "AssistantID mismatch")
assert.Equal(t, tt.expectedLocale, ctx.Locale, "Locale mismatch")
assert.Equal(t, tt.expectedTheme, ctx.Theme, "Theme mismatch")
assert.Equal(t, tt.expectedClientType, ctx.Client.Type, "Client.Type mismatch")
assert.Equal(t, tt.expectedReferer, ctx.Referer, "Referer mismatch")
assert.Equal(t, tt.expectedAccept, ctx.Accept, "Accept mismatch")
assert.NotNil(t, ctx.Space, "Space should not be nil")
// Client.UserAgent and Client.IP are set from headers/request, may be empty in test context
})
}
}
func TestParseClientType(t *testing.T) {
tests := []struct {
name string
userAgent string
expected string
}{
{"Empty user agent", "", "web"},
{"Standard web browser", "Mozilla/5.0", "web"},
{"Android", "Mozilla/5.0 (Linux; Android 10)", "android"},
{"iPhone", "Mozilla/5.0 (iPhone; CPU iPhone OS 14_0)", "ios"},
{"iPad", "Mozilla/5.0 (iPad; CPU OS 14_0)", "ios"},
{"Windows", "Mozilla/5.0 (Windows NT 10.0)", "windows"},
{"macOS", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)", "macos"},
{"Linux", "Mozilla/5.0 (X11; Linux x86_64)", "linux"},
{"Yao Agent", "Yao-Agent/1.0", "agent"},
{"JSSDK", "Yao-JSSDK/2.0", "jssdk"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := getClientType(tt.userAgent)
assert.Equal(t, tt.expected, result)
})
}
}
func TestParseAccept(t *testing.T) {
tests := []struct {
name string
clientType string
expected Accept
}{
{"Web client", "web", AcceptWebCUI},
{"Android client", "android", AccepNativeCUI},
{"iOS client", "ios", AccepNativeCUI},
{"Windows client", "windows", AcceptDesktopCUI},
{"macOS client", "macos", AcceptDesktopCUI},
{"Linux client", "linux", AcceptDesktopCUI},
{"Agent client", "agent", AcceptStandard},
{"JSSDK client", "jssdk", AcceptStandard},
{"Unknown client", "unknown", AcceptStandard},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := parseAccept(tt.clientType)
assert.Equal(t, tt.expected, result)
})
}
}
func TestValidateAccept(t *testing.T) {
tests := []struct {
name string
accept string
expected Accept
}{
{"Valid standard", "standard", AcceptStandard},
{"Valid cui-web", "cui-web", AcceptWebCUI},
{"Valid cui-native", "cui-native", AccepNativeCUI},
{"Valid cui-desktop", "cui-desktop", AcceptDesktopCUI},
{"Invalid value", "invalid", AcceptStandard},
{"Empty string", "", AcceptStandard},
{"Random string", "random-accept", AcceptStandard},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := validateAccept(tt.accept)
assert.Equal(t, tt.expected, result)
})
}
}
func TestValidateReferer(t *testing.T) {
tests := []struct {
name string
referer string
expected string
}{
{"Valid api", "api", RefererAPI},
{"Valid process", "process", RefererProcess},
{"Valid mcp", "mcp", RefererMCP},
{"Valid jssdk", "jssdk", RefererJSSDK},
{"Valid agent", "agent", RefererAgent},
{"Valid tool", "tool", RefererTool},
{"Valid hook", "hook", RefererHook},
{"Valid schedule", "schedule", RefererSchedule},
{"Valid script", "script", RefererScript},
{"Valid internal", "internal", RefererInternal},
{"Invalid value", "invalid", RefererAPI},
{"Empty string", "", RefererAPI},
{"Random string", "random-referer", RefererAPI},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := validateReferer(tt.referer)
assert.Equal(t, tt.expected, result)
})
}
}