From 29f37269935585aecc44f9e9f5dc8d81248660e6 Mon Sep 17 00:00:00 2001 From: Ramon Wenger Date: Tue, 4 May 2021 22:52:03 +0200 Subject: [PATCH] Refactor content block type --- .../books/schema/interfaces/contentblock.py | 9 +--- server/books/schema/nodes/chapter.py | 2 +- server/books/schema/nodes/content.py | 9 +++- server/books/schema/nodes/snapshot.py | 4 ++ server/books/tests/test_content_blocks.py | 52 ++++++++++++++++++ server/books/tests/test_create_snapshot.py | 54 +++++++++---------- server/core/tests/base_test.py | 19 +++++++ server/schema.graphql | 14 ++--- 8 files changed, 112 insertions(+), 51 deletions(-) create mode 100644 server/books/tests/test_content_blocks.py create mode 100644 server/core/tests/base_test.py diff --git a/server/books/schema/interfaces/contentblock.py b/server/books/schema/interfaces/contentblock.py index dc250595..274810c9 100644 --- a/server/books/schema/interfaces/contentblock.py +++ b/server/books/schema/interfaces/contentblock.py @@ -3,15 +3,8 @@ from graphene import relay from api.graphene_wagtail import GenericStreamFieldType -class ContentBlockType(graphene.Enum): - NORMAL = 'normal' - BASE_COMMUNICATION = 'base_communication' - TASK = 'task' - BASE_SOCIETY = 'base_society' - BASE_INTERDISCIPLINARY = 'base_interdisciplinary' - class ContentBlockInterface(relay.Node): title = graphene.String() contents = GenericStreamFieldType() - type = ContentBlockType() + type = graphene.String() diff --git a/server/books/schema/nodes/chapter.py b/server/books/schema/nodes/chapter.py index 9d39d69e..33e40b8c 100644 --- a/server/books/schema/nodes/chapter.py +++ b/server/books/schema/nodes/chapter.py @@ -14,7 +14,7 @@ from notes.schema import ChapterBookmarkNode class ChapterNode(DjangoObjectType): bookmark = graphene.Field(ChapterBookmarkNode) - content_blocks = DjangoFilterConnectionField('books.schema.nodes.ContentBlockNode') + content_blocks = graphene.List('books.schema.nodes.ContentBlockNode') class Meta: model = Chapter diff --git a/server/books/schema/nodes/content.py b/server/books/schema/nodes/content.py index 5af57324..d8a88a7e 100644 --- a/server/books/schema/nodes/content.py +++ b/server/books/schema/nodes/content.py @@ -49,9 +49,14 @@ class ContentBlockNode(DjangoObjectType): 'slug', 'title', ] interfaces = (ContentBlockInterface,) + convert_choices_to_enum = False - def resolve_mine(self, info, **kwargs): - return self.owner is not None and self.owner.pk == info.context.user.pk + def resolve_mine(parent, info, **kwargs): + return parent.owner is not None and parent.owner.pk == info.context.user.pk + + @staticmethod + def resolve_type(parent, info, **kwargs): + return parent.type def resolve_contents(self, info, **kwargs): updated_stream_data = [] diff --git a/server/books/schema/nodes/snapshot.py b/server/books/schema/nodes/snapshot.py index 73459f77..2622fcd8 100644 --- a/server/books/schema/nodes/snapshot.py +++ b/server/books/schema/nodes/snapshot.py @@ -14,6 +14,8 @@ from ...models import Module, Chapter, ChapterSnapshot, ContentBlock class SnapshotContentBlock: def __init__(self, content_block, snapshot): + self.id = content_block.id + self.pk = content_block.pk self.title = content_block.title self.contents = content_block.title self.type = content_block.type @@ -22,6 +24,8 @@ class SnapshotContentBlock: class SnapshotChapter: def __init__(self, chapter, snapshot, description_hidden=False, title_hidden=False): + self.id = chapter.id + self.pk = chapter.pk self.title = chapter.title self.description = chapter.description self.title_hidden = title_hidden diff --git a/server/books/tests/test_content_blocks.py b/server/books/tests/test_content_blocks.py new file mode 100644 index 00000000..ef243910 --- /dev/null +++ b/server/books/tests/test_content_blocks.py @@ -0,0 +1,52 @@ +from books.factories import ModuleFactory, ChapterFactory +from books.models import ContentBlock +from core.tests.base_test import SkillboxTestCase + +CONTENT_BLOCK_QUERY = """ +query ContentBlockQuery($slug: String!) { + module(slug: $slug) { + chapters { + edges { + node { + id + contentBlocks { + edges { + node { + id + title + type + } + } + } + } + } + } + } +} +""" + + +class ContentBlockTestCase(SkillboxTestCase): + def setUp(self) -> None: + self.createDefault() + self.client = self.get_client() + + 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_content_block(self): + result = self.client.execute(CONTENT_BLOCK_QUERY, variables={ + "slug": self.slug + }) + self.assertIsNone(result.get('errors')) + module = result.get('data').get('module') + content_block = module['chapters']['edges'][0]['node']['contentBlocks']['edges'][0]['node'] + self.assertEqual(content_block['title'], 'Title') + self.assertIsNotNone(content_block['type']) + diff --git a/server/books/tests/test_create_snapshot.py b/server/books/tests/test_create_snapshot.py index 7e7c3e5f..9a0a1d6b 100644 --- a/server/books/tests/test_create_snapshot.py +++ b/server/books/tests/test_create_snapshot.py @@ -5,6 +5,7 @@ from graphql_relay import to_global_id, from_global_id from api.schema import schema from books.factories import ModuleFactory, ChapterFactory, ContentBlockFactory from books.models import Snapshot, ChapterSnapshot +from core.tests.base_test import SkillboxTestCase from users.models import User, SchoolClass from users.services import create_users @@ -55,23 +56,16 @@ mutation CreateSnapshot($input: CreateSnapshotInput!) { creator { username } - snapshotChapters { - edges { - node { - id - descriptionHidden - titleHidden - title - description - contentBlocks { - edges { - node { - id - title - } - } - } - } + chapters { + id + descriptionHidden + titleHidden + title + description + contentBlocks { + id + title + hidden } } } @@ -112,12 +106,13 @@ def edges_to_array(entity): return [edge['node'] for edge in entity.get('edges')] -class CreateSnapshotTestCase(TestCase): +class CreateSnapshotTestCase(SkillboxTestCase): def setUp(self): - create_users() + self.createDefault() + self.client = self.get_client() # teacher will create snapshot self.slug = 'some-module' - self.teacher = User.objects.get(username='teacher') + self.module = ModuleFactory(slug=self.slug) self.skillbox_class = SchoolClass.objects.get(name='skillbox') @@ -144,10 +139,6 @@ class CreateSnapshotTestCase(TestCase): # chapter description is hidden for school class X self.chapter.title_hidden_for.add(self.skillbox_class) - request = RequestFactory().get('/') - request.user = self.teacher - self.client = Client(schema=schema, context_value=request) - # we make a snapshot S of the module M # snapshot S looks like module M for school class X @@ -190,7 +181,7 @@ class CreateSnapshotTestCase(TestCase): }) self.assertIsNone(result.get('errors')) snapshot = result.get('data').get('createSnapshot').get('snapshot') - chapter = snapshot.get('snapshotChapters').get('edges')[0]['node'] + chapter = snapshot.get('chapters')[0] self.assertIsNotNone(snapshot.get('created')) self.assertEqual(snapshot.get('creator').get('username'), self.teacher.username) @@ -199,10 +190,15 @@ class CreateSnapshotTestCase(TestCase): self.assertFalse(chapter['descriptionHidden']) _, chapter_id = from_global_id(chapter['id']) self.assertEqual(int(chapter_id), self.chapter.id) - content_blocks = [edge['node'] for edge in chapter['contentBlocks']['edges']] - self.assertEqual(len(content_blocks), 2) - self.assertEqual(content_blocks[0]['title'], self.title_visible) - self.assertEqual(content_blocks[1]['title'], self.title_custom) + content_blocks = chapter['contentBlocks'] + self.assertEqual(len(content_blocks), 3) + visible, hidden, custom = content_blocks + self.assertEqual(visible['title'], self.title_visible) + self.assertEqual(visible['hidden'], False) + self.assertEqual(hidden['title'], self.title_hidden) + self.assertEqual(hidden['hidden'], True) + self.assertEqual(custom['title'], self.title_custom) + self.assertEqual(custom['hidden'], False) self.assertEqual(ChapterSnapshot.objects.count(), 2) def test_apply_snapshot(self): diff --git a/server/core/tests/base_test.py b/server/core/tests/base_test.py new file mode 100644 index 00000000..5e3d1662 --- /dev/null +++ b/server/core/tests/base_test.py @@ -0,0 +1,19 @@ +from django.test import TestCase, RequestFactory +from graphene.test import Client + +from api.schema import schema +from users.models import User +from users.services import create_users + + +class SkillboxTestCase(TestCase): + def createDefault(self) -> None: + create_users() + self.teacher = User.objects.get(username='teacher') + + def get_client(self, user=None) -> Client: + request = RequestFactory().get('/') + if user is None: + user = self.teacher + request.user = user + return Client(schema=schema, context_value=request) diff --git a/server/schema.graphql b/server/schema.graphql index 99986780..30c4e294 100644 --- a/server/schema.graphql +++ b/server/schema.graphql @@ -303,7 +303,7 @@ interface ContentBlockInterface { id: ID! title: String contents: GenericStreamFieldType - type: ContentBlockType + type: String } type ContentBlockNode implements ContentBlockInterface { @@ -313,7 +313,7 @@ type ContentBlockNode implements ContentBlockInterface { visibleFor(offset: Int, before: String, after: String, first: Int, last: Int, name: String): SchoolClassNodeConnection! userCreated: Boolean! contents: GenericStreamFieldType - type: ContentBlockType + type: String id: ID! mine: Boolean bookmarks: [ContentBlockBookmarkNode] @@ -329,14 +329,6 @@ type ContentBlockNodeEdge { cursor: String! } -enum ContentBlockType { - NORMAL - BASE_COMMUNICATION - TASK - BASE_SOCIETY - BASE_INTERDISCIPLINARY -} - input ContentElementInput { id: String type: InputTypes! @@ -924,7 +916,7 @@ type SnapshotContentBlockNode implements ContentBlockInterface { id: ID! title: String contents: GenericStreamFieldType - type: ContentBlockType + type: String hidden: Boolean }