- web-search: real SearXNG /search?format=json query, top-5 formatted results (was a 'not configured' stub) - web-fetch: fetch page, strip scripts/styles/tags, truncate to 4000 runes for the LLM context - http: generic request tool (GET/POST/PUT/DELETE/PATCH) with scheme and method validation, status + truncated body - file: sandboxed read/write/list inside the data directory with path escape rejection; split into file_read/file_write/file_list - all tool schemas converted to proper JSON Schema; httptest/tempdir tests for each plugin
61 lines
1.6 KiB
Go
61 lines
1.6 KiB
Go
package websearch
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestSearch(t *testing.T) {
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if r.URL.Query().Get("format") != "json" {
|
|
t.Error("missing format=json")
|
|
}
|
|
if r.URL.Query().Get("q") != "昔涟" {
|
|
t.Errorf("unexpected query: %s", r.URL.Query().Get("q"))
|
|
}
|
|
w.Write([]byte(`{"results":[
|
|
{"title":"结果一","url":"https://a.com","content":"摘要一"},
|
|
{"title":"结果二","url":"https://b.com","content":"摘要二"}
|
|
]}`))
|
|
}))
|
|
defer srv.Close()
|
|
|
|
p := New(srv.URL)
|
|
out, err := p.Execute(context.Background(), "web_search", map[string]any{"query": "昔涟"})
|
|
if err != nil {
|
|
t.Fatalf("Execute: %v", err)
|
|
}
|
|
if !strings.Contains(out, "结果一") || !strings.Contains(out, "https://b.com") {
|
|
t.Errorf("unexpected output: %s", out)
|
|
}
|
|
}
|
|
|
|
func TestSearchNoResults(t *testing.T) {
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.Write([]byte(`{"results":[]}`))
|
|
}))
|
|
defer srv.Close()
|
|
|
|
p := New(srv.URL)
|
|
out, err := p.Execute(context.Background(), "web_search", map[string]any{"query": "xyz"})
|
|
if err != nil || !strings.Contains(out, "没有结果") {
|
|
t.Errorf("out=%q err=%v", out, err)
|
|
}
|
|
}
|
|
|
|
func TestSearchMissingQuery(t *testing.T) {
|
|
p := New("http://unused")
|
|
if _, err := p.Execute(context.Background(), "web_search", map[string]any{}); err == nil {
|
|
t.Error("expected error for missing query")
|
|
}
|
|
}
|
|
|
|
func TestDisabledWithoutURL(t *testing.T) {
|
|
if New("").Enabled() {
|
|
t.Error("plugin should be disabled without SearXNG URL")
|
|
}
|
|
}
|