0004-notifications-allow-notifications-without-an-end_tim.patch
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 |
- |