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 @@

Release – {{ result.name }}

Version: {{ result.version }}

Released: {{ result.release_date|date }}

-

{{ result.description|safe }}

+

{{ result.description }}

{% if result.release_notes_url %}

View Release Notes

{% 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 @@

Calendar – {{ result.name }}

-

{{ result.description|safe }}

+

{{ result.description }}

{% if result.rss %}

RSS Feed

{% 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 @@

Event – {{ result.name }}

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 @@

Job - {{ result.name }}

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