def test_follow_disabled(self): ''' Verify that follows don't show up when you disable them in the settings ''' from user.models import UserNotificationSetting # disable the follow notifications user_id = self.bogus_user.id self.set_setting(user_id, FollowVerb, dict(notify_mobile=False, enabled=False)) # verify that we disabled enabled = UserNotificationSetting.objects.enabled_for( user_id, FollowVerb) self.assertFalse(enabled) notification_feedly = NotificationFeedly() follows = Follow.objects.all()[:10] # clear the feed notification_feed = NotificationFeed(user_id) notification_feed.delete() # make sure that notifications for follows don't show up for follow in follows: follow.user_id = self.bogus_user2.id follow.target_id = user_id follow.created_at = datetime.datetime.now() activity = follow.create_activity() feed = notification_feedly._follow(follow) if feed: assert not feed.contains(activity) # the count should be zero self.assertEqual(notification_feed.count_unseen(), 0)
def test_love(self): love = Love.objects.all()[:10][0] love.created_at = datetime.datetime.now() love.influencer_id = self.bogus_user.id influencer_feed = NotificationFeed(self.bogus_user.id) love.entity.created_by_id = self.bogus_user2.id creator_feed = NotificationFeed(self.bogus_user2.id) # we want to write two notifications # someone loved your find # someone loved your love notification_feedly = NotificationFeedly() # clean slate for testing influencer_feed.delete() creator_feed.delete() # comparison activity activity = love.create_activity() notification_feedly.add_love(love) # influencer feed assert influencer_feed.contains(activity) # creator feed creator_activity = copy.deepcopy(activity) creator_activity.extra_context['find'] = True assert creator_feed.contains(creator_activity)
def test_follow_disabled(self): ''' Verify that follows don't show up when you disable them in the settings ''' from user.models import UserNotificationSetting # disable the follow notifications user_id = self.bogus_user.id self.set_setting( user_id, FollowVerb, dict(notify_mobile=False, enabled=False)) # verify that we disabled enabled = UserNotificationSetting.objects.enabled_for( user_id, FollowVerb) self.assertFalse(enabled) notification_feedly = NotificationFeedly() follows = Follow.objects.all()[:10] # clear the feed notification_feed = NotificationFeed(user_id) notification_feed.delete() # make sure that notifications for follows don't show up for follow in follows: follow.user_id = self.bogus_user2.id follow.target_id = user_id follow.created_at = datetime.datetime.now() activity = follow.create_activity() feed = notification_feedly._follow(follow) if feed: assert not feed.contains(activity) # the count should be zero self.assertEqual(notification_feed.count_unseen(), 0)
def test_add_love(self): # disable the follow notifications user_id = self.bogus_user.id self.set_setting(user_id, LoveVerb, dict(notify_mobile=False, enabled=False)) love = Love.objects.all()[:10][0] love.created_at = datetime.datetime.now() love.influencer_id = user_id influencer_feed = NotificationFeed(user_id) love.entity.created_by_id = self.bogus_user2.id creator_feed = NotificationFeed(self.bogus_user2.id) # we want to write two notifications # someone loved your find # someone loved your love notification_feedly = NotificationFeedly() # clean slate for testing influencer_feed.delete() creator_feed.delete() # comparison activity activity = love.create_activity() notification_feedly.add_love(love) # influencer is equal to user_id and shouldnt contain the activity assert not influencer_feed.contains(activity) # creator feed should contain since the settings hasn't been disabled creator_activity = copy.deepcopy(activity) creator_activity.extra_context['find'] = True assert creator_feed.contains(creator_activity)
def _follow(self, follow): ''' Thierry and 3 other people started following you ''' activity = follow.create_activity() feed = NotificationFeed(follow.target_id) feed.add(activity) return feed
def test_add_to_list(self): notification_feedly = NotificationFeedly() notification_feed = NotificationFeed(self.bogus_user.id) list_items = ListItem.objects.all()[:1] for list_item in list_items: list_item.entity.created_by_id = self.bogus_user.id notification_feedly.add_to_list(list_item) activity = list_item.create_activity() assert notification_feed.contains(activity)
def _add_to_list(self, list_item): ''' Guyon added your find to their list back in black Guyon and 3 other people added your finds to their lists ''' activity = list_item.create_activity() user_id = list_item.list.user_id created_by_id = list_item.entity.created_by_id if user_id != created_by_id: feed = NotificationFeed(created_by_id) feed.add(activity) return feed
def _follow(self, follow): ''' Thierry and 3 other people started following you ''' from user.models import UserNotificationSetting feed = None enabled = UserNotificationSetting.objects.enabled_for( follow.target_id, FollowVerb) if enabled: activity = follow.create_activity() feed = NotificationFeed(follow.target_id) feed.add(activity) return feed
def test_add_love(self): # disable the follow notifications user_id = self.bogus_user.id self.set_setting( user_id, LoveVerb, dict(notify_mobile=False, enabled=False)) love = Love.objects.all()[:10][0] love.created_at = datetime.datetime.now() love.influencer_id = user_id influencer_feed = NotificationFeed(user_id) love.entity.created_by_id = self.bogus_user2.id creator_feed = NotificationFeed(self.bogus_user2.id) # we want to write two notifications # someone loved your find # someone loved your love notification_feedly = NotificationFeedly() # clean slate for testing influencer_feed.delete() creator_feed.delete() # comparison activity activity = love.create_activity() notification_feedly.add_love(love) # influencer is equal to user_id and shouldnt contain the activity assert not influencer_feed.contains(activity) # creator feed should contain since the settings hasn't been disabled creator_activity = copy.deepcopy(activity) creator_activity.extra_context['find'] = True assert creator_feed.contains(creator_activity)
def _add_love(self, love): ''' We want to write two notifications - someone loved your find - someone loved your love ''' from user.models import UserNotificationSetting feeds = [] activity = love.create_notification_activity() # send notification about the find created_by_id = love.entity.created_by_id if love.user_id != created_by_id: enabled = UserNotificationSetting.objects.enabled_for( created_by_id, LoveVerb) if enabled: feed = NotificationFeed(created_by_id) activity.extra_context['find'] = True logger.info('notifying item finder %s', created_by_id) feed.add(activity) feeds.append(activity) # send notification about the love if love.user_id != love.influencer_id and love.influencer_id: if love.influencer_id != created_by_id: enabled = UserNotificationSetting.objects.enabled_for( love.influencer_id, LoveVerb) if enabled: logger.info('notifying influencer %s', love.influencer_id) feed = NotificationFeed(love.influencer_id) activity.extra_context.pop('find', True) feed.add(activity) feeds.append(feed) return feeds
def test_serialization(self): ''' Test if serialization doesnt take up too much memory ''' notification_feed = NotificationFeed(self.bogus_user.id) notification_feed.delete() love = Love.objects.all()[:10][0] follow = Follow.objects.all()[:10][0] list_item = ListItem.objects.all()[:1][0] notification_feed.add(love.create_activity()) notification_feed.add(follow.create_activity()) notification_feed.add(list_item.create_activity()) size = notification_feed.size() self.assertLess(size, 500)
def test_follow(self): notification_feedly = NotificationFeedly() follows = Follow.objects.all()[:10] notification_feed = NotificationFeed(self.bogus_user.id) notification_feed.delete() for follow in follows: follow.user_id = self.bogus_user2.id follow.target_id = self.bogus_user.id follow.created_at = datetime.datetime.now() activity = follow.create_activity() feed = notification_feedly._follow(follow) assert feed.contains(activity) # influencer feed self.assertEqual(notification_feed.count_unseen(), 1)
def test_scalability(self): ''' Test if everything works if aggregating more than 50 activities in one aggregated activity ''' notification_feed = NotificationFeed(self.bogus_user.id) notification_feed.delete() love = Love.objects.all()[:10][0] activities = [] activity = love.create_activity() for x in range(110): activity = copy.deepcopy(activity) activity.extra_context['entity_id'] = x activities.append(activity) # add them all notification_feed.add_many(activities) # verify that our feed size doesn't escalate for aggregated in notification_feed[:notification_feed.max_length]: full_activities = len(aggregated.activities) activity_count = aggregated.activity_count self.assertEqual(full_activities, 99) self.assertEqual(activity_count, 110) actor_count = aggregated.actor_count self.assertLess(actor_count, 110) size = notification_feed.size() self.assertLess(size, 6000)
def test_duplicates(self): ''' The task system can often attempt to duplicate an insert This should raise an error to prevent weird data ''' notification_feedly = NotificationFeedly() notification_feed = NotificationFeed(self.bogus_user.id) notification_feed.delete() love = Love.objects.all()[:10][0] for x in range(3): love.influencer_id = self.bogus_user.id notification_feedly.add_love(love) for aggregated in notification_feed[:notification_feed.max_length]: activity_count = aggregated.activity_count self.assertEqual(activity_count, 1)
def test_duplicate_love_unlove(self): ''' Test to verify that we dont end up with multiple notifications When users love and unlove the same data ''' notification_feedly = NotificationFeedly() notification_feed = NotificationFeed(self.bogus_user.id) notification_feed.delete() love = Love.objects.all()[:10][0] for x in range(3): love.id = x love.influencer_id = self.bogus_user.id notification_feedly.add_love(love) for aggregated in notification_feed[:notification_feed.max_length]: activity_count = aggregated.activity_count self.assertEqual(activity_count, 1)
def test_add_remove(self): ''' Try to remove an aggregated activity ''' from datetime import datetime, time, timedelta love = Love.objects.all()[:1][0] feed = NotificationFeed(13) # slow version activities = [] feed.delete() activity = love.create_activity() activities.append(activity) feed.add(activity) assert feed.contains(activity) # sticking in the same activity with a different time should fail # within the same day should fail activity.time = activity.time - timedelta(seconds=120) try: feed.add(activity) raise ValueError( 'DuplicateActivityException should have been raised') except feedly_exceptions.DuplicateActivityException, e: pass
def test_actor_count(self): love = Love.objects.all()[:1][0] feed = NotificationFeed(13) # setup the activities, all in the same aggregated activity activities = [] feed.delete() for x in range(150): activity = Activity(love.user, LoveVerb, love, love.user, time=love.created_at, extra_context=dict(x=x)) activities.append(activity) # now the fast insert self.assertEqual(int(feed.count()), 0) feed.add_many(activities) self.assertEqual(int(feed.count()), 1) aggregated_activity = feed[:1][0] # test our Guesstimate self.assertEqual(aggregated_activity.minimized_activities, 51) self.assertEqual(aggregated_activity.actor_count, 52)
def test_mark_all(self): loves = Love.objects.all()[:3] feed = NotificationFeed(13) feed.delete() activities = [l.create_activity() for l in loves] # so we have something to compare to aggregator = RecentVerbAggregator() aggregated_activities = aggregator.aggregate(activities) # insert into the feed feed.add_many(activities) self.assertEqual(feed.count_unseen(), len(aggregated_activities)) # verify if we denormalize correctly self.assertEqual(feed.count_unseen(), feed.get_denormalized_count()) # sanity check self.assertNotEqual(feed.count_unseen(), 0) # Activity gets inserted and marked read # a new activity is appended which updates the last_seen field # the activity is now not seen # # however mark_all will not update # verify that we have zero unseen after mark all feed.mark_all(seen=True) self.assertEqual(feed.count_unseen(), 0) # an update to an activity should kick the count back to one activity = activities[0] # check if an updated activity still gets marked import time time.sleep(1) activity.time = datetime.datetime.now() # hack to make sure its not duplicate activity.extra_context['foo'] = 'bar' feed.add(activity) self.assertEqual(feed.count_unseen(), 1) # mark as read again feed.mark_all(seen=True) self.assertEqual(feed.count_unseen(), 0)
def test_notification_feed(self): loves = Love.objects.all()[:10] feed = NotificationFeed(13) # slow version activities = [] feed.delete() for love in loves: activity = Activity(love.user, LoveVerb, love, love.user, time=love.created_at, extra_context=dict(hello='world')) activities.append(activity) feed.add(activity) assert feed.contains(activity) # so we have something to compare to aggregator = RecentVerbAggregator() aggregated_activities = aggregator.aggregate(activities) # check the feed feed_loves = feed[:20] self.assertEqual(len(aggregated_activities), len(feed_loves)) # now the fast version feed.delete() self.assertEqual(int(feed.count()), 0) feed.add_many(activities) for activity in activities: assert feed.contains(activity) # test if we aggregated correctly self.assertEqual(feed.count_unseen(), len(aggregated_activities)) # verify if we denormalize correctly self.assertEqual(feed.count_unseen(), feed.get_denormalized_count()) # sanity check self.assertNotEqual(feed.count_unseen(), 0) # test marking as seen or read feed.mark_all(seen=True) # verify that the new count is 0 self.assertEqual(feed.count_unseen(), 0) # verify if we denormalize correctly self.assertEqual(feed.count_unseen(), feed.get_denormalized_count())
def test_mark_all(self): loves = Love.objects.all()[:3] feed = NotificationFeed(13) feed.delete() activities = [l.create_activity() for l in loves] # so we have something to compare to aggregator = RecentVerbAggregator() aggregated_activities = aggregator.aggregate(activities) # insert into the feed feed.add_many(activities) self.assertEqual(feed.count_unseen(), len(aggregated_activities)) # verify if we denormalize correctly self.assertEqual(feed.count_unseen(), feed.get_denormalized_count()) # sanity check self.assertNotEqual(feed.count_unseen(), 0) # Activity gets inserted and marked read # a new activity is appended which updates the last_seen field # the activity is now not seen # # however mark_all will not update # first insert activity = activities[0] activity.time = datetime.datetime.now() feed.add(activity) self.assertNotEqual(feed.count_unseen(), 0) feed.mark_all(seen=True) self.assertEqual(feed.count_unseen(), 0) # check if an updated activity still gets marked import time time.sleep(1) activity.time = datetime.datetime.now() # hack to make sure its duplicate activity.extra_context['foo'] = 'bar' feed.add(activity) self.assertEqual(feed.count_unseen(), 1) # mark as read again feed.mark_all(seen=True) self.assertEqual(feed.count_unseen(), 0)