Restrict deletion of rooms to teachers
This commit is contained in:
parent
58d42e2472
commit
62bd0b2435
|
|
@ -5,7 +5,7 @@
|
|||
<room-group-widget v-bind="schoolClass"></room-group-widget>
|
||||
<room-entry-count-widget :entryCount="entryCount"></room-entry-count-widget>
|
||||
</router-link>
|
||||
<div class="room-widget__footer">
|
||||
<div class="room-widget__footer" v-if="canEditRoom">
|
||||
<div>
|
||||
<a @click="showMenu = !showMenu" class="room-widget__more-link">
|
||||
<ellipses></ellipses>
|
||||
|
|
@ -30,6 +30,8 @@
|
|||
import RoomEntryCountWidget from '@/components/rooms/RoomEntryCountWidget';
|
||||
import WidgetPopover from '@/components/rooms/WidgetPopover';
|
||||
|
||||
import {meQuery} from '@/graphql/queries';
|
||||
|
||||
export default {
|
||||
props: ['slug', 'title', 'entryCount', 'appearance', 'schoolClass', 'id'],
|
||||
|
||||
|
|
@ -42,16 +44,26 @@
|
|||
|
||||
data() {
|
||||
return {
|
||||
showMenu: false
|
||||
showMenu: false,
|
||||
me: {
|
||||
permissions: []
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
roomClass() {
|
||||
return `room-widget--${this.appearance}`
|
||||
},
|
||||
canEditRoom() {
|
||||
return this.me.permissions.includes('users.can_manage_school_class_content');
|
||||
}
|
||||
},
|
||||
|
||||
apollo: {
|
||||
me: meQuery
|
||||
},
|
||||
|
||||
methods: {
|
||||
deleteRoom(id) {
|
||||
this.$apollo.mutate({
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import graphene
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from graphene import relay
|
||||
from graphql_relay import to_global_id, from_global_id
|
||||
|
||||
|
|
@ -64,9 +65,14 @@ class DeleteRoom(relay.ClientIDMutation):
|
|||
errors = graphene.List(graphene.String)
|
||||
|
||||
@classmethod
|
||||
def mutate_and_get_payload(cls, *args, **kwargs):
|
||||
def mutate_and_get_payload(cls, root, info, **kwargs):
|
||||
id = kwargs.get('id')
|
||||
room = get_object(Room, id)
|
||||
user = info.context.user
|
||||
if not user.has_perm('users.can_manage_school_class_content'):
|
||||
raise PermissionDenied('Missing permissions')
|
||||
if room.school_class not in user.school_classes.all():
|
||||
raise PermissionDenied('Permission denied: Incorrect school classes')
|
||||
room.delete()
|
||||
return cls(success=True)
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
from django.test import TestCase, RequestFactory
|
||||
from graphene.test import Client
|
||||
from graphql_relay import to_global_id
|
||||
|
||||
from api.schema import schema
|
||||
from rooms.factories import RoomFactory
|
||||
from rooms.models import Room
|
||||
from users.models import User, SchoolClass
|
||||
from users.services import create_users
|
||||
|
||||
|
||||
class RoomDeleteEditPermissionsTestcase(TestCase):
|
||||
def setUp(self):
|
||||
create_users()
|
||||
self.teacher = User.objects.get(username='teacher')
|
||||
self.teacher2 = User.objects.get(username='teacher2')
|
||||
self.student = User.objects.get(username='student1')
|
||||
school_class = SchoolClass.objects.get(name='skillbox')
|
||||
self.room = RoomFactory(school_class=school_class)
|
||||
self.mutation = '''
|
||||
mutation DeleteRoom($input: DeleteRoomInput!) {
|
||||
deleteRoom(input: $input) {
|
||||
success
|
||||
errors
|
||||
}
|
||||
}
|
||||
'''
|
||||
self.variables = {
|
||||
'input': {
|
||||
'id': to_global_id('RoomNode', self.room.id)
|
||||
}
|
||||
}
|
||||
|
||||
def test_delete_own_room(self):
|
||||
self.assertEqual(Room.objects.count(), 1)
|
||||
request = RequestFactory().get('/')
|
||||
request.user = self.teacher
|
||||
self.client = Client(schema=schema, context_value=request)
|
||||
|
||||
|
||||
result = self.client.execute(self.mutation, variables=self.variables)
|
||||
|
||||
self.assertIsNone(result.get('errors'))
|
||||
self.assertEqual(Room.objects.count(), 0)
|
||||
|
||||
def test_delete_room_as_student(self):
|
||||
self.assertEqual(Room.objects.count(), 1)
|
||||
request = RequestFactory().get('/')
|
||||
request.user = self.student
|
||||
self.client = Client(schema=schema, context_value=request)
|
||||
|
||||
result = self.client.execute(self.mutation, variables=self.variables)
|
||||
|
||||
self.assertIsNotNone(result.get('errors'))
|
||||
self.assertEqual(Room.objects.count(), 1)
|
||||
|
||||
def test_delete_room_of_other_class(self):
|
||||
self.assertEqual(Room.objects.count(), 1)
|
||||
request = RequestFactory().get('/')
|
||||
request.user = self.teacher2
|
||||
self.client = Client(schema=schema, context_value=request)
|
||||
|
||||
result = self.client.execute(self.mutation, variables=self.variables)
|
||||
|
||||
self.assertIsNotNone(result.get('errors'))
|
||||
self.assertEqual(Room.objects.count(), 1)
|
||||
Loading…
Reference in New Issue