From c6ddb3b051c08c89d1769731788efa01a7fcbc7f Mon Sep 17 00:00:00 2001 From: Ramon Wenger Date: Tue, 12 Apr 2022 14:57:56 +0200 Subject: [PATCH] Update `create team` mutation signature --- .../src/graphql/gql/mutations/createTeam.gql | 11 +++++--- server/schema.graphql | 5 ++-- server/users/schema/mutations.py | 23 +++++++++------- server/users/schema/types.py | 11 ++++++++ server/users/tests/test_teams.py | 26 +++++++++++++------ 5 files changed, 53 insertions(+), 23 deletions(-) diff --git a/client/src/graphql/gql/mutations/createTeam.gql b/client/src/graphql/gql/mutations/createTeam.gql index a9ce574d..cc886695 100644 --- a/client/src/graphql/gql/mutations/createTeam.gql +++ b/client/src/graphql/gql/mutations/createTeam.gql @@ -1,9 +1,14 @@ #import "gql/fragments/teamParts.gql" mutation CreateTeamMutation($input: CreateTeamInput!) { createTeam(input: $input) { - success - team { - ...TeamParts + result { + __typename + ...on TeamNode { + ...TeamParts + } + ...on DuplicateName { + reason + } } } } diff --git a/server/schema.graphql b/server/schema.graphql index 61efe16d..7a30217b 100644 --- a/server/schema.graphql +++ b/server/schema.graphql @@ -367,11 +367,12 @@ input CreateTeamInput { } type CreateTeamPayload { - success: Boolean - team: TeamNode + result: CreateTeamResult clientMutationId: String } +union CreateTeamResult = TeamNode | DuplicateName + scalar Date scalar DateTime diff --git a/server/users/schema/mutations.py b/server/users/schema/mutations.py index 2903008b..93761178 100644 --- a/server/users/schema/mutations.py +++ b/server/users/schema/mutations.py @@ -10,12 +10,13 @@ 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, UpdateError, FieldError, CreateSchoolClassResult +from users.schema import CreateSchoolClassResult, CreateTeamResult, FieldError, SchoolClassNode, TeamNode, UpdateError from users.serializers import AvatarUrlSerializer, PasswordSerialzer - logger = get_logger(__name__) +DUPLICATE_REASON = {"reason": "Dieser Name wird bereits verwendet."} + class CodeNotFoundException(Exception): pass @@ -210,26 +211,28 @@ class CreateSchoolClass(TeacherOnlyMutation): user.set_selected_class(school_class) return cls(result=school_class) except IntegrityError: - return cls(result={"reason": "Dieser Name wird bereits verwendet."}) + return cls(result=DUPLICATE_REASON) class CreateTeam(TeacherOnlyMutation): class Input: name = graphene.String(required=True) - success = graphene.Boolean() - team = graphene.Field(TeamNode) + result = CreateTeamResult() @classmethod def mutate_and_get_payload(cls, root, info, **kwargs): name = kwargs.get('name') user = info.context.user - team = Team.objects.create(name=name, creator=user) - team.generate_code() - user.team = team - user.save() - return cls(success=True, team=team) + try: + team = Team.objects.create(name=name, creator=user) + team.generate_code() + user.team = team + user.save() + return cls(result=team) + except IntegrityError: + return cls(result=DUPLICATE_REASON) class UpdateTeam(TeacherOnlyMutation): diff --git a/server/users/schema/types.py b/server/users/schema/types.py index 4029b53e..61dddcb8 100644 --- a/server/users/schema/types.py +++ b/server/users/schema/types.py @@ -186,6 +186,17 @@ class DuplicateName(graphene.ObjectType): reason = graphene.String() +class CreateTeamResult(graphene.Union): + class Meta: + types = (TeamNode, DuplicateName) + + @classmethod + def resolve_type(cls, instance, info): + if type(instance).__name__ == "Team": + return TeamNode + return DuplicateName + + class CreateSchoolClassResult(graphene.Union): class Meta: types = (SchoolClassNode, DuplicateName) diff --git a/server/users/tests/test_teams.py b/server/users/tests/test_teams.py index 1a2a16f5..7bfe76a5 100644 --- a/server/users/tests/test_teams.py +++ b/server/users/tests/test_teams.py @@ -101,22 +101,33 @@ class TeamTest(TestCase): self.join_team(second_team.code, context) self.check_me(context, second_team.name, second_team.code) - def test_create_team_mutation(self): - team_name = "Dunder Mifflin" + def _get_team_mutation_result(self, name): variables = { "input": { - "name": team_name + "name": name } } result = self.client.execute(CREATE_TEAM_MUTATION, context=self.context, variables=variables) self.no_error(result) create_team = result.get('data').get('createTeam') - team = create_team.get('team') - success = create_team.get('success') - self.assertTrue(success) + result = create_team.get('result') + typename = result.get('__typename') + return result, typename + + def test_create_team_mutation_success(self): + team_name = "Dunder Mifflin" + team, typename = self._get_team_mutation_result(team_name) + self.assertEqual(typename, 'TeamNode') self.assertEqual(team.get('name'), team_name) self.assertIsNotNone(team.get('code')) + def test_create_team_mutation_fail_duplicate_name(self): + team_name = "Dunder Mifflin" + Team.objects.create(name=team_name) + duplicate_name, typename = self._get_team_mutation_result(team_name) + self.assertEqual(typename, 'DuplicateName') + self.assertEqual(duplicate_name.get('reason'), 'Dieser Name wird bereits verwendet.') + def test_update_team_name(self): new_name = 'Team Böhmermann' variables = { @@ -149,7 +160,7 @@ class TeamTest(TestCase): 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()) + self.assertFalse(self.team.members.filter(pk=schelm.pk).exists()) variables = { "input": { "name": 'Not gonna happen', @@ -199,4 +210,3 @@ class TeamTest(TestCase): student_after = User.objects.get(pk=self.student.pk) self.assertIsNone(student_after.team) -