package handlers import ( "encoding/json" "net/http" "net/http/httptest" "strings" "testing" "warpbox.dev/backend/libs/services" ) func TestLoggedInUploadStoresOwnerAndAnonymousUploadDoesNot(t *testing.T) { app, cleanup := newTestApp(t) defer cleanup() user, err := app.authService.CreateBootstrapUser("daniel", "daniel@example.test", "password123") if err != nil { t.Fatalf("CreateBootstrapUser returned error: %v", err) } _, token, err := app.authService.Login("daniel@example.test", "password123") if err != nil { t.Fatalf("Login returned error: %v", err) } request := multipartUploadRequest(t, "/api/v1/upload", "file", "owned.txt", "owned") request.Header.Set("Accept", "application/json") request.AddCookie(&http.Cookie{Name: userSessionCookieName, Value: token}) response := httptest.NewRecorder() app.Upload(response, request) if response.Code != http.StatusCreated { t.Fatalf("owned upload status = %d, body = %s", response.Code, response.Body.String()) } var ownedPayload services.UploadResult if err := json.Unmarshal(response.Body.Bytes(), &ownedPayload); err != nil { t.Fatalf("json.Unmarshal owned returned error: %v", err) } ownedBox, err := app.uploadService.GetBox(ownedPayload.BoxID) if err != nil { t.Fatalf("GetBox owned returned error: %v", err) } if ownedBox.OwnerID != user.ID { t.Fatalf("owned OwnerID = %q, want %q", ownedBox.OwnerID, user.ID) } owned := uploadThroughApp(t, app) anonymous, err := app.uploadService.GetBox(owned.BoxID) if err != nil { t.Fatalf("GetBox anonymous returned error: %v", err) } if anonymous.OwnerID != "" { t.Fatalf("anonymous OwnerID = %q, want empty", anonymous.OwnerID) } boxes, err := app.uploadService.ListBoxes(0) if err != nil { t.Fatalf("ListBoxes returned error: %v", err) } foundOwned := false for _, box := range boxes { if box.OwnerID == user.ID { foundOwned = true } } if !foundOwned { t.Fatalf("logged-in upload did not store owner id %q", user.ID) } } func TestInviteHandlerCreatesUserAndMarksInviteUsed(t *testing.T) { app, cleanup := newTestApp(t) defer cleanup() admin, err := app.authService.CreateBootstrapUser("admin", "admin@example.test", "password123") if err != nil { t.Fatalf("CreateBootstrapUser returned error: %v", err) } invite, err := app.authService.CreateInvite("friend@example.test", services.UserRoleUser, admin.ID, 0) if err != nil { t.Fatalf("CreateInvite returned error: %v", err) } request := httptest.NewRequest(http.MethodPost, "/invite/"+invite.Token, strings.NewReader("username=friend&password=password123")) request.Header.Set("Content-Type", "application/x-www-form-urlencoded") request.SetPathValue("token", invite.Token) response := httptest.NewRecorder() app.InvitePost(response, request) if response.Code != http.StatusSeeOther { t.Fatalf("InvitePost status = %d, body = %s", response.Code, response.Body.String()) } if _, err := app.authService.AcceptInvite(invite.Token, "friend", "password123"); err == nil { t.Fatalf("invite token remained reusable") } } func TestNonOwnerCannotManageOwnedBox(t *testing.T) { app, cleanup := newTestApp(t) defer cleanup() owner, err := app.authService.CreateBootstrapUser("owner", "owner@example.test", "password123") if err != nil { t.Fatalf("CreateBootstrapUser returned error: %v", err) } invite, err := app.authService.CreateInvite("other@example.test", services.UserRoleUser, owner.ID, 0) if err != nil { t.Fatalf("CreateInvite returned error: %v", err) } other, err := app.authService.AcceptInvite(invite.Token, "other", "password123") if err != nil { t.Fatalf("AcceptInvite returned error: %v", err) } result := createOwnedBoxThroughApp(t, app, owner.ID) if err := app.uploadService.RenameOwnedBox(result.BoxID, other.ID, "stolen"); err == nil { t.Fatalf("RenameOwnedBox allowed non-owner") } } func TestAdminUploadBypassesMaxUploadSize(t *testing.T) { app, cleanup := newTestApp(t) defer cleanup() _, err := app.authService.CreateBootstrapUser("admin", "admin@example.test", "password123") if err != nil { t.Fatalf("CreateBootstrapUser returned error: %v", err) } _, token, err := app.authService.Login("admin@example.test", "password123") if err != nil { t.Fatalf("Login returned error: %v", err) } request := multipartUploadRequest(t, "/api/v1/upload", "file", "large.txt", strings.Repeat("x", int(app.uploadService.MaxUploadSize())+1)) request.Header.Set("Accept", "application/json") request.AddCookie(&http.Cookie{Name: userSessionCookieName, Value: token}) response := httptest.NewRecorder() app.Upload(response, request) if response.Code != http.StatusCreated { t.Fatalf("admin upload status = %d, body = %s", response.Code, response.Body.String()) } } func createOwnedBoxThroughApp(t *testing.T, app *App, userID string) services.UploadResult { t.Helper() user, err := app.authService.UserByID(userID) if err != nil { t.Fatalf("UserByID returned error: %v", err) } _, token, err := app.authService.Login(user.Email, "password123") if err != nil { t.Fatalf("Login returned error: %v", err) } request := multipartUploadRequest(t, "/api/v1/upload", "file", "owned.txt", "owned") request.Header.Set("Accept", "application/json") request.AddCookie(&http.Cookie{Name: userSessionCookieName, Value: token}) response := httptest.NewRecorder() app.Upload(response, request) if response.Code != http.StatusCreated { t.Fatalf("upload status = %d, body = %s", response.Code, response.Body.String()) } var payload services.UploadResult if err := json.Unmarshal(response.Body.Bytes(), &payload); err != nil { t.Fatalf("json.Unmarshal returned error: %v", err) } return payload }