yao/openapi/tests/agent/assistant_test.go
Max 46e0f30599 Implement filtering for assistant tags retrieval
- Enhanced the HandleAssistantTags function to support multiple filtering options including type, connector, built-in status, mentionable status, automated status, and keywords.
- Updated the GetAssistantTags method in the store interfaces to accept a filter parameter, allowing for more granular tag retrieval.
- Refactored the Xun, Mongo, and Redis implementations of GetAssistantTags to utilize the new filtering capabilities.
- Added comprehensive tests for the new filtering functionality, ensuring correct behavior across various scenarios.
- Updated API endpoint documentation to reflect the new filtering options for assistant tags.
2025-11-08 11:14:08 +08:00

953 lines
31 KiB
Go

package openapi_test
import (
"encoding/json"
"fmt"
"net/http"
"testing"
"github.com/stretchr/testify/assert"
"github.com/yaoapp/yao/openapi"
"github.com/yaoapp/yao/openapi/tests/testutils"
)
// TestListAssistants tests the assistants listing endpoint
func TestListAssistants(t *testing.T) {
serverURL := testutils.Prepare(t)
defer testutils.Clean()
// Get base URL from server config
baseURL := ""
if openapi.Server != nil && openapi.Server.Config != nil {
baseURL = openapi.Server.Config.BaseURL
}
// Register test client and get token
client := testutils.RegisterTestClient(t, "Agent List Test Client", []string{"https://localhost/callback"})
defer testutils.CleanupTestClient(t, client.ClientID)
tokenInfo := testutils.ObtainAccessToken(t, serverURL, client.ClientID, client.ClientSecret, "https://localhost/callback", "openid profile")
t.Run("ListAssistantsSuccess", func(t *testing.T) {
// Test listing all assistants
req, err := http.NewRequest("GET", serverURL+baseURL+"/agent/assistants", nil)
assert.NoError(t, err)
req.Header.Set("Authorization", "Bearer "+tokenInfo.AccessToken)
resp, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
assert.NotNil(t, resp)
defer resp.Body.Close()
// Expect successful response
assert.Equal(t, http.StatusOK, resp.StatusCode, "Should successfully retrieve assistants")
var response map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&response)
assert.NoError(t, err)
// Response should have pagination structure
data, hasData := response["data"].([]interface{})
if hasData {
t.Logf("Successfully retrieved %d assistants", len(data))
} else {
t.Logf("Successfully retrieved assistants response (data field type: %T)", response["data"])
}
// Check pagination fields
assert.Contains(t, response, "page")
assert.Contains(t, response, "pagesize")
assert.Contains(t, response, "total")
})
t.Run("ListAssistantsWithPagination", func(t *testing.T) {
// Test with pagination parameters
req, err := http.NewRequest("GET", serverURL+baseURL+"/agent/assistants?page=1&pagesize=10", nil)
assert.NoError(t, err)
req.Header.Set("Authorization", "Bearer "+tokenInfo.AccessToken)
resp, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
assert.NotNil(t, resp)
defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode)
var response map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&response)
assert.NoError(t, err)
// Verify pagination values
page, hasPage := response["page"].(float64)
pagesize, hasPagesize := response["pagesize"].(float64)
if hasPage && hasPagesize {
assert.Equal(t, float64(1), page, "Page should be 1")
assert.Equal(t, float64(10), pagesize, "Pagesize should be 10")
t.Logf("Pagination working correctly: page=%d, pagesize=%d", int(page), int(pagesize))
}
})
t.Run("ListAssistantsWithKeywords", func(t *testing.T) {
// Test with keywords filter
req, err := http.NewRequest("GET", serverURL+baseURL+"/agent/assistants?keywords=test", nil)
assert.NoError(t, err)
req.Header.Set("Authorization", "Bearer "+tokenInfo.AccessToken)
resp, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
assert.NotNil(t, resp)
defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode)
var response map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&response)
assert.NoError(t, err)
data, hasData := response["data"].([]interface{})
if hasData {
t.Logf("Successfully retrieved %d assistants with keywords filter", len(data))
}
})
t.Run("ListAssistantsWithType", func(t *testing.T) {
// Test with type filter
req, err := http.NewRequest("GET", serverURL+baseURL+"/agent/assistants?type=assistant", nil)
assert.NoError(t, err)
req.Header.Set("Authorization", "Bearer "+tokenInfo.AccessToken)
resp, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
assert.NotNil(t, resp)
defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode)
var response map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&response)
assert.NoError(t, err)
data, hasData := response["data"].([]interface{})
if hasData {
t.Logf("Successfully retrieved %d assistants with type filter", len(data))
}
})
t.Run("ListAssistantsWithTags", func(t *testing.T) {
// Test with tags filter
req, err := http.NewRequest("GET", serverURL+baseURL+"/agent/assistants?tags=productivity,ai", nil)
assert.NoError(t, err)
req.Header.Set("Authorization", "Bearer "+tokenInfo.AccessToken)
resp, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
assert.NotNil(t, resp)
defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode)
var response map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&response)
assert.NoError(t, err)
data, hasData := response["data"].([]interface{})
if hasData {
t.Logf("Successfully retrieved %d assistants with tags filter", len(data))
}
})
t.Run("ListAssistantsWithBuiltInFilter", func(t *testing.T) {
// Test with built_in filter
req, err := http.NewRequest("GET", serverURL+baseURL+"/agent/assistants?built_in=true", nil)
assert.NoError(t, err)
req.Header.Set("Authorization", "Bearer "+tokenInfo.AccessToken)
resp, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
assert.NotNil(t, resp)
defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode)
var response map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&response)
assert.NoError(t, err)
data, hasData := response["data"].([]interface{})
if hasData {
t.Logf("Successfully retrieved %d built-in assistants", len(data))
// Verify that built-in assistants have sensitive fields filtered
for _, item := range data {
assistant, ok := item.(map[string]interface{})
if !ok {
continue
}
builtIn, hasBuiltIn := assistant["built_in"].(bool)
if hasBuiltIn && builtIn {
// Check that code-level fields are null or absent
prompts := assistant["prompts"]
workflow := assistant["workflow"]
tools := assistant["tools"]
kb := assistant["kb"]
mcp := assistant["mcp"]
options := assistant["options"]
// These should be nil or absent for built-in assistants
if prompts != nil {
t.Logf("Warning: Built-in assistant has non-nil prompts field: %v", prompts)
}
if workflow != nil {
t.Logf("Warning: Built-in assistant has non-nil workflow field: %v", workflow)
}
if tools != nil {
t.Logf("Warning: Built-in assistant has non-nil tools field: %v", tools)
}
if kb != nil {
t.Logf("Warning: Built-in assistant has non-nil kb field: %v", kb)
}
if mcp != nil {
t.Logf("Warning: Built-in assistant has non-nil mcp field: %v", mcp)
}
if options != nil {
t.Logf("Warning: Built-in assistant has non-nil options field: %v", options)
}
}
}
}
})
t.Run("ListAssistantsWithMentionableFilter", func(t *testing.T) {
// Test with mentionable filter
req, err := http.NewRequest("GET", serverURL+baseURL+"/agent/assistants?mentionable=true", nil)
assert.NoError(t, err)
req.Header.Set("Authorization", "Bearer "+tokenInfo.AccessToken)
resp, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
assert.NotNil(t, resp)
defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode)
var response map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&response)
assert.NoError(t, err)
data, hasData := response["data"].([]interface{})
if hasData {
t.Logf("Successfully retrieved %d mentionable assistants", len(data))
}
})
t.Run("ListAssistantsWithAutomatedFilter", func(t *testing.T) {
// Test with automated filter
req, err := http.NewRequest("GET", serverURL+baseURL+"/agent/assistants?automated=false", nil)
assert.NoError(t, err)
req.Header.Set("Authorization", "Bearer "+tokenInfo.AccessToken)
resp, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
assert.NotNil(t, resp)
defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode)
var response map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&response)
assert.NoError(t, err)
data, hasData := response["data"].([]interface{})
if hasData {
t.Logf("Successfully retrieved %d non-automated assistants", len(data))
}
})
t.Run("ListAssistantsWithSelectFields", func(t *testing.T) {
// Test with select parameter to limit returned fields
req, err := http.NewRequest("GET", serverURL+baseURL+"/agent/assistants?select=assistant_id,name,avatar,type", nil)
assert.NoError(t, err)
req.Header.Set("Authorization", "Bearer "+tokenInfo.AccessToken)
resp, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
assert.NotNil(t, resp)
defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode)
var response map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&response)
assert.NoError(t, err)
data, hasData := response["data"].([]interface{})
if hasData && len(data) > 0 {
// Check first assistant to verify field selection worked
assistant, ok := data[0].(map[string]interface{})
if ok {
t.Logf("Assistant fields returned: %+v", assistant)
// Note: The actual fields returned depend on the implementation
// This test verifies the select parameter is accepted without error
}
}
})
t.Run("ListAssistantsWithInvalidSelectFields", func(t *testing.T) {
// Test with invalid select fields (should be filtered by whitelist)
req, err := http.NewRequest("GET", serverURL+baseURL+"/agent/assistants?select=invalid_field,malicious_sql", nil)
assert.NoError(t, err)
req.Header.Set("Authorization", "Bearer "+tokenInfo.AccessToken)
resp, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
assert.NotNil(t, resp)
defer resp.Body.Close()
// Should still return 200, but with default/filtered fields
assert.Equal(t, http.StatusOK, resp.StatusCode)
var response map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&response)
assert.NoError(t, err)
t.Logf("Successfully handled invalid select fields by using whitelist")
})
t.Run("ListAssistantsWithMultipleFilters", func(t *testing.T) {
// Test with multiple filter parameters combined
req, err := http.NewRequest("GET", serverURL+baseURL+"/agent/assistants?type=assistant&built_in=false&mentionable=true&page=1&pagesize=5", nil)
assert.NoError(t, err)
req.Header.Set("Authorization", "Bearer "+tokenInfo.AccessToken)
resp, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
assert.NotNil(t, resp)
defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode)
var response map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&response)
assert.NoError(t, err)
data, hasData := response["data"].([]interface{})
if hasData {
t.Logf("Successfully retrieved %d assistants with multiple filters", len(data))
}
})
t.Run("ListAssistantsWithConnector", func(t *testing.T) {
// Test with connector filter
req, err := http.NewRequest("GET", serverURL+baseURL+"/agent/assistants?connector=openai", nil)
assert.NoError(t, err)
req.Header.Set("Authorization", "Bearer "+tokenInfo.AccessToken)
resp, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
assert.NotNil(t, resp)
defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode)
var response map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&response)
assert.NoError(t, err)
data, hasData := response["data"].([]interface{})
if hasData {
t.Logf("Successfully retrieved %d assistants with connector filter", len(data))
}
})
t.Run("ListAssistantsWithAssistantID", func(t *testing.T) {
// Test with specific assistant_id filter
req, err := http.NewRequest("GET", serverURL+baseURL+"/agent/assistants?assistant_id=test_assistant", nil)
assert.NoError(t, err)
req.Header.Set("Authorization", "Bearer "+tokenInfo.AccessToken)
resp, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
assert.NotNil(t, resp)
defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode)
var response map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&response)
assert.NoError(t, err)
data, hasData := response["data"].([]interface{})
if hasData {
t.Logf("Successfully retrieved %d assistants with assistant_id filter", len(data))
}
})
t.Run("ListAssistantsWithAssistantIDs", func(t *testing.T) {
// Test with multiple assistant_ids filter
req, err := http.NewRequest("GET", serverURL+baseURL+"/agent/assistants?assistant_ids=assistant1,assistant2,assistant3", nil)
assert.NoError(t, err)
req.Header.Set("Authorization", "Bearer "+tokenInfo.AccessToken)
resp, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
assert.NotNil(t, resp)
defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode)
var response map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&response)
assert.NoError(t, err)
data, hasData := response["data"].([]interface{})
if hasData {
t.Logf("Successfully retrieved %d assistants with assistant_ids filter", len(data))
}
})
t.Run("ListAssistantsWithInvalidPagination", func(t *testing.T) {
// Test with invalid pagination parameters (should use defaults)
req, err := http.NewRequest("GET", serverURL+baseURL+"/agent/assistants?page=-1&pagesize=1000", nil)
assert.NoError(t, err)
req.Header.Set("Authorization", "Bearer "+tokenInfo.AccessToken)
resp, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
assert.NotNil(t, resp)
defer resp.Body.Close()
// Should return error for invalid pagination
if resp.StatusCode == http.StatusBadRequest {
var errorResponse map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&errorResponse)
assert.NoError(t, err)
assert.Contains(t, errorResponse, "error")
t.Logf("Correctly rejected invalid pagination parameters")
} else {
// Or apply default/corrected values
assert.Equal(t, http.StatusOK, resp.StatusCode)
t.Logf("Applied default/corrected pagination values")
}
})
}
// TestAssistantEndpointsUnauthorized tests that endpoints return 401 when not authenticated
func TestAssistantEndpointsUnauthorized(t *testing.T) {
serverURL := testutils.Prepare(t)
defer testutils.Clean()
baseURL := ""
if openapi.Server != nil && openapi.Server.Config != nil {
baseURL = openapi.Server.Config.BaseURL
}
endpoints := []struct {
method string
path string
}{
{"GET", "/agent/assistants"},
{"GET", "/agent/assistants?page=1&pagesize=10"},
{"GET", "/agent/assistants?keywords=test"},
{"GET", "/agent/assistants?type=assistant"},
{"GET", "/agent/assistants?built_in=true"},
}
for _, endpoint := range endpoints {
t.Run(fmt.Sprintf("Unauthorized_%s_%s", endpoint.method, endpoint.path), func(t *testing.T) {
req, err := http.NewRequest(endpoint.method, serverURL+baseURL+endpoint.path, nil)
assert.NoError(t, err)
// No Authorization header
resp, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
assert.NotNil(t, resp)
defer resp.Body.Close()
assert.Equal(t, http.StatusUnauthorized, resp.StatusCode)
t.Logf("Correctly rejected unauthorized request to %s %s", endpoint.method, endpoint.path)
})
}
}
// TestAssistantPermissionFiltering tests that permission-based filtering works correctly
func TestAssistantPermissionFiltering(t *testing.T) {
serverURL := testutils.Prepare(t)
defer testutils.Clean()
baseURL := ""
if openapi.Server != nil && openapi.Server.Config != nil {
baseURL = openapi.Server.Config.BaseURL
}
// Create two different test users with tokens
client := testutils.RegisterTestClient(t, "Agent Permission Test Client", []string{"https://localhost/callback"})
defer testutils.CleanupTestClient(t, client.ClientID)
// User 1 token
token1 := testutils.ObtainAccessToken(t, serverURL, client.ClientID, client.ClientSecret, "https://localhost/callback", "openid profile")
// User 2 token (different user)
token2 := testutils.ObtainAccessToken(t, serverURL, client.ClientID, client.ClientSecret, "https://localhost/callback", "openid profile")
t.Run("User1CanSeeOwnAssistants", func(t *testing.T) {
// User 1 should see their own assistants
req, err := http.NewRequest("GET", serverURL+baseURL+"/agent/assistants", nil)
assert.NoError(t, err)
req.Header.Set("Authorization", "Bearer "+token1.AccessToken)
resp, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
assert.NotNil(t, resp)
defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode)
var response map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&response)
assert.NoError(t, err)
data, hasData := response["data"].([]interface{})
if hasData {
t.Logf("User 1 can see %d assistants", len(data))
}
})
t.Run("User2SeesFilteredResults", func(t *testing.T) {
// User 2 should see different assistants (permission filtering applied)
req, err := http.NewRequest("GET", serverURL+baseURL+"/agent/assistants", nil)
assert.NoError(t, err)
req.Header.Set("Authorization", "Bearer "+token2.AccessToken)
resp, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
assert.NotNil(t, resp)
defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode)
var response map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&response)
assert.NoError(t, err)
data, hasData := response["data"].([]interface{})
if hasData {
t.Logf("User 2 can see %d assistants (permission filtering applied)", len(data))
}
})
}
// TestAssistantResponseStructure tests that the response structure is correct
func TestAssistantResponseStructure(t *testing.T) {
serverURL := testutils.Prepare(t)
defer testutils.Clean()
baseURL := ""
if openapi.Server != nil && openapi.Server.Config != nil {
baseURL = openapi.Server.Config.BaseURL
}
client := testutils.RegisterTestClient(t, "Agent Response Structure Test Client", []string{"https://localhost/callback"})
defer testutils.CleanupTestClient(t, client.ClientID)
tokenInfo := testutils.ObtainAccessToken(t, serverURL, client.ClientID, client.ClientSecret, "https://localhost/callback", "openid profile")
t.Run("ResponseHasCorrectStructure", func(t *testing.T) {
req, err := http.NewRequest("GET", serverURL+baseURL+"/agent/assistants?page=1&pagesize=5", nil)
assert.NoError(t, err)
req.Header.Set("Authorization", "Bearer "+tokenInfo.AccessToken)
resp, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
assert.NotNil(t, resp)
defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode)
var response map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&response)
assert.NoError(t, err)
// Verify response structure matches OpenAPI standard
assert.Contains(t, response, "data", "Response should have 'data' field")
assert.Contains(t, response, "page", "Response should have 'page' field")
assert.Contains(t, response, "pagesize", "Response should have 'pagesize' field")
assert.Contains(t, response, "total", "Response should have 'total' field")
// Verify data is an array
data, ok := response["data"].([]interface{})
assert.True(t, ok, "Data field should be an array")
t.Logf("Response structure is correct with %d assistants", len(data))
})
}
// TestAssistantLocaleSupport tests that locale parameter works correctly
func TestAssistantLocaleSupport(t *testing.T) {
serverURL := testutils.Prepare(t)
defer testutils.Clean()
baseURL := ""
if openapi.Server != nil && openapi.Server.Config != nil {
baseURL = openapi.Server.Config.BaseURL
}
client := testutils.RegisterTestClient(t, "Agent Locale Test Client", []string{"https://localhost/callback"})
defer testutils.CleanupTestClient(t, client.ClientID)
tokenInfo := testutils.ObtainAccessToken(t, serverURL, client.ClientID, client.ClientSecret, "https://localhost/callback", "openid profile")
locales := []string{"en-us", "zh-cn", "ja-jp", "de-de", "fr-fr"}
for _, locale := range locales {
t.Run(fmt.Sprintf("LocaleSupport_%s", locale), func(t *testing.T) {
req, err := http.NewRequest("GET", serverURL+baseURL+"/agent/assistants?locale="+locale, nil)
assert.NoError(t, err)
req.Header.Set("Authorization", "Bearer "+tokenInfo.AccessToken)
resp, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
assert.NotNil(t, resp)
defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode)
var response map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&response)
assert.NoError(t, err)
t.Logf("Successfully retrieved assistants with locale: %s", locale)
})
}
}
// TestAssistantEdgeCases tests edge cases and boundary conditions
func TestAssistantEdgeCases(t *testing.T) {
serverURL := testutils.Prepare(t)
defer testutils.Clean()
baseURL := ""
if openapi.Server != nil && openapi.Server.Config != nil {
baseURL = openapi.Server.Config.BaseURL
}
client := testutils.RegisterTestClient(t, "Agent Edge Cases Test Client", []string{"https://localhost/callback"})
defer testutils.CleanupTestClient(t, client.ClientID)
tokenInfo := testutils.ObtainAccessToken(t, serverURL, client.ClientID, client.ClientSecret, "https://localhost/callback", "openid profile")
t.Run("EmptyKeywordsParameter", func(t *testing.T) {
// Test with empty keywords parameter
req, err := http.NewRequest("GET", serverURL+baseURL+"/agent/assistants?keywords=", nil)
assert.NoError(t, err)
req.Header.Set("Authorization", "Bearer "+tokenInfo.AccessToken)
resp, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode)
t.Logf("Handled empty keywords parameter correctly")
})
t.Run("EmptyTagsParameter", func(t *testing.T) {
// Test with empty tags parameter
req, err := http.NewRequest("GET", serverURL+baseURL+"/agent/assistants?tags=", nil)
assert.NoError(t, err)
req.Header.Set("Authorization", "Bearer "+tokenInfo.AccessToken)
resp, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode)
t.Logf("Handled empty tags parameter correctly")
})
t.Run("VeryLongKeywords", func(t *testing.T) {
// Test with very long keywords string
longKeywords := string(make([]byte, 1000))
for i := range longKeywords {
longKeywords = longKeywords[:i] + "test"
}
req, err := http.NewRequest("GET", serverURL+baseURL+"/agent/assistants?keywords="+longKeywords[:500], nil)
assert.NoError(t, err)
req.Header.Set("Authorization", "Bearer "+tokenInfo.AccessToken)
resp, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
defer resp.Body.Close()
// Should handle gracefully (either return results or error)
assert.True(t, resp.StatusCode == http.StatusOK || resp.StatusCode == http.StatusBadRequest)
t.Logf("Handled very long keywords parameter (status: %d)", resp.StatusCode)
})
t.Run("SpecialCharactersInKeywords", func(t *testing.T) {
// Test with special characters in keywords
specialKeywords := "test&special=chars<>\"';--"
req, err := http.NewRequest("GET", serverURL+baseURL+"/agent/assistants?keywords="+specialKeywords, nil)
assert.NoError(t, err)
req.Header.Set("Authorization", "Bearer "+tokenInfo.AccessToken)
resp, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode)
t.Logf("Handled special characters in keywords correctly")
})
t.Run("MaxPageSize", func(t *testing.T) {
// Test with maximum page size (should be capped at 100)
req, err := http.NewRequest("GET", serverURL+baseURL+"/agent/assistants?pagesize=100", nil)
assert.NoError(t, err)
req.Header.Set("Authorization", "Bearer "+tokenInfo.AccessToken)
resp, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode)
var response map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&response)
assert.NoError(t, err)
pagesize, ok := response["pagesize"].(float64)
if ok {
assert.LessOrEqual(t, int(pagesize), 100, "Pagesize should be capped at 100")
t.Logf("Correctly capped pagesize at %d", int(pagesize))
}
})
}
// TestListAssistantTags tests the assistant tags endpoint
func TestListAssistantTags(t *testing.T) {
serverURL := testutils.Prepare(t)
defer testutils.Clean()
baseURL := ""
if openapi.Server != nil && openapi.Server.Config != nil {
baseURL = openapi.Server.Config.BaseURL
}
client := testutils.RegisterTestClient(t, "Agent Tags Test Client", []string{"https://localhost/callback"})
defer testutils.CleanupTestClient(t, client.ClientID)
tokenInfo := testutils.ObtainAccessToken(t, serverURL, client.ClientID, client.ClientSecret, "https://localhost/callback", "openid profile")
t.Run("ListAssistantTagsSuccess", func(t *testing.T) {
// Test listing all assistant tags
req, err := http.NewRequest("GET", serverURL+baseURL+"/agent/assistants/tags", nil)
assert.NoError(t, err)
req.Header.Set("Authorization", "Bearer "+tokenInfo.AccessToken)
resp, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
assert.NotNil(t, resp)
defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode, "Should successfully retrieve tags")
var response map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&response)
assert.NoError(t, err)
data, hasData := response["data"].([]interface{})
if hasData {
t.Logf("Successfully retrieved %d tags", len(data))
// Verify tag structure
if len(data) > 0 {
tag, ok := data[0].(map[string]interface{})
if ok {
assert.Contains(t, tag, "value", "Tag should have value field")
assert.Contains(t, tag, "label", "Tag should have label field")
}
}
}
})
t.Run("ListAssistantTagsWithLocale", func(t *testing.T) {
// Test with locale parameter
req, err := http.NewRequest("GET", serverURL+baseURL+"/agent/assistants/tags?locale=zh-cn", nil)
assert.NoError(t, err)
req.Header.Set("Authorization", "Bearer "+tokenInfo.AccessToken)
resp, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
assert.NotNil(t, resp)
defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode)
var response map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&response)
assert.NoError(t, err)
data, hasData := response["data"].([]interface{})
if hasData {
t.Logf("Successfully retrieved %d tags with zh-cn locale", len(data))
}
})
t.Run("ListAssistantTagsWithFilters", func(t *testing.T) {
// Test with type filter
req, err := http.NewRequest("GET", serverURL+baseURL+"/agent/assistants/tags?type=assistant", nil)
assert.NoError(t, err)
req.Header.Set("Authorization", "Bearer "+tokenInfo.AccessToken)
resp, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
assert.NotNil(t, resp)
defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode)
var response map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&response)
assert.NoError(t, err)
data, hasData := response["data"].([]interface{})
if hasData {
t.Logf("Successfully retrieved %d tags with type filter", len(data))
}
})
t.Run("ListAssistantTagsWithConnector", func(t *testing.T) {
// Test with connector filter
req, err := http.NewRequest("GET", serverURL+baseURL+"/agent/assistants/tags?connector=openai", nil)
assert.NoError(t, err)
req.Header.Set("Authorization", "Bearer "+tokenInfo.AccessToken)
resp, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
assert.NotNil(t, resp)
defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode)
var response map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&response)
assert.NoError(t, err)
data, hasData := response["data"].([]interface{})
if hasData {
t.Logf("Successfully retrieved %d tags for openai connector", len(data))
}
})
t.Run("ListAssistantTagsWithBuiltInFilter", func(t *testing.T) {
// Test with built_in filter
req, err := http.NewRequest("GET", serverURL+baseURL+"/agent/assistants/tags?built_in=false", nil)
assert.NoError(t, err)
req.Header.Set("Authorization", "Bearer "+tokenInfo.AccessToken)
resp, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
assert.NotNil(t, resp)
defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode)
var response map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&response)
assert.NoError(t, err)
data, hasData := response["data"].([]interface{})
if hasData {
t.Logf("Successfully retrieved %d tags for non-built-in assistants", len(data))
}
})
t.Run("ListAssistantTagsWithMentionableFilter", func(t *testing.T) {
// Test with mentionable filter
req, err := http.NewRequest("GET", serverURL+baseURL+"/agent/assistants/tags?mentionable=true", nil)
assert.NoError(t, err)
req.Header.Set("Authorization", "Bearer "+tokenInfo.AccessToken)
resp, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
assert.NotNil(t, resp)
defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode)
var response map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&response)
assert.NoError(t, err)
data, hasData := response["data"].([]interface{})
if hasData {
t.Logf("Successfully retrieved %d tags for mentionable assistants", len(data))
}
})
t.Run("ListAssistantTagsWithKeywords", func(t *testing.T) {
// Test with keywords filter
req, err := http.NewRequest("GET", serverURL+baseURL+"/agent/assistants/tags?keywords=test", nil)
assert.NoError(t, err)
req.Header.Set("Authorization", "Bearer "+tokenInfo.AccessToken)
resp, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
assert.NotNil(t, resp)
defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode)
var response map[string]interface{}
err = json.NewDecoder(resp.Body).Decode(&response)
assert.NoError(t, err)
data, hasData := response["data"].([]interface{})
if hasData {
t.Logf("Successfully retrieved %d tags with keywords filter", len(data))
}
})
t.Run("ListAssistantTagsUnauthorized", func(t *testing.T) {
// Test without authentication
req, err := http.NewRequest("GET", serverURL+baseURL+"/agent/assistants/tags", nil)
assert.NoError(t, err)
// No Authorization header
resp, err := http.DefaultClient.Do(req)
assert.NoError(t, err)
assert.NotNil(t, resp)
defer resp.Body.Close()
assert.Equal(t, http.StatusUnauthorized, resp.StatusCode)
t.Logf("Correctly rejected unauthorized request")
})
}
// BenchmarkListAssistants benchmarks the list assistants endpoint
func BenchmarkListAssistants(b *testing.B) {
// Convert testing.B to testing.T for Prepare/Clean
t := &testing.T{}
serverURL := testutils.Prepare(t)
defer testutils.Clean()
baseURL := ""
if openapi.Server != nil && openapi.Server.Config != nil {
baseURL = openapi.Server.Config.BaseURL
}
client := testutils.RegisterTestClient(t, "Agent Benchmark Client", []string{"https://localhost/callback"})
defer testutils.CleanupTestClient(t, client.ClientID)
tokenInfo := testutils.ObtainAccessToken(t, serverURL, client.ClientID, client.ClientSecret, "https://localhost/callback", "openid profile")
// Reset timer after setup
b.ResetTimer()
// Run benchmark
for i := 0; i < b.N; i++ {
req, _ := http.NewRequest("GET", serverURL+baseURL+"/agent/assistants?page=1&pagesize=20", nil)
req.Header.Set("Authorization", "Bearer "+tokenInfo.AccessToken)
resp, err := http.DefaultClient.Do(req)
if err != nil {
b.Fatalf("Request failed: %v", err)
}
resp.Body.Close()
}
}