Files
gronod 9a02a27c7f
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
Fix config.Load treating empty env vars as overrides
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.
2026-09-20 23:03:25 +01:00

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")
}
}