from django.utils import timezone from misago.acl.testutils import override_acl from misago.categories.models import Category from misago.conf import settings from misago.readtracker.poststracker import save_read from misago.threads import testutils from misago.users.testutils import AuthenticatedUserTestCase GOTO_URL = '%s#post-%s' GOTO_PAGE_URL = '%s%s/#post-%s' class GotoViewTestCase(AuthenticatedUserTestCase): def setUp(self): super(GotoViewTestCase, self).setUp() self.category = Category.objects.get(slug='first-category') self.thread = testutils.post_thread(category=self.category) class GotoPostTests(GotoViewTestCase): def test_goto_first_post(self): """first post redirect url is valid""" response = self.client.get(self.thread.first_post.get_absolute_url()) self.assertEqual(response.status_code, 302) self.assertEqual( response['location'], GOTO_URL % (self.thread.get_absolute_url(), self.thread.first_post_id) ) response = self.client.get(response['location']) self.assertContains(response, self.thread.first_post.get_absolute_url()) def test_goto_last_post_on_page(self): """last post on page redirect url is valid""" for _ in range(settings.MISAGO_POSTS_PER_PAGE + settings.MISAGO_POSTS_TAIL - 1): post = testutils.reply_thread(self.thread) response = self.client.get(post.get_absolute_url()) self.assertEqual(response.status_code, 302) self.assertEqual( response['location'], GOTO_URL % (self.thread.get_absolute_url(), post.pk) ) response = self.client.get(response['location']) self.assertContains(response, post.get_absolute_url()) def test_goto_first_post_on_next_page(self): """first post on next page redirect url is valid""" for _ in range(settings.MISAGO_POSTS_PER_PAGE + settings.MISAGO_POSTS_TAIL): post = testutils.reply_thread(self.thread) response = self.client.get(post.get_absolute_url()) self.assertEqual(response.status_code, 302) self.assertEqual( response['location'], GOTO_PAGE_URL % (self.thread.get_absolute_url(), 2, post.pk) ) response = self.client.get(response['location']) self.assertContains(response, post.get_absolute_url()) def test_goto_first_post_on_page_three_out_of_five(self): """first post on next page redirect url is valid""" posts = [] for _ in range(settings.MISAGO_POSTS_PER_PAGE * 4 - 1): post = testutils.reply_thread(self.thread) posts.append(post) post = posts[settings.MISAGO_POSTS_PER_PAGE * 2 - 3] response = self.client.get(post.get_absolute_url()) self.assertEqual(response.status_code, 302) self.assertEqual( response['location'], GOTO_PAGE_URL % (self.thread.get_absolute_url(), 3, post.pk) ) response = self.client.get(response['location']) self.assertContains(response, post.get_absolute_url()) def test_goto_first_event_on_page_three_out_of_five(self): """event redirect url is valid""" posts = [] for _ in range(settings.MISAGO_POSTS_PER_PAGE * 4 - 1): post = testutils.reply_thread(self.thread) posts.append(post) post = posts[settings.MISAGO_POSTS_PER_PAGE * 2 - 2] self.thread.has_events = True self.thread.save() post.is_event = True post.save() response = self.client.get(post.get_absolute_url()) self.assertEqual(response.status_code, 302) self.assertEqual( response['location'], GOTO_PAGE_URL % (self.thread.get_absolute_url(), 3, post.pk) ) response = self.client.get(response['location']) self.assertContains(response, post.get_absolute_url()) class GotoLastTests(GotoViewTestCase): def test_goto_last_post(self): """first post redirect url is valid""" response = self.client.get(self.thread.get_last_post_url()) self.assertEqual(response.status_code, 302) self.assertEqual( response['location'], GOTO_URL % (self.thread.get_absolute_url(), self.thread.first_post_id) ) response = self.client.get(response['location']) self.assertContains(response, self.thread.last_post.get_absolute_url()) def test_goto_last_post_on_page(self): """last post on page redirect url is valid""" for _ in range(settings.MISAGO_POSTS_PER_PAGE + settings.MISAGO_POSTS_TAIL - 1): post = testutils.reply_thread(self.thread) response = self.client.get(self.thread.get_last_post_url()) self.assertEqual(response.status_code, 302) self.assertEqual( response['location'], GOTO_URL % (self.thread.get_absolute_url(), post.pk) ) response = self.client.get(response['location']) self.assertContains(response, post.get_absolute_url()) class GotoNewTests(GotoViewTestCase): def test_goto_first_post(self): """first unread post redirect url is valid""" response = self.client.get(self.thread.get_new_post_url()) self.assertEqual(response.status_code, 302) self.assertEqual( response['location'], GOTO_URL % (self.thread.get_absolute_url(), self.thread.first_post_id) ) def test_goto_first_new_post(self): """first unread post redirect url in already read thread is valid""" save_read(self.user, self.thread.first_post) post = testutils.reply_thread(self.thread, posted_on=timezone.now()) for _ in range(settings.MISAGO_POSTS_PER_PAGE + settings.MISAGO_POSTS_TAIL - 1): testutils.reply_thread(self.thread, posted_on=timezone.now()) response = self.client.get(self.thread.get_new_post_url()) self.assertEqual(response.status_code, 302) self.assertEqual( response['location'], GOTO_URL % (self.thread.get_absolute_url(), post.pk) ) def test_goto_first_new_post_on_next_page(self): """first unread post redirect url in already read multipage thread is valid""" save_read(self.user, self.thread.first_post) for _ in range(settings.MISAGO_POSTS_PER_PAGE + settings.MISAGO_POSTS_TAIL): last_post = testutils.reply_thread(self.thread, posted_on=timezone.now()) save_read(self.user, last_post) post = testutils.reply_thread(self.thread, posted_on=timezone.now()) for _ in range(settings.MISAGO_POSTS_PER_PAGE + settings.MISAGO_POSTS_TAIL - 1): testutils.reply_thread(self.thread, posted_on=timezone.now()) response = self.client.get(self.thread.get_new_post_url()) self.assertEqual(response.status_code, 302) self.assertEqual( response['location'], GOTO_PAGE_URL % (self.thread.get_absolute_url(), 2, post.pk) ) def test_goto_first_new_post_in_read_thread(self): """goto new in read thread points to last post""" save_read(self.user, self.thread.first_post) for _ in range(settings.MISAGO_POSTS_PER_PAGE + settings.MISAGO_POSTS_TAIL): post = testutils.reply_thread(self.thread, posted_on=timezone.now()) save_read(self.user, post) response = self.client.get(self.thread.get_new_post_url()) self.assertEqual(response.status_code, 302) self.assertEqual( response['location'], GOTO_PAGE_URL % (self.thread.get_absolute_url(), 2, post.pk) ) def test_guest_goto_first_new_post_in_thread(self): """guest goto new in read thread points to last post""" for _ in range(settings.MISAGO_POSTS_PER_PAGE + settings.MISAGO_POSTS_TAIL): post = testutils.reply_thread(self.thread, posted_on=timezone.now()) self.logout_user() response = self.client.get(self.thread.get_new_post_url()) self.assertEqual(response.status_code, 302) self.assertEqual( response['location'], GOTO_PAGE_URL % (self.thread.get_absolute_url(), 2, post.pk) ) class GotoBestAnswerTests(GotoViewTestCase): def test_view_handles_no_best_answer(self): """if thread has no best answer, redirect to first post""" response = self.client.get(self.thread.get_best_answer_url()) self.assertEqual(response.status_code, 302) self.assertEqual( response['location'], GOTO_URL % (self.thread.get_absolute_url(), self.thread.first_post_id), ) def test_view_handles_best_answer(self): """if thread has best answer, redirect to it""" for _ in range(settings.MISAGO_POSTS_PER_PAGE + settings.MISAGO_POSTS_TAIL): testutils.reply_thread(self.thread, posted_on=timezone.now()) best_answer = testutils.reply_thread(self.thread, posted_on=timezone.now()) self.thread.set_best_answer(self.user, best_answer) self.thread.save() for _ in range(settings.MISAGO_POSTS_PER_PAGE + settings.MISAGO_POSTS_TAIL - 1): testutils.reply_thread(self.thread, posted_on=timezone.now()) response = self.client.get(self.thread.get_best_answer_url()) self.assertEqual(response.status_code, 302) self.assertEqual( response['location'], GOTO_PAGE_URL % (self.thread.get_absolute_url(), 2, best_answer.pk), ) class GotoUnapprovedTests(GotoViewTestCase): def grant_permission(self): self.user.acl_cache['categories'][self.category.pk]['can_approve_content'] = 1 override_acl(self.user, self.user.acl_cache) def test_view_validates_permission(self): """view validates permission to see unapproved posts""" response = self.client.get(self.thread.get_unapproved_post_url()) self.assertContains(response, "You need permission to approve content", status_code=403) self.grant_permission() response = self.client.get(self.thread.get_unapproved_post_url()) self.assertEqual(response.status_code, 302) def test_view_handles_no_unapproved_posts(self): """if thread has no unapproved posts, redirect to last post""" self.grant_permission() response = self.client.get(self.thread.get_unapproved_post_url()) self.assertEqual(response.status_code, 302) self.assertEqual( response['location'], GOTO_URL % (self.thread.get_absolute_url(), self.thread.first_post_id) ) def test_view_handles_unapproved_posts(self): """if thread has unapproved posts, redirect to first of them""" for _ in range(settings.MISAGO_POSTS_PER_PAGE + settings.MISAGO_POSTS_TAIL): testutils.reply_thread(self.thread, posted_on=timezone.now()) post = testutils.reply_thread(self.thread, is_unapproved=True, posted_on=timezone.now()) for _ in range(settings.MISAGO_POSTS_PER_PAGE + settings.MISAGO_POSTS_TAIL - 1): testutils.reply_thread(self.thread, posted_on=timezone.now()) self.grant_permission() response = self.client.get(self.thread.get_unapproved_post_url()) self.assertEqual(response.status_code, 302) self.assertEqual( response['location'], GOTO_PAGE_URL % (self.thread.get_absolute_url(), 2, post.pk) ) class ThreadGotoPostTests(GotoViewTestCase): """brureforcing regression tests for regression test for #869""" def test_thread_growing_post_goto(self): """growing thread goto views don't fail""" for _ in range(60): post = testutils.reply_thread(self.thread, posted_on=timezone.now()) # go to post link is valid post_url = self.client.get(post.get_absolute_url())['location'] response = self.client.get(post_url) self.assertContains(response, post.get_absolute_url()) # go to last post link is valid last_url = self.client.get(self.thread.get_last_post_url())['location'] self.assertEqual(post_url, last_url) def test_thread_growing_event_goto(self): """growing thread goto views don't fail for events""" for i in range(60): testutils.reply_thread(self.thread, posted_on=timezone.now()) post = testutils.reply_thread(self.thread, posted_on=timezone.now()) post.is_event = True post.save() # go to post link is valid post_url = self.client.get(post.get_absolute_url())['location'] if i == 0: # manually set events flag after first event was created self.thread.has_events = True self.thread.save() response = self.client.get(post_url) self.assertContains(response, post.get_absolute_url()) # go to last post link is valid last_url = self.client.get(self.thread.get_last_post_url())['location'] self.assertEqual(post_url, last_url) def test_thread_post_goto(self): """thread goto views don't fail""" for _ in range(60): testutils.reply_thread(self.thread, posted_on=timezone.now()) for post in self.thread.post_set.order_by('id').iterator(): # go to post link is valid post_url = self.client.get(post.get_absolute_url())['location'] response = self.client.get(post_url) self.assertContains(response, post.get_absolute_url()) # go to last post link is valid last_url = self.client.get(self.thread.get_last_post_url())['location'] self.assertEqual(post_url, last_url) def test_thread_event_goto(self): """thread goto views don't fail for events""" for _ in range(60): testutils.reply_thread(self.thread, posted_on=timezone.now()) post = testutils.reply_thread(self.thread, posted_on=timezone.now()) post.is_event = True post.save() for post in self.thread.post_set.filter(is_event=True).order_by('id').iterator(): # go to post link is valid post_url = self.client.get(post.get_absolute_url())['location'] response = self.client.get(post_url) self.assertContains(response, post.get_absolute_url()) # go to last post link is valid last_url = self.client.get(self.thread.get_last_post_url())['location'] self.assertEqual(post_url, last_url)