Files
warpbox-dev/backend/libs/services/upload_test.go
Daniel Legt d77f164900
All checks were successful
Build and Publish Docker Image / deploy (push) Successful in 1m8s
feat: add upload policies, daily limits, and storage quotas
- Add environment variables to configure anonymous uploads, daily upload caps, and default user storage limits.
- Update config loader to parse and validate the new settings.
- Implement backend logic to track daily usage and active storage per user.
- Update README and `.env.example` to document the new settings and admin panels.
2026-05-30 17:23:20 +03:00

159 lines
4.8 KiB
Go

package services
import (
"bytes"
"io"
"log/slog"
"mime/multipart"
"net/http/httptest"
"os"
"path/filepath"
"strings"
"testing"
"time"
)
func TestDeleteTokenVerification(t *testing.T) {
service := newTestUploadService(t)
result := createTestBox(t, service, "file.txt", "hello")
box := getTestBox(t, service, result.BoxID)
token := tokenFromManageURL(t, result.ManageURL)
if box.DeleteTokenHash == "" {
t.Fatalf("DeleteTokenHash was not stored")
}
if strings.Contains(box.DeleteTokenHash, token) {
t.Fatalf("DeleteTokenHash contains the raw token")
}
if !service.VerifyDeleteToken(box, token) {
t.Fatalf("VerifyDeleteToken rejected the correct token")
}
if service.VerifyDeleteToken(box, "wrong-token") {
t.Fatalf("VerifyDeleteToken accepted the wrong token")
}
}
func TestDeleteBoxWithTokenRemovesMetadataAndFiles(t *testing.T) {
service := newTestUploadService(t)
result := createTestBox(t, service, "file.txt", "hello")
box := getTestBox(t, service, result.BoxID)
token := tokenFromManageURL(t, result.ManageURL)
if _, err := os.Stat(filepath.Join(service.filesDir, box.ID)); err != nil {
t.Fatalf("box files were not created: %v", err)
}
if err := service.DeleteBoxWithToken(box.ID, "wrong-token"); err == nil {
t.Fatalf("DeleteBoxWithToken accepted the wrong token")
}
if _, err := service.GetBox(box.ID); err != nil {
t.Fatalf("box was deleted after wrong token: %v", err)
}
if err := service.DeleteBoxWithToken(box.ID, token); err != nil {
t.Fatalf("DeleteBoxWithToken returned error: %v", err)
}
if _, err := service.GetBox(box.ID); !os.IsNotExist(err) {
t.Fatalf("GetBox after delete error = %v, want os.ErrNotExist", err)
}
if _, err := os.Stat(filepath.Join(service.filesDir, box.ID)); !os.IsNotExist(err) {
t.Fatalf("box directory still exists after delete: %v", err)
}
}
func TestUserActiveStorageUsedIgnoresExpiredBoxes(t *testing.T) {
service := newTestUploadService(t)
active, err := service.CreateBox(testFileHeaders(t, "file", "active.txt", "active"), UploadOptions{MaxDays: 1, OwnerID: "user-1"})
if err != nil {
t.Fatalf("CreateBox active returned error: %v", err)
}
expired, err := service.CreateBox(testFileHeaders(t, "file", "expired.txt", "expired"), UploadOptions{MaxDays: 1, OwnerID: "user-1"})
if err != nil {
t.Fatalf("CreateBox expired returned error: %v", err)
}
expiredBox, err := service.GetBox(expired.BoxID)
if err != nil {
t.Fatalf("GetBox returned error: %v", err)
}
expiredBox.ExpiresAt = time.Now().UTC().Add(-time.Hour)
if err := service.SaveBox(expiredBox); err != nil {
t.Fatalf("SaveBox returned error: %v", err)
}
activeBox, err := service.GetBox(active.BoxID)
if err != nil {
t.Fatalf("GetBox active returned error: %v", err)
}
want := activeBox.Files[0].Size
got, err := service.UserActiveStorageUsed("user-1")
if err != nil {
t.Fatalf("UserActiveStorageUsed returned error: %v", err)
}
if got != want {
t.Fatalf("UserActiveStorageUsed = %d, want %d", got, want)
}
}
func newTestUploadService(t *testing.T) *UploadService {
t.Helper()
service, err := NewUploadService(1024*1024, t.TempDir(), "http://example.test", slog.New(slog.NewTextHandler(io.Discard, nil)))
if err != nil {
t.Fatalf("NewUploadService returned error: %v", err)
}
t.Cleanup(func() {
if err := service.Close(); err != nil {
t.Fatalf("Close returned error: %v", err)
}
})
return service
}
func createTestBox(t *testing.T, service *UploadService, filename, body string) UploadResult {
t.Helper()
result, err := service.CreateBox(testFileHeaders(t, "file", filename, body), UploadOptions{MaxDays: 1})
if err != nil {
t.Fatalf("CreateBox returned error: %v", err)
}
return result
}
func getTestBox(t *testing.T, service *UploadService, boxID string) Box {
t.Helper()
box, err := service.GetBox(boxID)
if err != nil {
t.Fatalf("GetBox returned error: %v", err)
}
return box
}
func testFileHeaders(t *testing.T, field, filename, body string) []*multipart.FileHeader {
t.Helper()
var payload bytes.Buffer
writer := multipart.NewWriter(&payload)
part, err := writer.CreateFormFile(field, filename)
if err != nil {
t.Fatalf("CreateFormFile returned error: %v", err)
}
if _, err := part.Write([]byte(body)); err != nil {
t.Fatalf("part.Write returned error: %v", err)
}
if err := writer.Close(); err != nil {
t.Fatalf("writer.Close returned error: %v", err)
}
request := httptest.NewRequest("POST", "/upload", &payload)
request.Header.Set("Content-Type", writer.FormDataContentType())
if err := request.ParseMultipartForm(1024 * 1024); err != nil {
t.Fatalf("ParseMultipartForm returned error: %v", err)
}
return request.MultipartForm.File[field]
}
func tokenFromManageURL(t *testing.T, manageURL string) string {
t.Helper()
parts := strings.Split(strings.TrimRight(manageURL, "/"), "/")
if len(parts) == 0 {
t.Fatalf("empty manage URL")
}
return parts[len(parts)-1]
}