12 @pytest.fixture(scope='function')
14 """The tmpdir fixture wrapped in pathlib.Path."""
15 return pathlib.Path(str(tmpdir))
20 """Return a function which runs notmuch commands on our test maildir.
22 This uses the notmuch-config file created by the ``maildir``
26 """Run a notmuch comand.
28 This function runs with a timeout error as many notmuch
29 commands may block if multiple processes are trying to open
30 the database in write-mode. It is all too easy to
31 accidentally do this in the unittests.
33 cfg_fname = maildir.path / 'notmuch-config'
34 cmd = ['notmuch'] + list(args)
35 print('Invoking: {}'.format(' '.join(cmd)))
36 proc = subprocess.run(cmd,
38 env={'NOTMUCH_CONFIG': str(cfg_fname)})
39 proc.check_returncode()
45 """A basic test interface to a valid maildir directory.
47 This creates a valid maildir and provides a simple mechanism to
48 deliver test emails to it. It also writes a notmuch-config file
49 in the top of the maildir.
57 cfg_fname = tmppath/'notmuch-config'
58 with cfg_fname.open('w') as fp:
59 fp.write(textwrap.dedent("""\
64 primary_email=dst@example.com
69 exclude_tags=deleted;spam;
71 synchronize_flags=true
74 """.format(tmppath=tmppath)))
75 return MailDir(tmppath)
79 """An interface around a correct maildir."""
81 def __init__(self, path):
82 self._path = pathlib.Path(path)
83 self.mailbox = mailbox.Maildir(str(path))
88 """The pathname of the maildir."""
91 def _next_msgid(self):
92 """Return a new unique message ID."""
93 msgid = '{}@{}'.format(self._idcount, socket.getfqdn())
99 body='This is a test mail',
100 to='dst@example.com',
101 frm='src@example.com',
103 new=False, # Move to new dir or cur dir?
104 keywords=None, # List of keywords or labels
105 seen=False, # Seen flag (cur dir only)
106 replied=False, # Replied flag (cur dir only)
107 flagged=False): # Flagged flag (cur dir only)
108 """Deliver a new mail message in the mbox.
110 This does only adds the message to maildir, does not insert it
111 into the notmuch database.
113 :returns: A tuple of (msgid, pathname).
115 msgid = self._next_msgid()
117 msg = email.message.EmailMessage()
118 msg.add_header('Received', 'by MailDir; {}'.format(time.ctime(when)))
119 msg.add_header('Message-ID', '<{}>'.format(msgid))
120 msg.add_header('Date', time.ctime(when))
121 msg.add_header('From', frm)
122 msg.add_header('To', to)
123 msg.add_header('Subject', subject)
127 msg.set_content(body)
128 mdmsg = mailbox.MaildirMessage(msg)
130 mdmsg.set_subdir('cur')
137 boxid = self.mailbox.add(mdmsg)
140 basename += mailbox.Maildir.colon + mdmsg.get_info()
141 msgpath = self.path / mdmsg.get_subdir() / basename
142 return (msgid, msgpath)