154 lines
5.6 KiB
Go
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))
|
|
}
|
|
}
|