From baaefa6b46bc2bdbe0957994535be02183b161e0 Mon Sep 17 00:00:00 2001 From: Andy Babic Date: Tue, 20 Sep 2022 09:50:57 +0100 Subject: [PATCH 1/5] Store all PageFactory subclasses in PAGE_FACTORIES (cherry picked from commit 3b16897cab709132b4ad766ea2119c89c04f2013) --- src/wagtail_factories/factories.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/wagtail_factories/factories.py b/src/wagtail_factories/factories.py index b1d0799..ae2e3d1 100644 --- a/src/wagtail_factories/factories.py +++ b/src/wagtail_factories/factories.py @@ -12,10 +12,12 @@ # Wagtail<3.0 from wagtail.core.models import Collection, Page, Site +from factory.base import FactoryMetaClass from factory.django import DjangoModelFactory from wagtail.documents import get_document_model __all__ = [ + "get_page_factories", "CollectionFactory", "ImageFactory", "PageFactory", @@ -25,6 +27,13 @@ logger = logging.getLogger(__file__) +PAGE_FACTORIES = [] + + +def get_page_factories(): + return PAGE_FACTORIES + + class ParentNodeFactory(ParameteredAttribute): EXTEND_CONTAINERS = True @@ -115,7 +124,14 @@ class Meta: model = Collection -class PageFactory(MP_NodeFactory): +class PageFactoryMetaClass(FactoryMetaClass): + def __new__(mcs, class_name, bases, attrs): + new_class = super().__new__(mcs, class_name, bases, attrs) + PAGE_FACTORIES.append(new_class) + return new_class + + +class PageFactory(MP_NodeFactory, metaclass=PageFactoryMetaClass): title = "Test page" slug = factory.LazyAttribute(lambda obj: slugify(obj.title)) From 38f76386b9082b3b546bbebb23e2dad419f5f44c Mon Sep 17 00:00:00 2001 From: Andy Babic Date: Wed, 5 Oct 2022 10:15:02 +0100 Subject: [PATCH 2/5] Add test for get_page_factories() --- tests/test_factories.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/tests/test_factories.py b/tests/test_factories.py index 93833ae..d4158fa 100644 --- a/tests/test_factories.py +++ b/tests/test_factories.py @@ -1,7 +1,11 @@ import pytest import wagtail_factories -from tests.testapp.factories import MyTestPageFactory, MyTestPageGetOrCreateFactory +from tests.testapp.factories import ( + MyTestPageFactory, + MyTestPageGetOrCreateFactory, + MyTestPageWithStreamFieldFactory, +) try: from wagtail.models import Page, Site @@ -166,3 +170,12 @@ def test_document_add_to_collection(): collection__parent=root_collection, collection__name="new" ) assert document.collection.name == "new" + + +def test_get_page_facories(): + result = wagtail_factories.get_page_factories() + assert result == [ + MyTestPageFactory, + MyTestPageGetOrCreateFactory, + MyTestPageWithStreamFieldFactory, + ] From f15c79065a363ed8da9d96c9c0191a0c186fa9b3 Mon Sep 17 00:00:00 2001 From: Andy Babic Date: Tue, 20 Sep 2022 09:51:23 +0100 Subject: [PATCH 3/5] =?UTF-8?q?Support=20the=20Meta=20=E2=80=98autotest?= =?UTF-8?q?=E2=80=99=20option=20for=20PageFactory=20classes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/wagtail_factories/factories.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/wagtail_factories/factories.py b/src/wagtail_factories/factories.py index ae2e3d1..5290899 100644 --- a/src/wagtail_factories/factories.py +++ b/src/wagtail_factories/factories.py @@ -3,6 +3,7 @@ import factory from django.utils.text import slugify from factory import errors, utils +from factory.base import FactoryOptions, OptionDefault from factory.declarations import ParameteredAttribute from wagtail.images import get_image_model @@ -131,12 +132,23 @@ def __new__(mcs, class_name, bases, attrs): return new_class +class PageFactoryOptions(FactoryOptions): + def _build_default_options(self): + return super()._build_default_options() + [ + OptionDefault("autotest", True, inherit=False), + ] + + class PageFactory(MP_NodeFactory, metaclass=PageFactoryMetaClass): + title = "Test page" slug = factory.LazyAttribute(lambda obj: slugify(obj.title)) + _options_class = PageFactoryOptions + class Meta: model = Page + autotest = False class CollectionMemberFactory(DjangoModelFactory): From ed11acd2bda50e4cb5deef9e8aaf5affd919fc7f Mon Sep 17 00:00:00 2001 From: Andy Babic Date: Tue, 20 Sep 2022 09:52:57 +0100 Subject: [PATCH 4/5] Add test case to cover render-ability, edit-ability and preview-ability for all page types where Factory._meta.autotest is True --- src/wagtail_factories/autotest.py | 75 +++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 src/wagtail_factories/autotest.py diff --git a/src/wagtail_factories/autotest.py b/src/wagtail_factories/autotest.py new file mode 100644 index 0000000..6a76117 --- /dev/null +++ b/src/wagtail_factories/autotest.py @@ -0,0 +1,75 @@ +import os + +from django.contrib.auth import get_user_model +from django.http import HttpRequest +from django.test import TestCase +from wagtail.models import Page +from wagtail.admin.views.pages import EditView + +import wagtail_factories + + +class PageFeaturesTestCase(TestCase): + @classmethod + def setUpTestData(cls): + cls.user = get_user_model().objects.create_superuser("superuser") + cls.default_request = cls.get_request("/") + + @classmethod + def get_request(cls, path: str, method: str = "GET") -> HttpRequest: + request = HttpRequest() + request.method = method + request.path = path + request.user = get_user_model().objects.create_superuser("superuser") + + def assertCanRenderPageWithoutErrors(self, page: Page, route_path: str = "/"): + full_path = os.path.join(page.get_url(self.default_request), route_path) + request = self.get_request(full_path) + try: + view, args, kwargs = page.resolve_subpage(route_path) + except AttributeError: + page.serve(request) + else: + page.serve(request, view, args, kwargs) + + def assertCanEditPageWithoutErrors(self, page: Page): + path = f"/admin/pages/{page.id}/edit/" + request = self.get_request(path) + EditView.as_view()(request, page.id) + post_request = self.get_request(path, method="POST") + EditView.as_view()(post_request, page.id) + + def assertCanPreviewPageWithoutErrors(self, page: Page, preview_mode: str = ""): + path = f"/admin/pages/{page.id}/edit/preview/?mode={preview_mode}" + request = self.get_request(path) + preview_request = page.make_preview_request(request, preview_mode) + page.serve_preview(preview_request, preview_mode) + + +class PageAutoTestCase(PageFeaturesTestCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.factories_to_test = [ + f for f in wagtail_factories.get_page_factories() if f._meta.autotest + ] + + def test_can_render_pages_without_errors(self): + for factory in self.factories_to_test: + page = factory() + for path in page.get_route_paths(page): + with self.subTest(f"Page type: {type(page)}, Route: {path}"): + self.assertCanRenderPageWithoutErrors(page, path) + + def test_can_edit_pages_without_errors(self): + for factory in self.factories_to_test: + page = factory() + with self.subTest(f"Page type: {type(page)}"): + self.assertCanEditPageWithoutErrors(page) + + def test_can_preview_pages_without_errors(self): + for factory in self.factories_to_test: + page = factory() + for mode, label in page.preview_modes: + with self.subTest(f"Page type: {type(page)}, Mode: {label}"): + self.assertCanPreviewPageWithoutErrors(page, mode) From e84f21bf8ca595cf66b26786a5383084b47a77ae Mon Sep 17 00:00:00 2001 From: Andy Babic Date: Tue, 20 Sep 2022 10:44:55 +0100 Subject: [PATCH 5/5] Run PageAutoTestCase tests for the test app --- tests/test_autotest.py | 1 + 1 file changed, 1 insertion(+) create mode 100644 tests/test_autotest.py diff --git a/tests/test_autotest.py b/tests/test_autotest.py new file mode 100644 index 0000000..6f948ab --- /dev/null +++ b/tests/test_autotest.py @@ -0,0 +1 @@ +from wagtail_factories.autotest import PageAutoTestCase # noqa