Files
Agent-System-Backend/internal/app/regulations_compat_test.go
T

135 lines
5.7 KiB
Go

package app
import (
"context"
"encoding/json"
"errors"
"path/filepath"
"testing"
"time"
agentcommand "agent-command"
"agent-system-backend/internal/cmdbus"
"agent-system-backend/internal/store"
"agent-system-backend/pkg/extension"
)
// compatRegulationsPlugin stands in for the external kbreg repository: it uses
// only pkg/extension types and registers through the optional Registrar.
type compatRegulationsPlugin struct{ seen []extension.RegulationsCaller }
func (p *compatRegulationsPlugin) Register(reg extension.Registry) error {
registrar, ok := reg.(extension.RegulationsRegistrar)
if !ok {
return errors.New("regulations registrar unavailable")
}
return registrar.RegisterRegulationsProvider(p)
}
func (p *compatRegulationsPlugin) SearchRegulations(_ context.Context, c extension.RegulationsCaller, req extension.RegulationsSearchRequest) (extension.RegulationsSearchResult, error) {
p.seen = append(p.seen, c)
return extension.RegulationsSearchResult{CorpusRevision: "rev-compat", State: extension.RegulationsStateOK,
Hits: []extension.RegulationHit{{RegulationID: "r", EditionID: "e", NodeID: "n", Disclosure: extension.RegulationDisclosureExcerpt}}}, nil
}
func (p *compatRegulationsPlugin) ResolveRegulationEvidence(_ context.Context, c extension.RegulationsCaller, req extension.RegulationEvidenceRequest) (extension.RegulationEvidence, error) {
p.seen = append(p.seen, c)
return extension.RegulationEvidence{CorpusRevision: req.CorpusRevision, NodeID: req.NodeID, Disclosure: extension.RegulationDisclosureFull, HashVerified: true}, nil
}
func (p *compatRegulationsPlugin) SearchWeb(_ context.Context, c extension.RegulationsCaller, req extension.WebSearchRequest) (extension.WebSearchResult, error) {
p.seen = append(p.seen, c)
return extension.WebSearchResult{Provider: "compat", SentQuery: req.Query, State: extension.WebSearchStateEmpty}, nil
}
func (p *compatRegulationsPlugin) CaptureWeb(_ context.Context, c extension.RegulationsCaller, req extension.WebCaptureRequest) (extension.WebCapture, error) {
p.seen = append(p.seen, c)
return extension.WebCapture{FinalURL: req.URL, State: extension.WebCaptureStateFailed, Reason: "offline"}, nil
}
// compatRegulationsConsumer is a second compiled plugin that reaches the
// provider only through the dispatch Host type assertion.
func compatRegulationsConsumer(reg extension.Registry) error {
return reg.AddCommandHandler(json.RawMessage(`{"id":"consumer.regs","title":"regs"}`),
func(ctx context.Context, h extension.Host, req extension.Request) (any, error) {
regs, ok := h.(extension.RegulationsHost)
if !ok {
return nil, errors.New("regulations host capability missing")
}
search, err := regs.SearchRegulations(ctx, extension.RegulationsSearchRequest{SchemaVersion: extension.RegulationsSchemaVersion, Query: "注册检验"})
if err != nil {
return nil, err
}
web, err := regs.SearchWeb(ctx, extension.WebSearchRequest{SchemaVersion: extension.RegulationsSchemaVersion, Query: "注册检验 指导原则"})
if err != nil {
return nil, err
}
return map[string]any{"revision": search.CorpusRevision, "webState": web.State}, nil
})
}
func newRegulationsCompatApp(t *testing.T, plugins ...extension.InProc) (*cmdbus.Bus, *store.Store, hostcaps) {
t.Helper()
extension.ResetCompiled()
t.Cleanup(extension.ResetCompiled)
for _, p := range plugins {
extension.RegisterCompiled(p)
}
st, err := store.OpenSQLite(filepath.Join(t.TempDir(), "compat.db"))
if err != nil {
t.Fatal(err)
}
t.Cleanup(func() { st.Close() })
if err := st.EnsureUser("alice", ""); err != nil {
t.Fatal(err)
}
bus := cmdbus.New(st, nil, func() time.Time { return time.Unix(1700000000, 0).UTC() })
caps := hostcaps{st: st, regulations: &regulationsSlot{}}
applyCompiled("", bus, caps)
return bus, st, caps
}
func TestRegulationsCompiledPluginCompatibility(t *testing.T) {
provider := &compatRegulationsPlugin{}
impostor := &compatRegulationsPlugin{}
bus, st, caps := newRegulationsCompatApp(t,
extension.InProc{ID: "impostor", Register: impostor.Register},
extension.InProc{ID: "kbreg", Register: provider.Register},
extension.InProc{ID: "consumer", Register: compatRegulationsConsumer},
)
if caps.regulations.get() != extension.RegulationsProvider(provider) {
t.Fatal("compiled kbreg provider was not the registered provider")
}
resp := bus.Dispatch(context.Background(), cmdbus.Request{ID: "consumer.regs", Owner: "alice", Actor: "alice", Entrance: "button"})
if resp.Receipt.State != agentcommand.StateCommitted {
t.Fatalf("dispatch = %+v", resp.Receipt)
}
payload, _ := resp.Payload.(map[string]any)
if payload["revision"] != "rev-compat" || payload["webState"] != extension.WebSearchStateEmpty {
t.Fatalf("payload = %+v", resp.Payload)
}
want := extension.RegulationsCaller{PluginID: "consumer", Actor: "alice", Owner: "alice"}
if len(provider.seen) != 2 || provider.seen[0] != want || provider.seen[1] != want || len(impostor.seen) != 0 {
t.Fatalf("provider callers = %+v impostor = %+v", provider.seen, impostor.seen)
}
evs, err := st.ListAuditEvents("alice", 20)
if err != nil {
t.Fatal(err)
}
actions := map[string]bool{}
for _, ev := range evs {
actions[ev.Action] = true
}
if !actions[auditRegulationsSearch] || !actions[auditWebSearch] {
t.Fatalf("host audit missing: %+v", evs)
}
}
func TestRegulationsCompiledConsumerWithoutProvider(t *testing.T) {
bus, _, _ := newRegulationsCompatApp(t, extension.InProc{ID: "consumer", Register: compatRegulationsConsumer})
resp := bus.Dispatch(context.Background(), cmdbus.Request{ID: "consumer.regs", Owner: "alice", Actor: "alice", Entrance: "button"})
if resp.Receipt.State == agentcommand.StateCommitted {
t.Fatalf("consumer succeeded without a regulations provider: %+v", resp.Payload)
}
}