Fix project page schema
This commit is contained in:
parent
5dca389003
commit
98771b2db2
|
|
@ -1671,6 +1671,7 @@ export type PublicUserNode = Node & {
|
|||
id: Scalars['ID']['output'];
|
||||
isMe?: Maybe<Scalars['Boolean']['output']>;
|
||||
lastName: Scalars['String']['output'];
|
||||
schoolClasses?: Maybe<Array<Maybe<SchoolClassNode>>>;
|
||||
};
|
||||
|
||||
export type Query = {
|
||||
|
|
@ -2212,7 +2213,7 @@ export type SyncModuleVisibilityPayload = {
|
|||
export type TeamNode = Node & {
|
||||
__typename?: 'TeamNode';
|
||||
code?: Maybe<Scalars['String']['output']>;
|
||||
creator: PublicUserNode;
|
||||
creator?: Maybe<PublicUserNode>;
|
||||
/** The ID of the object */
|
||||
id: Scalars['ID']['output'];
|
||||
isDeleted: Scalars['Boolean']['output'];
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
:final="project.final"
|
||||
data-cy="project-share-link"
|
||||
class="project__share"
|
||||
v-if="canEdit"
|
||||
@share="updateProjectShareState(project.slug, !project.final)"
|
||||
/>
|
||||
|
||||
|
|
@ -109,7 +110,9 @@ export default {
|
|||
return [cls ? `project--${cls}` : ''];
|
||||
},
|
||||
isOwner() {
|
||||
return this.me.id === this.project.student.id;
|
||||
const myId = window.atob(this.me.id).split(':')[1];
|
||||
const projectId = window.atob(this.project.student.id).split(':')[1];
|
||||
return myId === projectId;
|
||||
},
|
||||
projectEntryCount() {
|
||||
return this.project.entries ? this.project.entries.length : 0;
|
||||
|
|
|
|||
|
|
@ -17,14 +17,16 @@ query ProjectQuery($id: ID!) {
|
|||
|
||||
class ProjectQueryTestCase(SkillboxTestCase):
|
||||
def _test_direct_project_access(self, user: User, should_have_access: bool):
|
||||
result = self.get_client(user).execute(project_query, variables={
|
||||
'id': self.project1.graphql_id
|
||||
})
|
||||
result = self.get_client(user).execute(
|
||||
project_query, variables={"id": self.project1.graphql_id}
|
||||
)
|
||||
self.assertIsNone(result.errors)
|
||||
if should_have_access:
|
||||
self.assertEqual(result.data.get('project').get('id'), self.project1.graphql_id)
|
||||
self.assertEqual(
|
||||
result.data.get("project").get("id"), self.project1.graphql_id
|
||||
)
|
||||
else:
|
||||
self.assertIsNone(result.data.get('project'))
|
||||
self.assertIsNone(result.data.get("project"))
|
||||
|
||||
def setUp(self):
|
||||
self.createDefault()
|
||||
|
|
@ -32,8 +34,8 @@ class ProjectQueryTestCase(SkillboxTestCase):
|
|||
school_class2 = SchoolClassFactory(users=[self.teacher2, self.student2])
|
||||
|
||||
self.project1 = ProjectFactory(student=self.student1)
|
||||
self.project1_id = to_global_id('ProjectNode', self.project1.id)
|
||||
self.query = '''
|
||||
self.project1_id = to_global_id("ProjectNode", self.project1.id)
|
||||
self.query = """
|
||||
query ProjectsQuery {
|
||||
projects {
|
||||
...ProjectParts
|
||||
|
|
@ -50,7 +52,7 @@ class ProjectQueryTestCase(SkillboxTestCase):
|
|||
__typename
|
||||
}
|
||||
|
||||
'''
|
||||
"""
|
||||
|
||||
def test_should_see_own_projects(self):
|
||||
self.assertEqual(Project.objects.count(), 1)
|
||||
|
|
@ -58,7 +60,9 @@ class ProjectQueryTestCase(SkillboxTestCase):
|
|||
result = self.get_client(self.student1).execute(self.query)
|
||||
|
||||
self.assertIsNone(result.errors)
|
||||
self.assertEqual(result.data.get('projects')[0].get('title'), self.project1.title)
|
||||
self.assertEqual(
|
||||
result.data.get("projects")[0].get("title"), self.project1.title
|
||||
)
|
||||
|
||||
def test_should_not_see_other_projects(self):
|
||||
self.assertEqual(Project.objects.count(), 1)
|
||||
|
|
@ -66,13 +70,13 @@ class ProjectQueryTestCase(SkillboxTestCase):
|
|||
result = self.get_client(self.student2).execute(self.query)
|
||||
|
||||
self.assertIsNone(result.errors)
|
||||
self.assertEqual(len(result.data.get('projects')), 0)
|
||||
self.assertEqual(len(result.data.get("projects")), 0)
|
||||
|
||||
def test_teacher_should_not_see_unfinished_projects(self):
|
||||
result = self.get_client().execute(self.query)
|
||||
|
||||
self.assertIsNone(result.errors)
|
||||
self.assertEqual(len(result.data.get('projects')), 0)
|
||||
self.assertEqual(len(result.data.get("projects")), 0)
|
||||
|
||||
def test_teacher_should_only_see_finished_projects(self):
|
||||
self.project1.final = True
|
||||
|
|
@ -82,8 +86,9 @@ class ProjectQueryTestCase(SkillboxTestCase):
|
|||
result = self.get_client().execute(self.query)
|
||||
|
||||
self.assertIsNone(result.errors)
|
||||
self.assertEqual(result.data.get('projects')[0].get('title'),
|
||||
self.project1.title)
|
||||
self.assertEqual(
|
||||
result.data.get("projects")[0].get("title"), self.project1.title
|
||||
)
|
||||
|
||||
def test_other_teacher_should_not_see_projects(self):
|
||||
self.project1.final = True
|
||||
|
|
@ -93,11 +98,13 @@ class ProjectQueryTestCase(SkillboxTestCase):
|
|||
result = self.get_client(self.teacher2).execute(self.query)
|
||||
|
||||
self.assertIsNone(result.errors)
|
||||
self.assertEqual(len(result.data.get('projects')), 0)
|
||||
self.assertEqual(len(result.data.get("projects")), 0)
|
||||
|
||||
def test_class_with_two_teachers_both_can_see_project(self):
|
||||
# create class with two teachers
|
||||
school_class3 = SchoolClassFactory(users=[self.teacher, self.teacher2, self.student1])
|
||||
school_class3 = SchoolClassFactory(
|
||||
users=[self.teacher, self.teacher2, self.student1]
|
||||
)
|
||||
|
||||
self.project1.final = True
|
||||
self.project1.save()
|
||||
|
|
@ -105,16 +112,18 @@ class ProjectQueryTestCase(SkillboxTestCase):
|
|||
# teacher can see project
|
||||
result = self.get_client(self.teacher).execute(self.query)
|
||||
self.assertIsNone(result.errors)
|
||||
self.assertEqual(len(result.data.get('projects')), 1)
|
||||
self.assertEqual(len(result.data.get("projects")), 1)
|
||||
|
||||
# teacher2 can see project
|
||||
result = self.get_client(self.teacher2).execute(self.query)
|
||||
self.assertIsNone(result.errors)
|
||||
self.assertEqual(len(result.data.get('projects')), 1)
|
||||
self.assertEqual(len(result.data.get("projects")), 1)
|
||||
|
||||
def test_class_with_two_teachers_direct_final_project_access(self):
|
||||
# create class with two teachers
|
||||
school_class3 = SchoolClassFactory(users=[self.teacher, self.teacher2, self.student1])
|
||||
school_class3 = SchoolClassFactory(
|
||||
users=[self.teacher, self.teacher2, self.student1]
|
||||
)
|
||||
|
||||
self.project1.final = True
|
||||
self.project1.save()
|
||||
|
|
@ -136,7 +145,6 @@ class ProjectQueryTestCase(SkillboxTestCase):
|
|||
# non-owner can't access project
|
||||
self._test_direct_project_access(self.student2, False)
|
||||
|
||||
|
||||
def test_direct_final_project_access(self):
|
||||
self.project1.final = True
|
||||
self.project1.save()
|
||||
|
|
@ -155,12 +163,14 @@ query ProjectQuery($id: ID!) {
|
|||
project(id: $id) {
|
||||
id
|
||||
student {
|
||||
email
|
||||
fullName
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
result = self.get_client(self.student1).execute(query, variables={
|
||||
'id': self.project1.graphql_id
|
||||
})
|
||||
self.assertEqual(result.data['project']['student']['email'], self.student1.email)
|
||||
result = self.get_client(self.student1).execute(
|
||||
query, variables={"id": self.project1.graphql_id}
|
||||
)
|
||||
self.assertEqual(
|
||||
result.data["project"]["student"]["fullName"], self.student1.full_name
|
||||
)
|
||||
|
|
|
|||
|
|
@ -191,6 +191,32 @@ type PublicUserNode implements Node {
|
|||
id: ID!
|
||||
fullName: String!
|
||||
isMe: Boolean
|
||||
schoolClasses: [SchoolClassNode]
|
||||
}
|
||||
|
||||
type SchoolClassNode implements Node {
|
||||
name: String!
|
||||
code: String
|
||||
|
||||
"""The ID of the object"""
|
||||
id: ID!
|
||||
pk: Int
|
||||
members: [ClassMemberNode]
|
||||
readOnly: Boolean
|
||||
}
|
||||
|
||||
"""
|
||||
We need to build this ourselves, because we want the active property on the node, because providing it on the
|
||||
Connection or Edge for a UserNodeConnection is difficult.
|
||||
"""
|
||||
type ClassMemberNode {
|
||||
user: PublicUserNode
|
||||
active: Boolean
|
||||
firstName: String
|
||||
lastName: String
|
||||
isTeacher: Boolean
|
||||
id: ID
|
||||
isMe: Boolean
|
||||
}
|
||||
|
||||
union HighlightableNode = ContentBlockNode | InstrumentNode | ModuleNode | ChapterNode
|
||||
|
|
@ -226,31 +252,6 @@ interface ContentBlockInterface {
|
|||
|
||||
scalar GenericStreamFieldType
|
||||
|
||||
type SchoolClassNode implements Node {
|
||||
name: String!
|
||||
code: String
|
||||
|
||||
"""The ID of the object"""
|
||||
id: ID!
|
||||
pk: Int
|
||||
members: [ClassMemberNode]
|
||||
readOnly: Boolean
|
||||
}
|
||||
|
||||
"""
|
||||
We need to build this ourselves, because we want the active property on the node, because providing it on the
|
||||
Connection or Edge for a UserNodeConnection is difficult.
|
||||
"""
|
||||
type ClassMemberNode {
|
||||
user: PublicUserNode
|
||||
active: Boolean
|
||||
firstName: String
|
||||
lastName: String
|
||||
isTeacher: Boolean
|
||||
id: ID
|
||||
isMe: Boolean
|
||||
}
|
||||
|
||||
type ContentBlockBookmarkNode implements Node {
|
||||
"""The ID of the object"""
|
||||
id: ID!
|
||||
|
|
|
|||
|
|
@ -157,6 +157,7 @@ class PrivateUserNode(DjangoObjectType):
|
|||
class PublicUserNode(DjangoObjectType):
|
||||
full_name = graphene.String(required=True)
|
||||
is_me = graphene.Boolean()
|
||||
school_classes = graphene.List(SchoolClassNode)
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
|
|
@ -167,6 +168,15 @@ class PublicUserNode(DjangoObjectType):
|
|||
def resolve_is_me(parent: User, info, **kwargs):
|
||||
return info.context.user.pk == parent.pk
|
||||
|
||||
@staticmethod
|
||||
def resolve_school_classes(root: User, info):
|
||||
if root.selected_class is None: # then we don't have any class to return
|
||||
return SchoolClass.objects.none()
|
||||
return SchoolClass.objects.filter(
|
||||
Q(schoolclassmember__active=True, schoolclassmember__user=root)
|
||||
| Q(pk=root.selected_class.pk)
|
||||
).distinct()
|
||||
|
||||
|
||||
class ClassMemberNode(ObjectType):
|
||||
"""
|
||||
|
|
|
|||
Loading…
Reference in New Issue