Mercurial > p > roundup > code
comparison test/test_templating.py @ 6099:55c56ceacb8e
escape HTML tags in markdown content
enabled fenced code blocks for markdown
allow mistune to be used as a markdown parser
test all installed markdown parsers and fallback code
| author | Christof Meerwald <cmeerw@cmeerw.org> |
|---|---|
| date | Mon, 24 Feb 2020 22:20:19 +0000 |
| parents | 72a281a55a17 |
| children | af16c135fb98 |
comparison
equal
deleted
inserted
replaced
| 6098:72a281a55a17 | 6099:55c56ceacb8e |
|---|---|
| 7 | 7 |
| 8 | 8 |
| 9 import pytest | 9 import pytest |
| 10 from .pytest_patcher import mark_class | 10 from .pytest_patcher import mark_class |
| 11 | 11 |
| 12 try: | 12 if ReStructuredText: |
| 13 from docutils.core import publish_parts as ReStructuredText | |
| 14 skip_rst = lambda func, *args, **kwargs: func | 13 skip_rst = lambda func, *args, **kwargs: func |
| 15 except ImportError: | 14 else: |
| 16 ReStructuredText = None | |
| 17 skip_rst = mark_class(pytest.mark.skip( | 15 skip_rst = mark_class(pytest.mark.skip( |
| 18 reason='ReStructuredText not available')) | 16 reason='ReStructuredText not available')) |
| 19 | 17 |
| 20 try: | 18 if StructuredText: |
| 21 from StructuredText.StructuredText import HTML as StructuredText | |
| 22 skip_stext = lambda func, *args, **kwargs: func | 19 skip_stext = lambda func, *args, **kwargs: func |
| 23 except ImportError: | 20 else: |
| 24 try: # older version | 21 skip_stext = mark_class(pytest.mark.skip( |
| 25 import StructuredText | 22 reason='StructuredText not available')) |
| 26 skip_stext = lambda func, *args, **kwargs: func | 23 |
| 27 except ImportError: | 24 import roundup.cgi.templating |
| 28 StructuredText = None | 25 if roundup.cgi.templating._import_mistune(): |
| 29 skip_stext = mark_class(pytest.mark.skip( | 26 skip_mistune = lambda func, *args, **kwargs: func |
| 30 reason='StructuredText not available')) | 27 else: |
| 31 | 28 skip_mistune = mark_class(pytest.mark.skip( |
| 32 try: | 29 reason='mistune not available')) |
| 30 | |
| 31 if roundup.cgi.templating._import_markdown2(): | |
| 32 skip_markdown2 = lambda func, *args, **kwargs: func | |
| 33 else: | |
| 34 skip_markdown2 = mark_class(pytest.mark.skip( | |
| 35 reason='markdown2 not available')) | |
| 36 | |
| 37 if roundup.cgi.templating._import_markdown(): | |
| 33 skip_markdown = lambda func, *args, **kwargs: func | 38 skip_markdown = lambda func, *args, **kwargs: func |
| 34 from markdown2 import markdown | 39 else: |
| 35 except ImportError: | 40 skip_markdown = mark_class(pytest.mark.skip( |
| 36 try: | 41 reason='markdown not available')) |
| 37 from markdown import markdown | |
| 38 except ImportError: | |
| 39 markdown = None | |
| 40 skip_markdown = mark_class(pytest.mark.skip( | |
| 41 reason='markdown not available')) | |
| 42 | 42 |
| 43 from roundup.anypy.strings import u2s, s2u | 43 from roundup.anypy.strings import u2s, s2u |
| 44 | 44 |
| 45 class MockDatabase(MockNull): | 45 class MockDatabase(MockNull): |
| 46 def getclass(self, name): | 46 def getclass(self, name): |
| 245 self.assertEqual(p.plain(hyperlink=1), 'A string <b> with <a href="mailto:rouilj@example.com">rouilj@example.com</a> embedded &lt; html</b>') | 245 self.assertEqual(p.plain(hyperlink=1), 'A string <b> with <a href="mailto:rouilj@example.com">rouilj@example.com</a> embedded &lt; html</b>') |
| 246 self.assertEqual(p.plain(escape=1, hyperlink=1), 'A string <b> with <a href="mailto:rouilj@example.com">rouilj@example.com</a> embedded &lt; html</b>') | 246 self.assertEqual(p.plain(escape=1, hyperlink=1), 'A string <b> with <a href="mailto:rouilj@example.com">rouilj@example.com</a> embedded &lt; html</b>') |
| 247 | 247 |
| 248 self.assertEqual(p.hyperlinked(), 'A string <b> with <a href="mailto:rouilj@example.com">rouilj@example.com</a> embedded &lt; html</b>') | 248 self.assertEqual(p.hyperlinked(), 'A string <b> with <a href="mailto:rouilj@example.com">rouilj@example.com</a> embedded &lt; html</b>') |
| 249 | 249 |
| 250 @skip_markdown | |
| 251 def test_string_markdown_installed(self): | |
| 252 pass # just so we have a record of a skipped test | |
| 253 | |
| 254 def test_string_markdown(self): | |
| 255 p = StringHTMLProperty(self.client, 'test', '1', None, 'test', u2s(u'A string http://localhost with cmeerw@example.com *embedded* \u00df')) | |
| 256 if markdown: | |
| 257 self.assertEqual(p.markdown().strip(), u2s(u'<p>A string <a href="http://localhost">http://localhost</a> with <a href="mailto:cmeerw@example.com">cmeerw@example.com</a> <em>embedded</em> \u00df</p>')) | |
| 258 else: | |
| 259 self.assertEqual(p.markdown(), u2s(u'A string <a href="http://localhost" rel="nofollow noopener">http://localhost</a> with <a href="mailto:cmeerw@example.com">cmeerw@example.com</a> *embedded* \u00df')) | |
| 260 | |
| 261 @skip_rst | 250 @skip_rst |
| 262 def test_string_rst_installed(self): | |
| 263 pass # just so we have a record of a skipped test | |
| 264 | |
| 265 def test_string_rst(self): | 251 def test_string_rst(self): |
| 266 p = StringHTMLProperty(self.client, 'test', '1', None, 'test', u2s(u'A string with cmeerw@example.com *embedded* \u00df')) | 252 p = StringHTMLProperty(self.client, 'test', '1', None, 'test', u2s(u'A string with cmeerw@example.com *embedded* \u00df')) |
| 267 | 253 |
| 268 # test case to make sure include directive is disabled | 254 # test case to make sure include directive is disabled |
| 269 q = StringHTMLProperty(self.client, 'test', '1', None, 'test', u2s(u'\n\n.. include:: XyZrMt.html\n\n<badtag>\n\n')) | 255 q = StringHTMLProperty(self.client, 'test', '1', None, 'test', u2s(u'\n\n.. include:: XyZrMt.html\n\n<badtag>\n\n')) |
| 293 | 279 |
| 294 </pre> | 280 </pre> |
| 295 </div> | 281 </div> |
| 296 </div> | 282 </div> |
| 297 ''' | 283 ''' |
| 298 if ReStructuredText: | 284 self.assertEqual(p.rst(), u2s(u'<div class="document">\n<p>A string with <a class="reference external" href="mailto:cmeerw@example.com">cmeerw@example.com</a> <em>embedded</em> \u00df</p>\n</div>\n')) |
| 299 self.assertEqual(p.rst(), u2s(u'<div class="document">\n<p>A string with <a class="reference external" href="mailto:cmeerw@example.com">cmeerw@example.com</a> <em>embedded</em> \u00df</p>\n</div>\n')) | 285 self.assertEqual(q.rst(), u2s(q_result)) |
| 300 self.assertEqual(q.rst(), u2s(q_result)) | 286 self.assertEqual(r.rst(), u2s(r_result)) |
| 301 self.assertEqual(r.rst(), u2s(r_result)) | |
| 302 else: | |
| 303 self.assertEqual(p.rst(), u2s(u'A string with <a href="mailto:cmeerw@example.com">cmeerw@example.com</a> *embedded* \u00df')) | |
| 304 | 287 |
| 305 @skip_stext | 288 @skip_stext |
| 306 def test_string_stext_installed(self): | |
| 307 pass # just so we have a record of a skipped test | |
| 308 | |
| 309 def test_string_stext(self): | 289 def test_string_stext(self): |
| 310 p = StringHTMLProperty(self.client, 'test', '1', None, 'test', u2s(u'A string with cmeerw@example.com *embedded* \u00df')) | 290 p = StringHTMLProperty(self.client, 'test', '1', None, 'test', u2s(u'A string with cmeerw@example.com *embedded* \u00df')) |
| 311 if StructuredText: | 291 self.assertEqual(p.stext(), u2s(u'<p>A string with <a href="mailto:cmeerw@example.com">cmeerw@example.com</a> <em>embedded</em> \u00df</p>\n')) |
| 312 self.assertEqual(p.stext(), u2s(u'<p>A string with <a href="mailto:cmeerw@example.com">cmeerw@example.com</a> <em>embedded</em> \u00df</p>\n')) | |
| 313 else: | |
| 314 self.assertEqual(p.stext(), u2s(u'A string with <a href="mailto:cmeerw@example.com">cmeerw@example.com</a> *embedded* \u00df')) | |
| 315 | 292 |
| 316 def test_string_field(self): | 293 def test_string_field(self): |
| 317 p = StringHTMLProperty(self.client, 'test', '1', None, 'test', 'A string <b> with rouilj@example.com embedded < html</b>') | 294 p = StringHTMLProperty(self.client, 'test', '1', None, 'test', 'A string <b> with rouilj@example.com embedded < html</b>') |
| 318 self.assertEqual(p.field(), '<input name="test1@test" size="30" type="text" value="A string <b> with rouilj@example.com embedded &lt; html</b>">') | 295 self.assertEqual(p.field(), '<input name="test1@test" size="30" type="text" value="A string <b> with rouilj@example.com embedded &lt; html</b>">') |
| 319 | 296 |
| 434 | 411 |
| 435 attrs={"disabled": "disabled", "class": "required", "size": 30} | 412 attrs={"disabled": "disabled", "class": "required", "size": 30} |
| 436 input=input_xhtml(**attrs) | 413 input=input_xhtml(**attrs) |
| 437 self.assertEqual(input, '<input class="required" disabled="disabled" size="30" type="text"/>') | 414 self.assertEqual(input, '<input class="required" disabled="disabled" size="30" type="text"/>') |
| 438 | 415 |
| 416 # common markdown test cases | |
| 417 class MarkdownTests: | |
| 418 def test_string_markdown(self): | |
| 419 p = StringHTMLProperty(self.client, 'test', '1', None, 'test', u2s(u'A string http://localhost with cmeerw@example.com <br> *embedded* \u00df')) | |
| 420 self.assertEqual(p.markdown().strip(), u2s(u'<p>A string <a href="http://localhost">http://localhost</a> with <a href="mailto:cmeerw@example.com">cmeerw@example.com</a> <br> <em>embedded</em> \u00df</p>')) | |
| 421 | |
| 422 def test_string_markdown_code_block(self): | |
| 423 p = StringHTMLProperty(self.client, 'test', '1', None, 'test', u2s(u'embedded code block\n\n```\nline 1\nline 2\n```\n\nnew paragraph')) | |
| 424 self.assertEqual(p.markdown().strip().replace('\n\n', '\n'), u2s(u'<p>embedded code block</p>\n<pre><code>line 1\nline 2\n</code></pre>\n<p>new paragraph</p>')) | |
| 425 | |
| 426 @skip_mistune | |
| 427 class MistuneTestCase(TemplatingTestCase, MarkdownTests) : | |
| 428 def setUp(self): | |
| 429 TemplatingTestCase.setUp(self) | |
| 430 | |
| 431 from roundup.cgi import templating | |
| 432 self.__markdown = templating.markdown | |
| 433 templating.markdown = templating._import_mistune() | |
| 434 | |
| 435 def tearDown(self): | |
| 436 from roundup.cgi import templating | |
| 437 templating.markdown = self.__markdown | |
| 438 | |
| 439 @skip_markdown2 | |
| 440 class Markdown2TestCase(TemplatingTestCase, MarkdownTests) : | |
| 441 def setUp(self): | |
| 442 TemplatingTestCase.setUp(self) | |
| 443 | |
| 444 from roundup.cgi import templating | |
| 445 self.__markdown = templating.markdown | |
| 446 templating.markdown = templating._import_markdown2() | |
| 447 | |
| 448 def tearDown(self): | |
| 449 from roundup.cgi import templating | |
| 450 templating.markdown = self.__markdown | |
| 451 | |
| 452 @skip_markdown | |
| 453 class MarkdownTestCase(TemplatingTestCase, MarkdownTests) : | |
| 454 def setUp(self): | |
| 455 TemplatingTestCase.setUp(self) | |
| 456 | |
| 457 from roundup.cgi import templating | |
| 458 self.__markdown = templating.markdown | |
| 459 templating.markdown = templating._import_markdown() | |
| 460 | |
| 461 def tearDown(self): | |
| 462 from roundup.cgi import templating | |
| 463 templating.markdown = self.__markdown | |
| 464 | |
| 465 | |
| 466 class NoMarkdownTestCase(TemplatingTestCase) : | |
| 467 def setUp(self): | |
| 468 TemplatingTestCase.setUp(self) | |
| 469 | |
| 470 from roundup.cgi import templating | |
| 471 self.__markdown = templating.markdown | |
| 472 templating.markdown = None | |
| 473 | |
| 474 def tearDown(self): | |
| 475 from roundup.cgi import templating | |
| 476 templating.markdown = self.__markdown | |
| 477 | |
| 478 def test_string_markdown(self): | |
| 479 p = StringHTMLProperty(self.client, 'test', '1', None, 'test', u2s(u'A string http://localhost with cmeerw@example.com <br> *embedded* \u00df')) | |
| 480 self.assertEqual(p.markdown(), u2s(u'A string <a href="http://localhost" rel="nofollow noopener">http://localhost</a> with <a href="mailto:cmeerw@example.com">cmeerw@example.com</a> <br> *embedded* \u00df')) | |
| 481 | |
| 482 class NoRstTestCase(TemplatingTestCase) : | |
| 483 def setUp(self): | |
| 484 TemplatingTestCase.setUp(self) | |
| 485 | |
| 486 from roundup.cgi import templating | |
| 487 self.__ReStructuredText = templating.ReStructuredText | |
| 488 templating.ReStructuredText = None | |
| 489 | |
| 490 def tearDown(self): | |
| 491 from roundup.cgi import templating | |
| 492 templating.ReStructuredText = self.__ReStructuredText | |
| 493 | |
| 494 def test_string_rst(self): | |
| 495 p = StringHTMLProperty(self.client, 'test', '1', None, 'test', u2s(u'A string with cmeerw@example.com *embedded* \u00df')) | |
| 496 self.assertEqual(p.rst(), u2s(u'A string with <a href="mailto:cmeerw@example.com">cmeerw@example.com</a> *embedded* \u00df')) | |
| 497 | |
| 498 class NoStextTestCase(TemplatingTestCase) : | |
| 499 def setUp(self): | |
| 500 TemplatingTestCase.setUp(self) | |
| 501 | |
| 502 from roundup.cgi import templating | |
| 503 self.__StructuredText = templating.StructuredText | |
| 504 templating.StructuredText = None | |
| 505 | |
| 506 def tearDown(self): | |
| 507 from roundup.cgi import templating | |
| 508 templating.StructuredText = self.__StructuredText | |
| 509 | |
| 510 def test_string_stext(self): | |
| 511 p = StringHTMLProperty(self.client, 'test', '1', None, 'test', u2s(u'A string with cmeerw@example.com *embedded* \u00df')) | |
| 512 self.assertEqual(p.stext(), u2s(u'A string with <a href="mailto:cmeerw@example.com">cmeerw@example.com</a> *embedded* \u00df')) | |
| 513 | |
| 514 | |
| 439 r''' | 515 r''' |
| 440 class HTMLPermissions: | 516 class HTMLPermissions: |
| 441 def is_edit_ok(self): | 517 def is_edit_ok(self): |
| 442 def is_view_ok(self): | 518 def is_view_ok(self): |
| 443 def is_only_view_ok(self): | 519 def is_only_view_ok(self): |
