##// END OF EJS Templates
Fixed unicode tags validation. Moved constants from classes to modules. Added error 404 when trying to get the non-existent thread. This fixes #19
neko259 -
r71:e89d805e default
parent child Browse files
Show More
@@ -39,7 +39,7 b' class PostForm(forms.Form):'
39 39
40 40
41 41 class ThreadForm(PostForm):
42 regex_tags = re.compile(r'^[\w\s]+$')
42 regex_tags = re.compile(ur'^[\w\s\d]+$', re.UNICODE)
43 43
44 44 tags = forms.CharField(max_length=100)
45 45
@@ -1,27 +1,31 b''
1 1 import os
2 2 from random import random
3 3 import re
4 from django.db import models
5 from django.utils import timezone
6 4 import time
7 5 import math
8 import markdown
9 from markdown.inlinepatterns import Pattern
10 from markdown.util import etree
6
7 from django.db import models
8 from django.http import Http404
9 from django.utils import timezone
10 from markupfield.fields import MarkupField
11 11
12 12 from neboard import settings
13 from markupfield.fields import MarkupField
13 import thumbs
14 14
15 import thumbs
16 15
17 16 NO_PARENT = -1
18 17 NO_IP = '0.0.0.0'
19 18 UNKNOWN_UA = ''
19 ALL_PAGES = -1
20 OPENING_POST_WEIGHT = 5
21 IMAGES_DIRECTORY = 'images/'
22 FILE_EXTENSION_DELIMITER = '.'
23
24 REGEX_PRETTY = re.compile(r'^\d(0)+$')
25 REGEX_SAME = re.compile(r'^(.)\1+$')
20 26
21 27
22 28 class PostManager(models.Manager):
23 ALL_PAGES = -1
24
25 29 def create_post(self, title, text, image=None, parent_id=NO_PARENT,
26 30 ip=NO_IP, tags=None):
27 31 post = self.create(title=title,
@@ -62,7 +66,7 b' class PostManager(models.Manager):'
62 66 threads = self.filter(parent=NO_PARENT)
63 67 threads = threads.order_by('-last_edit_time')
64 68
65 if page != self.ALL_PAGES:
69 if page != ALL_PAGES:
66 70 thread_count = len(threads)
67 71
68 72 if page < self.get_thread_page_count(tag=tag):
@@ -76,6 +80,9 b' class PostManager(models.Manager):'
76 80 def get_thread(self, opening_post_id):
77 81 opening_post = self.get(id=opening_post_id)
78 82
83 if not opening_post:
84 raise Http404
85
79 86 if opening_post.parent == NO_PARENT:
80 87 replies = self.filter(parent=opening_post_id)
81 88
@@ -151,8 +158,6 b' class Tag(models.Model):'
151 158 section. There can be multiple tags for each message
152 159 """
153 160
154 OPENING_POST_WEIGHT = 5
155
156 161 objects = TagManager()
157 162
158 163 name = models.CharField(max_length=100)
@@ -182,19 +187,16 b' class Tag(models.Model):'
182 187 class Post(models.Model):
183 188 """A post is a message."""
184 189
185 IMAGES_DIRECTORY = 'images/'
186 FILE_EXTENSION_DELIMITER = '.'
187
188 190 objects = PostManager()
189 191
190 192 def _update_image_filename(self, filename):
191 193 """Get unique image filename"""
192 194
193 path = self.IMAGES_DIRECTORY
195 path = IMAGES_DIRECTORY
194 196 new_name = str(int(time.mktime(time.gmtime())))
195 197 new_name += str(int(random() * 1000))
196 new_name += self.FILE_EXTENSION_DELIMITER
197 new_name += filename.split(self.FILE_EXTENSION_DELIMITER)[-1:][0]
198 new_name += FILE_EXTENSION_DELIMITER
199 new_name += filename.split(FILE_EXTENSION_DELIMITER)[-1:][0]
198 200
199 201 return os.path.join(path, new_name)
200 202
@@ -209,9 +211,6 b' class Post(models.Model):'
209 211 tags = models.ManyToManyField(Tag)
210 212 last_edit_time = models.DateTimeField()
211 213
212 regex_pretty = re.compile(r'^\d(0)+$')
213 regex_same = re.compile(r'^(.)\1+$')
214
215 214 def __unicode__(self):
216 215 return self.title + ' (' + self.text.raw + ')'
217 216
@@ -243,8 +242,8 b' class Post(models.Model):'
243 242 first = self.id == 1
244 243
245 244 id_str = str(self.id)
246 pretty = self.regex_pretty.match(id_str)
247 same_digits = self.regex_same.match(id_str)
245 pretty = REGEX_PRETTY.match(id_str)
246 same_digits = REGEX_SAME.match(id_str)
248 247
249 248 return first or pretty or same_digits
250 249
@@ -1,3 +1,4 b''
1 # coding=utf-8
1 2 from django.utils.unittest import TestCase
2 3 from django.test.client import Client
3 4
@@ -6,6 +7,11 b' import boards'
6 7 from boards.models import Post, Admin, Tag
7 8 from neboard import settings
8 9
10 TEST_TEXT = 'test text'
11
12 NEW_THREAD_PAGE = '/'
13 HTTP_CODE_REDIRECT = 302
14
9 15
10 16 class BoardTests(TestCase):
11 17 def _create_post(self):
@@ -119,8 +125,6 b' class BoardTests(TestCase):'
119 125 def test_pages(self):
120 126 """Test that the thread list is properly split into pages"""
121 127
122 PAGE_NUMBER = 2
123
124 128 for i in range(settings.MAX_THREAD_COUNT):
125 129 self._create_post()
126 130
@@ -130,4 +134,29 b' class BoardTests(TestCase):'
130 134 first_post = posts_in_second_page[0]
131 135
132 136 self.assertEqual(all_threads[settings.THREADS_PER_PAGE].id,
133 first_post.id) No newline at end of file
137 first_post.id)
138
139 def test_post_validation(self):
140 """Test the validation of the post form"""
141
142 Post.objects.all().delete()
143
144 client = Client()
145
146 valid_tags = u'tag1 tag_2 тег_3'
147 invalid_tags = u'$%_356 ---'
148
149 response = client.post(NEW_THREAD_PAGE, {'title': 'test title',
150 'text': TEST_TEXT,
151 'tags': valid_tags})
152 self.assertEqual(response.status_code, HTTP_CODE_REDIRECT,
153 msg='Posting new message failed: got code ' +
154 str(response.status_code))
155
156 self.assertEqual(1, Post.objects.count(),
157 msg='No posts were created')
158
159 response = client.post(NEW_THREAD_PAGE, {'text': TEST_TEXT,
160 'tags': invalid_tags})
161 self.assertEqual(1, Post.objects.count(), msg='The validation passed '
162 'where it should fail') No newline at end of file
@@ -110,7 +110,6 b' def thread(request, post_id):'
110 110 if request.method == 'POST':
111 111 return new_post(request, post_id)
112 112 else:
113 # TODO Show 404 if there is no such thread
114 113 posts = Post.objects.get_thread(post_id)
115 114
116 115 context = RequestContext(request)
General Comments 0
You need to be logged in to leave comments. Login now