From 39728f17356dc442e8f96503769f3bdd4b68e3d7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Laur=C3=A9line=20Gu=C3=A9rin?= <zebuline@entrouvert.com>
Date: Fri, 27 Mar 2020 14:33:59 +0100
Subject: [PATCH 1/7] cells: don't check validity in is_visible if placeholder
 search (#40252)

---
 combo/apps/calendar/models.py      |  4 ++--
 combo/apps/fargo/models.py         |  5 +++--
 combo/apps/newsletters/models.py   |  5 +++--
 combo/apps/notifications/models.py |  5 +++--
 combo/apps/search/models.py        |  6 +++---
 combo/apps/wcs/models.py           |  5 +++--
 combo/data/models.py               | 17 +++++++++--------
 combo/profile/models.py            |  5 +++--
 combo/public/templatetags/combo.py |  9 +++++----
 combo/public/views.py              |  2 +-
 tests/test_notification.py         |  4 ++--
 11 files changed, 37 insertions(+), 30 deletions(-)

diff --git a/combo/apps/calendar/models.py b/combo/apps/calendar/models.py
index a2a12bc..c8f5065 100644
--- a/combo/apps/calendar/models.py
+++ b/combo/apps/calendar/models.py
@@ -54,9 +54,9 @@ class BookingCalendar(CellBase):
     def is_enabled(cls):
         return settings.BOOKING_CALENDAR_CELL_ENABLED and is_chrono_enabled() and is_wcs_enabled()
 
-    def is_visible(self, user=None):
+    def is_visible(self, **kwargs):
         return self.agenda_reference and self.formdef_reference \
-            and super(BookingCalendar, self).is_visible(user=user)
+            and super(BookingCalendar, self).is_visible(**kwargs)
 
     def get_cell_extra_context(self, context):
         if context.get('placeholder_search_mode'):
diff --git a/combo/apps/fargo/models.py b/combo/apps/fargo/models.py
index 734f407..8b6d8da 100644
--- a/combo/apps/fargo/models.py
+++ b/combo/apps/fargo/models.py
@@ -59,10 +59,11 @@ class RecentDocumentsCell(CellBase):
                 fields=self.get_form_fields(),
                 widgets=self.get_form_widgets())
 
-    def is_visible(self, user=None):
+    def is_visible(self, **kwargs):
+        user = kwargs.get('user')
         if not user or user.is_anonymous:
             return False
-        return super(RecentDocumentsCell, self).is_visible(user)
+        return super(RecentDocumentsCell, self).is_visible(**kwargs)
 
     @classmethod
     def is_enabled(cls):
diff --git a/combo/apps/newsletters/models.py b/combo/apps/newsletters/models.py
index 13138b1..256b713 100644
--- a/combo/apps/newsletters/models.py
+++ b/combo/apps/newsletters/models.py
@@ -141,7 +141,8 @@ class NewslettersCell(CellBase):
             context['form'] = form
         return super(NewslettersCell, self).render(context)
 
-    def is_visible(self, user=None):
+    def is_visible(self, **kwargs):
+        user = kwargs.get('user')
         if user is None or not user.is_authenticated:
             return False
-        return super(NewslettersCell, self).is_visible(user)
+        return super(NewslettersCell, self).is_visible(**kwargs)
diff --git a/combo/apps/notifications/models.py b/combo/apps/notifications/models.py
index 21a08fb..6f818e4 100644
--- a/combo/apps/notifications/models.py
+++ b/combo/apps/notifications/models.py
@@ -171,10 +171,11 @@ class NotificationsCell(CellBase):
     class Meta:
         verbose_name = _('User Notifications')
 
-    def is_visible(self, user=None):
+    def is_visible(self, **kwargs):
+        user = kwargs.get('user')
         if user is None or not user.is_authenticated:
             return False
-        return super(NotificationsCell, self).is_visible(user)
+        return super(NotificationsCell, self).is_visible(**kwargs)
 
     def get_cell_extra_context(self, context):
         extra_context = super(NotificationsCell, self).get_cell_extra_context(context)
diff --git a/combo/apps/search/models.py b/combo/apps/search/models.py
index d8c6a18..fb21816 100644
--- a/combo/apps/search/models.py
+++ b/combo/apps/search/models.py
@@ -48,10 +48,10 @@ class SearchCell(CellBase):
     class Meta:
         verbose_name = _('Search')
 
-    def is_visible(self, user=None):
+    def is_visible(self, **kwargs):
         if not self.search_services:
             return False
-        return super(SearchCell, self).is_visible(user=user)
+        return super(SearchCell, self).is_visible(**kwargs)
 
     def get_default_form_class(self):
         from .forms import SearchCellForm
@@ -114,7 +114,7 @@ class SearchCell(CellBase):
     @classmethod
     def ajax_results_view(cls, request, cell_pk, service_slug):
         cell = cls.objects.get(pk=cell_pk)
-        if not cell.is_visible(request.user) or not cell.page.is_visible(request.user):
+        if not cell.is_visible(user=request.user) or not cell.page.is_visible(request.user):
             raise PermissionDenied
 
         query = request.GET.get('q')
diff --git a/combo/apps/wcs/models.py b/combo/apps/wcs/models.py
index f59e93c..54aa991 100644
--- a/combo/apps/wcs/models.py
+++ b/combo/apps/wcs/models.py
@@ -381,10 +381,11 @@ class WcsUserDataBaseCell(WcsDataBaseCell):
     class Meta:
         abstract = True
 
-    def is_visible(self, user=None):
+    def is_visible(self, **kwargs):
+        user = kwargs.get('user')
         if not user or user.is_anonymous:
             return False
-        return super(WcsUserDataBaseCell, self).is_visible(user)
+        return super(WcsUserDataBaseCell, self).is_visible(**kwargs)
 
 
 class CategoriesValidityMixin(object):
diff --git a/combo/data/models.py b/combo/data/models.py
index 1f1945f..68b34ac 100644
--- a/combo/data/models.py
+++ b/combo/data/models.py
@@ -856,10 +856,11 @@ class CellBase(six.with_metaclass(CellMeta, models.Model)):
         return self.invalid_reason_codes.get(
             validity_info.invalid_reason_code, validity_info.invalid_reason_code)
 
-    def is_visible(self, user=None):
-        validity_info = self.get_validity_info()
-        if validity_info is not None and validity_info.invalid_since and validity_info.invalid_since < now() - datetime.timedelta(days=2):
-            return False
+    def is_visible(self, user=None, check_validity_info=True):
+        if check_validity_info:
+            validity_info = self.get_validity_info()
+            if validity_info is not None and validity_info.invalid_since and validity_info.invalid_since < now() - datetime.timedelta(days=2):
+                return False
         return element_is_visible(self, user=user)
 
     def is_relevant(self, context):
@@ -1293,8 +1294,8 @@ class FeedCell(CellBase):
     class Meta:
         verbose_name = _('RSS/Atom Feed')
 
-    def is_visible(self, user=None):
-        return bool(self.url) and super(FeedCell, self).is_visible(user=user)
+    def is_visible(self, **kwargs):
+        return bool(self.url) and super(FeedCell, self).is_visible(**kwargs)
 
     def get_cell_extra_context(self, context):
         extra_context = super(FeedCell, self).get_cell_extra_context(context)
@@ -1406,8 +1407,8 @@ class JsonCellBase(CellBase):
     class Meta:
         abstract = True
 
-    def is_visible(self, user=None):
-        return bool(self.url) and super(JsonCellBase, self).is_visible(user=user)
+    def is_visible(self, **kwargs):
+        return bool(self.url) and super(JsonCellBase, self).is_visible(**kwargs)
 
     def is_user_dependant(self, context=None):
         urls = [self.url] + [x['url'] for x in self.additional_data or []]
diff --git a/combo/profile/models.py b/combo/profile/models.py
index 6c5c4a0..7edcb0a 100644
--- a/combo/profile/models.py
+++ b/combo/profile/models.py
@@ -45,10 +45,11 @@ class ProfileCell(JsonCellBase):
         idp = list(settings.KNOWN_SERVICES.get('authentic').values())[0]
         return '%sapi/users/{{ concerned_user|name_id }}/' % idp.get('url')
 
-    def is_visible(self, user=None):
+    def is_visible(self, **kwargs):
+        user = kwargs.get('user')
         if not user or user.is_anonymous:
             return False
-        return super(ProfileCell, self).is_visible(user)
+        return super(ProfileCell, self).is_visible(**kwargs)
 
     def get_cell_extra_context(self, context):
         extra_context = super(ProfileCell, self).get_cell_extra_context(context)
diff --git a/combo/public/templatetags/combo.py b/combo/public/templatetags/combo.py
index 76324bf..f392cbe 100644
--- a/combo/public/templatetags/combo.py
+++ b/combo/public/templatetags/combo.py
@@ -73,10 +73,11 @@ def placeholder(context, placeholder_name, **options):
         page_cells = context['page'].prefetched_cells
     elif not context.get('render_skeleton'):
         page_cells = context['page'].get_cells() if 'page' in context else []
-    context['cells'] = [x for x in page_cells if
-            x.placeholder == placeholder_name and
-            (context.get('render_skeleton') or x.is_relevant(context) and
-            x.is_visible(context['request'].user))]
+    context['cells'] = [
+        x for x in page_cells if
+        x.placeholder == placeholder_name and
+        (context.get('render_skeleton') or x.is_relevant(context) and
+         x.is_visible(user=context['request'].user, check_validity_info=False))]
     if context.get('render_skeleton'):
         context['skeleton'] = skeleton_text(context, placeholder_name)
     else:
diff --git a/combo/public/views.py b/combo/public/views.py
index 3974289..ea82b6e 100644
--- a/combo/public/views.py
+++ b/combo/public/views.py
@@ -109,7 +109,7 @@ def ajax_page_cell(request, page_pk, cell_reference):
     except ObjectDoesNotExist:
         raise Http404()
 
-    if not cell.is_visible(request.user):
+    if not cell.is_visible(user=request.user):
         raise PermissionDenied()
 
     exception = None
diff --git a/tests/test_notification.py b/tests/test_notification.py
index bd121ba..0369d81 100644
--- a/tests/test_notification.py
+++ b/tests/test_notification.py
@@ -95,9 +95,9 @@ def test_notification_cell(app, john_doe, jane_doe):
     context['synchronous'] = True # to get fresh content
 
     context['request'].user = None
-    assert cell.is_visible(context['request'].user) is False
+    assert cell.is_visible(user=context['request'].user) is False
     context['request'].user = john_doe
-    assert cell.is_visible(context['request'].user) is True
+    assert cell.is_visible(user=context['request'].user) is True
     assert cell.get_badge(context) is None
 
     notification1 = Notification.notify(john_doe, 'notibar')
-- 
2.20.1

