Show More
@@ -7,7 +7,7 b' import uuid' | |||||
7 | from django.core.exceptions import ObjectDoesNotExist |
|
7 | from django.core.exceptions import ObjectDoesNotExist | |
8 | from django.core.urlresolvers import reverse |
|
8 | from django.core.urlresolvers import reverse | |
9 | from django.db import models, transaction |
|
9 | from django.db import models, transaction | |
10 | from django.db.models import TextField |
|
10 | from django.db.models import TextField, QuerySet | |
11 | from django.template.loader import render_to_string |
|
11 | from django.template.loader import render_to_string | |
12 | from django.utils import timezone |
|
12 | from django.utils import timezone | |
13 |
|
13 | |||
@@ -66,7 +66,7 b' REFMAP_STR = \'<a href="{}">>>{}</a' | |||||
66 | class PostManager(models.Manager): |
|
66 | class PostManager(models.Manager): | |
67 | @transaction.atomic |
|
67 | @transaction.atomic | |
68 | def create_post(self, title: str, text: str, image=None, thread=None, |
|
68 | def create_post(self, title: str, text: str, image=None, thread=None, | |
69 |
ip=NO_IP, tags: list=None, |
|
69 | ip=NO_IP, tags: list=None, opening_posts: list=None): | |
70 | """ |
|
70 | """ | |
71 | Creates new post |
|
71 | Creates new post | |
72 | """ |
|
72 | """ | |
@@ -79,8 +79,8 b' class PostManager(models.Manager):' | |||||
79 |
|
79 | |||
80 | if not tags: |
|
80 | if not tags: | |
81 | tags = [] |
|
81 | tags = [] | |
82 |
if not |
|
82 | if not opening_posts: | |
83 |
|
|
83 | opening_posts = [] | |
84 |
|
84 | |||
85 | posting_time = timezone.now() |
|
85 | posting_time = timezone.now() | |
86 | if not thread: |
|
86 | if not thread: | |
@@ -117,7 +117,7 b' class PostManager(models.Manager):' | |||||
117 |
|
117 | |||
118 | post.build_url() |
|
118 | post.build_url() | |
119 | post.connect_replies() |
|
119 | post.connect_replies() | |
120 |
post.connect_threads( |
|
120 | post.connect_threads(opening_posts) | |
121 | post.connect_notifications() |
|
121 | post.connect_notifications() | |
122 |
|
122 | |||
123 | return post |
|
123 | return post | |
@@ -241,7 +241,7 b' class Post(models.Model, Viewable):' | |||||
241 | def get_thread(self): |
|
241 | def get_thread(self): | |
242 | return self.thread |
|
242 | return self.thread | |
243 |
|
243 | |||
244 |
def get_threads(self) -> |
|
244 | def get_threads(self) -> QuerySet: | |
245 | """ |
|
245 | """ | |
246 | Gets post's thread. |
|
246 | Gets post's thread. | |
247 | """ |
|
247 | """ | |
@@ -361,8 +361,6 b' class Post(models.Model, Viewable):' | |||||
361 |
|
361 | |||
362 | if self.id: |
|
362 | if self.id: | |
363 | for thread in self.get_threads().all(): |
|
363 | for thread in self.get_threads().all(): | |
364 | if thread.can_bump(): |
|
|||
365 | thread.update_bump_status(exclude_posts=[self]) |
|
|||
366 | thread.last_edit_time = self.last_edit_time |
|
364 | thread.last_edit_time = self.last_edit_time | |
367 |
|
365 | |||
368 | thread.save(update_fields=['last_edit_time', 'bumpable']) |
|
366 | thread.save(update_fields=['last_edit_time', 'bumpable']) |
@@ -211,13 +211,15 b' class Thread(models.Model):' | |||||
211 | return boards.models.Tag.objects.get_tag_url_list(self.get_tags()) |
|
211 | return boards.models.Tag.objects.get_tag_url_list(self.get_tags()) | |
212 |
|
212 | |||
213 | def update_posts_time(self, exclude_posts=None): |
|
213 | def update_posts_time(self, exclude_posts=None): | |
|
214 | last_edit_time = self.last_edit_time | |||
|
215 | ||||
214 | for post in self.post_set.all(): |
|
216 | for post in self.post_set.all(): | |
215 | if exclude_posts is None or post not in exclude_posts: |
|
217 | if exclude_posts is None or post not in exclude_posts: | |
216 | # Manual update is required because uids are generated on save |
|
218 | # Manual update is required because uids are generated on save | |
217 |
post.last_edit_time = |
|
219 | post.last_edit_time = last_edit_time | |
218 | post.save(update_fields=['last_edit_time']) |
|
220 | post.save(update_fields=['last_edit_time']) | |
219 |
|
221 | |||
220 |
post.threads.update(last_edit_time= |
|
222 | post.get_threads().update(last_edit_time=last_edit_time) | |
221 |
|
223 | |||
222 | def notify_clients(self): |
|
224 | def notify_clients(self): | |
223 | if not settings.get_bool('External', 'WebsocketsEnabled'): |
|
225 | if not settings.get_bool('External', 'WebsocketsEnabled'): |
@@ -375,6 +375,9 b' function processNewPost(post) {' | |||||
375 | showAsErrors($('form'), gettext('Sending message...')); |
|
375 | showAsErrors($('form'), gettext('Sending message...')); | |
376 | }, |
|
376 | }, | |
377 | success: updateOnPost, |
|
377 | success: updateOnPost, | |
|
378 | error: function() { | |||
|
379 | showAsErrors($('form'), gettext('Server error!')); | |||
|
380 | }, | |||
378 | url: '/api/add_post/' + threadId + '/' |
|
381 | url: '/api/add_post/' + threadId + '/' | |
379 | }; |
|
382 | }; | |
380 |
|
383 |
@@ -1,5 +1,6 b'' | |||||
1 | from django.core.paginator import Paginator |
|
1 | from django.core.paginator import Paginator | |
2 | from django.test import TestCase |
|
2 | from django.test import TestCase | |
|
3 | ||||
3 | from boards import settings |
|
4 | from boards import settings | |
4 | from boards.models import Tag, Post, Thread |
|
5 | from boards.models import Tag, Post, Thread | |
5 |
|
6 | |||
@@ -124,8 +125,8 b' class PostTests(TestCase):' | |||||
124 | tags=[tag]) |
|
125 | tags=[tag]) | |
125 | thread = opening_post.get_thread() |
|
126 | thread = opening_post.get_thread() | |
126 |
|
127 | |||
127 |
|
|
128 | Post.objects.create_post(title='title', text='text', thread=thread) | |
128 |
|
|
129 | Post.objects.create_post(title='title', text='text', thread=thread) | |
129 |
|
130 | |||
130 | replies = thread.get_replies() |
|
131 | replies = thread.get_replies() | |
131 | self.assertTrue(len(replies) > 0, 'No replies found for thread.') |
|
132 | self.assertTrue(len(replies) > 0, 'No replies found for thread.') | |
@@ -133,3 +134,45 b' class PostTests(TestCase):' | |||||
133 | replies = thread.get_replies(view_fields_only=True) |
|
134 | replies = thread.get_replies(view_fields_only=True) | |
134 | self.assertTrue(len(replies) > 0, |
|
135 | self.assertTrue(len(replies) > 0, | |
135 | 'No replies found for thread with view fields only.') |
|
136 | 'No replies found for thread with view fields only.') | |
|
137 | ||||
|
138 | def test_bumplimit(self): | |||
|
139 | """ | |||
|
140 | Tests that the thread bumpable status is changed and post uids and | |||
|
141 | last update times are updated across all post threads. | |||
|
142 | """ | |||
|
143 | ||||
|
144 | op1 = Post.objects.create_post(title='title', text='text') | |||
|
145 | op2 = Post.objects.create_post(title='title', text='text') | |||
|
146 | ||||
|
147 | thread1 = op1.get_thread() | |||
|
148 | thread1.max_posts = 5 | |||
|
149 | thread1.save() | |||
|
150 | ||||
|
151 | uid_1 = op1.uid | |||
|
152 | uid_2 = op2.uid | |||
|
153 | ||||
|
154 | # Create multi reply | |||
|
155 | Post.objects.create_post( | |||
|
156 | title='title', text='text', thread=thread1, | |||
|
157 | opening_posts=[op1, op2]) | |||
|
158 | thread_update_time_2 = op2.get_thread().last_edit_time | |||
|
159 | for i in range(6): | |||
|
160 | Post.objects.create_post(title='title', text='text', | |||
|
161 | thread=thread1) | |||
|
162 | ||||
|
163 | self.assertFalse(op1.get_thread().can_bump(), | |||
|
164 | 'Thread is bumpable when it should not be.') | |||
|
165 | self.assertTrue(op2.get_thread().can_bump(), | |||
|
166 | 'Thread is not bumpable when it should be.') | |||
|
167 | self.assertNotEqual( | |||
|
168 | uid_1, Post.objects.get(id=op1.id).uid, | |||
|
169 | 'UID of the first OP should be changed but it is not.') | |||
|
170 | self.assertEqual( | |||
|
171 | uid_2, Post.objects.get(id=op2.id).uid, | |||
|
172 | 'UID of the first OP should not be changed but it is.') | |||
|
173 | ||||
|
174 | self.assertNotEqual( | |||
|
175 | thread_update_time_2, | |||
|
176 | Thread.objects.get(id=op2.get_thread().id).last_edit_time, | |||
|
177 | 'Thread last update time should change when the other thread ' | |||
|
178 | 'changes status.') |
@@ -151,7 +151,7 b' class AllThreadsView(PostMixin, BaseBoar' | |||||
151 | tags = self.parse_tags_string(tag_strings) |
|
151 | tags = self.parse_tags_string(tag_strings) | |
152 |
|
152 | |||
153 | post = Post.objects.create_post(title=title, text=text, image=image, |
|
153 | post = Post.objects.create_post(title=title, text=text, image=image, | |
154 |
ip=ip, tags=tags, |
|
154 | ip=ip, tags=tags, opening_posts=threads) | |
155 |
|
155 | |||
156 | # This is required to update the threads to which posts we have replied |
|
156 | # This is required to update the threads to which posts we have replied | |
157 | # when creating this one |
|
157 | # when creating this one |
@@ -111,7 +111,7 b' class ThreadView(BaseBoardView, PostMixi' | |||||
111 |
|
111 | |||
112 | post = Post.objects.create_post(title=title, text=text, image=image, |
|
112 | post = Post.objects.create_post(title=title, text=text, image=image, | |
113 | thread=post_thread, ip=ip, |
|
113 | thread=post_thread, ip=ip, | |
114 |
|
|
114 | opening_posts=threads) | |
115 | post.notify_clients() |
|
115 | post.notify_clients() | |
116 |
|
116 | |||
117 | if html_response: |
|
117 | if html_response: |
General Comments 0
You need to be logged in to leave comments.
Login now