package services import ( "log/slog" "path/filepath" "testing" "time" "warpbox.dev/backend/libs/config" ) func TestSettingsLoadDefaultsAndOverrides(t *testing.T) { settings := newTestSettingsService(t) policy, err := settings.UploadPolicy() if err != nil { t.Fatalf("UploadPolicy returned error: %v", err) } if !policy.AnonymousUploadsEnabled || policy.AnonymousMaxUploadMB != 512 { t.Fatalf("default policy = %+v", policy) } policy.AnonymousUploadsEnabled = false policy.UserDailyUploadMB = 123 if err := settings.UpdateUploadPolicy(policy); err != nil { t.Fatalf("UpdateUploadPolicy returned error: %v", err) } next, err := settings.UploadPolicy() if err != nil { t.Fatalf("UploadPolicy returned error: %v", err) } if next.AnonymousUploadsEnabled || next.UserDailyUploadMB != 123 { t.Fatalf("override policy = %+v", next) } } func TestSettingsUseNewEnvDefaultsUntilSaved(t *testing.T) { root := t.TempDir() upload, err := NewUploadService(1024*1024, filepath.Join(root, "data"), "http://example.test", slog.Default()) if err != nil { t.Fatalf("NewUploadService returned error: %v", err) } defer upload.Close() first, err := NewSettingsService(upload.DB(), config.SettingsDefaults{ AnonymousUploadsEnabled: true, AnonymousMaxUploadMB: 111, AnonymousDailyUploadMB: 222, UserDailyUploadMB: 333, DefaultUserStorageMB: 444, UsageRetentionDays: 30, }) if err != nil { t.Fatalf("NewSettingsService first returned error: %v", err) } firstPolicy, err := first.UploadPolicy() if err != nil { t.Fatalf("UploadPolicy first returned error: %v", err) } if firstPolicy.AnonymousMaxUploadMB != 111 { t.Fatalf("first AnonymousMaxUploadMB = %v, want 111", firstPolicy.AnonymousMaxUploadMB) } second, err := NewSettingsService(upload.DB(), config.SettingsDefaults{ AnonymousUploadsEnabled: true, AnonymousMaxUploadMB: 555, AnonymousDailyUploadMB: 666, UserDailyUploadMB: 777, DefaultUserStorageMB: 888, UsageRetentionDays: 30, }) if err != nil { t.Fatalf("NewSettingsService second returned error: %v", err) } secondPolicy, err := second.UploadPolicy() if err != nil { t.Fatalf("UploadPolicy second returned error: %v", err) } if secondPolicy.AnonymousMaxUploadMB != 555 { t.Fatalf("second AnonymousMaxUploadMB = %v, want 555", secondPolicy.AnonymousMaxUploadMB) } if err := second.UpdateUploadPolicy(secondPolicy); err != nil { t.Fatalf("UpdateUploadPolicy returned error: %v", err) } third, err := NewSettingsService(upload.DB(), config.SettingsDefaults{ AnonymousUploadsEnabled: true, AnonymousMaxUploadMB: 999, AnonymousDailyUploadMB: 999, UserDailyUploadMB: 999, DefaultUserStorageMB: 999, UsageRetentionDays: 30, }) if err != nil { t.Fatalf("NewSettingsService third returned error: %v", err) } thirdPolicy, err := third.UploadPolicy() if err != nil { t.Fatalf("UploadPolicy third returned error: %v", err) } if thirdPolicy.AnonymousMaxUploadMB != 555 { t.Fatalf("third AnonymousMaxUploadMB = %v, want persisted 555", thirdPolicy.AnonymousMaxUploadMB) } } func TestSettingsRejectInvalidMegabytes(t *testing.T) { if _, err := ParseMegabytesValue("0"); err == nil { t.Fatalf("ParseMegabytesValue accepted zero") } settings := newTestSettingsService(t) policy, err := settings.UploadPolicy() if err != nil { t.Fatalf("UploadPolicy returned error: %v", err) } policy.DefaultUserStorageMB = -1 if err := settings.UpdateUploadPolicy(policy); err == nil { t.Fatalf("UpdateUploadPolicy accepted negative storage") } } func TestDailyUsageAndCleanup(t *testing.T) { settings := newTestSettingsService(t) now := time.Date(2026, 5, 30, 12, 0, 0, 0, time.UTC) if err := settings.AddUsage("ip", "127.0.0.1", 1024, now); err != nil { t.Fatalf("AddUsage returned error: %v", err) } if err := settings.AddUsage("ip", "127.0.0.1", 2048, now); err != nil { t.Fatalf("AddUsage returned error: %v", err) } usage, err := settings.UsageForIP("127.0.0.1", now) if err != nil { t.Fatalf("UsageForIP returned error: %v", err) } if usage.UploadedBytes != 3072 { t.Fatalf("UploadedBytes = %d, want 3072", usage.UploadedBytes) } if err := settings.CleanupUsage(now.AddDate(0, 0, 31), 30); err != nil { t.Fatalf("CleanupUsage returned error: %v", err) } usage, err = settings.UsageForIP("127.0.0.1", now) if err != nil { t.Fatalf("UsageForIP returned error: %v", err) } if usage.UploadedBytes != 0 { t.Fatalf("UploadedBytes after cleanup = %d, want 0", usage.UploadedBytes) } } func newTestSettingsService(t *testing.T) *SettingsService { t.Helper() root := t.TempDir() upload, err := NewUploadService(1024*1024, filepath.Join(root, "data"), "http://example.test", slog.Default()) if err != nil { t.Fatalf("NewUploadService returned error: %v", err) } t.Cleanup(func() { if err := upload.Close(); err != nil { t.Fatalf("Close returned error: %v", err) } }) settings, err := NewSettingsService(upload.DB(), config.SettingsDefaults{ AnonymousUploadsEnabled: true, AnonymousMaxUploadMB: 512, AnonymousDailyUploadMB: 2048, UserDailyUploadMB: 8192, DefaultUserStorageMB: 51200, UsageRetentionDays: 30, }) if err != nil { t.Fatalf("NewSettingsService returned error: %v", err) } return settings }