summaryrefslogtreecommitdiffstats
path: root/assets/hooks/test_qtmaildirconf.py
diff options
context:
space:
mode:
Diffstat (limited to 'assets/hooks/test_qtmaildirconf.py')
-rwxr-xr-xassets/hooks/test_qtmaildirconf.py70
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