예제 #1
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)
    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 _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
예제 #4
0
 def test_non_enrolled_get_ultimate_project_hidden_permission_denied(self):
     self.hidden_public_project.validate_and_update(
         closing_time=None, hide_ultimate_submission_fdbk=False)
     group = self.non_enrolled_group(self.hidden_public_project)
     obj_build.make_finished_submission(group=group)
     self.do_permission_denied_get_test(self.client, self.nobody,
                                        self.ultimate_submission_url(group))
    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)
예제 #6
0
 def test_enrolled_get_ultimate_project_hidden_permission_denied(self):
     for project in self.hidden_projects:
         project.validate_and_update(closing_time=self.past_closing_time,
                                     hide_ultimate_submission_fdbk=False)
         group = self.enrolled_group(project)
         obj_build.make_finished_submission(group=group)
         self.do_permission_denied_get_test(
             self.client, self.enrolled,
             self.ultimate_submission_url(group))
예제 #7
0
 def test_non_enrolled_get_ultimate_project_private_permission_denied(self):
     group = self.non_enrolled_group(self.visible_public_project)
     self.visible_public_project.validate_and_update(
         guests_can_submit=False,
         closing_time=self.past_closing_time,
         hide_ultimate_submission_fdbk=False)
     obj_build.make_finished_submission(group=group)
     self.do_permission_denied_get_test(self.client, self.nobody,
                                        self.ultimate_submission_url(group))
예제 #8
0
 def test_deadline_not_past_student_view_own_ultimate_permission_denied(
         self):
     self.visible_public_project.validate_and_update(
         closing_time=timezone.now() + timezone.timedelta(minutes=5),
         hide_ultimate_submission_fdbk=False)
     for group in self.non_staff_groups(self.visible_public_project):
         obj_build.make_finished_submission(group=group)
         self.do_permission_denied_get_test(
             self.client, group.members.first(),
             self.ultimate_submission_url(group))
예제 #9
0
 def test_deadline_past_or_none_but_ultimate_fdbk_hidden_permission_denied(
         self):
     for closing_time in None, self.past_closing_time:
         self.visible_public_project.validate_and_update(
             hide_ultimate_submission_fdbk=True, closing_time=closing_time)
         for group in self.non_staff_groups(self.visible_public_project):
             obj_build.make_finished_submission(group=group)
             self.do_permission_denied_get_test(
                 self.client, group.members.first(),
                 self.ultimate_submission_url(group))
예제 #10
0
 def test_extension_past_but_ultimate_fdbk_hidden_permission_denied(self):
     self.visible_public_project.validate_and_update(
         closing_time=self.past_closing_time,
         hide_ultimate_submission_fdbk=True)
     for group in self.non_staff_groups(self.visible_public_project):
         group.validate_and_update(extended_due_date=self.past_extension)
         obj_build.make_finished_submission(group=group)
         self.do_permission_denied_get_test(
             self.client, group.members.first(),
             self.ultimate_submission_url(group))
예제 #11
0
 def test_non_member_get_ultimate_permission_denied(self):
     self.visible_public_project.validate_and_update(
         closing_time=self.past_closing_time,
         hide_ultimate_submission_fdbk=False)
     group = self.enrolled_group(self.visible_public_project)
     obj_build.make_finished_submission(group=group)
     other_user = self.clone_user(self.enrolled)
     for user in self.nobody, other_user:
         self.do_permission_denied_get_test(
             self.client, user, self.ultimate_submission_url(group))
예제 #12
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
    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, [])
    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)
예제 #15
0
    def test_bonus_submission_counts_towards_limit(self):
        self.project.validate_and_update(
            num_bonus_submissions=1,
            submission_limit_per_day=1
        )
        group: ag_models.Group = ag_models.Group.objects.validate_and_create(
            members=self.student_users, project=self.project)

        regular_submission = obj_build.make_finished_submission(group=group)
        bonus_submission = obj_build.make_finished_submission(
            group=group, is_bonus_submission=True)
        past_limit_submission = obj_build.make_finished_submission(
            group=group, is_past_daily_limit=True)

        self.assertEqual(3, group.num_submits_towards_limit)
예제 #16
0
    def test_two_best_dont_count_for_user(self):
        self.project.validate_and_update(
            ultimate_submission_policy=ag_models.UltimateSubmissionPolicy.best)

        suite = ag_models.StudentTestSuite.objects.validate_and_create(
            name='suite',
            project=self.project,
            buggy_impl_names=[f'bug{i}' for i in range(3)],
            points_per_exposed_bug=1)

        best_submission = obj_build.make_finished_submission(
            self.group,
            does_not_count_for=[self.does_not_count_for_user.username])
        ag_models.StudentTestSuiteResult.objects.validate_and_create(
            student_test_suite=suite,
            submission=best_submission,
            bugs_exposed=suite.buggy_impl_names)
        self.assertEqual(
            3,
            get_submission_fdbk(best_submission,
                                ag_models.FeedbackCategory.max).total_points)

        second_best_submission = obj_build.make_finished_submission(
            self.group,
            does_not_count_for=[self.does_not_count_for_user.username])
        ag_models.StudentTestSuiteResult.objects.validate_and_create(
            student_test_suite=suite,
            submission=second_best_submission,
            bugs_exposed=suite.buggy_impl_names[:-1])
        self.assertEqual(
            2,
            get_submission_fdbk(second_best_submission,
                                ag_models.FeedbackCategory.max).total_points)

        other_submission = obj_build.make_finished_submission(self.group)
        self.assertEqual(
            0,
            get_submission_fdbk(other_submission,
                                ag_models.FeedbackCategory.max).total_points)

        counts_for_user_ultimate_submission = get_ultimate_submission(
            self.group, user=self.counts_for_user)
        self.assertEqual(best_submission, counts_for_user_ultimate_submission)

        does_not_count_for_user_ultimate_submission = get_ultimate_submission(
            self.group, user=self.does_not_count_for_user)
        self.assertEqual(other_submission,
                         does_not_count_for_user_ultimate_submission)
    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)
    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)
예제 #19
0
    def test_no_submissions_count_for_user(self):
        oldest_submission = obj_build.make_finished_submission(
            self.group,
            does_not_count_for=[self.does_not_count_for_user.username])
        most_recent_submission = obj_build.make_finished_submission(
            self.group,
            does_not_count_for=[self.does_not_count_for_user.username])

        counts_for_user_ultimate_submission = get_ultimate_submission(
            self.group, user=self.counts_for_user)
        self.assertEqual(most_recent_submission,
                         counts_for_user_ultimate_submission)

        does_not_count_for_user_ultimate_submission = get_ultimate_submission(
            self.group, user=self.does_not_count_for_user)
        self.assertIsNone(does_not_count_for_user_ultimate_submission)
예제 #20
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'])
예제 #22
0
    def test_most_recent_does_not_count_for_user(self):
        self.project.validate_and_update(ultimate_submission_policy=ag_models.
                                         UltimateSubmissionPolicy.most_recent)

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

        counts_for_user_ultimate_submission = get_ultimate_submission(
            self.group, user=self.counts_for_user)
        self.assertEqual(most_recent_submission,
                         counts_for_user_ultimate_submission)

        does_not_count_for_user_ultimate_submission = get_ultimate_submission(
            self.group, user=self.does_not_count_for_user)
        self.assertEqual(oldest_submission,
                         does_not_count_for_user_ultimate_submission)
 def test_ultimate_submission_files_include_staff(self):
     url = reverse('project-ultimate-submission-files',
                   kwargs={'pk': self.project.pk})
     url += '?include_staff=true'
     staff_submission2 = obj_build.make_finished_submission(
         submitted_files=self.files[:-1], group=self.staff_group)
     most_recent_submissions = [
         self.group1_submission2, self.group2_submission1, staff_submission2
     ]
     self.do_download_submissions_test(url, most_recent_submissions)
    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)
예제 #25
0
    def do_get_ultimate_submission_test(self,
                                        projects,
                                        group_funcs,
                                        users,
                                        closing_time,
                                        extension=None,
                                        hide_ultimates=False):
        for project in projects:
            project.validate_and_update(
                closing_time=closing_time,
                hide_ultimate_submission_fdbk=hide_ultimates)
            for group_func in group_funcs:
                group = group_func(project)
                group.validate_and_update(extended_due_date=extension)

                suite = obj_build.make_ag_test_suite(project)
                case = obj_build.make_ag_test_case(suite)
                cmd = obj_build.make_full_ag_test_command(case)
                best_submission = obj_build.make_finished_submission(
                    group=group)
                most_recent_submission = obj_build.make_finished_submission(
                    group=group)

                obj_build.make_correct_ag_test_command_result(
                    cmd, submission=best_submission)
                obj_build.make_incorrect_ag_test_command_result(
                    cmd, submission=most_recent_submission)

                for user in users:
                    url = self.ultimate_submission_url(group)
                    project.validate_and_update(
                        ultimate_submission_policy=ag_models.
                        UltimateSubmissionPolicy.most_recent)
                    self.do_get_object_test(self.client, user, url,
                                            most_recent_submission.to_dict())

                    project.validate_and_update(
                        ultimate_submission_policy=ag_models.
                        UltimateSubmissionPolicy.best)
                    self.do_get_object_test(self.client, user, url,
                                            best_submission.to_dict())
    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)
예제 #27
0
    def test_progress_computation(self):
        completed_count = 1
        rerun_task = ag_models.RerunSubmissionsTask.objects.validate_and_create(
            creator=self.creator,
            project=self.project,
            num_completed_subtasks=completed_count,
        )  # type: ag_models.RerunSubmissionsTask

        num_subtasks = (self.project.ag_test_suites.count() +
                        self.project.student_test_suites.count())

        self.assertAlmostEqual((completed_count / num_subtasks) * 100,
                               rerun_task.progress)

        # Make sure that the computed grogress doesn't change if we add
        # submissions (https://github.com/eecs-autograder/autograder-server/issues/274)
        other_submission = obj_build.make_finished_submission(
            group=self.submission.group)
        self.assertAlmostEqual((completed_count / num_subtasks) * 100,
                               rerun_task.progress)
예제 #28
0
    def test_get_ultimate_only_finished_grading_status_considered(self):
        group = obj_build.make_group(project=self.project)
        ultimate_submission = obj_build.make_finished_submission(group=group)
        non_considered_statuses = filter(
            lambda val: val != ag_models.Submission.GradingStatus.
            finished_grading, ag_models.Submission.GradingStatus.values)
        for grading_status in non_considered_statuses:
            obj_build.make_submission(group=group, status=grading_status)

        self.assertEqual(
            1,
            ag_models.Submission.objects.filter(
                status=ag_models.Submission.GradingStatus.finished_grading).
            count())

        for ultimate_submission_policy in ag_models.UltimateSubmissionPolicy:
            self.project.validate_and_update(
                ultimate_submission_policy=ultimate_submission_policy)
            self.assertSequenceEqual([ultimate_submission], [
                fdbk.submission for fdbk in get_ultimate_submissions(
                    self.project,
                    filter_groups=None,
                    ag_test_preloader=AGTestPreLoader(self.project))
            ])
    def test_serialize_groups_ultimate_submissions(self):
        group1 = obj_build.make_group(project=self.project)
        submission1 = obj_build.make_finished_submission(group1)
        submission1 = self._add_results_to_submission(submission1,
                                                      results_correct=False)
        submission1_fdbk = SubmissionResultFeedback(
            submission1, ag_models.FeedbackCategory.max,
            self.ag_test_preloader)
        self.assertEqual(0, submission1_fdbk.total_points)
        self.assertNotEqual(0, submission1_fdbk.total_points_possible)

        group2 = obj_build.make_group(project=self.project, num_members=2)
        submission2 = obj_build.make_finished_submission(group2)
        submission2 = self._add_results_to_submission(submission2,
                                                      results_correct=True)
        submission2_fdbk = SubmissionResultFeedback(
            submission2, ag_models.FeedbackCategory.max,
            self.ag_test_preloader)
        self.assertNotEqual(0, submission2_fdbk.total_points)
        self.assertNotEqual(0, submission2_fdbk.total_points_possible)

        expected = [{
            'username': group1.member_names[0],
            'group': group1.to_dict(),
            'ultimate_submission': {
                'results': {
                    'total_points':
                    two_decimal_place_string(submission1_fdbk.total_points),
                    'total_points_possible':
                    two_decimal_place_string(
                        submission1_fdbk.total_points_possible)
                },
                **submission1.to_dict()
            }
        }, {
            'username': group2.member_names[0],
            'group': group2.to_dict(),
            'ultimate_submission': {
                'results': {
                    'total_points':
                    two_decimal_place_string(submission2_fdbk.total_points),
                    'total_points_possible':
                    two_decimal_place_string(
                        submission2_fdbk.total_points_possible)
                },
                **submission2.to_dict()
            }
        }, {
            'username': group2.member_names[1],
            'group': group2.to_dict(),
            'ultimate_submission': {
                'results': {
                    'total_points':
                    two_decimal_place_string(submission2_fdbk.total_points),
                    'total_points_possible':
                    two_decimal_place_string(
                        submission2_fdbk.total_points_possible)
                },
                **submission2.to_dict()
            }
        }]

        actual = serialize_ultimate_submission_results([
            SubmissionResultFeedback(submission1,
                                     ag_models.FeedbackCategory.max,
                                     self.ag_test_preloader),
            SubmissionResultFeedback(submission2,
                                     ag_models.FeedbackCategory.max,
                                     self.ag_test_preloader)
        ],
                                                       full_results=False)
        self.assertEqual(expected, actual)
    def test_some_groups_have_finished_handgrading_result_others_have_no_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_no_handgrading = obj_build.make_group(project=self.project)
        submission1 = obj_build.make_finished_submission(group_no_handgrading)
        submission1 = self._add_results_to_submission(submission1,
                                                      results_correct=False)
        submission1_fdbk = SubmissionResultFeedback(
            submission1, ag_models.FeedbackCategory.max,
            self.ag_test_preloader)
        self.assertEqual(0, submission1_fdbk.total_points)
        self.assertNotEqual(0, submission1_fdbk.total_points_possible)

        group_2_members = obj_build.make_group(project=self.project,
                                               num_members=2)
        submission2 = obj_build.make_finished_submission(group_2_members)
        submission2 = self._add_results_to_submission(submission2,
                                                      results_correct=True)
        submission2_fdbk = SubmissionResultFeedback(
            submission2, ag_models.FeedbackCategory.max,
            self.ag_test_preloader)
        self.assertNotEqual(0, submission2_fdbk.total_points)
        self.assertNotEqual(0, submission2_fdbk.total_points_possible)
        group_2_handgrading_result = hg_models.HandgradingResult.objects.validate_and_create(
            submission=submission2,
            group=group_2_members,
            handgrading_rubric=handgrading_rubric,
            finished_grading=True)  # type: hg_models.HandgradingResult
        hg_models.CriterionResult.objects.validate_and_create(
            selected=True,
            criterion=criterion,
            handgrading_result=group_2_handgrading_result)

        group_with_handgrading = obj_build.make_group(project=self.project)
        submission3 = obj_build.make_finished_submission(
            group_with_handgrading)
        submission3 = self._add_results_to_submission(submission3,
                                                      results_correct=False)
        submission3_fdbk = SubmissionResultFeedback(
            submission3, ag_models.FeedbackCategory.max,
            self.ag_test_preloader)
        self.assertEqual(0, submission3_fdbk.total_points)
        self.assertNotEqual(0, submission3_fdbk.total_points_possible)
        group_3_handgrading_result = hg_models.HandgradingResult.objects.validate_and_create(
            submission=submission3,
            group=group_with_handgrading,
            handgrading_rubric=handgrading_rubric,
            finished_grading=True)  # type: hg_models.HandgradingResult
        hg_models.CriterionResult.objects.validate_and_create(
            selected=False,
            criterion=criterion,
            handgrading_result=group_3_handgrading_result)

        expected = [{
            'username': group_no_handgrading.member_names[0],
            'group': group_no_handgrading.to_dict(),
            'ultimate_submission': {
                'results': {
                    'total_points':
                    two_decimal_place_string(submission1_fdbk.total_points),
                    'total_points_possible':
                    two_decimal_place_string(
                        submission1_fdbk.total_points_possible),
                    'handgrading_total_points':
                    None,
                    'handgrading_total_points_possible':
                    None
                },
                **submission1.to_dict()
            }
        }, {
            'username': group_2_members.member_names[0],
            'group': group_2_members.to_dict(),
            'ultimate_submission': {
                'results': {
                    'total_points':
                    two_decimal_place_string(submission2_fdbk.total_points),
                    'total_points_possible':
                    two_decimal_place_string(
                        submission2_fdbk.total_points_possible),
                    'handgrading_total_points':
                    (submission2_fdbk.submission.handgrading_result.
                     total_points),
                    'handgrading_total_points_possible':
                    (submission2_fdbk.submission.handgrading_result.
                     total_points_possible)
                },
                **submission2.to_dict()
            }
        }, {
            'username': group_2_members.member_names[1],
            'group': group_2_members.to_dict(),
            'ultimate_submission': {
                'results': {
                    'total_points':
                    two_decimal_place_string(submission2_fdbk.total_points),
                    'total_points_possible':
                    two_decimal_place_string(
                        submission2_fdbk.total_points_possible),
                    'handgrading_total_points':
                    (submission2_fdbk.submission.handgrading_result.
                     total_points),
                    'handgrading_total_points_possible':
                    (submission2_fdbk.submission.handgrading_result.
                     total_points_possible)
                },
                **submission2.to_dict()
            }
        }, {
            'username': group_with_handgrading.member_names[0],
            'group': group_with_handgrading.to_dict(),
            'ultimate_submission': {
                'results': {
                    'total_points':
                    two_decimal_place_string(submission3_fdbk.total_points),
                    'total_points_possible':
                    two_decimal_place_string(
                        submission3_fdbk.total_points_possible),
                    'handgrading_total_points':
                    (submission3_fdbk.submission.handgrading_result.
                     total_points),
                    'handgrading_total_points_possible':
                    (submission3_fdbk.submission.handgrading_result.
                     total_points_possible)
                },
                **submission3.to_dict()
            }
        }]

        actual = serialize_ultimate_submission_results(
            [
                SubmissionResultFeedback(submission1,
                                         ag_models.FeedbackCategory.max,
                                         self.ag_test_preloader),
                SubmissionResultFeedback(submission2,
                                         ag_models.FeedbackCategory.max,
                                         self.ag_test_preloader),
                SubmissionResultFeedback(submission3,
                                         ag_models.FeedbackCategory.max,
                                         self.ag_test_preloader)
            ],
            full_results=False,
            include_handgrading=True)
        self.assertEqual(expected, actual)