From 95ad35aecff1d60f4bf53b8da80e7aa2aa899f10 Mon Sep 17 00:00:00 2001 From: Ramon Wenger Date: Thu, 9 Mar 2023 16:49:23 +0100 Subject: [PATCH] Add tests for all page types, also implement them --- server/books/models/chapter.py | 2 +- server/books/models/contentblock.py | 5 +- server/core/tests/test_core_hooks.py | 190 +++++++++++++++++++++++++++ server/core/wagtail_hooks.py | 3 + server/core/wagtail_utils.py | 4 +- 5 files changed, 199 insertions(+), 5 deletions(-) create mode 100644 server/core/tests/test_core_hooks.py diff --git a/server/books/models/chapter.py b/server/books/models/chapter.py index cefda10b..c344f8da 100644 --- a/server/books/models/chapter.py +++ b/server/books/models/chapter.py @@ -40,7 +40,7 @@ class Chapter(StrictHierarchyPage, GraphqlNodeMixin): ) def get_content_blocks(self): - return ContentBlock.objects.all().descendants_of(self) + return ContentBlock.objects.all().descendant_of(self) def sync_title_visibility(self, school_class_template, school_class_to_sync): if ( diff --git a/server/books/models/contentblock.py b/server/books/models/contentblock.py index 0b5fc93f..4b32b272 100644 --- a/server/books/models/contentblock.py +++ b/server/books/models/contentblock.py @@ -1,5 +1,4 @@ from django.db import models -from assignments.models import Assignment from wagtail.admin.panels import ( FieldPanel, TabbedInterface, @@ -32,7 +31,6 @@ from books.blocks import ( ) from core.wagtail_utils import StrictHierarchyPage from notes.models import ContentBlockBookmark -from surveys.models import Survey from users.models import SchoolClass, User from core.mixins import GraphqlNodeMixin @@ -194,7 +192,8 @@ class ContentBlock(StrictHierarchyPage, GraphqlNodeMixin): def is_hidden_for_class(self, school_class): return ( - not self.user_creted and self.hidden_for.filter(id=school_class.id).exists() + not self.user_created + and self.hidden_for.filter(id=school_class.id).exists() ) or ( self.user_created and not self.visible_for.filter(id=school_class.id).exists() diff --git a/server/core/tests/test_core_hooks.py b/server/core/tests/test_core_hooks.py new file mode 100644 index 00000000..8cc1cc26 --- /dev/null +++ b/server/core/tests/test_core_hooks.py @@ -0,0 +1,190 @@ +import json +from django.test import TestCase +from django.urls import reverse +from wagtail.models import Page +from wagtail.test.utils import WagtailTestUtils +from wagtail.test.utils.form_data import rich_text +from assignments.factories import AssignmentFactory +from assignments.models import Assignment +from books.blocks import AssignmentBlock, SurveyBlock +from books.factories import BookFactory, ChapterFactory, ModuleFactory, TopicFactory +from books.models.book import Book +from books.models.chapter import Chapter +from books.models.contentblock import ContentBlock +from books.models.module import Module +from books.models.topic import Topic + +from core.logger import get_logger +from surveys.factories import SurveyFactory +from surveys.models import Survey + +logger = get_logger(__name__) + + +def get_copy_payload(title, slug, parent): + return { + "new_title": title, + "new_slug": slug, + "new_parent_page": parent.id, + "copy_subpages": True, + "publish_copies": False, + "alias": False, + } + + +def get_copy_url(page): + return reverse("wagtailadmin_pages:copy", args=(page.id,)) + + +class CoreHooksTestCase(WagtailTestUtils, TestCase): + def setUp(self) -> None: + ( + self.book, + self.topic, + self.module, + self.chapter, + self.content_block, + ) = BookFactory.create_default_structure() + self.user = self.login() + + # create content blocks + assignment = AssignmentFactory() + assignment_block = AssignmentBlock() + assignment_value = assignment_block.to_python({"assignment_id": assignment.id}) + cleaned_assignment_value = assignment_block.clean(assignment_value) + assignment_content = ("assignment", cleaned_assignment_value) + + survey = SurveyFactory() + survey_block = SurveyBlock() + survey_value = survey_block.to_python({"survey_id": survey.id}) + cleaned_survey_value = survey_block.clean(survey_value) + survey_content = ("survey", cleaned_survey_value) + + self.content_block.contents.append(assignment_content) + self.content_block.contents.append(survey_content) + self.content_block.save() + + self.assertEqual( + self.content_block.contents[0].value["assignment_id"], assignment + ) + self.assertEqual(self.content_block.contents[1].value["survey_id"], survey) + self.assertEqual(Assignment.objects.count(), 1) + self.assertEqual(Survey.objects.count(), 1) + logger.debug(f"assignment: {assignment.id}") + + self.new_topic = TopicFactory.create( + parent=self.book, title="A second Topic", order=2 + ) + + self.new_module = ModuleFactory.create( + parent=self.new_topic, + title="A second module", + meta_title="Modul 1", + teaser="Whatever", + intro="

Hello

", + ) + self.new_chapter = ChapterFactory.create( + parent=self.new_module, title="A second chapter" + ) + + def test_after_create_hook(self): + # description = rich_text('

hello

') + self.assertEqual(Topic.objects.count(), 2) + description = { + "blocks": [ + { + "key": "thfb4", + "text": "asd", + "type": "unstyled", + "depth": 0, + "inlineStyleRanges": [], + "entityRanges": [], + "data": {}, + } + ], + "entityMap": {}, + } + post_data = { + "title": "New Page", + "order": 1, + "teaser": "Tease", + "description": json.dumps(description), + "slug": "hello-world", + } + url = reverse( + "wagtailadmin_pages:add", + args=("books", "topic", self.book.id), + ) + logger.debug(url) + response = self.client.post( + url, + post_data, + ) + logger.debug(response) + self.assertEqual(Topic.objects.count(), 3) + + def _check_copied_content_block(self, module=None): + if module is None: + module = self.new_module + + self.assertEqual(ContentBlock.objects.count(), 2) + self.assertEqual(Assignment.objects.count(), 2) + self.assertEqual(Survey.objects.count(), 2) + new_content_block = ContentBlock.objects.latest("-latest_revision_created_at") + logger.debug(f"new content block {new_content_block}") + new_assignment = Assignment.objects.latest("pk") + new_survey = Survey.objects.latest("pk") + self.assertEqual( + new_content_block.contents[0].value["assignment_id"], new_assignment + ) + self.assertEqual(new_assignment.module, module) + self.assertEqual(new_content_block.contents[1].value["survey_id"], new_survey) + self.assertEqual(new_survey.module, module) + + def test_content_block_after_copy_hook(self): + """ + should copy the content block, and set all entities' module to the new parent's parent module + """ + # inspired by wagtail.admin.tests.pages.test_copy_page + + url = get_copy_url(self.content_block) + post_data = get_copy_payload( + "Neuer Titel (Kopie)", "new-slug", self.new_chapter + ) + logger.debug(post_data) + response = self.client.post(url, post_data) + logger.debug(response) + self._check_copied_content_block() + + def test_chapter_after_copy_hook(self): + """ + should copy the chapter, and set all entities' module to the new parent module + """ + url = get_copy_url(self.chapter) + post_data = get_copy_payload("Neuer Titel (Kopie)", "new-slug", self.new_module) + response = self.client.post(url, post_data) + logger.debug(response) + self._check_copied_content_block() + + def test_module_after_copy_hook(self): + """ + should copy the module, and set all entities' module to the newly created module + """ + url = get_copy_url(self.module) + post_data = get_copy_payload("Neuer Titel (Kopie)", "new-slug", self.new_topic) + response = self.client.post(url, post_data) + logger.debug(response) + module = Module.objects.latest("-latest_revision_created_at") + self._check_copied_content_block(module) + + def test_topic_after_copy_hook(self): + """ + should copy the whole topic, and set all entities to the newly created child module + """ + url = get_copy_url(self.topic) + post_data = get_copy_payload("Neuer Titel (Kopie)", "new-slug", self.book) + response = self.client.post(url, post_data) + logger.debug(response) + topic = Topic.objects.latest("-latest_revision_created_at") + module = topic.get_children().first().specific + self._check_copied_content_block(module) diff --git a/server/core/wagtail_hooks.py b/server/core/wagtail_hooks.py index 3f54303e..8522efc2 100644 --- a/server/core/wagtail_hooks.py +++ b/server/core/wagtail_hooks.py @@ -109,6 +109,9 @@ def after_copy_hook(request, page, new_page): else: logger.debug(f"It's something else {type(page.specific)}, {ContentBlock}") + content_blocks = new_page.specific.get_content_blocks() + for content_block in content_blocks: + content_block.duplicate_attached_entities() logger.debug( f"After copy page old: {page.title} {page.pk}, {new_page.title} {new_page.pk}" diff --git a/server/core/wagtail_utils.py b/server/core/wagtail_utils.py index 1213eb82..06f1ac17 100644 --- a/server/core/wagtail_utils.py +++ b/server/core/wagtail_utils.py @@ -16,7 +16,9 @@ class StrictHierarchyPage(Page): return cls.objects.filter(id__in=parent.get_child_ids()).live() def get_content_blocks(self): - raise NotImplementedError() + from books.models.contentblock import ContentBlock + + return ContentBlock.objects.all().descendant_of(self) def wagtail_parent_filter(parent_cls, child_cls):