def test_gdpr(self): user = factory.Student() user2 = factory.Student() admin = factory.Admin() # Test if users cant access other data api.get(self, 'users/GDPR', params={'pk': user2.pk}, user=user, status=403) # Test all the gdpr calls for _ in range( int(api_settings.DEFAULT_THROTTLE_RATES['gdpr'].split('/') [0])): api.get(self, 'users/GDPR', params={'pk': 0}, user=user) # Test timeout api.get(self, 'users/GDPR', params={'pk': 0}, user=user, status=429) # Test admin api.get(self, 'users/GDPR', params={'pk': user.pk}, user=admin) # Test no timeout for admin for _ in range( int(api_settings.DEFAULT_THROTTLE_RATES['gdpr'].split('/') [0])): api.get(self, 'users/GDPR', params={'pk': 0}, user=admin) api.get(self, 'users/GDPR', params={'pk': 0}, user=admin)
def setUp(self): self.admin = factory.Admin() self.student = factory.Student() self.journal = factory.Journal(user=self.student) self.TA = factory.Student() nfac.make_participation( user=self.TA, course=self.journal.assignment.courses.first(), role=self.journal.assignment.courses.first().role_set.get( name='TA')) self.teacher = self.journal.assignment.courses.first().author self.comment = factory.StudentComment( entry__node__journal=self.journal) self.TA_comment = nfac.make_comment(self.comment.entry, self.TA, 'TA comment', False) self.teacher_comment = nfac.make_comment(self.comment.entry, self.teacher, 'Teacher comment', False) set_entry_comment_counts(self) assert self.teacher.has_permission('can_grade', self.journal.assignment), \ 'Teacher requires can_grade permission in the relevant assignment' assert self.TA.has_permission('can_grade', self.journal.assignment), \ 'TA requires can_grade permission in the relevant assignment' assert not self.teacher_comment.published, 'Teacher comment should be unpublished.' assert not self.TA_comment.published, 'TA comment should be unpublished.' assert self.entry_comments == 3, 'Journal should have 3 comments total' assert self.entry_published_comments == 1, 'Journal should have 3 comments of which only one is published' assert self.entry_unpublished_comments == 2, 'Expected 2 unpublished comments'
def test_update(self): user = factory.Student() user2 = factory.Student() admin = factory.Admin() # Test update the own user old_username = user.username resp = api.update(self, 'users', params={ 'pk': 0, 'username': '******', 'full_name': 'abc' }, user=user)['user'] assert resp[ 'username'] == old_username, 'Username should not be updated' assert resp['full_name'] == 'abc', 'Firstname should be updated' # Test update user as admin resp = api.update(self, 'users', params={ 'pk': user.pk, 'full_name': 'not_admin' }, user=admin)['user'] assert resp['full_name'] == 'not_admin', 'Firstname should be updated' # Test update other user as user api.update(self, 'users', params={ 'pk': user.pk, 'full_name': 'not_admin' }, user=user2, status=403) is_test_student = factory.TestUser(lti_id=None) resp = api.update(self, 'users', user=is_test_student, params={ 'email': '*****@*****.**', 'pk': is_test_student.pk })['user'] is_test_student = User.objects.get(pk=is_test_student.pk) assert is_test_student.is_test_student, 'Test student status should remain intact after updating email.' assert not is_test_student.verified_email, 'Updating email without LTI should not validate said email.' assert resp['email'] == '*****@*****.**', 'Email should be updated'
def test_rest(self): # Test the basic rest functionality as a superuser api.test_rest(self, 'assignments', create_params=self.create_params, get_params={'course_id': self.course.pk}, update_params={'description': 'test_description2'}, delete_params={'course_id': self.course.pk}, user=factory.Admin()) # Test the basic rest functionality as a teacher api.test_rest(self, 'assignments', create_params=self.create_params, get_params={'course_id': self.course.pk}, update_params={'description': 'test_description2'}, delete_params={'course_id': self.course.pk}, user=self.teacher) # Test the basic rest functionality as a student api.test_rest(self, 'assignments', create_params=self.create_params, create_status=403, user=factory.Student())
def test_get(self): student = factory.Student() assignment = factory.Assignment(courses=[self.course]) api.get(self, 'assignments', params={'pk': assignment.pk}, user=student, status=403) factory.Participation(user=student, course=self.course, role=Role.objects.get(course=self.course, name='Student')) resp = api.get(self, 'assignments', params={ 'pk': assignment.pk, 'course_id': self.course.pk }, user=student)['assignment'] assert resp[ 'journal'] is not None, 'Response should include student serializer' resp = api.get(self, 'assignments', params={ 'pk': assignment.pk, 'course_id': self.course.pk }, user=self.teacher)['assignment'] assert resp[ 'journals'] is not None, 'Response should include teacher serializer'
def test_password(self): user = factory.Student() user_factory.DEFAULT_PASSWORD # Test with wrong password api.update(self, 'users/password', params={ 'old_password': '******', 'new_password': '******' }, user=user, status=400) # Test with invalid new password api.update(self, 'users/password', params={ 'old_password': user_factory.DEFAULT_PASSWORD, 'new_password': '******' }, user=user, status=400) # Test with valid new password api.update(self, 'users/password', params={ 'old_password': user_factory.DEFAULT_PASSWORD, 'new_password': '******' }, user=user)
def test_update(self): assignment = api.create(self, 'assignments', params=self.create_params, user=self.teacher)['assignment'] # Try to publish the assignment # TODO: Test cannot unpublish when there are entries inside api.update(self, 'assignments', params={ 'pk': assignment['id'], 'published': True }, user=factory.Student(), status=403) api.update(self, 'assignments', params={ 'pk': assignment['id'], 'published': True }, user=self.teacher) api.update(self, 'assignments', params={ 'pk': assignment['id'], 'published': True }, user=factory.Admin())
def test_update(self): # Check if students cannot update journals api.update(self, 'journals', params={'pk': self.journal.pk}, user=self.student, status=403) # Check if teacher can only update the published state api.update(self, 'journals', params={'pk': self.journal.pk}, user=self.teacher, status=403) api.update(self, 'journals', params={'pk': self.journal.pk, 'published': True}, user=self.teacher) # Check if the admin can update the journal api.update(self, 'journals', params={'pk': self.journal.pk, 'user': factory.Student().pk}, user=factory.Admin())
def setUp(self): self.create_params = {'name': 'test_course', 'abbreviation': 'TC'} self.student = factory.Student() self.teacher1 = factory.Teacher() self.teacher2 = factory.Teacher() self.admin = factory.Admin() self.course1 = factory.Course(author=self.teacher1) self.course2 = factory.Course(author=self.teacher1) self.course3 = factory.Course(author=self.teacher2)
def test_login(self): user = factory.Student() old_last_login = User.objects.get(pk=user.pk).last_login api.login(self, user) assert old_last_login != User.objects.get( pk=user.pk).last_login, 'Last login should be updated' old_last_login = User.objects.get(pk=user.pk).last_login api.login(self, user, password="******", status=401) assert old_last_login == User.objects.get( pk=user.pk).last_login, 'Last login should not be updated'
def setUp(self): self.student = factory.Student() self.journal = factory.Journal(user=self.student) self.teacher = self.journal.assignment.courses.first().author self.unrelated_assignment = factory.Assignment() self.video = SimpleUploadedFile('file.mp4', b'file_content', content_type='video/mp4') self.student_download_url = reverse('VLE:user-download', kwargs={'pk': self.student.pk}) self.upload_url = reverse('VLE:user-upload')
def test_names(self): assignment = self.journal.assignment course = assignment.courses.first() url = 'names/{}/{}/{}'.format(course.id, assignment.id, self.journal.id) # Check if these users can view the names api.get(self, url, user=self.student) api.get(self, url, user=self.teacher) api.get(self, url, user=factory.Admin()) # CHeck if a random student cannot view the names api.get(self, url, user=factory.Student(), status=403)
def test_create(self): api.create(self, 'comments', params={ 'entry_id': self.comment.entry.pk, 'text': 'test-create-comment' }, user=self.student) comment = api.create(self, 'comments', params={ 'entry_id': self.comment.entry.pk, 'text': 'test-create-comment', 'published': False }, user=self.student)['comment'] assert comment[ 'published'], 'Student should not be able to post unpublished comments' comment = api.create(self, 'comments', params={ 'entry_id': self.comment.entry.pk, 'text': 'test-create-comment', 'published': False }, user=self.teacher)['comment'] assert not comment['published'], 'Comment should not be published' comment = api.create(self, 'comments', params={ 'entry_id': self.comment.entry.pk, 'text': 'test-create-comment', 'published': True }, user=self.teacher)['comment'] assert comment['published'], 'Comment should be published' api.create(self, 'comments', params={ 'entry_id': self.comment.entry.pk, 'text': 'test-create-comment', 'published': True }, user=factory.Student(), status=403) set_entry_comment_counts(self)
def setUp(self): """Setup.""" self.student = factory.Student() self.teacher = factory.Teacher() self.course = factory.LtiCourse(author=self.teacher) self.assignment = factory.LtiAssignment(author=self.teacher, courses=[self.course]) self.journal = factory.Journal( assignment=self.assignment, user=self.student, sourcedid='f6d552', grade_url= 'https://uvadlo-tes.instructure.com/api/lti/v1/tools/267/grade_passback' )
def test_get(self): comments = api.get(self, 'comments', params={'entry_id': self.teacher_comment.entry.pk}, user=self.student)['comments'] assert len( comments ) == self.entry_published_comments, 'Student can only see published comments' api.get(self, 'comments', params={'pk': self.teacher_comment.pk}, user=self.student, status=403) api.get(self, 'comments', params={'pk': self.teacher_comment.pk}, user=self.teacher) comments = api.get(self, 'comments', params={'entry_id': self.comment.entry.pk}, user=self.teacher)['comments'] assert len( comments ) == self.entry_comments, 'Teacher should be able to see all comments' self.teacher_comment.published = True self.teacher_comment.save() self.entry_published_comments = self.entry_published_comments + 1 self.entry_unpublished_comments = self.entry_unpublished_comments - 1 comments = api.get(self, 'comments', params={'entry_id': self.teacher_comment.entry.pk}, user=self.student)['comments'] assert len( comments ) == self.entry_published_comments, 'Student should be able to see published comments' api.get(self, 'comments', params={'entry_id': self.comment.entry.pk}, user=factory.Student(), status=403) api.get(self, 'comments', params={'entry_id': self.comment.entry.pk}, user=factory.Admin())
def test_delete(self): user = factory.Student() user2 = factory.Student() user3 = factory.Student() admin = factory.Admin() admin2 = factory.Admin() # Test to delete user as other user api.delete(self, 'users', params={'pk': user2.pk}, user=user, status=403) # Test to delete own user api.delete(self, 'users', params={'pk': user.pk}, user=user) api.get(self, 'users', params={'pk': user.pk}, user=admin, status=404) api.delete(self, 'users', params={'pk': 0}, user=user2) api.get(self, 'users', params={'pk': user2.pk}, user=admin, status=404) # Test to delete user as admin api.delete(self, 'users', params={'pk': user3.pk}, user=admin) api.get(self, 'users', params={'pk': user3.pk}, user=admin, status=404) # Test to see if the last admin cannot be removed api.delete(self, 'users', params={'pk': admin2.pk}, user=admin) api.delete(self, 'users', params={'pk': admin.pk}, user=admin, status=400) api.get(self, 'users', params={'pk': admin2.pk}, user=admin, status=404)
def test_get(self): student = factory.Student() admin = factory.Admin() journal = factory.Journal(user=student) teacher = journal.assignment.courses.first().author # Test get all users api.get(self, 'users', user=student, status=403) resp = api.get(self, 'users', user=admin)['users'] assert len(resp) == User.objects.count( ), 'Test if the admin got all the users' # Test get own user resp = api.get(self, 'users', params={'pk': 0}, user=student)['user'] assert 'id' in resp, 'Test if the student got userdata' assert 'verified_email' in resp, 'Test if the student got all their userdata' resp = api.get(self, 'users', params={'pk': 0}, user=admin)['user'] assert resp[ 'is_superuser'], 'Admin user should be flagged as superuser.' # Check if a user cant see other users data api.get(self, 'users', params={'pk': admin.pk}, user=student, status=403) # Test get user as supervisor assert permissions.is_user_supervisor_of( teacher, student), 'Teacher should be supervisor of student' resp = api.get(self, 'users', params={'pk': student.pk}, user=teacher)['user'] assert 'username' in resp, 'Supervisor can retrieve basic supervisee data' assert 'full_name' in resp, 'Supervisor can retrieve basic supervisee data' assert 'verified_email' not in resp, 'Supervisor can\'t retrieve all supervisee data' assert 'email' not in resp, 'Supervisor can\'t retrieve all supervisee data' # Test get user as admin resp = api.get(self, 'users', params={'pk': student.pk}, user=admin)['user'] assert 'id' in resp, 'Admin can retrieve basic user data' assert 'verified_email' in resp, 'Admin can retrieve all user data' assert 'email' in resp, 'Admin can retrieve all user data'
def setUp(self): self.teacher = factory.Teacher() self.course = factory.Course(author=self.teacher) factory.Assignment(courses=[self.course]) participation = factory.Participation(course=self.course) self.student = participation.user # Username is 4 chartacters for the unenrolled check self.not_connected = factory.Student(username='******', full_name='Not Connected') self.create_params = { 'course_id': self.course.pk, 'user_id': self.not_connected.pk } self.group1 = factory.Group(course=self.course) self.group2 = factory.Group(course=self.course) self.update_params = { 'pk': self.course.pk, 'user_id': self.student.pk, 'role': 'Teacher' }
def test_rest(self): # Test the basic rest functionality as a superuser api.test_rest(self, 'courses', create_params=self.create_params, update_params={'abbreviation': 'TC2'}, user=factory.Admin()) # Test the basic rest functionality as a teacher api.test_rest(self, 'courses', create_params=self.create_params, update_params={'abbreviation': 'TC2'}, user=factory.Teacher()) # Test the basic rest functionality as a student api.test_rest(self, 'courses', create_params=self.create_params, create_status=403, user=factory.Student())
def test_recover_password(self): api.post(self, 'recover_password', status=400) # Test invalid token api.post(self, 'recover_password', params={ 'username': self.student.username, 'recovery_token': 'invalid_token', 'new_password': self.valid_pass }, status=400) # Test invalid password token = PasswordResetTokenGenerator().make_token(self.student) api.post(self, 'recover_password', params={ 'username': self.student.username, 'recovery_token': token, 'new_password': '******' }, status=400) # Test invalid username api.post(self, 'recover_password', params={ 'username': factory.Student().username, 'recovery_token': token, 'new_password': self.valid_pass }, status=400) # Test everything valid api.post(self, 'recover_password', params={ 'username': self.student.username, 'recovery_token': token, 'new_password': self.valid_pass })
def test_verify_email(self): api.post(self, 'verify_email', status=400) # Test invalid token api.post(self, 'verify_email', params={ 'username': self.not_verified.username, 'token': 'invalid_token' }, status=400) # Test invalid username token = PasswordResetTokenGenerator().make_token(self.not_verified) api.post(self, 'verify_email', params={ 'username': factory.Student().username, 'token': token }, status=400) # Test everything valid resp = api.post(self, 'verify_email', params={ 'username': self.not_verified.username, 'token': token }) assert VLE.models.User.objects.get( pk=self.not_verified.pk).verified_email assert 'Success' in resp['description'] # Test already verified token = PasswordResetTokenGenerator().make_token(self.student) resp = api.post(self, 'verify_email', params={ 'username': self.student.username, 'token': token }) assert 'already verified' in resp['description']
def test_update(self): # TODO: Improve template testing api.update(self, 'formats', params={ 'pk': self.assignment.pk, 'assignment_details': None, 'templates': [], 'presets': [], 'removed_presets': [], 'removed_templates': [] }, user=factory.Student(), status=403) api.update(self, 'formats', params={ 'pk': self.assignment.pk, 'assignment_details': None, 'templates': [], 'presets': [], 'removed_presets': [], 'removed_templates': [] }, user=self.teacher) api.update(self, 'formats', params={ 'pk': self.assignment.pk, 'assignment_details': None, 'templates': [], 'presets': [], 'removed_presets': [], 'removed_templates': [] }, user=factory.Admin())
def test_get(self): # Test list only done by teachers api.get(self, 'roles', params={'course_id': self.course.pk}, user=self.student, status=403) api.get(self, 'roles', params={'course_id': self.course.pk}, user=self.teacher) # Test not in course/assignment api.get(self, 'roles', params={ 'pk': 0, 'course_id': self.course.pk }, user=factory.Student(), status=403) api.get(self, 'roles', params={ 'pk': 0, 'assignment_id': self.assignment.pk }, user=factory.Student(), status=403) # Test get own role api.get(self, 'roles', params={ 'pk': 0, 'course_id': self.course.pk }, user=self.student) api.get(self, 'roles', params={ 'pk': 0, 'assignment_id': self.assignment.pk }, user=self.student) api.get(self, 'roles', params={ 'pk': self.student.pk, 'course_id': self.course.pk }, user=self.student) # Test other role api.get(self, 'roles', params={ 'pk': self.teacher.pk, 'course_id': self.course.pk }, user=self.student, status=403) api.get(self, 'roles', params={ 'pk': self.student.pk, 'course_id': self.course.pk }, user=self.teacher)
def test_lti_update(self): # Valid LTI coupling to pre-existing account user = factory.Student(verified_email=False) resp = api.update(self, 'users', user=user, params={ **gen_jwt_params(params={ 'user_id': 'valid_id1', 'custom_user_full_name': 'new full name', 'custom_user_email': '*****@*****.**', 'custom_user_image': 'https://new.com/img.png', }, user=user), 'pk': user.pk, })['user'] user = User.objects.get(pk=user.pk) assert user.lti_id, 'Pre-existing user should now be linked via LTI' assert resp[ 'full_name'] == 'new full name' and user.full_name == 'new full name', 'Full name should be updated' assert user.verified_email, 'Updating email via LTI should also verify it' assert resp[ 'email'] == '*****@*****.**' and user.email == '*****@*****.**', 'Email should be updated' assert user.profile_picture == 'https://new.com/img.png', 'Profile picture should be updated.' # Cannot couple an account using an already known LTI id user2 = factory.Student() resp = api.update(self, 'users', user=user2, params={ **gen_jwt_params(params={'user_id': user.lti_id}, user=user2), 'pk': user2.pk, }, status=400) assert 'lti id already exists' in resp['description'] # Cannot link to a user when the email address is already claimed resp = api.update( self, 'users', user=user2, params={ **gen_jwt_params(params={'custom_user_email': user.email}), 'pk': user2.pk, }, status=400) assert 'is taken' in resp[ 'description'], 'Cannot link to a user when the email address is already claimed' # It is forbidden to link a test account to an existing account lti_teacher = factory.LtiTeacher() resp = api.update( self, 'users', user=lti_teacher, params={ **gen_jwt_params(params=factory.JWTTestUserParams()), 'pk': 0, }, status=403) teacher = factory.Teacher() resp = api.update( self, 'users', user=teacher, params={ **gen_jwt_params(params=factory.JWTTestUserParams()), 'pk': 0, }, status=403)
def setUp(self): self.student = factory.Student() self.not_verified = factory.Student(verified_email=False) self.is_test_student = factory.TestUser() self.valid_pass = '******'
def setUp(self): self.student = factory.Student() self.journal = factory.Journal(user=self.student) self.teacher = self.journal.assignment.courses.first().author
def test_unenrolled(self): api.get(self, 'participations/unenrolled', params={ 'course_id': self.course.pk, 'unenrolled_query': '' }, user=self.student, status=403) resp = api.get(self, 'participations/unenrolled', params={ 'course_id': self.course.pk, 'unenrolled_query': '' }, user=self.teacher) assert len(resp['participants']) == 0 # Check perfect name that is small resp = api.get(self, 'participations/unenrolled', params={ 'course_id': self.course.pk, 'unenrolled_query': self.not_connected.username }, user=self.teacher) assert len(resp['participants']) == 1 # Check first and last name resp = api.get(self, 'participations/unenrolled', params={ 'course_id': self.course.pk, 'unenrolled_query': self.not_connected.full_name[:5] + ' ' + 'invalid_last_name' }, user=self.teacher) assert len(resp['participants']) == 0 resp = api.get(self, 'participations/unenrolled', params={ 'course_id': self.course.pk, 'unenrolled_query': self.not_connected.full_name }, user=self.teacher) assert len(resp['participants']) == 1 # Check subnames of longer names other_not_conn = factory.Student( username='******', full_name='longfirstname longlastname') resp = api.get(self, 'participations/unenrolled', params={ 'course_id': self.course.pk, 'unenrolled_query': other_not_conn.full_name[:6] }, user=self.teacher) assert len(resp['participants']) == 1 resp = api.get(self, 'participations/unenrolled', params={ 'course_id': self.course.pk, 'unenrolled_query': other_not_conn.full_name[-6:] }, user=self.teacher) assert len(resp['participants']) == 1 resp = api.get(self, 'participations/unenrolled', params={ 'course_id': self.course.pk, 'unenrolled_query': other_not_conn.username[:6] }, user=self.teacher) assert len(resp['participants']) == 1 # Check too small, not found resp = api.get(self, 'participations/unenrolled', params={ 'course_id': self.course.pk, 'unenrolled_query': other_not_conn.full_name[:4] }, user=self.teacher) assert len(resp['participants']) == 0