Projet

Général

Profil

0004-notifications-allow-notifications-without-an-end_tim.patch

Benjamin Dauvergne, 24 mars 2018 02:29

Télécharger (6,78 ko)

Voir les différences:

Subject: [PATCH 4/5] notifications: allow notifications without an
 end_timestamp (#22732)

Those notifications will disappear only with an action of the user.
 .../migrations/0005_auto_20180324_0025.py          | 20 +++++++
 combo/apps/notifications/models.py                 | 21 ++++---
 tests/test_notification.py                         | 66 ++++++++++++++++++++++
 3 files changed, 100 insertions(+), 7 deletions(-)
 create mode 100644 combo/apps/notifications/migrations/0005_auto_20180324_0025.py
combo/apps/notifications/migrations/0005_auto_20180324_0025.py
1
# -*- coding: utf-8 -*-
2
# Generated by Django 1.11.11 on 2018-03-24 00:25
3
from __future__ import unicode_literals
4

  
5
from django.db import migrations, models
6

  
7

  
8
class Migration(migrations.Migration):
9

  
10
    dependencies = [
11
        ('notifications', '0004_auto_20180316_1026'),
12
    ]
13

  
14
    operations = [
15
        migrations.AlterField(
16
            model_name='notification',
17
            name='end_timestamp',
18
            field=models.DateTimeField(null=True, verbose_name='End date and time'),
19
        ),
20
    ]
combo/apps/notifications/models.py
42 42
        return qs.filter(search_id)
43 43

  
44 44
    def ack(self):
45
        self.update(acked=True)
45
        self.filter(end_timestamp__isnull=True).update(acked=True, end_timestamp=now() - timedelta(seconds=5))
46
        self.filter(end_timestamp__isnull=False).update(acked=True)
46 47

  
47 48
    def visible(self, user=None, n=None):
48 49
        qs = self
49 50
        if user:
50 51
            qs = qs.filter(user=user)
51 52
        n = n or now()
52
        qs = qs.filter(start_timestamp__lte=n, end_timestamp__gt=n)
53
        qs = qs.filter(Q(start_timestamp__lte=n) & (Q(end_timestamp__isnull=True) | Q(end_timestamp__gte=n)))
53 54
        return qs.order_by('-start_timestamp')
54 55

  
55 56
    def new(self):
......
72 73
    url = models.URLField(_('URL'), default='', blank=True)
73 74
    origin = models.CharField(_('Origin'), max_length=100, blank=True)
74 75
    start_timestamp = models.DateTimeField(_('Start date and time'))
75
    end_timestamp = models.DateTimeField(_('End date and time'))
76
    end_timestamp = models.DateTimeField(_('End date and time'), null=True)
76 77
    acked = models.BooleanField(_('Acked'), default=False)
77 78
    external_id = models.SlugField(_('External identifier'), null=True)
78 79

  
79

  
80 80
    class Meta:
81 81
        verbose_name = _('Notification')
82 82
        unique_together = (
......
104 104
        '''
105 105
        start_timestamp = start_timestamp or now()
106 106

  
107
        if duration:
107
        if duration == 0:
108
            end_timestamp = None
109
        elif duration:
108 110
            if not isinstance(duration, timedelta):
109 111
                duration = timedelta(seconds=duration)
110 112
            end_timestamp = start_timestamp + duration
......
155 157
        self.save(update_fields=['end_timestamp', 'acked'])
156 158

  
157 159
    def ack(self):
158
        self.acked = True
159
        self.save(update_fields=['acked'])
160
        if self.end_timestamp:
161
            self.acked = True
162
            self.save(update_fields=['acked'])
163
        else:
164
            self.acked = True
165
            self.end_timestamp = now() - timedelta(seconds=5)
166
            self.save(update_fields=['acked', 'end_timestamp'])
160 167

  
161 168

  
162 169
@register_cell_class
tests/test_notification.py
3 3
import mock
4 4
import pytest
5 5
from decimal import Decimal
6
from datetime import timedelta as timedelta
6 7

  
7 8
from django.test.client import RequestFactory
8 9
from django.utils.timezone import timedelta, now
......
348 349
    # be sure the are no more reminders created
349 350
    regie.notify_new_remote_invoices()
350 351
    assert Notification.objects.count() == 4
352

  
353

  
354
def test_notification_never_expire(app, freezer, rf, john_doe):
355
    start = freezer()
356

  
357
    app.authorization = ('Basic', (john_doe.username, john_doe.username))
358
    app.post_json(reverse('api-notification-add'), params={
359
        'summary': 'notibar',
360
        'url': 'http://www.example.net',
361
        'body': 'foobar',
362
        'origin': 'blah',
363
        'duration': 0,
364
    })
365
    app.post_json(reverse('api-notification-add'), params={
366
        'summary': 'notifoo',
367
        'url': 'http://www.example.net',
368
        'body': 'foobar',
369
        'origin': 'blah',
370
        'duration': 86400 * 2,  # 2 days
371
    })
372
    page = Page.objects.create(title='notif', slug='test_notification_cell', template_name='standard')
373
    cell = NotificationsCell(page=page, placeholder='content', order=0)
374

  
375
    request = rf.get('/')
376
    request.user = john_doe
377
    context = {'request': request}
378

  
379
    freezer.move_to(start - timedelta(seconds=10))
380
    assert Notification.objects.visible(john_doe).count() == 0
381
    content = cell.render(context)
382
    assert 'notibar' not in content
383
    assert 'notifoo' not in content
384

  
385
    freezer.move_to(start + timedelta(seconds=10))
386
    assert Notification.objects.visible(john_doe).count() == 2
387
    content = cell.render(context)
388
    assert 'notibar' in content
389
    assert 'notifoo' in content
390

  
391
    freezer.move_to(start + timedelta(days=1))
392
    content = cell.render(context)
393
    assert Notification.objects.visible(john_doe).count() == 2
394
    assert 'notibar' in content
395
    assert 'notifoo' in content
396

  
397
    freezer.move_to(start + timedelta(days=3))
398
    content = cell.render(context)
399
    assert Notification.objects.visible(john_doe).count() == 1
400
    assert 'notibar' in content
401
    assert 'notifoo' not in content
402

  
403
    freezer.move_to(start + timedelta(days=365))
404
    content = cell.render(context)
405
    assert Notification.objects.visible(john_doe).count() == 1
406
    assert 'notibar' in content
407
    assert 'notifoo' not in content
408

  
409
    Notification.objects.visible(john_doe).ack()
410

  
411
    # acking a notification without and end_timestamp, forget it
412
    freezer.move_to(start + timedelta(days=365, seconds=1))
413
    content = cell.render(context)
414
    assert Notification.objects.visible(john_doe).count() == 0
415
    assert 'notibar' not in content
416
    assert 'notifoo' not in content
351
-