Add join team mutation
This commit is contained in:
parent
4e1ab68a52
commit
a4ff9d2942
|
|
@ -347,6 +347,17 @@ type CreateSchoolClassPayload {
|
||||||
clientMutationId: String
|
clientMutationId: String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input CreateTeamInput {
|
||||||
|
name: String!
|
||||||
|
clientMutationId: String
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateTeamPayload {
|
||||||
|
success: Boolean
|
||||||
|
team: TeamNode
|
||||||
|
clientMutationId: String
|
||||||
|
}
|
||||||
|
|
||||||
type CustomMutation {
|
type CustomMutation {
|
||||||
redeemCoupon(input: CouponInput!): CouponPayload
|
redeemCoupon(input: CouponInput!): CouponPayload
|
||||||
spellCheck(input: SpellCheckInput!): SpellCheckPayload
|
spellCheck(input: SpellCheckInput!): SpellCheckPayload
|
||||||
|
|
@ -365,6 +376,8 @@ type CustomMutation {
|
||||||
updateSchoolClass(input: UpdateSchoolClassInput!): UpdateSchoolClassPayload
|
updateSchoolClass(input: UpdateSchoolClassInput!): UpdateSchoolClassPayload
|
||||||
createSchoolClass(input: CreateSchoolClassInput!): CreateSchoolClassPayload
|
createSchoolClass(input: CreateSchoolClassInput!): CreateSchoolClassPayload
|
||||||
updateOnboardingProgress: UpdateOnboardingProgress
|
updateOnboardingProgress: UpdateOnboardingProgress
|
||||||
|
createTeam(input: CreateTeamInput!): CreateTeamPayload
|
||||||
|
joinTeam(input: JoinTeamInput!): JoinTeamPayload
|
||||||
addProject(input: AddProjectInput!): AddProjectPayload
|
addProject(input: AddProjectInput!): AddProjectPayload
|
||||||
updateProject(input: UpdateProjectInput!): UpdateProjectPayload
|
updateProject(input: UpdateProjectInput!): UpdateProjectPayload
|
||||||
deleteProject(input: DeleteProjectInput!): DeleteProjectPayload
|
deleteProject(input: DeleteProjectInput!): DeleteProjectPayload
|
||||||
|
|
@ -578,6 +591,17 @@ type JoinClassPayload {
|
||||||
clientMutationId: String
|
clientMutationId: String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input JoinTeamInput {
|
||||||
|
code: String!
|
||||||
|
clientMutationId: String
|
||||||
|
}
|
||||||
|
|
||||||
|
type JoinTeamPayload {
|
||||||
|
success: Boolean
|
||||||
|
team: TeamNode
|
||||||
|
clientMutationId: String
|
||||||
|
}
|
||||||
|
|
||||||
type Logout {
|
type Logout {
|
||||||
success: Boolean
|
success: Boolean
|
||||||
}
|
}
|
||||||
|
|
@ -803,8 +827,8 @@ type SchoolClassNode implements Node {
|
||||||
id: ID!
|
id: ID!
|
||||||
name: String!
|
name: String!
|
||||||
isDeleted: Boolean!
|
isDeleted: Boolean!
|
||||||
users(offset: Int, before: String, after: String, first: Int, last: Int, username: String, email: String): UserNodeConnection!
|
|
||||||
code: String
|
code: String
|
||||||
|
users(offset: Int, before: String, after: String, first: Int, last: Int, username: String, email: String): UserNodeConnection!
|
||||||
moduleSet(offset: Int, before: String, after: String, first: Int, last: Int, slug: String, slug_Icontains: String, slug_In: [String], title: String, title_Icontains: String, title_In: [String]): ModuleNodeConnection!
|
moduleSet(offset: Int, before: String, after: String, first: Int, last: Int, slug: String, slug_Icontains: String, slug_In: [String], title: String, title_Icontains: String, title_In: [String]): ModuleNodeConnection!
|
||||||
hiddenChapterTitles(offset: Int, before: String, after: String, first: Int, last: Int, slug: String, title: String): ChapterNodeConnection!
|
hiddenChapterTitles(offset: Int, before: String, after: String, first: Int, last: Int, slug: String, title: String): ChapterNodeConnection!
|
||||||
hiddenChapterDescriptions(offset: Int, before: String, after: String, first: Int, last: Int, slug: String, title: String): ChapterNodeConnection!
|
hiddenChapterDescriptions(offset: Int, before: String, after: String, first: Int, last: Int, slug: String, title: String): ChapterNodeConnection!
|
||||||
|
|
@ -920,6 +944,16 @@ type SyncModuleVisibilityPayload {
|
||||||
clientMutationId: String
|
clientMutationId: String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TeamNode implements Node {
|
||||||
|
name: String!
|
||||||
|
isDeleted: Boolean!
|
||||||
|
code: String
|
||||||
|
id: ID!
|
||||||
|
creator: UserNode
|
||||||
|
members: [UserNode]
|
||||||
|
pk: Int
|
||||||
|
}
|
||||||
|
|
||||||
type TopicConnection {
|
type TopicConnection {
|
||||||
pageInfo: PageInfo!
|
pageInfo: PageInfo!
|
||||||
edges: [TopicEdge]!
|
edges: [TopicEdge]!
|
||||||
|
|
@ -1280,6 +1314,7 @@ type UserNode implements Node {
|
||||||
avatarUrl: String!
|
avatarUrl: String!
|
||||||
email: String!
|
email: String!
|
||||||
onboardingVisited: Boolean!
|
onboardingVisited: Boolean!
|
||||||
|
team: TeamNode
|
||||||
schoolClasses(offset: Int, before: String, after: String, first: Int, last: Int, name: String): SchoolClassNodeConnection!
|
schoolClasses(offset: Int, before: String, after: String, first: Int, last: Int, name: String): SchoolClassNodeConnection!
|
||||||
id: ID!
|
id: ID!
|
||||||
pk: Int
|
pk: Int
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ class TeamFactory(factory.django.DjangoModelFactory):
|
||||||
model = Team
|
model = Team
|
||||||
|
|
||||||
name = factory.Faker('name')
|
name = factory.Faker('name')
|
||||||
|
code = factory.Sequence(lambda n: "CODE{}".format(n))
|
||||||
is_deleted = False
|
is_deleted = False
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,7 @@ class JoinClass(relay.ClientIDMutation):
|
||||||
|
|
||||||
return cls(success=True, school_class=school_class)
|
return cls(success=True, school_class=school_class)
|
||||||
except SchoolClass.DoesNotExist:
|
except SchoolClass.DoesNotExist:
|
||||||
raise CodeNotFoundException('[CNV] Code ist nicht gültig') # CAV = Code Not Valid
|
raise CodeNotFoundException('[CNV] Code ist nicht gültig') # CNV = Code Not Valid
|
||||||
|
|
||||||
|
|
||||||
class AddRemoveMember(relay.ClientIDMutation):
|
class AddRemoveMember(relay.ClientIDMutation):
|
||||||
|
|
@ -211,7 +211,7 @@ class CreateSchoolClass(relay.ClientIDMutation):
|
||||||
|
|
||||||
class CreateTeam(relay.ClientIDMutation):
|
class CreateTeam(relay.ClientIDMutation):
|
||||||
class Input:
|
class Input:
|
||||||
name = graphene.String()
|
name = graphene.String(required=True)
|
||||||
|
|
||||||
success = graphene.Boolean()
|
success = graphene.Boolean()
|
||||||
team = graphene.Field(TeamNode)
|
team = graphene.Field(TeamNode)
|
||||||
|
|
@ -231,6 +231,27 @@ class CreateTeam(relay.ClientIDMutation):
|
||||||
return cls(success=True, team=team)
|
return cls(success=True, team=team)
|
||||||
|
|
||||||
|
|
||||||
|
class JoinTeam(relay.ClientIDMutation):
|
||||||
|
class Input:
|
||||||
|
code = graphene.String(required=True)
|
||||||
|
|
||||||
|
success = graphene.Boolean()
|
||||||
|
team = graphene.Field(TeamNode)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def mutate_and_get_payload(cls, root, info, **kwargs):
|
||||||
|
user = info.context.user
|
||||||
|
code = kwargs.get('code')
|
||||||
|
try:
|
||||||
|
team = Team.objects.get(Q(code__iexact=code))
|
||||||
|
user.team = team
|
||||||
|
user.save()
|
||||||
|
|
||||||
|
return cls(success=True, team=team)
|
||||||
|
except Team.DoesNotExist:
|
||||||
|
raise CodeNotFoundException('[CNV] Code ist nicht gültig') # CNV = Code Not Valid
|
||||||
|
|
||||||
|
|
||||||
class UpdateOnboardingProgress(graphene.Mutation):
|
class UpdateOnboardingProgress(graphene.Mutation):
|
||||||
success = graphene.Boolean()
|
success = graphene.Boolean()
|
||||||
|
|
||||||
|
|
@ -254,3 +275,4 @@ class ProfileMutations:
|
||||||
create_school_class = CreateSchoolClass.Field()
|
create_school_class = CreateSchoolClass.Field()
|
||||||
update_onboarding_progress = UpdateOnboardingProgress.Field()
|
update_onboarding_progress = UpdateOnboardingProgress.Field()
|
||||||
create_team = CreateTeam.Field()
|
create_team = CreateTeam.Field()
|
||||||
|
join_team = JoinTeam.Field()
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,8 @@ from graphene import Context
|
||||||
from graphene.test import Client
|
from graphene.test import Client
|
||||||
|
|
||||||
from api.schema import schema
|
from api.schema import schema
|
||||||
from core.factories import UserFactory, TeacherFactory
|
from core.factories import TeacherFactory
|
||||||
from users.factories import TeamFactory
|
from users.factories import TeamFactory
|
||||||
from users.models import Role
|
|
||||||
from users.services import create_teacher
|
|
||||||
|
|
||||||
ME_QUERY = """
|
ME_QUERY = """
|
||||||
query MeQuery {
|
query MeQuery {
|
||||||
|
|
@ -31,6 +29,18 @@ CREATE_MUTATION = """
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
JOIN_TEAM_MUTATION = """
|
||||||
|
mutation JoinTeamMutation($input: JoinTeamInput!) {
|
||||||
|
joinTeam(input: $input) {
|
||||||
|
success
|
||||||
|
team {
|
||||||
|
name
|
||||||
|
code
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
class TeamTest(TestCase):
|
class TeamTest(TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
|
@ -41,15 +51,50 @@ class TeamTest(TestCase):
|
||||||
self.user = TeacherFactory(username='ueli', team=self.team)
|
self.user = TeacherFactory(username='ueli', team=self.team)
|
||||||
self.context = Context(user=self.user)
|
self.context = Context(user=self.user)
|
||||||
|
|
||||||
def test_team_query(self):
|
@staticmethod
|
||||||
result = self.client.execute(ME_QUERY, context=self.context)
|
def get_team(result):
|
||||||
|
return result.get('data').get('me').get('team')
|
||||||
|
|
||||||
|
def no_error(self, result):
|
||||||
self.assertIsNone(result.get('errors'))
|
self.assertIsNone(result.get('errors'))
|
||||||
team = result.get('data').get('me').get('team')
|
|
||||||
self.assertEqual(team.get('name'), self.team_name)
|
def check_me(self, context, name, code):
|
||||||
self.assertEqual(team.get('code'), self.code)
|
result = self.client.execute(ME_QUERY, context=context)
|
||||||
|
self.no_error(result)
|
||||||
|
team = self.get_team(result)
|
||||||
|
|
||||||
|
self.assertEqual(team.get('name'), name)
|
||||||
|
self.assertEqual(team.get('code'), code)
|
||||||
|
|
||||||
|
def join_team(self, code, context):
|
||||||
|
variables = {
|
||||||
|
"input": {
|
||||||
|
"code": code
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result = self.client.execute(JOIN_TEAM_MUTATION, variables=variables, context=context)
|
||||||
|
self.no_error(result)
|
||||||
|
success = result['data']['joinTeam']['success']
|
||||||
|
self.assertTrue(success)
|
||||||
|
|
||||||
|
def test_team_query(self):
|
||||||
|
self.check_me(self.context, self.team_name, self.code)
|
||||||
|
|
||||||
def test_join_team_mutation(self):
|
def test_join_team_mutation(self):
|
||||||
raise NotImplementedError()
|
teacher = TeacherFactory(username='hansli')
|
||||||
|
context = Context(user=teacher)
|
||||||
|
self.join_team(self.code, context)
|
||||||
|
|
||||||
|
self.check_me(context, self.team_name, self.code)
|
||||||
|
|
||||||
|
def test_join_second_team_mutation(self):
|
||||||
|
teacher = TeacherFactory(username='peterli')
|
||||||
|
context = Context(user=teacher)
|
||||||
|
second_team = TeamFactory()
|
||||||
|
self.join_team(self.code, context)
|
||||||
|
self.check_me(context, self.team_name, self.code)
|
||||||
|
self.join_team(second_team.code, context)
|
||||||
|
self.check_me(context, second_team.name, second_team.code)
|
||||||
|
|
||||||
def test_create_team_mutation(self):
|
def test_create_team_mutation(self):
|
||||||
team_name = "Dunder Mifflin"
|
team_name = "Dunder Mifflin"
|
||||||
|
|
@ -59,7 +104,7 @@ class TeamTest(TestCase):
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result = self.client.execute(CREATE_MUTATION, context=self.context, variables=variables)
|
result = self.client.execute(CREATE_MUTATION, context=self.context, variables=variables)
|
||||||
self.assertIsNone(result.get('errors'))
|
self.no_error(result)
|
||||||
create_team = result.get('data').get('createTeam')
|
create_team = result.get('data').get('createTeam')
|
||||||
team = create_team.get('team')
|
team = create_team.get('team')
|
||||||
success = create_team.get('success')
|
success = create_team.get('success')
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue