package config import ( "path/filepath" "testing" ) func TestDefaults(t *testing.T) { clearConfigEnv(t) cfg, err := Load() if err != nil { t.Fatalf("Load returned error: %v", err) } if cfg.UploadsDir != filepath.Join("data", "uploads") { t.Fatalf("unexpected uploads dir: %s", cfg.UploadsDir) } if cfg.DBDir != filepath.Join("data", "db") { t.Fatalf("unexpected db dir: %s", cfg.DBDir) } if !cfg.GuestUploadsEnabled || !cfg.APIEnabled || !cfg.ZipDownloadsEnabled || !cfg.OneTimeDownloadsEnabled { t.Fatal("expected default guest/API/download toggles to be enabled") } if cfg.AdminUsername != "admin" { t.Fatalf("unexpected admin username: %s", cfg.AdminUsername) } if cfg.AdminPassword != "" { t.Fatal("expected default admin password to be empty") } } func TestEnvironmentOverrides(t *testing.T) { clearConfigEnv(t) t.Setenv("WARPBOX_DATA_DIR", "/tmp/warpbox-test") t.Setenv("WARPBOX_GUEST_UPLOADS_ENABLED", "false") t.Setenv("WARPBOX_API_ENABLED", "false") t.Setenv("WARPBOX_GLOBAL_MAX_FILE_SIZE_BYTES", "100") t.Setenv("WARPBOX_BOX_POLL_INTERVAL_MS", "2000") t.Setenv("WARPBOX_ADMIN_USERNAME", "root") t.Setenv("WARPBOX_ONE_TIME_DOWNLOAD_RETRY_ON_FAILURE", "true") cfg, err := Load() if err != nil { t.Fatalf("Load returned error: %v", err) } if cfg.UploadsDir != filepath.Join("/tmp/warpbox-test", "uploads") { t.Fatalf("unexpected uploads dir: %s", cfg.UploadsDir) } if cfg.GuestUploadsEnabled || cfg.APIEnabled { t.Fatal("expected boolean environment overrides to be applied") } if cfg.GlobalMaxFileSizeBytes != 100 { t.Fatalf("unexpected global max file size: %d", cfg.GlobalMaxFileSizeBytes) } if cfg.BoxPollIntervalMS != 2000 { t.Fatalf("unexpected poll interval: %d", cfg.BoxPollIntervalMS) } if cfg.AdminUsername != "root" { t.Fatalf("unexpected admin username: %s", cfg.AdminUsername) } if !cfg.OneTimeDownloadRetryOnFailure { t.Fatal("expected one-time retry-on-failure env override to be applied") } if cfg.Source(SettingAPIEnabled) != SourceEnv { t.Fatalf("expected API setting source to be env, got %s", cfg.Source(SettingAPIEnabled)) } } func TestMegabyteSizeEnvironmentOverrides(t *testing.T) { clearConfigEnv(t) t.Setenv("WARPBOX_GLOBAL_MAX_FILE_SIZE_MB", "2048") t.Setenv("WARPBOX_GLOBAL_MAX_BOX_SIZE_MB", "4096") cfg, err := Load() if err != nil { t.Fatalf("Load returned error: %v", err) } if cfg.GlobalMaxFileSizeBytes != 2048*1024*1024 { t.Fatalf("unexpected global max file size: %d", cfg.GlobalMaxFileSizeBytes) } if cfg.GlobalMaxBoxSizeBytes != 4096*1024*1024 { t.Fatalf("unexpected global max box size: %d", cfg.GlobalMaxBoxSizeBytes) } } func TestByteSizeEnvironmentOverridesTakePrecedence(t *testing.T) { clearConfigEnv(t) t.Setenv("WARPBOX_GLOBAL_MAX_FILE_SIZE_MB", "2048") t.Setenv("WARPBOX_GLOBAL_MAX_FILE_SIZE_BYTES", "100") cfg, err := Load() if err != nil { t.Fatalf("Load returned error: %v", err) } if cfg.GlobalMaxFileSizeBytes != 100 { t.Fatalf("unexpected global max file size: %d", cfg.GlobalMaxFileSizeBytes) } } func TestInvalidEnvironmentValues(t *testing.T) { clearConfigEnv(t) t.Setenv("WARPBOX_SESSION_TTL_SECONDS", "1") if _, err := Load(); err == nil { t.Fatal("expected invalid session ttl to fail") } clearConfigEnv(t) t.Setenv("WARPBOX_GUEST_UPLOADS_ENABLED", "maybe") if _, err := Load(); err == nil { t.Fatal("expected invalid boolean to fail") } } func TestSettingsOverridePrecedence(t *testing.T) { clearConfigEnv(t) t.Setenv("WARPBOX_API_ENABLED", "true") cfg, err := Load() if err != nil { t.Fatalf("Load returned error: %v", err) } if err := cfg.ApplyOverrides(map[string]string{SettingAPIEnabled: "false"}); err != nil { t.Fatalf("ApplyOverrides returned error: %v", err) } if cfg.APIEnabled { t.Fatal("expected DB override to beat environment value") } if cfg.Source(SettingAPIEnabled) != SourceDB { t.Fatalf("expected DB source, got %s", cfg.Source(SettingAPIEnabled)) } } func TestSettingsOverrideValidation(t *testing.T) { clearConfigEnv(t) cfg, err := Load() if err != nil { t.Fatalf("Load returned error: %v", err) } if err := cfg.ApplyOverride(SettingDefaultGuestExpirySecs, "-1"); err == nil { t.Fatal("expected negative expiry override to fail") } if err := cfg.ApplyOverride(SettingGlobalMaxFileSizeBytes, "1"); err == nil { t.Fatal("expected hard limit override to fail") } } func clearConfigEnv(t *testing.T) { t.Helper() for _, name := range []string{ "WARPBOX_DATA_DIR", "WARPBOX_ADMIN_PASSWORD", "WARPBOX_ADMIN_USERNAME", "WARPBOX_ADMIN_EMAIL", "WARPBOX_ADMIN_ENABLED", "WARPBOX_ALLOW_ADMIN_SETTINGS_OVERRIDE", "WARPBOX_ADMIN_COOKIE_SECURE", "WARPBOX_GUEST_UPLOADS_ENABLED", "WARPBOX_API_ENABLED", "WARPBOX_ZIP_DOWNLOADS_ENABLED", "WARPBOX_ONE_TIME_DOWNLOADS_ENABLED", "WARPBOX_ONE_TIME_DOWNLOAD_RETRY_ON_FAILURE", "WARPBOX_RENEW_ON_ACCESS_ENABLED", "WARPBOX_RENEW_ON_DOWNLOAD_ENABLED", "WARPBOX_DEFAULT_GUEST_EXPIRY_SECONDS", "WARPBOX_MAX_GUEST_EXPIRY_SECONDS", "WARPBOX_GLOBAL_MAX_FILE_SIZE_MB", "WARPBOX_GLOBAL_MAX_FILE_SIZE_BYTES", "WARPBOX_GLOBAL_MAX_BOX_SIZE_MB", "WARPBOX_GLOBAL_MAX_BOX_SIZE_BYTES", "WARPBOX_DEFAULT_USER_MAX_FILE_SIZE_MB", "WARPBOX_DEFAULT_USER_MAX_FILE_SIZE_BYTES", "WARPBOX_DEFAULT_USER_MAX_BOX_SIZE_MB", "WARPBOX_DEFAULT_USER_MAX_BOX_SIZE_BYTES", "WARPBOX_SESSION_TTL_SECONDS", "WARPBOX_BOX_POLL_INTERVAL_MS", "WARPBOX_THUMBNAIL_BATCH_SIZE", "WARPBOX_THUMBNAIL_INTERVAL_SECONDS", } { t.Setenv(name, "") } }