def test_student_cannot_download_answer_file_not_owned(self): s_exercise = SubmissionExercise.objects.get(name="T1 TEXT") r_exercise = ReviewExercise.objects.get(name="T1 TEXT REVIEW") sub = OriginalSubmission(course=self.course, text="juups", submitter_user=self.s1, exercise=s_exercise) sub.save() r_exercise.question_order = ['3'] r_exercise.save() rev_sub = ReviewSubmission(course=self.course, reviewed_submission=sub, submitter_user=self.s2, exercise=r_exercise) rev_sub.save() temp_file = SimpleUploadedFile(name='lorem_ipsum.txt', content=bytearray('jada jada', 'utf-8')) answer_with_file = Answer( question=Question.objects.get(pk=3), submission=rev_sub, uploaded_file=temp_file, ) answer_with_file.save() request = self.factory.get( f'/courses/prog1/F2018/submissions/download/{answer_with_file.pk}/?type=answer' ) request.user = self.s3 self.kwargs['pk'] = answer_with_file.pk self.assertRaises(PermissionDenied, DownloadSubmissionView.as_view(), request, **self.kwargs) g = StudentGroup(name="g1", course=self.course, student_usernames=[self.s1.email, self.s3.email]) g.save() sub.submitter_group = g sub.save() for user in self.students + [self.t1]: request = self.factory.get( f'/courses/prog1/F2018/submissions/download/{answer_with_file.pk}/?type=answer' ) request.user = user self.kwargs['pk'] = answer_with_file.pk if user == self.s4: self.assertRaises(PermissionDenied, DownloadSubmissionView.as_view(), request, **self.kwargs) else: response = DownloadSubmissionView.as_view()(request, **self.kwargs) self.assertEqual(response.status_code, 200)
def post(self, *args, **kwargs): """ TODO: error checking """ self.object = self.get_object() ctx = self.get_context_data() exercise = self.object as_student_form = ChooseStudentForm(self.request.POST, exercise=exercise) answers_valid, answer_forms = ReviewExerciseDetailView._validate_forms(self) if answers_valid and as_student_form.is_valid(): rsub = ReviewSubmission(course=ctx['course'], exercise=self.object, reviewed_submission=as_student_form.cleaned_data['reviewed_submission'], submitter_user=as_student_form.cleaned_data['submitter_user']) if exercise.use_groups: rsub.submitter_group = as_student_form.cleaned_data['submitter_group'] rsub.save() ReviewExerciseDetailView._save_modelform_answers(self, answer_forms, rsub) messages.success(self.request, 'Submission successful! You may see it below.') return redirect(rsub) ctx['forms'] = answer_forms ctx['choose_student_form'] = as_student_form return self.render_to_response(ctx)
def test_student_cannot_download_hide_from_receiver_answer_file(self): s_exercise = SubmissionExercise.objects.get(name="T1 TEXT") r_exercise = ReviewExercise.objects.get(name="T1 TEXT REVIEW") sub = OriginalSubmission(course=self.course, text="juups", submitter_user=self.s1, exercise=s_exercise) sub.save() r_exercise.question_order = ['3'] r_exercise.save() rev_sub = ReviewSubmission(course=self.course, reviewed_submission=sub, submitter_user=self.s2, exercise=r_exercise) rev_sub.save() temp_file = SimpleUploadedFile(name='lorem_ipsum.txt', content=bytearray('jada jada', 'utf-8')) question = Question.objects.get(pk=3) answer_with_file = Answer( question=question, submission=rev_sub, uploaded_file=temp_file, ) answer_with_file.save() request = self.factory.get( f'/courses/prog1/F2018/submissions/download/{answer_with_file.pk}/?type=answer' ) request.user = self.s1 self.kwargs['pk'] = answer_with_file.pk self.assertEqual( DownloadSubmissionView.as_view()(request, **self.kwargs).status_code, 200) question.hide_from_receiver = True question.save() self.assertRaises(PermissionDenied, DownloadSubmissionView.as_view(), request, **self.kwargs)
def test_studentCannotSubmitMultipleTimes(self): # student cannot submit multiple times SubmissionExercises for s in [self.s1, self.s2]: self.create_originalsubmission_for(self.SE1, s) res = self.get(self.SE1, s) self.assertContains( res, "You have reached the maximum number of submissions") self.assertEqual(res.context_data['disable_form'], True) # this will try to post (the form is disabled but the user could use devtools) -> should not succeed res = self.post(self.SE1, s, {'text': 'bla'}) self.assertContains(res, "You cannot submit") self.assertEqual(res.context_data['disable_form'], True) self.assertEqual(OriginalSubmission.objects.count(), 2) # this will create two reviewlocks since both loaded the page for s in [self.s1, self.s2]: res = self.get(self.RE1, s) self.assertContains( res, f"text by {self.s1 if s == self.s2 else self.s2}") self.assertEqual(ReviewLock.objects.all().count(), 2) # after submissions are created, no more reviews can be made for s in [self.s1, self.s2]: rsub = ReviewSubmission(course=self.course, exercise=self.RE1, submitter_user=s, reviewed_submission=ReviewLock.objects.get( user=s).original_submission) rsub.save_and_destroy_lock() res = self.get(self.RE1, s) self.assertContains( res, 'You have already submitted your peer-reviews to this exercise.' )
def test_save_and_destroy_lock_reviewsubmission(self): os = OriginalSubmission(course=self.course, exercise=self.se, submitter_user=self.s1, text="jadajada") os.save() rl = ReviewLock(review_exercise=self.re, user=self.s2, original_submission=os) rl.save() rs = ReviewSubmission(course=self.course, exercise=self.re, submitter_user=self.s2, reviewed_submission=os) self.assertEqual(ReviewLock.objects.count(), 1) rs.save_and_destroy_lock() self.assertEqual(ReviewLock.objects.count(), 0) rs2 = ReviewSubmission(course=self.course, exercise=self.re, submitter_user=self.s2, reviewed_submission=os) self.assertRaises(OperationalError, rs2.save_and_destroy_lock) rs2 = ReviewSubmission(course=self.course, exercise=self.re, submitter_user=self.s3, reviewed_submission=os) self.assertRaises(OperationalError, rs2.save_and_destroy_lock)
def _post_random(self, ctx): rlock_list = self.object.reviewlocks_for(self.request.user) rlock = rlock_list.last() reviewed_submission = None lock_was_expired = False if rlock: reviewed_submission = rlock.original_submission elif not rlock and self.object.reviewlock_expiry_hours != 0: # if the expiry time has been set and a user keeps the exercise page # visible for a very long time without refreshing, it is possible that # whenever the form is actually submitted the original reviewlock has # already expired and deleted. in that situation, from the system's POV, # the user is making a bogus form submission since no lock is held. # if this "race condition" happens, grab the originally reviewed submission's # PK from the submitted form. # # this is not beautiful, but serves the purpose. other implementation # possibilities could be to just show an error page but that would waste # the peer-reviewing efforts by the student. some sort of verification could # also be implemented client-side in JavaScript to show the user a warning or # something. this, however, is the easiest solution. reviewed_submission = self.object.reviewable_exercise.submissions.get(pk=self.request.POST.get('choice')) lock_was_expired = True new_review_submission = ReviewSubmission(course=ctx['course'], submitter_user=self.request.user, exercise=self.object, reviewed_submission=reviewed_submission) if self.object.use_groups: new_review_submission.submitter_group = ctx['my_group'] if lock_was_expired: new_review_submission.save() else: new_review_submission.save_and_destroy_lock() self._save_modelform_answers(self.answer_forms, new_review_submission) if self.request.LTI_MODE: return _construct_aplus_response(exercise=self.object, user=self.request.user) return HttpResponseRedirect(new_review_submission.get_absolute_url())
def _post_choose(self, ctx): cf = ChooseForm(self.request.POST, exercise=self.object, user=self.request.user) if not cf.is_valid(): # this prevents fiddling with html form fields in dev tools raise PermissionDenied('You cannot do that. If you believe this is an error, contact admin.') # if ChooseForm is valid, construct a new ReviewSubmission reviewed_submission = OriginalSubmission.objects.get(pk=self.request.POST.get('choice')) new_review_submission = ReviewSubmission(course=ctx['course'], submitter_user=self.request.user, exercise=self.object, reviewed_submission=reviewed_submission) if self.object.use_groups: new_review_submission.submitter_group = ctx['my_group'] new_review_submission.save() self._save_modelform_answers(self.answer_forms, new_review_submission) if self.request.LTI_MODE: return _construct_aplus_response(exercise=self.object, user=self.request.user) return HttpResponseRedirect(new_review_submission.get_absolute_url())
def test_reviewexercise_type_group(self): se = SubmissionExercise.objects.get(name="T1 TEXT") re = ReviewExercise.objects.get(name="T1 TEXT REVIEW") se.type = SubmissionExercise.GROUP_NO_SUBMISSION se.save() re.type = ReviewExercise.GROUP re.use_groups = True re.save() temp_email = "*****@*****.**" g = StudentGroup( course=se.course, name="g1", student_usernames=[self.s1.email, self.s2.email, temp_email]) g.save() user_count_before = User.objects.count() self.assertEqual(0, se.submissions.count()) request = self.factory.get(re.get_absolute_url()) request.user = self.s1 self.kwargs['pk'] = re.pk # should create temp user for [email protected] # should have three orig subs because three group members res = ReviewExerciseDetailView.as_view()(request, **self.kwargs) self.assertEqual(user_count_before + 1, User.objects.count()) self.assertEqual(3, se.submissions.count()) # when students review each other, inlined options are not shown, only ChooseForm dropdown self.assertEqual(len(res.context_data['chooseform_options_list']), 0) temp_user = User.objects.get(email=temp_email) self.assertEqual(temp_user.temporary, True) self.assertEqual(temp_user.lti, False) request.user = self.s2 ReviewExerciseDetailView.as_view()(request, **self.kwargs) # page load as another user of the group shouldn't have any effect self.assertEqual(user_count_before + 1, User.objects.count()) self.assertEqual(3, se.submissions.count()) orig_subs_for_temp_user = OriginalSubmission.objects.filter( submitter_user=temp_user) self.assertEqual(1, orig_subs_for_temp_user.count()) resub = ReviewSubmission( course=re.course, exercise=re, submitter_user=self.s1, reviewed_submission=orig_subs_for_temp_user.first(), ) resub.save() # create actual user. this will be used to simulate sihbboleth login in a future time # when the system allready has a submission temporarily made for this user. actual_user = User.objects.create(username="******", email=temp_email) actual_user.set_password("actual_password") actual_user.save() self.assertEqual(2, User.objects.filter(email=temp_email).count()) orig_submitter = OriginalSubmission.objects.get( submitter_user__email=temp_email).submitter_user.username # logging in a user would normally trigger users/receivers.py which will: # - find all submissions done with a temp user using same email # - transfer all submissions to this actual user # - delete temp user # here we'll just call the signal handler directly fake_request = HttpRequest() fake_request.LTI_MODE = False fake_request.user = actual_user change_original_submission_submitters(None, request=fake_request, user=actual_user) actual_submitter = OriginalSubmission.objects.get( submitter_user__email=temp_email).submitter_user.username self.assertNotEqual(orig_submitter, actual_submitter) self.assertEqual(1, User.objects.filter(email=temp_email).count()) actual_user = User.objects.get(email=temp_email) self.assertEqual(actual_user.temporary, False) request.user = actual_user response = ReviewExerciseDetailView.as_view()(request, **self.kwargs) self.assertEqual(user_count_before + 1, User.objects.all().count()) self.assertEqual(3, se.submissions.count()) # nothing, student1, student2 self.assertEqual( str(response.context_data['chooseForm']).count("<option"), 3) re.can_review_own_submission = True re.save() response = ReviewExerciseDetailView.as_view()(request, **self.kwargs) # nothing, student1, student2, actual_user self.assertEqual( str(response.context_data['chooseForm']).count("<option"), 4) # actual_user can see one review by another student (student1) request = self.factory.get(re.get_list_url()) request.user = actual_user self.kwargs['pk'] = re.pk response = ReviewSubmissionListView.as_view()(request, **self.kwargs) self.assertEqual( response.context_data['reviewsubmission_list'].count(), 1)
def test_reviewlocks_created_correctly_for_groups(self): groups = [ StudentGroup.objects.create( course=self.course, name="g1", student_usernames=[self.s1.email, self.s2.email]), StudentGroup.objects.create( course=self.course, name="g2", student_usernames=[self.s3.email, self.s4.email]), StudentGroup.objects.create( course=self.course, name="g3", student_usernames=[self.s5.email, self.s6.email]), ] se = SubmissionExercise.objects.get(name='T1 TEXT') se.use_groups = True se.save() # OS for all groups for s, g in [(self.s1, groups[0]), (self.s3, groups[1]), (self.s5, groups[2])]: self.post(se, s, {'text': f'text by {g.name}'}) self.assertEqual(OriginalSubmission.objects.count(), 3) re = se.review_exercise re.use_groups = True re.save() # g1 -> g2, g2 -> g1 request = self.factory.get('/courses/prog1/F2018/exercises/r/1/') self.kwargs['pk'] = re.pk for s, target_name in [(self.s1, 'g2'), (self.s2, 'g2'), (self.s3, 'g1'), (self.s4, 'g1')]: request.user = s response = ReviewExerciseDetailView.as_view()(request, **self.kwargs) self.assertContains(response, f"text by {target_name}") self.assertEqual(ReviewLock.objects.all().count(), 2) # g1 -> review for g2 rlock = re.reviewlocks_for(self.s1).first() rsub = ReviewSubmission(course=self.course, exercise=re, submitter_user=self.s1, submitter_group=groups[0], reviewed_submission=rlock.original_submission) rsub.save_and_destroy_lock() for s in [self.s1, self.s2]: request.user = s response = ReviewExerciseDetailView.as_view()(request, **self.kwargs) self.assertContains( response, 'You have already submitted your peer-reviews') self.assertEqual(response.context_data['disable_form'], True) self.assertEqual(ReviewLock.objects.all().count(), 1) # increase sub count that groups can do. g1 -> g3 re.max_submission_count = 2 re.save() for s, target_name in [(self.s1, 'g3'), (self.s2, 'g3')]: request.user = s response = ReviewExerciseDetailView.as_view()(request, **self.kwargs) self.assertContains(response, f"text by {target_name}") self.assertEqual(ReviewLock.objects.all().count(), 2) # nothing left for g3 to review for s in [self.s5, self.s6]: request.user = s response = ReviewExerciseDetailView.as_view()(request, **self.kwargs) self.assertContains(response, 'no-submissions-for-peer-review') self.assertEqual(response.context_data['disable_form'], True) self.assertEqual(ReviewLock.objects.all().count(), 2) # increase how many reviews can receive. g3 -> g1 since g1 oldest and 1 review re.max_reviews_per_submission = 2 re.save() for s, target_name in [(self.s5, 'g1'), (self.s6, 'g1')]: request.user = s response = ReviewExerciseDetailView.as_view()(request, **self.kwargs) self.assertContains(response, f"text by {target_name}") self.assertEqual(ReviewLock.objects.all().count(), 3)
def test_reviewlocks_created_correctly(self): se = SubmissionExercise.objects.get(pk=1) for s in self.students: OriginalSubmission(course=self.course, submitter_user=s, exercise=se, text=f"text by {s}").save() # this will create two reviewlocks since both loaded the page re = ReviewExercise.objects.get(reviewable_exercise=se) for s in [self.s1, self.s2]: request = self.factory.get('/courses/prog1/F2018/exercises/r/1/') request.user = s self.kwargs['pk'] = re.pk response = ReviewExerciseDetailView.as_view()(request, **self.kwargs) self.assertContains( response, f"text by {self.s1 if s == self.s2 else self.s2}") self.assertEqual(ReviewLock.objects.all().count(), 2) # the same reviewlocks are still used since no reviews have been made for s in [self.s1, self.s2]: request = self.factory.get('/courses/prog1/F2018/exercises/r/1/') request.user = s self.kwargs['pk'] = re.pk response = ReviewExerciseDetailView.as_view()(request, **self.kwargs) self.assertContains( response, f"text by {self.s1 if s == self.s2 else self.s2}") self.assertEqual(ReviewLock.objects.all().count(), 2) # after submissions are created, no more reviews can be made for s in [self.s1, self.s2]: rlock = ReviewLock.objects.get(user=s) rsub = ReviewSubmission( course=self.course, exercise=re, submitter_user=s, reviewed_submission=rlock.original_submission) rsub.save_and_destroy_lock() request = self.factory.get('/courses/prog1/F2018/exercises/r/1/') request.user = s self.kwargs['pk'] = re.pk response = ReviewExerciseDetailView.as_view()(request, **self.kwargs) self.assertContains( response, 'You have already submitted your peer-reviews to this exercise.' ) self.assertEqual(ReviewLock.objects.all().count(), 0) # now in the system: 4 OS, 0 RL, 2 RS # s4 loads the page -> RL should be for s3 request = self.factory.get('/courses/prog1/F2018/exercises/r/1/') request.user = self.s4 self.kwargs['pk'] = re.pk response = ReviewExerciseDetailView.as_view()(request, **self.kwargs) self.assertContains(response, f"text by {self.s3}") self.assertEqual(ReviewLock.objects.all().count(), 1) re.max_submission_count = 2 re.save() # s1 loads the page -> RL should be for s4 since no RLs for s4 exist yet request.user = self.s1 response = ReviewExerciseDetailView.as_view()(request, **self.kwargs) self.assertContains(response, f"text by {self.s4}") self.assertEqual(ReviewLock.objects.all().count(), 2) # s2 loads the page -> nothing to review since all can recieve only one request.user = self.s2 response = ReviewExerciseDetailView.as_view()(request, **self.kwargs) self.assertContains(response, f"no-submissions-for-peer-review") self.assertEqual(ReviewLock.objects.all().count(), 2) # increase the number of reviews an OS can get re.max_reviews_per_submission = 2 re.save() # s2 should now get s3 since cannot get himself and s1 already done request.user = self.s2 self.kwargs['pk'] = re.pk response = ReviewExerciseDetailView.as_view()(request, **self.kwargs) self.assertContains(response, f"text by {self.s3}") self.assertEqual(ReviewLock.objects.all().count(), 3) # s3 has not yet loaded the page -> should get s1 request.user = self.s3 self.kwargs['pk'] = re.pk response = ReviewExerciseDetailView.as_view()(request, **self.kwargs) self.assertContains(response, f"text by {self.s1}") self.assertEqual(ReviewLock.objects.all().count(), 4)
def test_original_submission_delete_confirmation_page_shows_cascades(self): os = OriginalSubmission( course=self.course, exercise=SubmissionExercise.objects.get(name="T1 TEXT"), submitter_user=self.s1, text="jada jada jada jada", ) os.save() request = self.factory.get(os.get_delete_url()) self.kwargs['pk'] = os.exercise.pk self.kwargs['sub_pk'] = os.pk request.user = self.s1 # students cannot access self.assertRaises(PermissionDenied, OriginalSubmissionDeleteView.as_view(), request, **self.kwargs) request.user = self.t1 response = OriginalSubmissionDeleteView.as_view()(request, **self.kwargs) self.assertContains(response, "No peer-reviews exist yet") res = [] for s in [self.s2, self.s3]: re = ReviewSubmission( course=self.course, exercise=ReviewExercise.objects.get(name="T1 TEXT REVIEW"), reviewed_submission=os, submitter_user=s, ) re.save() res.append(re) response = OriginalSubmissionDeleteView.as_view()(request, **self.kwargs) self.assertNotContains(response, "No peer-reviews exist yet") # -> is turned into -> in the response -> just replace that when looking for self.assertContains(response, str(res[0]).replace(">", ">")) self.assertContains(response, str(res[1]).replace(">", ">")) self.assertEqual(OriginalSubmission.objects.count(), 1) self.assertEqual(ReviewSubmission.objects.count(), 2) request = self.factory.get(res[0].get_delete_url()) self.kwargs['pk'] = res[0].exercise.pk self.kwargs['sub_pk'] = res[0].pk request.user = self.s1 # students cannot access self.assertRaises(PermissionDenied, ReviewSubmissionDeleteView.as_view(), request, **self.kwargs) # delete page doesn't list any useful information, no need to check os.delete() self.assertEqual(OriginalSubmission.objects.count(), 0) self.assertEqual(ReviewSubmission.objects.count(), 0)
def test_download_tokens_allow_downloading(self): exercise = SubmissionExercise.objects.get(pk=1) exercise.type = 'FILE_UPLOAD' exercise.accepted_filetypes = '.txt' exercise.save() temp_file = SimpleUploadedFile(name='lorem_ipsum.txt', content=bytearray('jada jada', 'utf-8')) sub = OriginalSubmission(course=self.course, file=temp_file, submitter_user=self.s1, exercise=exercise) sub.save() rev = ReviewSubmission(course=self.course, submitter_user=self.s1, exercise=exercise.review_exercise, reviewed_submission=sub) rev.save() answer_with_file = Answer( question=Question.objects.get(pk=3), submission=rev, uploaded_file=temp_file, ) answer_with_file.save() view_request = self.factory.get(exercise.get_absolute_url() + "?some=queryparams") osub_token = sub.get_download_token_for(self.s1, view_request) view_request = self.factory.get( exercise.review_exercise.get_absolute_url() + "?some=queryparams") rsub_token = rev.get_download_token_for(self.s1, view_request) cases = [ (AnonymousUser, 403, sub, ""), (AnonymousUser, 200, sub, f"?dl_token={osub_token}"), (AnonymousUser, 403, sub, f"?dl_token={osub_token}_THIS_SHOULD_CAUSE_PROBLEMS"), (AnonymousUser, 403, answer_with_file, ""), (AnonymousUser, 200, answer_with_file, f"&dl_token={rsub_token}"), (AnonymousUser, 403, answer_with_file, f"&dl_token={rsub_token}_THIS_SHOULD_CAUSE_PROBLEMS"), ] for user, code, sub, query in cases: url = f"{sub.get_file_download_url()}{query}" request = self.factory.get(url) request.user = user self.kwargs['pk'] = sub.pk if code == 403: self.assertRaises(PermissionDenied, DownloadSubmissionView.as_view(), request, **self.kwargs) else: response = DownloadSubmissionView.as_view()(request, **self.kwargs) self.assertEqual(response.status_code, code) DownloadToken.objects.all().delete() for user, _, sub, query in cases: url = f"{sub.get_file_download_url()}{query}" request = self.factory.get(url) request.user = user self.kwargs['pk'] = sub.pk self.assertRaises(PermissionDenied, DownloadSubmissionView.as_view(), request, **self.kwargs)
def test_reviewsubmissionlist_parties(self): sub_exercise = SubmissionExercise.objects.get(pk=1) rev_exercise = ReviewExercise.objects.get(pk=1) for user in self.students[:2]: OriginalSubmission(course=self.course, submitter_user=user, exercise=sub_exercise, text="jadajada").save() for user in self.students[:2]: revsub = OriginalSubmission.objects.filter(exercise=sub_exercise) \ .exclude(submitter_user=user).first() ReviewSubmission(course=self.course, submitter_user=user, exercise=rev_exercise, reviewed_submission=revsub).save() # teacher sees all reviews request = self.factory.get( '/courses/prog1/F2018/submissions/r/1/list/') request.user = User.objects.get(username="******") self.kwargs['pk'] = 1 response = ReviewSubmissionListView.as_view()(request, **self.kwargs) self.assertEqual(ReviewSubmission.objects.all().count(), 2) self.assertEqual(response.context_data['object_list'].count(), 2) self.assertContains(response, "student1") # hacky self.assertContains(response, "student2") rev_exercise.type = ReviewExercise.RANDOM rev_exercise.save() # list doesn't show who reviewed who for url in [ '/courses/prog1/F2018/submissions/r/1/list/', '/courses/prog1/F2018/submissions/r/1/list/?mode=my' ]: request = self.factory.get(url) request.user = self.s1 response = ReviewSubmissionListView.as_view()(request, **self.kwargs) self.assertNotContains(response, 'Reviewer') self.assertNotContains(response, 'Reviewed') self.assertNotContains(response, '<td>student2', html=True) self.assertNotContains(response, '<td>student1', html=True) for typ in [ReviewExercise.CHOOSE, ReviewExercise.GROUP]: rev_exercise.type = typ rev_exercise.save() # student can see who he reviewed request = self.factory.get( '/courses/prog1/F2018/submissions/r/1/list/') request.user = self.s1 response = ReviewSubmissionListView.as_view()(request, **self.kwargs) self.assertContains(response, 'Reviewer') self.assertContains(response, 'Reviewed') self.assertContains(response, '<td>student2', html=True) self.assertContains(response, '<td>student1', html=True) # student CANNOT see who reviewed him request = self.factory.get( '/courses/prog1/F2018/submissions/r/1/list/?mode=my') request.user = self.s1 response = ReviewSubmissionListView.as_view()(request, **self.kwargs) self.assertNotContains(response, 'Reviewer') self.assertNotContains(response, 'Reviewed') self.assertNotContains(response, '<td>student2', html=True) self.assertNotContains(response, '<td>student1', html=True)
def test_reviewsubmissionlist_list_contents(self): sub_exercise = SubmissionExercise.objects.get(pk=1) rev_exercise = ReviewExercise.objects.get(pk=1) for user in self.students[:2]: OriginalSubmission(course=self.course, submitter_user=user, exercise=sub_exercise, text="jadajada").save() for user in self.students[:2]: revsub = OriginalSubmission.objects.filter(exercise=sub_exercise) \ .exclude(submitter_user=user).first() ReviewSubmission(course=self.course, submitter_user=user, exercise=rev_exercise, reviewed_submission=revsub).save() # teacher sees all reviews request = self.factory.get( '/courses/prog1/F2018/submissions/r/1/list/') request.user = User.objects.get(username="******") self.kwargs['pk'] = 1 response = ReviewSubmissionListView.as_view()(request, **self.kwargs) self.assertEqual(ReviewSubmission.objects.all().count(), 2) self.assertEqual(response.context_data['object_list'].count(), 2) self.assertContains(response, "student1") # hacky self.assertContains(response, "student2") # student1 sees reviews of him by student2 request = self.factory.get( '/courses/prog1/F2018/submissions/r/1/list/?mode=my') request.user = self.s1 self.kwargs['pk'] = 1 response = ReviewSubmissionListView.as_view()(request, **self.kwargs) self.assertEqual(ReviewSubmission.objects.all().count(), 2) self.assertEqual(response.context_data['object_list'].count(), 1) self.assertEqual( response.context_data['object_list'][0].submitter_user, self.s2) # student2 sees reviews of him by student1 request = self.factory.get( '/courses/prog1/F2018/submissions/r/1/list/?mode=my') request.user = self.s2 self.kwargs['pk'] = 1 response = ReviewSubmissionListView.as_view()(request, **self.kwargs) self.assertEqual(ReviewSubmission.objects.all().count(), 2) self.assertEqual(response.context_data['object_list'].count(), 1) self.assertEqual( response.context_data['object_list'][0].submitter_user, self.s1) # if RE.show_reviews_only_to_teacher, nothing in the list rev_exercise.show_reviews_only_to_teacher = True rev_exercise.save() request = self.factory.get( '/courses/prog1/F2018/submissions/r/1/list/?mode=my') request.user = self.s2 self.kwargs['pk'] = 1 response = ReviewSubmissionListView.as_view()(request, **self.kwargs) self.assertEqual(response.context_data['object_list'].count(), 0) self.assertContains(response, 'will only be visible') rev_exercise.show_reviews_only_to_teacher = False rev_exercise.save() # reviews by student missing rev_exercise.min_submission_count = 100 rev_exercise.save() request = self.factory.get( '/courses/prog1/F2018/submissions/r/1/list/?mode=my') request.user = self.s2 self.kwargs['pk'] = 1 response = ReviewSubmissionListView.as_view()(request, **self.kwargs) self.assertEqual(response.context_data['object_list'].count(), 0) self.assertContains(response, 'available after completing') # available in the future -> students should not see anything rev_exercise.min_submission_count = 0 rev_exercise.show_reviews_after_date = timezone.now( ) + datetime.timedelta(days=1) rev_exercise.save() request = self.factory.get( '/courses/prog1/F2018/submissions/r/1/list/?mode=my') request.user = self.s2 self.kwargs['pk'] = 1 response = ReviewSubmissionListView.as_view()(request, **self.kwargs) self.assertEqual(response.context_data['object_list'].count(), 0) self.assertContains(response, 'will be available after')