+ @pytest.mark.sig
+ def test_signature_extraction_no_signature(self, const1):
+ assert (const1, None, None) == extract_signature(const1)
+
+ @pytest.mark.sig
+ def test_signature_extraction_just_text(self, const1, const2):
+ origtext, textsig, htmlsig = extract_signature(
+ f"{const1}{EMAIL_SIG_SEP}{const2}"
+ )
+ assert origtext == const1
+ assert textsig == const2
+ assert htmlsig is None
+
+ @pytest.mark.sig
+ def test_signature_extraction_html(self, const1, const2):
+ path = pathlib.Path("somepath")
+ sigconst = "HTML signature from {path} but as a string"
+
+ def filereader_fn(path):
+ return (
+ f'<div id="signature">{sigconst.format(path=path)}</div>'
+ )
+
+ origtext, textsig, htmlsig = extract_signature(
+ f"{const1}{EMAIL_SIG_SEP}{HTML_SIG_MARKER} {path}\n{const2}",
+ filereader_fn=filereader_fn,
+ )
+ assert origtext == const1
+ assert textsig == const2
+ assert htmlsig == sigconst.format(path=path)
+
+ @pytest.mark.sig
+ def test_signature_extraction_file_not_found(self, const1):
+ path = pathlib.Path("/does/not/exist")
+ with pytest.raises(FileNotFoundError):
+ origtext, textsig, htmlsig = extract_signature(
+ f"{const1}{EMAIL_SIG_SEP}{HTML_SIG_MARKER}{path}\n{const1}"
+ )
+
+ @pytest.mark.imgproc
+ def test_image_registry(self, const1):
+ reg = ImageRegistry()
+ cid = reg.register(const1)
+ assert "@" in cid
+ assert not cid.startswith("<")
+ assert not cid.endswith(">")
+ assert const1 in reg
+
+ @pytest.mark.imgproc
+ def test_image_registry_file_uri(self, const1):
+ reg = ImageRegistry()
+ reg.register("/some/path")
+ for path in reg:
+ assert path.startswith("file://")
+ break
+
+ @pytest.mark.converter
+ @pytest.mark.sig
+ def test_converter_signature_handling(
+ self, const1, fake_filewriter, monkeypatch
+ ):
+ path = pathlib.Path(const1)
+
+ mailparts = (
+ "This is the mail body\n",
+ f"{EMAIL_SIG_SEP}",
+ "This is a plain-text signature only",
+ )
+
+ def filereader_fn(path):
+ return ""
+
+ with monkeypatch.context() as m:
+ m.setattr(markdown.Markdown, "convert", lambda s, t: t)
+ convert_markdown_to_html(
+ "".join(mailparts),
+ path,
+ filewriter_fn=fake_filewriter,
+ filereader_fn=filereader_fn,
+ )
+
+ soup = bs4.BeautifulSoup(fake_filewriter.pop()[1], "html.parser")
+ body = soup.body.contents
+
+ assert mailparts[0] in body.pop(0)
+
+ sig = soup.select_one("#signature")
+ assert sig == body.pop(0)
+
+ sep = sig.select_one("span.sig_separator")
+ assert sep == sig.contents[0]
+ assert f"\n{sep.text}\n" == EMAIL_SIG_SEP
+
+ assert mailparts[2] in sig.contents[1]
+
+ @pytest.mark.converter
+ @pytest.mark.sig
+ def test_converter_signature_handling_htmlsig(
+ self, const1, fake_filewriter, monkeypatch
+ ):
+ path = pathlib.Path(const1)
+
+ mailparts = (
+ "This is the mail body",
+ f"{EMAIL_SIG_SEP}",
+ f"{HTML_SIG_MARKER}{path}\n",
+ "This is the plain-text version",
+ )
+
+ htmlsig = "HTML Signature from {path}"
+
+ def filereader_fn(path):
+ return f'<div id="signature">{htmlsig.format(path=path)}</div>'
+
+ def mdwn_fn(t):
+ return t.upper()
+
+ with monkeypatch.context() as m:
+ m.setattr(
+ markdown.Markdown, "convert", lambda s, t: mdwn_fn(t)
+ )
+ convert_markdown_to_html(
+ "".join(mailparts),
+ path,
+ filewriter_fn=fake_filewriter,
+ filereader_fn=filereader_fn,
+ )
+
+ soup = bs4.BeautifulSoup(fake_filewriter.pop()[1], "html.parser")
+ sig = soup.select_one("#signature")
+ sig.span.extract()
+
+ assert HTML_SIG_MARKER not in sig.text
+ assert htmlsig.format(path=path) == sig.text.strip()
+
+ plaintext = fake_filewriter.pop()[1]
+ assert plaintext.endswith(EMAIL_SIG_SEP + mailparts[-1])
+
+ @pytest.mark.converter
+ @pytest.mark.sig
+ def test_converter_signature_handling_htmlsig_with_image(
+ self, const1, fake_filewriter, monkeypatch, test_png
+ ):
+ path = pathlib.Path(const1)
+
+ mailparts = (
+ "This is the mail body",
+ f"{EMAIL_SIG_SEP}",
+ f"{HTML_SIG_MARKER}{path}\n",
+ "This is the plain-text version",
+ )
+
+ htmlsig = (
+ "HTML Signature from {path} with image\n"
+ f'<img src="{test_png}">\n'
+ )
+
+ def filereader_fn(path):
+ return f'<div id="signature">{htmlsig.format(path=path)}</div>'
+
+ def mdwn_fn(t):
+ return t.upper()
+
+ with monkeypatch.context() as m:
+ m.setattr(
+ markdown.Markdown, "convert", lambda s, t: mdwn_fn(t)
+ )
+ convert_markdown_to_html(
+ "".join(mailparts),
+ path,
+ filewriter_fn=fake_filewriter,
+ filereader_fn=filereader_fn,
+ )
+
+ assert fake_filewriter.pop()[0].suffix == ".png"
+
+ soup = bs4.BeautifulSoup(fake_filewriter.pop()[1], "html.parser")
+ assert soup.img.attrs["src"].startswith("cid:")
+
+ @pytest.mark.converter
+ @pytest.mark.sig
+ def test_converter_signature_handling_textsig_with_image(
+ self, const1, fake_filewriter, test_png
+ ):
+ mailparts = (
+ "This is the mail body",
+ f"{EMAIL_SIG_SEP}",
+ "This is the plain-text version with image\n",
+ f"![Inline]({test_png})",
+
+ )
+ tree = convert_markdown_to_html
+ "".join(mailparts),
+ pathlib.Path(const1),
+ filewriter_fn=fake_filewriter,
+ )
+
+ assert tree.subtype == "relative"
+ assert tree.children[0].subtype == "alternative"
+ assert tree.children[1].subtype == "png"
+ written = fake_filewriter.pop()
+ assert tree.children[1].path == written[0]
+ assert written[1] == request.urlopen(test_png).read()
+
+ def test_converter_attribution_to_admonition(self, fake_filewriter):
+
+