#101 test model page

This commit is contained in:
Laurent Van Wambeke 2023-05-10 10:12:25 +02:00
parent ced76e8d13
commit cd6bb608d4
3 changed files with 184 additions and 179 deletions

View File

@ -123,9 +123,14 @@ class BasePage(models.Model):
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
if not self.slug: if not self.slug:
self.slug = slugify(self.title)[:100] self.slug = slugify(self.title)[:100]
count = Page.objects.filter(slug__startswith=self.slug).count() pagecount = Page.objects.filter(slug__startswith=self.slug).count()
if count: staticpagecount = StaticPage.objects.filter(
self.slug += "-" + str(count) slug__startswith=self.slug
).count()
if pagecount:
self.slug += "-" + str(pagecount)
if staticpagecount:
self.slug += "-" + str(staticpagecount)
if self.parent and not self.cover: if self.parent and not self.cover:
self.cover = self.parent.cover self.cover = self.parent.cover
@ -150,7 +155,6 @@ class BasePage(models.Model):
def is_trash(self): def is_trash(self):
return self.status == self.STATUS_TRASH return self.status == self.STATUS_TRASH
# for the following property, as we call the properties is_published and display_title as property, we need to call them as property (without parenthesis) and not as method (with parenthesis)
@property @property
def display_title(self): def display_title(self):
if self.is_published: if self.is_published:

View File

@ -12,6 +12,21 @@ def stations():
return baker.make(models.Station, _quantity=2) return baker.make(models.Station, _quantity=2)
@pytest.fixture
def staticpages():
return baker.make(models.StaticPage, _quantity=3)
@pytest.fixture
def pages():
return baker.make(models.Page, _quantity=3)
@pytest.fixture
def navitem():
return baker.make(models.NavItem)
@pytest.fixture @pytest.fixture
def programs(stations): def programs(stations):
items = list( items = list(

View File

@ -2,269 +2,255 @@ import pytest
from model_bakery import baker from model_bakery import baker
from aircox.models import Category, PageQuerySet, Page, StaticPage, Comment, NavItem from aircox.models import Category, Page, StaticPage, NavItem
@pytest.mark.django_db @pytest.mark.django_db
class TestCategory: class TestCategory:
def test__str__(self): def test__str__(self):
# return category title field.
category = baker.make(Category) category = baker.make(Category)
title = category.__str__() title = category.__str__()
assert title == category.title assert title == category.title
# poupée russe du modèle page.
# BasePage > Page
# BasePage > StaticPage
# Cannot create BasePage fake instance in fake db
# ? Do I need to create fake page and staticpage instances in order to test each method from BasePage ?
class TestBasePageQuerySet():
# BasePAgeQuerySet is queryset, we use as fake db instances of the model StaticPage in the test. We do not use instances of the Page Model because it's use also as an abstract class.
class TestBasePageQuerySet:
@pytest.mark.django_db @pytest.mark.django_db
def test_draft(self): def test_draft(self, staticpages):
# return an array of all draft pages draft_pages = StaticPage.objects.draft()
baker.make(Page, _quantity=5)
draft_pages = Page.objects.draft()
for page in draft_pages: for page in draft_pages:
assert page.status == Page.STATUS_DRAFT assert page.status == StaticPage.STATUS_DRAFT
@pytest.mark.django_db @pytest.mark.django_db
def test_published(self): def test_published(self, staticpages):
# retrun an array of all published pages published_pages = StaticPage.objects.published()
baker.make(Page, _quantity=5)
published_pages = Page.objects.published()
for page in published_pages: for page in published_pages:
assert page.status == Page.STATUS_PUBLISHED assert page.status == StaticPage.STATUS_PUBLISHED
@pytest.mark.django_db @pytest.mark.django_db
def test_trash(self): def test_trash(self, staticpages):
# return an array of all trash pages trashed_pages = StaticPage.objects.trash()
baker.make(Page, _quantity=5)
trashed_pages = Page.objects.trash()
for page in trashed_pages: for page in trashed_pages:
assert page.status == Page.STATUS_TRASH assert page.status == StaticPage.STATUS_TRASH
@pytest.mark.django_db @pytest.mark.django_db
def test_parent_with_page(self): def test_parent_return_childs_from_parent_object(self, staticpages):
parent = baker.make(Page) parent = baker.make(StaticPage)
child1 = baker.make(Page, parent=parent) childs = baker.make(StaticPage, _quantity=3, parent=parent)
child2 = baker.make(Page, parent=parent) nochild = baker.make(StaticPage, parent=None)
child3 = baker.make(Page, parent=parent) parent_childs = StaticPage.objects.parent(parent)
nochild = baker.make(Page, parent=None)
''' retrieve all child page from same parent instance ''' for child in childs:
parent_childs = Page.objects.parent(parent) assert child in parent_childs
assert child1 in parent_childs
assert child2 in parent_childs
assert child3 in parent_childs
assert nochild not in parent_childs assert nochild not in parent_childs
''' retrieve all child page from same parent id''' @pytest.mark.django_db
parentid_childs = Page.objects.parent(parent.id) def test_parent_return_childs_from_parent_id(self, staticpages):
parent = baker.make(StaticPage)
childs = baker.make(StaticPage, _quantity=3, parent=parent)
nochild = baker.make(StaticPage, parent=None)
parent_childs = StaticPage.objects.parent(parent.id)
assert child1 in parentid_childs for child in childs:
assert child2 in parentid_childs assert child in parent_childs
assert child3 in parentid_childs assert nochild not in parent_childs
assert nochild not in parentid_childs
@pytest.mark.django_db @pytest.mark.django_db
def test_search_with_searchcontent(self): def test_search_with_searchcontent(self, staticpages):
baker.make(Page, _quantity=4) page1 = baker.make(StaticPage, title="test")
page1 = baker.make(Page, title='test') page2 = baker.make(StaticPage, content="test")
page2 = baker.make(Page, content='test') q = "test"
q = 'test' results = StaticPage.objects.search(q=q)
results = Page.objects.search(q=q)
# check : title and content data was use to determine if pages are in result from search 'test'
assert page1 in results assert page1 in results
assert page2 in results assert page2 in results
@pytest.mark.django_db @pytest.mark.django_db
def test_search_without_searchcontent(self): def test_search_without_searchcontent(self, staticpages):
baker.make(Page, _quantity=4) page1 = baker.make(StaticPage, title="test")
page1 = baker.make(Page, title='test') page2 = baker.make(StaticPage, content="test")
page2 = baker.make(Page, content='test') q = "test"
q = 'test' results = StaticPage.objects.search(q=q, search_content=False)
results = Page.objects.search(q=q, search_content=False)
# check : as we search not in content, only the page with the data 'test' in its title should be return in the results
assert page1 in results assert page1 in results
assert page2 not in results assert page2 not in results
# BasePage is abstract, we use as fake db instances of the model StaticPage in the test. We do not use instances of the Page Model because it's use as an abstract class also.
class TestBasePage: class TestBasePage:
@pytest.mark.django_db
def test__str__(self, staticpages):
page = baker.make(StaticPage, title="Test")
assert page.__str__() == "Test"
@pytest.mark.django_db @pytest.mark.django_db
def test__str__(self): def test_save_generate_unique_slug(self, staticpages):
# return page title page = baker.make(StaticPage, title="Title with spaces", slug=None)
page = baker.make(Page, title='Test')
assert page.__str__() == 'Test'
@pytest.mark.django_db
def test_save_case1(self):
''' save case 1:
- no slug
- the slug generate with .save() is unique in db'''
page = baker.make(Page, title='Title with spaces', slug=None)
page.save() page.save()
assert page.slug == 'title-with-spaces'
assert page.slug == "title-with-spaces"
@pytest.mark.django_db @pytest.mark.django_db
def test_save_case2(self): def test_save_generate_slug_that_already_exist(self, staticpages):
''' save case 2: baker.make(StaticPage, slug="title")
- no slug page = baker.make(StaticPage, title="Title", slug=None)
- the slug generate with .save() is not unique in db'''
baker.make(Page, slug='title')
page = baker.make(Page, title='Title', slug=None)
page.save() page.save()
assert page.slug == 'title-1'
assert page.slug == "title-1"
@pytest.mark.django_db @pytest.mark.django_db
def test_save_case3(self): def test_save_without_cover_with_parent(self, staticpages):
''' save case 3: parent = baker.make(StaticPage)
- save a page without cover but with a parent with a cover child = baker.make(StaticPage, cover=None, parent=parent)
'''
parent = baker.make(Page)
child = baker.make(Page, cover=None, parent=parent)
child.save() child.save()
assert child.cover == parent.cover assert child.cover == parent.cover
@pytest.mark.django_db @pytest.mark.django_db
def test_get_absolute_url(self): def test_get_absolute_url_from_unpublished_page(self, staticpages):
unpublished_page = baker.make(
StaticPage, slug="page-slug", status=StaticPage.STATUS_DRAFT
)
unpublished_page = baker.make(Page, slug='page-slug', status=Page.STATUS_DRAFT) assert unpublished_page.get_absolute_url() == "#"
assert unpublished_page.get_absolute_url() == '#'
''' !!! only work with staticpage instance, not page instance. error when using page : TestBasePage::test_get_absolute_url - django.urls.exceptions.NoReverseMatch: Reverse for 'None' not found. 'None' is not a valid view function or pattern name'''
published_page = baker.make(StaticPage, slug='another-page-slug', status=Page.STATUS_PUBLISHED)
assert published_page.get_absolute_url() == '/pages/another-page-slug/'
# as the following are property from page.py, we test them without the parenthesis at the end. For example: page.is_draft and not page.is_draft()
#property
@pytest.mark.django_db @pytest.mark.django_db
def test_is_draft(self): def test_get_absolute_url_from_published_page(self, staticpages):
#return true if the page/staticapge is draft. published_page = baker.make(
page = baker.make(Page, status=Page.STATUS_DRAFT) StaticPage,
slug="another-page-slug",
status=StaticPage.STATUS_PUBLISHED,
)
assert published_page.get_absolute_url() == "/pages/another-page-slug/"
# as the following test methods are property from page.py, we call them without the parenthesis.
@pytest.mark.django_db
def test_is_draft(self, staticpages):
page = baker.make(StaticPage, status=StaticPage.STATUS_DRAFT)
assert page.is_draft == True assert page.is_draft == True
#property
@pytest.mark.django_db @pytest.mark.django_db
def test_is_published(self): def test_is_published(self, staticpages):
#return true if the page/staticapge is published. page = baker.make(StaticPage, status=StaticPage.STATUS_PUBLISHED)
page = baker.make(Page, status=Page.STATUS_PUBLISHED)
assert page.is_published == True assert page.is_published == True
#property
@pytest.mark.django_db @pytest.mark.django_db
def test_is_draft(self): def test_is_draft(self, staticpages):
#return true if the page/staticapge is published. page = baker.make(StaticPage, status=StaticPage.STATUS_TRASH)
page = baker.make(Page, status=Page.STATUS_TRASH)
assert page.is_trash == True assert page.is_trash == True
''' !! in display_title property from page.py, we need to remove the parenthesis of .is_published() and display_title(), because they are property and not proper method, in order to work. otherwhise we get an error : "TypeError: 'bool' object is not callable" '''
#property
@pytest.mark.django_db @pytest.mark.django_db
def test_display_title(self): def test_display_title(self, staticpages):
parent_page = baker.make(Page, title='Parent page title', status=Page.STATUS_PUBLISHED) parent_page = baker.make(
child_unpublished_page = baker.make(Page, title='Child page title', parent=parent_page, status=Page.STATUS_DRAFT) StaticPage,
title="Parent page title",
# display title of a published page with title status=StaticPage.STATUS_PUBLISHED,
assert parent_page.display_title == 'Parent page title' )
# display title of the parent page if child is draft child_unpublished_page = baker.make(
assert child_unpublished_page.display_title == 'Parent page title' StaticPage,
title="Child page title",
#cached_property parent=parent_page,
@pytest.mark.django_db status=StaticPage.STATUS_DRAFT,
def test_headline(self): )
page = baker.make(Page, content='<h2>My headline</h2><p>My content.</p>')
empty_content_page = baker.make(Page, content='')
assert page.headline == 'My headline\n' assert parent_page.display_title == "Parent page title"
assert child_unpublished_page.display_title == "Parent page title"
@pytest.mark.django_db
def test_headline(self, staticpages):
page = baker.make(
StaticPage, content="<h2>My headline</h2><p>My content.</p>"
)
empty_content_page = baker.make(StaticPage, content="")
assert page.headline == "My headline\n"
assert empty_content_page.headline == "" assert empty_content_page.headline == ""
#classmethod : is called on the class itself. Exemple below : Page.classmethod(arg)
#this classmethod is not suitable for StaticPage because staticpage don't have category argument. It's intend only for Page.
@pytest.mark.django_db @pytest.mark.django_db
def test_get_init_kwargs_from(self): def test_get_init_kwargs_from(self, staticpages):
page = baker.make(Page) page = baker.make(Page)
kwargs = Page.get_init_kwargs_from(page) kwargs = Page.get_init_kwargs_from(page)
assert kwargs == {"cover": page.cover, "category": page.category} assert kwargs == {"cover": page.cover, "category": page.category}
#this classmethod is not suitable for StaticPage because staticpage don't have category argument. It's intend only for Page.
#classmethod
# from_page classmethod create a new instance of the class (page or staticpage) from a page object. It's a fast way to create a new instance without having to manually extract all the informations from the page object in order to create the new instance.
# Only for informations: below are some theorical explanation of the tools use in the method from_page.
# - cls from the classmethod from_page from page.py refers to the class itself
# - The **something syntax in Python is used to pass a variable number of keyword arguments (from the 'something') to a function or method
# - It (**something) is a shorthand way of passing the dictionary as individual arguments without having to unpack it explicitly. (example : unpack this dictionary "something = {'key1' : 'value1', 'key2' : 'value2'}" and "**something" return this arguments "{key1='value1', key2='value2'}")
@pytest.mark.django_db @pytest.mark.django_db
def test_from_page(self): def test_from_page(self, pages):
page_object = baker.make(Page) page_object = baker.make(Page)
new_page_instance = Page.from_page(page_object) new_page_instance = Page.from_page(page_object)
# assert that after creating new instance with the methodclass "from_page", the new page instance have the same arguments than the page object (we only test here with cover and category arguments)
assert new_page_instance.cover == page_object.cover assert new_page_instance.cover == page_object.cover
assert new_page_instance.category == page_object.category assert new_page_instance.category == page_object.category
class TestPageQuerySet():
class TestPageQuerySet:
@pytest.mark.django_db @pytest.mark.django_db
def test_published(self): def test_published(self, pages):
baker.make(Page, _quantity=5) baker.make(Page, _quantity=5)
published_pages_list = Page.objects.published() published_pages_list = Page.objects.published()
for page in published_pages_list: for page in published_pages_list:
assert page.status == Page.STATUS_PUBLISHED assert page.status == Page.STATUS_PUBLISHED
#class TestPage():
## TODO en cours par laurent
class TestPage:
@pytest.mark.django_db
def test_save_published_page_pubdate(self, pages):
page = baker.make(Page, status=Page.STATUS_PUBLISHED, pub_date=None)
page.save()
assert page.pub_date is not None
@pytest.mark.django_db
def test_save_unpublished_page_pubdate(self, pages):
page = baker.make(Page, status=Page.STATUS_DRAFT, pub_date=None)
page.save()
assert page.pub_date == None
@pytest.mark.django_db
def test_save_child_page_category(self, pages):
parent = baker.make(Page)
child = baker.make(Page, parent=parent, category=None)
child.save()
assert child.category == parent.category
class TestStaticPage:
@pytest.mark.django_db
def test_get_absolute_url(self, staticpages):
page = baker.make(
StaticPage, attach_to=StaticPage.ATTACH_TO_DIFFUSIONS
)
assert page.get_absolute_url() == "/week/"
class TestNavItem:
@pytest.mark.django_db
def test_get_url_from_selfurl(self, navitem):
assert navitem.url == navitem.get_url()
@pytest.mark.django_db
def test_get_url_from_pageurl(self, navitem):
page = baker.make(StaticPage)
item = baker.make(NavItem, url=None, page=page)
assert item.get_url() == page.get_absolute_url()
@pytest.mark.django_db
def test_get_url_without_selfurl_page(self, navitem):
item = baker.make(NavItem, url=None, page=None)
assert item.get_url() == None