from django.core.paginator import Paginator from django.test import TestCase from boards import settings from boards.models import Tag, Post, Thread, KeyPair from boards.models.thread import STATUS_ARCHIVE class PostTests(TestCase): def _create_post(self): tag, created = Tag.objects.get_or_create(name='test_tag') return Post.objects.create_post(title='title', text='text', tags=[tag]) def test_post_add(self): """Test adding post""" post = self._create_post() self.assertIsNotNone(post, 'No post was created.') self.assertEqual('test_tag', post.get_thread().tags.all()[0].name, 'No tags were added to the post.') def test_delete_post(self): """Test post deletion""" post = self._create_post() post_id = post.id post.delete() self.assertFalse(Post.objects.filter(id=post_id).exists()) def test_delete_thread(self): """Test thread deletion""" opening_post = self._create_post() thread = opening_post.get_thread() reply = Post.objects.create_post("", "", thread=thread) thread.delete() self.assertFalse(Post.objects.filter(id=reply.id).exists(), 'Reply was not deleted with the thread.') self.assertFalse(Post.objects.filter(id=opening_post.id).exists(), 'Opening post was not deleted with the thread.') def test_post_to_thread(self): """Test adding post to a thread""" op = self._create_post() post = Post.objects.create_post("", "", thread=op.get_thread()) self.assertIsNotNone(post, 'Reply to thread wasn\'t created') self.assertEqual(op.get_thread().last_edit_time, post.pub_time, 'Post\'s create time doesn\'t match thread last edit' ' time') def test_delete_posts_by_ip(self): """Test deleting posts with the given ip""" post = self._create_post() post_id = post.id Post.objects.delete_posts_by_ip('0.0.0.0') self.assertFalse(Post.objects.filter(id=post_id).exists()) def test_get_thread(self): """Test getting all posts of a thread""" opening_post = self._create_post() for i in range(2): Post.objects.create_post('title', 'text', thread=opening_post.get_thread()) thread = opening_post.get_thread() self.assertEqual(3, thread.get_replies().count()) def test_create_post_with_tag(self): """Test adding tag to post""" tag = Tag.objects.create(name='test_tag') post = Post.objects.create_post(title='title', text='text', tags=[tag]) thread = post.get_thread() self.assertIsNotNone(post, 'Post not created') self.assertTrue(tag in thread.tags.all(), 'Tag not added to thread') def test_thread_max_count(self): """Test deletion of old posts when the max thread count is reached""" for i in range(settings.get_int('Messages', 'MaxThreadCount') + 1): self._create_post() self.assertEqual(settings.get_int('Messages', 'MaxThreadCount'), len(Thread.objects.exclude(status=STATUS_ARCHIVE))) def test_pages(self): """Test that the thread list is properly split into pages""" for i in range(settings.get_int('Messages', 'MaxThreadCount')): self._create_post() all_threads = Thread.objects.exclude(status=STATUS_ARCHIVE) paginator = Paginator(Thread.objects.exclude(status=STATUS_ARCHIVE), settings.get_int('View', 'ThreadsPerPage')) posts_in_second_page = paginator.page(2).object_list first_post = posts_in_second_page[0] self.assertEqual(all_threads[settings.get_int('View', 'ThreadsPerPage')].id, first_post.id) def test_reflinks(self): """ Tests that reflinks are parsed within post and connecting replies to the replied posts. Local reflink example: [post]123[/post] Global reflink example: [post]key_type::key::123[/post] """ key = KeyPair.objects.generate_key(primary=True) tag = Tag.objects.create(name='test_tag') post = Post.objects.create_post(title='', text='', tags=[tag]) post_local_reflink = Post.objects.create_post(title='', text='[post]%d[/post]' % post.id, thread=post.get_thread()) self.assertTrue(post_local_reflink in post.referenced_posts.all(), 'Local reflink not connecting posts.') def test_thread_replies(self): """ Tests that the replies can be queried from a thread in all possible ways. """ tag = Tag.objects.create(name='test_tag') opening_post = Post.objects.create_post(title='title', text='text', tags=[tag]) thread = opening_post.get_thread() Post.objects.create_post(title='title', text='text', thread=thread) Post.objects.create_post(title='title', text='text', thread=thread) replies = thread.get_replies() self.assertTrue(len(replies) > 0, 'No replies found for thread.') replies = thread.get_replies(view_fields_only=True) self.assertTrue(len(replies) > 0, 'No replies found for thread with view fields only.') def test_bumplimit(self): """ Tests that the thread bumpable status is changed and post uids and last update times are updated across all post threads. """ op1 = Post.objects.create_post(title='title', text='text') op2 = Post.objects.create_post(title='title', text='text') thread1 = op1.get_thread() thread1.max_posts = 5 thread1.save() uid_1 = op1.uid uid_2 = op2.uid # Create multi reply Post.objects.create_post( title='title', text='text', thread=thread1, opening_posts=[op1, op2]) thread_update_time_2 = op2.get_thread().last_edit_time for i in range(6): Post.objects.create_post(title='title', text='text', thread=thread1) self.assertFalse(op1.get_thread().can_bump(), 'Thread is bumpable when it should not be.') self.assertTrue(op2.get_thread().can_bump(), 'Thread is not bumpable when it should be.') self.assertNotEqual( uid_1, Post.objects.get(id=op1.id).uid, 'UID of the first OP should be changed but it is not.') self.assertEqual( uid_2, Post.objects.get(id=op2.id).uid, 'UID of the first OP should not be changed but it is.') self.assertNotEqual( thread_update_time_2, Thread.objects.get(id=op2.get_thread().id).last_edit_time, 'Thread last update time should change when the other thread ' 'changes status.')