diff --git a/boards/forms.py b/boards/forms.py --- a/boards/forms.py +++ b/boards/forms.py @@ -39,7 +39,7 @@ class PostForm(forms.Form): class ThreadForm(PostForm): - regex_tags = re.compile(r'^[\w\s]+$') + regex_tags = re.compile(ur'^[\w\s\d]+$', re.UNICODE) tags = forms.CharField(max_length=100) diff --git a/boards/models.py b/boards/models.py --- a/boards/models.py +++ b/boards/models.py @@ -1,27 +1,31 @@ import os from random import random import re -from django.db import models -from django.utils import timezone import time import math -import markdown -from markdown.inlinepatterns import Pattern -from markdown.util import etree + +from django.db import models +from django.http import Http404 +from django.utils import timezone +from markupfield.fields import MarkupField from neboard import settings -from markupfield.fields import MarkupField +import thumbs -import thumbs NO_PARENT = -1 NO_IP = '0.0.0.0' UNKNOWN_UA = '' +ALL_PAGES = -1 +OPENING_POST_WEIGHT = 5 +IMAGES_DIRECTORY = 'images/' +FILE_EXTENSION_DELIMITER = '.' + +REGEX_PRETTY = re.compile(r'^\d(0)+$') +REGEX_SAME = re.compile(r'^(.)\1+$') class PostManager(models.Manager): - ALL_PAGES = -1 - def create_post(self, title, text, image=None, parent_id=NO_PARENT, ip=NO_IP, tags=None): post = self.create(title=title, @@ -62,7 +66,7 @@ class PostManager(models.Manager): threads = self.filter(parent=NO_PARENT) threads = threads.order_by('-last_edit_time') - if page != self.ALL_PAGES: + if page != ALL_PAGES: thread_count = len(threads) if page < self.get_thread_page_count(tag=tag): @@ -76,6 +80,9 @@ class PostManager(models.Manager): def get_thread(self, opening_post_id): opening_post = self.get(id=opening_post_id) + if not opening_post: + raise Http404 + if opening_post.parent == NO_PARENT: replies = self.filter(parent=opening_post_id) @@ -151,8 +158,6 @@ class Tag(models.Model): section. There can be multiple tags for each message """ - OPENING_POST_WEIGHT = 5 - objects = TagManager() name = models.CharField(max_length=100) @@ -182,19 +187,16 @@ class Tag(models.Model): class Post(models.Model): """A post is a message.""" - IMAGES_DIRECTORY = 'images/' - FILE_EXTENSION_DELIMITER = '.' - objects = PostManager() def _update_image_filename(self, filename): """Get unique image filename""" - path = self.IMAGES_DIRECTORY + path = IMAGES_DIRECTORY new_name = str(int(time.mktime(time.gmtime()))) new_name += str(int(random() * 1000)) - new_name += self.FILE_EXTENSION_DELIMITER - new_name += filename.split(self.FILE_EXTENSION_DELIMITER)[-1:][0] + new_name += FILE_EXTENSION_DELIMITER + new_name += filename.split(FILE_EXTENSION_DELIMITER)[-1:][0] return os.path.join(path, new_name) @@ -209,9 +211,6 @@ class Post(models.Model): tags = models.ManyToManyField(Tag) last_edit_time = models.DateTimeField() - regex_pretty = re.compile(r'^\d(0)+$') - regex_same = re.compile(r'^(.)\1+$') - def __unicode__(self): return self.title + ' (' + self.text.raw + ')' @@ -243,8 +242,8 @@ class Post(models.Model): first = self.id == 1 id_str = str(self.id) - pretty = self.regex_pretty.match(id_str) - same_digits = self.regex_same.match(id_str) + pretty = REGEX_PRETTY.match(id_str) + same_digits = REGEX_SAME.match(id_str) return first or pretty or same_digits diff --git a/boards/tests.py b/boards/tests.py --- a/boards/tests.py +++ b/boards/tests.py @@ -1,3 +1,4 @@ +# coding=utf-8 from django.utils.unittest import TestCase from django.test.client import Client @@ -6,6 +7,11 @@ import boards from boards.models import Post, Admin, Tag from neboard import settings +TEST_TEXT = 'test text' + +NEW_THREAD_PAGE = '/' +HTTP_CODE_REDIRECT = 302 + class BoardTests(TestCase): def _create_post(self): @@ -119,8 +125,6 @@ class BoardTests(TestCase): def test_pages(self): """Test that the thread list is properly split into pages""" - PAGE_NUMBER = 2 - for i in range(settings.MAX_THREAD_COUNT): self._create_post() @@ -130,4 +134,29 @@ class BoardTests(TestCase): first_post = posts_in_second_page[0] self.assertEqual(all_threads[settings.THREADS_PER_PAGE].id, - first_post.id) \ No newline at end of file + first_post.id) + + def test_post_validation(self): + """Test the validation of the post form""" + + Post.objects.all().delete() + + client = Client() + + valid_tags = u'tag1 tag_2 тег_3' + invalid_tags = u'$%_356 ---' + + response = client.post(NEW_THREAD_PAGE, {'title': 'test title', + 'text': TEST_TEXT, + 'tags': valid_tags}) + self.assertEqual(response.status_code, HTTP_CODE_REDIRECT, + msg='Posting new message failed: got code ' + + str(response.status_code)) + + self.assertEqual(1, Post.objects.count(), + msg='No posts were created') + + response = client.post(NEW_THREAD_PAGE, {'text': TEST_TEXT, + 'tags': invalid_tags}) + self.assertEqual(1, Post.objects.count(), msg='The validation passed ' + 'where it should fail') \ No newline at end of file diff --git a/boards/views.py b/boards/views.py --- a/boards/views.py +++ b/boards/views.py @@ -110,7 +110,6 @@ def thread(request, post_id): if request.method == 'POST': return new_post(request, post_id) else: - # TODO Show 404 if there is no such thread posts = Post.objects.get_thread(post_id) context = RequestContext(request)