def test_replied_tells_author_and_op_author(self): # Some dude starts a thread author = create_user() content = create_content() op = create_comment(author=author, reply_content=content) # Another dude posts a reply guest_author = create_user() reply = create_comment(replied_comment=op, author=guest_author, parent_comment=op) self.assertEqual(reply.thread.op, op) # A third dude replies to the guest author guest_author_2 = create_user() reply_2 = create_comment(replied_comment=reply, author=guest_author_2, parent_comment=op) self.assertTrue(reply_2.thread.op.author, author) # Issue the action pn = Actions.replied(guest_author_2, reply_2) notifications = expander.expand(pn) print notifications # Now, we should tell both the OP author, and the guest author. notifications = filter(lambda n: n.channel == 'EmailChannel', notifications) self.assertEqual(len(notifications), 2) n1 = notifications[0] n2 = notifications[1] self.assertEqual(n1.action, 'replied') self.assertEqual(n1.recipient, guest_author) self.assertEqual(n2.action, 'thread_replied') self.assertEqual(n2.recipient, author)
def test_details_repost_zero_for_text_posts(self): # These will have the same reply_content_id (None), but we should handle that and not count them as reposts. cmt = create_comment() cmt2 = create_comment() self.assertEqual(cmt.details().repost_count, 0) self.assertEqual(cmt2.details().repost_count, 0)
def test_replies_have_no_op_class(self): comment = create_comment(reply_content=create_content()) reply = create_comment(reply_content=create_content(), parent_comment=comment) reply2 = create_comment(reply_content=create_content(), parent_comment=comment) posts = self._render_replies([reply, reply2]) self.assertNumCssMatches(0, posts, '.op.expanded')
def test_details_repost_one_for_repost(self): content = create_content() cmt = create_comment(reply_content=content) cmt2 = create_comment(reply_content=content) self.assertEqual(cmt.details.force().repost_count, 0) self.assertEqual(cmt2.details().repost_count, 1)
def test_replies_have_no_op_class(self): comment = create_comment(reply_content=create_content(), reply_text="hello friends") reply = create_comment(reply_text="reply!", parent_comment=comment) reply2 = create_comment(reply_text="another", parent_comment=comment) posts = self._render_replies([reply, reply2]) self.assertNumCssMatches(0, posts, '.op.expanded')
def test_page_loads_with_feed_item(self): user = create_staff() other = create_user() user.follow(other) create_comment(author=other, reply_content=create_content()) self.assertStatus(200, '/feed', user=user)
def test_text_reply(self): comment = create_comment(reply_content=create_content(), reply_text="hello friends") reply = create_comment(reply_text="reply!", parent_comment=comment) post = self._render_post(reply, fullsize=False) self.assertNumCssMatches(0, post, '.has_content') self.assertNumCssMatches(0, post, '.op.expanded') self.assertNumCssMatches(0, post, 'div.reply_content')
def test_details_replies_two_replies(self): cmt = create_comment() first = create_comment(parent_comment=cmt, timestamp=1) second = create_comment(parent_comment=cmt, timestamp=2) d = cmt.details() self.assertEqual(d.reply_count, 2) self.assertEqual(d.last_reply_id, second.id) self.assertEqual(d.last_reply_time, second.timestamp)
def test_actor(self): author = create_user() op = create_comment(author=author, reply_content=create_content()) replier = create_user() reply = create_comment(replied_comment=op, author=replier) activity = ThreadReplyActivity.from_comment(replier, reply) self.assertEqual(activity.actor['id'], replier.id)
def test_details_replies_one_reply(self): with override_service('time', FakeTimeProvider): cmt = create_comment() Services.time.step() child = create_comment(parent_comment=cmt) d = cmt.details() self.assertEqual(d.reply_count, 1) self.assertEqual(d.last_reply_id, child.id) self.assertAlmostEqual(d.last_reply_time, child.timestamp, places=4)
def test_anonymous_actor(self): author = create_user() op = create_comment(author=author, reply_content=create_content()) for anon in [True, False]: replier = create_user() reply = create_comment(replied_comment=op, author=replier, anonymous=anon) activity = ThreadReplyActivity.from_comment(replier, reply) self.assertEqual(activity.is_actor_anonymous, anon)
def test_get_multiple_posts_by_post(self): comment = create_comment() comment1 = create_comment() id_list = [short_id(x.id) for x in [comment, comment1]] req = {'ids': id_list} result = self.post('/public_api/posts/', data=req) self.assertAPISuccess(result) json = util.loads(result.content) self.assertEqual(2, len(json['posts'])) self.check_comment(comment.details(), json['posts'][0])
def test_details_repost_zero_for_different_content(self): content = create_content() cmt = create_comment(reply_content=content) self.assertEqual(cmt.details().repost_count, 0) content2 = create_content() cmt2 = create_comment(reply_content=content2) self.assertEqual(cmt.details.force().repost_count, 0) self.assertEqual(cmt2.details().repost_count, 0)
def test_details_replies_two_replies_last_curated(self): # The last reply should include curated replies to prevent "stuck" active/pinned curated OPs auto-curating # their replies. cmt = create_comment() first = create_comment(parent_comment=cmt, timestamp=1) second = create_comment(parent_comment=cmt, timestamp=2) second.moderate_and_save(Visibility.CURATED, second.author) d = cmt.details() self.assertEqual(d.reply_count, 2) self.assertEqual(d.last_reply_id, second.id) self.assertEqual(d.last_reply_time, second.timestamp)
def test_details_repost_zero_for_audio_remix(self): content = create_content() cmt = create_comment(reply_content=content) cmt2 = create_comment(reply_content=content) external_content = ExternalContent.from_dict( dict(type="yt", end_time=10.0, start_time=0.0, source_url="123445555")) external_content.parent_comment = cmt2 external_content.save() self.assertEqual(cmt2.details().repost_count, 0)
def test_delivering_email_records_email_sent_metric(self): with override_service('experiment_placer', FakeExperimentPlacer, kwargs={'email_notifications': 'experimental'}): user = create_user(email="*****@*****.**") comment = create_comment() comment2 = create_comment(author=user, replied_comment=comment) pn = Actions.replied(user, comment2) notification = Notification.from_pending_notification(pn, user, "EmailChannel") channel = EmailChannel() with override_service('metrics', FakeMetrics): channel.deliver(notification) self.assertEqual(1, len(Services.metrics.email_sent.records))
def test_details_repost_zero_for_audio_remix(self): content = create_content() cmt = create_comment(reply_content=content) cmt2 = create_comment(reply_content=content) external_content = ExternalContent.from_dict(dict( type="yt", end_time=10.0, start_time=0.0, source_url="123445555" )) external_content.parent_comment = cmt2 external_content.save() self.assertEqual(cmt2.details().repost_count, 0)
def test_replied_to_own_thread_does_not_email_self(self): user = create_user() comment = create_comment(author=user) assert comment.author == user reply = create_comment(replied_comment=comment) assert comment == reply.replied_comment pn = Actions.replied(user, reply) notifications = expander.expand(pn) recipients = [n.recipient for n in notifications] self.assertNotIn(user, recipients)
def test_get_post_and_replies(self): comment = create_comment(anonymous=True) rep1 = create_comment(parent_comment=comment, replied_comment=comment) rep2 = create_comment(parent_comment=comment, replied_comment=rep1) rep3 = create_comment(parent_comment=comment, replied_comment=rep1) rep4 = create_comment(parent_comment=comment) reply_ids = [short_id(x.id) for x in [rep1, rep2, rep3, rep4]] req = {'ids': [short_id(comment.id)]} result = self.post('/public_api/posts/', data=req) self.assertAPISuccess(result) json = util.loads(result.content) self.assertEqual(1, len(json['posts'])) post = json['posts'][0] for id in reply_ids: self.assertIn(id, [x['id'] for x in post['replies']])
def test_mute_thread_via_api(self): comment = create_comment() user = create_user() assert comment.id not in user.redis.muted_threads self.api_post('/api/comment/mute', {'comment_id': comment.id}, user=user) assert comment.id in user.redis.muted_threads
def test_standard_reply(self): comment = create_comment(reply_content=create_content()) post = self._render_post(comment, fullsize=False) self.assertNumCssMatches(1, post, '.has_content') self.assertNumCssMatches(0, post, '.op.expanded') self.assertNumCssMatches(1, post, 'div.reply_content')
def test_properties_dont_get_serialized(self): # CommentDetails should only serialize its dict contents, not any of its member properties. cmt = create_comment().details() cmt.test_foo_property = 1 d = util.loads(util.dumps(cmt)) self.assertFalse('test_foo_property' in d)
def after_setUp(self): self.inviter = create_user() self.invitee = create_user() self.comment = create_comment( author=self.inviter, reply_content=create_content(), category=create_group(name=MONSTER_MOBILE_GROUP))
def test_sticker_from_user(self): user = create_user() comment = create_comment() self.assertFalse(CommentSticker.get_sticker_from_user(comment.id, user)) self.api_post('/api/sticker/comment', {'type_id': '1', 'comment_id': comment.id}, user=user) self.assertTrue(CommentSticker.get_sticker_from_user(comment.id, user))
def test_sticker_from_user(self): user = create_user() comment = create_comment() self.assertFalse(CommentSticker.get_sticker_from_user(comment.id, user)) self.api_post("/api/sticker/comment", {"type_id": "1", "comment_id": comment.id}, user=user) self.assertTrue(CommentSticker.get_sticker_from_user(comment.id, user))
def test_no_reply_notifications_for_inactive_users(self): author = create_user() comment = create_comment(author=author) action_func_list = [Actions.remixed, Actions.replied, Actions.thread_replied] # First make sure that the user can receive all possible "comment" # related notifications, like replied, remixed ... etc for func in action_func_list: pending_notification = func(author, comment) self.assertTrue(EmailChannel.enabled_for_recipient_action(pending_notification.action, author, pending_notification)) author.is_active = False author.save() for func in action_func_list: pending_notification = func(author, comment) self.assertFalse(EmailChannel.enabled_for_recipient_action(pending_notification.action, author, pending_notification))
def test_get_user_by_username(self): user = create_user() comments = [create_comment(author=user) for x in range(3)] anon_comments = [create_comment(author=user, anonymous=True) for x in range(3)] username = user.username result = self.get('/public_api/users/{0}'.format(username)) self.assertAPISuccess(result) result = self.post('/public_api/users/{0}'.format(username)) self.assertAPISuccess(result) json = util.loads(result.content) self.check_user(user, json) returned_posts = [x['id'] for x in json['posts']] for c in comments: self.assertIn(short_id(c.id), returned_posts) for c in anon_comments: self.assertNotIn(short_id(c.id), returned_posts)
def test_title_in_metadata(self): user = self.user title = "here's a title for this comment" cmt = create_comment(title=title) ctx = self._ctx(user, cmt) cmt = TemplateComment(cmt.details(), request_context=ctx) self.assertTrue(strip_template_chars(title) in cmt.shareable_metadata()['title'])
def test_expander_honors_unsubscribe_per_channel(self): author = utils.create_user() comment = utils.create_comment() comment.author = author comment.save() self.assertEqual(comment.thread.op.author, author) another_user = utils.create_user() pn = Actions.replied(another_user, comment) notifications = expander.expand(pn) self.assertTrue(notifications) notification = filter(lambda n: n.channel == 'EmailChannel', notifications)[0] self.assertEqual(author, notification.recipient) # Now, let the user unsubscribe to the reply action. author.kv.subscriptions.unsubscribe('thread_replied') pn = Actions.replied(another_user, comment) notifications = expander.expand(pn) recipients = [ n.recipient for n in notifications if n.channel == 'EmailChannel' ] self.assertFalse(author in recipients)
def test_standard_op(self): comment = create_comment(reply_content=create_content(), reply_text="hello friends") post = self._render_post(comment, fullsize=True) self.assertNumCssMatches(1, post, '.has_content') self.assertNumCssMatches(1, post, '.op.expanded') self.assertNumCssMatches(1, post, 'div.reply_content')
def test_has_stickered(self): result = self.api_post('/api/sticker/comment', { 'type_id': str(1), 'comment_id': create_comment().id, }, user=self.user) self.assertTrue(self.user.has_stickered())
def test_handle_bad_post_id(self): comment = create_comment() result = self.get('/public_api/posts/{0}'.format( short_id(comment.id + 10000))) self.assertAPIFailure(result) result = self.post('/public_api/posts/{0}'.format( short_id(comment.id + 10000))) self.assertAPIFailure(result)
def test_queryset_details(self): comments = [create_comment(reply_content=create_content()) for _ in xrange(10)] details1 = CachedCall.multicall([cmt.details for cmt in comments]) queryset = Comment.objects.filter(id__in=[cmt.id for cmt in comments]) details2 = CachedCall.queryset_details(queryset) self.assertEquals(details1, details2)
def test_get_post_by_short_id(self): comment = create_comment() result = self.get('/public_api/posts/{0}'.format(short_id(comment.id))) self.assertAPISuccess(result) result = self.post('/public_api/posts/{0}'.format(short_id(comment.id))) self.assertAPISuccess(result) json = util.loads(result.content) self.check_comment(comment.details(), json)
def test_anonymous_user_url_when_staff(self): user = self.user author = create_user() cmt = create_comment(author=author, anonymous=True) ctx = self._ctx(user, cmt) cmt = TemplateComment(cmt.details(), request_context=ctx) url = cmt.get_user_url() self.assertEqual(url, reverse('user_link', args=[author.username]))
def test_trim_max_request(self): comments = [ create_comment() for x in range(knobs.PUBLIC_API_MAX_ITEMS + 2) ] id_list = [short_id(x.id) for x in comments] req = {'ids': id_list} result = self.post('/public_api/posts/', data=req) self.assertAPIFailure(result)
def test_details_replies_no_replies(self): cmt = create_comment(timestamp=123) d = cmt.details() self.assertEqual(d.reply_count, 0) self.assertEqual(d.last_reply_id, None) # This should be the timestamp of the OP in this case. self.assertEqual(d.last_reply_time, 123)
def _sticker(self, user, sticker_type_id=1, sender=None): comment = create_comment(author=user) sender = sender or create_user() result = self.api_post('/api/sticker/comment', { 'type_id': str(sticker_type_id), 'comment_id': comment.id }, user=sender)