Add update team mutation on server and some tests for it

This commit is contained in:
Ramon Wenger 2021-03-25 18:00:04 +01:00
parent b84aa50443
commit 9bde5dbb20
3 changed files with 116 additions and 49 deletions

View File

@ -6,11 +6,13 @@ from graphene import relay
from graphql_relay import from_global_id
from api.utils import get_object
from core.logger import get_logger
from users.inputs import PasswordUpdateInput
from users.models import SchoolClass, SchoolClassMember, Team
from users.schema import SchoolClassNode, TeamNode
from users.serializers import PasswordSerialzer, AvatarUrlSerializer
logger = get_logger(__name__)
class CodeNotFoundException(Exception):
pass
@ -25,6 +27,18 @@ class UpdateError(graphene.ObjectType):
errors = graphene.List(FieldError)
class TeacherOnlyMutation(relay.ClientIDMutation):
class Meta:
abstract = True
@classmethod
def mutate(cls, root, info, input):
user = info.context.user
if 'users.can_manage_school_class_content' not in user.get_role_permissions():
raise PermissionError('Permission denied')
return super().mutate(root, info, input)
class UpdatePassword(relay.ClientIDMutation):
class Input:
password_input = graphene.Argument(PasswordUpdateInput)
@ -154,7 +168,7 @@ class AddRemoveMember(relay.ClientIDMutation):
school_class = get_object(SchoolClass, school_class_id)
if not user.is_teacher() or not school_class.users.filter(pk=user.pk).exists():
raise PermissionError('Fehlende Berechtigung')
raise PermissionError('Permission denied')
school_class_member = SchoolClassMember.objects.get(user__pk=member_pk, school_class=school_class)
school_class_member.active = active
@ -163,7 +177,7 @@ class AddRemoveMember(relay.ClientIDMutation):
return cls(success=True)
class UpdateSchoolClass(relay.ClientIDMutation):
class UpdateSchoolClass(TeacherOnlyMutation):
class Input:
id = graphene.ID(required=True)
name = graphene.String()
@ -177,9 +191,7 @@ class UpdateSchoolClass(relay.ClientIDMutation):
name = kwargs.get('name')
user = info.context.user
if 'users.can_manage_school_class_content' not in user.get_role_permissions():
raise PermissionError()
# todo: only allow to edit your own school class
school_class = get_object(SchoolClass, id)
school_class.name = name
school_class.save()
@ -187,7 +199,7 @@ class UpdateSchoolClass(relay.ClientIDMutation):
return cls(success=True, school_class=school_class)
class CreateSchoolClass(relay.ClientIDMutation):
class CreateSchoolClass(TeacherOnlyMutation):
class Input:
name = graphene.String()
@ -197,30 +209,14 @@ class CreateSchoolClass(relay.ClientIDMutation):
@classmethod
def mutate_and_get_payload(cls, root, info, **kwargs):
name = kwargs.get('name')
user = info.context.user
if 'users.can_manage_school_class_content' not in user.get_role_permissions():
raise PermissionError()
school_class = SchoolClass.objects.create(name=name)
SchoolClassMember.objects.create(school_class=school_class, user=user)
user.set_selected_class(school_class)
return cls(success=True, school_class=school_class)
class TeacherOnlyMutation(relay.ClientIDMutation):
class Meta:
abstract = True
@classmethod
def mutate(cls, root, info, input):
user = info.context.user
if 'users.can_manage_school_class_content' not in user.get_role_permissions():
raise PermissionError('Missing permissions')
return super().mutate(root, info, input)
class CreateTeam(TeacherOnlyMutation):
class Input:
name = graphene.String(required=True)
@ -240,6 +236,30 @@ class CreateTeam(TeacherOnlyMutation):
return cls(success=True, team=team)
class UpdateTeam(TeacherOnlyMutation):
class Input:
id = graphene.ID(required=True)
name = graphene.String()
success = graphene.Boolean()
team = graphene.Field(TeamNode)
@classmethod
def mutate_and_get_payload(cls, root, info, **kwargs):
id = kwargs.get('id')
name = kwargs.get('name')
user = info.context.user
team = get_object(Team, id)
if user not in team.members.all():
logger.info('User not part of this team')
raise PermissionError('Permission denied')
team.name = name
team.save()
return cls(success=True, team=team)
class JoinTeam(TeacherOnlyMutation):
class Input:
code = graphene.String(required=True)
@ -285,3 +305,4 @@ class ProfileMutations:
update_onboarding_progress = UpdateOnboardingProgress.Field()
create_team = CreateTeam.Field()
join_team = JoinTeam.Field()
update_team = UpdateTeam.Field()

View File

@ -1,32 +1,16 @@
# -*- coding: utf-8 -*-
#
# ITerativ GmbH
# http://www.iterativ.ch/
#
# Copyright (c) 2019 ITerativ GmbH. All rights reserved.
#
# Created on 2019-10-10
# @author: chrigu <christian.cueni@iterativ.ch>
from django.conf import settings
# -*- coding: utf-8 -*-
#
# ITerativ GmbH
# http://www.iterativ.ch/
#
# Copyright (c) 2019 ITerativ GmbH. All rights reserved.
#
# Created on 2019-04-09
# @author: chrigu <christian.cueni@iterativ.ch>
from django.test import TestCase, RequestFactory
from graphene import Context
from graphene.test import Client
from graphql_relay import to_global_id
from api.utils import get_graphql_mutation, get_object
from core.factories import UserFactory
from users.models import SchoolClass, User
from api.schema import schema
from api.utils import get_graphql_mutation, get_object
from core.factories import UserFactory, TeacherFactory
from users.models import SchoolClass, User
from users.services import create_users
UPDATE_SCHOOL_CLASS_MUTATION = get_graphql_mutation('updateSchoolClass.gql')
class SchoolClassesTest(TestCase):
@ -53,6 +37,7 @@ class SchoolClassesTest(TestCase):
class_name = SchoolClass.generate_default_group_name(user=user)
self.assertEqual(f'{self.prefix} {user.pk}', class_name)
class ModifySchoolClassTest(TestCase):
def setUp(self):
create_users()
@ -72,9 +57,8 @@ class ModifySchoolClassTest(TestCase):
school_class = SchoolClass.objects.get(name='skillbox')
self.assertEqual(school_class.name, 'skillbox')
id = to_global_id('SchoolClassNode', school_class.id)
mutation = get_graphql_mutation('updateSchoolClass.gql')
result = self.client.execute(mutation, variables={
result = self.client.execute(UPDATE_SCHOOL_CLASS_MUTATION, variables={
'input': {
'id': id,
'name': class_name
@ -85,15 +69,30 @@ class ModifySchoolClassTest(TestCase):
school_class = get_object(SchoolClass, id)
self.assertEqual(school_class.name, class_name)
def test_update_school_class_not_in_class_fails(self):
client = Client(schema=schema)
teacher = TeacherFactory(username='conan')
context = Context(user=teacher)
school_class = SchoolClass.objects.get(name='skillbox')
self.assertEqual(school_class.name, 'skillbox')
id = to_global_id('SchoolClassNode', school_class.id)
variables = {
'input': {
'id': id,
'name': 'Nein'
}
}
result = client.execute(UPDATE_SCHOOL_CLASS_MUTATION, variables=variables, context=context)
self.assertIsNone(result.get('errors'))
def test_update_school_class_fail(self):
class_name = 'Nanana'
school_class = SchoolClass.objects.get(name='skillbox')
self.assertEqual(school_class.name, 'skillbox')
id = to_global_id('SchoolClassNode', school_class.id)
mutation = get_graphql_mutation('updateSchoolClass.gql')
result = self.student_client.execute(mutation, variables={
result = self.student_client.execute(UPDATE_SCHOOL_CLASS_MUTATION, variables={
'input': {
'id': id,
'name': class_name

View File

@ -1,6 +1,7 @@
from django.test import TestCase
from graphene import Context
from graphene.test import Client
from graphql_relay import to_global_id
from api.schema import schema
from api.utils import get_graphql_mutation
@ -21,6 +22,7 @@ ME_QUERY = """
CREATE_TEAM_MUTATION = get_graphql_mutation('createTeam.gql')
JOIN_TEAM_MUTATION = get_graphql_mutation('joinTeam.gql')
UPDATE_TEAM_MUTATION = get_graphql_mutation('updateTeam.gql')
class TeamTest(TestCase):
@ -29,6 +31,7 @@ class TeamTest(TestCase):
self.team_name = 'Fiterativ'
self.code = 'AAAA'
self.team = TeamFactory(name=self.team_name, code=self.code)
self.team_id = to_global_id('TeamNode', self.team.id)
self.user = TeacherFactory(username='ueli', team=self.team)
self.student = UserFactory(username='fritzli')
self.context = Context(user=self.user)
@ -43,7 +46,7 @@ class TeamTest(TestCase):
def permission_error(self, result):
errors = result.get('errors')
self.assertIsNotNone(errors)
self.assertIn('permission', errors[0]['message'])
self.assertIn('Permission denied', errors[0]['message'])
def check_me(self, context, name, code):
result = self.client.execute(ME_QUERY, context=context)
@ -99,6 +102,50 @@ class TeamTest(TestCase):
self.assertEqual(team.get('name'), team_name)
self.assertIsNotNone(team.get('code'))
def test_update_team_name(self):
new_name = 'Team Böhmermann'
variables = {
"input": {
"name": new_name,
"id": self.team_id
}
}
result = self.client.execute(UPDATE_TEAM_MUTATION, context=self.context, variables=variables)
self.no_error(result)
update_team = result.get('data').get('updateTeam')
team = update_team.get('team')
success = update_team.get('success')
self.assertTrue(success)
self.assertEqual(team.get('name'), new_name)
def test_update_team_name_as_student_fails(self):
context = Context(user=self.student)
variables = {
"input": {
"name": 'Not gonna happen',
"id": self.team_id
}
}
result = self.client.execute(UPDATE_TEAM_MUTATION, context=context, variables=variables)
self.permission_error(result)
def test_update_team_name_not_in_team_fails(self):
schelm = TeacherFactory(username='schelm')
context = Context(user=schelm)
team = Team.objects.get(pk=self.team.pk)
old_name = team.name
self.assertFalse(self.team.members.filter(pk=schelm.pk).exists())
variables = {
"input": {
"name": 'Not gonna happen',
"id": self.team_id
}
}
result = self.client.execute(UPDATE_TEAM_MUTATION, context=context, variables=variables)
self.permission_error(result)
team = Team.objects.get(pk=self.team.pk)
self.assertEqual(team.name, old_name)
def test_create_team_mutation_as_student_fails(self):
self.assertEqual(Team.objects.count(), 1)
variables = {