package config import "testing" func TestConfigRejectsRealDispatcherWithoutBroker(t *testing.T) { c := FromEnv() c.Mode, c.RabbitURL, c.DBPath = "real", "", ":memory:" if err := c.Validate("dispatcher"); err == nil { t.Fatal("expected real-mode broker requirement") } } func TestConfigAcceptsMockAgent(t *testing.T) { c := Config{Mode: "mock", SpoolRoot: t.TempDir()} if err := c.Validate("agent"); err != nil { t.Fatal(err) } } func TestConfigLoadsUnifiedDispatcherGRPCSettings(t *testing.T) { t.Setenv("DISPATCHER_GRPC_LISTEN", "127.0.0.1:19443") t.Setenv("DISPATCHER_GRPC_ENDPOINT", "dispatcher.test:19443") t.Setenv("DISPATCHER_GRPC_SERVER_NAME", "dispatcher.test") t.Setenv("DISPATCHER_ALLOWED_AGENT_IDS", "agent-cell-a,agent-cell-b") c := FromEnv() if c.DispatcherGRPCListen != "127.0.0.1:19443" || c.DispatcherGRPCEndpoint != "dispatcher.test:19443" || c.DispatcherGRPCServerName != "dispatcher.test" || c.DispatcherGRPCAllowedAgentIDs != "agent-cell-a,agent-cell-b" { t.Fatalf("unified Dispatcher gRPC settings were not loaded: %+v", c) } } func TestConfigRequiresPhoneLogPair(t *testing.T) { c := Config{Mode: "mock", SpoolRoot: t.TempDir(), CallLogPath: "calls.jsonl"} if err := c.Validate("agent"); err == nil { t.Fatal("expected phone log key requirement") } c.CallLogPhoneKey = "0123456789abcdef" if err := c.Validate("agent"); err != nil { t.Fatal(err) } c.CallLogPath = "" if err := c.Validate("agent"); err != nil { t.Fatalf("key-only configuration should use spool fallback: %v", err) } c.CallLogPhoneKey = "short" if err := c.Validate("agent"); err == nil { t.Fatal("expected phone log key length requirement") } } func TestConfigRequiresAgentTLSFilesWhenRPCIsEnabled(t *testing.T) { c := Config{Mode: "mock", SpoolRoot: t.TempDir(), GRPCListen: "127.0.0.1:19090"} if err := c.Validate("agent"); err == nil { t.Fatal("expected mTLS file requirement") } c.MTLSCAFile, c.MTLSCertFile, c.MTLSKeyFile = "ca.pem", "agent.pem", "agent.key" if err := c.Validate("agent"); err != nil { t.Fatal(err) } c.Mode, c.GRPCListen = "real", "" if err := c.Validate("agent"); err == nil { t.Fatal("expected real agent listener requirement") } } func TestConfigRequiresStaticArtifactForRealAgent(t *testing.T) { c := Config{Mode: "real", SpoolRoot: t.TempDir(), GRPCListen: "127.0.0.1:19090", MTLSCAFile: "ca.pem", MTLSCertFile: "agent.pem", MTLSKeyFile: "agent.key"} if err := c.Validate("agent"); err == nil { t.Fatal("expected static artifact requirement") } c.StaticArtifactPath = "artifact.json" if err := c.Validate("agent"); err != nil { t.Fatal(err) } } func TestConfigRequiresControlTokenWhenHTTPIsEnabled(t *testing.T) { c := Config{Mode: "mock", DBPath: ":memory:", ControlListen: "127.0.0.1:8081"} if err := c.Validate("dispatcher"); err == nil { t.Fatal("expected control token requirement") } c.ControlToken = "test-token" if err := c.Validate("dispatcher"); err != nil { t.Fatal(err) } }