package main import ( "context" "errors" "strings" "testing" "opsxdb/server/internal/aitools" ) func TestCallToolReloadsPolicyAndFailsClosed(t *testing.T) { policy := aitools.Policy{Mode: aitools.ModeReadOnly, AllowedConnectionIDs: []string{"c1"}} var loadErr error load := func() (*aitools.Runtime, error) { if loadErr != nil { return nil, loadErr } rt := aitools.NewRuntime(policy) rt.Audit = func(aitools.AuditEntry) {} rt.LoadConns = func() ([]aitools.SavedConnection, error) { return []aitools.SavedConnection{{ID: "c1"}, {ID: "c2"}}, nil } return rt, nil } list := func() ([]aitools.ConnectionSummary, error) { out, err := callTool(context.Background(), aitools.ToolListConnections, nil, load) if err != nil { return nil, err } return out.(map[string]any)["connections"].([]aitools.ConnectionSummary), nil } first, err := list() if err != nil || len(first) != 1 || first[0].ID != "c1" { t.Fatalf("initial whitelist: %v, %v", first, err) } policy.AllowedConnectionIDs = []string{"c2"} second, err := list() if err != nil || len(second) != 1 || second[0].ID != "c2" { t.Fatalf("updated whitelist: %v, %v", second, err) } loadErr = errors.New("invalid mcp.json") if _, err := list(); err == nil || !strings.Contains(err.Error(), "invalid mcp.json") { t.Fatalf("broken policy must reject calls, got %v", err) } }