Files
Plexum-fabric-channel-plugin/internal/config/config_test.go
hzhang f8d43ae70e feat: Phase F-1 — Plexum-fabric-channel-plugin foundation
Ports the foundation of Fabric.OpenclawPlugin to a native Plexum
channel plugin (Go). F-2+ phases (socket.io inbound, wakeup gate,
tools, presence, etc.) follow.

Layout:
  internal/identity/      — fabric-identity.json registry (agent → API key)
  internal/fabric/        — REST client (Center auth + Guild messaging)
  internal/config/        — channels/<name>.json fabric extension parser
  cmd/plexum-fabric-register/      — agent registration CLI
  cmd/plexum-fabric-channel-plugin/— Plexum SDK plugin entry
  scripts/install.sh      — build + install + manifest generator

Plugin behavior (F-1):
- Reads <profile>/channels/*.json, filters plugin=plexum-fabric-channel,
  builds (plexum-channel-name → fabric channel-id) index
- Validates each bound agent's API key against Center at init
  (warmSessions); logs warning but doesn't refuse init on bad keys
- `send` MCP tool: POST plain text to the bound Fabric channel as the
  agent user; selects guild endpoint+token from cached session
- Manifest channels[] is generated by install.sh from current
  channels/*.json — re-run with --reset-manifest after adding bindings
- Plugin-private config at
  <profile>/plugins/plexum-fabric-channel/config.json
  (center_api_base, default http://localhost:7001/api)

Live smoke verified:
- plexum-fabric-register against running Fabric Center (port 7001):
  validated fak_..., wrote identity file with user_id + email captured

Tests: identity (5) + config (6) = 11 unit tests.

F-2 will hook socket.io for inbound + wakeup gating + token refresh.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-31 15:13:34 +01:00

93 lines
2.5 KiB
Go

package config
import (
"os"
"path/filepath"
"strings"
"testing"
)
func write(t *testing.T, dir, name, content string) {
t.Helper()
if err := os.WriteFile(filepath.Join(dir, name), []byte(content), 0o600); err != nil {
t.Fatal(err)
}
}
func TestLoadHappyPath(t *testing.T) {
dir := t.TempDir()
write(t, dir, "team-x.json", `{
"agent_id": "alice",
"plugin": "plexum-fabric-channel",
"fabric": {"guild_node_id": "gn_1", "channel_id": "ch_x"}
}`)
write(t, dir, "team-y.json", `{
"agent_id": "bob",
"plugin": "plexum-fabric-channel",
"fabric": {"guild_node_id": "gn_2", "channel_id": "ch_y"}
}`)
got, err := Load(dir)
if err != nil {
t.Fatal(err)
}
if len(got) != 2 {
t.Fatalf("len = %d", len(got))
}
}
func TestLoadSkipsOtherPlugins(t *testing.T) {
dir := t.TempDir()
write(t, dir, "mine.json", `{"agent_id":"a","plugin":"plexum-fabric-channel","fabric":{"guild_node_id":"g","channel_id":"c"}}`)
write(t, dir, "other.json", `{"agent_id":"a","plugin":"another-plugin"}`)
write(t, dir, "no-plugin.json", `{"agent_id":"a"}`)
got, err := Load(dir)
if err != nil {
t.Fatal(err)
}
if len(got) != 1 || got[0].PlexumChannelName != "mine" {
t.Errorf("got = %+v", got)
}
}
func TestLoadErrorsOnMissingFabricFields(t *testing.T) {
dir := t.TempDir()
write(t, dir, "broken.json", `{"agent_id":"a","plugin":"plexum-fabric-channel"}`)
_, err := Load(dir)
if err == nil || !strings.Contains(err.Error(), "fabric") {
t.Errorf("err = %v", err)
}
}
func TestLoadErrorsOnMissingAgentID(t *testing.T) {
dir := t.TempDir()
write(t, dir, "broken.json", `{"plugin":"plexum-fabric-channel","fabric":{"guild_node_id":"g","channel_id":"c"}}`)
_, err := Load(dir)
if err == nil || !strings.Contains(err.Error(), "agent_id") {
t.Errorf("err = %v", err)
}
}
func TestLoadMissingDirEmpty(t *testing.T) {
got, err := Load(filepath.Join(t.TempDir(), "nope"))
if err != nil || got != nil {
t.Errorf("missing dir: err=%v got=%v", err, got)
}
}
func TestIndex(t *testing.T) {
bindings := []FabricBinding{
{PlexumChannelName: "a", AgentID: "u", FabricGuildNodeID: "g1", FabricChannelID: "c1"},
{PlexumChannelName: "b", AgentID: "u", FabricGuildNodeID: "g1", FabricChannelID: "c2"},
}
idx := Index(bindings)
if idx[Key("g1", "c1")] == nil || idx[Key("g1", "c1")].PlexumChannelName != "a" {
t.Errorf("idx miss for c1")
}
if idx[Key("g1", "c2")] == nil || idx[Key("g1", "c2")].PlexumChannelName != "b" {
t.Errorf("idx miss for c2")
}
if idx[Key("g1", "ghost")] != nil {
t.Errorf("ghost entry")
}
}