def setUp(self): url = reverse('forums.threads', args=[u'test-forum']) self.context = {'request': test_utils.RequestFactory().get(url)} self.group = group(save=True) # Set up forum_1 f = self.forum_1 = forum(save=True) ct = ContentType.objects.get_for_model(self.forum_1) permission(codename='forums_forum.thread_edit_forum', content_type=ct, object_id=f.id, group=self.group, save=True) permission(codename='forums_forum.post_edit_forum', content_type=ct, object_id=f.id, group=self.group, save=True) permission(codename='forums_forum.post_delete_forum', content_type=ct, object_id=f.id, group=self.group, save=True) permission(codename='forums_forum.thread_delete_forum', content_type=ct, object_id=f.id, group=self.group, save=True) permission(codename='forums_forum.thread_sticky_forum', content_type=ct, object_id=f.id, group=self.group, save=True) permission(codename='forums_forum.thread_move_forum', content_type=ct, object_id=f.id, group=self.group, save=True) # Set up forum_2 f = self.forum_2 = forum(save=True) permission(codename='forums_forum.thread_move_forum', content_type=ct, object_id=f.id, group=self.group, save=True)
def test_discussion_filter_forum(self): """Filter by forum in discussion forums.""" forum1 = forum(name=u"Forum 1", save=True) thread1 = thread(forum=forum1, title=u"audio 1", save=True) post(thread=thread1, save=True) forum2 = forum(name=u"Forum 2", save=True) thread2 = thread(forum=forum2, title=u"audio 2", save=True) post(thread=thread2, save=True) import kitsune.search.forms reload(kitsune.search.forms) import kitsune.search.views import kitsune.search.forms kitsune.search.views.SearchForm = kitsune.search.forms.SearchForm # Wait... reload? WTF is that about? What's going on here is # that SearchForm pulls the list of forums from the db **at # module load time**. Since we need it to include the two # forums we just created, we need to reload the module and # rebind it in kitsune.search.views. Otherwise when we go to get # cleaned_data from it, it ditches the forum data we so # lovingly put in our querystring and then our filters are # wrong and then this test FAILS. self.refresh() qs = {"a": 1, "w": 4, "format": "json"} for forum_id in (forum1.id, forum2.id): qs["forum"] = int(forum_id) response = self.client.get(reverse("search"), qs) eq_(json.loads(response.content)["total"], 1)
def setUp(self): url = reverse('forums.threads', args=[u'test-forum']) self.context = {'request': RequestFactory().get(url)} self.group = group(save=True) # Set up forum_1 f = self.forum_1 = forum(save=True) ct = ContentType.objects.get_for_model(self.forum_1) permission(codename='forums_forum.thread_edit_forum', content_type=ct, object_id=f.id, group=self.group, save=True) permission(codename='forums_forum.post_edit_forum', content_type=ct, object_id=f.id, group=self.group, save=True) permission(codename='forums_forum.post_delete_forum', content_type=ct, object_id=f.id, group=self.group, save=True) permission(codename='forums_forum.thread_delete_forum', content_type=ct, object_id=f.id, group=self.group, save=True) permission(codename='forums_forum.thread_sticky_forum', content_type=ct, object_id=f.id, group=self.group, save=True) permission(codename='forums_forum.thread_move_forum', content_type=ct, object_id=f.id, group=self.group, save=True) # Set up forum_2 f = self.forum_2 = forum(save=True) permission(codename='forums_forum.thread_move_forum', content_type=ct, object_id=f.id, group=self.group, save=True)
def test_canonical_url(self): """Verify the canonical URL is set correctly.""" f = forum(save=True) response = get(self.client, 'forums.threads', args=[f.slug]) eq_('/forums/%s' % f.slug, pq(response.content)('link[rel="canonical"]')[0].attrib['href'])
def test_watch_forum_then_new_thread(self, get_current): """Watching a forum and creating a new thread should send email.""" get_current.return_value.domain = 'testserver' f = forum(save=True) poster = user(save=True) watcher = user(save=True) self._toggle_watch_forum_as(f, watcher, turn_on=True) self.client.login(username=poster.username, password='******') post(self.client, 'forums.new_thread', { 'title': 'a title', 'content': 'a post' }, args=[f.slug]) t = Thread.objects.all().order_by('-id')[0] attrs_eq(mail.outbox[0], to=[watcher.email], subject='{f} - {t}'.format(f=f, t=t)) body = NEW_THREAD_EMAIL.format(username=poster.username, forum_slug=f.slug, thread=t.title, thread_id=t.id) starts_with(mail.outbox[0].body, body)
def test_delete_post_belongs_to_thread_and_forum(self): # Delete post action - post belongs to thread and thread # belongs to forum. f = forum(save=True) t = thread(forum=f, save=True) # Post belongs to a different forum and thread. p = forum_post(save=True) u = p.author # Give the user the permission to delete posts. g = group(save=True) ct = ContentType.objects.get_for_model(f) permission(codename='forums_forum.post_delete_forum', content_type=ct, object_id=p.thread.forum_id, group=g, save=True) permission(codename='forums_forum.post_delete_forum', content_type=ct, object_id=f.id, group=g, save=True) g.user_set.add(u) self.client.login(username=u.username, password='******') # Post isn't in the passed forum: r = get(self.client, 'forums.delete_post', args=[f.slug, p.thread.id, p.id]) eq_(404, r.status_code) # Post isn't in the passed thread: r = get(self.client, 'forums.delete_post', args=[p.thread.forum.slug, t.id, p.id]) eq_(404, r.status_code)
def test_move_thread(self): """Move a thread.""" t = forum_post(save=True).thread f = forum(save=True) u = user(save=True) g = group(save=True) # Give the user permission to move threads between the two forums. ct = ContentType.objects.get_for_model(f) permission(codename='forums_forum.thread_move_forum', content_type=ct, object_id=f.id, group=g, save=True) permission(codename='forums_forum.thread_move_forum', content_type=ct, object_id=t.forum.id, group=g, save=True) g.user_set.add(u) self.client.login(username=u.username, password='******') response = post(self.client, 'forums.move_thread', {'forum': f.id}, args=[t.forum.slug, t.id]) eq_(200, response.status_code) t = Thread.uncached.get(pk=t.pk) eq_(f.id, t.forum.id)
def test_forums_search_authorized_forums(self): """Only authorized people can search certain forums""" # Create two threads: one in a restricted forum and one not. forum1 = forum(name=u'ou812forum', save=True) thread1 = thread(forum=forum1, save=True) post(thread=thread1, content=u'audio', save=True) forum2 = restricted_forum(name=u'restrictedkeepout', save=True) thread2 = thread(forum=forum2, save=True) post(thread=thread2, content=u'audio restricted', save=True) self.refresh() # Do a search as an anonymous user but don't specify the # forums to filter on. Should only see one of the posts. response = self.client.get(reverse('search'), { 'author': '', 'created': '0', 'created_date': '', 'updated': '0', 'updated_date': '', 'sortby': '0', 'a': '1', 'w': '4', 'q': 'audio', 'format': 'json' }) eq_(200, response.status_code) content = json.loads(response.content) eq_(content['total'], 1) # Do a search as an authorized user but don't specify the # forums to filter on. Should see both posts. u = user(save=True) g = group(save=True) g.user_set.add(u) ct = ContentType.objects.get_for_model(forum2) permission(codename='forums_forum.view_in_forum', content_type=ct, object_id=forum2.id, group=g, save=True) self.client.login(username=u.username, password='******') response = self.client.get(reverse('search'), { 'author': '', 'created': '0', 'created_date': '', 'updated': '0', 'updated_date': '', 'sortby': '0', 'a': '1', 'w': '4', 'q': 'audio', 'format': 'json' }) # Sees both results eq_(200, response.status_code) content = json.loads(response.content) eq_(content['total'], 2)
def test_watch_GET_405(self): """Watch forum with HTTP GET results in 405.""" f = forum(save=True) u = user(save=True) self.client.login(username=u.username, password='******') response = get(self.client, 'forums.watch_forum', args=[f.id]) eq_(405, response.status_code)
def test_show_new_thread(self): """'Post new thread' shows if user has permission to post.""" f = forum(save=True) u = user(save=True) self.client.login(username=u.username, password='******') response = get(self.client, 'forums.threads', args=[f.slug]) self.assertContains(response, 'Post a new thread')
def test_fire_on_new_thread(self, fire): """The event fires when there is a new thread.""" u = user(save=True) f = forum(save=True) 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_edit_thread_belongs_to_forum(self): """Edit thread action - thread belongs to forum.""" f = forum(save=True) t = forum_post(save=True).thread # Thread belongs to a different forum u = t.creator self.client.login(username=u.username, password='******') r = get(self.client, 'forums.edit_thread', args=[f.slug, t.id]) eq_(404, r.status_code)
def test_reply_thread_belongs_to_forum(self): """Reply action - thread belongs to forum.""" f = forum(save=True) t = thread(save=True) # Thread belongs to a different forum u = user(save=True) self.client.login(username=u.username, password='******') r = post(self.client, 'forums.reply', {}, args=[f.slug, t.id]) eq_(404, r.status_code)
def test_posts_thread_belongs_to_forum(self): """Posts view - redirect if thread does not belong to forum.""" f = forum(save=True) t = thread(save=True) # Thread belongs to a different forum r = get(self.client, 'forums.posts', args=[f.slug, t.id]) eq_(200, r.status_code) u = r.redirect_chain[0][0] assert u.endswith(t.get_absolute_url())
def test_discussion_filter_forum(self): """Filter by forum in discussion forums.""" forum1 = forum(name=u'Forum 1', save=True) thread1 = thread(forum=forum1, title=u'audio 1', save=True) post(thread=thread1, save=True) forum2 = forum(name=u'Forum 2', save=True) thread2 = thread(forum=forum2, title=u'audio 2', save=True) post(thread=thread2, save=True) self.refresh() qs = {'a': 1, 'w': 4, 'format': 'json'} for forum_id in (forum1.id, forum2.id): qs['forum'] = int(forum_id) response = self.client.get(reverse('search'), qs) eq_(json.loads(response.content)['total'], 1)
def test_public_access(self): # Assert Forums think they're publicly viewable and postable # at appropriate times. # By default, users have access to forums that aren't restricted. u = user(save=True) f = forum(save=True) assert f.allows_viewing_by(u) assert f.allows_posting_by(u)
def test_display_order(self): """Verify the display_order is respected.""" forum1 = forum(display_order=1, save=True) forum2 = forum(display_order=2, save=True) # forum1 should be listed first r = get(self.client, 'forums.forums') eq_(200, r.status_code) doc = pq(r.content) eq_(forum1.name, doc('ol.forums > li a:first').text()) forum1.display_order = 3 forum1.save() # forum2 should be listed first r = get(self.client, 'forums.forums') eq_(200, r.status_code) doc = pq(r.content) eq_(forum2.name, doc('ol.forums > li a:first').text())
def test_fire_on_new_thread(self, fire): """The event fires when there is a new thread.""" u = user(save=True) f = forum(save=True) 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 _restricted_forum(permission_code='forums_forum.view_in_forum'): """Return a forum with specified restriction.""" restricted_forum = forum(save=True) # Make it restricted. ct = ContentType.objects.get_for_model(restricted_forum) permission(codename=permission_code, content_type=ct, object_id=restricted_forum.id, save=True) return restricted_forum
def test_threads_sort(self): """Ensure that threads are being sorted properly by date/time.""" # Threads are sorted descending by last post date. f = forum(save=True) t1 = thread(forum=f, created=YESTERDAY, save=True) post(thread=t1, created=YESTERDAY, save=True) t2 = thread(forum=f, save=True) post(thread=t2, save=True) eq_(t2.id, ThreadsFeed().items(f)[0].id)
def test_restricted_is_invisible(self): """Forums with restricted view_in permission shouldn't show up.""" restricted_forum = forum(save=True) # Make it restricted. ct = ContentType.objects.get_for_model(restricted_forum) permission(codename='forums_forum.view_in_forum', content_type=ct, object_id=restricted_forum.id, save=True) response = get(self.client, 'forums.forums') self.assertNotContains(response, restricted_forum.slug)
def test_move_thread_403(self): """Moving a thread without permissions returns 403.""" t = forum_post(save=True).thread f = forum(save=True) u = user(save=True) self.client.login(username=u.username, password='******') response = post(self.client, 'forums.move_thread', {'forum': f.id}, args=[t.forum.slug, t.id]) eq_(403, response.status_code)
def test_is_listed(self): """Verify is_listed is respected.""" forum1 = forum(is_listed=True, save=True) forum2 = forum(is_listed=True, save=True) # Both forums should be listed. r = get(self.client, 'forums.forums') eq_(200, r.status_code) doc = pq(r.content) eq_(2, len(doc('ol.forums > li'))) forum1.is_listed = False forum1.save() # Only forum2 should be listed. r = get(self.client, 'forums.forums') eq_(200, r.status_code) doc = pq(r.content) eq_(1, len(doc('ol.forums > li'))) eq_(forum2.name, doc('ol.forums > li a').text())
def test_new_thread_redirect(self): """Posting a new thread should redirect.""" f = forum(save=True) u = user(save=True) self.client.login(username=u.username, password='******') url = reverse('forums.new_thread', args=[f.slug]) data = {'title': 'some title', 'content': 'some content'} r = self.client.post(url, data, follow=False) eq_(302, r.status_code) assert f.slug in r['location'] assert 'last=' in r['location']
def test_empty_thread_errors(self): """Posting an empty thread shows errors.""" f = forum(save=True) u = user(save=True) self.client.login(username=u.username, password='******') response = post(self.client, 'forums.new_thread', {'title': '', 'content': ''}, args=[f.slug]) doc = pq(response.content) errors = doc('ul.errorlist li a') eq_(errors[0].text, 'Please provide a title.') eq_(errors[1].text, 'Please provide a message.')
def test_recent_threads(self): """Verify the Community Discussions section.""" f = forum(slug='contributors', save=True) thread(forum=f, title='we are SUMO!!!!!!', save=True) self.refresh() response = self.client.get(urlparams(reverse('community.home'))) eq_(response.status_code, 200) doc = pq(response.content) eq_(1, len(doc('#recent-threads'))) assert 'we are SUMO!' in doc('#recent-threads li').html()
def test_perm_is_defined_on(self): """Test permission relationship Test whether we check for permission relationship, independent of whether the permission is actually assigned to anyone. """ from kitsune.forums.tests import forum, restricted_forum f1 = restricted_forum() f2 = forum(save=True) perm = 'forums_forum.view_in_forum' assert access.perm_is_defined_on(perm, f1) assert not access.perm_is_defined_on(perm, f2)
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" f = forum(save=True) watcher = user(save=True) self._toggle_watch_forum_as(f, watcher, turn_on=True) self.client.login(username=watcher.username, password="******") post(self.client, "forums.new_thread", {"title": "a title", "content": "a post"}, args=[f.slug]) # Assert no email is sent. assert not mail.outbox
def test_watch_forum(self): """Watch and unwatch a forum.""" f = forum(save=True) u = user(save=True) self.client.login(username=u.username, password='******') response = post(self.client, 'forums.watch_forum', {'watch': 'yes'}, args=[f.slug]) self.assertContains(response, 'Stop watching this forum') response = post(self.client, 'forums.watch_forum', {'watch': 'no'}, args=[f.slug]) self.assertNotContains(response, 'Stop watching this forum')
def test_restricted_hide_new_thread(self): """'Post new thread' doesn't show if user has no permission to post. """ f = forum(save=True) ct = ContentType.objects.get_for_model(f) # If the forum has the permission and the user isn't assigned said # permission, then they can't post. permission(codename='forums_forum.post_in_forum', content_type=ct, object_id=f.id, save=True) u = user(save=True) self.client.login(username=u.username, password='******') response = get(self.client, 'forums.threads', args=[f.slug]) self.assertNotContains(response, 'Post a new thread')
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' f = forum(save=True) watcher = user(save=True) self._toggle_watch_forum_as(f, watcher, turn_on=True) self.client.login(username=watcher.username, password='******') post(self.client, 'forums.new_thread', {'title': 'a title', 'content': 'a post'}, args=[f.slug]) # Assert no email is sent. assert not mail.outbox
def test_preview(self): """Preview the thread post.""" f = forum(save=True) u = user(save=True) self.client.login(username=u.username, password='******') content = 'Full of awesome.' response = post(self.client, 'forums.new_thread', {'title': 'Topic', 'content': content, 'preview': 'any string'}, args=[f.slug]) eq_(200, response.status_code) doc = pq(response.content) eq_(content, doc('#post-preview div.content').text()) eq_(0, f.thread_set.count()) # No thread was created.
def test_move_updates_last_posts(self): # Moving the thread containing a forum's last post to a new # forum should update the last_post of both # forums. Consequently, deleting the last post shouldn't # delete the old forum. [bug 588994] # Setup forum to move latest thread from. old_forum = forum(save=True) t1 = thread(forum=old_forum, save=True) p1 = post(thread=t1, created=YESTERDAY, save=True) t2 = thread(forum=old_forum, save=True) p2 = post(thread=t2, save=True) # Newest post of all. # Setup forum to move latest thread to. new_forum = forum(save=True) t3 = thread(forum=new_forum, save=True) p3 = post(thread=t3, created=YESTERDAY, save=True) # Verify the last_post's are correct. eq_(p2, Forum.objects.get(id=old_forum.id).last_post) eq_(p3, Forum.objects.get(id=new_forum.id).last_post) # Move the t2 thread. t2 = Thread.objects.get(id=t2.id) t2.forum = new_forum t2.save() # Old forum's last_post updated? eq_(p1.id, Forum.objects.get(id=old_forum.id).last_post_id) # New forum's last_post updated? eq_(p2.id, Forum.objects.get(id=new_forum.id).last_post_id) # Delete the post, and both forums should still exist: p2.delete() eq_(1, Forum.objects.filter(id=old_forum.id).count()) eq_(1, Forum.objects.filter(id=new_forum.id).count())
def test_access_restriction(self): """Assert Forums are inaccessible to the public when restricted.""" # If the a forum has 'forums_forum.view_in_forum' permission defined, # then it isn't public by default. If it has # 'forums_forum.post_in_forum', then it isn't postable to by default. f = forum(save=True) ct = ContentType.objects.get_for_model(f) permission(codename='forums_forum.view_in_forum', content_type=ct, object_id=f.id, save=True) permission(codename='forums_forum.post_in_forum', content_type=ct, object_id=f.id, save=True) unprivileged_user = user(save=True) assert not f.allows_viewing_by(unprivileged_user) assert not f.allows_posting_by(unprivileged_user)
def test_new_short_thread_errors(self): """Posting a short new thread shows errors.""" f = forum(save=True) u = user(save=True) self.client.login(username=u.username, password='******') response = post(self.client, 'forums.new_thread', {'title': 'wha?', 'content': 'wha?'}, args=[f.slug]) doc = pq(response.content) errors = doc('ul.errorlist li a') eq_(errors[0].text, 'Your title is too short (4 characters). ' + 'It must be at least 5 characters.') eq_(errors[1].text, 'Your message is too short (4 characters). ' + 'It must be at least 5 characters.')
def test_watch_forum(self): """Watch then unwatch a forum.""" f = forum(save=True) forum_post(thread=thread(forum=f, save=True), save=True) u = user(save=True) self.client.login(username=u.username, password='******') post(self.client, 'forums.watch_forum', {'watch': 'yes'}, args=[f.slug]) assert NewThreadEvent.is_notifying(u, f) # NewPostEvent is not notifying. assert not NewPostEvent.is_notifying(u, f.last_post) post(self.client, 'forums.watch_forum', {'watch': 'no'}, args=[f.slug]) assert not NewThreadEvent.is_notifying(u, f)