Separate common tests and add tests for common pages
This commit is contained in:
parent
73dd1d6ba0
commit
c26397ae8d
7 changed files with 119 additions and 39 deletions
|
@ -12,3 +12,4 @@ types-requests
|
||||||
mypy
|
mypy
|
||||||
curlylint
|
curlylint
|
||||||
djhtml
|
djhtml
|
||||||
|
wagtail-factories
|
||||||
|
|
|
@ -33,6 +33,8 @@ djangorestframework==3.13.1 # via -r requirements/base.txt, wagtail
|
||||||
djhtml==1.5.1 # via -r requirements/dev.in
|
djhtml==1.5.1 # via -r requirements/dev.in
|
||||||
draftjs-exporter==2.1.7 # via -r requirements/base.txt, wagtail
|
draftjs-exporter==2.1.7 # via -r requirements/base.txt, wagtail
|
||||||
et-xmlfile==1.1.0 # via -r requirements/base.txt, openpyxl
|
et-xmlfile==1.1.0 # via -r requirements/base.txt, openpyxl
|
||||||
|
factory-boy==3.2.1 # via wagtail-factories
|
||||||
|
faker==14.1.0 # via factory-boy
|
||||||
flake8==4.0.1 # via -r requirements/dev.in
|
flake8==4.0.1 # via -r requirements/dev.in
|
||||||
gunicorn==20.1.0 # via -r requirements/base.txt
|
gunicorn==20.1.0 # via -r requirements/base.txt
|
||||||
honcho==1.1.0 # via -r requirements/dev.in
|
honcho==1.1.0 # via -r requirements/dev.in
|
||||||
|
@ -58,11 +60,12 @@ pycodestyle==2.8.0 # via flake8
|
||||||
pyflakes==2.4.0 # via flake8
|
pyflakes==2.4.0 # via flake8
|
||||||
pygments==2.12.0 # via -r requirements/base.txt
|
pygments==2.12.0 # via -r requirements/base.txt
|
||||||
pyparsing==3.0.9 # via -r requirements/base.txt, packaging
|
pyparsing==3.0.9 # via -r requirements/base.txt, packaging
|
||||||
|
python-dateutil==2.8.2 # via faker
|
||||||
pytz==2022.1 # via -r requirements/base.txt, django-modelcluster, djangorestframework, l18n
|
pytz==2022.1 # via -r requirements/base.txt, django-modelcluster, djangorestframework, l18n
|
||||||
redis==4.3.4 # via -r requirements/base.txt, django-redis, django-rq, rq
|
redis==4.3.4 # via -r requirements/base.txt, django-redis, django-rq, rq
|
||||||
requests==2.28.1 # via -r requirements/base.txt, wagtail, wagtail-generic-chooser
|
requests==2.28.1 # via -r requirements/base.txt, wagtail, wagtail-generic-chooser
|
||||||
rq==1.10.1 # via -r requirements/base.txt, django-rq
|
rq==1.10.1 # via -r requirements/base.txt, django-rq
|
||||||
six==1.16.0 # via -r requirements/base.txt, html5lib, l18n
|
six==1.16.0 # via -r requirements/base.txt, html5lib, l18n, python-dateutil
|
||||||
soupsieve==2.3.2.post1 # via -r requirements/base.txt, beautifulsoup4
|
soupsieve==2.3.2.post1 # via -r requirements/base.txt, beautifulsoup4
|
||||||
sqlparse==0.4.2 # via -r requirements/base.txt, django, django-debug-toolbar
|
sqlparse==0.4.2 # via -r requirements/base.txt, django, django-debug-toolbar
|
||||||
tablib[xls,xlsx]==3.2.1 # via -r requirements/base.txt, wagtail
|
tablib[xls,xlsx]==3.2.1 # via -r requirements/base.txt, wagtail
|
||||||
|
@ -73,8 +76,9 @@ types-requests==2.28.5 # via -r requirements/dev.in
|
||||||
types-urllib3==1.26.17 # via types-requests
|
types-urllib3==1.26.17 # via types-requests
|
||||||
typing-extensions==4.3.0 # via mypy
|
typing-extensions==4.3.0 # via mypy
|
||||||
urllib3==1.26.11 # via -r requirements/base.txt, requests
|
urllib3==1.26.11 # via -r requirements/base.txt, requests
|
||||||
wagtail==3.0.1 # via -r requirements/base.txt, wagtail-draftail-snippet
|
wagtail==3.0.1 # via -r requirements/base.txt, wagtail-draftail-snippet, wagtail-factories
|
||||||
wagtail-draftail-snippet==0.4.1 # via -r requirements/base.txt
|
wagtail-draftail-snippet==0.4.1 # via -r requirements/base.txt
|
||||||
|
wagtail-factories==3.1.0 # via -r requirements/dev.in
|
||||||
wagtail-generic-chooser==0.4.1 # via -r requirements/base.txt
|
wagtail-generic-chooser==0.4.1 # via -r requirements/base.txt
|
||||||
webencodings==0.5.1 # via -r requirements/base.txt, html5lib
|
webencodings==0.5.1 # via -r requirements/base.txt, html5lib
|
||||||
wheel==0.37.1 # via pip-tools
|
wheel==0.37.1 # via pip-tools
|
||||||
|
|
19
website/common/factories.py
Normal file
19
website/common/factories.py
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import factory
|
||||||
|
import wagtail_factories
|
||||||
|
|
||||||
|
from . import models
|
||||||
|
|
||||||
|
|
||||||
|
class BaseContentFactory(wagtail_factories.PageFactory):
|
||||||
|
title = factory.Faker("catch_phrase")
|
||||||
|
subtitle = factory.Faker("bs")
|
||||||
|
|
||||||
|
|
||||||
|
class ContentPageFactory(BaseContentFactory):
|
||||||
|
class Meta:
|
||||||
|
model = models.ContentPage
|
||||||
|
|
||||||
|
|
||||||
|
class ListingPageFactory(BaseContentFactory):
|
||||||
|
class Meta:
|
||||||
|
model = models.ListingPage
|
0
website/common/tests/__init__.py
Normal file
0
website/common/tests/__init__.py
Normal file
69
website/common/tests/test_pages.py
Normal file
69
website/common/tests/test_pages.py
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
from django.template.loader import get_template
|
||||||
|
from django.test import SimpleTestCase, TestCase
|
||||||
|
|
||||||
|
from website.common.factories import ContentPageFactory, ListingPageFactory
|
||||||
|
from website.common.models import BasePage
|
||||||
|
from website.common.utils import get_page_models
|
||||||
|
from website.home.models import HomePage
|
||||||
|
|
||||||
|
|
||||||
|
class BasePageTestCase(SimpleTestCase):
|
||||||
|
def test_unique_body_classes(self) -> None:
|
||||||
|
body_classes = [page.body_class for page in get_page_models()]
|
||||||
|
self.assertEqual(len(body_classes), len(set(body_classes)))
|
||||||
|
|
||||||
|
def test_pages_inherit_base_page(self) -> None:
|
||||||
|
for page_model in get_page_models():
|
||||||
|
self.assertTrue(
|
||||||
|
issubclass(page_model, BasePage),
|
||||||
|
f"{page_model} does not inherit from {BasePage}.",
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_pages_have_template(self) -> None:
|
||||||
|
for page in get_page_models():
|
||||||
|
get_template(page.template)
|
||||||
|
|
||||||
|
|
||||||
|
class ContentPageTestCase(TestCase):
|
||||||
|
@classmethod
|
||||||
|
def setUpTestData(cls) -> None:
|
||||||
|
cls.home_page = HomePage.objects.get()
|
||||||
|
cls.page = ContentPageFactory(parent=cls.home_page)
|
||||||
|
|
||||||
|
def test_accessible(self) -> None:
|
||||||
|
response = self.client.get(self.page.url)
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
|
def test_queries(self) -> None:
|
||||||
|
with self.assertNumQueries(15):
|
||||||
|
self.client.get(self.page.url)
|
||||||
|
|
||||||
|
|
||||||
|
class ListingPageTestCase(TestCase):
|
||||||
|
@classmethod
|
||||||
|
def setUpTestData(cls) -> None:
|
||||||
|
cls.home_page = HomePage.objects.get()
|
||||||
|
cls.page = ListingPageFactory(parent=cls.home_page)
|
||||||
|
|
||||||
|
# Orphaned content page, shouldn't show up on lists
|
||||||
|
ContentPageFactory()
|
||||||
|
|
||||||
|
ContentPageFactory(parent=cls.page)
|
||||||
|
ContentPageFactory(parent=cls.page)
|
||||||
|
|
||||||
|
def test_accessible(self) -> None:
|
||||||
|
response = self.client.get(self.page.url)
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
self.assertEqual(len(response.context["child_pages"]), 2)
|
||||||
|
|
||||||
|
def test_queries(self) -> None:
|
||||||
|
expected_queries = 18
|
||||||
|
|
||||||
|
with self.assertNumQueries(expected_queries):
|
||||||
|
self.client.get(self.page.url)
|
||||||
|
|
||||||
|
# Add another page, and check queries don't change
|
||||||
|
ContentPageFactory(parent=self.page)
|
||||||
|
|
||||||
|
with self.assertNumQueries(expected_queries):
|
||||||
|
self.client.get(self.page.url)
|
21
website/common/tests/test_streamfield.py
Normal file
21
website/common/tests/test_streamfield.py
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
from django.test import SimpleTestCase
|
||||||
|
|
||||||
|
from website.common.streamfield import (
|
||||||
|
IGNORE_HEADING_BLOCKS,
|
||||||
|
IGNORE_PLAINTEXT_BLOCKS,
|
||||||
|
get_blocks,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class StreamFieldBlocksTestCase(SimpleTestCase):
|
||||||
|
def test_ignored_plaintext_blocks(self) -> None:
|
||||||
|
plaintext_block_classes = [c[1].__class__ for c in get_blocks()]
|
||||||
|
|
||||||
|
for block_class in IGNORE_PLAINTEXT_BLOCKS:
|
||||||
|
self.assertIn(block_class, plaintext_block_classes)
|
||||||
|
|
||||||
|
def test_ignored_heading_blocks(self) -> None:
|
||||||
|
heading_block_classes = [c[1].__class__ for c in get_blocks()]
|
||||||
|
|
||||||
|
for block_class in IGNORE_HEADING_BLOCKS:
|
||||||
|
self.assertIn(block_class, heading_block_classes)
|
|
@ -1,33 +1,13 @@
|
||||||
from django.template.loader import get_template
|
|
||||||
from django.test import SimpleTestCase
|
from django.test import SimpleTestCase
|
||||||
from wagtail.rich_text import features as richtext_feature_registry
|
from wagtail.rich_text import features as richtext_feature_registry
|
||||||
|
|
||||||
from .embed import YouTubeLiteEmbedFinder
|
from website.common.embed import YouTubeLiteEmbedFinder
|
||||||
from .models import BasePage
|
from website.common.rich_text import (
|
||||||
from .rich_text import (
|
|
||||||
RICH_TEXT_FEATURES,
|
RICH_TEXT_FEATURES,
|
||||||
RICH_TEXT_FEATURES_PLAIN,
|
RICH_TEXT_FEATURES_PLAIN,
|
||||||
RICH_TEXT_FEATURES_SIMPLE,
|
RICH_TEXT_FEATURES_SIMPLE,
|
||||||
)
|
)
|
||||||
from .streamfield import IGNORE_HEADING_BLOCKS, IGNORE_PLAINTEXT_BLOCKS, get_blocks
|
from website.common.utils import count_words, extract_text, get_table_of_contents
|
||||||
from .utils import count_words, extract_text, get_page_models, get_table_of_contents
|
|
||||||
|
|
||||||
|
|
||||||
class BasePageTestCase(SimpleTestCase):
|
|
||||||
def test_unique_body_classes(self) -> None:
|
|
||||||
body_classes = [page.body_class for page in get_page_models()]
|
|
||||||
self.assertEqual(len(body_classes), len(set(body_classes)))
|
|
||||||
|
|
||||||
def test_pages_inherit_base_page(self) -> None:
|
|
||||||
for page_model in get_page_models():
|
|
||||||
self.assertTrue(
|
|
||||||
issubclass(page_model, BasePage),
|
|
||||||
f"{page_model} does not inherit from {BasePage}.",
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_pages_have_template(self) -> None:
|
|
||||||
for page in get_page_models():
|
|
||||||
get_template(page.template)
|
|
||||||
|
|
||||||
|
|
||||||
class YouTubeLiteEmbedFinderTestCase(SimpleTestCase):
|
class YouTubeLiteEmbedFinderTestCase(SimpleTestCase):
|
||||||
|
@ -127,20 +107,6 @@ class CountWordsTestCase(SimpleTestCase):
|
||||||
self.assertEqual(count_words("Hello there! How are you?"), 5)
|
self.assertEqual(count_words("Hello there! How are you?"), 5)
|
||||||
|
|
||||||
|
|
||||||
class StreamFieldBlocksTestCase(SimpleTestCase):
|
|
||||||
def test_ignored_plaintext_blocks(self) -> None:
|
|
||||||
plaintext_block_classes = [c[1].__class__ for c in get_blocks()]
|
|
||||||
|
|
||||||
for block_class in IGNORE_PLAINTEXT_BLOCKS:
|
|
||||||
self.assertIn(block_class, plaintext_block_classes)
|
|
||||||
|
|
||||||
def test_ignored_heading_blocks(self) -> None:
|
|
||||||
heading_block_classes = [c[1].__class__ for c in get_blocks()]
|
|
||||||
|
|
||||||
for block_class in IGNORE_HEADING_BLOCKS:
|
|
||||||
self.assertIn(block_class, heading_block_classes)
|
|
||||||
|
|
||||||
|
|
||||||
class RichTextFeaturesTestCase(SimpleTestCase):
|
class RichTextFeaturesTestCase(SimpleTestCase):
|
||||||
def test_features_exist(self) -> None:
|
def test_features_exist(self) -> None:
|
||||||
for feature in RICH_TEXT_FEATURES:
|
for feature in RICH_TEXT_FEATURES:
|
Loading…
Reference in a new issue