diff --git a/apps/downloads/search_indexes.py b/apps/downloads/search_indexes.py index c56dc1e06..2bc71acdb 100644 --- a/apps/downloads/search_indexes.py +++ b/apps/downloads/search_indexes.py @@ -1,6 +1,7 @@ """Haystack search indexes for the downloads app.""" import datetime +import html from django.template.defaultfilters import striptags, truncatewords_html from django.utils import timezone @@ -43,7 +44,7 @@ def prepare_version(self, obj): def prepare_description(self, obj): """Return a truncated plain-text description.""" - return striptags(truncatewords_html(obj.content.rendered, 50)) + return html.unescape(striptags(truncatewords_html(obj.content.rendered, 50))) def prepare(self, obj): """Boost recent releases.""" diff --git a/apps/downloads/tests/test_search_indexes.py b/apps/downloads/tests/test_search_indexes.py new file mode 100644 index 000000000..15bfa27d6 --- /dev/null +++ b/apps/downloads/tests/test_search_indexes.py @@ -0,0 +1,22 @@ +from types import SimpleNamespace + +from django.template.loader import render_to_string +from django.test import SimpleTestCase + +from apps.downloads.search_indexes import ReleaseIndex + + +class ReleaseSearchIndexTests(SimpleTestCase): + def test_prepare_description_returns_plain_text(self): + obj = SimpleNamespace(content=SimpleNamespace(rendered="
Data & AI role
")) + + self.assertEqual(ReleaseIndex().prepare_description(obj), "Data & AI role alert(1)") + + def test_result_template_escapes_description(self): + rendered = render_to_string( + "search/includes/downloads.release.html", + {"result": {"description": ""}}, + ) + + self.assertNotIn("") + ) + + self.assertEqual(EventIndex().prepare_description(obj), "Data & AI role alert(1)") + + def test_calendar_prepare_description_returns_plain_text(self): + obj = SimpleNamespace(description="Data & AI role
") + + self.assertEqual(CalendarIndex().prepare_description(obj), "Data & AI role alert(1)") + + def test_result_templates_escape_description(self): + for template in ( + "search/includes/events.event.html", + "search/includes/events.calendar.html", + ): + with self.subTest(template=template): + rendered = render_to_string(template, {"result": {"description": ""}}) + + self.assertNotIn("") + ) + + self.assertEqual(JobIndex().prepare_description(obj), "Data & AI role alert(1)") + + def test_result_template_escapes_description(self): + rendered = render_to_string( + "search/includes/jobs.job.html", + {"result": {"description": ""}}, + ) + + self.assertNotIn(""), + ) + + self.assertEqual(PageIndex().prepare_description(obj), "Data & AI role alert(1)") + + def test_prepare_description_keeps_existing_description(self): + obj = SimpleNamespace(description="Kept & raw", content=None) + + self.assertEqual(PageIndex().prepare_description(obj), "Kept & raw") diff --git a/templates/search/includes/downloads.release.html b/templates/search/includes/downloads.release.html index f2f808d7d..b55efedac 100644 --- a/templates/search/includes/downloads.release.html +++ b/templates/search/includes/downloads.release.html @@ -1,7 +1,7 @@Version: {{ result.version }}
Released: {{ result.release_date|date }}
-{{ result.description|safe }}
+{{ result.description }}
{% if result.release_notes_url %} {% endif %} diff --git a/templates/search/includes/events.calendar.html b/templates/search/includes/events.calendar.html index 9fb6ff730..473c7cb21 100644 --- a/templates/search/includes/events.calendar.html +++ b/templates/search/includes/events.calendar.html @@ -1,5 +1,5 @@{{ result.description|safe }}
+{{ result.description }}
{% if result.rss %} {% endif %} diff --git a/templates/search/includes/events.event.html b/templates/search/includes/events.event.html index f015b5513..43e859e32 100644 --- a/templates/search/includes/events.event.html +++ b/templates/search/includes/events.event.html @@ -25,4 +25,4 @@Location: {{ result.venue }}
{% endif %} -{{ result.description|safe }}
\ No newline at end of file +{{ result.description }}
\ No newline at end of file diff --git a/templates/search/includes/jobs.job.html b/templates/search/includes/jobs.job.html index 7dd2c0d68..b65c2ee40 100644 --- a/templates/search/includes/jobs.job.html +++ b/templates/search/includes/jobs.job.html @@ -3,4 +3,4 @@Location: {{ result.city }}{% if result.region %}, {{ result.region }}{% endif %} {{ result.country }}
{% if result.telecommuting %}Telecommuting: Yes
{% endif %} -{{ result.description|safe }}
\ No newline at end of file +{{ result.description }}
\ No newline at end of file