From 45f99385d319a27f55f042ad9789b311aba34018 Mon Sep 17 00:00:00 2001 From: Ramon Wenger Date: Wed, 5 May 2021 19:47:06 +0200 Subject: [PATCH] Fix unit tests --- .../tests/test_custom_assignments.py | 9 +- server/books/schema/interfaces/chapter.py | 2 +- .../books/schema/interfaces/contentblock.py | 2 +- server/books/schema/nodes/chapter.py | 59 ++------ server/books/schema/nodes/content.py | 14 +- server/books/schema/nodes/snapshot.py | 6 +- server/books/schema/queries.py | 5 +- .../tests/test_content_block_visibility.py | 11 +- server/books/tests/test_content_blocks.py | 12 +- .../test_copy_visibility_for_other_class.py | 126 ++++++++---------- server/books/tests/test_create_snapshot.py | 35 ++--- server/books/tests/test_own_content_blocks.py | 14 +- server/core/settings.py | 4 +- server/objectives/schema.py | 5 +- 14 files changed, 106 insertions(+), 198 deletions(-) diff --git a/server/assignments/tests/test_custom_assignments.py b/server/assignments/tests/test_custom_assignments.py index 94b739d8..435a394b 100644 --- a/server/assignments/tests/test_custom_assignments.py +++ b/server/assignments/tests/test_custom_assignments.py @@ -56,11 +56,7 @@ class CustomAssignmentTestCase(TestCase): edges { node { contentBlocks { - edges { - node { - contents - } - } + contents } } } @@ -78,8 +74,7 @@ class CustomAssignmentTestCase(TestCase): @staticmethod def get_first_contents(result): - return result.get('data').get('module').get('chapters').get('edges')[0].get('node').get('contentBlocks').get( - 'edges')[0].get('node').get('contents') + return result.get('data').get('module').get('chapters').get('edges')[0].get('node').get('contentBlocks')[0].get('contents') def test_module_query(self): result = self.query_module() diff --git a/server/books/schema/interfaces/chapter.py b/server/books/schema/interfaces/chapter.py index 13d028f2..6fc855bf 100644 --- a/server/books/schema/interfaces/chapter.py +++ b/server/books/schema/interfaces/chapter.py @@ -2,6 +2,6 @@ import graphene from graphene import relay from graphene_django.filter import DjangoFilterConnectionField -class ChapterInterface(relay.Node): +class ChapterInterface(graphene.Interface): description = graphene.String() title = graphene.String() diff --git a/server/books/schema/interfaces/contentblock.py b/server/books/schema/interfaces/contentblock.py index 0e3f4b38..a2f1d41a 100644 --- a/server/books/schema/interfaces/contentblock.py +++ b/server/books/schema/interfaces/contentblock.py @@ -4,7 +4,7 @@ from graphene import relay from api.graphene_wagtail import GenericStreamFieldType -class ContentBlockInterface(relay.Node): +class ContentBlockInterface(graphene.Interface): title = graphene.String() contents = GenericStreamFieldType() type = graphene.String() diff --git a/server/books/schema/nodes/chapter.py b/server/books/schema/nodes/chapter.py index 33e40b8c..20bb6af0 100644 --- a/server/books/schema/nodes/chapter.py +++ b/server/books/schema/nodes/chapter.py @@ -2,11 +2,8 @@ import graphene from django.db.models import Q from graphene import relay from graphene_django import DjangoObjectType -from graphene_django.filter import DjangoFilterConnectionField -from graphql_relay import to_global_id from books.models import Chapter, ContentBlock -from books.models.snapshot import ChapterSnapshot from books.schema.interfaces import ChapterInterface from notes.models import ChapterBookmark from notes.schema import ChapterBookmarkNode @@ -15,6 +12,8 @@ from notes.schema import ChapterBookmarkNode class ChapterNode(DjangoObjectType): bookmark = graphene.Field(ChapterBookmarkNode) content_blocks = graphene.List('books.schema.nodes.ContentBlockNode') + title_hidden_for = graphene.List('users.schema.SchoolClassNode') + description_hidden_for = graphene.List('users.schema.SchoolClassNode') class Meta: model = Chapter @@ -24,7 +23,7 @@ class ChapterNode(DjangoObjectType): filter_fields = [ 'slug', 'title', ] - interfaces = (ChapterInterface,) + interfaces = (relay.Node, ChapterInterface) def resolve_content_blocks(self, info, **kwargs): user = info.context.user @@ -51,52 +50,10 @@ class ChapterNode(DjangoObjectType): chapter=self ).first() - -class ChapterInSnapshotNode(DjangoObjectType): - title_hidden = graphene.Boolean() - description_hidden = graphene.Boolean() - title = graphene.String() - description = graphene.String() - id = graphene.ID(required=True) - - class Meta: - model = ChapterSnapshot - only_fields = '__all__' - filter_fields = [ - 'id', - ] - interfaces = (ChapterInterface,) + @staticmethod + def resolve_title_hidden_for(parent: Chapter, info, **kwargs): + return parent.title_hidden_for.all() @staticmethod - def resolve_title_hidden(parent, info): - return parent.title_hidden - - @staticmethod - def resolve_description_hidden(parent, info): - return parent.description_hidden - - @staticmethod - def resolve_title(parent, info): - return parent.chapter.title - - @staticmethod - def resolve_description(parent, info): - return parent.chapter.description - - @staticmethod - def resolve_content_blocks(parent, info, **kwargs): - snapshot = parent.snapshot - - user_created = Q(user_created=True) - hidden_for_snapshot = Q(hidden_for_snapshots=snapshot) - custom_hidden = Q(contentblocksnapshot__hidden=True) - - qs = ContentBlock.get_by_parent(parent.chapter) \ - .exclude(user_created) \ - .exclude(hidden_for_snapshot) \ - .exclude(custom_hidden) - - return qs - - def resolve_id(self, *args): - return to_global_id('SnapshotChapterNode', self.chapter.pk) + def resolve_description_hidden_for(parent: Chapter, info, **kwargs): + return parent.description_hidden_for.all() diff --git a/server/books/schema/nodes/content.py b/server/books/schema/nodes/content.py index fcba199e..33013b32 100644 --- a/server/books/schema/nodes/content.py +++ b/server/books/schema/nodes/content.py @@ -1,10 +1,12 @@ import graphene +from graphene import relay from graphene_django import DjangoObjectType from books.models import ContentBlock from books.schema.interfaces.contentblock import ContentBlockInterface from books.utils import are_solutions_enabled_for from core.logger import get_logger +from core.mixins import HiddenAndVisibleForMixin from notes.models import ContentBlockBookmark from notes.schema import ContentBlockBookmarkNode from rooms.models import ModuleRoomSlug @@ -34,11 +36,9 @@ def is_solution_and_hidden_for_user(type, user, module): return type == 'solution' and not (are_solutions_enabled_for(user, module) or user.is_teacher()) -class ContentBlockNode(DjangoObjectType): +class ContentBlockNode(DjangoObjectType, HiddenAndVisibleForMixin): mine = graphene.Boolean() bookmarks = graphene.List(ContentBlockBookmarkNode) - hidden_for = graphene.List('users.schema.SchoolClassNode') - visible_for = graphene.List('users.schema.SchoolClassNode') class Meta: model = ContentBlock @@ -48,7 +48,7 @@ class ContentBlockNode(DjangoObjectType): filter_fields = [ 'slug', 'title', ] - interfaces = (ContentBlockInterface,) + interfaces = (relay.Node, ContentBlockInterface,) convert_choices_to_enum = False def resolve_mine(parent, info, **kwargs): @@ -78,12 +78,6 @@ class ContentBlockNode(DjangoObjectType): content_block=self ) - def resolve_hidden_for(parent, info, **kwargs): - return parent.hidden_for.all() - - def resolve_visible_for(parent, info, **kwargs): - return parent.visible_for.all() - def process_module_room_slug_block(content): if content['type'] == 'module_room_slug': diff --git a/server/books/schema/nodes/snapshot.py b/server/books/schema/nodes/snapshot.py index 3372749c..1b2df07c 100644 --- a/server/books/schema/nodes/snapshot.py +++ b/server/books/schema/nodes/snapshot.py @@ -4,8 +4,6 @@ from graphene import relay, ObjectType from graphene_django import DjangoObjectType from graphene_django.filter import DjangoFilterConnectionField -from . import ChapterInSnapshotNode - from books.models.snapshot import Snapshot from ..interfaces import ModuleInterface, ChapterInterface from ..interfaces.contentblock import ContentBlockInterface @@ -47,14 +45,14 @@ class SnapshotChapter: class SnapshotContentBlockNode(ObjectType): class Meta: - interfaces = (ContentBlockInterface,) + interfaces = (relay.Node, ContentBlockInterface,) hidden = graphene.Boolean() class SnapshotChapterNode(ObjectType): class Meta: - interfaces = (ChapterInterface,) + interfaces = (relay.Node, ChapterInterface,) content_blocks = graphene.List(SnapshotContentBlockNode) description_hidden = graphene.Boolean() diff --git a/server/books/schema/queries.py b/server/books/schema/queries.py index 2923442f..43fc75ea 100644 --- a/server/books/schema/queries.py +++ b/server/books/schema/queries.py @@ -4,10 +4,9 @@ from graphene_django.filter import DjangoFilterConnectionField from api.utils import get_object from core.logger import get_logger - -from ..models import Book, Topic, Module, Chapter, Snapshot -from .nodes import ContentBlockNode, ChapterNode, ModuleNode, TopicNode, SnapshotNode from .connections import TopicConnection, ModuleConnection +from .nodes import ContentBlockNode, ChapterNode, ModuleNode, TopicNode, SnapshotNode +from ..models import Book, Topic, Module, Chapter, Snapshot logger = get_logger(__name__) diff --git a/server/books/tests/test_content_block_visibility.py b/server/books/tests/test_content_block_visibility.py index 0de602cd..501a77e5 100644 --- a/server/books/tests/test_content_block_visibility.py +++ b/server/books/tests/test_content_block_visibility.py @@ -3,8 +3,8 @@ from graphene.test import Client from graphql_relay import to_global_id from api.schema import schema -from books.models import ContentBlock, Chapter from books.factories import ModuleFactory +from books.models import ContentBlock, Chapter from users.factories import SchoolClassFactory from users.models import User from users.services import create_users @@ -29,7 +29,6 @@ class ContentBlocksVisibleForTeachers(TestCase): user_content_block.visible_for.add(school_class) user_content_block.save() - teacher_request = RequestFactory().get('/') teacher_request.user = teacher self.teacher_client = Client(schema=schema, context_value=teacher_request) @@ -49,7 +48,7 @@ class ContentBlocksVisibleForTeachers(TestCase): 'id': self.chapter }) self.assertIsNone(result.get('errors')) - self.assertEqual(len(result.get('data').get('chapter').get('contentBlocks').get('edges')), 2) + self.assertEqual(len(result.get('data').get('chapter').get('contentBlocks')), 2) def test_teacher_created_content_block(self): self.assertEqual(ContentBlock.objects.count(), 2) @@ -58,11 +57,7 @@ class ContentBlocksVisibleForTeachers(TestCase): query ChapterQuery($id: ID!) { chapter(id: $id) { contentBlocks { - edges { - node { - id - } - } + id } } } diff --git a/server/books/tests/test_content_blocks.py b/server/books/tests/test_content_blocks.py index ef243910..c8ea52ee 100644 --- a/server/books/tests/test_content_blocks.py +++ b/server/books/tests/test_content_blocks.py @@ -10,13 +10,9 @@ query ContentBlockQuery($slug: String!) { node { id contentBlocks { - edges { - node { - id - title - type - } - } + id + title + type } } } @@ -46,7 +42,7 @@ class ContentBlockTestCase(SkillboxTestCase): }) self.assertIsNone(result.get('errors')) module = result.get('data').get('module') - content_block = module['chapters']['edges'][0]['node']['contentBlocks']['edges'][0]['node'] + content_block = module['chapters']['edges'][0]['node']['contentBlocks'][0] self.assertEqual(content_block['title'], 'Title') self.assertIsNotNone(content_block['type']) diff --git a/server/books/tests/test_copy_visibility_for_other_class.py b/server/books/tests/test_copy_visibility_for_other_class.py index 145b0462..74342dd5 100644 --- a/server/books/tests/test_copy_visibility_for_other_class.py +++ b/server/books/tests/test_copy_visibility_for_other_class.py @@ -20,48 +20,38 @@ fragment SchoolClassFragment on SchoolClassNode { } """ -EDGES_FRAGMENT = SCHOOL_CLASS_FRAGMENT + """ -fragment SchoolClassNodeFragment on SchoolClassNodeConnection { - edges { - node { - ...SchoolClassFragment - } - } -} -""" - -CONTENT_BLOCK_QUERY = EDGES_FRAGMENT + """ +CONTENT_BLOCK_QUERY = SCHOOL_CLASS_FRAGMENT + """ query ContentBlockQuery($id: ID!) { contentBlock(id: $id) { hiddenFor { - ...SchoolClassNodeFragment + ...SchoolClassFragment } visibleFor { - ...SchoolClassNodeFragment + ...SchoolClassFragment } } } """ -CHAPTER_QUERY = EDGES_FRAGMENT + """ +CHAPTER_QUERY = SCHOOL_CLASS_FRAGMENT + """ query ChapterQuery($id: ID!) { chapter(id: $id) { id titleHiddenFor { - ...SchoolClassNodeFragment + ...SchoolClassFragment } descriptionHiddenFor { - ...SchoolClassNodeFragment + ...SchoolClassFragment } } } """ -OBJECTIVE_GROUP_QUERY = EDGES_FRAGMENT + """ +OBJECTIVE_GROUP_QUERY = SCHOOL_CLASS_FRAGMENT + """ query ObjectiveGroupQuery($id: ID!) { objectiveGroup(id: $id) { hiddenFor { - ...SchoolClassNodeFragment + ...SchoolClassFragment } objectives { edges { @@ -69,10 +59,10 @@ query ObjectiveGroupQuery($id: ID!) { id text hiddenFor { - ...SchoolClassNodeFragment + ...SchoolClassFragment } visibleFor { - ...SchoolClassNodeFragment + ...SchoolClassFragment } } } @@ -193,61 +183,61 @@ class CopyVisibilityForClassesTestCase(TestCase): def _test_in_sync(self): # the hidden block is hidden for both now hidden_result = self._get_result(CONTENT_BLOCK_QUERY, self.teacher_client, self.hidden_content_block) - hidden_for = hidden_result.get('data').get('contentBlock').get('hiddenFor').get('edges') - self.assertTrue(TEMPLATE_CLASS_NAME in map(lambda x: x['node']['name'], hidden_for)) - self.assertTrue(SYNC_CLASS_NAME in map(lambda x: x['node']['name'], hidden_for)) + hidden_for = hidden_result.get('data').get('contentBlock').get('hiddenFor') + self.assertTrue(TEMPLATE_CLASS_NAME in map(lambda x: x['name'], hidden_for)) + self.assertTrue(SYNC_CLASS_NAME in map(lambda x: x['name'], hidden_for)) # the other hidden block is hidden for no one now other_hidden_result = self._get_result(CONTENT_BLOCK_QUERY, self.teacher_client, self.other_hidden_content_block) - hidden_for = other_hidden_result.get('data').get('contentBlock').get('hiddenFor').get('edges') + hidden_for = other_hidden_result.get('data').get('contentBlock').get('hiddenFor') self.assertEqual(len(hidden_for), 0) # the default block is still hidden for no one default_result = self._get_result(CONTENT_BLOCK_QUERY, self.teacher_client, self.default_content_block) - hidden_for = default_result.get('data').get('contentBlock').get('hiddenFor').get('edges') + hidden_for = default_result.get('data').get('contentBlock').get('hiddenFor') self.assertEqual(len(hidden_for), 0) # the custom block is visible for both custom_result = self._get_result(CONTENT_BLOCK_QUERY, self.teacher_client, self.custom_content_block) - visible_for = custom_result.get('data').get('contentBlock').get('visibleFor').get('edges') - self.assertTrue(TEMPLATE_CLASS_NAME in map(lambda x: x['node']['name'], visible_for)) - self.assertTrue(SYNC_CLASS_NAME in map(lambda x: x['node']['name'], visible_for)) + visible_for = custom_result.get('data').get('contentBlock').get('visibleFor') + self.assertTrue(TEMPLATE_CLASS_NAME in map(lambda x: x['name'], visible_for)) + self.assertTrue(SYNC_CLASS_NAME in map(lambda x: x['name'], visible_for)) # the other custom block is visible for no one other_custom_result = self._get_result(CONTENT_BLOCK_QUERY, self.teacher_client, self.other_custom_content_block) - visible_for = other_custom_result.get('data').get('contentBlock').get('visibleFor').get('edges') + visible_for = other_custom_result.get('data').get('contentBlock').get('visibleFor') self.assertEqual(len(visible_for), 0) def test_hidden_for_and_visible_for_set_correctly(self): self.assertEqual(ContentBlock.objects.count(), 5) hidden_result = self._get_result(CONTENT_BLOCK_QUERY, self.teacher_client, self.hidden_content_block) - hidden_for = hidden_result.get('data').get('contentBlock').get('hiddenFor').get('edges') - self.assertTrue(TEMPLATE_CLASS_NAME in map(lambda x: x['node']['name'], hidden_for)) - self.assertFalse(SYNC_CLASS_NAME in map(lambda x: x['node']['name'], hidden_for)) + hidden_for = hidden_result.get('data').get('contentBlock').get('hiddenFor') + self.assertTrue(TEMPLATE_CLASS_NAME in map(lambda x: x['name'], hidden_for)) + self.assertFalse(SYNC_CLASS_NAME in map(lambda x: x['name'], hidden_for)) other_hidden_result = self._get_result(CONTENT_BLOCK_QUERY, self.teacher_client, self.other_hidden_content_block) - hidden_for = other_hidden_result.get('data').get('contentBlock').get('hiddenFor').get('edges') - self.assertFalse(TEMPLATE_CLASS_NAME in map(lambda x: x['node']['name'], hidden_for)) - self.assertTrue(SYNC_CLASS_NAME in map(lambda x: x['node']['name'], hidden_for)) + hidden_for = other_hidden_result.get('data').get('contentBlock').get('hiddenFor') + self.assertFalse(TEMPLATE_CLASS_NAME in map(lambda x: x['name'], hidden_for)) + self.assertTrue(SYNC_CLASS_NAME in map(lambda x: x['name'], hidden_for)) default_result = self._get_result(CONTENT_BLOCK_QUERY, self.teacher_client, self.default_content_block) - hidden_for = default_result.get('data').get('contentBlock').get('hiddenFor').get('edges') + hidden_for = default_result.get('data').get('contentBlock').get('hiddenFor') self.assertEqual(len(hidden_for), 0) custom_result = self._get_result(CONTENT_BLOCK_QUERY, self.teacher_client, self.custom_content_block) - visible_for = custom_result.get('data').get('contentBlock').get('visibleFor').get('edges') - self.assertTrue(TEMPLATE_CLASS_NAME in map(lambda x: x['node']['name'], visible_for)) - self.assertFalse(SYNC_CLASS_NAME in map(lambda x: x['node']['name'], visible_for)) + visible_for = custom_result.get('data').get('contentBlock').get('visibleFor') + self.assertTrue(TEMPLATE_CLASS_NAME in map(lambda x: x['name'], visible_for)) + self.assertFalse(SYNC_CLASS_NAME in map(lambda x: x['name'], visible_for)) other_custom_result = self._get_result(CONTENT_BLOCK_QUERY, self.teacher_client, self.other_custom_content_block) - visible_for = other_custom_result.get('data').get('contentBlock').get('visibleFor').get('edges') - self.assertFalse(TEMPLATE_CLASS_NAME in map(lambda x: x['node']['name'], visible_for)) - self.assertTrue(SYNC_CLASS_NAME in map(lambda x: x['node']['name'], visible_for)) + visible_for = other_custom_result.get('data').get('contentBlock').get('visibleFor') + self.assertFalse(TEMPLATE_CLASS_NAME in map(lambda x: x['name'], visible_for)) + self.assertTrue(SYNC_CLASS_NAME in map(lambda x: x['name'], visible_for)) def test_syncs_correctly(self): self.module.sync_from_school_class(self.template_school_class, self.school_class_to_be_synced) @@ -269,24 +259,24 @@ class CopyVisibilityForClassesTestCase(TestCase): result = self.student1_client.execute(query, variables=variables) self.assertIsNone(result.get('errors')) chapter = result.get('data').get('chapter') - title_hidden_for = chapter.get('titleHiddenFor').get('edges') - description_hidden_for = chapter.get('descriptionHiddenFor').get('edges') - self.assertTrue(TEMPLATE_CLASS_NAME in map(lambda x: x['node']['name'], title_hidden_for)) - self.assertTrue(TEMPLATE_CLASS_NAME in map(lambda x: x['node']['name'], description_hidden_for)) - self.assertTrue(SYNC_CLASS_NAME not in map(lambda x: x['node']['name'], title_hidden_for)) - self.assertTrue(SYNC_CLASS_NAME not in map(lambda x: x['node']['name'], description_hidden_for)) + title_hidden_for = chapter.get('titleHiddenFor') + description_hidden_for = chapter.get('descriptionHiddenFor') + self.assertTrue(TEMPLATE_CLASS_NAME in map(lambda x: x['name'], title_hidden_for)) + self.assertTrue(TEMPLATE_CLASS_NAME in map(lambda x: x['name'], description_hidden_for)) + self.assertTrue(SYNC_CLASS_NAME not in map(lambda x: x['name'], title_hidden_for)) + self.assertTrue(SYNC_CLASS_NAME not in map(lambda x: x['name'], description_hidden_for)) self._execute_sync() result = self.student1_client.execute(query, variables=variables) self.assertIsNone(result.get('errors')) chapter = result.get('data').get('chapter') - title_hidden_for = chapter.get('titleHiddenFor').get('edges') - description_hidden_for = chapter.get('descriptionHiddenFor').get('edges') - self.assertTrue(TEMPLATE_CLASS_NAME in map(lambda x: x['node']['name'], title_hidden_for)) - self.assertTrue(TEMPLATE_CLASS_NAME in map(lambda x: x['node']['name'], description_hidden_for)) - self.assertTrue(SYNC_CLASS_NAME in map(lambda x: x['node']['name'], title_hidden_for)) - self.assertTrue(SYNC_CLASS_NAME in map(lambda x: x['node']['name'], description_hidden_for)) + title_hidden_for = chapter.get('titleHiddenFor') + description_hidden_for = chapter.get('descriptionHiddenFor') + self.assertTrue(TEMPLATE_CLASS_NAME in map(lambda x: x['name'], title_hidden_for)) + self.assertTrue(TEMPLATE_CLASS_NAME in map(lambda x: x['name'], description_hidden_for)) + self.assertTrue(SYNC_CLASS_NAME in map(lambda x: x['name'], title_hidden_for)) + self.assertTrue(SYNC_CLASS_NAME in map(lambda x: x['name'], description_hidden_for)) def _objective_group_query(self): query = OBJECTIVE_GROUP_QUERY @@ -303,29 +293,29 @@ class CopyVisibilityForClassesTestCase(TestCase): def test_objective_group_visibility(self): query, variables = self._objective_group_query() objective_group = self._get_objective_group(self.student1_client, query, variables) - hidden_for = objective_group.get('hiddenFor').get('edges') - self.assertTrue(TEMPLATE_CLASS_NAME in map(lambda x: x['node']['name'], hidden_for)) - self.assertTrue(SYNC_CLASS_NAME not in map(lambda x: x['node']['name'], hidden_for)) + hidden_for = objective_group.get('hiddenFor') + self.assertTrue(TEMPLATE_CLASS_NAME in map(lambda x: x['name'], hidden_for)) + self.assertTrue(SYNC_CLASS_NAME not in map(lambda x: x['name'], hidden_for)) self._execute_sync() objective_group = self._get_objective_group(self.student1_client, query, variables) - hidden_for = objective_group.get('hiddenFor').get('edges') - self.assertTrue(TEMPLATE_CLASS_NAME in map(lambda x: x['node']['name'], hidden_for)) - self.assertTrue(SYNC_CLASS_NAME in map(lambda x: x['node']['name'], hidden_for)) + hidden_for = objective_group.get('hiddenFor') + self.assertTrue(TEMPLATE_CLASS_NAME in map(lambda x: x['name'], hidden_for)) + self.assertTrue(SYNC_CLASS_NAME in map(lambda x: x['name'], hidden_for)) def test_objective_visibility(self): query, variables = self._objective_group_query() objective_group = self._get_objective_group(self.student2_client, query, variables) - objective = objective_group.get('objectives').get('edges')[0]['node'] - hidden_for = objective.get('hiddenFor').get('edges') - self.assertTrue(TEMPLATE_CLASS_NAME in map(lambda x: x['node']['name'], hidden_for)) - self.assertTrue(SYNC_CLASS_NAME not in map(lambda x: x['node']['name'], hidden_for)) + objective = objective_group.get('objectives')['edges'][0]['node'] + hidden_for = objective.get('hiddenFor') + self.assertTrue(TEMPLATE_CLASS_NAME in map(lambda x: x['name'], hidden_for)) + self.assertTrue(SYNC_CLASS_NAME not in map(lambda x: x['name'], hidden_for)) self._execute_sync() objective_group = self._get_objective_group(self.student2_client, query, variables) - objective = objective_group.get('objectives').get('edges')[0]['node'] - hidden_for = objective.get('hiddenFor').get('edges') - self.assertTrue(TEMPLATE_CLASS_NAME in map(lambda x: x['node']['name'], hidden_for)) - self.assertTrue(SYNC_CLASS_NAME in map(lambda x: x['node']['name'], hidden_for)) + objective = objective_group.get('objectives')['edges'][0]['node'] + hidden_for = objective.get('hiddenFor') + self.assertTrue(TEMPLATE_CLASS_NAME in map(lambda x: x['name'], hidden_for)) + self.assertTrue(SYNC_CLASS_NAME in map(lambda x: x['name'], hidden_for)) diff --git a/server/books/tests/test_create_snapshot.py b/server/books/tests/test_create_snapshot.py index 9a0a1d6b..440e555a 100644 --- a/server/books/tests/test_create_snapshot.py +++ b/server/books/tests/test_create_snapshot.py @@ -1,4 +1,4 @@ -from django.test import TestCase, RequestFactory +from django.test import RequestFactory from graphene.test import Client from graphql_relay import to_global_id, from_global_id @@ -7,7 +7,6 @@ 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 MODULE_QUERY = """ query ModulesQuery($slug: String!) { @@ -19,26 +18,14 @@ query ModulesQuery($slug: String!) { node { id contentBlocks { - edges { - node { - id - title - visibleFor { - edges { - node { - name - } - } - } - hiddenFor { - edges { - node { - name - } - } - } - } + id + title + visibleFor { + name } + hiddenFor { + name + } } } } @@ -150,7 +137,7 @@ class CreateSnapshotTestCase(SkillboxTestCase): module = result.get('data').get('module') chapter = edges_to_array(module.get('chapters'))[0] self.assertIsNotNone(chapter) - content_blocks = edges_to_array(chapter.get('contentBlocks')) + content_blocks = chapter.get('contentBlocks') content_block_titles = [node['title'] for node in content_blocks] self.assertTrue(self.title_visible in content_block_titles) self.assertTrue(self.title_hidden in content_block_titles) @@ -162,11 +149,11 @@ class CreateSnapshotTestCase(SkillboxTestCase): # check if hidden node is hidden for this school class self.assertTrue( school_class_name in [school_class['name'] for school_class in - edges_to_array(hidden_node.get('hiddenFor'))]) + hidden_node.get('hiddenFor')]) # check if the custom node is visible for this school class self.assertTrue( school_class_name in [school_class['name'] for school_class in - edges_to_array(custom_node.get('visibleFor'))]) + custom_node.get('visibleFor')]) def test_setup(self): # make sure everything is setup correctly diff --git a/server/books/tests/test_own_content_blocks.py b/server/books/tests/test_own_content_blocks.py index 1f427e93..a69ebb16 100644 --- a/server/books/tests/test_own_content_blocks.py +++ b/server/books/tests/test_own_content_blocks.py @@ -37,12 +37,8 @@ class OwnContentTestCase(TestCase): id title contentBlocks { - edges { - node { - id - title - } - } + id + title } } } @@ -51,14 +47,14 @@ class OwnContentTestCase(TestCase): "id": self.chapter_id }) self.assertIsNone(result.get('errors')) - self.assertEqual(len(result.get('data').get('chapter').get('contentBlocks').get('edges')), 1) + self.assertEqual(len(result.get('data').get('chapter').get('contentBlocks')), 1) custom_content_block = ContentBlock(title='own', slug='own', user_created=True, owner=self.user) self.chapter.specific.add_child(instance=custom_content_block) result = self.client.execute(chapterQuery, variables={ "id": self.chapter_id }) - self.assertEqual(len(result.get('data').get('chapter').get('contentBlocks').get('edges')), 2) + self.assertEqual(len(result.get('data').get('chapter').get('contentBlocks')), 2) for school_class in self.user.school_classes.all(): custom_content_block.visible_for.add(school_class) @@ -66,5 +62,5 @@ class OwnContentTestCase(TestCase): result = self.client.execute(chapterQuery, variables={ "id": self.chapter_id }) - self.assertEqual(len(result.get('data').get('chapter').get('contentBlocks').get('edges')), 2) + self.assertEqual(len(result.get('data').get('chapter').get('contentBlocks')), 2) diff --git a/server/core/settings.py b/server/core/settings.py index f89f243c..db2e0cb9 100644 --- a/server/core/settings.py +++ b/server/core/settings.py @@ -372,8 +372,8 @@ GRAPHENE = { # http://docs.wagtail.io/en/v2.1/advanced_topics/settings.html?highlight=urls WAGTAIL_SITE_NAME = 'skillbox' -GRAPHQL_QUERIES_DIR = os.path.join(BASE_DIR, '..', 'client', 'src', 'graphql', 'gql') -GRAPHQL_MUTATIONS_DIR = os.path.join(GRAPHQL_QUERIES_DIR, 'mutations') +GRAPHQL_QUERIES_DIR = os.path.join(BASE_DIR, '..', 'client', 'src', 'graphql', 'gql', 'queries') +GRAPHQL_MUTATIONS_DIR = os.path.join(GRAPHQL_QUERIES_DIR, '../mutations') # Sendgrid Config diff --git a/server/objectives/schema.py b/server/objectives/schema.py index 2872f8b1..d2f203a9 100644 --- a/server/objectives/schema.py +++ b/server/objectives/schema.py @@ -4,10 +4,11 @@ from graphene import relay from graphene_django import DjangoObjectType from graphene_django.filter import DjangoFilterConnectionField +from core.mixins import HiddenAndVisibleForMixin, HiddenForMixin from objectives.models import ObjectiveGroup, Objective -class ObjectiveGroupNode(DjangoObjectType): +class ObjectiveGroupNode(DjangoObjectType, HiddenForMixin): pk = graphene.Int() display_title = graphene.String() @@ -36,7 +37,7 @@ class ObjectiveGroupNode(DjangoObjectType): return self.objectives.filter(objectives_from_publisher | objectives_from_teacher) -class ObjectiveNode(DjangoObjectType): +class ObjectiveNode(DjangoObjectType, HiddenAndVisibleForMixin): pk = graphene.Int() user_created = graphene.Boolean() mine = graphene.Boolean()