def test_follow(self):
        url = FOLLOW_URL.format(self.ray.id)

        # login to follow others
        response = self.anonymous_client.post(url)
        self.assertEqual(response.status_code, 403)
        # use GET to follow
        response = self.lux_client.get(url)
        self.assertEqual(response.status_code, 405)
        # can't follow yourself
        response = self.ray_client.post(url)
        self.assertEqual(response.status_code, 400)
        # follow successfully
        response = self.lux_client.post(url)
        self.assertEqual(response.status_code, 201)
        # repeating follow is muted instead of throwing exceptions
        response = self.lux_client.post(url)
        self.assertEqual(response.status_code, 201)
        self.assertEqual(response.data['duplicate'], True)
        # reverse follow will create new data
        before_count = FriendshipService.get_following_count(self.ray.id)
        response = self.ray_client.post(FOLLOW_URL.format(self.lux.id))
        self.assertEqual(response.status_code, 201)
        after_count = FriendshipService.get_following_count(self.ray.id)
        self.assertEqual(after_count, before_count + 1)
    def test_unfollow(self):
        url = UNFOLLOW_URL.format(self.ray.id)

        # log in to unfollow others
        response = self.anonymous_client.post(url)
        self.assertEqual(response.status_code, 403)
        # can't use get to unfollow others
        response = self.lux_client.get(url)
        self.assertEqual(response.status_code, 405)
        # can't unfollow yourself
        response = self.ray_client.post(url)
        self.assertEqual(response.status_code, 400)
        # unfollow successfully
        self.create_friendship(from_user=self.lux, to_user=self.ray)
        before_count = FriendshipService.get_following_count(self.lux.id)
        response = self.lux_client.post(url)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data['deleted'], 1)
        after_count = FriendshipService.get_following_count(self.lux.id)
        self.assertEqual(after_count, before_count - 1)
        # If not following, unfollow request will be muted
        before_count = FriendshipService.get_following_count(self.lux.id)
        response = self.lux_client.post(url)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data['deleted'], 0)
        after_count = FriendshipService.get_following_count(self.lux.id)
        self.assertEqual(before_count, after_count)
Exemple #3
0
    def test_follow(self):
        url = FOLLOW_URL.format(self.linghu.id)

        # 需要登录才能 follow 别人
        response = self.anonymous_client.post(url)
        self.assertEqual(response.status_code, 403)
        # 要用 get 来 follow
        response = self.dongxie_client.get(url)
        self.assertEqual(response.status_code, 405)
        # 不可以 follow 自己
        response = self.linghu_client.post(url)
        self.assertEqual(response.status_code, 400)
        # follow 成功
        response = self.dongxie_client.post(url)
        self.assertEqual(response.status_code, 201)
        # 重复 follow 静默成功
        response = self.dongxie_client.post(url)
        self.assertEqual(response.status_code, 400)
        self.assertEqual(response.data['success'], False)
        # 反向关注会创建新的数据
        before_count = FriendshipService.get_following_count(self.linghu.id)
        response = self.linghu_client.post(FOLLOW_URL.format(self.dongxie.id))
        self.assertEqual(response.status_code, 201)
        after_count = FriendshipService.get_following_count(self.linghu.id)
        self.assertEqual(after_count, before_count + 1)
Exemple #4
0
    def test_follow(self):
        url = FOLLOW_URL.format(self.linghu.id)

        # 需要登录才能 follow 别人
        response = self.anonymous_client.post(url)
        self.assertEqual(response.status_code, 403)
        # 要用 get 来 follow
        response = self.dongxie_client.get(url)
        self.assertEqual(response.status_code, 405)
        # 不可以 follow 自己
        response = self.linghu_client.post(url)
        self.assertEqual(response.status_code, 400)

        # follow 成功
        response = self.dongxie_client.post(url)
        # self.assertEqual(response.status_code, 201)
        # self.assertEqual('created_at' in response.data, True)
        # self.assertEqual('user' in response.data, True)
        # self.assertEqual(response.data['user']['id'], self.linghu.id)
        # self.assertEqual(response.data['user']['username'], self.linghu.username)

        # 重复 follow 会 400
        response = self.dongxie_client.post(url)
        self.assertEqual(response.status_code, 400)

        # 反向关注会创建新的数据
        before_count = FriendshipService.get_following_count(self.linghu.id)
        response = self.linghu_client.post(FOLLOW_URL.format(self.dongxie.id))
        self.assertEqual(response.status_code, 201)
        after_count = FriendshipService.get_following_count(self.linghu.id)
        self.assertEqual(after_count, before_count + 1)
Exemple #5
0
    def test_follow(self):
        url = FOLLOW_URL.format(self.linghu.id)

        # need login first, then follow others
        response = self.anonymous_client.post(url)
        self.assertEqual(response.status_code, 403)
        # use get to follow
        response = self.dongxie_client.get(url)
        self.assertEqual(response.status_code, 405)
        # cannot follow yourself
        response = self.linghu_client.post(url)
        self.assertEqual(response.status_code, 400)
        # follow success
        response = self.dongxie_client.post(url)
        self.assertEqual(response.status_code, 201)
        #self.assertEqual('created_at' in response.data, True)
        #self.assertEqual('user' in response.data, True)
        #self.assertEqual(response.data['user']['id'], self.linghu.id)
        #self.assertEqual(response.data['user']['username'], self.linghu.username)
        # dup follow, silent success
        response = self.dongxie_client.post(url)
        self.assertEqual(response.status_code, 201)
        self.assertEqual(response.data['duplicate'], True)
        # follow reversely will create new relation
        before_count = FriendshipService.get_following_count(self.linghu.id)
        response = self.linghu_client.post(FOLLOW_URL.format(self.dongxie.id))
        self.assertEqual(response.status_code, 201)
        after_count = FriendshipService.get_following_count(self.linghu.id)
        self.assertEqual(after_count, before_count + 1)
Exemple #6
0
    def test_unfollow(self):
        url = UNFOLLOW_URL.format(self.linghu.id)

        # 需要登录才能 unfollow 别人
        response = self.anonymous_client.post(url)
        self.assertEqual(response.status_code, 403)
        # 不能用 get 来 unfollow 别人
        response = self.dongxie_client.get(url)
        self.assertEqual(response.status_code, 405)
        # 不能用 unfollow 自己
        response = self.linghu_client.post(url)
        self.assertEqual(response.status_code, 400)

        # unfollow 成功
        self.create_friendship(self.dongxie, self.linghu)
        before_count = FriendshipService.get_following_count(self.dongxie.id)
        response = self.dongxie_client.post(url)
        after_count = FriendshipService.get_following_count(self.dongxie.id)
        self.assertEqual(response.status_code, 204)
        self.assertEqual(response.data['deleted'], 1)
        self.assertEqual(after_count, before_count - 1)

        # 未 follow 的情况下 unfollow 静默处理
        before_count = FriendshipService.get_following_count(self.dongxie.id)
        response = self.dongxie_client.post(url)
        after_count = FriendshipService.get_following_count(self.dongxie.id)
        self.assertEqual(response.status_code, 204)
        self.assertEqual(response.data['deleted'], 0)
        self.assertEqual(after_count, before_count)
Exemple #7
0
    def test_follow(self):
        url = FOLLOW_URL.format(self.linghu.id)

        # cannot follow without login
        response = self.anonymous_client.post(url)
        self.assertEqual(response.status_code, 403)
        # fail to follow through get
        response = self.dongxie_client.get(url)
        self.assertEqual(response.status_code, 405)
        # cannot self-follow
        response = self.linghu_client.post(url)
        self.assertEqual(response.status_code, 400)
        # success
        response = self.dongxie_client.post(url)
        self.assertEqual(response.status_code, 201)
        # duplicate follow
        response = self.dongxie_client.post(url)
        self.assertEqual(response.status_code, 201)
        self.assertEqual(response.data['duplicate'], True)
        # mutual follow
        count = FriendshipService.get_following_count(self.linghu.id)
        response = self.linghu_client.post(FOLLOW_URL.format(self.dongxie.id))
        self.assertEqual(response.status_code, 201)
        self.assertEqual(FriendshipService.get_following_count(self.linghu.id),
                         count + 1)
Exemple #8
0
 def _test_follow(self):
     self._create_dummy_friendship()
     # only allow POST method
     response = self.user2_client.get(FOLLOW_URL.format(self.user3.id))
     self.assertEqual(response.status_code, 405)
     # anonymous client not allowed
     response = self.anonymous_client.post(FOLLOW_URL.format(self.user3.id))
     self.assertEqual(response.status_code, 403)
     # follow non-existed user
     # user_id 999 not exists
     response = self.user2_client.post(FOLLOW_URL.format(999))
     self.assertEqual(response.status_code, 404)
     # not support follow myself
     response = self.user2_client.post(FOLLOW_URL.format(self.user2.id))
     self.assertEqual(response.status_code, 201)
     # follow
     before_count = FriendshipService.get_following_count(self.user2.id)
     response = self.user2_client.post(FOLLOW_URL.format(self.user3.id))
     self.assertEqual(response.status_code, 201)
     self.assertEqual(response.data['success'], True)
     self.assertEqual(response.data['friendship']['from_user_id'],
                      self.user2.id)
     self.assertEqual(response.data['friendship']['to_user_id'],
                      self.user3.id)
     after_count = FriendshipService.get_following_count(self.user2.id)
     self.assertEqual(before_count + 1, after_count)
     # re-follow throws error
     before_count = FriendshipService.get_following_count(self.user2.id)
     response = self.user2_client.post(FOLLOW_URL.format(self.user3.id))
     self.assertEqual(response.status_code, 201)
     self.assertEqual(response.data['success'], True)
     self.assertEqual(response.data['duplicated'], True)
     after_count = FriendshipService.get_following_count(self.user2.id)
     self.assertEqual(before_count, after_count)
Exemple #9
0
 def _test_unfollow(self):
     self._create_dummy_friendship()
     # only allow POST method
     response = self.user2_client.get(UNFOLLOW_URL.format(self.user3.id))
     self.assertEqual(response.status_code, 405)
     # anonymous client not allowed
     response = self.anonymous_client.post(
         UNFOLLOW_URL.format(self.user3.id))
     self.assertEqual(response.status_code, 403)
     # unfollow non-existed user, user_id 999 not exists
     response = self.user2_client.post(UNFOLLOW_URL.format(999))
     self.assertEqual(response.status_code, 404)
     # not support unfollow myself
     response = self.user2_client.post(UNFOLLOW_URL.format(self.user2.id))
     self.assertEqual(response.status_code, 400)
     self.assertEqual(response.data['success'], False)
     self.assertEqual(response.data['message'],
                      "You cannot unfollow yourself.")
     # unfollow
     before_count = FriendshipService.get_following_count(self.user2.id)
     response = self.user2_client.post(UNFOLLOW_URL.format(self.user1.id))
     self.assertEqual(response.status_code, 200)
     self.assertEqual(response.data['success'], True)
     self.assertEqual(int(response.data['deleted']), 1)
     after_count = FriendshipService.get_following_count(self.user2.id)
     self.assertEqual(before_count - 1, after_count)
     # re-unfollow
     before_count = FriendshipService.get_following_count(self.user2.id)
     response = self.user2_client.post(UNFOLLOW_URL.format(self.user1.id))
     self.assertEqual(response.status_code, 400)
     self.assertEqual(response.data, 'Friendship not exists')
     after_count = FriendshipService.get_following_count(self.user2.id)
     self.assertEqual(before_count, after_count)
Exemple #10
0
    def test_unfollow(self):
        url = UNFOLLOW_URL.format(self.linghu.id)

        # need login first, then unfollow others
        response = self.anonymous_client.post(url)
        self.assertEqual(response.status_code, 403)
        # cannot use get to unfollow
        response = self.dongxie_client.get(url)
        self.assertEqual(response.status_code, 405)
        # cannot unfollow yourself
        response = self.linghu_client.post(url)
        self.assertEqual(response.status_code, 400)
        # unfollow success
        self.create_friendship(from_user=self.dongxie, to_user=self.linghu)
        before_count = FriendshipService.get_following_count(self.dongxie.id)
        response = self.dongxie_client.post(url)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data['deleted'], 1)
        after_count = FriendshipService.get_following_count(self.dongxie.id)
        self.assertEqual(after_count, before_count - 1)
        # unfollow, then unfollow,
        before_count = FriendshipService.get_following_count(self.dongxie.id)
        response = self.dongxie_client.post(url)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data['deleted'], 0)
        after_count = FriendshipService.get_following_count(self.dongxie.id)
        self.assertEqual(before_count, after_count)
Exemple #11
0
    def test_unfollow(self):
        url = UNFOLLOW_URL.format(self.alex.id)

        # need to login to unfollow others
        response = self.anonymous_client.post(url)
        self.assertEqual(response.status_code, 403)
        # need to use post to unfollow
        response = self.bob_client.get(url)
        self.assertEqual(response.status_code, 405)
        # you cannot unfollow yourself
        response = self.alex_client.post(url)
        self.assertEqual(response.status_code, 400)
        # successful unfollow
        self.create_friendship(from_user=self.bob, to_user=self.alex)
        before_count = FriendshipService.get_following_count(self.bob.id)
        response = self.bob_client.post(url)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data['deleted'], 1)
        after_count = FriendshipService.get_following_count(self.bob.id)
        self.assertEqual(after_count, before_count - 1)
        # unfollow a person that you haven't followed, silent process
        before_count = FriendshipService.get_following_count(self.alex.id)
        response = self.bob_client.post(url)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data['deleted'], 0)
        after_count = FriendshipService.get_following_count(self.alex.id)
        self.assertEqual(before_count, after_count)
Exemple #12
0
    def test_follow(self):
        url = FOLLOW_URL.format(self.alex.id)

        # need to login to follow others
        response = self.anonymous_client.post(url)
        self.assertEqual(response.status_code, 403)
        # need to use post to follow
        response = self.bob_client.get(url)
        self.assertEqual(response.status_code, 405)
        # you cannot follow yourself
        response = self.alex_client.post(url)
        self.assertEqual(response.status_code, 400)
        # successful follow
        response = self.bob_client.post(url)
        self.assertEqual(response.status_code, 201)
        # self.assertEqual('user' in response.data, True)
        self.assertEqual('created_at' in response.data, True)
        self.assertEqual(response.data['user']['id'], self.alex.id)
        self.assertEqual(response.data['user']['username'], self.alex.username)

        # duplicate follow silent process
        response = self.bob_client.post(url)
        self.assertEqual(response.status_code, 400)
        self.assertEqual(response.data['duplicate'], True)

        # follow back will create new records
        before_count = FriendshipService.get_following_count(self.alex.id)
        response = self.alex_client.post(FOLLOW_URL.format(self.bob.id))
        self.assertEqual(response.status_code, 201)
        after_count = FriendshipService.get_following_count(self.alex.id)
        self.assertEqual(after_count, before_count + 1)
Exemple #13
0
    def test_get_following_user_id_set(self):
        FriendshipService.invalidate_following_cache(
            from_user_id=self.user2.id)
        user_id_set_2 = FriendshipService.get_following_user_id_set(
            self.user2.id)
        self.assertEqual(user_id_set_2, {self.user1.id, self.user3.id})
        user_id_set_1 = FriendshipService.get_following_user_id_set(
            self.user1.id)
        self.assertEqual(user_id_set_1, {self.user2.id})

        Friendship.objects.filter(
            from_user=self.user2,
            to_user=self.user3,
        ).delete()
        Friendship.objects.filter(
            from_user=self.user1,
            to_user=self.user2,
        ).delete()
        # mannually clear the cache
        FriendshipService.invalidate_following_cache(
            from_user_id=self.user2.id)
        user_id_set_2 = FriendshipService.get_following_user_id_set(
            self.user2.id)
        self.assertEqual(user_id_set_2, {self.user1.id})
        # cache automatically cleared in delete() by listener
        user_id_set_1 = FriendshipService.get_following_user_id_set(
            self.user1.id)
        self.assertEqual(len(user_id_set_1), 0)
        # cache automatically cleared in create() by listener
        Friendship.objects.create(from_user=self.user1, to_user=self.user3)
        user_id_set_1 = FriendshipService.get_following_user_id_set(
            self.user1.id)
        self.assertEqual(user_id_set_1, {self.user3.id})
Exemple #14
0
    def test_get_followings(self):
        user1 = self.create_user('user1')
        user2 = self.create_user('user2')
        for to_user in [user1, user2, self.alex]:
            self.create_friendship(from_user=self.bob, to_user=to_user)
        user_id_set = FriendshipService.get_following_user_id_set(self.bob.id)
        self.assertEqual(user_id_set, {user1.id, user2.id, self.alex.id})

        FriendshipService.unfollow(self.bob.id, self.alex.id)
        user_id_set = FriendshipService.get_following_user_id_set(self.bob.id)
        self.assertEqual(user_id_set, {user1.id, user2.id})
Exemple #15
0
    def test_get_following(self):
        user1 = self.create_user('user1')
        user2 = self.create_user('user2')
        for to_user in [user1, user2, self.ming]:
            self.create_friendship(self.rui, to_user)

        user_id_set = FriendshipService.get_following_user_id_set(self.rui.id)
        self.assertSetEqual(user_id_set, {user1.id, user2.id, self.ming.id})

        FriendshipService.unfollow(self.rui.id, self.ming.id)
        user_id_set = FriendshipService.get_following_user_id_set(self.rui.id)
        self.assertSetEqual(user_id_set, {user1.id, user2.id})
Exemple #16
0
    def test_get_followings(self):
        user1 = self.create_user('user1')
        user2 = self.create_user('user2')
        for to_user in [user1, user2, self.lux]:
            Friendship.objects.create(from_user=self.ray, to_user=to_user)

        user_id_set = FriendshipService.get_following_user_id_set(self.ray.id)
        self.assertSetEqual(user_id_set, {user1.id, user2.id, self.lux.id})

        Friendship.objects.filter(from_user=self.ray,
                                  to_user=self.lux).delete()
        user_id_set = FriendshipService.get_following_user_id_set(self.ray.id)
        self.assertSetEqual(user_id_set, {user1.id, user2.id})
Exemple #17
0
    def test_get_followings(self):
        user3 = self.create_user('user3')
        user4 = self.create_user('user4')
        for to_user in [self.user2, user3, user4]:
            Friendship.objects.create(to_user=to_user, from_user=self.user1)
        user_id_set = FriendshipService.get_following_user_id_set(
            self.user1.id)
        self.assertEqual(user_id_set, {self.user2.id, user3.id, user4.id})

        Friendship.objects.filter(to_user=self.user2,
                                  from_user=self.user1).delete()
        user_id_set = FriendshipService.get_following_user_id_set(
            self.user1.id)
        self.assertEqual(user_id_set, {user3.id, user4.id})
Exemple #18
0
    def test_get_followings(self):
        user1 = self.create_user('user1')
        user2 = self.create_user('user2')
        for to_user in [user1, user2, self.dongxie]:
            Friendship.objects.create(from_user=self.linghu, to_user=to_user)

        user_id_set = FriendshipService.get_followed_user_id_set(
            self.linghu.id)
        self.assertEqual(user_id_set, {user1.id, user2.id, self.dongxie.id})

        Friendship.objects.filter(from_user=self.linghu,
                                  to_user=self.dongxie).delete()
        user_id_set = FriendshipService.get_followed_user_id_set(
            self.linghu.id)
        self.assertEqual(user_id_set, {user1.id, user2.id})
Exemple #19
0
    def follow(self, request, pk):
        # /api/friendships/<pk>/follow/
        # 特殊判断重复 follow 的情况(比如前端猛点好多少次 follow)
        # 静默处理,不报错,因为这类重复操作因为网络延迟的原因会比较多,没必要当做错误处理

        # get_object 会检测if user with id=pk 是否存在,如果不存在会return 404 异常
        follow_user = self.get_object()

        if FriendshipService.has_followed(request.user.id, int(pk)):
            return Response({
                'success': True,
                'duplicate': True,
            },
                            status=status.HTTP_201_CREATED)
        serializer = FriendshipSerializerForCreate(
            data={
                'from_user_id': request.user.id,
                'to_user_id': pk,
            })
        if not serializer.is_valid():
            return Response({
                'success': False,
                'errors': serializer.errors,
            },
                            status=status.HTTP_400_BAD_REQUEST)
        instance = serializer.save()
        return Response(
            # instead returning success=> true, returning the pk (the request tries to follow the pk) data
            # the return data includes user_id, created_at
            FollowingSerializer(instance, context={
                'request': request
            }).data,
            status=status.HTTP_201_CREATED,
        )
Exemple #20
0
 def create(self, validated_data):
     from_user_id = validated_data['from_user_id']
     to_user_id = validated_data['to_user_id']
     return FriendshipService.follow(
         from_user_id=from_user_id,
         to_user_id=to_user_id,
     )
 def follow(self, request, pk):
     if FriendshipService.has_followed(request.user.id, int(pk)):
         return Response({
             'success': True,
             'duplicate': True,
         },
                         status=status.HTTP_201_CREATED)
     serializer = FriendshipSerializerForCreate(
         data={
             'from_user_id': request.user.id,
             'to_user_id': pk,
         })
     if not serializer.is_valid():
         return Response({
             'success': False,
             'errors': serializer.errors,
         },
                         status=status.HTTP_400_BAD_REQUEST)
     instance = serializer.save()
     return Response(
         FollowingSerializer(instance, context={
             'request': request
         }).data,
         status=status.HTTP_201_CREATED,
     )
Exemple #22
0
    def unfollow(self, request, pk):
        to_user = self.get_object()
        # not support unfollow yourself
        if request.user.id == to_user.id:
            return Response(
                {
                    'success': False,
                    'message': "You cannot unfollow yourself."
                },
                status=status.HTTP_400_BAD_REQUEST)

        # delete the friendship
        delete = FriendshipService.unfollow(
            from_user_id=request.user.id,  # only logged in user can unfollow
            to_user_id=to_user.id,
        )
        # delete as the number of objects deleted
        if not delete:
            return Response('Friendship not exists',
                            status=status.HTTP_400_BAD_REQUEST)

        return Response({
            'success': True,
            'deleted': '{}'.format(delete),
        },
                        status=status.HTTP_200_OK)
Exemple #23
0
 def fanout_to_followers(cls, tweet):
     newsfeeds = [
         NewsFeed(user=follower, tweet=tweet)
         for follower in FriendshipService.get_followers(tweet.user)
     ]
     newsfeeds.append(NewsFeed(user=tweet.user, tweet=tweet))
     NewsFeed.objects.bulk_create(newsfeeds)
Exemple #24
0
    def follow(self, request, pk):
        # 特殊判断重复 follow 的情况(比如前端猛点好多少次 follow)
        # 静默处理,不报错,因为这类重复操作因为网络延迟的原因会比较多,没必要当做错误处理
        to_follow_user = self.get_object()
        if FriendshipService.has_followed(request.user.id, to_follow_user.id):
            return Response(
                {
                    'success': False,
                    'message': 'Please check input',
                    'errors': [{
                        'pk': f'You has followed user with id={pk}'
                    }],
                },
                status=status.HTTP_400_BAD_REQUEST)

        serializer = FriendshipSerializerForCreate(
            data={
                'from_user_id': request.user.id,
                'to_user_id': pk,
            })
        if not serializer.is_valid():
            return Response(
                {
                    "success": False,
                    "message": "Please check input.",
                    "errors": serializer.errors,
                },
                status=status.HTTP_400_BAD_REQUEST)
        instance = serializer.save()
        return Response(
            FollowingSerializer(instance, context={
                'request': request
            }).data,
            status=status.HTTP_201_CREATED,
        )
Exemple #25
0
    def follow(self, request, pk):
        # check i fuser with id=pk exists
        # self.get_object()
        # 特殊判断重复 follow 的情况 (比如前端猛点多次follow)
        # 静默处理, 不报错, 因为这类重复操作 因为网络延迟的原因会比较多, 没必要当做错误处理
        if FriendshipService.has_followed(request.user.id, int(pk)):
            return Response({
                'success': True,
                'duplicate': True,
            },
                            status=status.HTTP_201_CREATED)
        serializer = FriendshipSerializerForCreate(
            data={
                'from_user_id': request.user.id,
                'to_user_id': pk,
            })
        if not serializer.is_valid():
            return Response({
                'success': False,
                'errors': serializer.errors,
            },
                            status=status.HTTP_400_BAD_REQUEST)
        serializer.save()

        return Response({'success': True}, status=status.HTTP_201_CREATED)
Exemple #26
0
 def follow(self, request, pk):
     # egde case check: duplicate follow action (e.g. multiple clicks from frontend)
     # silent processing. No need to report error.
     # because this kind of duplicated operation are mostly because of internet delay,
     if FriendshipService.has_followed(request.user.id, int(pk)):
         return Response(
             {
                 'success': True,
                 'duplicate': True,
                 'error': [{
                     'pk': f'you have followed the user with id={pk}'
                 }],
             },
             status=status.HTTP_400_BAD_REQUEST)
     serializer = FriendshipSerializerForCreate(
         data={
             'from_user_id': request.user.id,
             'to_user_id': pk,
         })
     if not serializer.is_valid():
         return Response({
             'success': False,
             'errors': serializer.errors,
         },
                         status=status.HTTP_400_BAD_REQUEST)
     instance = serializer.save()
     return Response(
         FollowingSerializer(instance, context={
             'request': request
         }).data,
         status=status.HTTP_201_CREATED,
     )
Exemple #27
0
    def follow(self, request, pk):
        # check if the user to follow exists
        to_user = self.get_object()
        # Friendship already existed. Raise error
        # avoid duplicated friendships in HBase
        if FriendshipService.has_followed(from_user_id=request.user.id,
                                          to_user_id=to_user.id):
            return Response({
                'success': True,
                'duplicated': True,
            },
                            status=status.HTTP_201_CREATED)

        # Friendship not exists, creat new friendship
        serializer = FriendshipCreateSerializer(
            data={
                'from_user_id':
                request.user.id,  # only logged in user can follow
                'to_user_id': pk,
            })
        if not serializer.is_valid():
            return Response({
                'success': False,
                'errors': serializer.errors,
            },
                            status=status.HTTP_400_BAD_REQUEST)

        friendship = serializer.save()
        return Response(
            {
                'success': True,
                'friendship': FriendshipCreateSerializer(friendship).data,
            },
            status=status.HTTP_201_CREATED)
Exemple #28
0
    def follow(self, request, pk):
        # check if user with id=pk exists
        to_follow_user = self.get_object()

        if FriendshipService.has_followed(request.user.id, to_follow_user.id):
            return Response({
                'success': False,
                'message': 'Please check input',
                'errors': [{'pk': f'You has followed user with id={pk}'}],
            }, status=status.HTTP_400_BAD_REQUEST)

        # /api/friendships/<pk>/follow/
        serializer = FriendshipSerializerForCreate(data={
            'from_user_id': request.user.id,
            'to_user_id': to_follow_user.id,
        })
        if not serializer.is_valid():
            return Response({
                'success': False,
                'message': 'Please check input',
                'errors': serializer.errors,
            }, status=status.HTTP_400_BAD_REQUEST)
        instance = serializer.save()
        return Response(
            FollowingSerializer(instance, context={'request': request}).data,
            status=status.HTTP_201_CREATED
        )
Exemple #29
0
    def test_get_followings(self):
        user3 = self.create_user('user3')
        user4 = self.create_user('user4')
        for to_user in [user3, user4, self.user2]:
            Friendship.objects.create(from_user=self.user1, to_user=to_user)
        # FriendshipService.invalidate_following_cache(from_user_id=self.user1.id)

        user_id_set = FriendshipService.get_following_user_id_set(
            self.user1.id)
        self.assertEqual(user_id_set, {user3.id, user4.id, self.user2.id})

        Friendship.objects.filter(from_user=self.user1.id,
                                  to_user=self.user2.id).delete()
        # FriendshipService.invalidate_following_cache(from_user_id=self.user1.id)
        user_id_set = FriendshipService.get_following_user_id_set(
            self.user1.id)
        self.assertEqual(user_id_set, {user3.id, user4.id})
Exemple #30
0
    def fanout_to_followers(cls, tweet):
        # 错误的方法
        # 不可以将数据库操作放在 for 循环里面,效率会非常低
        # for follower in FriendshipService.get_followers(tweet.user):
        #     NewsFeed.objects.create(
        #         user=follower,
        #         tweet=tweet,
        #     )

        # 正确的方法:使用 bulk_create,会把 insert 语句合成一条
        print(FriendshipService.get_followers(tweet.user))
        newsfeeds = [
            NewsFeed(user=follower, tweet=tweet)
            for follower in FriendshipService.get_followers(tweet.user)
        ]
        newsfeeds.append(NewsFeed(user=tweet.user, tweet=tweet))
        NewsFeed.objects.bulk_create(newsfeeds)