Add update team mutation on server and some tests for it
This commit is contained in:
parent
b84aa50443
commit
9bde5dbb20
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
|
|
|
|||
Loading…
Reference in New Issue