diff --git a/lacommunaute/forum_conversation/models.py b/lacommunaute/forum_conversation/models.py index c0325e804..1370cc224 100644 --- a/lacommunaute/forum_conversation/models.py +++ b/lacommunaute/forum_conversation/models.py @@ -22,6 +22,14 @@ def unanswered(self): .exclude(status=Topic.TOPIC_LOCKED) .exclude(type=Topic.TOPIC_ANNOUNCE) .filter(posts_count=1) + .select_related( + "forum", + "poster", + "poster__forum_profile", + "first_post", + "first_post__poster", + ) + .order_by("-last_post_on") ) def optimized_for_topics_list(self, user_id): diff --git a/lacommunaute/forum_conversation/tests/tests_models.py b/lacommunaute/forum_conversation/tests/tests_models.py index a09117cf9..22556d37d 100644 --- a/lacommunaute/forum_conversation/tests/tests_models.py +++ b/lacommunaute/forum_conversation/tests/tests_models.py @@ -1,8 +1,11 @@ +from datetime import datetime, timezone + from django.conf import settings from django.core.exceptions import ValidationError from django.db import IntegrityError from django.test import TestCase from django.urls import reverse +from factory import Iterator from lacommunaute.forum.factories import ForumFactory from lacommunaute.forum_conversation.factories import ( @@ -47,6 +50,15 @@ def test_unanswered(self): self.assertEqual(Topic.objects.unanswered().get(), topic) + def test_unanswered_order(self): + forum = ForumFactory() + last_post_dates = [datetime(2025, 5, i, tzinfo=timezone.utc) for i in range(20, 24)] + + TopicFactory.create_batch( + size=len(last_post_dates), forum=forum, posts_count=1, last_post_on=Iterator(last_post_dates) + ) + assert list(Topic.objects.unanswered().values_list("last_post_on", flat=True)) == last_post_dates[::-1] + def test_optimized_for_topics_list_disapproved(self): TopicFactory(approved=False) self.assertEqual(Topic.objects.optimized_for_topics_list(1).count(), 0) diff --git a/lacommunaute/pages/tests/test_homepage.py b/lacommunaute/pages/tests/test_homepage.py index d184037e3..3aa8aa647 100644 --- a/lacommunaute/pages/tests/test_homepage.py +++ b/lacommunaute/pages/tests/test_homepage.py @@ -1,5 +1,6 @@ import re +import pytest from dateutil.relativedelta import relativedelta from django.urls import reverse from django.utils import timezone @@ -7,6 +8,7 @@ from lacommunaute.event.factories import EventFactory from lacommunaute.forum.factories import ForumFactory +from lacommunaute.forum_conversation.factories import TopicFactory from lacommunaute.utils.testing import parse_response_to_soup @@ -49,3 +51,25 @@ def test_events(db, client): assertContains(response, reverse("event:detail", kwargs={"pk": future_event.pk})) assertNotContains(response, unvisible_future_event.name) assertContains(response, reverse("event:current")) + + +@pytest.mark.parametrize("nb_topics,nb_expected", [(i, i) for i in range(5)] + [(i, 4) for i in range(5, 7)]) +def test_unsanswered_topics(db, client, nb_topics, nb_expected, snapshot): + TopicFactory.create_batch(nb_topics, with_post=True, with_tags=["Pirmadienis", "Poniedziałek", "Lundi", "Montag"]) + response = client.get(reverse("pages:home")) + assert len(response.context_data["unanswered_topics"]) == nb_expected + assert ('id="unanswered_topics"' in str(response.content)) == (nb_expected > 0) + + +def test_numqueries(db, client, django_assert_num_queries): + savepoint_queries = 4 + session_queries = 2 + with django_assert_num_queries( + savepoint_queries + + session_queries + + 1 # get first public forum + + 1 # get most recent updated forums in documentation + + 1 # get unanswered topics + + 1 # get upcoming events + ): + client.get(reverse("pages:home")) diff --git a/lacommunaute/pages/views.py b/lacommunaute/pages/views.py index 939eb5d0c..6ffb497b1 100644 --- a/lacommunaute/pages/views.py +++ b/lacommunaute/pages/views.py @@ -8,6 +8,8 @@ from lacommunaute.event.models import Event from lacommunaute.forum.models import Forum +from lacommunaute.forum_conversation.forms import PostForm +from lacommunaute.forum_conversation.models import Topic logger = logging.getLogger(__name__) @@ -28,6 +30,8 @@ def get_context_data(self, **kwargs: Any) -> dict[str, Any]: context["forums_category"] = Forum.objects.filter(parent__type=1).order_by("-updated")[:4] context["forum"] = Forum.objects.get_main_forum() context["upcoming_events"] = Event.objects.filter(date__gte=timezone.now()).order_by("date")[:4] + context["unanswered_topics"] = Topic.objects.unanswered()[:4] + context["form"] = PostForm(user=self.request.user) return context diff --git a/lacommunaute/partner/tests/tests_partner_listview.py b/lacommunaute/partner/tests/tests_partner_listview.py index 0cb085108..ab92bcfbc 100644 --- a/lacommunaute/partner/tests/tests_partner_listview.py +++ b/lacommunaute/partner/tests/tests_partner_listview.py @@ -1,5 +1,6 @@ import pytest from django.urls import reverse +from factory import Iterator from lacommunaute.partner.factories import PartnerFactory from lacommunaute.users.factories import UserFactory @@ -21,7 +22,8 @@ def test_listview(client, db, snapshot, url): def test_pagination(client, db, snapshot, url): - PartnerFactory.create_batch(8 * 3 + 1) + num_of_partners = 8 * 3 + 1 + PartnerFactory.create_batch(num_of_partners, name=Iterator([f"Partner {i}" for i in range(num_of_partners)])) response = client.get(url) assert response.status_code == 200 assert str(parse_response_to_soup(response, selector="ul.pagination")) == snapshot(name="partner_pagination") diff --git a/lacommunaute/templates/forum_conversation/topic_simple_list.html b/lacommunaute/templates/forum_conversation/topic_simple_list.html new file mode 100644 index 000000000..3e74f7ed0 --- /dev/null +++ b/lacommunaute/templates/forum_conversation/topic_simple_list.html @@ -0,0 +1,50 @@ +{% load i18n %} +
Des professionnels ont besoin de votre aide !
+ {% with topics=unanswered_topics %} + {% include "forum_conversation/topic_simple_list.html" with active_tag=active_tag %} + {% endwith %} +