diff options
| author | Craig Jennings <c@cjennings.net> | 2026-06-13 07:29:56 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-06-13 07:29:56 -0500 |
| commit | 636a470ff7fd04066e1a1f4d92554ddee0c66e2a (patch) | |
| tree | 068859507359bfeaa07ddfbb15ef3b6f8681cdd2 /tests | |
| parent | ed12628612b19b956d5cb32f0708b1dea81e3d18 (diff) | |
| download | dotemacs-636a470ff7fd04066e1a1f4d92554ddee0c66e2a.tar.gz dotemacs-636a470ff7fd04066e1a1f4d92554ddee0c66e2a.zip | |
fix: lock-screen, confirm-tier, and mail-folder audit bugs
Lock screen: slock is X11-only and never grabbed the Wayland session, so C-; ! l silently did nothing. On Wayland the locker now runs loginctl lock-session, which logind turns into a Lock signal that hypridle handles by running hyprlock, the same path idle and before-sleep locking already use. X11 keeps slock. system-commands.el now also requires host-environment, which it used at load time but never declared.
Confirmation tier: the global (fset 'yes-or-no-p 'y-or-n-p) plus use-short-answers t both flattened yes-or-no-p to a single keystroke, so the deliberate strong-confirm tier for irreversible actions was dead. A stray space could power off the machine or destroy files. I added cj/confirm-strong, which binds use-short-answers nil for one call to force a typed "yes", and routed the six irreversible sites through it (shutdown/reboot, permanent file destruction, file overwrites). I dropped the redundant fset and kept use-short-answers t so ordinary prompts stay single-key.
Mail folders: the cmail context set no trash folder, so D fell back to a nonexistent /trash, and no context set a refile folder, so r targeted a nonexistent /archive everywhere. Accepting mu4e's offer to create the maildir stranded mail where mbsync never syncs it. cmail now trashes to /cmail/Trash. Refile is computed per message rather than per context, because mu4e context :vars are sticky and a per-context refile would leak one account's archive folder into another. cmail archives to /cmail/Archive. The Gmail-backed accounts have no synced archive maildir, so they signal rather than move mail into an unsynced folder.
Lock and confirm-tier need a daemon restart to fully take effect. The mail changes apply on next mu4e open.
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/test-mail-config-refile-folder.el | 40 | ||||
| -rw-r--r-- | tests/test-system-lib-confirm-strong.el | 37 |
2 files changed, 77 insertions, 0 deletions
diff --git a/tests/test-mail-config-refile-folder.el b/tests/test-mail-config-refile-folder.el new file mode 100644 index 00000000..e2d224eb --- /dev/null +++ b/tests/test-mail-config-refile-folder.el @@ -0,0 +1,40 @@ +;;; test-mail-config-refile-folder.el --- Tests for refile-folder dispatch -*- lexical-binding: t; -*- + +;;; Commentary: +;; ERT tests for `cj/mu4e--refile-folder-for-maildir', the per-message refile +;; (archive) target dispatch. cmail has a real synced Archive folder; the +;; Gmail-backed accounts (gmail, dmail) have none, so refiling them must signal +;; rather than move mail into an unsynced, phantom folder (silent mail loss). + +;;; Code: + +(require 'ert) + +(add-to-list 'load-path (expand-file-name "modules" user-emacs-directory)) +(require 'mail-config) + +(ert-deftest test-mail-config-refile-cmail-returns-archive () + "Normal: a cmail message refiles into the synced /cmail/Archive folder." + (should (string= (cj/mu4e--refile-folder-for-maildir "/cmail/INBOX") + "/cmail/Archive")) + (should (string= (cj/mu4e--refile-folder-for-maildir "/cmail/Sent") + "/cmail/Archive"))) + +(ert-deftest test-mail-config-refile-gmail-signals () + "Error: gmail has no synced archive folder, so refile signals rather than +moving mail into a phantom folder." + (should-error (cj/mu4e--refile-folder-for-maildir "/gmail/INBOX") + :type 'user-error)) + +(ert-deftest test-mail-config-refile-dmail-signals () + "Error: dmail (Gmail-backed) has no synced archive folder; refile signals." + (should-error (cj/mu4e--refile-folder-for-maildir "/dmail/INBOX") + :type 'user-error)) + +(ert-deftest test-mail-config-refile-nil-maildir-signals () + "Boundary: a message with no maildir cannot be refiled; signal." + (should-error (cj/mu4e--refile-folder-for-maildir nil) + :type 'user-error)) + +(provide 'test-mail-config-refile-folder) +;;; test-mail-config-refile-folder.el ends here diff --git a/tests/test-system-lib-confirm-strong.el b/tests/test-system-lib-confirm-strong.el new file mode 100644 index 00000000..26c00822 --- /dev/null +++ b/tests/test-system-lib-confirm-strong.el @@ -0,0 +1,37 @@ +;;; test-system-lib-confirm-strong.el --- Tests for cj/confirm-strong -*- lexical-binding: t; -*- + +;;; Commentary: +;; ERT tests for `cj/confirm-strong', the typed-"yes" confirmation used for +;; irreversible actions. The behavior under test is the long-form guarantee: +;; the prompt demands a typed yes/no even when the global single-key default +;; (`use-short-answers') is in effect. + +;;; Code: + +(require 'ert) +(require 'cl-lib) +(require 'system-lib) + +(ert-deftest test-system-lib-confirm-strong-returns-t-on-yes () + "Normal: passes a t answer through from `yes-or-no-p'." + (cl-letf (((symbol-function 'yes-or-no-p) (lambda (&rest _) t))) + (should (eq (cj/confirm-strong "Really? ") t)))) + +(ert-deftest test-system-lib-confirm-strong-returns-nil-on-no () + "Normal: passes a nil answer through from `yes-or-no-p'." + (cl-letf (((symbol-function 'yes-or-no-p) (lambda (&rest _) nil))) + (should (eq (cj/confirm-strong "Really? ") nil)))) + +(ert-deftest test-system-lib-confirm-strong-forces-long-form () + "Boundary: binds `use-short-answers' to nil for the call even when it is +globally t, so the irreversible prompt requires a typed yes/no regardless of +the single-key default." + (let ((use-short-answers t) + (seen 'unset)) + (cl-letf (((symbol-function 'yes-or-no-p) + (lambda (&rest _) (setq seen use-short-answers) t))) + (cj/confirm-strong "Really? ") + (should (eq seen nil))))) + +(provide 'test-system-lib-confirm-strong) +;;; test-system-lib-confirm-strong.el ends here |
