Files
MindSift/internal/config/config_test.go
T

123 lines
4.0 KiB
Go

package config
import (
"log/slog"
"os"
"path/filepath"
"testing"
)
func TestConfigLogLevelAndDebug(t *testing.T) {
// Load writes the generated JWT secret into the data directory; keep it out of the repository
t.Setenv("DATA_DIR", t.TempDir())
os.Setenv("PORT", "9090")
defer os.Unsetenv("PORT")
// 1. Default info
os.Unsetenv("LOG_LEVEL")
os.Unsetenv("DEBUG")
cfg := Load()
if cfg.SlogLevel() != slog.LevelInfo {
t.Fatalf("expected LevelInfo, got %v", cfg.SlogLevel())
}
// 2. LOG_LEVEL=debug
os.Setenv("LOG_LEVEL", "debug")
cfg = Load()
if cfg.SlogLevel() != slog.LevelDebug {
t.Fatalf("expected LevelDebug, got %v", cfg.SlogLevel())
}
// 3. LOG_LEVEL=warn
os.Setenv("LOG_LEVEL", "warn")
cfg = Load()
if cfg.SlogLevel() != slog.LevelWarn {
t.Fatalf("expected LevelWarn, got %v", cfg.SlogLevel())
}
// 4. LOG_LEVEL=error
os.Setenv("LOG_LEVEL", "error")
cfg = Load()
if cfg.SlogLevel() != slog.LevelError {
t.Fatalf("expected LevelError, got %v", cfg.SlogLevel())
}
// 5. DEBUG=true overrides LOG_LEVEL
os.Setenv("LOG_LEVEL", "error")
os.Setenv("DEBUG", "true")
cfg = Load()
if cfg.SlogLevel() != slog.LevelDebug {
t.Fatalf("expected LevelDebug when DEBUG=true, got %v", cfg.SlogLevel())
}
// 6. DEBUG=1 overrides LOG_LEVEL
os.Setenv("DEBUG", "1")
cfg = Load()
if cfg.SlogLevel() != slog.LevelDebug {
t.Fatalf("expected LevelDebug when DEBUG=1, got %v", cfg.SlogLevel())
}
os.Unsetenv("DEBUG")
os.Unsetenv("LOG_LEVEL")
}
func TestJWTSecretNeverUsesAKnownDefault(t *testing.T) {
dir := t.TempDir()
for _, env := range []string{"", "mindsift-default-selfhosted-jwt-secret-key-2026", "change_this_to_a_secure_random_key_min_32_chars"} {
got := resolveJWTSecret(env, dir)
if got == env || len(got) < 32 {
t.Fatalf("env %q: insecure secret %q", env, got)
}
}
// The generated secret is stable across restarts
first := resolveJWTSecret("", dir)
if again := resolveJWTSecret("", dir); again != first {
t.Fatalf("generated secret must persist, got %q then %q", first, again)
}
info, err := os.Stat(filepath.Join(dir, jwtSecretFile))
if err != nil || info.Mode().Perm() != 0o600 {
t.Fatalf("secret file must exist with mode 0600: %v %v", info, err)
}
if got := resolveJWTSecret("ein-eigener-sehr-langer-zufaelliger-wert-123456", dir); got != "ein-eigener-sehr-langer-zufaelliger-wert-123456" {
t.Fatalf("a real JWT_SECRET must win, got %q", got)
}
}
func TestCustomLinkValidation(t *testing.T) {
t.Setenv("DATA_DIR", t.TempDir())
// 1. Valid https URL and label
t.Setenv("LEGAL_CUSTOM_LINK_LABEL", "Unternehmensseite")
t.Setenv("LEGAL_CUSTOM_LINK_URL", "https://example.com/company")
cfg := Load()
if cfg.Legal.CustomLinkLabel != "Unternehmensseite" {
t.Errorf("expected label 'Unternehmensseite', got %q", cfg.Legal.CustomLinkLabel)
}
if cfg.Legal.CustomLinkURL != "https://example.com/company" {
t.Errorf("expected url 'https://example.com/company', got %q", cfg.Legal.CustomLinkURL)
}
// 2. Insecure http URL -> ignored
t.Setenv("LEGAL_CUSTOM_LINK_LABEL", "Insecure Site")
t.Setenv("LEGAL_CUSTOM_LINK_URL", "http://insecure.example.com")
cfg = Load()
if cfg.Legal.CustomLinkURL != "" || cfg.Legal.CustomLinkLabel != "" {
t.Errorf("expected empty custom link for http, got url=%q label=%q", cfg.Legal.CustomLinkURL, cfg.Legal.CustomLinkLabel)
}
// 3. Invalid scheme (javascript:) -> ignored
t.Setenv("LEGAL_CUSTOM_LINK_LABEL", "Exploit")
t.Setenv("LEGAL_CUSTOM_LINK_URL", "javascript:alert(1)")
cfg = Load()
if cfg.Legal.CustomLinkURL != "" || cfg.Legal.CustomLinkLabel != "" {
t.Errorf("expected empty custom link for javascript:, got url=%q label=%q", cfg.Legal.CustomLinkURL, cfg.Legal.CustomLinkLabel)
}
// 4. Empty URL -> empty
t.Setenv("LEGAL_CUSTOM_LINK_LABEL", "Only Label")
t.Setenv("LEGAL_CUSTOM_LINK_URL", "")
cfg = Load()
if cfg.Legal.CustomLinkURL != "" || cfg.Legal.CustomLinkLabel != "" {
t.Errorf("expected empty custom link when url is empty, got url=%q label=%q", cfg.Legal.CustomLinkURL, cfg.Legal.CustomLinkLabel)
}
}