Merged in feature/hide-assignment-results-from-students (pull request #2)

Feature/hide assignment results from students

Approved-by: Christian Cueni <christian.cueni@iterativ.ch>
This commit is contained in:
Ramon Wenger 2018-10-17 11:16:05 +00:00 committed by Christian Cueni
commit 9135776896
8 changed files with 173 additions and 15 deletions

View File

@ -0,0 +1,16 @@
import random
import factory
from books.factories import ModuleFactory
from .models import Assignment
from core.factories import fake
class AssignmentFactory(factory.django.DjangoModelFactory):
class Meta:
model = Assignment
title = factory.LazyAttribute(lambda x: fake.sentence(nb_words=random.randint(4, 8)))
assignment = factory.LazyAttribute(lambda x: fake.sentence(nb_words=random.randint(4, 8)))
module = factory.SubFactory(ModuleFactory)

View File

@ -25,4 +25,7 @@ class AssignmentNode(DjangoObjectType):
#todo: restrict for students #todo: restrict for students
def resolve_submissions(self, info, **kwargs): def resolve_submissions(self, info, **kwargs):
return self.submissions.all() user = info.context.user
if user.has_perm('users.can_manage_school_class_content'):
return self.submissions.filter(student__in=user.users_in_same_school_class())
return []

View File

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

View File

View File

@ -0,0 +1,129 @@
from django.test import RequestFactory, TestCase
from graphene.test import Client
from graphql_relay import to_global_id
from api.utils import get_graphql_mutation
from assignments.models import Assignment, StudentSubmission
from books.factories import ModuleFactory
from ..factories import AssignmentFactory
from users.models import User
from users.services import create_users
from api.schema import schema
class AssignmentPermissionsTestCase(TestCase):
def setUp(self):
create_users()
self.teacher = User.objects.get(username='teacher')
self.teacher2 = User.objects.get(username='teacher2')
self.student1 = User.objects.get(username='student1')
self.student2 = User.objects.get(username='student2')
self.student_second_class = User.objects.get(username='student_second_class')
self.assignment = AssignmentFactory(
owner=self.teacher
)
self.assignment_id = to_global_id('AssignmentNode', self.assignment.pk)
self.module_id = to_global_id('ModuleNode', self.assignment.module.pk)
def _create_client(self, user):
request = RequestFactory().get('/')
request.user = user
return Client(schema=schema, context_value=request)
def _submit_submission(self, user=None):
mutation = '''
mutation UpdateAssignment($input: UpdateAssignmentInput!) {
updateAssignment(input: $input){
updatedAssignment {
id
title
assignment
submission {
id
text
final
document
}
}
}
}
'''
if user is None:
client = self._create_client(self.student1)
else:
client = self._create_client(user)
return client.execute(mutation, variables={
'input': {
"assignment": {
"id": self.assignment_id,
"answer": 'Halo',
"final": True
}
}
})
def test_permissions(self):
self.assertTrue(self.teacher.has_perm('users.can_manage_school_class_content'))
self.assertTrue(self.teacher2.has_perm('users.can_manage_school_class_content'))
self.assertFalse(self.student1.has_perm('users.can_manage_school_class_content'))
self.assertFalse(self.student2.has_perm('users.can_manage_school_class_content'))
def test_count(self):
self.assertEqual(Assignment.objects.count(), 1)
def test_submit_submission(self):
result = self._submit_submission()
self.assertIsNone(result.get('errors'))
self.assertEqual(StudentSubmission.objects.count(), 1)
def _test_visibility(self, user, count):
client = self._create_client(user)
query = '''
query AssignmentWithSubmissions($id: ID!) {
assignment(id: $id) {
title
submissions {
id
text
document
student {
firstName
lastName
}
}
}
}
'''
result = client.execute(query, variables={
'id': self.assignment_id
})
self.assertIsNone(result.get('errors'))
self.assertEqual(len(result.get('data').get('assignment').get('submissions')), count)
def test_visible_for_teacher(self):
self._submit_submission()
self._test_visibility(self.teacher, 1)
def test_visible_for_teacher2(self):
self._submit_submission()
self._test_visibility(self.teacher2, 0)
def test_visible_for_student1(self):
self._submit_submission()
self._test_visibility(self.student1, 0)
def test_visible_for_student2(self):
self._submit_submission()
self._test_visibility(self.student2, 0)
def test_advanced_visibility(self):
self._submit_submission(self.student1)
self._submit_submission(self.student_second_class)
self._test_visibility(self.teacher, 1)
self._test_visibility(self.teacher2, 1)

View File

@ -33,20 +33,13 @@ class RoleManager(models.Manager):
def create_default_roles(self): def create_default_roles(self):
for key, value in self.DEFAULT_ROLES.items(): for key, value in self.DEFAULT_ROLES.items():
role = self.create(name=value, key=key) role, created = self.get_or_create(name=value, key=key)
role.save()
can_manage_school_class_content, = self._create_default_permissions() can_manage_school_class_content, = self._create_default_permissions()
if key == "teacher": if key == "teacher":
role.role_permission.add(can_manage_school_class_content.id) role.role_permission.add(can_manage_school_class_content.id)
# elif key == "school_admin":
# role.role_permission.add()
#
# elif key == "student":
# role.role_permission.add()
def get_default_teacher_role(self): def get_default_teacher_role(self):
return self._get_default_role(self.TEACHER_KEY) return self._get_default_role(self.TEACHER_KEY)

View File

@ -31,6 +31,9 @@ class User(AbstractUser):
def has_perm(self, perm, obj=None): def has_perm(self, perm, obj=None):
return super(User, self).has_perm(perm, obj) or perm in self.get_all_permissions(obj) return super(User, self).has_perm(perm, obj) or perm in self.get_all_permissions(obj)
def users_in_same_school_class(self):
return User.objects.filter(school_classes__users=self.pk)
class SchoolClass(models.Model): class SchoolClass(models.Model):
name = models.CharField(max_length=100, blank=False, null=False) name = models.CharField(max_length=100, blank=False, null=False)
@ -43,7 +46,6 @@ class SchoolClass(models.Model):
return 'SchoolClass {}-{}-{}'.format(self.id, self.name, self.year) return 'SchoolClass {}-{}-{}'.format(self.id, self.name, self.year)
class Role(models.Model): class Role(models.Model):
key = models.CharField(_('Key'), max_length=100, blank=False, null=False, unique=True) key = models.CharField(_('Key'), max_length=100, blank=False, null=False, unique=True)
name = models.CharField(_('Name'), max_length=100, blank=False, null=False) name = models.CharField(_('Name'), max_length=100, blank=False, null=False)
@ -79,7 +81,6 @@ class Role(models.Model):
) )
class UserRole(models.Model): class UserRole(models.Model):
user = models.ForeignKey(User, blank=False, null=False, on_delete=models.CASCADE, related_name='user_roles') user = models.ForeignKey(User, blank=False, null=False, on_delete=models.CASCADE, related_name='user_roles')
role = models.ForeignKey(Role, blank=False, null=False, on_delete=models.CASCADE, related_name='user_roles') role = models.ForeignKey(Role, blank=False, null=False, on_delete=models.CASCADE, related_name='user_roles')

View File

@ -13,10 +13,29 @@ def create_users(data=None):
teacher = UserFactory(username='teacher') teacher = UserFactory(username='teacher')
UserRole.objects.create(user=teacher, role=teacher_role) UserRole.objects.create(user=teacher, role=teacher_role)
students = []
for i in range(1, 7): for i in range(1, 7):
student = UserFactory(username='student{}'.format(i)) student = UserFactory(username='student{}'.format(i))
UserRole.objects.create(user=student, role=student_role) UserRole.objects.create(user=student, role=student_role)
SchoolClassFactory(users=[teacher, student]) students.append(student)
SchoolClassFactory(
users=[teacher] + students,
year='2018',
name='skillbox'
)
teacher2 = UserFactory(username='teacher2')
UserRole.objects.create(user=teacher2, role=teacher_role)
student_second_class = UserFactory(username='student_second_class')
UserRole.objects.create(user=student_second_class, role=student_role)
SchoolClassFactory(
users=[teacher2, student_second_class],
year='2018',
name='second_class'
)
else: else:
for school_class in data: for school_class in data: