Repository: wagtail/wagtail

Issue:
Implemented date_since in get_most_popular() inside search_promotions.models
Fixes #10812

Should the same change be applied to wagtail.search.models or is it better to create a separate issue?

-   [Y ] Do the tests still pass?[^1]
-   [Y] Does the code comply with the style guide?
-   [Y] For Python changes: Have you added tests to cover the new/fixed behaviour?



Discussion:

Resolving patch:
diff --git a/wagtail/contrib/search_promotions/models.py b/wagtail/contrib/search_promotions/models.py
--- a/wagtail/contrib/search_promotions/models.py
+++ b/wagtail/contrib/search_promotions/models.py
@@ -56,10 +56,13 @@ def get(cls, query_string):
 
     @classmethod
     def get_most_popular(cls, date_since=None):
-        # TODO: Implement date_since
+        objects = cls.objects.filter(daily_hits__isnull=False)
+
+        if date_since:
+            objects = objects.filter(daily_hits__date__gte=date_since)
+
         return (
-            cls.objects.filter(daily_hits__isnull=False)
-            .annotate(_hits=models.Sum("daily_hits__hits"))
+            objects.annotate(_hits=models.Sum("daily_hits__hits"))
             .distinct()
             .order_by("-_hits")
         )


Test patch:
diff --git a/wagtail/contrib/search_promotions/tests.py b/wagtail/contrib/search_promotions/tests.py
--- a/wagtail/contrib/search_promotions/tests.py
+++ b/wagtail/contrib/search_promotions/tests.py
@@ -78,6 +78,69 @@ def test_search_pick_ordering(self):
             Query.get("root page").editors_picks.last().description, "Last search pick"
         )
 
+    def test_get_most_popular(self):
+        popularQuery = Query.get("popular")
+        for i in range(5):
+            popularQuery.add_hit()
+        SearchPromotion.objects.create(
+            query=Query.get("popular"),
+            page_id=2,
+            sort_order=0,
+            description="Popular search pick",
+        )
+        SearchPromotion.objects.create(
+            query=Query.get("uninteresting"),
+            page_id=1,
+            sort_order=2,
+            description="Uninteresting search pick",
+        )
+
+        # Check
+        self.assertEqual(Query.get_most_popular().count(), 1)
+        popular_picks = Query.get("popular").editors_picks.first()
+        self.assertEqual(
+            popular_picks.description,
+            "Popular search pick",
+        )
+        self.assertEqual(popular_picks.query.hits, 5)
+
+    def test_get_most_popular_since(self):
+        TODAY = date.today()
+        TWO_DAYS_AGO = TODAY - timedelta(days=2)
+        FIVE_DAYS_AGO = TODAY - timedelta(days=5)
+
+        popularQuery = Query.get("popular")
+        for i in range(5):
+            popularQuery.add_hit(date=FIVE_DAYS_AGO)
+
+        surpriseQuery = Query.get("surprise")
+        surpriseQuery.add_hit(date=TODAY)
+        surpriseQuery.add_hit(date=TWO_DAYS_AGO)
+        surpriseQuery.add_hit(date=FIVE_DAYS_AGO)
+        SearchPromotion.objects.create(
+            query=Query.get("popular"),
+            page_id=2,
+            sort_order=0,
+            description="Popular search pick",
+        )
+        SearchPromotion.objects.create(
+            query=Query.get("surprise"),
+            page_id=2,
+            sort_order=2,
+            description="Surprising search pick",
+        )
+
+        # Check
+        most_popular_queries = Query.get_most_popular(date_since=TWO_DAYS_AGO)
+        self.assertEqual(most_popular_queries.count(), 1)
+        editors_picks = Query.get("surprise").editors_picks
+        surprise_picks = editors_picks.first()
+        self.assertEqual(
+            surprise_picks.description,
+            "Surprising search pick",
+        )
+        self.assertEqual(surprise_picks.query.hits, 3)
+
 
 class TestGetSearchPromotionsTemplateTag(TestCase):
     def test_get_search_promotions_template_tag(self):