aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-07-13 23:13:30 -0500
committerCraig Jennings <c@cjennings.net>2026-07-13 23:13:30 -0500
commit9927367c02c4e8723af27efb1dedbb8f89149c85 (patch)
tree6077ccdf80bfe7484d54d4077f3af072f3fde0fb /tests
parentc67233b9100ab61bff0304cea621c3cee89b55e9 (diff)
downloaddotemacs-9927367c02c4e8723af27efb1dedbb8f89149c85.tar.gz
dotemacs-9927367c02c4e8723af27efb1dedbb8f89149c85.zip
fix(mail): repair account nav, send fallback, and reply handling
Seven config-audit findings in mail-config, each verified against the installed mu4e 1.14 source before changing anything: - The C-; e account nav commands now require mu4e before searching. The maps register eagerly at startup, but mu4e-search has no autoload cookie, so a nav key pressed before mu4e's first launch signaled void-function. - With msmtp absent, both send variables now get cj/mail--send-mail-unavailable, which signals a user-error naming msmtp. The old fallback left message-send-mail-function nil (the top-level defvar pre-empts message.el's default), so the first send died with "invalid function: nil". - I removed the unconditional org-msg-edit-mode advice on the two reply commands. org-msg-post-setup already runs on mu4e-compose-mode-hook and applies org-msg-default-alternatives itself, so the advice forced org-msg onto text-only replies and re-ran a major mode org-msg had already set up. - I dropped the save-attachment headers action: mu4e-view-save-attachments takes no message argument and reads MIME parts from the view buffer, so it never worked from headers. - I deleted the obsolete HTML view knobs (mu4e-view-prefer-html and both mu4e-html2text-command sets): the shr-based view has ignored them since mu4e 1.7. - I reordered the contexts so cjennings.net comes first: with pick-first, gmail-first made gmail the silent default account for the first compose. - I dropped mu4e-starred-folder (not a mu4e variable, never had an effect) and the obsolete mu4e-maildir alias. New tests cover the nav-command mu4e load and the msmtp-absent fallback.
Diffstat (limited to 'tests')
-rw-r--r--tests/test-mail-config--account-search-queries.el22
-rw-r--r--tests/test-mail-config-transport.el17
2 files changed, 37 insertions, 2 deletions
diff --git a/tests/test-mail-config--account-search-queries.el b/tests/test-mail-config--account-search-queries.el
index 9f1b6b3e..02a74692 100644
--- a/tests/test-mail-config--account-search-queries.el
+++ b/tests/test-mail-config--account-search-queries.el
@@ -38,9 +38,12 @@
(ert-deftest test-mail-make-account-map-closures-capture-distinct-queries ()
"Normal: each binding runs its own account-scoped search (no closure leak).
-mu4e-search is mocked to capture the query each command passes."
+mu4e-search is mocked to capture the query each command passes; require is
+mocked so the commands' mu4e load never pulls the real package in batch."
(let ((searched '()))
- (cl-letf (((symbol-function 'mu4e-search)
+ (cl-letf (((symbol-function 'require)
+ (lambda (feature &rest _) feature))
+ ((symbol-function 'mu4e-search)
(lambda (q) (push q searched))))
(let ((map (cj/--mail-make-account-map "dmail")))
(funcall (keymap-lookup map "i"))
@@ -49,5 +52,20 @@ mu4e-search is mocked to capture the query each command passes."
(should (member "maildir:/dmail/INBOX AND flag:unread AND NOT flag:trashed"
searched))))
+(ert-deftest test-mail-make-account-map-loads-mu4e-before-search ()
+ "Error: a nav command loads mu4e before it calls `mu4e-search'.
+The C-; e maps register eagerly at startup, but `mu4e-search' carries no
+autoload cookie, so a nav key pressed before mu4e's first launch signaled
+void-function. The command must require mu4e first, then search."
+ (let ((events '()))
+ (cl-letf (((symbol-function 'require)
+ (lambda (feature &rest _) (push (list :require feature) events) feature))
+ ((symbol-function 'mu4e-search)
+ (lambda (q) (push (list :search q) events))))
+ (funcall (keymap-lookup (cj/--mail-make-account-map "cmail") "i")))
+ (should (equal (nreverse events)
+ '((:require mu4e)
+ (:search "maildir:/cmail/INBOX"))))))
+
(provide 'test-mail-config--account-search-queries)
;;; test-mail-config--account-search-queries.el ends here
diff --git a/tests/test-mail-config-transport.el b/tests/test-mail-config-transport.el
index 0240102a..9329ac70 100644
--- a/tests/test-mail-config-transport.el
+++ b/tests/test-mail-config-transport.el
@@ -66,6 +66,23 @@ EXECUTABLES is an alist of program name strings to executable paths."
(should (equal test-mail-config--warnings
'((mail-config . "msmtp not found; SMTP mail sending unavailable")))))))
+(ert-deftest test-mail-config-transport-msmtp-missing-sets-descriptive-fallback ()
+ "Error: with msmtp absent, the send functions get a descriptive fallback.
+The old behavior left `message-send-mail-function' nil (the top-level defvar
+pre-empts message.el's default), so the first send died with \"invalid
+function: nil\". The fallback must be installed on both send variables and
+must signal a `user-error' that names msmtp."
+ (test-mail-config--with-executables nil
+ (let (send-mail-function message-send-mail-function)
+ (cj/mail-configure-smtpmail)
+ (should (eq send-mail-function #'cj/mail--send-mail-unavailable))
+ (should (eq message-send-mail-function #'cj/mail--send-mail-unavailable))
+ (should-error (cj/mail--send-mail-unavailable) :type 'user-error)
+ (condition-case err
+ (cj/mail--send-mail-unavailable)
+ (user-error
+ (should (string-match-p "msmtp" (cadr err))))))))
+
(ert-deftest test-mail-config-transport-mbsync-present-builds-command ()
"When mbsync exists, build the mu4e sync command."
(test-mail-config--with-executables '(("mbsync" . "/usr/bin/mbsync"))