122 lines
4.9 KiB
Go
122 lines
4.9 KiB
Go
package webui
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strconv"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func storeTestMessage(t *testing.T, app *App, mailboxID int64, folder, from, subject, body string) int64 {
|
|
t.Helper()
|
|
raw := "From: " + from + "\r\nTo: recipient@example.com\r\nSubject: " + subject + "\r\n\r\n" + body
|
|
uid, err := app.Mailstore.StoreMessage(mailboxID, folder, []byte(raw), subject+"@example.com", from, subject)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return uid
|
|
}
|
|
|
|
// TestWebmailSearchAcrossFolders confirms /mail/search finds messages by subject or
|
|
// sender across every folder, and that a query scoped to one folder (via
|
|
// webmailFolderView's own ?q=) only returns that folder's matches.
|
|
func TestWebmailSearchAcrossFolders(t *testing.T) {
|
|
app := newTestApp(t)
|
|
mux := app.Mux()
|
|
domains, _ := app.DB.ListDomains()
|
|
mailboxID := createTestMailboxWithPassword(t, app, "searcher@example.com", domains[0].ID, "searcher-password-1!")
|
|
cookie := webmailLoginSession(t, app, mailboxID)
|
|
|
|
storeTestMessage(t, app, mailboxID, "INBOX", "boss@example.com", "Quarterly report", "body one")
|
|
storeTestMessage(t, app, mailboxID, "Sent", "searcher@example.com", "Re: Quarterly report", "body two")
|
|
storeTestMessage(t, app, mailboxID, "INBOX", "someone@example.com", "totally unrelated", "body three")
|
|
|
|
req := httptest.NewRequest(http.MethodGet, MailboxPrefix+"/mail/search?q=quarterly", nil)
|
|
req.AddCookie(cookie)
|
|
rec := httptest.NewRecorder()
|
|
mux.ServeHTTP(rec, req)
|
|
if rec.Code != http.StatusOK {
|
|
t.Fatalf("search: status=%d", rec.Code)
|
|
}
|
|
body := rec.Body.String()
|
|
if !strings.Contains(body, "Quarterly report") || !strings.Contains(body, "Re: Quarterly report") {
|
|
t.Fatalf("expected both matching messages across folders, got: %s", body)
|
|
}
|
|
if strings.Contains(body, "totally unrelated") {
|
|
t.Fatal("expected the non-matching message excluded from search results")
|
|
}
|
|
|
|
// Scoped to one folder via the folder-view's own ?q= — Sent's match shouldn't appear.
|
|
scopedReq := httptest.NewRequest(http.MethodGet, MailboxPrefix+"/mail/INBOX?q=quarterly", nil)
|
|
scopedReq.AddCookie(cookie)
|
|
scopedRec := httptest.NewRecorder()
|
|
mux.ServeHTTP(scopedRec, scopedReq)
|
|
scopedBody := scopedRec.Body.String()
|
|
if !strings.Contains(scopedBody, "Quarterly report") {
|
|
t.Fatal("expected the INBOX match present when scoped to INBOX")
|
|
}
|
|
if strings.Contains(scopedBody, "Re: Quarterly report") {
|
|
t.Fatal("expected the Sent-folder match excluded when scoped to INBOX")
|
|
}
|
|
}
|
|
|
|
// TestWebmailFolderUnreadBadges confirms the sidebar shows a per-folder unread
|
|
// count, and that it drops once a message is actually read.
|
|
func TestWebmailFolderUnreadBadges(t *testing.T) {
|
|
app := newTestApp(t)
|
|
mux := app.Mux()
|
|
domains, _ := app.DB.ListDomains()
|
|
mailboxID := createTestMailboxWithPassword(t, app, "badges@example.com", domains[0].ID, "badges-password-1!")
|
|
cookie := webmailLoginSession(t, app, mailboxID)
|
|
|
|
uid := storeTestMessage(t, app, mailboxID, "INBOX", "someone@example.com", "unread me", "body")
|
|
|
|
get := func() string {
|
|
req := httptest.NewRequest(http.MethodGet, MailboxPrefix+"/mail/INBOX", nil)
|
|
req.AddCookie(cookie)
|
|
rec := httptest.NewRecorder()
|
|
mux.ServeHTTP(rec, req)
|
|
return rec.Body.String()
|
|
}
|
|
|
|
if !strings.Contains(get(), `folder-unread-badge">1<`) {
|
|
t.Fatalf("expected an unread badge showing 1, got: %s", get())
|
|
}
|
|
|
|
viewReq := httptest.NewRequest(http.MethodGet, MailboxPrefix+"/mail/INBOX/"+strconv.FormatInt(uid, 10), nil)
|
|
viewReq.AddCookie(cookie)
|
|
mux.ServeHTTP(httptest.NewRecorder(), viewReq)
|
|
|
|
if strings.Contains(get(), `folder-unread-badge">1<`) {
|
|
t.Fatal("expected the unread badge gone after reading the message")
|
|
}
|
|
}
|
|
|
|
// TestWebmailFolderGroupsConsecutiveSameSubject confirms a run of messages sharing
|
|
// a normalized subject (Re:/Fwd: stripped) collapses into one expandable row, while
|
|
// an intervening different-subject message breaks the run into separate groups.
|
|
func TestWebmailFolderGroupsConsecutiveSameSubject(t *testing.T) {
|
|
app := newTestApp(t)
|
|
mux := app.Mux()
|
|
domains, _ := app.DB.ListDomains()
|
|
mailboxID := createTestMailboxWithPassword(t, app, "grouper@example.com", domains[0].ID, "grouper-password-1!")
|
|
cookie := webmailLoginSession(t, app, mailboxID)
|
|
|
|
storeTestMessage(t, app, mailboxID, "INBOX", "a@example.com", "Project status", "1")
|
|
storeTestMessage(t, app, mailboxID, "INBOX", "b@example.com", "Re: Project status", "2")
|
|
storeTestMessage(t, app, mailboxID, "INBOX", "c@example.com", "unrelated", "3")
|
|
|
|
req := httptest.NewRequest(http.MethodGet, MailboxPrefix+"/mail/INBOX", nil)
|
|
req.AddCookie(cookie)
|
|
rec := httptest.NewRecorder()
|
|
mux.ServeHTTP(rec, req)
|
|
body := rec.Body.String()
|
|
if !strings.Contains(body, "msg-group-toggle") || !strings.Contains(body, "+1 more") {
|
|
t.Fatalf("expected the two 'Project status' messages grouped with a +1 more toggle, got: %s", body)
|
|
}
|
|
if !strings.Contains(body, "msg-row-older") {
|
|
t.Fatal("expected the older grouped row hidden by default via msg-row-older")
|
|
}
|
|
}
|