Build and publish / Test and build (darwin) (push) Successful in 2m4s
Build and publish / Test and build (linux) (push) Successful in 3m3s
Build and publish / Test and build (windows) (push) Successful in 2m50s
Build and publish / Build and publish Docker image (push) Successful in 2m4s
A set-but-empty environment variable wiped the corresponding .env value, so an EMBY_SERVER_URL='' guard on CI broke the config tests. Empty variables now count as unset, and the tests clear the config env keys explicitly for hermeticity.
133 lines
3.1 KiB
Go
133 lines
3.1 KiB
Go
package config
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
// clearEnv empties every config variable so a developer/CI environment cannot
|
|
// leak into Load results (empty variables are treated as unset by Load).
|
|
func clearEnv(t *testing.T) {
|
|
t.Helper()
|
|
for _, k := range []string{
|
|
"EMBY_SERVER_URL", "EMBY_USERNAME", "EMBY_PASSWORD",
|
|
"EMBY_API_KEY", "EMBY_USER_ID", "EMBY_VERIFY_SSL", "LLM_MAX_ITEMS",
|
|
"MCP_TRANSPORT", "MCP_LISTEN_ADDR", "MCP_SESSION_TIMEOUT",
|
|
} {
|
|
t.Setenv(k, "")
|
|
}
|
|
}
|
|
|
|
func writeEnv(t *testing.T, content string) string {
|
|
t.Helper()
|
|
p := filepath.Join(t.TempDir(), ".env")
|
|
if err := os.WriteFile(p, []byte(content), 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return p
|
|
}
|
|
|
|
func TestLoadBasic(t *testing.T) {
|
|
clearEnv(t)
|
|
p := writeEnv(t, `
|
|
# comment
|
|
EMBY_SERVER_URL = "http://emby.local:8096/"
|
|
EMBY_USERNAME = 'user'
|
|
EMBY_PASSWORD = pass
|
|
EMBY_VERIFY_SSL = False
|
|
LLM_MAX_ITEMS = 42
|
|
`)
|
|
cfg, err := Load(p)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if cfg.ServerURL != "http://emby.local:8096" {
|
|
t.Errorf("ServerURL = %q", cfg.ServerURL)
|
|
}
|
|
if cfg.Username != "user" || cfg.Password != "pass" {
|
|
t.Errorf("creds = %q/%q", cfg.Username, cfg.Password)
|
|
}
|
|
if cfg.VerifySSL {
|
|
t.Error("VerifySSL should be false")
|
|
}
|
|
if cfg.MaxChunkSize != 42 {
|
|
t.Errorf("MaxChunkSize = %d", cfg.MaxChunkSize)
|
|
}
|
|
}
|
|
|
|
func TestLoadAPIKeyRequiresUserID(t *testing.T) {
|
|
clearEnv(t)
|
|
p := writeEnv(t, `EMBY_SERVER_URL="http://x"
|
|
EMBY_API_KEY="abc"`)
|
|
if _, err := Load(p); err == nil {
|
|
t.Fatal("expected error for missing EMBY_USER_ID")
|
|
}
|
|
p2 := writeEnv(t, `EMBY_SERVER_URL="http://x"
|
|
EMBY_API_KEY="abc"
|
|
EMBY_USER_ID="u1"`)
|
|
cfg, err := Load(p2)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if cfg.APIKey != "abc" || cfg.UserID != "u1" {
|
|
t.Errorf("cfg = %+v", cfg)
|
|
}
|
|
}
|
|
|
|
func TestLoadMissingFile(t *testing.T) {
|
|
clearEnv(t)
|
|
if _, err := Load(filepath.Join(t.TempDir(), "nope.env")); err == nil {
|
|
t.Fatal("expected error for missing file")
|
|
}
|
|
}
|
|
|
|
func TestLoadDefaults(t *testing.T) {
|
|
clearEnv(t)
|
|
p := writeEnv(t, `EMBY_SERVER_URL="http://x"
|
|
EMBY_USERNAME="u"
|
|
EMBY_PASSWORD="p"`)
|
|
cfg, err := Load(p)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !cfg.VerifySSL {
|
|
t.Error("VerifySSL should default to true")
|
|
}
|
|
if cfg.Transport != TransportStdio {
|
|
t.Errorf("Transport = %q", cfg.Transport)
|
|
}
|
|
if cfg.ListenAddr != "127.0.0.1:8080" {
|
|
t.Errorf("ListenAddr = %q", cfg.ListenAddr)
|
|
}
|
|
if cfg.SessionTimeout != 30*time.Minute {
|
|
t.Errorf("SessionTimeout = %v", cfg.SessionTimeout)
|
|
}
|
|
}
|
|
|
|
func TestLoadHTTPMode(t *testing.T) {
|
|
clearEnv(t)
|
|
// HTTP mode authenticates per request; no server-side creds needed.
|
|
p := writeEnv(t, `EMBY_SERVER_URL="http://x"
|
|
MCP_TRANSPORT=http
|
|
MCP_LISTEN_ADDR="0.0.0.0:9090"
|
|
MCP_SESSION_TIMEOUT="5m"`)
|
|
cfg, err := Load(p)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if cfg.Transport != TransportHTTP || cfg.ListenAddr != "0.0.0.0:9090" || cfg.SessionTimeout != 5*time.Minute {
|
|
t.Errorf("cfg = %+v", cfg)
|
|
}
|
|
}
|
|
|
|
func TestLoadInvalidTransport(t *testing.T) {
|
|
clearEnv(t)
|
|
p := writeEnv(t, `EMBY_SERVER_URL="http://x"
|
|
MCP_TRANSPORT=grpc`)
|
|
if _, err := Load(p); err == nil {
|
|
t.Fatal("expected error for invalid transport")
|
|
}
|
|
}
|