Files
Agent-System-Backend/internal/hostapi/shared_search_test.go
T
weichen 92ede3b970
ci / vet-and-test (pull_request) Successful in 37s
Close the EXT-8 remaining blocks: vector sharing, hostapi face, citation consistency
Why: EXT-8 closure needs the vector channel shared (not just fulltext), the /host/v1 knowledge face honoring the authorizer, and citation-ref-to-artifact consistency pinned as an acceptance test.
Evidence: TestRetrieveSharedVectorChannel (hash embedder: authorized shared vector hit retrievable, denied yields zero), TestSharedSearchFace (hostapi switches to SharedSearch when wired), TestSharedCitationRefDownloadable (shared hit -> Ref -> artifact content download for the authorized member); go test ./... 32/32 packages ok.
Impact: store.SearchKnowledgeVectorsShared; rag.Pipeline.RetrieveShared (own + shared fulltext + shared vector, RRF-merged); server searchKnowledge prefers RetrieveShared when the retriever implements it; hostapi Server.SharedSearch wired in the composition root through the same authorizer slot. Default behavior unchanged.
Refs: EXT-8 proposal acceptance; slices 1-2.
2026-10-08 17:16:10 +00:00

50 lines
1.6 KiB
Go

package hostapi
import (
"context"
"net/http"
"net/http/httptest"
"testing"
core "agent-system-core"
)
// EXT-8 余项:hostapi 检索面——SharedSearch 可用时整体切换(本人+适配器放行的
// 共享追加);不可用时维持现状(仅本人回调)。
func TestSharedSearchFace(t *testing.T) {
own := []core.RetrievalHit{{Doc: core.KnowledgeDoc{Owner: "bob", Chunk: "本人命中"}}}
sharedHit := core.RetrievalHit{Doc: core.KnowledgeDoc{Owner: "alice", ProjectID: "prj-s", Chunk: "共享命中"}}
srv := &Server{Token: "t", Search: func(ctx context.Context, owner, text string) ([]core.RetrievalHit, error) {
return own, nil
}}
run := func() int {
rec := httptest.NewRecorder()
req := httptest.NewRequest(http.MethodGet, "/host/v1/knowledge/search?q=x", nil)
req.Header.Set("Authorization", "Bearer "+srv.Token)
srv.Handler().ServeHTTP(rec, req)
return rec.Code
}
if code := run(); code != http.StatusOK {
t.Fatalf("plain search: %d", code)
}
srv.SharedSearch = func(ctx context.Context, owner, text string) ([]core.RetrievalHit, error) {
return append(own, sharedHit), nil
}
rec := httptest.NewRecorder()
req := httptest.NewRequest(http.MethodGet, "/host/v1/knowledge/search?q=x", nil)
req.Header.Set("Authorization", "Bearer "+srv.Token)
srv.Handler().ServeHTTP(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("shared search: %d %s", rec.Code, rec.Body.String())
}
var hits []core.RetrievalHit
if err := jsonUnmarshal(rec.Body.Bytes(), &hits); err != nil {
t.Fatal(err)
}
if len(hits) != 2 || hits[1].Doc.Owner != "alice" {
t.Fatalf("hits = %+v, want 本人+共享", hits)
}
}