yao/agent/search/handlers/web/agent_test.go
Max fa471bc4c4 Update tests to use context and correct URL references
- Modified the `createTestContext` function to use `context.Background()` for improved context management in tests.
- Updated the URL in the `TestAddURL` function to point to the correct Yao Agent Caller resource, ensuring accurate test assertions for added URLs.
2025-12-19 20:10:16 +08:00

285 lines
7.6 KiB
Go

package web_test
import (
"context"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/yaoapp/yao/agent/assistant"
agentContext "github.com/yaoapp/yao/agent/context"
"github.com/yaoapp/yao/agent/search/handlers/web"
"github.com/yaoapp/yao/agent/search/types"
"github.com/yaoapp/yao/agent/testutils"
oauthTypes "github.com/yaoapp/yao/openapi/oauth/types"
)
// TestAgentProviderWithAssistantConfig tests AgentProvider using web-agent-caller assistant config
func TestAgentProviderWithAssistantConfig(t *testing.T) {
if testing.Short() {
t.Skip("Skipping integration test")
}
testutils.Prepare(t)
defer testutils.Clean(t)
// Load the web-agent-caller test assistant to get its config
ast, err := assistant.LoadPath("/assistants/tests/web-agent-caller")
require.NoError(t, err)
require.NotNil(t, ast)
require.NotNil(t, ast.Uses)
// Verify assistant config
assert.Equal(t, "tests.web-agent-caller", ast.ID)
assert.Equal(t, "tests.web-agent", ast.Uses.Web)
// Create AgentProvider from uses.web
provider := web.NewAgentProvider(ast.Uses.Web)
require.NotNil(t, provider)
// Create a mock context
ctx := createTestContext(t)
// Execute search
req := &types.Request{
Query: "Yao App Engine",
Type: types.SearchTypeWeb,
Source: types.SourceAuto,
Limit: 5,
}
result, err := provider.Search(ctx, req)
require.NoError(t, err)
require.NotNil(t, result)
// Verify result structure
assert.Equal(t, types.SearchTypeWeb, result.Type)
assert.Equal(t, "Yao App Engine", result.Query)
assert.Equal(t, types.SourceAuto, result.Source)
// Agent should return mock results from Next hook
if result.Error == "" {
assert.Greater(t, result.Total, 0)
assert.NotEmpty(t, result.Items)
assert.Greater(t, result.Duration, int64(0))
// Verify result item structure
for _, item := range result.Items {
assert.Equal(t, types.SearchTypeWeb, item.Type)
assert.Equal(t, types.SourceAuto, item.Source)
assert.NotEmpty(t, item.Title)
assert.NotEmpty(t, item.URL)
}
t.Logf("Agent search returned %d results in %dms", result.Total, result.Duration)
} else {
t.Logf("Agent search returned error: %s", result.Error)
}
}
// TestAgentProviderWithSiteRestriction tests AgentProvider with domain restriction
func TestAgentProviderWithSiteRestriction(t *testing.T) {
if testing.Short() {
t.Skip("Skipping integration test")
}
testutils.Prepare(t)
defer testutils.Clean(t)
// Create AgentProvider
provider := web.NewAgentProvider("tests.web-agent")
// Create a mock context
ctx := createTestContext(t)
// Execute search with site restriction
req := &types.Request{
Query: "documentation",
Type: types.SearchTypeWeb,
Source: types.SourceHook,
Sites: []string{"github.com"},
Limit: 3,
}
result, err := provider.Search(ctx, req)
require.NoError(t, err)
require.NotNil(t, result)
assert.Equal(t, types.SearchTypeWeb, result.Type)
assert.Equal(t, types.SourceHook, result.Source)
if result.Error == "" {
// All results should be from github.com (mock data respects sites)
for _, item := range result.Items {
assert.Contains(t, item.URL, "github.com", "Result URL should be from github.com")
}
t.Logf("Site-restricted agent search returned %d results", result.Total)
} else {
t.Logf("Agent search returned error: %s", result.Error)
}
}
// TestAgentProviderWithTimeRange tests AgentProvider with time range filter
func TestAgentProviderWithTimeRange(t *testing.T) {
if testing.Short() {
t.Skip("Skipping integration test")
}
testutils.Prepare(t)
defer testutils.Clean(t)
// Create AgentProvider
provider := web.NewAgentProvider("tests.web-agent")
// Create a mock context
ctx := createTestContext(t)
// Execute search with time range
req := &types.Request{
Query: "artificial intelligence news",
Type: types.SearchTypeWeb,
Source: types.SourceAuto,
TimeRange: "week",
Limit: 5,
}
result, err := provider.Search(ctx, req)
require.NoError(t, err)
require.NotNil(t, result)
if result.Error == "" {
t.Logf("Time-ranged agent search (last week) returned %d results in %dms", result.Total, result.Duration)
} else {
t.Logf("Agent search returned error: %s", result.Error)
}
}
// TestAgentProviderNotFound tests AgentProvider when agent is not found
func TestAgentProviderNotFound(t *testing.T) {
if testing.Short() {
t.Skip("Skipping integration test")
}
testutils.Prepare(t)
defer testutils.Clean(t)
// Create AgentProvider with non-existent agent
provider := web.NewAgentProvider("nonexistent.agent")
// Create a mock context
ctx := createTestContext(t)
req := &types.Request{
Query: "test query",
Type: types.SearchTypeWeb,
Source: types.SourceAuto,
}
result, err := provider.Search(ctx, req)
// Should not return error, but result should have error message
require.NoError(t, err)
require.NotNil(t, result)
assert.NotEmpty(t, result.Error)
assert.Contains(t, result.Error, "not found")
}
// TestAgentProviderWithoutContext tests AgentProvider without context
func TestAgentProviderWithoutContext(t *testing.T) {
if testing.Short() {
t.Skip("Skipping integration test")
}
testutils.Prepare(t)
defer testutils.Clean(t)
// Create AgentProvider
provider := web.NewAgentProvider("tests.web-agent")
req := &types.Request{
Query: "test query",
Type: types.SearchTypeWeb,
Source: types.SourceAuto,
}
// Call without context (nil)
result, err := provider.Search(nil, req)
// Should still work - agent provider handles nil context
require.NoError(t, err)
require.NotNil(t, result)
// May have error if context is required for agent call
t.Logf("Agent search without context: error=%s, total=%d", result.Error, result.Total)
}
// TestWebHandlerAgentMode tests the web handler in agent mode
func TestWebHandlerAgentMode(t *testing.T) {
if testing.Short() {
t.Skip("Skipping integration test")
}
testutils.Prepare(t)
defer testutils.Clean(t)
// Create handler with agent mode
handler := web.NewHandler("tests.web-agent", nil)
require.NotNil(t, handler)
// Verify type
assert.Equal(t, types.SearchTypeWeb, handler.Type())
// Create a mock context
ctx := createTestContext(t)
// Execute search with context
req := &types.Request{
Query: "Yao framework",
Type: types.SearchTypeWeb,
Source: types.SourceAuto,
Limit: 5,
}
result, err := handler.SearchWithContext(ctx, req)
require.NoError(t, err)
require.NotNil(t, result)
assert.Equal(t, types.SearchTypeWeb, result.Type)
assert.Equal(t, "Yao framework", result.Query)
if result.Error == "" {
t.Logf("Handler agent mode returned %d results", result.Total)
} else {
t.Logf("Handler agent mode returned error: %s", result.Error)
}
}
// TestWebHandlerAgentModeWithoutContext tests the web handler in agent mode without context
func TestWebHandlerAgentModeWithoutContext(t *testing.T) {
// Create handler with agent mode
handler := web.NewHandler("tests.web-agent", nil)
require.NotNil(t, handler)
req := &types.Request{
Query: "test",
Type: types.SearchTypeWeb,
Source: types.SourceAuto,
}
// Call Search() without context (uses SearchWithContext with nil)
result, err := handler.Search(req)
require.NoError(t, err)
require.NotNil(t, result)
assert.NotEmpty(t, result.Error)
assert.Contains(t, result.Error, "requires context")
}
// createTestContext creates a test context for agent calls
func createTestContext(t *testing.T) *agentContext.Context {
authorized := &oauthTypes.AuthorizedInfo{
UserID: "test-user",
TenantID: "test-tenant",
}
ctx := agentContext.New(context.Background(), authorized, "test-chat-id")
ctx.AssistantID = "tests.web-agent-caller"
return ctx
}