package tools import ( "net/http" "net/http/httptest" "testing" core "agent-system-core" ) type dummyCtx struct{ project string } func (dummyCtx) ProjectID() string { return "" } func (dummyCtx) ConversationID() string { return "" } func (dummyCtx) Retrieve(q core.RetrievalQuery) ([]core.RetrievalHit, error) { return nil, nil } func (dummyCtx) WriteArtifact(name, kind, mime string, content []byte) (core.Artifact, error) { return core.Artifact{}, nil } // TestHTTPExecutorTemplateAndPath:模板变量注入、结果路径裁剪、错误状态。 func TestHTTPExecutorTemplateAndPath(t *testing.T) { srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/translate" { http.NotFound(w, r) return } w.Header().Set("Content-Type", "application/json") w.Write([]byte(`{"data":[{"translated":"hello","src":"你好"}],"meta":{"n":1}}`)) })) defer srv.Close() spec := core.HTTPToolSpec{ Method: "POST", URL: srv.URL + "/translate", BodyTemplate: `{"q":"{{param.text}}"}`, ResultPath: "data.0.translated", } exec := HTTPExecutor(spec, nil) out, err := exec(dummyCtx{}, []byte(`{"text":"你好"}`)) if err != nil { t.Fatal(err) } if out != `"hello"` && out != "hello" { t.Errorf("result: %q", out) } // ResultPath 不存在 → 显式错误。 specBad := spec specBad.ResultPath = "missing.path" if _, err := HTTPExecutor(specBad, nil)(dummyCtx{}, []byte(`{}`)); err == nil { t.Error("missing path should error") } // 404 → 错误带状态码。 spec404 := spec spec404.URL = srv.URL + "/nope" spec404.ResultPath = "" if _, err := HTTPExecutor(spec404, nil)(dummyCtx{}, nil); err == nil { t.Error("404 should error") } } func TestExpandTemplate(t *testing.T) { got := expandTemplate(`{{param.a}}/{{param.b.c}}/{{param.unknown}}`, map[string]any{ "a": "x", "b": map[string]any{"c": "y"}, }) if got != "x/y/" { t.Errorf("expand: %q", got) } }