Add mutation and unit test for duplication

This commit is contained in:
Ramon Wenger 2022-09-20 23:07:02 +02:00
parent bfb6a6e7a0
commit 6be6ab8092
5 changed files with 128 additions and 1 deletions

27
server/books/managers.py Normal file
View File

@ -0,0 +1,27 @@
from wagtail.core.models import PageManager
from typing import TYPE_CHECKING
from core.logger import get_logger
if TYPE_CHECKING:
from books.models import ContentBlock
logger = get_logger(__name__)
class ContentBlockManager(PageManager):
def duplicate(self, content_block: "ContentBlock", user):
try:
new_content_block = self.model(
user_created=True,
owner=user,
contents=content_block.contents,
title=content_block.title,
type=content_block.type,
)
content_block.add_sibling(instance=new_content_block, pos='right')
revision = new_content_block.save_revision()
revision.publish()
new_content_block.save()
return new_content_block
except Exception as e:
logger.warn(e)

View File

@ -6,6 +6,7 @@ from wagtail.core.blocks import StreamBlock
from wagtail.core.fields import StreamField from wagtail.core.fields import StreamField
from wagtail.images.blocks import ImageChooserBlock from wagtail.images.blocks import ImageChooserBlock
from books.managers import ContentBlockManager
from core.wagtail_utils import get_default_settings from core.wagtail_utils import get_default_settings
from books.blocks import CMSDocumentBlock, SolutionBlock, TextBlock, BasicKnowledgeBlock, LinkBlock, VideoBlock, \ from books.blocks import CMSDocumentBlock, SolutionBlock, TextBlock, BasicKnowledgeBlock, LinkBlock, VideoBlock, \
DocumentBlock, \ DocumentBlock, \
@ -90,6 +91,8 @@ class ContentBlock(StrictHierarchyPage):
parent_page_types = ['books.Chapter'] parent_page_types = ['books.Chapter']
subpage_types = [] subpage_types = []
objects = ContentBlockManager()
@property @property
def module(self): def module(self):
return self.get_parent().get_parent().specific return self.get_parent().get_parent().specific

View File

@ -1,5 +1,6 @@
from books.schema.mutations.chapter import UpdateChapterVisibility from books.schema.mutations.chapter import UpdateChapterVisibility
from books.schema.mutations.contentblock import MutateContentBlock, AddContentBlock, DeleteContentBlock from books.schema.mutations.contentblock import DuplicateContentBlock, MutateContentBlock, AddContentBlock, \
DeleteContentBlock
from books.schema.mutations.module import UpdateSolutionVisibility, UpdateLastModule, SyncModuleVisibility from books.schema.mutations.module import UpdateSolutionVisibility, UpdateLastModule, SyncModuleVisibility
from books.schema.mutations.snapshot import CreateSnapshot, ApplySnapshot, ShareSnapshot, UpdateSnapshot, DeleteSnapshot from books.schema.mutations.snapshot import CreateSnapshot, ApplySnapshot, ShareSnapshot, UpdateSnapshot, DeleteSnapshot
from books.schema.mutations.topic import UpdateLastTopic from books.schema.mutations.topic import UpdateLastTopic
@ -9,6 +10,7 @@ class BookMutations(object):
mutate_content_block = MutateContentBlock.Field() mutate_content_block = MutateContentBlock.Field()
add_content_block = AddContentBlock.Field() add_content_block = AddContentBlock.Field()
delete_content_block = DeleteContentBlock.Field() delete_content_block = DeleteContentBlock.Field()
duplicate_content_block = DuplicateContentBlock.Field()
update_solution_visibility = UpdateSolutionVisibility.Field() update_solution_visibility = UpdateSolutionVisibility.Field()
update_last_module = UpdateLastModule.Field() update_last_module = UpdateLastModule.Field()
update_last_topic = UpdateLastTopic.Field() update_last_topic = UpdateLastTopic.Field()

View File

@ -143,3 +143,22 @@ class DeleteContentBlock(relay.ClientIDMutation):
return cls(success=True) return cls(success=True)
except ContentBlock.DoesNotExist: except ContentBlock.DoesNotExist:
return cls(success=False, errors='Content block not found') return cls(success=False, errors='Content block not found')
class DuplicateContentBlock(relay.ClientIDMutation):
class Input:
id = graphene.ID(required=True)
content_block = graphene.Field(ContentBlockNode)
@classmethod
def mutate_and_get_payload(cls, root, info, **kwargs):
id = from_global_id(kwargs.get('id'))[1]
user = info.context.user
try:
content_block = ContentBlock.objects.get(pk=id)
new_content_block = ContentBlock.objects.duplicate(content_block=content_block, user=user)
return cls(content_block=new_content_block)
except ContentBlock.DoesNotExist:
return cls(content_block=None)

View File

@ -0,0 +1,76 @@
from graphql_relay import to_global_id
from books.factories import ContentBlockFactory, ModuleFactory, ChapterFactory
from books.models import ContentBlock
from core.tests.base_test import SkillboxTestCase
DUPLICATE_CONTENT_BLOCK_MUTATION = """
mutation DuplicateContentBlockMutation($input: DuplicateContentBlockInput!) {
duplicateContentBlock(input: $input) {
contentBlock {
id
}
}
}
"""
CONTENT_BLOCK_QUERY = """
query ContentBlockQuery($slug: String!) {
module(slug: $slug) {
chapters {
id
contentBlocks {
id
title
type
}
}
}
}
"""
class DuplicateContentBlockTestCase(SkillboxTestCase):
def setUp(self) -> None:
self.createDefault()
#
self.slug = 'module'
self.module = ModuleFactory(slug=self.slug)
self.chapter = ChapterFactory(parent=self.module)
self.content_block = ContentBlock(
type=ContentBlock.NORMAL,
title='Title',
)
self.chapter.add_child(instance=self.content_block)
def test_duplicate_content_block(self):
result = self.get_client().execute(CONTENT_BLOCK_QUERY, variables={
'slug': self.slug
})
self.assertIsNone(result.errors)
module = result.data.get('module')
chapter = module.get('chapters')[0]
content_blocks = chapter.get('contentBlocks')
self.assertEqual(len(content_blocks), 1)
self.assertEqual(ContentBlock.objects.count(), 1)
result = self.get_client().execute(DUPLICATE_CONTENT_BLOCK_MUTATION, variables={
'input': {
"id": to_global_id('ContentBlockNode', self.content_block.id)
}
})
self.assertIsNone(result.errors)
duplicate_content_block = result.data.get('duplicateContentBlock')
content_block = duplicate_content_block.get('contentBlock')
# self.assertEqual(content_block['title'], 'Title')
self.assertIsNotNone(content_block['id'])
result = self.get_client().execute(CONTENT_BLOCK_QUERY, variables={
'slug': self.slug
})
self.assertIsNone(result.errors)
module = result.data.get('module')
chapter = module.get('chapters')[0]
content_blocks = chapter.get('contentBlocks')
self.assertEqual(ContentBlock.objects.count(), 2)
self.assertEqual(len(content_blocks), 2)