def test_get_results_exclude_staff(self): student_group, student_submission = self._make_group_with_submissions( 1) # Staff and admin will be excluded staff_group, staff_submission = self._make_group_with_submissions( 1, members_role=obj_build.UserRole.staff) admin_group, admin_submission = self._make_group_with_submissions( 1, members_role=obj_build.UserRole.admin) expected = [ self._make_result_content_for_user(student_group.member_names[0], student_group, student_submission, points_only=True), ] admin = obj_build.make_admin_user(self.course) self.client.force_authenticate(admin) query_params = {'include_staff': 'false'} url = f'{self.base_url}?{urlencode(query_params)}' admin = obj_build.make_admin_user(self.course) self.client.force_authenticate(admin) response = self.client.get(url) self.assertEqual(status.HTTP_200_OK, response.status_code) self.assertSequenceEqual(expected, response.data['results'])
def test_admin_get_results_ultimate_policy_most_recent(self): self.assertEqual(ag_models.UltimateSubmissionPolicy.most_recent, self.project.ultimate_submission_policy) student_group, _ = self._make_group_with_submissions(2, num_submissions=3) staff_group, _ = self._make_group_with_submissions( 1, members_role=obj_build.UserRole.staff) expected = [ self._make_result_content_for_user( username, student_group, student_group.submissions.first(), points_only=True) for username in student_group.member_names ] expected.append( self._make_result_content_for_user(staff_group.member_names[0], staff_group, staff_group.submissions.first(), points_only=True)) 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(expected, response.data['results'])
def test_user_can_copy_course_and_is_admin_copy_course_new_name_semester_year( self): user = obj_build.make_admin_user(self.course) user.user_permissions.add( Permission.objects.get(codename='create_course')) new_name = 'stave' new_semester = ag_models.Semester.fall new_year = 2017 self.client.force_authenticate(user) response = self.client.post( reverse('copy-course', kwargs={'course_pk': self.course.pk}), { 'new_name': new_name, 'new_semester': new_semester.value, 'new_year': new_year }) self.assertEqual(status.HTTP_201_CREATED, response.status_code) new_course = ag_models.Course.objects.get(pk=response.data['pk']) self.assertEqual(new_name, new_course.name) self.assertEqual(new_semester, new_course.semester) self.assertEqual(new_year, new_course.year) self.assertEqual(new_course.to_dict(), response.data)
def test_admin_change_late_day_count_for_other_course_permission_denied( self): admin = obj_build.make_admin_user(self.course) # Student for other course other_course = obj_build.make_course() other_course_student = obj_build.make_student_user(other_course) self.assertFalse(other_course.is_admin(admin)) self.client.force_authenticate(admin) response = self.client.put( self.get_pk_url(other_course_student, other_course), {'late_days_remaining': 10}) self.assertEqual(status.HTTP_403_FORBIDDEN, response.status_code) response = self.client.put( self.get_username_url(other_course_student, other_course), {'late_days_remaining': 10}) self.assertEqual(status.HTTP_403_FORBIDDEN, response.status_code) # Guest for other course other_guest = obj_build.make_user() response = self.client.put(self.get_pk_url(other_guest, other_course), {'late_days_remaining': 7}) self.assertEqual(status.HTTP_403_FORBIDDEN, response.status_code) other_guest = obj_build.make_user() response = self.client.put( self.get_username_url(other_guest, other_course), {'late_days_remaining': 7}) self.assertEqual(status.HTTP_403_FORBIDDEN, response.status_code)
def test_get_results_no_groups_exist(self): 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'])
def do_ultimate_submission_scores_csv_test(self, url, expected_rows): self.client.force_authenticate(self.admin) response = self.client.post(url) self.assertEqual(status.HTTP_202_ACCEPTED, response.status_code) # Check the content directly from the filesystem task = ag_models.DownloadTask.objects.get(pk=response.data['pk']) self.assertEqual(100, task.progress) self.assertEqual('', task.error_msg) with open(task.result_filename) as f: actual_result = list(csv.DictReader(f)) self.assertEqual(expected_rows, actual_result) # Check the content returned by the result endpoint result_content_url = reverse('download_tasks-result', kwargs={'pk': task.pk}) response = self.client.get(result_content_url) _check_csv_response(self, response, expected_rows) # Make sure that other admin users can request results for downloads # they didn't start. other_admin = obj_build.make_admin_user(self.project.course) self.client.force_authenticate(other_admin) response = self.client.get(result_content_url) _check_csv_response(self, response, expected_rows)
def test_group_has_user_most_recent_doesnt_count_for(self): self.assertEqual(ag_models.UltimateSubmissionPolicy.most_recent, self.project.ultimate_submission_policy) group, _ = self._make_group_with_submissions(2, num_submissions=3) # IMPORTANT: Keep the doesn't count for user as the first in the # group. That way we can verify that special-casing an ultimate # submission for a member of the group doesn't affect the # other group members' scores. doesnt_count_for_username = group.member_names[0] counts_for_username = group.member_names[1] most_recent_submission = group.submissions.all()[0] most_recent_submission.does_not_count_for = [doesnt_count_for_username] most_recent_submission.save() second_most_recent_submission = group.submissions.all()[1] expected = [ self._make_result_content_for_user(doesnt_count_for_username, group, second_most_recent_submission, points_only=True), self._make_result_content_for_user(counts_for_username, group, most_recent_submission, points_only=True) ] 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(expected, response.data['results'])
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 setUp(self): super().setUp() self.client = APIClient() self.project = obj_build.make_project() self.admin = obj_build.make_admin_user(self.project.course) self.other_course = obj_build.make_course() self.other_course.admins.add(self.admin)
def test_put_missing_body_param(self): admin = obj_build.make_admin_user(self.course) self.client.force_authenticate(admin) response = self.client.put(self.get_pk_url(admin, self.course), {}) self.assertEqual(status.HTTP_400_BAD_REQUEST, response.status_code) response = self.client.put(self.get_username_url(admin, self.course), {}) self.assertEqual(status.HTTP_400_BAD_REQUEST, response.status_code)
def test_admin_edit_project(self): request_data = { 'name': self.project.name + 'waaaaa', 'min_group_size': 3, 'max_group_size': 5 } admin = obj_build.make_admin_user(self.course) self.do_patch_object_test(self.project, self.client, admin, self.url, request_data)
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'])
def test_admin_cannot_copy_courses_permission_denied(self): user = obj_build.make_admin_user(self.course) self.client.force_authenticate(user) response = self.client.post( reverse('copy-course', kwargs={'course_pk': self.course.pk}), { 'new_name': 'New', 'new_semester': ag_models.Semester.summer.value, 'new_year': 2021 }) self.assertEqual(status.HTTP_403_FORBIDDEN, response.status_code)
def test_admin_change_late_day_count_by_username(self): admin = obj_build.make_admin_user(self.course) student = obj_build.make_student_user(self.course) self.client.force_authenticate(admin) response = self.client.put(self.get_username_url(student, self.course), {'late_days_remaining': 42}) self.assertEqual(status.HTTP_200_OK, response.status_code) self.assertEqual({'late_days_remaining': 42}, response.data) remaining = ag_models.LateDaysRemaining.objects.get(user=student, course=self.course) self.assertEqual(42, remaining.late_days_remaining)
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 test_course_admin_add_project(self): admin = obj_build.make_admin_user(self.course) args = { 'name': 'spam project', 'min_group_size': 2, 'max_group_size': 3 } self.client.force_authenticate(admin) response = self.client.post(self.url, args) self.assertEqual(status.HTTP_201_CREATED, response.status_code) new_project = self.course.projects.get(name=args['name']) for arg_name, value in args.items(): self.assertEqual(value, getattr(new_project, arg_name), msg=arg_name)
def test_admin_change_late_day_count_by_username_object_exists(self): admin = obj_build.make_admin_user(self.course) student = obj_build.make_student_user(self.course) ag_models.LateDaysRemaining.objects.validate_and_create( user=student, course=self.course) self.do_get_late_days_test(admin, student, self.course, self.initial_num_late_days) self.client.force_authenticate(admin) response = self.client.put(self.get_username_url(student, self.course), {'late_days_remaining': 27}) self.assertEqual(status.HTTP_200_OK, response.status_code) self.assertEqual({'late_days_remaining': 27}, response.data) remaining = ag_models.LateDaysRemaining.objects.get(user=student, course=self.course) self.assertEqual(27, remaining.late_days_remaining)
def test_get_results_custom_page_size(self): student_group1, student_submission1 = self._make_group_with_submissions( 2) # This will be on_page 2 student_group2, student_submission2 = self._make_group_with_submissions( 1) expected = [ # There are still two entries for student_group1, even # though we only have one group per page. self._make_result_content_for_user(student_group1.member_names[0], student_group1, student_submission1, points_only=True), self._make_result_content_for_user(student_group1.member_names[1], student_group1, student_submission1, points_only=True), ] admin = obj_build.make_admin_user(self.course) self.client.force_authenticate(admin) query_params = {'groups_per_page': 1} url = f'{self.base_url}?{urlencode(query_params)}' response = self.client.get(url) self.assertEqual(status.HTTP_200_OK, response.status_code) self.assertSequenceEqual(expected, response.data['results']) page_two = [ self._make_result_content_for_user(student_group2.member_names[0], student_group2, student_submission2, points_only=True), ] query_params = {'groups_per_page': 1, 'page': 2} url = f'{self.base_url}?{urlencode(query_params)}' response = self.client.get(url) self.assertEqual(status.HTTP_200_OK, response.status_code) self.assertSequenceEqual(page_two, response.data['results'])
def test_get_results_with_result_details(self): student_group, submission = self._make_group_with_submissions(1) expected = [ self._make_result_content_for_user(student_group.member_names[0], student_group, submission, points_only=False) ] admin = obj_build.make_admin_user(self.course) self.client.force_authenticate(admin) query_params = {'full_results': 'true'} url = f'{self.base_url}?{urlencode(query_params)}' response = self.client.get(url) self.assertEqual(status.HTTP_200_OK, response.status_code) self.assertSequenceEqual(expected, response.data['results'])
def test_get_results_group_has_extension_ultimate_submission_is_null(self): student_group, student_submission = self._make_group_with_submissions( 2, extended_due_date=timezone.now() + datetime.timedelta(days=1)) expected = [ self._make_result_content_for_user(student_group.member_names[0], student_group, None, points_only=True), self._make_result_content_for_user(student_group.member_names[1], student_group, None, points_only=True), ] 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(expected, response.data['results'])
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_user_can_copy_course_and_is_admin_view_calls_copy_course(self): user = obj_build.make_admin_user(self.course) user.user_permissions.add( Permission.objects.get(codename='create_course')) dummy_course = obj_build.make_course() mock_copy_course = mock.Mock(return_value=dummy_course) with mock.patch( 'autograder.rest_api.views.course_views.course_views.copy_course', new=mock_copy_course): self.client.force_authenticate(user) response = self.client.post( reverse('copy-course', kwargs={'course_pk': self.course.pk}), { 'new_name': 'Cloney', 'new_semester': ag_models.Semester.spring.value, 'new_year': 2021 }) mock_copy_course.assert_called_once_with( course=self.course, new_course_name='Cloney', new_course_semester=ag_models.Semester.spring, new_course_year=2021)
def test_invalid_create_invitation_missing_invited_usernames(self): self.project.validate_and_update(max_group_size=3) other_admin = obj_build.make_admin_user(self.course) self.do_invalid_create_object_test( self.project.group_invitations, self.client, self.admin, self.get_invitations_url(self.project), {})
def test_edit_project_invalid_settings(self): request_data = {'min_group_size': 2, 'max_group_size': 1} admin = obj_build.make_admin_user(self.course) self.do_patch_object_invalid_args_test(self.project, self.client, admin, self.url, request_data)
def test_admin_list_projects(self): admin = obj_build.make_admin_user(self.course) self.do_valid_list_projects_test(admin, self.all_projects, show_closing_time=True, show_instructor_files=True)
def test_admin_get_project(self): self.assertFalse(self.project.visible_to_students) admin = obj_build.make_admin_user(self.course) self.do_get_object_test(self.client, admin, self.url, self.project.to_dict())