Files
mailgoserver/internal/webui/webmail_pane_bulk_test.go
T

154 lines
5.6 KiB
Go

package webui
import (
"net/http"
"net/http/httptest"
"net/url"
"strconv"
"strings"
"testing"
)
// TestWebmailMessagePaneMarksReadAndReturnsFragment confirms the Outlook-style reading
// pane's fetch endpoint returns a bare fragment (no dashboard chrome) containing the
// message body, and marks the message read just like opening the full page does.
func TestWebmailMessagePaneMarksReadAndReturnsFragment(t *testing.T) {
app := newTestApp(t)
mux := app.Mux()
domains, _ := app.DB.ListDomains()
mailboxID := createTestMailboxWithPassword(t, app, "panetest@example.com", domains[0].ID, "panetest-password-1!")
cookie := webmailLoginSession(t, app, mailboxID)
uid := storeTestMessage(t, app, mailboxID, "INBOX", "a@example.com", "Pane test", "the body of the message")
req := httptest.NewRequest(http.MethodGet, MailboxPrefix+"/mail/INBOX/"+strconv.FormatInt(uid, 10)+"/pane", nil)
req.AddCookie(cookie)
rec := httptest.NewRecorder()
mux.ServeHTTP(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("expected 200, got %d: %s", rec.Code, rec.Body.String())
}
body := rec.Body.String()
if !strings.Contains(body, "the body of the message") {
t.Errorf("expected the message body in the fragment, got:\n%s", body)
}
if strings.Contains(body, "<!DOCTYPE") || strings.Contains(body, "navbar-brand") {
t.Errorf("expected a bare fragment with no page chrome, got:\n%s", body)
}
msg, err := app.DB.GetMessageByUID(mailboxID, uid)
if err != nil {
t.Fatal(err)
}
if isUnread(msg.Flags) {
t.Error("expected the message marked read after loading it in the pane")
}
}
// TestWebmailBulkActionDeleteAndMarkRead confirms the folder view's bulk toolbar
// (multi-select checkboxes -> POST .../bulk) can delete-to-Trash and mark-read/unread
// several messages in one request.
func TestWebmailBulkActionDeleteAndMarkRead(t *testing.T) {
app := newTestApp(t)
mux := app.Mux()
domains, _ := app.DB.ListDomains()
mailboxID := createTestMailboxWithPassword(t, app, "bulktest@example.com", domains[0].ID, "bulktest-password-1!")
cookie := webmailLoginSession(t, app, mailboxID)
uid1 := storeTestMessage(t, app, mailboxID, "INBOX", "a@example.com", "One", "body1")
uid2 := storeTestMessage(t, app, mailboxID, "INBOX", "b@example.com", "Two", "body2")
uid3 := storeTestMessage(t, app, mailboxID, "INBOX", "c@example.com", "Three", "body3")
post := func(action string, uids ...int64) *httptest.ResponseRecorder {
form := url.Values{"action": {action}}
for _, u := range uids {
form.Add("uid", strconv.FormatInt(u, 10))
}
req := httptest.NewRequest(http.MethodPost, MailboxPrefix+"/mail/INBOX/bulk", strings.NewReader(form.Encode()))
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.AddCookie(cookie)
rec := httptest.NewRecorder()
mux.ServeHTTP(rec, req)
return rec
}
// Mark uid1 and uid2 read in one bulk request.
if rec := post("read", uid1, uid2); rec.Code != http.StatusFound {
t.Fatalf("bulk read: status=%d body=%s", rec.Code, rec.Body.String())
}
for _, uid := range []int64{uid1, uid2} {
msg, err := app.DB.GetMessageByUID(mailboxID, uid)
if err != nil {
t.Fatal(err)
}
if isUnread(msg.Flags) {
t.Errorf("expected message %d marked read", uid)
}
}
msg3, err := app.DB.GetMessageByUID(mailboxID, uid3)
if err != nil {
t.Fatal(err)
}
if !isUnread(msg3.Flags) {
t.Error("expected message 3 (not in the bulk request) to remain unread")
}
// Bulk-delete uid1 and uid3 (uid2 stays in INBOX).
if rec := post("delete", uid1, uid3); rec.Code != http.StatusFound {
t.Fatalf("bulk delete: status=%d body=%s", rec.Code, rec.Body.String())
}
inbox, err := app.DB.ListMessagesInFolder(mailboxID, "INBOX")
if err != nil {
t.Fatal(err)
}
if len(inbox) != 1 || inbox[0].ID != uid2 {
t.Fatalf("expected only message 2 left in INBOX, got %+v", inbox)
}
trash, err := app.DB.ListMessagesInFolder(mailboxID, "Trash")
if err != nil {
t.Fatal(err)
}
if len(trash) != 2 {
t.Fatalf("expected 2 messages in Trash, got %d", len(trash))
}
}
// TestWebmailBulkActionSkipsUIDFromAnotherFolder confirms a uid that doesn't actually
// belong to the requested folder is silently skipped rather than aborting the whole
// batch or letting a stale/mismatched selection touch the wrong message.
func TestWebmailBulkActionSkipsUIDFromAnotherFolder(t *testing.T) {
app := newTestApp(t)
mux := app.Mux()
domains, _ := app.DB.ListDomains()
mailboxID := createTestMailboxWithPassword(t, app, "bulkskiptest@example.com", domains[0].ID, "bulkskiptest-password-1!")
cookie := webmailLoginSession(t, app, mailboxID)
inboxUID := storeTestMessage(t, app, mailboxID, "INBOX", "a@example.com", "In inbox", "body")
sentUID := storeTestMessage(t, app, mailboxID, "Sent", "b@example.com", "In sent", "body")
form := url.Values{"action": {"delete"}, "uid": {strconv.FormatInt(inboxUID, 10), strconv.FormatInt(sentUID, 10)}}
req := httptest.NewRequest(http.MethodPost, MailboxPrefix+"/mail/INBOX/bulk", strings.NewReader(form.Encode()))
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.AddCookie(cookie)
rec := httptest.NewRecorder()
mux.ServeHTTP(rec, req)
if rec.Code != http.StatusFound {
t.Fatalf("status=%d body=%s", rec.Code, rec.Body.String())
}
sent, err := app.DB.ListMessagesInFolder(mailboxID, "Sent")
if err != nil {
t.Fatal(err)
}
if len(sent) != 1 {
t.Fatalf("expected the Sent message untouched (wrong folder for this bulk request), got %d left", len(sent))
}
trash, err := app.DB.ListMessagesInFolder(mailboxID, "Trash")
if err != nil {
t.Fatal(err)
}
if len(trash) != 1 {
t.Fatalf("expected the INBOX message moved to Trash, got %d in Trash", len(trash))
}
}