def _toggle_watch_question(self, event_type, user, turn_on=True): """Helper to watch/unwatch a question. Fails if called twice with the same turn_on value.""" q = QuestionFactory() self.client.login(username=user.username, password='******') event_cls = (QuestionReplyEvent if event_type == 'reply' else QuestionSolvedEvent) # Make sure 'before' values are the reverse. if turn_on: assert not event_cls.is_notifying(user, q), ( '%s should not be notifying.' % event_cls.__name__) else: assert event_cls.is_notifying(user, q), ( '%s should be notifying.' % event_cls.__name__) url = 'questions.watch' if turn_on else 'questions.unwatch' data = {'event_type': event_type} if turn_on else {} post(self.client, url, data, args=[q.id]) if turn_on: assert event_cls.is_notifying(user, q), ( '%s should be notifying.' % event_cls.__name__) else: assert not event_cls.is_notifying(user, q), ( '%s should not be notifying.' % event_cls.__name__) return q
def test_autowatch_reply(self, get_current): """ Tests the autowatch setting of users. If a user has the setting turned on, they should get notifications after posting in a thread for that thread. If they have that setting turned off, they should not. """ get_current.return_value.domain = "testserver" u = user(save=True) t1 = question(save=True) t2 = question(save=True) assert not QuestionReplyEvent.is_notifying(u, t1) assert not QuestionReplyEvent.is_notifying(u, t2) self.client.login(username=u.username, password="******") s = Setting.objects.create(user=u, name="questions_watch_after_reply", value="True") data = {"content": "some content"} post(self.client, "questions.reply", data, args=[t1.id]) assert QuestionReplyEvent.is_notifying(u, t1) s.value = "False" s.save() post(self.client, "questions.reply", data, args=[t2.id]) assert not QuestionReplyEvent.is_notifying(u, t2)
def test_autowatch_reply(self, get_current): """ Tests the autowatch setting of users. If a user has the setting turned on, they should get notifications after posting in a thread for that thread. If they have that setting turned off, they should not. """ get_current.return_value.domain = 'testserver' u = UserFactory() t1 = QuestionFactory() t2 = QuestionFactory() assert not QuestionReplyEvent.is_notifying(u, t1) assert not QuestionReplyEvent.is_notifying(u, t2) self.client.login(username=u.username, password='******') s = Setting.objects.create(user=u, name='questions_watch_after_reply', value='True') data = {'content': 'some content'} post(self.client, 'questions.reply', data, args=[t1.id]) assert QuestionReplyEvent.is_notifying(u, t1) s.value = 'False' s.save() post(self.client, 'questions.reply', data, args=[t2.id]) assert not QuestionReplyEvent.is_notifying(u, t2)
def test_watch_both_then_new_post(self, get_current): """Watching both forum and thread. Replying to a thread should send ONE email.""" get_current.return_value.domain = 'testserver' t = thread(save=True) f = t.forum forum_post(thread=t, save=True) poster = user(save=True) watcher = user(save=True) self._toggle_watch_forum_as(f, watcher, turn_on=True) self._toggle_watch_thread_as(t, watcher, turn_on=True) self.client.login(username=poster.username, password='******') post(self.client, 'forums.reply', {'content': 'a post'}, args=[f.slug, t.id]) eq_(1, len(mail.outbox)) p = Post.objects.all().order_by('-id')[0] attrs_eq(mail.outbox[0], to=[watcher.email], subject='Re: {f} - {t}'.format(f=f, t=t)) body = REPLY_EMAIL.format( username=poster.username, forum_slug=f.slug, thread=t.title, thread_id=t.id, post_id=p.id) starts_with(mail.outbox[0].body, body)
def test_post_ratelimit(self): """Verify that rate limiting kicks in after 4 threads or replies.""" d = document(save=True) u = user(save=True) self.client.login(username=u.username, password='******') # Create 2 threads: for i in range(2): response = post(self.client, 'wiki.discuss.new_thread', {'title': 'Topic', 'content': 'hellooo'}, args=[d.slug]) eq_(200, response.status_code) # Now 3 replies (only 2 should save): t = Thread.objects.all()[0] for i in range(3): response = post(self.client, 'wiki.discuss.reply', {'content': 'hellooo'}, args=[d.slug, t.id]) eq_(200, response.status_code) # And another thread that shouldn't save: response = post(self.client, 'wiki.discuss.new_thread', {'title': 'Topic', 'content': 'hellooo'}, args=[d.slug]) # We should only have 4 posts (each thread and reply creates a post). eq_(4, Post.objects.count())
def test_solution(self, save): a = answer(save=True) q = a.question self.client.login(username=q.creator.username, password='******') post(self.client, 'questions.solve', args=[q.id, a.id]) assert save.called
def test_watch_forum_then_new_post(self, get_current): """Watching a forum and replying to a thread should send email.""" get_current.return_value.domain = 'testserver' t = ThreadFactory() f = t.forum PostFactory(thread=t) poster = UserFactory() watcher = UserFactory() self._toggle_watch_forum_as(f, watcher, turn_on=True) self.client.login(username=poster.username, password='******') post(self.client, 'forums.reply', {'content': 'a post'}, args=[f.slug, t.id]) p = Post.objects.all().order_by('-id')[0] attrs_eq(mail.outbox[0], to=[watcher.email], subject=u'Re: {f} - {t}'.format(f=f, t=t)) body = REPLY_EMAIL.format( username=poster.profile.name, forum_slug=f.slug, thread=t.title, thread_id=t.id, post_id=p.id) starts_with(mail.outbox[0].body, body)
def test_watch_all_then_new_post(self, get_current): """Watching document + thread + locale and reply to thread.""" get_current.return_value.domain = 'testserver' u = UserFactory() _d = DocumentFactory(title='an article title') d = self._toggle_watch_kbforum_as(u.username, _d, turn_on=True) t = ThreadFactory(title='Sticky Thread', document=d) self._toggle_watch_thread_as(u.username, t, turn_on=True) self.client.login(username=u.username, password='******') post(self.client, 'wiki.discuss.watch_locale', {'watch': 'yes'}) # Reply as jsocol to document d. u2 = UserFactory(username='******') self.client.login(username=u2.username, password='******') post(self.client, 'wiki.discuss.reply', {'content': 'a post'}, args=[d.slug, t.id]) # Only ONE email was sent. As expected. eq_(1, len(mail.outbox)) p = Post.objects.all().order_by('-id')[0] attrs_eq(mail.outbox[0], to=[u.email], subject='Re: an article title - Sticky Thread') starts_with(mail.outbox[0].body, REPLY_EMAIL % { 'user': u2.profile.name, 'document_slug': d.slug, 'thread_id': t.id, 'post_id': p.id, })
def test_watch_both_then_new_post(self, get_current): """Watching both and replying to a thread should send ONE email.""" get_current.return_value.domain = 'testserver' u = UserFactory() d = DocumentFactory(title='an article title') f = self._toggle_watch_kbforum_as(u.username, d, turn_on=True) t = ThreadFactory(title='Sticky Thread', document=d) self._toggle_watch_thread_as(u.username, t, turn_on=True) u2 = UserFactory(username='******') self.client.login(username=u2.username, password='******') post(self.client, 'wiki.discuss.reply', {'content': 'a post'}, args=[f.slug, t.id]) eq_(1, len(mail.outbox)) p = Post.objects.all().order_by('-id')[0] attrs_eq(mail.outbox[0], to=[u.email], subject='Re: an article title - Sticky Thread') starts_with(mail.outbox[0].body, REPLY_EMAIL % { 'user': u2.profile.name, 'document_slug': d.slug, 'thread_id': t.id, 'post_id': p.id, }) self._toggle_watch_kbforum_as(u.username, d, turn_on=False) self._toggle_watch_thread_as(u.username, t, turn_on=False)
def test_autowatch_reply(self, get_current): """Replying to a thread creates a watch.""" get_current.return_value.domain = 'testserver' u = user(save=True) t1 = thread(save=True) t2 = thread(save=True) assert not NewPostEvent.is_notifying(u, t1) assert not NewPostEvent.is_notifying(u, t2) self.client.login(username=u.username, password='******') # If the poster has the forums_watch_after_reply setting set to True, # they will start watching threads they reply to. s = Setting.objects.create(user=u, name='forums_watch_after_reply', value='True') data = {'content': 'some content'} post(self.client, 'forums.reply', data, args=[t1.forum.slug, t1.pk]) assert NewPostEvent.is_notifying(u, t1) # Setting forums_watch_after_reply back to False, now they shouldn't # start watching threads they reply to. s.value = 'False' s.save() post(self.client, 'forums.reply', data, args=[t2.forum.slug, t2.pk]) assert not NewPostEvent.is_notifying(u, t2)
def test_unsolve(self, delete): answer = Answer.objects.get(pk=1) question = answer.question self.client.login(username='******', password='******') question.solution = answer question.save() post(self.client, 'questions.unsolve', args=[question.id, answer.id]) assert delete.called
def test_fire_on_new_thread(self, fire): """The event fires when there is a new thread.""" d = document(save=True) u = user(save=True) self.client.login(username=u.username, password="******") post(self.client, "wiki.discuss.new_thread", {"title": "a title", "content": "a post"}, args=[d.slug]) # NewThreadEvent.fire() is called. assert fire.called
def test_fire_on_reply(self, fire): """The event fires when there is a reply.""" t = thread(save=True) u = user(save=True) self.client.login(username=u.username, password="******") post(self.client, "wiki.discuss.reply", {"content": "a post"}, args=[t.document.slug, t.id]) # NewPostEvent.fire() is called. assert fire.called
def test_fire_on_reply(self, fire): """The event fires when there is a reply.""" u = user(save=True) t = thread(save=True) self.client.login(username=u.username, password='******') post(self.client, 'forums.reply', {'content': 'a post'}, args=[t.forum.slug, t.id]) # NewPostEvent.fire() is called. assert fire.called
def test_fire_on_solution(self, fire): """The event also fires when an answer is marked as a solution.""" a = answer(save=True) q = a.question self.client.login(username=q.creator, password="******") post(self.client, "questions.solve", args=[q.id, a.id]) assert fire.called
def test_unsolve(self, delete): a = answer(save=True) q = a.question self.client.login(username=q.creator.username, password='******') q.solution = a q.save() post(self.client, 'questions.unsolve', args=[q.id, a.id]) assert delete.called
def test_fire_on_reply(self, fire): """The event fires when there is a reply.""" t = ThreadFactory() u = UserFactory() self.client.login(username=u.username, password='******') post(self.client, 'wiki.discuss.reply', {'content': 'a post'}, args=[t.document.slug, t.id]) # NewPostEvent.fire() is called. assert fire.called
def test_fire_on_solution(self, fire): """The event also fires when an answer is marked as a solution.""" a = AnswerFactory() q = a.question self.client.login(username=q.creator, password='******') post(self.client, 'questions.solve', args=[q.id, a.id]) assert fire.called
def _toggle_watch_forum_as(self, forum, user, turn_on=True): """Watch a forum and return it.""" self.client.login(username=user.username, password="******") watch = "yes" if turn_on else "no" post(self.client, "forums.watch_forum", {"watch": watch}, args=[forum.slug]) # Watch exists or not, depending on watch. if turn_on: assert NewThreadEvent.is_notifying(user, forum), "NewThreadEvent should be notifying." else: assert not NewPostEvent.is_notifying(user, forum), "NewThreadEvent should not be notifying."
def test_fire_on_new_thread(self, fire): """The event fires when there is a new thread.""" u = UserFactory() f = ForumFactory() self.client.login(username=u.username, password='******') post(self.client, 'forums.new_thread', {'title': 'a title', 'content': 'a post'}, args=[f.slug]) # NewThreadEvent.fire() is called. assert fire.called
def test_fire_on_new_thread(self, fire): """The event fires when there is a new thread.""" d = document(save=True) u = user(save=True) self.client.login(username=u.username, password='******') post(self.client, 'wiki.discuss.new_thread', {'title': 'a title', 'content': 'a post'}, args=[d.slug]) # NewThreadEvent.fire() is called. assert fire.called
def test_edit_thread_creator(self): """Changing thread title as the thread creator works.""" t = ThreadFactory() u = t.creator self.client.login(username=u.username, password='******') post(self.client, 'forums.edit_thread', {'title': 'A new title'}, args=[t.forum.slug, t.id]) edited_t = Thread.objects.get(id=t.id) eq_('A new title', edited_t.title)
def test_upload_video_ogv_flv(self): """Upload the same video, in ogv and flv formats""" ogv = open(TEST_VID['ogv']) flv = open(TEST_VID['flv']) post(self.client, 'gallery.upload_async', {'ogv': ogv, 'flv': flv}, args=['video']) ogv.close() flv.close() vid = Video.objects.all()[0] assert vid.ogv.url.endswith('098f6b.ogv') assert vid.flv.url.endswith('098f6b.flv')
def test_watch_other_thread_then_reply(self): """Watching a different thread than the one we're replying to shouldn't notify.""" u_b = user(username="******", save=True) _t = thread(save=True) self._toggle_watch_thread_as(u_b.username, _t, turn_on=True) u = user(save=True) t2 = thread(save=True) self.client.login(username=u.username, password="******") post(self.client, "wiki.discuss.reply", {"content": "a post"}, args=[t2.document.slug, t2.id]) assert not mail.outbox
def test_edit_post(self): """Changing post content works.""" p = forum_post(save=True) t = p.thread u = p.author self.client.login(username=u.username, password='******') post(self.client, 'forums.edit_post', {'content': 'Some new content'}, args=[t.forum.slug, t.id, p.id]) edited_p = Post.objects.get(id=p.id) eq_('Some new content', edited_p.content)
def test_watch_forum_then_new_thread_as_self(self, get_current): """Watching a forum and creating a new thread as myself should not send email.""" get_current.return_value.domain = "testserver" u = user(save=True) d = document(save=True) f = self._toggle_watch_kbforum_as(u.username, d, turn_on=True) self.client.login(username=u.username, password="******") post(self.client, "wiki.discuss.new_thread", {"title": "a title", "content": "a post"}, args=[f.slug]) # Assert no email is sent. assert not mail.outbox
def _toggle_watch_thread_as(self, username, thread, turn_on=True): """Watch a thread and return it.""" self.client.login(username=username, password="******") user = User.objects.get(username=username) watch = "yes" if turn_on else "no" post(self.client, "wiki.discuss.watch_thread", {"watch": watch}, args=[thread.document.slug, thread.id]) # Watch exists or not, depending on watch. if turn_on: assert NewPostEvent.is_notifying(user, thread), "NewPostEvent should be notifying." else: assert not NewPostEvent.is_notifying(user, thread), "NewPostEvent should not be notifying." return thread
def _toggle_watch_kbforum_as(self, username, document, turn_on=True): """Watch a discussion forum and return it.""" self.client.login(username=username, password="******") user = User.objects.get(username=username) watch = "yes" if turn_on else "no" post(self.client, "wiki.discuss.watch_forum", {"watch": watch}, args=[document.slug]) # Watch exists or not, depending on watch. if turn_on: assert NewThreadEvent.is_notifying(user, document), "NewThreadEvent should be notifying." else: assert not NewThreadEvent.is_notifying(user, document), "NewThreadEvent should not be notifying." return document
def test_watch_forum_then_new_post_as_self(self, get_current): """Watching a forum and replying as myself should not send email.""" get_current.return_value.domain = "testserver" u = user(save=True) d = document(title="an article title", save=True) f = self._toggle_watch_kbforum_as(u.username, d, turn_on=True) t = thread(document=d, save=True) self.client.login(username=u.username, password="******") post(self.client, "wiki.discuss.reply", {"content": "a post"}, args=[f.slug, t.id]) # Assert no email is sent. assert not mail.outbox
def test_edit_thread(self): """Changing thread title works.""" u = user(save=True) self.client.login(username=u.username, password='******') d = document(save=True) t = thread(title='Sticky Thread', document=d, creator=u, save=True) post(self.client, 'wiki.discuss.edit_thread', {'title': 'A new title'}, args=[d.slug, t.id]) edited_t = d.thread_set.get(pk=t.id) eq_('Sticky Thread', t.title) eq_('A new title', edited_t.title)
def test_sticky_thread_belongs_to_document(self): """Sticky action - thread belongs to document.""" r = post(self.client, 'wiki.discuss.sticky_thread', {}, args=[self.doc_2.slug, self.thread.id]) eq_(404, r.status_code)
def test_reply_thread_belongs_to_document(self): """Reply action - thread belongs to document.""" r = post(self.client, "wiki.discuss.reply", {}, args=[self.doc_2.slug, self.thread.id]) eq_(404, r.status_code)
def test_locked_thread_belongs_to_document(self): """Lock action - thread belongs to document.""" r = post(self.client, "wiki.discuss.lock_thread", {}, args=[self.doc_2.slug, self.thread.id]) eq_(404, r.status_code)
def test_locked_thread_403(self): """Marking a thread locked without permissions returns 403.""" response = post(self.client, 'wiki.discuss.lock_thread', args=[self.doc.slug, self.thread.id]) eq_(403, response.status_code)