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)
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 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'])
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 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, [])
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)
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()
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)
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)
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)
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)
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'])
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)