Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 25 additions & 1 deletion kitsune/notifications/api.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import django_filters
from rest_framework import serializers, viewsets, permissions, mixins, status
from rest_framework.decorators import action
from rest_framework.response import Response
Expand Down Expand Up @@ -42,6 +43,26 @@ class Meta:
)


class NotificationFilter(django_filters.FilterSet):
is_read = django_filters.MethodFilter(action='filter_is_read')

class Meta(object):
model = Notification
fields = [
'is_read',
]

# This has to be a method filter because ``is_read`` is not a database field
# of ``Notification``, so BooleanFilter (and friends) don't work on it.
def filter_is_read(self, queryset, value):
if value in ['1', 'true', 'True', 1, True]:
return queryset.exclude(read_at=None)
elif value in ['0', 'false', 'False', 0, False]:
return queryset.filter(read_at=None)
else:
return queryset


class NotificationViewSet(mixins.ListModelMixin,
mixins.RetrieveModelMixin,
viewsets.GenericViewSet):
Expand All @@ -51,9 +72,12 @@ class NotificationViewSet(mixins.ListModelMixin,
permissions.IsAuthenticated,
OnlyOwner,
]
filter_class = NotificationFilter
filter_fields = ['is_read']

def get_queryset(self, *args, **kwargs):
return self.model.objects.filter(owner=self.request.user)
qs = super(NotificationViewSet, self).get_queryset(*args, **kwargs)
return qs.filter(owner=self.request.user)

@action(methods=['POST'])
def mark_read(self, request, pk=None):
Expand Down
53 changes: 36 additions & 17 deletions kitsune/notifications/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,32 +86,51 @@ class TestNotificationViewSet(TestCase):
def setUp(self):
self.client = APIClient()

follower = profile()
followed = profile()
q = question(creator=followed.user, save=True)
self.follower = profile().user
self.followed = profile().user
self.question = question(creator=self.followed, save=True)
# The above might make follows, which this test isn't about. Clear them out.
Follow.objects.all().delete()
follow(self.follower, self.followed)

follow(follower.user, followed.user)

# Make a new action for the above. This should trigger notifications
action.send(followed.user, verb='asked', action_object=q)
def _makeNotification(self, is_read=False):
# Make a new action. This should trigger notifications
action.send(self.followed, verb='asked', action_object=self.question)
act = Action.objects.order_by('-id')[0]
self.notification = Notification.objects.get(action=act)
n = Notification.objects.get(action=act)
if is_read:
n.is_read = True
n.save()
return n

def test_mark_read(self):
eq_(self.notification.is_read, False)
self.client.force_authenticate(user=self.notification.owner)
req = self.client.post(reverse('notification-mark-read', args=[self.notification.id]))
n = self._makeNotification()
self.client.force_authenticate(user=self.follower)
req = self.client.post(reverse('notification-mark-read', args=[n.id]))
eq_(req.status_code, 204)
n = Notification.objects.get(id=self.notification.id)
n = Notification.objects.get(id=n.id)
eq_(n.is_read, True)

def test_mark_unread(self):
self.notification.is_read = True
self.notification.save()
self.client.force_authenticate(user=self.notification.owner)
req = self.client.post(reverse('notification-mark-unread', args=[self.notification.id]))
n = self._makeNotification(is_read=True)
self.client.force_authenticate(user=self.follower)
req = self.client.post(reverse('notification-mark-unread', args=[n.id]))
eq_(req.status_code, 204)
n = Notification.objects.get(id=self.notification.id)
n = Notification.objects.get(id=n.id)
eq_(n.is_read, False)

def test_filter_is_read_false(self):
n = self._makeNotification(is_read=False)
self._makeNotification(is_read=True)
self.client.force_authenticate(user=self.follower)
req = self.client.get(reverse('notification-list') + '?is_read=0')
eq_(req.status_code, 200)
eq_([d['id'] for d in req.data], [n.id])

def test_filter_is_read_true(self):
self._makeNotification(is_read=False)
n = self._makeNotification(is_read=True)
self.client.force_authenticate(user=self.follower)
req = self.client.get(reverse('notification-list') + '?is_read=1')
eq_(req.status_code, 200)
eq_([d['id'] for d in req.data], [n.id])