def test_get_handgrading_results_exclude_staff(self):
        staff_group = obj_build.make_group(members_role=obj_build.UserRole.staff,
                                           project=self.project)
        admin_group = obj_build.make_group(members_role=obj_build.UserRole.admin,
                                           project=self.project)

        staff_submission = obj_build.make_finished_submission(group=staff_group)
        admin_submission = obj_build.make_finished_submission(group=admin_group)

        staff_hg_result = hg_models.HandgradingResult.objects.validate_and_create(
            submission=staff_submission, group=staff_group, handgrading_rubric=self.rubric)
        admin_hg_result = hg_models.HandgradingResult.objects.validate_and_create(
            submission=admin_submission, group=admin_group, handgrading_rubric=self.rubric)

        self.client.force_authenticate(self.staff)
        url = reverse('handgrading_results', kwargs={'pk': self.project.pk})
        url += '?' + urlencode({'include_staff': 'false'})
        response = self.client.get(url)
        self.assertEqual(status.HTTP_200_OK, response.status_code)
        self.assertSequenceEqual([], response.data['results'])

        student_group = obj_build.make_group(members_role=obj_build.UserRole.student,
                                             project=self.project)
        student_submission = obj_build.make_finished_submission(group=student_group)
        student_hg_result = hg_models.HandgradingResult.objects.validate_and_create(
            submission=student_submission, group=student_group, handgrading_rubric=self.rubric)

        response = self.client.get(url)
        self.assertEqual(status.HTTP_200_OK, response.status_code)
        self.assertEqual(1, len(response.data['results']))
        self.assertEqual(student_group.member_names, response.data['results'][0]['member_names'])
    def setUp(self):
        super().setUp()

        self.maxDiff = None

        self.client = APIClient()

        self.project = obj_build.make_project(
            ultimate_submission_policy=ag_models.UltimateSubmissionPolicy.
            most_recent, )

        self.url = reverse('project-ultimate-submission-scores',
                           kwargs={'pk': self.project.pk})

        self.admin = obj_build.make_admin_user(self.project.course)

        self.ag_test_suite = obj_build.make_ag_test_suite(project=self.project)
        self.ag_test_case = obj_build.make_ag_test_case(
            ag_test_suite=self.ag_test_suite)
        self.ag_test_cmd = obj_build.make_full_ag_test_command(
            ag_test_case=self.ag_test_case)

        self.student_group = obj_build.make_group(project=self.project,
                                                  num_members=2)
        self.student_submission = obj_build.make_finished_submission(
            self.student_group)
        self.student_result = obj_build.make_incorrect_ag_test_command_result(
            ag_test_command=self.ag_test_cmd,
            submission=self.student_submission)

        self.student_submission = update_denormalized_ag_test_results(
            self.student_submission.pk)
        self.student_result_fdbk = SubmissionResultFeedback(
            self.student_submission, ag_models.FeedbackCategory.max,
            AGTestPreLoader(self.project))

        self.assertEqual(0, self.student_result_fdbk.total_points)
        self.assertNotEqual(0, self.student_result_fdbk.total_points_possible)

        self.staff_group = obj_build.make_group(
            project=self.project, members_role=obj_build.UserRole.admin)
        self.staff_submission = obj_build.make_finished_submission(
            self.staff_group)
        self.staff_result = obj_build.make_correct_ag_test_command_result(
            ag_test_command=self.ag_test_cmd, submission=self.staff_submission)

        self.staff_submission = update_denormalized_ag_test_results(
            self.staff_submission.pk)
        self.staff_result_fdbk = SubmissionResultFeedback(
            self.staff_submission, ag_models.FeedbackCategory.max,
            AGTestPreLoader(self.project))

        self.assertNotEqual(0, self.staff_result_fdbk.total_points)
        self.assertNotEqual(0, self.staff_result_fdbk.total_points_possible)

        # Make sure we use the right queryset
        other_project = obj_build.make_project(course=self.project.course)
        other_group = obj_build.make_group(project=other_project)
        other_submission = obj_build.make_finished_submission(other_group)
    def test_group_has_extension_ultimate_submission_is_none(self):
        group_with_future_extension = obj_build.make_group(
            num_members=2,
            project=self.project,
            extended_due_date=timezone.now() + datetime.timedelta(days=1))
        extension_submission = obj_build.make_finished_submission(
            group_with_future_extension)
        extension_submission = self._add_results_to_submission(
            extension_submission, results_correct=True)

        group = obj_build.make_group(project=self.project)
        submission = obj_build.make_finished_submission(group)
        submission = self._add_results_to_submission(submission,
                                                     results_correct=False)
        submission_fdbk = SubmissionResultFeedback(
            submission, ag_models.FeedbackCategory.max, self.ag_test_preloader)
        self.assertEqual(0, submission_fdbk.total_points)
        self.assertNotEqual(0, submission_fdbk.total_points_possible)

        expected = [{
            'username': group_with_future_extension.member_names[0],
            'group': group_with_future_extension.to_dict(),
            'ultimate_submission': None
        }, {
            'username': group_with_future_extension.member_names[1],
            'group': group_with_future_extension.to_dict(),
            'ultimate_submission': None
        }, {
            'username': group.member_names[0],
            'group': group.to_dict(),
            'ultimate_submission': {
                'results': {
                    'total_points':
                    two_decimal_place_string(submission_fdbk.total_points),
                    'total_points_possible':
                    two_decimal_place_string(
                        submission_fdbk.total_points_possible)
                },
                **submission.to_dict()
            }
        }]

        actual = serialize_ultimate_submission_results([
            SubmissionResultFeedback(extension_submission,
                                     ag_models.FeedbackCategory.max,
                                     self.ag_test_preloader),
            SubmissionResultFeedback(submission,
                                     ag_models.FeedbackCategory.max,
                                     self.ag_test_preloader)
        ],
                                                       full_results=False)
        self.assertEqual(expected, actual)
    def test_get_num_queued_submissions(self):
        client = APIClient()

        course = obj_build.make_course()
        admin = obj_build.make_admin_user(course)
        proj_kwargs = {'visible_to_students': True, 'guests_can_submit': True}
        no_submits = obj_build.make_project(course, **proj_kwargs)
        with_submits1 = obj_build.make_project(course, **proj_kwargs)
        with_submits2 = obj_build.make_project(course, **proj_kwargs)

        group_with_submits1 = obj_build.make_group(project=with_submits1)
        group_with_submits2 = obj_build.make_group(project=with_submits2)

        g1_statuses = [
            ag_models.Submission.GradingStatus.queued,
            ag_models.Submission.GradingStatus.finished_grading,
            ag_models.Submission.GradingStatus.removed_from_queue,
            ag_models.Submission.GradingStatus.received,
            ag_models.Submission.GradingStatus.being_graded,
            ag_models.Submission.GradingStatus.error
        ]

        for grading_status in g1_statuses:
            obj_build.make_submission(status=grading_status,
                                      group=group_with_submits1)

        for i in range(3):
            obj_build.make_submission(
                status=ag_models.Submission.GradingStatus.queued,
                group=group_with_submits2)

        client.force_authenticate(admin)
        response = client.get(
            reverse('project-num-queued-submissions',
                    kwargs={'pk': no_submits.pk}))
        self.assertEqual(status.HTTP_200_OK, response.status_code)
        self.assertEqual(0, response.data)

        response = client.get(
            reverse('project-num-queued-submissions',
                    kwargs={'pk': with_submits1.pk}))
        self.assertEqual(status.HTTP_200_OK, response.status_code)
        self.assertEqual(1, response.data)

        response = client.get(
            reverse('project-num-queued-submissions',
                    kwargs={'pk': with_submits2.pk}))
        self.assertEqual(status.HTTP_200_OK, response.status_code)
        self.assertEqual(3, response.data)
    def _make_group_with_submissions(
            self,
            num_members: int,
            *,
            num_submissions: int = 1,
            members_role: obj_build.UserRole = obj_build.UserRole.student,
            members=None,
            **group_kwargs):
        assert num_submissions > 0

        self._num_groups += 1
        if members is None:
            # We want groups to be sorted in the same order they're created.
            members = [
                User.objects.create(
                    username=f'group{self._num_groups}_user{i}')
                for i in range(num_members)
            ]
        group = obj_build.make_group(members=members,
                                     members_role=members_role,
                                     project=self.project,
                                     **group_kwargs)

        # The first submission gets correct results so that it's the best.
        # The others get incorrect results.
        best_submission = obj_build.make_finished_submission(group=group)
        best_submission = self._add_results_to_submission(best_submission,
                                                          results_correct=True)

        for i in range(num_submissions - 1):
            submission = obj_build.make_finished_submission(group=group)
            self._add_results_to_submission(submission, results_correct=False)

        return group, best_submission
    def setUp(self):
        super().setUp()
        self.group = obj_build.make_group()
        self.student = self.group.members.first()
        self.project = self.group.project
        ag_models.ExpectedStudentFile.objects.validate_and_create(
            pattern='*', max_num_matches=10, project=self.project)

        self.submitted_files = [SimpleUploadedFile('file{}'.format(i),
                                                   'waaaluigi{}'.format(i).encode())
                                for i in range(3)]
        self.submission = obj_build.make_submission(
            group=self.group,
            submitted_files=self.submitted_files,
            status=Submission.GradingStatus.finished_grading)

        self.handgrading_rubric = hg_models.HandgradingRubric.objects.validate_and_create(
            project=self.project
        )  # type: hg_models.HandgradingRubric

        [self.admin] = obj_build.make_admin_users(self.project.course, 1)
        [self.staff] = obj_build.make_staff_users(self.project.course, 1)
        [self.handgrader] = obj_build.make_users(1)
        self.project.course.handgraders.add(self.handgrader)

        self.client = APIClient()
        self.course = self.handgrading_rubric.project.course
        self.url = reverse('handgrading_result',
                           kwargs={'group_pk': self.submission.group.pk})
    def test_remove_from_queue_when_being_marked_as_being_graded_race_condition_prevented(self):
        group = obj_build.make_group(members_role=obj_build.UserRole.admin)
        submission = obj_build.make_submission(group=group)

        path = ('autograder.core.models'
                '.Submission.GradingStatus.removed_from_queue')

        @sleeper_subtest(
            path,
            new_callable=mock.PropertyMock,
            return_value=(ag_models.Submission.GradingStatus.removed_from_queue))
        def do_request_and_wait():
            tasks.grade_submission(submission.pk)

        subtest = do_request_and_wait()

        print('sending remove from queue request')
        client = APIClient()
        client.force_authenticate(
            submission.group.members.first())
        response = client.post(reverse('submission-remove-from-queue',
                                       kwargs={'pk': submission.pk}))
        subtest.join()
        submission.refresh_from_db()
        self.assertNotEqual(
            ag_models.Submission.GradingStatus.removed_from_queue,
            submission.status)
        self.assertEqual(status.HTTP_400_BAD_REQUEST, response.status_code)

        self.assertEqual(ag_models.Submission.GradingStatus.finished_grading,
                         submission.status)
    def test_serialize_groups_ultimate_submissions_full_results(self):
        group = obj_build.make_group(project=self.project)
        submission = obj_build.make_finished_submission(group)
        submission = self._add_results_to_submission(submission,
                                                     results_correct=False)
        submission_fdbk = SubmissionResultFeedback(
            submission, ag_models.FeedbackCategory.max, self.ag_test_preloader)
        self.assertEqual(0, submission_fdbk.total_points)
        self.assertNotEqual(0, submission_fdbk.total_points_possible)

        expected = [
            {
                'username': group.member_names[0],
                'group': group.to_dict(),
                'ultimate_submission': {
                    'results': submission_fdbk.to_dict(),
                    **submission.to_dict()
                }
            },
        ]

        actual = serialize_ultimate_submission_results([
            SubmissionResultFeedback(submission,
                                     ag_models.FeedbackCategory.max,
                                     self.ag_test_preloader)
        ],
                                                       full_results=True)
        self.assertEqual(expected, actual)
    def setUp(self):
        super().setUp()

        self.maxDiff = None

        self.project = obj_build.make_project(
            # Future closing_time
            closing_time=timezone.now() + datetime.timedelta(days=1))
        self.course = self.project.course

        self.ag_test_suite = obj_build.make_ag_test_suite(self.project)
        self.ag_test_case = obj_build.make_ag_test_case(self.ag_test_suite)
        self.ag_test_cmd = obj_build.make_full_ag_test_command(
            self.ag_test_case)

        self.student_test_suite = obj_build.make_student_test_suite(
            self.project)

        self.client = APIClient()
        self.base_url = reverse('all-ultimate-submission-results',
                                kwargs={'project_pk': self.project.pk})

        # For use by self._make_group_with_submissions only
        self._num_groups = 0

        # This is to make sure we use the right group queryset
        other_project = obj_build.make_project()
        other_group = obj_build.make_group(project=other_project)
        other_submission = obj_build.make_finished_submission(other_group)
Beispiel #10
0
    def test_get_ultimate_submission_most_recent_submission_doesnt_count_for_user(
            self):
        project = obj_build.make_project(visible_to_students=True,
                                         hide_ultimate_submission_fdbk=False,
                                         ultimate_submission_policy=ag_models.
                                         UltimateSubmissionPolicy.most_recent)
        course = project.course

        counts_for_user = obj_build.make_student_user(course)
        does_not_count_for_user = obj_build.make_student_user(course)

        group = obj_build.make_group(
            members=[counts_for_user, does_not_count_for_user],
            project=project)

        second_most_recent_submission = obj_build.make_finished_submission(
            group=group)
        most_recent_submission = obj_build.make_finished_submission(
            group=group, does_not_count_for=[does_not_count_for_user.username])

        self.client.force_authenticate(counts_for_user)
        response = self.client.get(self.ultimate_submission_url(group))
        self.assertEqual(status.HTTP_200_OK, response.status_code)
        self.assertEqual(most_recent_submission.to_dict(), response.data)

        self.client.force_authenticate(does_not_count_for_user)
        response = self.client.get(self.ultimate_submission_url(group))
        self.assertEqual(status.HTTP_200_OK, response.status_code)
        self.assertEqual(second_most_recent_submission.to_dict(),
                         response.data)
Beispiel #11
0
    def setUp(self):
        super().setUp()
        self.project = obj_build.make_project()

        # Make sure we use the right group queryset
        other_project = obj_build.make_project(course=self.project.course)
        other_group = obj_build.make_group(project=other_project)
        other_subimssion = obj_build.make_finished_submission(other_group)
    def do_handgrading_results_test(self, user: User, *,
                                    num_results: int, num_groups: int=None,
                                    page_size: int=None, page_num: int=None):
        if num_groups is None:
            num_groups = num_results
        else:
            assert num_groups >= num_results

        groups = [obj_build.make_group(3, project=self.project) for _ in range(num_groups)]
        expected_data = []
        for i in range(num_results):
            group = groups[i]
            s = obj_build.make_finished_submission(group=group)
            score = random.randint(0, self.rubric.max_points + 3)
            hg_result = hg_models.HandgradingResult.objects.validate_and_create(
                submission=s, group=group, handgrading_rubric=self.rubric,
                points_adjustment=score,
                finished_grading=bool(random.getrandbits(1)))

            # Groups that have a handgrading result
            data = hg_result.group.to_dict()
            data['handgrading_result'] = {
                'total_points': hg_result.total_points,
                'total_points_possible': hg_result.total_points_possible,
                'finished_grading': hg_result.finished_grading
            }
            data['member_names'].sort()
            expected_data.append(data)

        # Groups that don't have a handgrading result
        for i in range(num_results, num_groups):
            data = groups[i].to_dict()
            data['member_names'].sort()
            data['handgrading_result'] = None
            expected_data.append(data)

        expected_data.sort(key=lambda group: group['member_names'][0])

        self.client.force_authenticate(user)
        url = reverse('handgrading_results', kwargs={'pk': self.project.pk})
        query_params = {}
        if page_num is not None:
            query_params['page'] = page_num
        else:
            page_num = 1

        if page_size is not None:
            query_params['page_size'] = page_size
        else:
            page_size = HandgradingResultPaginator.page_size

        expected_data = expected_data[page_num - 1 * page_size:page_num * page_size]

        if query_params:
            url += '?' + urlencode(query_params)
        response = self.client.get(url)
        self.assertEqual(status.HTTP_200_OK, response.status_code)
        self.assertSequenceEqual(expected_data, response.data['results'])
    def setUp(self):
        super().setUp()

        self.client = APIClient()

        # This submission that belongs to another project shouldn't
        # prevent us from downloading files for our project.
        obj_build.make_submission(
            status=ag_models.Submission.GradingStatus.being_graded)

        self.files = [
            SimpleUploadedFile('file1.txt', b'adsfadslkfajsdkfj'),
            SimpleUploadedFile('file2.txt', b'asdqeirueinfaksdnfaadf'),
            SimpleUploadedFile('file3.txt', b'cmxcnajsddhadf')
        ]

        self.files_by_name = dict(
            zip([file_.name for file_ in self.files], self.files))

        max_group_size = 3
        self.project = obj_build.make_project(visible_to_students=True,
                                              max_group_size=max_group_size)
        ag_models.ExpectedStudentFile.objects.validate_and_create(
            project=self.project, pattern='*', max_num_matches=3)
        self.student_group1 = obj_build.make_group(project=self.project)
        self.group1_submission1 = obj_build.make_finished_submission(
            submitted_files=self.files[:1], group=self.student_group1)
        self.group1_submission2 = obj_build.make_finished_submission(
            submitted_files=self.files[:2], group=self.student_group1)

        self.student_group2 = obj_build.make_group(num_members=max_group_size,
                                                   project=self.project)
        self.group2_submission1 = obj_build.make_finished_submission(
            submitted_files=self.files[-1:], group=self.student_group2)

        self.staff_group = obj_build.make_group(
            project=self.project, members_role=obj_build.UserRole.staff)
        self.staff_submission1 = obj_build.make_finished_submission(
            submitted_files=self.files, group=self.staff_group)

        self.no_submissions_group = obj_build.make_group(project=self.project)

        [self.admin] = obj_build.make_admin_users(self.project.course, 1)
    def test_get_results_group_has_no_submissions(self):
        group = obj_build.make_group(num_members=2, project=self.project)
        self.assertEqual(0, group.submissions.count())

        admin = obj_build.make_admin_user(self.course)
        self.client.force_authenticate(admin)

        response = self.client.get(self.base_url)
        self.assertEqual(status.HTTP_200_OK, response.status_code)
        self.assertSequenceEqual([], response.data['results'])
Beispiel #15
0
class _TestCase(UnitTestBase):
    class GroupAndSubmissionData:
        def __init__(self, group: ag_models.Group,
                     best_submission: ag_models.Submission,
                     most_recent_submission: ag_models.Submission):
            self.group = group
            self.best_submission = best_submission
            self.most_recent_submission = most_recent_submission

    def prepare_data(self,
                     project: ag_models.Project,
                     num_suites=1,
                     cases_per_suite=1,
                     cmds_per_suite=1,
                     num_groups=1,
                     num_other_submissions=0) -> List[GroupAndSubmissionData]:
        cmds = []
        for i in range(num_suites):
            sys.stdout.write('\rBuilding suite {}'.format(i))
            sys.stdout.flush()
            suite = obj_build.make_ag_test_suite(project)
            for j in range(cases_per_suite):
                case = obj_build.make_ag_test_case(suite)
                for k in range(cmds_per_suite):
                    cmd = obj_build.make_full_ag_test_command(case)
                    cmds.append(cmd)

        group_and_submission_data = []
        for i in range(num_groups):
            sys.stdout.write('\rBuilding group {}'.format(i))
            sys.stdout.flush()
            group = obj_build.make_group(project=project)
            best_sub = obj_build.make_finished_submission(group=group)
            for cmd in cmds:
                obj_build.make_correct_ag_test_command_result(
                    cmd, submission=best_sub)
            best_sub = update_denormalized_ag_test_results(best_sub.pk)

            for j in range(num_other_submissions):
                sub = obj_build.make_finished_submission(group=group)
                for cmd in cmds:
                    obj_build.make_incorrect_ag_test_command_result(
                        cmd, submission=sub)
                sub = update_denormalized_ag_test_results(sub.pk)

            most_recent = obj_build.make_finished_submission(group=group)
            for cmd in cmds:
                obj_build.make_incorrect_ag_test_command_result(
                    cmd, submission=most_recent)
            most_recent = update_denormalized_ag_test_results(most_recent.pk)

            group_and_submission_data.append(
                self.GroupAndSubmissionData(group, best_sub, most_recent))

        return group_and_submission_data
Beispiel #16
0
    def setUp(self):
        super().setUp()
        self.project = obj_build.make_project()
        self.course = self.project.course

        self.counts_for_user = obj_build.make_student_user(self.course)
        self.does_not_count_for_user = obj_build.make_student_user(self.course)

        self.group = obj_build.make_group(
            members=[self.counts_for_user, self.does_not_count_for_user],
            project=self.project)
    def test_download_ultimate_submission_scores_only_one_staff_group_with_submission(
            self):
        # This is a regression test to prevent a divide by zero error.
        # See https://github.com/eecs-autograder/autograder-server/issues/273
        ag_models.Group.objects.all().delete()
        group = obj_build.make_group(project=self.project,
                                     members_role=obj_build.UserRole.admin)
        obj_build.make_finished_submission(group)

        # Exclude staff
        self.do_ultimate_submission_scores_csv_test(self.url, [])
Beispiel #18
0
    def test_error_some_submissions_not_in_project(self):
        other_submission = obj_build.make_submission(
            group=obj_build.make_group())

        with self.assertRaises(exceptions.ValidationError) as cm:
            ag_models.RerunSubmissionsTask.objects.validate_and_create(
                creator=self.creator,
                project=self.project,
                rerun_all_submissions=False,
                submission_pks=[other_submission.pk])

        self.assertIn('submission_pks', cm.exception.message_dict)
Beispiel #19
0
    def setUp(self):
        super().setUp()
        self.project = obj_build.make_project()
        [self.creator] = obj_build.make_admin_users(self.project.course, 1)

        self.ag_test_suite = obj_build.make_ag_test_suite(self.project)
        self.ag_test_case = obj_build.make_ag_test_case(self.ag_test_suite)
        self.student_test_suite = obj_build.make_student_test_suite(
            self.project)

        self.submission = obj_build.make_submission(group=obj_build.make_group(
            project=self.project))
    def setUp(self):
        super().setUp()
        self.initial_num_bonus_submissions = 10
        self.project = obj_build.make_project(
            num_bonus_submissions=self.initial_num_bonus_submissions)

        self.groups = [
            obj_build.make_group(project=self.project) for i in range(5)
        ]

        # Make sure bonus submissions are only changed for self.project
        self.other_project = obj_build.make_project(course=self.project.course,
                                                    num_bonus_submissions=3)
        self.other_groups = [
            obj_build.make_group(project=self.other_project) for i in range(5)
        ]

        self.admin = obj_build.make_admin_user(self.project.course)
        self.url = reverse('edit-bonus-submissions',
                           kwargs={'project_pk': self.project.pk})
        self.client = APIClient()
Beispiel #21
0
    def test_get_ultimate_submission_no_finished_submissions(self):
        for policy in ag_models.UltimateSubmissionPolicy:
            self.project.validate_and_update(ultimate_submission_policy=policy)
            group = obj_build.make_group(project=self.project)
            submission = obj_build.make_submission(group=group)

            self.assertEqual(1, group.submissions.count())
            self.assertNotEqual(
                ag_models.Submission.GradingStatus.finished_grading,
                submission.status)
            ultimate_submission = get_ultimate_submission(group)
            self.assertIsNone(ultimate_submission)
    def test_group_has_unfinished_handgrading_result(self):
        handgrading_rubric = hg_models.HandgradingRubric.objects.validate_and_create(
            project=self.project)  # type: hg_models.HandgradingRubric

        criterion = hg_models.Criterion.objects.validate_and_create(
            points=2, handgrading_rubric=handgrading_rubric)

        group_unfinished_handgrading = obj_build.make_group(
            project=self.project)
        submission = obj_build.make_finished_submission(
            group_unfinished_handgrading)
        submission = self._add_results_to_submission(submission,
                                                     results_correct=False)
        submission_fdbk = SubmissionResultFeedback(
            submission, ag_models.FeedbackCategory.max, self.ag_test_preloader)
        handgrading_result = hg_models.HandgradingResult.objects.validate_and_create(
            submission=submission,
            group=group_unfinished_handgrading,
            handgrading_rubric=handgrading_rubric,
            finished_grading=False)  # type: hg_models.HandgradingResult
        hg_models.CriterionResult.objects.validate_and_create(
            selected=True,
            criterion=criterion,
            handgrading_result=handgrading_result)

        expected = [{
            'username': group_unfinished_handgrading.member_names[0],
            'group': group_unfinished_handgrading.to_dict(),
            'ultimate_submission': {
                'results': {
                    'total_points':
                    two_decimal_place_string(submission_fdbk.total_points),
                    'total_points_possible':
                    two_decimal_place_string(
                        submission_fdbk.total_points_possible),
                    'handgrading_total_points':
                    None,
                    'handgrading_total_points_possible':
                    None
                },
                **submission.to_dict()
            }
        }]

        actual = serialize_ultimate_submission_results(
            [
                SubmissionResultFeedback(submission,
                                         ag_models.FeedbackCategory.max,
                                         self.ag_test_preloader)
            ],
            full_results=False,
            include_handgrading=True)
        self.assertEqual(expected, actual)
Beispiel #23
0
    def test_prefetching_doesnt_skew_num_submissions_and_num_submissions_towards_limit(
            self):
        self.maxDiff = None
        group1 = obj_build.make_group(project=self.visible_public_project)
        group1_yesterday_submission = obj_build.make_submission(
            group=group1,
            timestamp=timezone.now() - datetime.timedelta(days=1))
        group1_not_towards_limit_submission = obj_build.make_submission(
            group=group1, count_towards_daily_limit=False)
        group1_towards_limit_submission = obj_build.make_submission(
            group=group1)

        group1.refresh_from_db()
        self.assertEqual(3, group1.num_submissions)
        self.assertEqual(1, group1.num_submits_towards_limit)

        group2 = obj_build.make_group(project=self.visible_public_project)
        group2_yesterday_submission = obj_build.make_submission(
            group=group2,
            timestamp=timezone.now() - datetime.timedelta(days=1))
        group2_yesterday_submission2 = obj_build.make_submission(
            group=group2,
            timestamp=timezone.now() - datetime.timedelta(days=1))
        group2_not_towards_limit_submission = obj_build.make_submission(
            group=group2, count_towards_daily_limit=False)
        group2_towards_limit_submission = obj_build.make_submission(
            group=group2)

        group2.refresh_from_db()
        self.assertEqual(4, group2.num_submissions)
        self.assertEqual(1, group2.num_submits_towards_limit)

        self.client.force_authenticate(self.admin)
        response = self.client.get(
            self.get_groups_url(self.visible_public_project))
        self.assertEqual(status.HTTP_200_OK, response.status_code)

        self.assertCountEqual(
            [group1.to_dict(), group2.to_dict()], response.data)
Beispiel #24
0
    def test_get_ultimate_submission_group_has_no_submissions(self):
        for policy in ag_models.UltimateSubmissionPolicy:
            self.project.validate_and_update(ultimate_submission_policy=policy)
            group = obj_build.make_group(project=self.project)

            self.assertEqual(0, group.submissions.count())
            ultimate_submission = get_ultimate_submission(group)
            self.assertIsNone(ultimate_submission)

            ultimate_submissions = list(
                get_ultimate_submissions(self.project,
                                         filter_groups=[group],
                                         ag_test_preloader=AGTestPreLoader(
                                             self.project)))
            self.assertSequenceEqual([], ultimate_submissions)
    def test_subtract_bonus_submissions_one_group_only(self):
        to_subtract = 5

        new_group = obj_build.make_group(project=self.project)
        url = self.url + f'?group_pk={new_group.pk}'

        self.client.force_authenticate(self.admin)
        response = self.client.patch(url, {'subtract': to_subtract})
        self.assertEqual(status.HTTP_204_NO_CONTENT, response.status_code)

        new_group.refresh_from_db()
        self.assertEqual(self.initial_num_bonus_submissions - to_subtract,
                         new_group.bonus_submissions_remaining)

        self._check_bonus_submissions(self.initial_num_bonus_submissions)
    def setUp(self):
        super().setUp()

        self.rubric = handgrading_models.HandgradingRubric.objects.validate_and_create(
            project=obj_build.build_project())

        ag_models.ExpectedStudentFile.objects.validate_and_create(
            project=self.rubric.project, pattern='*', max_num_matches=10)
        self.submitted_files = [
            SimpleUploadedFile('file{}'.format(i), b'waaaluigi')
            for i in range(4)
        ]
        self.submission = obj_build.make_submission(
            group=obj_build.make_group(project=self.rubric.project),
            submitted_files=self.submitted_files)
Beispiel #27
0
    def test_user_passed_to_get_ultimate_submission_func(self):
        project = obj_build.make_project(visible_to_students=True,
                                         hide_ultimate_submission_fdbk=False)
        group = obj_build.make_group(project=project)

        mocked_get_ultimate_submission = mock.Mock(return_value=None)

        with mock.patch(
                'autograder.rest_api.views.group_views.get_ultimate_submission',
                new=mocked_get_ultimate_submission):
            self.client.force_authenticate(group.members.first())
            response = self.client.get(self.ultimate_submission_url(group))
            self.assertEqual(status.HTTP_404_NOT_FOUND, response.status_code)

            mocked_get_ultimate_submission.assert_called_once_with(
                group, user=group.members.first())
    def test_create_criterion_results_on_create(self):
        [admin] = obj_build.make_admin_users(self.course, 1)
        self.client.force_authenticate(admin)

        # Create HandgradingResult
        submission = obj_build.make_submission(
            group=obj_build.make_group(project=self.handgrading_rubric.project))
        handgrading_result = hg_models.HandgradingResult.objects.validate_and_create(
            submission=submission,
            group=submission.group,
            handgrading_rubric=self.handgrading_rubric)

        # Create dummy submissions and groups with no submissions. These should not be affected
        dummy_submission = obj_build.make_submission(
            group=obj_build.make_group(project=self.handgrading_rubric.project))
        dummy_submission = obj_build.make_submission(
            group=obj_build.make_group(project=self.handgrading_rubric.project))
        group_with_no_submission = obj_build.make_group(project=self.handgrading_rubric.project)
        group_with_no_submission = obj_build.make_group(project=self.handgrading_rubric.project)

        self.assertEqual(0, handgrading_result.criterion_results.count())
        self.assertEqual(1, hg_models.HandgradingResult.objects.count())

        # Create dummy project with its own groups and HandgradingResults.
        #   These should not be affected
        dummy_project = obj_build.make_project(course=self.handgrading_rubric.project.course)
        dummy_handgrading_rubric = hg_models.HandgradingRubric.objects.validate_and_create(
            points_style=hg_models.PointsStyle.start_at_max_and_subtract,
            max_points=0,
            show_grades_and_rubric_to_students=False,
            handgraders_can_leave_comments=True,
            handgraders_can_adjust_points=True,
            project=dummy_project)
        dummy_submission = obj_build.make_submission(
            group=obj_build.make_group(project=self.handgrading_rubric.project))
        dummy_handgrading_result = hg_models.HandgradingResult.objects.validate_and_create(
            submission=dummy_submission,
            group=dummy_submission.group,
            handgrading_rubric=dummy_handgrading_rubric)

        self.assertEqual(0, hg_models.CriterionResult.objects.count())
        self.assertEqual(2, hg_models.HandgradingResult.objects.count())

        # Create Criterion, which should create a CriterionResult for above HandgradingResult
        response = self.client.post(self.url, self.data)
        self.assertEqual(status.HTTP_201_CREATED, response.status_code)

        handgrading_result.refresh_from_db()
        self.assertEqual(1, handgrading_result.criterion_results.count())
        self.assertEqual(1, hg_models.CriterionResult.objects.count())

        criterion_results = handgrading_result.to_dict()["criterion_results"]
        self.assertFalse(criterion_results[0]["selected"])
        self.assertEqual(criterion_results[0]["criterion"], response.data)
Beispiel #29
0
    def test_prefetching_doesnt_skew_num_submissions_and_num_submissions_towards_limit(
            self):
        group = obj_build.make_group(project=self.visible_public_project)
        yesterday_submission = obj_build.make_submission(
            group=group, timestamp=timezone.now() - datetime.timedelta(days=1))
        not_towards_limit_submission = obj_build.make_submission(
            group=group, count_towards_daily_limit=False)
        towards_limit_submission = obj_build.make_submission(group=group)

        group.refresh_from_db()
        self.assertEqual(3, group.num_submissions)
        self.assertEqual(1, group.num_submits_towards_limit)

        self.client.force_authenticate(self.admin)
        response = self.client.get(self.group_url(group))
        self.assertEqual(status.HTTP_200_OK, response.status_code)
        self.assertEqual(3, response.data['num_submissions'])
        self.assertEqual(1, response.data['num_submits_towards_limit'])
Beispiel #30
0
    def test_get_ultimate_submission_no_finished_submissions(self):
        group_with_finished_submissions_data = self.prepare_data(
            self.project)[0]

        group_with_no_finished_submissions = obj_build.make_group(
            project=self.project)
        unfinished_submission = obj_build.make_submission(
            group=group_with_no_finished_submissions)

        self.project.validate_and_update(ultimate_submission_policy=ag_models.
                                         UltimateSubmissionPolicy.most_recent)

        self.assertEqual(
            1, group_with_no_finished_submissions.submissions.count())
        self.assertNotEqual(
            ag_models.Submission.GradingStatus.finished_grading,
            unfinished_submission.status)
        ultimate_submissions = [
            fdbk.submission for fdbk in get_ultimate_submissions(
                self.project,
                filter_groups=None,
                ag_test_preloader=AGTestPreLoader(self.project))
        ]
        self.assertSequenceEqual(
            [group_with_finished_submissions_data.most_recent_submission],
            ultimate_submissions)

        self.project.validate_and_update(
            ultimate_submission_policy=ag_models.UltimateSubmissionPolicy.best)

        self.assertEqual(
            1, group_with_no_finished_submissions.submissions.count())
        self.assertNotEqual(
            ag_models.Submission.GradingStatus.finished_grading,
            unfinished_submission.status)
        ultimate_submissions = [
            fdbk.submission for fdbk in get_ultimate_submissions(
                self.project,
                filter_groups=None,
                ag_test_preloader=AGTestPreLoader(self.project))
        ]
        self.assertSequenceEqual(
            [group_with_finished_submissions_data.best_submission],
            ultimate_submissions)