cells: display invalidity date or delay (#43605)

This commit is contained in:
Lauréline Guérin 2020-06-05 11:42:02 +02:00
parent 6d332a9ca5
commit 4a62897422
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
5 changed files with 78 additions and 28 deletions

View File

@ -547,6 +547,12 @@ class ValidityInfo(models.Model):
class Meta:
unique_together = [('content_type', 'object_id')]
@property
def invalid_datetime(self):
if not self.invalid_since:
return
return self.invalid_since + datetime.timedelta(days=2)
class CellMeta(MediaDefiningClass, ModelBase):
pass
@ -917,7 +923,7 @@ class CellBase(six.with_metaclass(CellMeta, models.Model)):
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):
if validity_info is not None and validity_info.invalid_datetime and validity_info.invalid_datetime <= now():
return False
return element_is_visible(self, user=user)

View File

@ -150,11 +150,15 @@
<span class="extra-css-class">[{{ cell.extra_css_class }}]</span>
{% endif %}
<span class="additional-label"><i>{{cell.get_additional_label|default_if_none:""}}</i></span>
{% with cell.get_invalid_reason as invalid_reason %}
{% if invalid_reason %}
<span class="invalid">{{ invalid_reason }}</span>
{% if cell.get_invalid_reason %}
<span class="invalid">{{ cell.get_invalid_reason }} -
{% if cell.get_validity_info.invalid_datetime|date_in_past %}
{% blocktrans with cell.get_validity_info.invalid_datetime|date:"DATETIME_FORMAT" as invalidity_date %}This cell is no longer displayed since {{ invalidity_date }}.{% endblocktrans %}
{% else %}
{% blocktrans with cell.get_validity_info.invalid_datetime|timeuntil as invalidity_delay %}This cell will no longer be displayed in {{ invalidity_delay }}.{% endblocktrans %}
{% endif %}
</span>
{% endif %}
{% endwith %}
</span>
{% if not cell.public %}
<span class="visibility-summary

View File

@ -25,7 +25,6 @@ import math
import time
from django import template
from django.conf import settings
from django.core import signing
from django.core.exceptions import PermissionDenied
from django.core.serializers.json import DjangoJSONEncoder
@ -43,6 +42,7 @@ from django.utils import dateparse, six
from django.utils.encoding import force_text
from django.utils.html import format_html
from django.utils.safestring import mark_safe
from django.utils.timezone import now
from combo.data.models import Page, Placeholder
from combo.public.menu import get_menu_context
@ -450,6 +450,16 @@ def age_in_months(value, today=None):
return ''
return years * 12 + months
@register.filter(expects_localtime=True)
def date_in_past(value):
value = parse_datetime(value)
try:
return value <= now()
except TypeError:
return False
def parse_decimal(value, default=Decimal(0)):
if isinstance(value, six.string_types):
# replace , by . for French users comfort

View File

@ -13,7 +13,6 @@ from django.apps import apps
from django.conf import settings
from django.db import connection
from django.forms.widgets import Media
from django.template import Context
from django.test import override_settings
from django.test.client import RequestFactory
from django.test.utils import CaptureQueriesContext
@ -1127,6 +1126,28 @@ def test_cell_is_visible():
assert cell.is_visible() is False
def test_cell_invalidity_marker():
page = Page.objects.create()
cell = TextCell.objects.create(page=page, order=0)
cell.mark_as_invalid('foo_bar_reason')
validity_info = ValidityInfo.objects.latest('pk')
old_reason = validity_info.invalid_reason_code
old_date = validity_info.invalid_since
cell.mark_as_invalid('another_foo_bar_reason', force=False)
validity_info.refresh_from_db()
assert old_reason == validity_info.invalid_reason_code
assert old_date == validity_info.invalid_since
cell.mark_as_invalid('another_foo_bar_reason')
validity_info.refresh_from_db()
assert validity_info.invalid_reason_code == 'another_foo_bar_reason'
assert old_date < validity_info.invalid_since
cell.mark_as_valid()
assert ValidityInfo.objects.exists() is False
def test_hourly():
appconfig = apps.get_app_config('data')
page = Page.objects.create(title='xxx', slug='test_current_forms_cell_render', template_name='standard')

View File

@ -1,29 +1,27 @@
import base64
import json
import datetime
import mock
import os
import re
import shutil
import mock
from django.core.files.storage import default_storage
from django.urls import reverse
from django.conf import settings
from django.contrib.auth.models import User, Group
from django.contrib.auth.models import Group
from django.db import connection
from django.template import TemplateSyntaxError
from django.test import override_settings
from django.test.client import RequestFactory
from django.test.utils import CaptureQueriesContext
from django.utils.http import urlencode
from django.utils.timezone import now
from django.utils.six import BytesIO
from django.utils.six.moves.urllib import parse as urlparse
import pytest
from webtest import TestApp
from webtest import Upload
from combo.wsgi import application
from combo.data.forms import LinkCellForm
from combo.data.models import (
Page, CellBase, TextCell, LinkCell, ConfigJsonCell, JsonCell, PageSnapshot,
@ -169,39 +167,50 @@ def test_edit_page(app, admin_user):
assert Page.objects.all()[0].exclude_from_navigation is False
def test_edit_page_cell_invalid_placeholder(app, admin_user):
def test_edit_page_cell_invalid_placeholder(freezer, app, admin_user):
freezer.move_to('2020-06-05 12:00:01')
page = Page.objects.create(title='One', slug='one', template_name='standard')
cell = TextCell.objects.create(page=page, placeholder='content', text='Foobar', order=1)
cell.mark_as_invalid('foo_bar_reason')
validity_info = ValidityInfo.objects.latest('pk')
old_reason = validity_info.invalid_reason_code
old_date = validity_info.invalid_since
app = login(app)
ValidityInfo.objects.update(invalid_since=now() - datetime.timedelta(minutes=1))
resp = app.get('/manage/pages/%s/' % page.pk)
assert '<span class="invalid">foo_bar_reason</span>' in resp.text
assert '<span class="invalid">foo_bar_reason' in resp.text
assert 'This cell will no longer be displayed in 1 day, 23 hours' in resp.text
cell.mark_as_invalid('another_foo_bar_reason', force=False)
validity_info.refresh_from_db()
assert old_reason == validity_info.invalid_reason_code
assert old_date == validity_info.invalid_since
ValidityInfo.objects.update(invalid_since=now() - datetime.timedelta(minutes=47*60-1))
resp = app.get('/manage/pages/%s/' % page.pk)
assert '<span class="invalid">foo_bar_reason' in resp.text
assert 'This cell will no longer be displayed in 1 hour, 1 minute.' in resp.text
cell.mark_as_invalid('another_foo_bar_reason')
validity_info.refresh_from_db()
assert validity_info.invalid_reason_code == 'another_foo_bar_reason'
assert old_date < validity_info.invalid_since
ValidityInfo.objects.update(invalid_since=now() - datetime.timedelta(minutes=47*60+29))
resp = app.get('/manage/pages/%s/' % page.pk)
assert '<span class="invalid">foo_bar_reason' in resp.text
assert 'This cell will no longer be displayed in 31 minutes.' in resp.text
ValidityInfo.objects.update(invalid_since=now() - datetime.timedelta(days=2))
resp = app.get('/manage/pages/%s/' % page.pk)
assert '<span class="invalid">foo_bar_reason' in resp.text
assert 'This cell is no longer displayed since June 5, 2020, noon.' in resp.text
ValidityInfo.objects.update(invalid_since=now() - datetime.timedelta(days=2, minutes=10*60+2))
resp = app.get('/manage/pages/%s/' % page.pk)
assert '<span class="invalid">foo_bar_reason' in resp.text
assert 'This cell is no longer displayed since June 5, 2020, 1:58 a.m.' in resp.text
cell.mark_as_valid()
assert ValidityInfo.objects.exists() is False
resp = app.get('/manage/pages/%s/' % page.pk)
assert '<span class="invalid">foo_bar_reason</span>' not in resp.text
assert '<span class="invalid">foo_bar_reason' not in resp.text
cell2 = LinkListCell.objects.create(order=0, placeholder='content', page=page)
item = LinkCell.objects.create(page=page, placeholder=cell2.link_placeholder, order=0)
item.mark_as_invalid('foo_bar_reason')
cell2.check_validity()
resp = app.get('/manage/pages/%s/' % page.pk)
assert '<span class="invalid">Invalid link</span>' in resp.text
assert '<span class="invalid">Invalid link' in resp.text
assert 'This cell will no longer be displayed in 2 days.' in resp.text
assert '<span class="invalid">foo_bar_reason</span>' in resp.text