updated layout for webmail

This commit is contained in:
2026-08-15 16:31:27 +01:00
parent f283c90f11
commit 6f0c305367
35 changed files with 2660 additions and 219 deletions
+87
View File
@@ -451,6 +451,93 @@ func TestWebmailComposeReplyPrefill(t *testing.T) {
}
}
// extractSeed pulls out #body_html_seed's own content from a rendered compose page —
// the seed div can itself contain a nested <div> (a signature's wrapper), so its end
// is located via the exact markup immediately following the seed div's closing tag in
// webmail_compose.html, not just "the next </div>" (which would match the nested one).
func extractSeed(t *testing.T, page string) string {
t.Helper()
const openMarker = `id="body_html_seed" style="display: none;">`
const closeMarker = "</div>\n </form>"
start := strings.Index(page, openMarker)
if start < 0 {
t.Fatal("body_html_seed not found in rendered page")
}
start += len(openMarker)
end := strings.Index(page[start:], closeMarker)
if end < 0 {
t.Fatal("body_html_seed's closing markup not found in rendered page")
}
return page[start : start+end]
}
// TestWebmailComposeDefaultSignatureInsertion confirms a mailbox's default-for-new
// signature is auto-inserted into a brand-new compose, and its (possibly different)
// default-for-reply signature is auto-inserted into a reply — both above the quoted
// original, matching where a real signature belongs.
func TestWebmailComposeDefaultSignatureInsertion(t *testing.T) {
app := newTestApp(t)
mux := app.Mux()
domains, _ := app.DB.ListDomains()
mailboxID := createTestMailboxWithPassword(t, app, "sigcompose@example.com", domains[0].ID, "sigcompose-password-1!")
cookie := webmailLoginSession(t, app, mailboxID)
newSigID, err := app.DB.CreateSignature(mailboxID, "New", "<p>Sent from my desk</p>")
if err != nil {
t.Fatal(err)
}
replySigID, err := app.DB.CreateSignature(mailboxID, "Reply", "<p>Sent on the go</p>")
if err != nil {
t.Fatal(err)
}
if err := app.DB.SetDefaultSignature(mailboxID, newSigID, false); err != nil {
t.Fatal(err)
}
if err := app.DB.SetDefaultSignature(mailboxID, replySigID, true); err != nil {
t.Fatal(err)
}
// Brand-new compose gets the "new" default.
req := httptest.NewRequest(http.MethodGet, MailboxPrefix+"/mail/compose", nil)
req.AddCookie(cookie)
rec := httptest.NewRecorder()
mux.ServeHTTP(rec, req)
body := rec.Body.String()
// The picker's hidden .sig-data divs legitimately contain every signature's HTML
// (so the JS can swap between them client-side) — only the seed div (what actually
// loads into the editor) should be checked for which one was auto-inserted. The
// seed div's own content can itself contain a nested <div> (the signature's
// wrapper), so its end is found via the exact markup that follows the seed div's
// closing tag in the template, not just "the next </div>".
seed := extractSeed(t, body)
if !strings.Contains(seed, "Sent from my desk") {
t.Errorf("expected the default-for-new signature inserted, got seed:\n%s", seed)
}
if strings.Contains(seed, "Sent on the go") {
t.Error("did not expect the reply signature in a brand-new compose's seed")
}
// Reply gets the "reply" default instead, above the quote.
raw := "From: original@example.com\r\nTo: sigcompose@example.com\r\nSubject: Hi\r\nMessage-Id: <o1@example.com>\r\n\r\noriginal body"
uid, err := app.Mailstore.StoreMessage(mailboxID, "INBOX", []byte(raw), "o1@example.com", "original@example.com", "Hi")
if err != nil {
t.Fatal(err)
}
replyReq := httptest.NewRequest(http.MethodGet, MailboxPrefix+"/mail/compose?reply="+strconv.FormatInt(uid, 10)+"&folder=INBOX", nil)
replyReq.AddCookie(cookie)
replyRec := httptest.NewRecorder()
mux.ServeHTTP(replyRec, replyReq)
replySeed := extractSeed(t, replyRec.Body.String())
if !strings.Contains(replySeed, "Sent on the go") {
t.Errorf("expected the default-for-reply signature inserted into the seed, got:\n%s", replySeed)
}
sigIdx := strings.Index(replySeed, "Sent on the go")
quoteIdx := strings.Index(replySeed, "wrote:")
if sigIdx < 0 || quoteIdx < 0 || sigIdx > quoteIdx {
t.Error("expected the signature above the quoted original")
}
}
// TestWebmailMoveAndDeleteMessage confirms moving a message changes its folder, and
// deleting from a non-Trash folder moves to Trash first, requiring a second delete to
// actually remove it.