From e4902845118aa3807f0c9f056c09a5fe9872a5d2 Mon Sep 17 00:00:00 2001
From: Eliot Berriot <contact@eliotberriot.com>
Date: Thu, 1 Mar 2018 20:38:48 +0100
Subject: [PATCH] Use our new event system for track favorites

---
 api/funkwhale_api/favorites/activities.py | 17 +++++++++
 api/funkwhale_api/favorites/consumers.py  |  0
 api/funkwhale_api/favorites/views.py      |  2 ++
 api/tests/favorites/test_activity.py      | 43 +++++++++++++++++++++++
 api/tests/favorites/test_favorites.py     | 24 ++++++++++++-
 5 files changed, 85 insertions(+), 1 deletion(-)
 create mode 100644 api/funkwhale_api/favorites/activities.py
 create mode 100644 api/funkwhale_api/favorites/consumers.py

diff --git a/api/funkwhale_api/favorites/activities.py b/api/funkwhale_api/favorites/activities.py
new file mode 100644
index 00000000..a9deef55
--- /dev/null
+++ b/api/funkwhale_api/favorites/activities.py
@@ -0,0 +1,17 @@
+from funkwhale_api.common import channels
+from funkwhale_api.activity import record
+
+from . import serializers
+
+record.registry.register_serializer(
+    serializers.TrackFavoriteActivitySerializer)
+
+
+@record.registry.register_consumer('favorites.TrackFavorite')
+def broadcast_track_favorite_to_instance_timeline(data, obj):
+    if obj.user.privacy_level not in ['instance', 'everyone']:
+        return
+    channels.group_send('instance_timeline', {
+        'type': 'event',
+        'data': data
+    })
diff --git a/api/funkwhale_api/favorites/consumers.py b/api/funkwhale_api/favorites/consumers.py
new file mode 100644
index 00000000..e69de29b
diff --git a/api/funkwhale_api/favorites/views.py b/api/funkwhale_api/favorites/views.py
index 08ae00b6..d874c9e1 100644
--- a/api/funkwhale_api/favorites/views.py
+++ b/api/funkwhale_api/favorites/views.py
@@ -4,6 +4,7 @@ from rest_framework.response import Response
 from rest_framework import pagination
 from rest_framework.decorators import list_route
 
+from funkwhale_api.activity import record
 from funkwhale_api.music.models import Track
 from funkwhale_api.common.permissions import ConditionalAuthentication
 
@@ -33,6 +34,7 @@ class TrackFavoriteViewSet(mixins.CreateModelMixin,
         instance = self.perform_create(serializer)
         serializer = self.get_serializer(instance=instance)
         headers = self.get_success_headers(serializer.data)
+        record.send(instance)
         return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
 
     def get_queryset(self):
diff --git a/api/tests/favorites/test_activity.py b/api/tests/favorites/test_activity.py
index b4d76658..84778fd0 100644
--- a/api/tests/favorites/test_activity.py
+++ b/api/tests/favorites/test_activity.py
@@ -1,5 +1,6 @@
 from funkwhale_api.users.serializers import UserActivitySerializer
 from funkwhale_api.favorites import serializers
+from funkwhale_api.favorites import activities
 
 
 def test_get_favorite_activity_url(settings, factories):
@@ -26,3 +27,45 @@ def test_activity_favorite_serializer(factories):
     data = serializers.TrackFavoriteActivitySerializer(favorite).data
 
     assert data == expected
+
+
+def test_track_favorite_serializer_is_connected(activity_registry):
+    conf = activity_registry['favorites.TrackFavorite']
+    assert conf['serializer'] == serializers.TrackFavoriteActivitySerializer
+
+
+def test_track_favorite_serializer_instance_activity_consumer(
+        activity_registry):
+    conf = activity_registry['favorites.TrackFavorite']
+    consumer = activities.broadcast_track_favorite_to_instance_timeline
+    assert consumer in conf['consumers']
+
+
+def test_broadcast_track_favorite_to_instance_timeline(
+        factories, mocker):
+    p = mocker.patch('funkwhale_api.common.channels.group_send')
+    favorite = factories['favorites.TrackFavorite']()
+    data = serializers.TrackFavoriteActivitySerializer(favorite).data
+    consumer = activities.broadcast_track_favorite_to_instance_timeline
+    message = {
+        "type": 'event',
+        "data": data
+    }
+    consumer(data=data, obj=favorite)
+    p.assert_called_once_with('instance_timeline', message)
+
+
+def test_broadcast_track_favorite_to_instance_timeline_private(
+        factories, mocker):
+    p = mocker.patch('funkwhale_api.common.channels.group_send')
+    favorite = factories['favorites.TrackFavorite'](
+        user__privacy_level='me'
+    )
+    data = serializers.TrackFavoriteActivitySerializer(favorite).data
+    consumer = activities.broadcast_track_favorite_to_instance_timeline
+    message = {
+        "type": 'event',
+        "data": data
+    }
+    consumer(data=data, obj=favorite)
+    p.assert_not_called()
diff --git a/api/tests/favorites/test_favorites.py b/api/tests/favorites/test_favorites.py
index 8165722e..f4a045af 100644
--- a/api/tests/favorites/test_favorites.py
+++ b/api/tests/favorites/test_favorites.py
@@ -33,7 +33,8 @@ def test_user_can_get_his_favorites(factories, logged_in_client, client):
     assert expected == parsed_json['results']
 
 
-def test_user_can_add_favorite_via_api(factories, logged_in_client, client):
+def test_user_can_add_favorite_via_api(
+        factories, logged_in_client, activity_muted):
     track = factories['music.Track']()
     url = reverse('api:v1:favorites:tracks-list')
     response = logged_in_client.post(url, {'track': track.pk})
@@ -51,6 +52,27 @@ def test_user_can_add_favorite_via_api(factories, logged_in_client, client):
     assert favorite.user == logged_in_client.user
 
 
+def test_adding_favorites_calls_activity_record(
+        factories, logged_in_client, activity_muted):
+    track = factories['music.Track']()
+    url = reverse('api:v1:favorites:tracks-list')
+    response = logged_in_client.post(url, {'track': track.pk})
+
+    favorite = TrackFavorite.objects.latest('id')
+    expected = {
+        'track': track.pk,
+        'id': favorite.id,
+        'creation_date': favorite.creation_date.isoformat().replace('+00:00', 'Z'),
+    }
+    parsed_json = json.loads(response.content.decode('utf-8'))
+
+    assert expected == parsed_json
+    assert favorite.track == track
+    assert favorite.user == logged_in_client.user
+
+    activity_muted.assert_called_once_with(favorite)
+
+
 def test_user_can_remove_favorite_via_api(logged_in_client, factories, client):
     favorite = factories['favorites.TrackFavorite'](user=logged_in_client.user)
     url = reverse('api:v1:favorites:tracks-detail', kwargs={'pk': favorite.pk})
-- 
GitLab