Introduce new environment variables to control the behavior of one-time download boxes: - `WARPBOX_ONE_TIME_DOWNLOAD_EXPIRY_SECONDS`: Sets the lifetime of a one-time box after uploads are complete. - `WARPBOX_ONE_TIME_DOWNLOAD_RETRY_ON_FAILURE`: Determines whether a box remains available if the ZIP creation or transfer fails. To support these settings, the ZIP delivery process was refactored to use a temporary file. This ensures that a one-time box is only marked as consumed after the file has been successfully transferred to the client, preventing data loss on network interruptions. Additionally, added a `DecorateFiles` helper in the box store to reduce code duplication.
188 lines
5.4 KiB
Go
188 lines
5.4 KiB
Go
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, "")
|
|
}
|
|
}
|