Example #1
0
    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)
Example #2
0
    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)
Example #3
0
    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)
Example #4
0
    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.'
            )
Example #5
0
    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)
Example #6
0
    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())
Example #7
0
    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())
Example #8
0
    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)
Example #9
0
    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)
Example #10
0
    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)
Example #11
0
    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 -&gt; in the response -> just replace that when looking for
        self.assertContains(response, str(res[0]).replace(">", "&gt;"))
        self.assertContains(response, str(res[1]).replace(">", "&gt;"))

        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)
Example #12
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)
Example #13
0
    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)
Example #14
0
    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')