updated layout for webmail and added http dns letsencrypt
This commit is contained in:
@@ -80,16 +80,17 @@ func TestWebmailFolderUnreadBadges(t *testing.T) {
|
||||
return rec.Body.String()
|
||||
}
|
||||
|
||||
if !strings.Contains(get(), `folder-unread-badge">1<`) {
|
||||
t.Fatalf("expected an unread badge showing 1, got: %s", get())
|
||||
if !strings.Contains(get(), `folder-unread-badge" title="1 total, 1 unread">1 / <strong>1</strong><`) {
|
||||
t.Fatalf("expected a badge showing 1 total / 1 unread, 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")
|
||||
// Still 1 total message, but no longer unread — the "/ N unread" part should be gone.
|
||||
if !strings.Contains(get(), `folder-unread-badge" title="1 total">1<`) {
|
||||
t.Fatalf("expected the badge to show just the total (1) with no unread suffix, got: %s", get())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,6 +102,9 @@ func TestWebmailFolderGroupsConsecutiveSameSubject(t *testing.T) {
|
||||
mux := app.Mux()
|
||||
domains, _ := app.DB.ListDomains()
|
||||
mailboxID := createTestMailboxWithPassword(t, app, "grouper@example.com", domains[0].ID, "grouper-password-1!")
|
||||
if err := app.DB.SetMailboxGroupMessages(mailboxID, true); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cookie := webmailLoginSession(t, app, mailboxID)
|
||||
|
||||
storeTestMessage(t, app, mailboxID, "INBOX", "a@example.com", "Project status", "1")
|
||||
@@ -119,3 +123,211 @@ func TestWebmailFolderGroupsConsecutiveSameSubject(t *testing.T) {
|
||||
t.Fatal("expected the older grouped row hidden by default via msg-row-older")
|
||||
}
|
||||
}
|
||||
|
||||
// TestWebmailFolderGroupingOffByDefault confirms grouping is off unless a mailbox
|
||||
// owner explicitly enables it via Account > Preferences — same three messages as
|
||||
// TestWebmailFolderGroupsConsecutiveSameSubject, but no toggle call this time.
|
||||
func TestWebmailFolderGroupingOffByDefault(t *testing.T) {
|
||||
app := newTestApp(t)
|
||||
mux := app.Mux()
|
||||
domains, _ := app.DB.ListDomains()
|
||||
mailboxID := createTestMailboxWithPassword(t, app, "nogroup@example.com", domains[0].ID, "nogroup-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")
|
||||
|
||||
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, "+1 more") {
|
||||
t.Fatal("expected no grouping by default")
|
||||
}
|
||||
|
||||
// Enabling it via the Account > Preferences form flips the behavior live.
|
||||
prefReq := httptest.NewRequest(http.MethodPost, MailboxPrefix+"/account/preferences", strings.NewReader("group_messages=true"))
|
||||
prefReq.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
prefReq.AddCookie(cookie)
|
||||
prefRec := httptest.NewRecorder()
|
||||
mux.ServeHTTP(prefRec, prefReq)
|
||||
if prefRec.Code != http.StatusFound {
|
||||
t.Fatalf("preferences save: status=%d body=%s", prefRec.Code, prefRec.Body.String())
|
||||
}
|
||||
|
||||
req2 := httptest.NewRequest(http.MethodGet, MailboxPrefix+"/mail/INBOX", nil)
|
||||
req2.AddCookie(cookie)
|
||||
rec2 := httptest.NewRecorder()
|
||||
mux.ServeHTTP(rec2, req2)
|
||||
if !strings.Contains(rec2.Body.String(), "+1 more") {
|
||||
t.Fatal("expected grouping enabled after saving the preference")
|
||||
}
|
||||
}
|
||||
|
||||
// TestWebmailFolderShowsSenderDisplayName confirms the folder list shows just the
|
||||
// display name from a "Name <addr>" cached_from value, not the raw address string,
|
||||
// while keeping the full address available via the row's title attribute.
|
||||
func TestWebmailFolderShowsSenderDisplayName(t *testing.T) {
|
||||
app := newTestApp(t)
|
||||
mux := app.Mux()
|
||||
domains, _ := app.DB.ListDomains()
|
||||
mailboxID := createTestMailboxWithPassword(t, app, "namedisplay@example.com", domains[0].ID, "namedisplay-password-1!")
|
||||
cookie := webmailLoginSession(t, app, mailboxID)
|
||||
|
||||
storeTestMessage(t, app, mailboxID, "INBOX", "Bob Marley <bob@example.com>", "One love", "body")
|
||||
|
||||
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, `title="Bob Marley <bob@example.com>"`) {
|
||||
t.Errorf("expected the full address in the title attribute, got:\n%s", body)
|
||||
}
|
||||
if !strings.Contains(body, ">Bob Marley<") {
|
||||
t.Errorf("expected just the display name shown in the row, got:\n%s", body)
|
||||
}
|
||||
}
|
||||
|
||||
// TestWebmailFolderUnreadOnlyFilter confirms ?unread=1 hides read messages.
|
||||
func TestWebmailFolderUnreadOnlyFilter(t *testing.T) {
|
||||
app := newTestApp(t)
|
||||
mux := app.Mux()
|
||||
domains, _ := app.DB.ListDomains()
|
||||
mailboxID := createTestMailboxWithPassword(t, app, "unreadfilter@example.com", domains[0].ID, "unreadfilter-password-1!")
|
||||
cookie := webmailLoginSession(t, app, mailboxID)
|
||||
|
||||
storeTestMessage(t, app, mailboxID, "INBOX", "a@example.com", "Unread one", "body")
|
||||
readUID := storeTestMessage(t, app, mailboxID, "INBOX", "b@example.com", "Already read", "body")
|
||||
if err := app.DB.SetMessageFlags(mailboxID, readUID, `\Seen`); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
get := func(path string) string {
|
||||
req := httptest.NewRequest(http.MethodGet, path, nil)
|
||||
req.AddCookie(cookie)
|
||||
rec := httptest.NewRecorder()
|
||||
mux.ServeHTTP(rec, req)
|
||||
return rec.Body.String()
|
||||
}
|
||||
|
||||
all := get(MailboxPrefix + "/mail/INBOX")
|
||||
if !strings.Contains(all, "Unread one") || !strings.Contains(all, "Already read") {
|
||||
t.Fatalf("expected both messages without the filter, got:\n%s", all)
|
||||
}
|
||||
|
||||
unreadOnly := get(MailboxPrefix + "/mail/INBOX?unread=1")
|
||||
if !strings.Contains(unreadOnly, "Unread one") {
|
||||
t.Error("expected the unread message still shown")
|
||||
}
|
||||
if strings.Contains(unreadOnly, "Already read") {
|
||||
t.Errorf("expected the read message hidden with ?unread=1, got:\n%s", unreadOnly)
|
||||
}
|
||||
}
|
||||
|
||||
// TestWebmailFolderSortByFrom confirms ?sort=from&dir=asc orders the list by sender
|
||||
// instead of the default received-order.
|
||||
func TestWebmailFolderSortByFrom(t *testing.T) {
|
||||
app := newTestApp(t)
|
||||
mux := app.Mux()
|
||||
domains, _ := app.DB.ListDomains()
|
||||
mailboxID := createTestMailboxWithPassword(t, app, "sortfrom@example.com", domains[0].ID, "sortfrom-password-1!")
|
||||
cookie := webmailLoginSession(t, app, mailboxID)
|
||||
|
||||
storeTestMessage(t, app, mailboxID, "INBOX", "zzz@example.com", "From Z", "body")
|
||||
storeTestMessage(t, app, mailboxID, "INBOX", "aaa@example.com", "From A", "body")
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, MailboxPrefix+"/mail/INBOX?sort=from&dir=asc", nil)
|
||||
req.AddCookie(cookie)
|
||||
rec := httptest.NewRecorder()
|
||||
mux.ServeHTTP(rec, req)
|
||||
body := rec.Body.String()
|
||||
|
||||
idxA := strings.Index(body, "From A")
|
||||
idxZ := strings.Index(body, "From Z")
|
||||
if idxA < 0 || idxZ < 0 || idxA > idxZ {
|
||||
t.Fatalf("expected 'From A' (aaa@) before 'From Z' (zzz@) when sorted by sender ascending, got:\n%s", body)
|
||||
}
|
||||
}
|
||||
|
||||
// TestWebmailFolderHasCollapsibleSidebarMarkup is a light smoke test for the
|
||||
// collapsible-sidebar feature's markup/JS anchors — the actual show/hide behavior is
|
||||
// client-side (localStorage-backed) and not exercisable from a Go test, but a missing
|
||||
// element ID here would silently break the JS with no visible error.
|
||||
func TestWebmailFolderHasCollapsibleSidebarMarkup(t *testing.T) {
|
||||
app := newTestApp(t)
|
||||
mux := app.Mux()
|
||||
domains, _ := app.DB.ListDomains()
|
||||
mailboxID := createTestMailboxWithPassword(t, app, "sidebartest@example.com", domains[0].ID, "sidebartest-password-1!")
|
||||
cookie := webmailLoginSession(t, app, mailboxID)
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, MailboxPrefix+"/mail/INBOX", nil)
|
||||
req.AddCookie(cookie)
|
||||
rec := httptest.NewRecorder()
|
||||
mux.ServeHTTP(rec, req)
|
||||
body := rec.Body.String()
|
||||
|
||||
for _, id := range []string{`id="folderSidebarCol"`, `id="messageListCol"`, `id="sidebarCollapseBtn"`, `id="sidebarShowBtn"`, "webmail_sidebar_collapsed"} {
|
||||
if !strings.Contains(body, id) {
|
||||
t.Errorf("expected %q present in the rendered page", id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestWebmailFolderShowsMessagePreview confirms the folder list shows a short preview
|
||||
// snippet of the message body under the subject.
|
||||
func TestWebmailFolderShowsMessagePreview(t *testing.T) {
|
||||
app := newTestApp(t)
|
||||
mux := app.Mux()
|
||||
domains, _ := app.DB.ListDomains()
|
||||
mailboxID := createTestMailboxWithPassword(t, app, "previewtest@example.com", domains[0].ID, "previewtest-password-1!")
|
||||
cookie := webmailLoginSession(t, app, mailboxID)
|
||||
|
||||
storeTestMessage(t, app, mailboxID, "INBOX", "a@example.com", "Meeting notes", "Here is a summary of what we discussed today in the meeting.")
|
||||
|
||||
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-row2") || !strings.Contains(body, "Here is a summary") {
|
||||
t.Errorf("expected the message preview snippet rendered, got:\n%s", body)
|
||||
}
|
||||
}
|
||||
|
||||
// TestWebmailRebuildMessageCache confirms the Account > Preferences "Refresh now"
|
||||
// action re-derives an already-stored message's sender display name from its raw
|
||||
// content, for mail that predates the fix that started caching it.
|
||||
func TestWebmailRebuildMessageCache(t *testing.T) {
|
||||
app := newTestApp(t)
|
||||
mux := app.Mux()
|
||||
domains, _ := app.DB.ListDomains()
|
||||
mailboxID := createTestMailboxWithPassword(t, app, "rebuildtest@example.com", domains[0].ID, "rebuildtest-password-1!")
|
||||
cookie := webmailLoginSession(t, app, mailboxID)
|
||||
|
||||
// Simulate a stale row: the raw content has the display name, but cached_from was
|
||||
// stored as the bare address (what pre-fix code would have passed).
|
||||
raw := "From: Bob Marley <bob@example.com>\r\nTo: rebuildtest@example.com\r\nSubject: One love\r\n\r\nHello there"
|
||||
if _, err := app.Mailstore.StoreMessage(mailboxID, "INBOX", []byte(raw), "<one@example.com>", "bob@example.com", "One love"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
req := httptest.NewRequest(http.MethodPost, MailboxPrefix+"/account/rebuild-cache", nil)
|
||||
req.AddCookie(cookie)
|
||||
rec := httptest.NewRecorder()
|
||||
mux.ServeHTTP(rec, req)
|
||||
if rec.Code != http.StatusFound {
|
||||
t.Fatalf("rebuild-cache: status=%d body=%s", rec.Code, rec.Body.String())
|
||||
}
|
||||
|
||||
folderReq := httptest.NewRequest(http.MethodGet, MailboxPrefix+"/mail/INBOX", nil)
|
||||
folderReq.AddCookie(cookie)
|
||||
folderRec := httptest.NewRecorder()
|
||||
mux.ServeHTTP(folderRec, folderReq)
|
||||
if !strings.Contains(folderRec.Body.String(), ">Bob Marley<") {
|
||||
t.Errorf("expected the display name shown after rebuild, got:\n%s", folderRec.Body.String())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user