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
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)
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))
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))
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))
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))
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))
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))
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)
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)
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)
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)
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 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)
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)
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)
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)