Add tests and hooks for "after page move" and "after page create" hooks

Relates to MS-666
This commit is contained in:
Ramon Wenger 2023-03-14 17:07:05 +01:00
parent d18b21e466
commit deecef5e5b
3 changed files with 144 additions and 33 deletions

View File

@ -41,30 +41,30 @@ def duplicate_entities_generator(new_module):
def duplicate_entities(block): def duplicate_entities(block):
content_type = block.block_type content_type = block.block_type
value = block.value value = block.value
logger.debug(block) # logger.debug(block)
if content_type == "assignment": if content_type == "assignment":
assignment = value.get("assignment_id") assignment = value.get("assignment_id")
# copy the assignment # copy the assignment
assignment.pk = None assignment.pk = None
assignment.title = f"{assignment.title} (Kopie)" assignment.title = f"{assignment.title} (Kopie)"
assignment.module = new_module assignment.module = new_module
logger.debug(f"setting new module {new_module}, {assignment.module}") # logger.debug(f"setting new module {new_module}, {assignment.module}")
assignment.save() assignment.save()
data = {"assignment_id": assignment} data = {"assignment_id": assignment}
new_block = ("assignment", data) new_block = ("assignment", data)
return new_block return new_block
if content_type == "survey": if content_type == "survey":
logger.debug(value) # logger.debug(value)
survey = value.get("survey_id") survey = value.get("survey_id")
# copy the survey # copy the survey
survey.pk = None survey.pk = None
survey.title = f"{survey.title} (Kopie)" survey.title = f"{survey.title} (Kopie)"
survey.module = new_module survey.module = new_module
logger.debug(f"setting new module {new_module}, {survey.module}") # logger.debug(f"setting new module {new_module}, {survey.module}")
survey.save() survey.save()
data = {"survey_id": survey} data = {"survey_id": survey}
new_block = ("survey", data) new_block = ("survey", data)
logger.debug(new_block) # logger.debug(new_block)
return new_block return new_block
return block return block
@ -159,19 +159,19 @@ class ContentBlock(StrictHierarchyPage, GraphqlNodeMixin):
# duplicate all attached Surveys and Assignments # duplicate all attached Surveys and Assignments
def duplicate_attached_entities(self): def duplicate_attached_entities(self):
logger.debug("starting to duplicate inside the content block") # logger.debug("starting to duplicate inside the content block")
duplicate_entities = duplicate_entities_generator(self.module) duplicate_entities = duplicate_entities_generator(self.module)
logger.debug(f"new module: {self.module}") # logger.debug(f"new module: {self.module}")
iterator = map(duplicate_entities, self.contents) iterator = map(duplicate_entities, self.contents)
logger.debug("here is the iterator") # logger.debug("here is the iterator")
new_contents = list(iterator) new_contents = list(iterator)
logger.debug(new_contents) # logger.debug(new_contents)
# we can't just insert a list here, we need a StreamValue data type # we can't just insert a list here, we need a StreamValue data type
# so we need to clear the list, then add each element in turn # so we need to clear the list, then add each element in turn
self.contents.clear() self.contents.clear()
# like this, the internal methods of the SteamValue data type can work on the single elements # like this, the internal methods of the SteamValue data type can work on the single elements
for content in new_contents: for content in new_contents:
logger.debug(content) # logger.debug(content)
self.contents.append(content) self.contents.append(content)
# as an illustration # as an illustration
@ -180,8 +180,8 @@ class ContentBlock(StrictHierarchyPage, GraphqlNodeMixin):
# value = block.to_python(data) # value = block.to_python(data)
# clean_value = block.clean(value) # clean_value = block.clean(value)
# self.contents.append(('solution', clean_value)) # self.contents.append(('solution', clean_value))
logger.debug("self.contents") # logger.debug("self.contents")
logger.debug(self.contents) # logger.debug(self.contents)
self.save() self.save()
def is_hidden_for_class(self, school_class): def is_hidden_for_class(self, school_class):
@ -193,6 +193,23 @@ class ContentBlock(StrictHierarchyPage, GraphqlNodeMixin):
and not self.visible_for.filter(id=school_class.id).exists() and not self.visible_for.filter(id=school_class.id).exists()
) )
def reassign_entities(self):
module = self.module
logger.debug("reassigning entities")
for content in self.contents:
if content.block_type == "assignment":
assignment = content.value.get("assignment_id")
logger.debug(assignment.module)
if assignment.module != module:
assignment.module = module
assignment.save()
if content.block_type == "survey":
survey = content.value.get("survey_id")
logger.debug(survey.module)
if survey.module != module:
survey.module = module
survey.save()
# def save(self, *args, **kwargs): # def save(self, *args, **kwargs):
# todo: move this to the after_create_page and after_edit_page hooks, and remove from here. # todo: move this to the after_create_page and after_edit_page hooks, and remove from here.
# for data in self.contents.raw_data: # for data in self.contents.raw_data:

View File

@ -1,6 +1,7 @@
import json import json
from django.test import TestCase from django.test import TestCase
from django.urls import reverse from django.urls import reverse
from wagtail.models import Page
from wagtail.test.utils import WagtailTestUtils from wagtail.test.utils import WagtailTestUtils
from assignments.factories import AssignmentFactory from assignments.factories import AssignmentFactory
from assignments.models import Assignment from assignments.models import Assignment
@ -45,6 +46,7 @@ class CoreHooksTestCase(WagtailTestUtils, TestCase):
# create content blocks # create content blocks
assignment = AssignmentFactory() assignment = AssignmentFactory()
self.assignment_id = assignment.id
assignment_block = AssignmentBlock() assignment_block = AssignmentBlock()
assignment_value = assignment_block.to_python({"assignment_id": assignment.id}) assignment_value = assignment_block.to_python({"assignment_id": assignment.id})
cleaned_assignment_value = assignment_block.clean(assignment_value) cleaned_assignment_value = assignment_block.clean(assignment_value)
@ -66,7 +68,7 @@ class CoreHooksTestCase(WagtailTestUtils, TestCase):
self.assertEqual(self.content_block.contents[1].value["survey_id"], survey) self.assertEqual(self.content_block.contents[1].value["survey_id"], survey)
self.assertEqual(Assignment.objects.count(), 1) self.assertEqual(Assignment.objects.count(), 1)
self.assertEqual(Survey.objects.count(), 1) self.assertEqual(Survey.objects.count(), 1)
logger.debug(f"assignment: {assignment.id}") # logger.debug(f"assignment: {assignment.id}")
self.new_topic = TopicFactory.create( self.new_topic = TopicFactory.create(
parent=self.book, title="A second Topic", order=2 parent=self.book, title="A second Topic", order=2
@ -111,12 +113,11 @@ class CoreHooksTestCase(WagtailTestUtils, TestCase):
"wagtailadmin_pages:add", "wagtailadmin_pages:add",
args=("books", "topic", self.book.id), args=("books", "topic", self.book.id),
) )
logger.debug(url) # logger.debug(url)
response = self.client.post( self.client.post(
url, url,
post_data, post_data,
) )
logger.debug(response)
self.assertEqual(Topic.objects.count(), 3) self.assertEqual(Topic.objects.count(), 3)
def _check_copied_content_block(self, module=None): def _check_copied_content_block(self, module=None):
@ -127,7 +128,6 @@ class CoreHooksTestCase(WagtailTestUtils, TestCase):
self.assertEqual(Assignment.objects.count(), 2) self.assertEqual(Assignment.objects.count(), 2)
self.assertEqual(Survey.objects.count(), 2) self.assertEqual(Survey.objects.count(), 2)
new_content_block = ContentBlock.objects.latest("-latest_revision_created_at") 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_assignment = Assignment.objects.latest("pk")
new_survey = Survey.objects.latest("pk") new_survey = Survey.objects.latest("pk")
self.assertEqual( self.assertEqual(
@ -147,9 +147,7 @@ class CoreHooksTestCase(WagtailTestUtils, TestCase):
post_data = get_copy_payload( post_data = get_copy_payload(
"Neuer Titel (Kopie)", "new-slug", self.new_chapter "Neuer Titel (Kopie)", "new-slug", self.new_chapter
) )
logger.debug(post_data) self.client.post(url, post_data)
response = self.client.post(url, post_data)
logger.debug(response)
self._check_copied_content_block() self._check_copied_content_block()
def test_chapter_after_copy_hook(self): def test_chapter_after_copy_hook(self):
@ -158,8 +156,7 @@ class CoreHooksTestCase(WagtailTestUtils, TestCase):
""" """
url = get_copy_url(self.chapter) url = get_copy_url(self.chapter)
post_data = get_copy_payload("Neuer Titel (Kopie)", "new-slug", self.new_module) post_data = get_copy_payload("Neuer Titel (Kopie)", "new-slug", self.new_module)
response = self.client.post(url, post_data) self.client.post(url, post_data)
logger.debug(response)
self._check_copied_content_block() self._check_copied_content_block()
def test_module_after_copy_hook(self): def test_module_after_copy_hook(self):
@ -168,8 +165,7 @@ class CoreHooksTestCase(WagtailTestUtils, TestCase):
""" """
url = get_copy_url(self.module) url = get_copy_url(self.module)
post_data = get_copy_payload("Neuer Titel (Kopie)", "new-slug", self.new_topic) post_data = get_copy_payload("Neuer Titel (Kopie)", "new-slug", self.new_topic)
response = self.client.post(url, post_data) self.client.post(url, post_data)
logger.debug(response)
module = Module.objects.latest("-latest_revision_created_at") module = Module.objects.latest("-latest_revision_created_at")
self._check_copied_content_block(module) self._check_copied_content_block(module)
@ -179,8 +175,90 @@ class CoreHooksTestCase(WagtailTestUtils, TestCase):
""" """
url = get_copy_url(self.topic) url = get_copy_url(self.topic)
post_data = get_copy_payload("Neuer Titel (Kopie)", "new-slug", self.book) post_data = get_copy_payload("Neuer Titel (Kopie)", "new-slug", self.book)
response = self.client.post(url, post_data) self.client.post(url, post_data)
logger.debug(response)
topic = Topic.objects.latest("-latest_revision_created_at") topic = Topic.objects.latest("-latest_revision_created_at")
module = topic.get_children().first().specific module = topic.get_children().first().specific
self._check_copied_content_block(module) self._check_copied_content_block(module)
def test_chapter_after_move_hook(self):
"""
should move the chapter, and set all entities' module to the new parent's parent module
"""
assignment = self.content_block.contents[0].value["assignment_id"]
survey = self.content_block.contents[1].value["survey_id"]
self.assertEqual(self.chapter.pk, self.content_block.get_parent().pk)
logger.debug("content blocks")
logger.debug(self.chapter.get_content_blocks())
url = reverse(
"wagtailadmin_pages:move_confirm",
args=(self.chapter.id, self.new_module.id),
)
logger.debug(url)
response = self.client.post(url)
logger.debug(response)
chapter = Page.objects.get(id=self.chapter.id)
logger.debug("new content blocks")
logger.debug(chapter.specific.get_content_blocks())
self.assertEqual(chapter.get_parent().id, self.new_module.id)
# reload the assignment from the DB
assignment = Assignment.objects.get(id=assignment.id)
self.assertEqual(assignment.module, self.new_module)
survey = Survey.objects.get(id=survey.id)
self.assertEqual(survey.module, self.new_module)
def test_content_block_after_move_hook(self):
"""
should move the content block, and set all entities' module to the new parent's parent module
"""
url = reverse(
"wagtailadmin_pages:move_confirm",
args=(self.content_block.id, self.new_chapter.id),
)
self.client.post(url)
assignment = self.content_block.contents[0].value["assignment_id"]
self.assertEqual(assignment.module, self.new_module)
def test_content_block_after_create_hook(self):
"""
should save the content block and set all new entites' module to the correct module
"""
assignment = AssignmentFactory(module=self.module)
survey = SurveyFactory(module=None)
self.assertEqual(assignment.module, assignment.module)
self.assertIsNone(survey.module)
self.assertEqual(ContentBlock.objects.count(), 1)
url = reverse(
"wagtailadmin_pages:add",
args=("books", "contentblock", self.new_chapter.id),
)
post_data = {
"title": "New Content Block",
"order": 1,
"slug": "hello-world",
"contents-count": 2,
"contents-0-deleted": "",
"contents-0-order": "0",
"contents-0-type": "assignment",
"contents-0-id": "",
"contents-0-value-assignment_id": f"{assignment.id}",
"contents-1-deleted": "",
"contents-1-order": "1",
"contents-1-type": "survey",
"contents-1-id": "",
"contents-1-value-survey_id": f"{survey.id}",
"type": "normal",
}
response = self.client.post(
url,
post_data,
)
self.assertEqual(ContentBlock.objects.count(), 2)
# reload assignment
assignment = Assignment.objects.get(id=assignment.id)
self.assertEqual(assignment.module, self.new_module)
survey = Survey.objects.get(id=survey.id)
self.assertEqual(survey.module, self.new_module)

View File

@ -6,6 +6,7 @@ from wagtail import hooks
from basicknowledge.models import BasicKnowledge from basicknowledge.models import BasicKnowledge
from books.models import ContentBlockSnapshot from books.models import ContentBlockSnapshot
from books.models.chapter import Chapter
from books.models.contentblock import ContentBlock from books.models.contentblock import ContentBlock
from core.logger import get_logger from core.logger import get_logger
@ -102,20 +103,32 @@ def remove_page_types_from_menu(parent_page, pages, request):
def after_copy_hook(request, page, new_page): def after_copy_hook(request, page, new_page):
# todo: find every ContentBlock further down in the tree, see if there are any Surveys or Assignments and copy them and reassign them # todo: find every ContentBlock further down in the tree, see if there are any Surveys or Assignments and copy them and reassign them
if type(page.specific) == ContentBlock: if type(page.specific) == ContentBlock:
logger.debug("It's a content block") # logger.debug("It's a content block")
content_block: ContentBlock = new_page.specific content_block: ContentBlock = new_page.specific
logger.debug(f"duplicatin {content_block.title, content_block.pk}") # logger.debug(f"duplicatin {content_block.title, content_block.pk}")
content_block.duplicate_attached_entities() content_block.duplicate_attached_entities()
else: else:
logger.debug(f"It's something else {type(page.specific)}, {ContentBlock}") # logger.debug(f"It's something else {type(page.specific)}, {ContentBlock}")
content_blocks = new_page.specific.get_content_blocks() content_blocks = new_page.specific.get_content_blocks()
for content_block in content_blocks: for content_block in content_blocks:
content_block.duplicate_attached_entities() content_block.duplicate_attached_entities()
logger.debug(
f"After copy page old: {page.title} {page.pk}, {new_page.title} {new_page.pk}" @hooks.register("after_move_page")
) def after_move_hook(request, page):
logger.debug(f"after moving the page {page.title}")
if type(page.specific) == ContentBlock:
logger.debug("it's a content block")
page.specific.reassign_entities()
if type(page.specific) == Chapter:
logger.debug("it's a chapter")
content_blocks = page.specific.get_content_blocks()
logger.debug(page.id)
logger.debug(page.specific.get_content_blocks())
logger.debug(page.get_children())
for content_block in content_blocks:
content_block.reassign_entities()
@hooks.register("after_edit_page") @hooks.register("after_edit_page")
@ -125,4 +138,7 @@ def after_edit_hook(request, page):
@hooks.register("after_create_page") @hooks.register("after_create_page")
def after_create_hook(request, page): def after_create_hook(request, page):
logger.debug(f"After create page {page.title}") # reassign assignment and survey module
if type(page.specific) == ContentBlock:
content_block = page.specific
content_block.reassign_entities()