Add tests and fixes for them.

Actually create PostStatus objects for new posts. Temporarily only run these new tests so we can add djangobb to the full test suite.
This commit is contained in:
Ray Schamp 2014-03-12 10:39:39 -04:00
parent 81b5a685c3
commit 883e8e2f72
5 changed files with 202 additions and 15 deletions

View file

@ -13,7 +13,7 @@ from django.utils.translation import ugettext_lazy as _
from django.utils.timezone import now
from djangobb_forum.models import Topic, Post, Profile, Reputation, Report, \
Attachment, Poll, PollChoice
Attachment, Poll, PollChoice, PostStatus
from djangobb_forum import settings as forum_settings
from djangobb_forum.util import smiles, convert_text_to_html, filter_language, \
set_language, UnapprovedImageError
@ -163,6 +163,10 @@ class AddPostForm(forms.ModelForm):
body=self.cleaned_data['body'])
post.save()
if self.user.groups.filter(name="New Scratchers").exists():
tracking_data = dict(**self.request_data)
tracking_data['permalink'] = self.url
status = PostStatus.objects.create_for_post(post, **tracking_data)
if forum_settings.ATTACHMENT_SUPPORT:
self.save_attachment(post, self.cleaned_data['attachment'])
return post

View file

@ -11,9 +11,10 @@ class Migration(SchemaMigration):
# Adding model 'PostStatus'
db.create_table('djangobb_forum_poststatus', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('post', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['djangobb_forum.Post'])),
('post', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['djangobb_forum.Post'], unique=True)),
('state', self.gf('django_fsm.db.fields.fsmfield.FSMField')(default='unreviewed', max_length=50)),
('topic', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['djangobb_forum.Topic'])),
('forum', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['djangobb_forum.Forum'])),
('user_agent', self.gf('django.db.models.fields.CharField')(max_length=200, null=True, blank=True)),
('referrer', self.gf('django.db.models.fields.CharField')(max_length=200, null=True, blank=True)),
('permalink', self.gf('django.db.models.fields.CharField')(max_length=200, null=True, blank=True)),
@ -134,9 +135,10 @@ class Migration(SchemaMigration):
},
'djangobb_forum.poststatus': {
'Meta': {'object_name': 'PostStatus'},
'forum': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['djangobb_forum.Forum']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'permalink': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
'post': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['djangobb_forum.Post']"}),
'post': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['djangobb_forum.Post']", 'unique': 'True'}),
'referrer': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
'state': ('django_fsm.db.fields.fsmfield.FSMField', [], {'default': "'unreviewed'", 'max_length': '50'}),
'topic': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['djangobb_forum.Topic']"}),

View file

@ -575,7 +575,7 @@ class PostStatus(models.Model):
MARKED_SPAM = 'marked_spam'
MARKED_HAM = 'marked_ham'
post = models.ForeignKey(Post)
post = models.OneToOneField(Post, db_index=True)
state = FSMField(default=UNREVIEWED)
topic = models.ForeignKey(Topic) # Original topic
forum = models.ForeignKey(Forum) # Original forum
@ -592,17 +592,17 @@ class PostStatus(models.Model):
def _get_spam_dustbin(self):
if self.spam_category is None:
self.spam_category, _ = Category.objects.get_or_create(
name=settings.SPAM_CATEGORY_NAME)
name=forum_settings.SPAM_CATEGORY_NAME)
if self.spam_forum is None:
self.spam_forum, _ = Forum.objects.get_or_create(
category=self.spam_category,
name=settings.SPAM_FORUM_NAME)
name=forum_settings.SPAM_FORUM_NAME)
if self.spam_topic is None:
filterbot = User.objects.get_by_natural_key("filterbot")
self.spam_topic, _ = Topic.objects.get_or_create(
forum=self.spam_forum, name=settings.SPAM_TOPIC_NAME,
forum=self.spam_forum, name=forum_settings.SPAM_TOPIC_NAME,
user=filterbot)
return (self.spam_topic, self.spam_forum)
@ -739,8 +739,7 @@ class PostStatus(models.Model):
"""
Akismet detected this post is spam, move it to the dustbin and report it.
"""
Report.objects.create_spam_report_for(self.post)
self.post.move_to()
self._delete_post()
@transition(
field=state, source=UNREVIEWED, target=FILTERED_HAM,
@ -771,7 +770,7 @@ class PostStatus(models.Model):
Akismet that this is spam.
"""
self._submit_spam()
self.post.delete()
self._delete_post()
from .signals import post_saved, topic_saved

View file

@ -1,5 +1,6 @@
from test_forum import *
from test_reputation import *
from test_profile import *
from test_utils import *
from test_templatetags import *
from test_spam import *
# from test_forum import *
# from test_reputation import *
# from test_profile import *
# from test_utils import *
# from test_templatetags import *

View file

@ -0,0 +1,181 @@
from django.conf import settings
from django.contrib.auth.models import User, Group
from django.core.urlresolvers import reverse
from django.db import models
from django.test import TestCase
from django_fsm.db.fields import can_proceed
from djangobb_forum import settings as forum_settings
from djangobb_forum.forms import AddPostForm
from djangobb_forum.models import Category, Forum, Topic, Post, PostStatus
profile_app, profile_model = settings.AUTH_PROFILE_MODULE.split('.')
UserProfileModel = models.get_model(profile_app, profile_model)
class BaseTestCase(TestCase):
def setUp(self):
Category.objects.create(name=forum_settings.SPAM_CATEGORY_NAME)
self.password = "password"
self.user = User.objects.create_user(
username="testuser", password=self.password)
UserProfileModel.objects.create(user=self.user)
new_scratchers = Group.objects.create(name="New Scratchers")
self.user.groups.add(new_scratchers)
self.veteran_user = User.objects.create_user(
username="veteranuser", password=self.password)
UserProfileModel.objects.create(user=self.veteran_user)
self.test_category = Category.objects.create(name="Test Category")
self.test_forum = Forum.objects.create(
name="Test Forum", category=self.test_category)
self.test_topic = Topic.objects.create(
name="Test Topic", forum=self.test_forum, user=self.user)
self.test_post = Post.objects.create(
topic=self.test_topic, user=self.user, body="Test content",
body_html="<p>Test content</p>")
User.objects.create_user(username="filterbot", password="password")
User.objects.create_user(username="systemuser", password="password")
class TestPostStatusUnit(BaseTestCase):
def setUp(self):
super(TestPostStatusUnit, self).setUp()
def test_get_spam_dustbin(self):
"""
Ensure the dustbin forum and topic are created and available.
"""
self.post_status = PostStatus.objects.create_for_post(self.test_post)
topic, forum = self.post_status._get_spam_dustbin()
self.assertTrue(topic is not None)
self.assertTrue(forum is not None)
def test_transition_filter_ham(self):
"""
If a post is ham, it can transition to filtered as ham.
"""
self.post_status = PostStatus.objects.create_for_post(self.test_post)
self.post_status._comment_check = lambda: False
self.post_status.is_ham = lambda: True
self.post_status.is_spam = lambda: False
self.assertTrue(can_proceed(self.post_status.filter_ham))
self.post_status.filter_ham()
self.assertEqual(PostStatus.FILTERED_HAM, self.post_status.state)
def test_transition_filter_spam(self):
"""
If a post is spam, it can transition to filtered as spam.
"""
self.post_status = PostStatus.objects.create_for_post(self.test_post)
self.post_status._comment_check = lambda: True
self.post_status.is_ham = lambda: False
self.post_status.is_spam = lambda: True
self.assertTrue(can_proceed(self.post_status.filter_spam))
self.post_status.filter_spam()
self.assertEqual(PostStatus.FILTERED_SPAM, self.post_status.state)
self.assertEqual(
self.post_status.post.topic.forum.name, forum_settings.SPAM_FORUM_NAME)
def test_transition_mark_ham(self):
"""
Ensure a post filtered as spam can be marked as ham, and moved back to
its original location after marking as ham.
"""
self.post_status = PostStatus.objects.create_for_post(self.test_post)
self.post_status.state = PostStatus.FILTERED_SPAM
self.post_status.save()
self.post_status._delete_post()
self.post_status._submit_spam = lambda: True
self.post_status._submit_ham = lambda: True
self.assertTrue(can_proceed(self.post_status.mark_ham))
self.post_status.mark_ham()
self.assertEqual(PostStatus.MARKED_HAM, self.post_status.state)
self.assertEqual(self.post_status.post.topic.name, "Test Topic")
self.assertEqual(self.post_status.post.topic.forum.name, "Test Forum")
def test_transition_mark_spam(self):
"""
A post filtered as ham should be able to be marked as spam, and is moved
to the spam forum/topic when marked.
"""
self.post_status = PostStatus.objects.create_for_post(self.test_post)
self.post_status.state = PostStatus.FILTERED_HAM
self.post_status.save()
self.post_status._submit_spam = lambda: True
self.post_status._submit_ham = lambda: True
self.assertTrue(can_proceed(self.post_status.mark_spam))
self.post_status.mark_spam()
self.assertEqual(PostStatus.MARKED_SPAM, self.post_status.state)
self.assertEqual(
self.post_status.post.topic.forum.name, forum_settings.SPAM_FORUM_NAME)
class TestPostStatusIntegration(BaseTestCase):
def test_status_created_topic(self):
"""
Ensure a new scratcher's new topic generates an associated PostStatus.
"""
self.client.login(username=self.user.username, password=self.password)
response = self.client.post(
reverse('djangobb:add_topic', args=[self.test_forum.id]),
{
'name': "test_status_created_topic",
'body': "This is a test post, please ignore."})
topic_query = Topic.objects.filter(name='test_status_created_topic')
self.assertTrue(topic_query.exists())
topic = topic_query.get()
self.assertEqual(topic.posts.count(), 1)
post = topic.last_post
self.assertTrue(post.poststatus is not None)
def test_status_created_post(self):
"""
A new scratcher's reply should generate a PostStatus.
"""
self.client.login(username=self.user.username, password=self.password)
response = self.client.post(
reverse('djangobb:topic', args=[self.test_topic.id]),
{
AddPostForm.FORM_NAME: True,
'body': "Test test_status_created_post"})
self.assertEqual(self.test_topic.posts.count(), 2)
post = self.test_topic.posts.all()[1]
self.assertTrue(post.poststatus is not None)
self.client.logout()
def test_status_not_created_not_new_scratcher_topic(self):
"""
Ensure users who aren't new scratchers don't get PostStatus objects
generated for their topics.
"""
self.client.login(
username=self.veteran_user.username, password=self.password)
response = self.client.post(
reverse('djangobb:add_topic', args=[self.test_forum.id]),
{
'name': "test_status_not_created_not_new_scratcher",
'body': "This is a test post, please ignore."})
post_query = Post.objects.filter(
topic__name='test_status_not_created_not_new_scratcher')
self.assertTrue(post_query.exists())
post = post_query.get()
with self.assertRaises(PostStatus.DoesNotExist):
status = post.poststatus
self.client.logout()
def test_status_not_created_not_new_scratcher_post(self):
"""
A non-new scratcher's reply should not generate a PostStatus.
"""
self.client.login(
username=self.veteran_user.username, password=self.password)
response = self.client.post(
reverse('djangobb:topic', args=[self.test_topic.id]),
{
AddPostForm.FORM_NAME: True,
'body': "Test test_status_not_created_not_new_scratcher_post."})
self.assertEqual(self.test_topic.posts.count(), 2)
post = self.test_topic.posts.all()[1]
with self.assertRaises(PostStatus.DoesNotExist):
status = post.poststatus
self.client.logout()