def test_not_found_across_course(self): # This ensure course is filtered another_participation = factories.ParticipationFactory( course=factories.CourseFactory(identifier="another-course")) with self.assertRaises(grades.ParticipantNotFound): grades.find_participant_from_id(self.course, another_participation.user.email)
def setUp(self): super(RunCourseUpdateCommandTest, self).setUp() self.course = factories.CourseFactory( active_git_commit_sha=self.default_old_sha) user = factories.UserFactory() instructor_role = factories.ParticipationRoleFactory( course=self.course, identifier="instructor" ) self.participation = factories.ParticipationFactory( course=self.course, preview_git_commit_sha=None, user=user) self.participation.roles.set([instructor_role]) self.request = mock.MagicMock() self.request.user = user self.pctx = mock.MagicMock() self.pctx.course = self.course self.pctx.participation = self.participation self.repo = mock.MagicMock() self.content_repo = self.repo fake_get_dulwich_client_and_remote_path_from_course = mock.patch( "course.versioning.get_dulwich_client_and_remote_path_from_course") self.mock_get_dulwich_client_and_remote_path_from_course = ( fake_get_dulwich_client_and_remote_path_from_course.start() ) self.mock_client = mock.MagicMock() remote_path = "/remote/path" self.mock_get_dulwich_client_and_remote_path_from_course.return_value = ( self.mock_client, remote_path ) self.mock_client.fetch.return_value = { b"HEAD": self.default_switch_to_sha.encode()} self.addCleanup(fake_get_dulwich_client_and_remote_path_from_course.stop) fake_transfer_remote_refs = mock.patch( "course.versioning.transfer_remote_refs") self.mock_transfer_remote_refs = fake_transfer_remote_refs.start() self.addCleanup(fake_transfer_remote_refs.stop) fake_is_parent_commit = mock.patch("course.versioning.is_parent_commit") self.mock_is_parent_commit = fake_is_parent_commit.start() self.mock_is_parent_commit.return_value = False self.addCleanup(fake_is_parent_commit.stop) fake_validate_course_content = mock.patch( "course.validation.validate_course_content") self.mock_validate_course_content = fake_validate_course_content.start() self.mock_validate_course_content.return_value = [] self.addCleanup(fake_validate_course_content.stop)
def test_unicode(self): course2 = factories.CourseFactory(identifier="another-course") user = factories.UserFactory() participation1 = factories.ParticipationFactory(course=self.course, user=user) participation2 = factories.ParticipationFactory(course=course2, user=user) self.assertNotEqual(str(participation1), str(participation2))
def test_participation_not_match(self): another_exam = factories.ExamFactory(course=factories.CourseFactory( identifier="another-course")) resp = self.post_issue_exam_ticket_view(data=self.get_post_data( exam=another_exam.pk)) self.assertFormErrorLoose(resp, None) self.assertEqual(resp.status_code, 200) self.assertEqual(ExamTicket.objects.count(), 0) self.assertAddMessageCallCount(1) self.assertAddMessageCalledWith("User is not enrolled in course.")
def test_not_found_across_course(self): # This ensure course is filtered another_participation = factories.ParticipationFactory( course=factories.CourseFactory(identifier="another-course")) with self.assertRaises(grades.ParticipantNotFound) as cm: grades.find_participant_from_user_attr( self.course, "username", another_participation.user.username) expected_error_msg = ("no participant found with username '%s'" % another_participation.user.username) self.assertIn(expected_error_msg, str(cm.exception))
def create_flow_page_visit(self, course, n_participations_per_course=5, n_sessions_per_participation=1, n_null_answer_visits_per_session=5, n_non_null_answer_visits_per_session=3): """ :param course::class:`Course` :param n_participations_per_course: number of participation created for each course :param n_sessions_per_participation: number of session created for each participation :param n_null_answer_visits_per_session: number of flowpagevisit, which does not have an answer, created for each session :param n_non_null_answer_visits_per_session: number of flowpagevisit, which has an answer, created for each session :return::class:`Tuple`: number of all flow_page_visits, number of null answer flow_page_visits, and number of non-null answer flow_page_visits. """ my_course = factories.CourseFactory(identifier=course.identifier) participations = factories.ParticipationFactory.create_batch( size=n_participations_per_course, course=my_course) for participation in participations: flow_sessions = factories.FlowSessionFactory.create_batch( size=n_sessions_per_participation, participation=participation) for flow_session in flow_sessions: null_anaswer_fpds = factories.FlowPageDataFactory.create_batch( size=n_null_answer_visits_per_session, flow_session=flow_session ) for fpd in null_anaswer_fpds: factories.FlowPageVisitFactory.create(page_data=fpd) non_null_anaswer_fpds = factories.FlowPageDataFactory.create_batch( size=n_non_null_answer_visits_per_session, flow_session=flow_session ) for fpd in non_null_anaswer_fpds: factories.FlowPageVisitFactory.create( page_data=fpd, answer={"answer": "abcd"}) n_null_answer_fpv = ( n_participations_per_course * n_sessions_per_participation * n_null_answer_visits_per_session) n_non_null_answer_fpv = ( n_participations_per_course * n_sessions_per_participation * n_non_null_answer_visits_per_session) n_all_fpv = n_null_answer_fpv + n_non_null_answer_fpv return n_all_fpv, n_null_answer_fpv, n_non_null_answer_fpv
def test_clean_fail(self): course2 = factories.CourseFactory(identifier="another-course") opportunity3 = factories.GradingOpportunityFactory(course=course2, identifier="gopp3") gc = factories.GradeChangeFactory(opportunity=opportunity3, participation=self.participation) with self.assertRaises(ValidationError) as cm: gc.clean() expected_error_msg = ("Participation and opportunity must live " "in the same course") self.assertIn(expected_error_msg, str(cm.exception))
def test_fail_course_not_matched(self): another_course = factories.CourseFactory(identifier="another-course") another_course_fs = factories.FlowSessionFactory( participation=factories.ParticipationFactory( course=another_course)) token = self.create_token() resp = self.c.get(self.get_get_flow_session_content_url( flow_session_id=another_course_fs.id), HTTP_AUTHORIZATION="Token %i_%s" % (token.id, self.default_token_hash_str)) self.assertEqual(resp.status_code, 403)
def test_clean_failure(self): course2 = factories.CourseFactory(identifier="another-course") participation3 = factories.ParticipationFactory(course=course2, user=self.user2) et2 = models.ExamTicket(exam=self.exam, participation=participation3, code="cdef") with self.assertRaises(ValidationError) as cm: et2.clean() expected_error_msg = ("Participation and exam must live " "in the same course") self.assertIn(expected_error_msg, str(cm.exception))
def test_flow_session_course_not_matching(self): another_course = factories.CourseFactory(identifier="another-course") some_user = factories.UserFactory() his_participation = factories.ParticipationFactory( course=another_course, user=some_user) his_flow_session = factories.FlowSessionFactory( course=another_course, participation=his_participation) url = self.get_page_grading_url_by_ordinal( page_ordinal=1, course_identifier=self.course.identifier, flow_session_id=his_flow_session.pk) with self.temporarily_switch_to_user( self.instructor_participation.user): resp = self.c.get(url) self.assertEqual(resp.status_code, 400)
def test_get_role_desc(self): course2 = factories.CourseFactory(identifier="another-course") user = factories.UserFactory() participation1 = factories.ParticipationFactory(course=self.course, user=user) participation2 = factories.ParticipationFactory(course=course2, user=user) self.assertIsInstance(participation1.get_role_desc(), six.text_type) self.assertEqual(participation1.get_role_desc(), participation2.get_role_desc()) instructor_role = factories.ParticipationRoleFactory( course=self.course, identifier="instructor") participation2.roles.set([instructor_role]) self.assertNotEqual(participation1.get_role_desc(), participation2.get_role_desc())
def test_add_default_roles_and_permissions(self): # make sure add_default_roles_and_permissions is called after # a course is created, and not called when updated. with mock.patch("course.models.add_default_roles_and_permissions" ) as mock_add_default_roles_and_permissions: new_course = factories.CourseFactory( identifier="yet-another-course") self.assertEqual(mock_add_default_roles_and_permissions.call_count, 1) self.assertIn(new_course, mock_add_default_roles_and_permissions.call_args[0]) mock_add_default_roles_and_permissions.reset_mock() new_course.is_hidden = False new_course.save() self.assertEqual(mock_add_default_roles_and_permissions.call_count, 0)
def create_flow_page_visit_grade(cls, course=None, n_participations_per_course=1, n_sessions_per_participation=1, n_non_null_answer_visits_per_session=3): if course is None: course = factories.CourseFactory(identifier=course.identifier) participations = factories.ParticipationFactory.create_batch( size=n_participations_per_course, course=course) grader1 = factories.UserFactory() grader2 = factories.UserFactory() graders = [grader1, grader2] visit_time = now() - timedelta(days=1) for participation in participations: flow_sessions = factories.FlowSessionFactory.create_batch( size=n_sessions_per_participation, participation=participation) for flow_session in flow_sessions: non_null_anaswer_fpds = factories.FlowPageDataFactory.create_batch( size=n_non_null_answer_visits_per_session, flow_session=flow_session) for fpd in non_null_anaswer_fpds: visit_time = visit_time + timedelta(seconds=10) factories.FlowPageVisitFactory.create( visit_time=visit_time, page_data=fpd, answer={"answer": "abcd"}) shuffle(graders) grade_time = visit_time + timedelta(seconds=10) factories.FlowPageVisitGradeFactory.create( grader=graders[0], grade_time=grade_time) n_non_null_answer_fpv = (n_participations_per_course * n_sessions_per_participation * n_non_null_answer_visits_per_session) #print(n_non_null_answer_fpv) return n_non_null_answer_fpv
def test_available_kind_choices(self): factories.EventFactory( course=self.course, kind="some_kind1", ordinal=None) factories.EventFactory( course=self.course, kind="some_kind2", ordinal=1) another_course = factories.CourseFactory(identifier="another-course") factories.EventFactory( course=another_course, kind="some_kind3", ordinal=1) factories.EventFactory( course=another_course, kind="some_kind4", ordinal=1) form = calendar.RecurringEventForm(self.course.identifier) self.assertIn( '<option value="some_kind1">some_kind1</option>', form.as_p()) self.assertIn( '<option value="some_kind2">some_kind2</option>', form.as_p()) self.assertNotIn( '<option value="some_kind3">some_kind3</option>', form.as_p()) self.assertNotIn( '<option value="some_kind4">some_kind4</option>', form.as_p())
def test_result(self): flow_ids = ["c", "b", "a"] for flow_id in flow_ids: factories.FlowSessionFactory.create_batch( size=2, participation=self.student_participation, flow_id=flow_id) another_course = factories.CourseFactory(identifier="another-course") another_participation = factories.ParticipationFactory( course=another_course) # This make sure other courses' flow_id won't be included factories.FlowSessionFactory(participation=another_participation, flow_id="d") resp = self.get_flow_list_view() self.assertEqual(resp.status_code, 200) self.assertResponseContextEqual(resp, "flow_ids", sorted(flow_ids))
def setUp(self): self.repo = mock.MagicMock() self.course = factories.CourseFactory() fake_get_yaml_from_repo_safely = mock.patch( "course.validation.get_yaml_from_repo_safely") self.mock_get_yaml_from_repo_safely = fake_get_yaml_from_repo_safely.start( ) self.mock_get_yaml_from_repo_safely.side_effect = ( get_yaml_from_repo_safely_side_effect) self.addCleanup(fake_get_yaml_from_repo_safely.stop) fake_validate_staticpage_desc = mock.patch( "course.validation.validate_staticpage_desc") self.mock_validate_staticpage_desc = fake_validate_staticpage_desc.start( ) self.addCleanup(fake_validate_staticpage_desc.stop) fake_get_yaml_from_repo = mock.patch( "course.content.get_yaml_from_repo") self.mock_get_yaml_from_repo = fake_get_yaml_from_repo.start() self.mock_get_yaml_from_repo.side_effect = get_yaml_from_repo_side_effect self.addCleanup(fake_get_yaml_from_repo.stop) fake_validate_calendar_desc_struct = mock.patch( "course.validation.validate_calendar_desc_struct") self.mock_validate_calendar_desc_struct = ( fake_validate_calendar_desc_struct.start()) self.addCleanup(fake_validate_calendar_desc_struct.stop) fake_check_attributes_yml = ( mock.patch("course.validation.check_attributes_yml")) self.mock_check_attributes_yml = fake_check_attributes_yml.start() self.addCleanup(fake_check_attributes_yml.stop) fake_validate_flow_id = ( mock.patch("course.validation.validate_flow_id")) self.mock_validate_flow_id = fake_validate_flow_id.start() self.addCleanup(fake_validate_flow_id.stop) fake_validate_flow_desc = ( mock.patch("course.validation.validate_flow_desc")) self.mock_validate_flow_desc = fake_validate_flow_desc.start() self.addCleanup(fake_validate_flow_desc.stop) fake_check_for_page_type_changes = ( mock.patch("course.validation.check_for_page_type_changes")) self.mock_check_for_page_type_changes = ( fake_check_for_page_type_changes.start()) self.addCleanup(fake_check_for_page_type_changes.stop) fake_check_grade_identifier_link = ( mock.patch("course.validation.check_grade_identifier_link")) self.mock_check_grade_identifier_link = ( fake_check_grade_identifier_link.start()) self.addCleanup(fake_check_grade_identifier_link.stop) fake_get_repo_blob = (mock.patch("course.validation.get_repo_blob")) self.mock_get_repo_blob = fake_get_repo_blob.start() self.mock_get_repo_blob.side_effect = get_repo_blob_side_effect self.addCleanup(fake_get_repo_blob.stop) fake_validate_static_page_name = ( mock.patch("course.validation.validate_static_page_name")) self.mock_validate_static_page_name = fake_validate_static_page_name.start( ) self.addCleanup(fake_validate_static_page_name.stop) fake_vctx_add_warning = ( mock.patch("course.validation.ValidationContext.add_warning")) self.mock_vctx_add_warning = fake_vctx_add_warning.start() self.addCleanup(fake_vctx_add_warning.stop)
def test_course_not_none_check_attributes_yml(self): # This test check_attributes_yml args access_type # is generated with course-specific pperm.access_files_for user = factories.UserFactory() # {{{ create another course with different set of participation role # permission and participation permission another_course = factories.CourseFactory(identifier="another-course") another_course_prole = ParticipationRole( course=another_course, identifier="another_course_role", name="another_course_role") another_course_prole.save() another_course_participation = factories.ParticipationFactory( course=another_course, user=user) another_course_participation.roles.set([another_course_prole]) another_course_ppm_access_files_for_roles = "another_role" ParticipationPermission( participation=another_course_participation, permission=pperm.access_files_for, argument=another_course_ppm_access_files_for_roles).save() another_course_rpm_access_files_for_roles = "another_course_everyone" ParticipationRolePermission( role=another_course_prole, permission=pperm.access_files_for, argument=another_course_rpm_access_files_for_roles).save() self.assertTrue( another_course_participation.has_permission( pperm.access_files_for, argument=another_course_ppm_access_files_for_roles)) self.assertTrue( another_course_participation.has_permission( pperm.access_files_for, argument=another_course_rpm_access_files_for_roles)) # }}} # {{{ create for default test course extra participation role # permission and participation permission this_course_prole = ParticipationRole(course=self.course, identifier="another_course_role", name="another_course_role") this_course_prole.save() this_course_participation = factories.ParticipationFactory( course=self.course, user=user) this_course_participation.roles.set([this_course_prole]) this_course_ppm_access_files_for_roles = "this_course_some_role" ParticipationPermission( participation=this_course_participation, permission=pperm.access_files_for, argument=this_course_ppm_access_files_for_roles).save() this_course_rpm_access_files_for_roles = "this_course_everyone" ParticipationRolePermission( role=this_course_prole, permission=pperm.access_files_for, argument=this_course_rpm_access_files_for_roles).save() self.assertTrue( this_course_participation.has_permission( pperm.access_files_for, argument=this_course_ppm_access_files_for_roles)) self.assertTrue( this_course_participation.has_permission( pperm.access_files_for, argument=this_course_rpm_access_files_for_roles)) # }}} validation.validate_course_content(self.repo, course_file, events_file, validate_sha, course=self.course) self.assertEqual(self.mock_vctx_add_warning.call_count, 0) # check_attributes_yml is called self.assertEqual(self.mock_check_attributes_yml.call_count, 1) access_kinds = list(self.mock_check_attributes_yml.call_args[0][-1]) self.assertIn(this_course_ppm_access_files_for_roles, access_kinds) self.assertIn(this_course_rpm_access_files_for_roles, access_kinds) self.assertNotIn(another_course_ppm_access_files_for_roles, access_kinds) self.assertNotIn(another_course_rpm_access_files_for_roles, access_kinds)
def setUpTestData(cls): # noqa super(FindParticipantFromUserAttrTest, cls).setUpTestData() cls.course = factories.CourseFactory() cls.student_participation = factories.ParticipationFactory( course=cls.course)
def setUp(self): self.course1 = factories.CourseFactory() self.course2 = factories.CourseFactory(identifier="another-course")
def setUp(self): self.course = factories.CourseFactory()