diff options
| author | Danilo M. <danix@danix.xyz> | 2026-09-14 18:49:48 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-09-14 18:49:48 +0200 |
| commit | c2753771096e7c303da4b351986f7f313917dcf8 (patch) | |
| tree | 2f96b6c85c4bd5bb74382a2cc3492eeba173e039 /assets/hooks/test_qtmaildirconf.py | |
| parent | c1c196ebeef9a17defe8a3070e8f10d548ffdf40 (diff) | |
| download | qtmaildir-c2753771096e7c303da4b351986f7f313917dcf8.tar.gz qtmaildir-c2753771096e7c303da4b351986f7f313917dcf8.zip | |
fix(hooks): spam is not an inbox arrival
notmuch's new.tags applies inbox to every newly indexed file and the Inbox
filter is tag:inbox, so spam-folder mail appeared in the Inbox view. Add
spam to the post-new hook's NOT_ARRIVALS set so the existing all-files
carve-out covers it, and rename the sent_* helpers to not_arrival_* now
that the list means more than sent mail. Trash stays out: measured 0
affected files and it is out of scope.
Diffstat (limited to 'assets/hooks/test_qtmaildirconf.py')
| -rwxr-xr-x | assets/hooks/test_qtmaildirconf.py | 70 |
1 files changed, 47 insertions, 23 deletions
diff --git a/assets/hooks/test_qtmaildirconf.py b/assets/hooks/test_qtmaildirconf.py index c8aa78d..89565d9 100755 --- a/assets/hooks/test_qtmaildirconf.py +++ b/assets/hooks/test_qtmaildirconf.py @@ -15,7 +15,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. """Unit checks for the qtmaildir.conf reader the post-new hook uses to find -the sent folders. +the non-arrival folders. The file is written by QSettings, not by configparser, so the cases that matter are the ones where the two disagree: a section name carrying a dot, a @@ -37,37 +37,51 @@ def write_config(tmp, text): return path -def test_sent_folders_are_read_per_account(): +def test_not_arrival_folders_are_read_per_account(): with tempfile.TemporaryDirectory() as tmp: path = write_config(tmp, "[account.work]\n" "maildir = work\n" "sent = Sent\n" "trash = Trash\n") - assert qtmaildirconf.sent_folders(path) == ["work/Sent"] + assert qtmaildirconf.not_arrival_folders(path) == ["work/Sent"] -def test_drafts_are_excluded_alongside_sent(): - """A draft never arrived either, so it must not carry `inbox`. Both keys - feed one list: the hook asks a single question, "is this a folder mail - arrives in", and sent and drafts answer it the same way. +def test_drafts_and_spam_are_excluded_alongside_sent(): + """Neither a draft nor spam ever arrived, so neither must carry `inbox`. + All three keys feed one list: the hook asks a single question, "is this a + folder mail arrives in", and sent, drafts and spam answer it the same way. - Trash is deliberately NOT here. qtmaildir's own Delete leaves `inbox` on - a trashed message so Restore can put it back where it came from, and - stripping it here would fight that. + Trash is deliberately NOT here: the reported defect is spam and 0 trashed + files carried `inbox` (item 202), and qtmaildir's own Delete now strips + `unread` and `inbox` (item 168), so its own moves do not leave the tag + behind. """ with tempfile.TemporaryDirectory() as tmp: path = write_config(tmp, "[account.work]\n" "maildir = work\n" "sent = Sent\n" "drafts = Drafts\n" + "spam = Spam\n" "trash = Trash\n") - assert qtmaildirconf.sent_folders(path) == ["work/Sent", "work/Drafts"] + assert qtmaildirconf.not_arrival_folders(path) == [ + "work/Sent", "work/Drafts", "work/Spam"] + + +def test_spam_may_be_the_only_non_arrival_folder(): + """An account need not keep sent mail or drafts locally, and Gmail's + spam folder is one the reader must still pick up on its own.""" + with tempfile.TemporaryDirectory() as tmp: + path = write_config(tmp, "[account.g]\n" + "maildir = gmail\n" + "spam = [Gmail]/Spam\n") + assert qtmaildirconf.not_arrival_folders(path) == [ + "gmail/[Gmail]/Spam"] def test_an_account_with_only_drafts_still_contributes(): with tempfile.TemporaryDirectory() as tmp: path = write_config(tmp, "[account.a]\nmaildir = a\ndrafts = Drafts\n") - assert qtmaildirconf.sent_folders(path) == ["a/Drafts"] + assert qtmaildirconf.not_arrival_folders(path) == ["a/Drafts"] def test_an_account_section_may_carry_a_dot(): @@ -78,7 +92,7 @@ def test_an_account_section_may_carry_a_dot(): path = write_config(tmp, "[account.provider.name]\n" "maildir = provider-name\n" "sent = Sent\n") - assert qtmaildirconf.sent_folders(path) == ["provider-name/Sent"] + assert qtmaildirconf.not_arrival_folders(path) == ["provider-name/Sent"] def test_a_folder_may_contain_spaces_and_brackets(): @@ -88,7 +102,7 @@ def test_a_folder_may_contain_spaces_and_brackets(): path = write_config(tmp, "[account.g]\n" "maildir = gmail\n" "sent = [Gmail]/Posta inviata\n") - assert qtmaildirconf.sent_folders(path) == [ + assert qtmaildirconf.not_arrival_folders(path) == [ "gmail/[Gmail]/Posta inviata"] @@ -99,13 +113,23 @@ def test_an_account_without_a_sent_key_contributes_nothing(): with tempfile.TemporaryDirectory() as tmp: path = write_config(tmp, "[account.a]\nmaildir = a\ntrash = Trash\n" "[account.b]\nmaildir = b\nsent = Sent\n") - assert qtmaildirconf.sent_folders(path) == ["b/Sent"] + assert qtmaildirconf.not_arrival_folders(path) == ["b/Sent"] def test_an_empty_sent_value_contributes_nothing(): with tempfile.TemporaryDirectory() as tmp: path = write_config(tmp, "[account.a]\nmaildir = a\nsent =\n") - assert qtmaildirconf.sent_folders(path) == [] + assert qtmaildirconf.not_arrival_folders(path) == [] + + +def test_an_account_without_a_spam_key_contributes_nothing(): + """`spam` is optional like the others. A missing key must not append the + bare maildir, and an EMPTY value must not either: either would become an + empty-path prefix matching the whole account.""" + with tempfile.TemporaryDirectory() as tmp: + path = write_config(tmp, "[account.a]\nmaildir = a\nsent = Sent\n" + "[account.b]\nmaildir = b\nspam =\n") + assert qtmaildirconf.not_arrival_folders(path) == ["a/Sent"] def test_an_account_without_a_maildir_contributes_nothing(): @@ -113,7 +137,7 @@ def test_an_account_without_a_maildir_contributes_nothing(): and a bare `Sent` would match every account's sent folder at once.""" with tempfile.TemporaryDirectory() as tmp: path = write_config(tmp, "[account.a]\nsent = Sent\n") - assert qtmaildirconf.sent_folders(path) == [] + assert qtmaildirconf.not_arrival_folders(path) == [] def test_comments_and_other_sections_are_ignored(): @@ -127,14 +151,14 @@ def test_comments_and_other_sections_are_ignored(): "; another comment\n" "maildir = a\n" "sent = Sent\n") - assert qtmaildirconf.sent_folders(path) == ["a/Sent"] + assert qtmaildirconf.not_arrival_folders(path) == ["a/Sent"] def test_a_missing_file_yields_no_folders(): """The hook must run on a system with no qtmaildir config at all: it then protects nothing, rather than failing the sync.""" with tempfile.TemporaryDirectory() as tmp: - assert qtmaildirconf.sent_folders(Path(tmp) / "absent.conf") == [] + assert qtmaildirconf.not_arrival_folders(Path(tmp) / "absent.conf") == [] def test_an_unreadable_file_yields_no_folders(): @@ -143,25 +167,25 @@ def test_an_unreadable_file_yields_no_folders(): mail for one cycle.""" with tempfile.TemporaryDirectory() as tmp: path = write_config(tmp, "this is not an ini file\n[[[\n") - assert qtmaildirconf.sent_folders(path) == [] + assert qtmaildirconf.not_arrival_folders(path) == [] def test_the_query_scopes_every_folder(): folders = ["a/Sent", "g/[Gmail]/Posta inviata"] - query = qtmaildirconf.sent_query(folders) + query = qtmaildirconf.not_arrival_query(folders) assert query == ('path:"a/Sent/**" or path:"g/[Gmail]/Posta inviata/**"') def test_the_query_is_empty_when_no_folder_is_configured(): """An empty query means "match everything" to notmuch, so the caller must be able to tell "nothing to protect" from "protect the world".""" - assert qtmaildirconf.sent_query([]) == "" + assert qtmaildirconf.not_arrival_query([]) == "" def test_a_folder_containing_a_quote_cannot_break_out_of_the_query(): """The folder name reaches a notmuch query as a quoted string. A stray double quote would end the term and let the rest be read as syntax.""" - query = qtmaildirconf.sent_query(['a/He said "hi"']) + query = qtmaildirconf.not_arrival_query(['a/He said "hi"']) assert query.count('"') % 2 == 0 assert "\\\"" in query or '""' in query |
