Adjust permissions, add unit tests
This commit is contained in:
parent
0eba96fd5e
commit
b0591d9c7e
|
|
@ -26,7 +26,8 @@ from users.schema import AllUsersQuery, UsersQuery, ProfileMutations
|
|||
|
||||
|
||||
class Query(UsersQuery, AllUsersQuery, ModuleRoomsQuery, RoomsQuery, ObjectivesQuery, BookQuery, AssignmentsQuery,
|
||||
StudentSubmissionQuery, InstrumentQuery, PortfolioQuery, SurveysQuery, AllNewsTeasersQuery, graphene.ObjectType):
|
||||
StudentSubmissionQuery, InstrumentQuery, PortfolioQuery, SurveysQuery, AllNewsTeasersQuery,
|
||||
graphene.ObjectType):
|
||||
node = relay.Node.Field()
|
||||
|
||||
if settings.DEBUG:
|
||||
|
|
@ -34,8 +35,8 @@ class Query(UsersQuery, AllUsersQuery, ModuleRoomsQuery, RoomsQuery, ObjectivesQ
|
|||
|
||||
|
||||
class Mutation(BookMutations, RoomMutations, AssignmentMutations, ObjectiveMutations, OauthMutations,
|
||||
PortfolioMutations, ProfileMutations, SurveyMutations, NoteMutations, SpellCheckMutations,
|
||||
graphene.ObjectType):
|
||||
PortfolioMutations, ProfileMutations, SurveyMutations, NoteMutations, SpellCheckMutations,
|
||||
graphene.ObjectType):
|
||||
if settings.DEBUG:
|
||||
debug = graphene.Field(DjangoDebug, name='_debug')
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ from graphql_relay import from_global_id
|
|||
from rest_framework.exceptions import PermissionDenied
|
||||
|
||||
from api.utils import get_object
|
||||
from assignments.models import Assignment, SubmissionFeedback
|
||||
from assignments.models import Assignment, StudentSubmission, SubmissionFeedback
|
||||
from assignments.schema.types import AssignmentNode, StudentSubmissionNode, SubmissionFeedbackNode
|
||||
from .inputs import AssignmentInput, SubmissionFeedbackInput
|
||||
|
||||
|
|
@ -57,18 +57,23 @@ class UpdateSubmissionFeedback(relay.ClientIDMutation):
|
|||
submission_feedback_data = kwargs.get('submission_feedback')
|
||||
user = info.context.user
|
||||
student_submission_id = from_global_id(submission_feedback_data['student_submission'])[1]
|
||||
student_submission = StudentSubmission.objects.get(id=student_submission_id)
|
||||
|
||||
if not user.is_teacher():
|
||||
if not user.is_teacher() or not student_submission.student in user.users_in_active_school_class():
|
||||
raise PermissionDenied('Missing permissions')
|
||||
|
||||
# todo: replace with middleware
|
||||
if user.read_only:
|
||||
raise PermissionError('No valid license')
|
||||
|
||||
(submission_feedback, created) = SubmissionFeedback.objects.get_or_create(student_submission_id=student_submission_id)
|
||||
(submission_feedback, created) = SubmissionFeedback.objects.get_or_create(
|
||||
student_submission_id=student_submission_id,
|
||||
defaults={
|
||||
'teacher': user
|
||||
})
|
||||
|
||||
|
||||
final = submission_feedback_data.get('final') if 'final' in submission_feedback_data else submission_feedback.final
|
||||
final = submission_feedback_data.get(
|
||||
'final') if 'final' in submission_feedback_data else submission_feedback.final
|
||||
|
||||
submission_feedback.teacher = user
|
||||
submission_feedback.final = final
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import graphene
|
||||
from graphene import relay
|
||||
|
||||
from api.utils import get_object
|
||||
from assignments.models import StudentSubmission
|
||||
from assignments.schema.types import AssignmentNode, StudentSubmissionNode
|
||||
|
||||
|
||||
|
|
@ -9,5 +11,14 @@ class AssignmentsQuery(object):
|
|||
assignments = graphene.List(AssignmentNode)
|
||||
|
||||
|
||||
class StudentSubmissionQuery(object):
|
||||
student_submission = relay.Node.Field(StudentSubmissionNode)
|
||||
|
||||
class StudentSubmissionQuery:
|
||||
student_submission = graphene.Field(StudentSubmissionNode, id=graphene.ID(required=True))
|
||||
|
||||
def resolve_student_submission(root, info, *args, **kwargs):
|
||||
user = info.context.user
|
||||
id = kwargs.get('id')
|
||||
submission = get_object(StudentSubmission, id)
|
||||
if user == submission.student or (user.is_teacher() and submission.student in user.users_in_active_school_class()):
|
||||
return root
|
||||
return None
|
||||
|
|
|
|||
|
|
@ -22,19 +22,20 @@ class StudentSubmissionNode(DjangoObjectType):
|
|||
filter_fields = []
|
||||
interfaces = (relay.Node,)
|
||||
|
||||
def resolve_submission_feedback(self, info, **kwargs):
|
||||
@staticmethod
|
||||
def resolve_submission_feedback(root: StudentSubmission, info, **kwargs):
|
||||
user = info.context.user
|
||||
|
||||
if not hasattr(self, 'submission_feedback'):
|
||||
if not hasattr(root, 'submission_feedback'):
|
||||
return None
|
||||
|
||||
# teacher path
|
||||
if user.is_teacher():
|
||||
return self.submission_feedback
|
||||
if user.is_teacher() and root.student in user.users_in_active_school_class():
|
||||
return root.submission_feedback
|
||||
|
||||
# student path
|
||||
if self.submission_feedback.final:
|
||||
return self.submission_feedback
|
||||
if root.submission_feedback.final:
|
||||
return root.submission_feedback
|
||||
|
||||
return None
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ class SubmissionFeedbackTestCase(SkillboxTestCase):
|
|||
self.student_submission_id = to_global_id('StudentSubmissionNode', self.student_submission.pk)
|
||||
|
||||
school_class = SchoolClassFactory()
|
||||
for user in [self.student1, self.teacher, self.teacher2]:
|
||||
for user in [self.student1, self.teacher]:
|
||||
SchoolClassMember.objects.create(
|
||||
user=user,
|
||||
school_class=school_class
|
||||
|
|
@ -94,6 +94,24 @@ class SubmissionFeedbackTestCase(SkillboxTestCase):
|
|||
'id': self.assignment_id
|
||||
})
|
||||
|
||||
def _fetch_submission_teacher(self, user):
|
||||
client = self.get_client(user)
|
||||
query = '''
|
||||
query StudentSubmission($id: ID!) {
|
||||
studentSubmission(id: $id) {
|
||||
id
|
||||
text
|
||||
document
|
||||
submissionFeedback {
|
||||
text
|
||||
}
|
||||
}
|
||||
}
|
||||
'''
|
||||
return client.execute(query, variables={
|
||||
'id': self.student_submission_id
|
||||
})
|
||||
|
||||
def _fetch_submission_feedback(self, user):
|
||||
client = create_client(user)
|
||||
query = '''
|
||||
|
|
@ -125,6 +143,8 @@ class SubmissionFeedbackTestCase(SkillboxTestCase):
|
|||
def test_student_cannot_create_feedback(self):
|
||||
result = self._create_submission_feedback(self.student1, False, 'Balalal', self.student_submission_id)
|
||||
self.assertIsNotNone(result.errors)
|
||||
self.assertEqual(len(result.errors), 1)
|
||||
self.assertEqual(result.errors[0].get('message'), 'Missing permissions')
|
||||
|
||||
def test_teacher_can_update_feedback(self):
|
||||
assignment = AssignmentFactory(
|
||||
|
|
@ -146,7 +166,7 @@ class SubmissionFeedbackTestCase(SkillboxTestCase):
|
|||
self.assertTrue(submission_feedback_response.get('final'))
|
||||
self.assertEqual(submission_feedback_response.get('text'), 'Some')
|
||||
|
||||
def test_rogue_teacher_cannot_update_feedback(self):
|
||||
def test_external_teacher_cannot_update_feedback(self):
|
||||
assignment = AssignmentFactory(
|
||||
owner=self.teacher
|
||||
)
|
||||
|
|
@ -183,11 +203,21 @@ class SubmissionFeedbackTestCase(SkillboxTestCase):
|
|||
self.assertEqual(result.data.get('assignment').get('submissions')[0].get('submissionFeedback')
|
||||
.get('text'), submission_feedback.text)
|
||||
|
||||
def test_rogue_teacher_cannot_see_feedback(self):
|
||||
def test_external_teacher_cannot_see_assignment_with_feedback(self):
|
||||
SubmissionFeedbackFactory(teacher=self.teacher, final=False,
|
||||
student_submission=self.student_submission)
|
||||
self.student_submission.final = True
|
||||
self.student_submission.save()
|
||||
|
||||
result = self._fetch_assignment_teacher(self.teacher2)
|
||||
self.assertIsNone(result.data.get('assignment').get('submissions')[0].get('submissionFeedback'))
|
||||
self.assertEqual(result.data.get('assignment').get('submissions'), [])
|
||||
|
||||
def test_external_teacher_cannot_see_feedback(self):
|
||||
SubmissionFeedbackFactory(teacher=self.teacher, final=False,
|
||||
student_submission=self.student_submission)
|
||||
self.student_submission.final = True
|
||||
self.student_submission.save()
|
||||
|
||||
result = self._fetch_submission_teacher(self.teacher2)
|
||||
self.assertIsNone(result.errors)
|
||||
self.assertIsNone(result.data.get('studentSubmission'))
|
||||
|
|
|
|||
Loading…
Reference in New Issue