Projet

Général

Profil

0001-cells-display-invalidity-date-or-delay-43605.patch

Lauréline Guérin, 05 juin 2020 15:03

Télécharger (10,5 ko)

Voir les différences:

Subject: [PATCH] cells: display invalidity date or delay (#43605)

 combo/data/models.py                         |  8 ++-
 combo/manager/templates/combo/page_view.html | 12 +++--
 combo/public/templatetags/combo.py           | 12 ++++-
 tests/test_cells.py                          | 23 ++++++++-
 tests/test_manager.py                        | 51 ++++++++++++--------
 5 files changed, 78 insertions(+), 28 deletions(-)
combo/data/models.py
547 547
    class Meta:
548 548
        unique_together = [('content_type', 'object_id')]
549 549

  
550
    @property
551
    def invalid_datetime(self):
552
        if not self.invalid_since:
553
            return
554
        return self.invalid_since + datetime.timedelta(days=2)
555

  
550 556

  
551 557
class CellMeta(MediaDefiningClass, ModelBase):
552 558
    pass
......
917 923
    def is_visible(self, user=None, check_validity_info=True):
918 924
        if check_validity_info:
919 925
            validity_info = self.get_validity_info()
920
            if validity_info is not None and validity_info.invalid_since and validity_info.invalid_since < now() - datetime.timedelta(days=2):
926
            if validity_info is not None and validity_info.invalid_datetime and validity_info.invalid_datetime <= now():
921 927
                return False
922 928
        return element_is_visible(self, user=user)
923 929

  
combo/manager/templates/combo/page_view.html
150 150
                  <span class="extra-css-class">[{{ cell.extra_css_class }}]</span>
151 151
                  {% endif %}
152 152
                  <span class="additional-label"><i>{{cell.get_additional_label|default_if_none:""}}</i></span>
153
                  {% with cell.get_invalid_reason as invalid_reason %}
154
                  {% if invalid_reason %}
155
                  <span class="invalid">{{ invalid_reason }}</span>
153
                  {% if cell.get_invalid_reason %}
154
                  <span class="invalid">{{ cell.get_invalid_reason }} -
155
                    {% if cell.get_validity_info.invalid_datetime|date_in_past %}
156
                      {% blocktrans with cell.get_validity_info.invalid_datetime|date:"DATETIME_FORMAT" as invalidity_date %}This cell is no longer displayed since {{ invalidity_date }}.{% endblocktrans %}
157
                    {% else %}
158
                      {% blocktrans with cell.get_validity_info.invalid_datetime|timeuntil as invalidity_delay %}This cell will no longer be displayed in {{ invalidity_delay }}.{% endblocktrans %}
159
                    {% endif %}
160
                  </span>
156 161
                  {% endif %}
157
                  {% endwith %}
158 162
                </span>
159 163
                {% if not cell.public %}
160 164
                  <span class="visibility-summary
combo/public/templatetags/combo.py
25 25
import time
26 26

  
27 27
from django import template
28
from django.conf import settings
29 28
from django.core import signing
30 29
from django.core.exceptions import PermissionDenied
31 30
from django.core.serializers.json import DjangoJSONEncoder
......
43 42
from django.utils.encoding import force_text
44 43
from django.utils.html import format_html
45 44
from django.utils.safestring import mark_safe
45
from django.utils.timezone import now
46 46

  
47 47
from combo.data.models import Page, Placeholder
48 48
from combo.public.menu import get_menu_context
......
450 450
        return ''
451 451
    return years * 12 + months
452 452

  
453

  
454
@register.filter(expects_localtime=True)
455
def date_in_past(value):
456
    value = parse_datetime(value)
457
    try:
458
        return value <= now()
459
    except TypeError:
460
        return False
461

  
462

  
453 463
def parse_decimal(value, default=Decimal(0)):
454 464
    if isinstance(value, six.string_types):
455 465
        # replace , by . for French users comfort
tests/test_cells.py
13 13
from django.conf import settings
14 14
from django.db import connection
15 15
from django.forms.widgets import Media
16
from django.template import Context
17 16
from django.test import override_settings
18 17
from django.test.client import RequestFactory
19 18
from django.test.utils import CaptureQueriesContext
......
1127 1126
    assert cell.is_visible() is False
1128 1127

  
1129 1128

  
1129
def test_cell_invalidity_marker():
1130
    page = Page.objects.create()
1131
    cell = TextCell.objects.create(page=page, order=0)
1132
    cell.mark_as_invalid('foo_bar_reason')
1133
    validity_info = ValidityInfo.objects.latest('pk')
1134
    old_reason = validity_info.invalid_reason_code
1135
    old_date = validity_info.invalid_since
1136

  
1137
    cell.mark_as_invalid('another_foo_bar_reason', force=False)
1138
    validity_info.refresh_from_db()
1139
    assert old_reason == validity_info.invalid_reason_code
1140
    assert old_date == validity_info.invalid_since
1141

  
1142
    cell.mark_as_invalid('another_foo_bar_reason')
1143
    validity_info.refresh_from_db()
1144
    assert validity_info.invalid_reason_code == 'another_foo_bar_reason'
1145
    assert old_date < validity_info.invalid_since
1146

  
1147
    cell.mark_as_valid()
1148
    assert ValidityInfo.objects.exists() is False
1149

  
1150

  
1130 1151
def test_hourly():
1131 1152
    appconfig = apps.get_app_config('data')
1132 1153
    page = Page.objects.create(title='xxx', slug='test_current_forms_cell_render', template_name='standard')
tests/test_manager.py
1 1
import base64
2
import json
2
import datetime
3
import mock
3 4
import os
4 5
import re
5 6
import shutil
6 7

  
7
import mock
8

  
9 8
from django.core.files.storage import default_storage
10 9
from django.urls import reverse
11 10
from django.conf import settings
12
from django.contrib.auth.models import User, Group
11
from django.contrib.auth.models import Group
13 12
from django.db import connection
14 13
from django.template import TemplateSyntaxError
15 14
from django.test import override_settings
16 15
from django.test.client import RequestFactory
17 16
from django.test.utils import CaptureQueriesContext
18 17
from django.utils.http import urlencode
18
from django.utils.timezone import now
19 19
from django.utils.six import BytesIO
20 20
from django.utils.six.moves.urllib import parse as urlparse
21 21

  
22 22
import pytest
23
from webtest import TestApp
24 23
from webtest import Upload
25 24

  
26
from combo.wsgi import application
27 25
from combo.data.forms import LinkCellForm
28 26
from combo.data.models import (
29 27
    Page, CellBase, TextCell, LinkCell, ConfigJsonCell, JsonCell, PageSnapshot,
......
169 167
    assert Page.objects.all()[0].exclude_from_navigation is False
170 168

  
171 169

  
172
def test_edit_page_cell_invalid_placeholder(app, admin_user):
170
def test_edit_page_cell_invalid_placeholder(freezer, app, admin_user):
171
    freezer.move_to('2020-06-05 12:00:01')
173 172
    page = Page.objects.create(title='One', slug='one', template_name='standard')
174 173
    cell = TextCell.objects.create(page=page, placeholder='content', text='Foobar', order=1)
175 174
    cell.mark_as_invalid('foo_bar_reason')
176
    validity_info = ValidityInfo.objects.latest('pk')
177
    old_reason = validity_info.invalid_reason_code
178
    old_date = validity_info.invalid_since
179 175

  
180 176
    app = login(app)
177
    ValidityInfo.objects.update(invalid_since=now() - datetime.timedelta(minutes=1))
181 178
    resp = app.get('/manage/pages/%s/' % page.pk)
182
    assert '<span class="invalid">foo_bar_reason</span>' in resp.text
179
    assert '<span class="invalid">foo_bar_reason' in resp.text
180
    assert 'This cell will no longer be displayed in 1 day, 23 hours' in resp.text
181

  
182
    ValidityInfo.objects.update(invalid_since=now() - datetime.timedelta(minutes=47*60-1))
183
    resp = app.get('/manage/pages/%s/' % page.pk)
184
    assert '<span class="invalid">foo_bar_reason' in resp.text
185
    assert 'This cell will no longer be displayed in 1 hour, 1 minute.' in resp.text
183 186

  
184
    cell.mark_as_invalid('another_foo_bar_reason', force=False)
185
    validity_info.refresh_from_db()
186
    assert old_reason == validity_info.invalid_reason_code
187
    assert old_date == validity_info.invalid_since
187
    ValidityInfo.objects.update(invalid_since=now() - datetime.timedelta(minutes=47*60+29))
188
    resp = app.get('/manage/pages/%s/' % page.pk)
189
    assert '<span class="invalid">foo_bar_reason' in resp.text
190
    assert 'This cell will no longer be displayed in 31 minutes.' in resp.text
188 191

  
189
    cell.mark_as_invalid('another_foo_bar_reason')
190
    validity_info.refresh_from_db()
191
    assert validity_info.invalid_reason_code == 'another_foo_bar_reason'
192
    assert old_date < validity_info.invalid_since
192
    ValidityInfo.objects.update(invalid_since=now() - datetime.timedelta(days=2))
193
    resp = app.get('/manage/pages/%s/' % page.pk)
194
    assert '<span class="invalid">foo_bar_reason' in resp.text
195
    assert 'This cell is no longer displayed since June 5, 2020, noon.' in resp.text
196

  
197
    ValidityInfo.objects.update(invalid_since=now() - datetime.timedelta(days=2, minutes=10*60+2))
198
    resp = app.get('/manage/pages/%s/' % page.pk)
199
    assert '<span class="invalid">foo_bar_reason' in resp.text
200
    assert 'This cell is no longer displayed since June 5, 2020, 1:58 a.m.' in resp.text
193 201

  
194 202
    cell.mark_as_valid()
195 203
    assert ValidityInfo.objects.exists() is False
196 204
    resp = app.get('/manage/pages/%s/' % page.pk)
197
    assert '<span class="invalid">foo_bar_reason</span>' not in resp.text
205
    assert '<span class="invalid">foo_bar_reason' not in resp.text
198 206

  
199 207
    cell2 = LinkListCell.objects.create(order=0, placeholder='content', page=page)
200 208
    item = LinkCell.objects.create(page=page, placeholder=cell2.link_placeholder, order=0)
201 209
    item.mark_as_invalid('foo_bar_reason')
202 210
    cell2.check_validity()
203 211
    resp = app.get('/manage/pages/%s/' % page.pk)
204
    assert '<span class="invalid">Invalid link</span>' in resp.text
212
    assert '<span class="invalid">Invalid link' in resp.text
213
    assert 'This cell will no longer be displayed in 2 days.' in resp.text
205 214
    assert '<span class="invalid">foo_bar_reason</span>' in resp.text
206 215

  
207 216

  
208
-