diff --git a/client/src/graphql/gql/fragments/roomParts.gql b/client/src/graphql/gql/fragments/roomParts.gql index a2c15275..8ecf7f93 100644 --- a/client/src/graphql/gql/fragments/roomParts.gql +++ b/client/src/graphql/gql/fragments/roomParts.gql @@ -6,6 +6,7 @@ fragment RoomParts on RoomNode { entryCount appearance description + restricted schoolClass { ...SchoolClassParts } diff --git a/client/src/graphql/gql/mutations/addRoom.gql b/client/src/graphql/gql/mutations/rooms/addRoom.gql similarity index 100% rename from client/src/graphql/gql/mutations/addRoom.gql rename to client/src/graphql/gql/mutations/rooms/addRoom.gql diff --git a/client/src/graphql/gql/mutations/addRoomEntry.gql b/client/src/graphql/gql/mutations/rooms/addRoomEntry.gql similarity index 100% rename from client/src/graphql/gql/mutations/addRoomEntry.gql rename to client/src/graphql/gql/mutations/rooms/addRoomEntry.gql diff --git a/client/src/graphql/gql/mutations/deleteRoom.gql b/client/src/graphql/gql/mutations/rooms/deleteRoom.gql similarity index 100% rename from client/src/graphql/gql/mutations/deleteRoom.gql rename to client/src/graphql/gql/mutations/rooms/deleteRoom.gql diff --git a/client/src/graphql/gql/mutations/deleteRoomEntry.gql b/client/src/graphql/gql/mutations/rooms/deleteRoomEntry.gql similarity index 100% rename from client/src/graphql/gql/mutations/deleteRoomEntry.gql rename to client/src/graphql/gql/mutations/rooms/deleteRoomEntry.gql diff --git a/client/src/graphql/gql/mutations/updateRoom.gql b/client/src/graphql/gql/mutations/rooms/updateRoom.gql similarity index 100% rename from client/src/graphql/gql/mutations/updateRoom.gql rename to client/src/graphql/gql/mutations/rooms/updateRoom.gql diff --git a/client/src/graphql/gql/mutations/updateRoomEntry.gql b/client/src/graphql/gql/mutations/rooms/updateRoomEntry.gql similarity index 100% rename from client/src/graphql/gql/mutations/updateRoomEntry.gql rename to client/src/graphql/gql/mutations/rooms/updateRoomEntry.gql diff --git a/client/src/graphql/gql/mutations/rooms/updateRoomVisibility.gql b/client/src/graphql/gql/mutations/rooms/updateRoomVisibility.gql new file mode 100644 index 00000000..e92f7e16 --- /dev/null +++ b/client/src/graphql/gql/mutations/rooms/updateRoomVisibility.gql @@ -0,0 +1,9 @@ +mutation UpdateRoomVisibility($input: UpdateRoomVisibilityInput!) { + updateRoomVisibility(input: $input) { + success + room { + id + restricted + } + } +} diff --git a/server/rooms/migrations/0010_room_restricted.py b/server/rooms/migrations/0010_room_restricted.py new file mode 100644 index 00000000..37235d8d --- /dev/null +++ b/server/rooms/migrations/0010_room_restricted.py @@ -0,0 +1,18 @@ +# Generated by Django 2.2.24 on 2021-08-27 13:45 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('rooms', '0009_comment'), + ] + + operations = [ + migrations.AddField( + model_name='room', + name='restricted', + field=models.BooleanField(default=False), + ), + ] diff --git a/server/rooms/models.py b/server/rooms/models.py index 0ea27335..d8d7d0e8 100644 --- a/server/rooms/models.py +++ b/server/rooms/models.py @@ -17,6 +17,7 @@ class Room(TitleSlugDescriptionModel): related_name='rooms') appearance = models.CharField(blank=True, null=False, max_length=255) user_created = models.BooleanField(blank=False, null=False, default=True) + restricted = models.BooleanField(default=False) def __str__(self): return f'{self.title} - {self.school_class}' diff --git a/server/rooms/mutations.py b/server/rooms/mutations.py index b3146595..91401fc5 100644 --- a/server/rooms/mutations.py +++ b/server/rooms/mutations.py @@ -8,7 +8,7 @@ from rooms.inputs import UpdateRoomArgument, AddRoomArgument, AddRoomEntryArgume from rooms.models import Comment, Room, RoomEntry from rooms.schema import CommentNode, RoomNode, RoomEntryNode from rooms.serializers import RoomSerializer, RoomEntrySerializer -from users.models import SchoolClass +from users.models import SchoolClass, SchoolClassMember class MutateRoom(relay.ClientIDMutation): @@ -144,6 +144,28 @@ class DeleteRoomEntry(relay.ClientIDMutation): return cls(success=True, room_id=room_id, room_slug=room_slug) +class UpdateRoomVisibility(relay.ClientIDMutation): + class Input: + id = graphene.ID(required=True) + restricted = graphene.Boolean(required=True) + + success = graphene.Boolean() + room = graphene.Field(RoomNode) + + @classmethod + def mutate_and_get_payload(cls, root, info, **kwargs): + id = kwargs.get('id') + restricted = kwargs.get('restricted') + user = info.context.user + room = get_object(Room, id) + if not user.is_teacher() or not SchoolClassMember.objects.filter(active=True,user=user,school_class=room.school_class).exists(): + raise Exception('You are not permitted to do this') + room.restricted = restricted + room.save() + return cls(success=True, room=room) + + + class AddComment(relay.ClientIDMutation): class Input: comment = graphene.String(required=True) @@ -173,3 +195,4 @@ class RoomMutations: delete_room_entry = DeleteRoomEntry.Field() update_room_entry = UpdateRoomEntry.Field() add_comment = AddComment.Field() + update_room_visibility = UpdateRoomVisibility.Field() diff --git a/server/rooms/tests/test_room_visibility_mutation.py b/server/rooms/tests/test_room_visibility_mutation.py new file mode 100644 index 00000000..08b9afa2 --- /dev/null +++ b/server/rooms/tests/test_room_visibility_mutation.py @@ -0,0 +1,55 @@ +from graphql_relay import to_global_id + +from core.tests.base_test import SkillboxTestCase +from core.tests.helpers import GQLResult +from rooms.factories import RoomFactory + + +class TestRoomVisibilityMutationTestCase(SkillboxTestCase): + def setUp(self) -> None: + self.createDefault() + self.room = RoomFactory(school_class=self.school_class) + self.room_id = to_global_id('RoomNode', self.room.id) + self.mutation = """ +mutation UpdateRoomVisibility($input: UpdateRoomVisibilityInput!) { + updateRoomVisibility(input: $input) { + success + room { + id + restricted + } + } +} + """ + + def test_successful_mutation(self): + res = self.get_client().execute(self.mutation, variables={ + 'input': { + 'id': self.room_id, + 'restricted': True + } + }) + result = GQLResult(res) + self.assertIsNone(result.errors) + self.assertEqual(result.data.get('updateRoomVisibility').get('room').get('restricted'), True) + + def test_permission_denied(self): + res = self.get_client(self.student1).execute(self.mutation, variables={ + 'input': { + 'id': self.room_id, + 'restricted': True + } + }) + result = GQLResult(res) + self.assertIsNotNone(result.errors) + + res = self.get_client(self.teacher2).execute(self.mutation, variables={ + 'input': { + 'id': self.room_id, + 'restricted': True + } + }) + result = GQLResult(res) + self.assertIsNotNone(result.errors) + + diff --git a/server/schema.graphql b/server/schema.graphql index 963f2433..960e7a77 100644 --- a/server/schema.graphql +++ b/server/schema.graphql @@ -939,6 +939,7 @@ type RoomNode implements Node { schoolClass: SchoolClassNode! appearance: String! userCreated: Boolean! + restricted: Boolean! roomEntries(offset: Int, before: String, after: String, first: Int, last: Int, slug: String): RoomEntryNodeConnection! pk: Int entryCount: Int