tests.py 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. from django.test import SimpleTestCase
  2. from landing.admin_rich_text import LandingPageAdminForm
  3. from landing.models import LandingPage
  4. from landing.rich_text import render_rich_html, sanitize_rich_html
  5. class RichTextSanitizerTests(SimpleTestCase):
  6. def test_historical_html_keeps_supported_rich_content(self):
  7. source = (
  8. '<h2>Heading</h2><p style="text-align:center;color:red">Text</p>'
  9. '<ul><li>One</li></ul>'
  10. '<a href="https://example.org">Link</a>'
  11. '<img src="/media/example.png" alt="Example" width="320">'
  12. )
  13. cleaned = sanitize_rich_html(source)
  14. self.assertIn('<h2>Heading</h2>', cleaned)
  15. self.assertIn('<ul><li>One</li></ul>', cleaned)
  16. self.assertIn('href="https://example.org"', cleaned)
  17. self.assertIn('src="/media/example.png"', cleaned)
  18. self.assertIn('text-align:center', cleaned)
  19. self.assertNotIn('color:', cleaned)
  20. def test_xss_payloads_are_removed_server_side(self):
  21. source = (
  22. '<script>alert(1)</script>'
  23. '<img src="javascript:alert(1)" onerror="alert(2)">'
  24. '<a href="javascript:alert(3)">bad</a>'
  25. '<p onclick="alert(4)">safe text</p>'
  26. )
  27. cleaned = sanitize_rich_html(source)
  28. lowered = cleaned.lower()
  29. self.assertNotIn('<script', lowered)
  30. self.assertNotIn('javascript:', lowered)
  31. self.assertNotIn('onerror', lowered)
  32. self.assertNotIn('onclick', lowered)
  33. self.assertIn('safe text', cleaned)
  34. def test_rendered_content_is_sanitized_and_safe(self):
  35. rendered = render_rich_html('<strong>ok</strong><script>bad()</script>')
  36. self.assertEqual(str(rendered), '<strong>ok</strong>')
  37. self.assertTrue(hasattr(rendered, '__html__'))
  38. def test_model_save_path_sanitizes_without_requiring_editor_field_type(self):
  39. page = LandingPage(title='Historical', slug='historical', content='<p>ok</p><script>bad()</script>')
  40. page.clean()
  41. self.assertEqual(page.content, '<p>ok</p>')
  42. self.assertEqual(LandingPage._meta.get_field('content').get_internal_type(), 'TextField')
  43. class RichTextEditorWidgetTests(SimpleTestCase):
  44. def test_admin_uses_widget_without_editor_specific_model_field(self):
  45. form = LandingPageAdminForm()
  46. self.assertEqual(form.fields["content"].widget.__class__.__name__, "TinyMCE")
  47. self.assertEqual(LandingPage._meta.get_field("content").get_internal_type(), "TextField")