"""A test for markdownconverter module."""
import unittest
import timApp.markdown.dumboclient
from timApp.document.docparagraph import DocParagraph
from timApp.document.viewcontext import default_view_ctx
from timApp.markdown.markdownconverter import md_to_html, par_list_to_html_list
from timApp.tests.db.timdbtest import TimDbTest
from tim_common.cs_sanitizer import tim_sanitize
SMART_PUNCT_MD = """
"Test"
Test1 -- test1
Test2 --- test2
Ellipses...
"""
SMART_PUNCT_HTML = """
<p>“Test”</p>
<p>Test1 – test1</p>
<p>Test2 — test2</p>
<p>Ellipses…</p>
"""
NO_SMART_PUNCT_HTML = """
<p>"Test"</p>
<p>Test1 -- test1</p>
<p>Test2 --- test2</p>
<p>Ellipses...</p>
"""
[docs]class MarkdownConverterTest(TimDbTest):
[docs] def check_conversion(self, html, md, macros=None):
self.assertEqual(html, md_to_html(md, sanitize=True, macros=macros))
[docs] def test_smart_punct(self):
d = self.create_doc()
main_par = DocParagraph.create(d.document, md=SMART_PUNCT_MD)
def check_html(expected: str, par: DocParagraph, reason: str):
bs = par_list_to_html_list(
[par],
settings=d.document.get_settings(),
view_ctx=default_view_ctx,
)
self.assertEqual(expected.strip(), bs[0], reason)
check_html(NO_SMART_PUNCT_HTML, main_par, "Default case: smart punct disabled")
d.document.set_settings({"smart_punct": "true"})
check_html(SMART_PUNCT_HTML, main_par, "Doc smart_punct: true")
d.document.set_settings({"smart_punct": "false"})
check_html(NO_SMART_PUNCT_HTML, main_par, "Doc smart_punct: false")
second_par = DocParagraph.create(d.document, md=SMART_PUNCT_MD)
check_html(
NO_SMART_PUNCT_HTML, second_par, "Doc smart_punct: false; second par"
)
second_par.set_attr("smart_punct", "true")
check_html(
SMART_PUNCT_HTML,
second_par,
"Doc smart_punct: false; second par with smart_punct: true",
)
[docs] def test_markdown(self):
cases = [
("", ""),
('<h1 id="hello">Hello</h1>', "# Hello"),
('<h2 id="hello">Hello</h2>', "## Hello"),
('<h3 id="hello">Hello</h3>', "### Hello"),
('<h4 id="hello">Hello</h4>', "#### Hello"),
('<h5 id="hello">Hello</h5>', "##### Hello"),
('<h6 id="hello-world">Hello world</h6>', "###### Hello world"),
('<p class="heading" id="hello">Hello</p>', "####### Hello"),
("<p>test</p>", "test"),
]
for html, md in cases:
self.check_conversion(html, md)
d = self.create_doc()
self.assertListEqual(
[html for html, _ in cases],
par_list_to_html_list(
[DocParagraph.create(d.document, md=md) for _, md in cases],
settings=d.document.get_settings(),
view_ctx=default_view_ctx,
),
)
macrotests = [
("<p>hello world!</p>", "hello %%somemacro%%!", {"somemacro": "world"})
]
for html, md, macros in macrotests:
self.check_conversion(html, md, macros)
[docs] def test_rst(self):
d = self.create_doc(
initial_par="""
#- {settings=""}
input_format: markdown
#- {input_format=rst}
.. image:: images/hi.png
"""
)
p = d.document.get_paragraphs()[1]
self.assertEqual(
['<p><img src="images/hi.png" alt="image" /></p>'],
par_list_to_html_list(
[p], settings=d.document.get_settings(), view_ctx=default_view_ctx
),
)
d = self.create_doc(
initial_par="""
#- {settings=""}
input_format: rst
#-
.. image:: images/hi.png
#- {input_format=markdown}
.. image:: images/hi.png
"""
)
p = d.document.get_paragraphs()[1:]
self.assertEqual(
[
'<p><img src="images/hi.png" alt="image" /></p>',
"<p>.. image:: images/hi.png</p>",
],
par_list_to_html_list(
p, settings=d.document.get_settings(), view_ctx=default_view_ctx
),
)
[docs] def test_bracketed_spans(self):
self.assertEqual(
'<p><span class="testing">test</span></p>',
md_to_html("[test]{.testing}"),
msg="If this test fails, you probably do not have up-to-date Dumbo. "
"Run ./pull_all.sh to update.",
)
[docs] def test_unsafe_not_allowed(self):
self.assertEqual(
"""
<p><span class="error">Error in expanding macros: access to attribute '<strong>class</strong>' of 'str' object is unsafe.</span></p>
""".strip(),
md_to_html("""%%''.__class__.__mro__%%""", macros={}),
)
[docs] def test_markup_md_conversion(self):
self.assertEqual(
{"test1": "value1", "test2": "<em>value2</em>"},
timApp.markdown.dumboclient.call_dumbo(
{"test1": "value1", "test2": "md:*value2*"}, path="/mdkeys"
),
)
self.assertEqual(
[
{"test1": "value1", "test2": "<em>value2</em>"},
{"test3": "value3", "test4": "<strong>value4</strong>"},
],
timApp.markdown.dumboclient.call_dumbo(
[
{"test1": "value1", "test2": "md:*value2*"},
{"test3": "value3", "test4": "md:**value4**"},
],
path="/mdkeys",
),
)
[docs] def test_markdown_sanitize_neutral(self):
test_strs = [
"Image 1",
"[Image 1](/images/1041/image.png)",
"[Image 1](/images/1041/image.png){width=300, height=200}",
]
for t in test_strs:
self.assertEqual(tim_sanitize(t), t)