This tutorial will test comments that are created on a Wagtail page using the package Django Comments Xtd, using Factory Boy.
Our starting point is a commenting functionality and a page testing setup for Wagtail with Factory Boy. As in the earlier tutorials we create a comment factory in /tests/factories.py
. Because we also want to save a user with our comments, we start by creating a user factory:
import factory
from userauth.models import CustomUser
class CustomUserFactory(factory.django.DjangoModelFactory):
class Meta:
model = CustomUser
username = factory.Sequence(lambda n: 'Username{0}'.format(n))
password = factory.Sequence(lambda n: 'Password{0}'.format(n))
We automatically generate a username and password because that is the minimum Django expects. Note that in our authentication implementation we use email instead of username, but this is managed by allauth, and since we do not use allauth's signup functionality, we need to take care of this ourselves. Now we are ready to create a comment factory:
from ..models import ArticlePage, CustomComment
from django.contrib.contenttypes.models import ContentType
from django.contrib.sites.models import Site as DjangoSite
class CustomCommentFactory(factory.django.DjangoModelFactory):
class Meta:
model = CustomComment
content_type = ContentType.objects.get_for_model(ArticlePage)
site = DjangoSite.objects.get_current()
page = factory.SubFactory(ArticlePageFactory)
user = factory.SubFactory(CustomUserFactory)
comment = factory.Sequence(lambda n: 'Comment {0}'.format(n))
Looking at the model for comments we need three required fields: content_type
, site
and object_pk
. Our comments are going to be on an ArticlePage
, so we can retrieve the content type using the Django method get_for_model()
. The current site can be retrieved with the Django method get_current()
. We rename the Site
class to avoid confusion with the Wagtail Site
class. The third required field object_pk
will be defined when creating the comment instance. page
and user
are two foreign key relations of the comment, so we use a SubFactory
for them. And finally for the comment text itself we generate a text with Sequence
.
We can set up a few Wagtail pages just as we have done earlier. Put the following in a file /tests/test_comments.py
:
from .factories import HomePageFactory, ArticlePageFactory, ArticleIndexPageFactory
from django.test import TestCase
from wagtail.core.models import Page, Site
class TestComments(TestCase):
@classmethod
def setUpTestData(cls):
cls.site = Site.objects.create(is_default_site=True, root_page=Page.get_first_root_node())
cls.homepage = HomePageFactory()
cls.articleindexpage = ArticleIndexPageFactory(parent=cls.homepage)
cls.articlepage1 = ArticlePageFactory(parent=cls.articleindexpage)
Now we add a user and a comment by that user to the setup:
from .factories import CustomUserFactory, CustomCommentFactory
cls.user = CustomUserFactory(email="johndoe@example.com", display_name="John")
cls.customcomment = CustomCommentFactory(object_pk=str(cls.articlepage1.pk), user=cls.user)
The fields for the user are self-explanatory. For the comment, as mention before, now we define the object_pk
: we set it to the primary key of the page on which we want the comment. Since Django Comments defines the field as a text field, we convert the primary key first. That completes the setup. The test itself is now very simple. The interesting part of the model to test is the save()
method, and since the comment is already created this should have done its work already. So we just check whether the page and the user are save correctly:
def test_custom_comment_gets_saved_correctly(self):
self.assertEqual(self.customcomment.page.url, self.articlepage1.url)
self.assertEqual(self.customcomment.user_name, self.user.display_name)
We leave it at that. Checking our coverage with
coverage run --source=cms manage.py test cms.tests
coverage html
tells us that the largest part of our uncovered code is in our streamforms, so that's where we'll go next.
Comment on this article (sign in first or confirm by name and email below)