package metastore import ( "errors" "testing" "time" "warpbox/lib/config" ) func TestOpenClose(t *testing.T) { store, err := Open(t.TempDir()) if err != nil { t.Fatalf("Open returned error: %v", err) } if err := store.Close(); err != nil { t.Fatalf("Close returned error: %v", err) } } func TestBootstrapAdminFromPassword(t *testing.T) { clearMetastoreConfigEnv(t) t.Setenv("WARPBOX_ADMIN_PASSWORD", "secret-pass") t.Setenv("WARPBOX_ADMIN_EMAIL", "admin@example.test") cfg, err := config.Load() if err != nil { t.Fatalf("Load returned error: %v", err) } store := openTestStore(t) result, err := BootstrapAdmin(cfg, store) if err != nil { t.Fatalf("BootstrapAdmin returned error: %v", err) } if !result.AdminLoginEnabled { t.Fatal("expected admin login to be enabled") } if !result.AdminTag.Protected { t.Fatal("expected admin tag to be protected") } if result.AdminUser == nil { t.Fatal("expected bootstrap admin user") } if !hasString(result.AdminUser.TagIDs, result.AdminTag.ID) { t.Fatal("expected bootstrap admin to have admin tag") } if !VerifyPassword(result.AdminUser.PasswordHash, "secret-pass") { t.Fatal("expected bootstrap admin password to verify") } } func TestBootstrapAdminDisabledWithoutPassword(t *testing.T) { clearMetastoreConfigEnv(t) cfg, err := config.Load() if err != nil { t.Fatalf("Load returned error: %v", err) } store := openTestStore(t) result, err := BootstrapAdmin(cfg, store) if err != nil { t.Fatalf("BootstrapAdmin returned error: %v", err) } if result.AdminLoginEnabled { t.Fatal("expected admin login to be disabled without password or existing admin") } if !result.AdminTag.Protected { t.Fatal("expected admin tag to still be created") } users, err := store.ListUsers() if err != nil { t.Fatalf("ListUsers returned error: %v", err) } if len(users) != 0 { t.Fatalf("expected no users, got %d", len(users)) } } func TestDuplicateUsersAndTags(t *testing.T) { store := openTestStore(t) if _, err := store.CreateUserWithPassword("alex", "alex@example.test", "secret", nil); err != nil { t.Fatalf("CreateUserWithPassword returned error: %v", err) } if _, err := store.CreateUserWithPassword("Alex", "other@example.test", "secret", nil); !errors.Is(err, ErrDuplicate) { t.Fatalf("expected duplicate username error, got %v", err) } if _, err := store.CreateUserWithPassword("other", "alex@example.test", "secret", nil); !errors.Is(err, ErrDuplicate) { t.Fatalf("expected duplicate email error, got %v", err) } tag := Tag{Name: "staff"} if err := store.CreateTag(&tag); err != nil { t.Fatalf("CreateTag returned error: %v", err) } duplicate := Tag{Name: "Staff"} if err := store.CreateTag(&duplicate); !errors.Is(err, ErrDuplicate) { t.Fatalf("expected duplicate tag error, got %v", err) } } func TestPermissionResolutionAndGlobalCaps(t *testing.T) { clearMetastoreConfigEnv(t) t.Setenv("WARPBOX_DEFAULT_USER_MAX_FILE_SIZE_BYTES", "50") t.Setenv("WARPBOX_GLOBAL_MAX_FILE_SIZE_BYTES", "100") t.Setenv("WARPBOX_GLOBAL_MAX_BOX_SIZE_BYTES", "1000") cfg, err := config.Load() if err != nil { t.Fatalf("Load returned error: %v", err) } tagFileLimit := int64(80) tagBoxLimit := int64(2000) userFileLimit := int64(60) user := User{MaxFileSizeBytes: &userFileLimit} tags := []Tag{ { Permissions: TagPermissions{ UploadAllowed: true, AllowedExpirySeconds: []int64{3600, 600}, MaxFileSizeBytes: &tagFileLimit, MaxBoxSizeBytes: &tagBoxLimit, ZipDownloadAllowed: true, }, }, } perms := ResolveUserPermissions(cfg, user, tags) if !perms.UploadAllowed || !perms.ZipDownloadAllowed { t.Fatal("expected tag booleans to grant permissions") } if perms.MaxFileSizeBytes != 80 { t.Fatalf("expected tag limit to beat user/default limit, got %d", perms.MaxFileSizeBytes) } if perms.MaxBoxSizeBytes != 1000 { t.Fatalf("expected global max box cap, got %d", perms.MaxBoxSizeBytes) } if len(perms.AllowedExpirySeconds) != 2 || perms.AllowedExpirySeconds[0] != 600 || perms.AllowedExpirySeconds[1] != 3600 { t.Fatalf("unexpected expiry durations: %#v", perms.AllowedExpirySeconds) } } func TestSettingsStorageAndPrecedence(t *testing.T) { clearMetastoreConfigEnv(t) t.Setenv("WARPBOX_API_ENABLED", "true") store := openTestStore(t) if err := store.SetSetting(config.SettingAPIEnabled, "false"); err != nil { t.Fatalf("SetSetting returned error: %v", err) } overrides, err := store.ListSettings() if err != nil { t.Fatalf("ListSettings returned error: %v", err) } cfg, err := config.Load() if err != nil { t.Fatalf("Load returned error: %v", err) } if err := cfg.ApplyOverrides(overrides); err != nil { t.Fatalf("ApplyOverrides returned error: %v", err) } if cfg.APIEnabled { t.Fatal("expected stored DB override to beat env") } } func TestSessionExpiry(t *testing.T) { store := openTestStore(t) session, err := store.CreateSession("user-id", time.Millisecond) if err != nil { t.Fatalf("CreateSession returned error: %v", err) } time.Sleep(2 * time.Millisecond) if _, ok, err := store.GetSession(session.Token); err != nil || ok { t.Fatalf("expected expired session to be invalid, ok=%v err=%v", ok, err) } } func openTestStore(t *testing.T) *Store { t.Helper() store, err := Open(t.TempDir()) if err != nil { t.Fatalf("Open returned error: %v", err) } t.Cleanup(func() { _ = store.Close() }) return store } func clearMetastoreConfigEnv(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_RENEW_ON_ACCESS_ENABLED", "WARPBOX_RENEW_ON_DOWNLOAD_ENABLED", "WARPBOX_DEFAULT_GUEST_EXPIRY_SECONDS", "WARPBOX_MAX_GUEST_EXPIRY_SECONDS", "WARPBOX_GLOBAL_MAX_FILE_SIZE_BYTES", "WARPBOX_GLOBAL_MAX_BOX_SIZE_BYTES", "WARPBOX_DEFAULT_USER_MAX_FILE_SIZE_BYTES", "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, "") } }