ultisuite-backend/internal/websearch/client_test.go
R3D347HR4Y 621b0099d6
Some checks are pending
CI / Go tests (push) Waiting to run
CI / Integration tests (push) Waiting to run
CI / DB migrations (push) Waiting to run
feat(deploy): enhance Nginx configuration and API integration for UltiAI
- Updated .env.example to include new configuration options for the UltiAI branding and API endpoints.
- Enhanced Nginx configuration to support new API routes for the MCP and WebSocket connections.
- Introduced sub-filters for branding adjustments in Nginx responses.
- Added new JavaScript patch for API endpoint adjustments.
- Implemented tests for new API functionalities and improved error handling in the AI gateway.
2026-06-15 00:22:23 +02:00

211 lines
6.0 KiB
Go

package websearch
import (
"context"
"net/http"
"net/http/httptest"
"strings"
"testing"
)
func TestSearchBrave(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if got := r.Header.Get("X-Subscription-Token"); got != "test-key" {
t.Fatalf("unexpected token header: %q", got)
}
if got := r.URL.Query().Get("q"); got != "Jane Doe Acme" {
t.Fatalf("unexpected query: %q", got)
}
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{
"web": {
"results": [
{"title": "Jane Doe - LinkedIn", "url": "https://linkedin.com/in/jane", "description": "CEO at Acme"}
]
}
}`))
}))
defer srv.Close()
oldURL := braveSearchURL
braveSearchURL = srv.URL
t.Cleanup(func() { braveSearchURL = oldURL })
client := NewClient()
results, err := client.Search(context.Background(), Provider{
Type: ProviderBrave,
APIKey: "test-key",
}, "Jane Doe Acme", 5)
if err != nil {
t.Fatalf("Search: %v", err)
}
if len(results) != 1 || results[0].Title != "Jane Doe - LinkedIn" {
t.Fatalf("unexpected results: %#v", results)
}
}
func TestSearchBing(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if got := r.Header.Get("Ocp-Apim-Subscription-Key"); got != "bing-key" {
t.Fatalf("unexpected bing key: %q", got)
}
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"webPages":{"value":[{"name":"Result","url":"https://example.com","snippet":"Hello"}]}}`))
}))
defer srv.Close()
oldURL := bingSearchURL
bingSearchURL = srv.URL
t.Cleanup(func() { bingSearchURL = oldURL })
client := NewClient()
results, err := client.Search(context.Background(), Provider{
Type: ProviderBing,
APIKey: "bing-key",
}, "hello", 5)
if err != nil {
t.Fatalf("Search: %v", err)
}
if len(results) != 1 || results[0].URL != "https://example.com" {
t.Fatalf("unexpected results: %#v", results)
}
}
func TestSearchSearXNG(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if got := r.URL.Query().Get("format"); got != "json" {
t.Fatalf("expected json format, got %q", got)
}
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"results":[{"title":"SearX","url":"https://searx.example","content":"desc"}]}`))
}))
defer srv.Close()
client := NewClient()
results, err := client.Search(context.Background(), Provider{
Type: ProviderSearXNG,
BaseURL: srv.URL,
}, "test", 5)
if err != nil {
t.Fatalf("Search: %v", err)
}
if len(results) != 1 || results[0].Title != "SearX" {
t.Fatalf("unexpected results: %#v", results)
}
}
func TestSearchCustomJSON(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if got := r.URL.Query().Get("q"); got != "custom query" {
t.Fatalf("unexpected query: %q", got)
}
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"data":{"items":[{"title":"Custom","link":"https://custom.test","summary":"note"}]}}`))
}))
defer srv.Close()
client := NewClient()
results, err := client.Search(context.Background(), Provider{
Type: ProviderCustom,
BaseURL: srv.URL,
ResultsPath: "data.items",
TitleField: "title",
URLField: "link",
DescField: "summary",
}, "custom query", 3)
if err != nil {
t.Fatalf("Search: %v", err)
}
if len(results) != 1 || results[0].Title != "Custom" {
t.Fatalf("unexpected results: %#v", results)
}
}
func TestSearchDuckDuckGoHTML(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
t.Fatalf("expected POST, got %s", r.Method)
}
w.Header().Set("Content-Type", "text/html")
_, _ = w.Write([]byte(`
<a class="result__a" href="https://duckduckgo.com/l/?uddg=https%3A%2F%2Fexample.com">Example</a>
<a class="result__snippet">Example description</a>
`))
}))
defer srv.Close()
oldURL := duckDuckGoHTMLURL
duckDuckGoHTMLURL = srv.URL
t.Cleanup(func() { duckDuckGoHTMLURL = oldURL })
client := NewClient()
results, err := client.Search(context.Background(), Provider{Type: ProviderDuckDuckGo}, "example", 5)
if err != nil {
t.Fatalf("Search: %v", err)
}
if len(results) != 1 || results[0].URL != "https://example.com" {
t.Fatalf("unexpected results: %#v", results)
}
}
func TestBuildContactSearchQuery(t *testing.T) {
got := BuildContactSearchQuery("Jean", "Dupont", "Marie", "Ultimail", "CTO", "Lyon")
want := "Jean Marie Dupont Ultimail CTO Lyon"
if got != want {
t.Fatalf("BuildContactSearchQuery() = %q, want %q", got, want)
}
if BuildContactSearchQuery("", "", "", "", "", "") != "" {
t.Fatal("expected empty query")
}
}
func TestFormatResultsForPrompt(t *testing.T) {
text := FormatResultsForPrompt([]Result{
{Title: "Profil", URL: "https://example.com", Description: "Bio"},
})
if text == "" {
t.Fatal("expected non-empty prompt section")
}
for _, part := range []string{"homonymes", "Profil", "https://example.com", "Bio"} {
if !strings.Contains(text, part) {
t.Fatalf("missing %q in: %s", part, text)
}
}
}
func TestResolveProvider(t *testing.T) {
settings := Settings{
DefaultProviderID: "brave-1",
Providers: []Provider{{
ID: "brave-1", Name: "Brave", Type: ProviderBrave, APIKey: "key",
}},
}
p, err := ResolveProvider(settings)
if err != nil {
t.Fatalf("ResolveProvider: %v", err)
}
if p.ID != "brave-1" {
t.Fatalf("unexpected provider: %#v", p)
}
}
func TestProviderConfigured(t *testing.T) {
cases := []struct {
p Provider
want bool
}{
{Provider{Type: ProviderDuckDuckGo}, true},
{Provider{Type: ProviderSearXNG, BaseURL: "https://searx.local"}, true},
{Provider{Type: ProviderSearXNG}, false},
{Provider{
Type: ProviderCustom, BaseURL: "https://api.local",
ResultsPath: "results", TitleField: "title", URLField: "url",
}, true},
}
for _, tc := range cases {
if got := providerConfigured(tc.p); got != tc.want {
t.Fatalf("providerConfigured(%#v) = %v, want %v", tc.p, got, tc.want)
}
}
}