def setUp(self): super(TeamAPITestCase, self).setUp() self.topics_count = 4 self.users = { "student_unenrolled": UserFactory.create(password=self.test_password), "student_enrolled": UserFactory.create(password=self.test_password), "student_enrolled_not_on_team": UserFactory.create(password=self.test_password), # This student is enrolled in both test courses and is a member of a team in each course, but is not on the # same team as student_enrolled. "student_enrolled_both_courses_other_team": UserFactory.create(password=self.test_password), "staff": AdminFactory.create(password=self.test_password), "course_staff": StaffFactory.create(course_key=self.test_course_1.id, password=self.test_password), } # 'solar team' is intentionally lower case to test case insensitivity in name ordering self.test_team_1 = CourseTeamFactory.create( name=u"sólar team", course_id=self.test_course_1.id, topic_id="topic_0" ) self.test_team_2 = CourseTeamFactory.create(name="Wind Team", course_id=self.test_course_1.id) self.test_team_3 = CourseTeamFactory.create(name="Nuclear Team", course_id=self.test_course_1.id) self.test_team_4 = CourseTeamFactory.create(name="Coal Team", course_id=self.test_course_1.id, is_active=False) self.test_team_5 = CourseTeamFactory.create(name="Another Team", course_id=self.test_course_2.id) for user, course in [ ("student_enrolled", self.test_course_1), ("student_enrolled_not_on_team", self.test_course_1), ("student_enrolled_both_courses_other_team", self.test_course_1), ("student_enrolled_both_courses_other_team", self.test_course_2), ]: CourseEnrollment.enroll(self.users[user], course.id, check_access=True) self.test_team_1.add_user(self.users["student_enrolled"]) self.test_team_3.add_user(self.users["student_enrolled_both_courses_other_team"]) self.test_team_5.add_user(self.users["student_enrolled_both_courses_other_team"])
def test_access_on_course_with_pre_requisites(self): """ Test course access when a course has pre-requisite course yet to be completed """ seed_milestone_relationship_types() user = UserFactory.create() pre_requisite_course = CourseFactory.create(org="test_org", number="788", run="test_run") pre_requisite_courses = [unicode(pre_requisite_course.id)] course = CourseFactory.create( org="test_org", number="786", run="test_run", pre_requisite_courses=pre_requisite_courses ) set_prerequisite_courses(course.id, pre_requisite_courses) # user should not be able to load course even if enrolled CourseEnrollmentFactory(user=user, course_id=course.id) response = access._has_access_course_desc(user, "view_courseware_with_prerequisites", course) self.assertFalse(response) self.assertIsInstance(response, access_response.MilestoneError) # Staff can always access course staff = StaffFactory.create(course_key=course.id) self.assertTrue(access._has_access_course_desc(staff, "view_courseware_with_prerequisites", course)) # User should be able access after completing required course fulfill_course_milestone(pre_requisite_course.id, user) self.assertTrue(access._has_access_course_desc(user, "view_courseware_with_prerequisites", course))
def test_access_on_course_with_pre_requisites(self): """ Test course access when a course has pre-requisite course yet to be completed """ user = UserFactory.create() pre_requisite_course = CourseFactory.create( org='test_org', number='788', run='test_run' ) pre_requisite_courses = [unicode(pre_requisite_course.id)] course = CourseFactory.create( org='test_org', number='786', run='test_run', pre_requisite_courses=pre_requisite_courses ) set_prerequisite_courses(course.id, pre_requisite_courses) # user should not be able to load course even if enrolled CourseEnrollmentFactory(user=user, course_id=course.id) response = access._has_access_course(user, 'load', course) self.assertFalse(response) self.assertIsInstance(response, access_response.MilestoneAccessError) # Staff can always access course staff = StaffFactory.create(course_key=course.id) self.assertTrue(access._has_access_course(staff, 'load', course)) # User should be able access after completing required course fulfill_course_milestone(pre_requisite_course.id, user) self.assertTrue(access._has_access_course(user, 'load', course))
def test__catalog_visibility(self): """ Tests the catalog visibility tri-states """ user = UserFactory.create() course_id = SlashSeparatedCourseKey("edX", "test", "2012_Fall") staff = StaffFactory.create(course_key=course_id) course = Mock(id=course_id, catalog_visibility=CATALOG_VISIBILITY_CATALOG_AND_ABOUT) self.assertTrue(access._has_access_course_desc(user, "see_in_catalog", course)) self.assertTrue(access._has_access_course_desc(user, "see_about_page", course)) self.assertTrue(access._has_access_course_desc(staff, "see_in_catalog", course)) self.assertTrue(access._has_access_course_desc(staff, "see_about_page", course)) # Now set visibility to just about page course = Mock( id=SlashSeparatedCourseKey("edX", "test", "2012_Fall"), catalog_visibility=CATALOG_VISIBILITY_ABOUT ) self.assertFalse(access._has_access_course_desc(user, "see_in_catalog", course)) self.assertTrue(access._has_access_course_desc(user, "see_about_page", course)) self.assertTrue(access._has_access_course_desc(staff, "see_in_catalog", course)) self.assertTrue(access._has_access_course_desc(staff, "see_about_page", course)) # Now set visibility to none, which means neither in catalog nor about pages course = Mock( id=SlashSeparatedCourseKey("edX", "test", "2012_Fall"), catalog_visibility=CATALOG_VISIBILITY_NONE ) self.assertFalse(access._has_access_course_desc(user, "see_in_catalog", course)) self.assertFalse(access._has_access_course_desc(user, "see_about_page", course)) self.assertTrue(access._has_access_course_desc(staff, "see_in_catalog", course)) self.assertTrue(access._has_access_course_desc(staff, "see_about_page", course))
def test_entrance_exam_gating_for_staff(self): """ Tests gating is disabled if user is member of staff. """ # Login as member of staff self.client.logout() staff_user = StaffFactory(course_key=self.course.id) staff_user.is_staff = True self.client.login(username=staff_user.username, password='******') # assert staff has access to all toc self.request.user = staff_user unlocked_toc = self._return_table_of_contents() for toc_section in self.expected_unlocked_toc: self.assertIn(toc_section, unlocked_toc)
def setUp(self): super(TeamAPITestCase, self).setUp() teams_configuration = { 'topics': [ { 'id': 'topic_{}'.format(i), 'name': name, 'description': 'Description for topic {}.'.format(i) } for i, name in enumerate([u'sólar power', 'Wind Power', 'Nuclear Power', 'Coal Power']) ] } self.topics_count = 4 self.test_course_1 = CourseFactory.create( org='TestX', course='TS101', display_name='Test Course', teams_configuration=teams_configuration ) self.test_course_2 = CourseFactory.create(org='MIT', course='6.002x', display_name='Circuits') self.users = { 'student_unenrolled': UserFactory.create(password=self.test_password), 'student_enrolled': UserFactory.create(password=self.test_password), 'student_enrolled_not_on_team': UserFactory.create(password=self.test_password), # This student is enrolled in both test courses and is a member of a team in each course, but is not on the # same team as student_enrolled. 'student_enrolled_both_courses_other_team': UserFactory.create(password=self.test_password), 'staff': AdminFactory.create(password=self.test_password), 'course_staff': StaffFactory.create(course_key=self.test_course_1.id, password=self.test_password) } # 'solar team' is intentionally lower case to test case insensitivity in name ordering self.test_team_1 = CourseTeamFactory.create( name=u'sólar team', course_id=self.test_course_1.id, topic_id='topic_0' ) self.test_team_2 = CourseTeamFactory.create(name='Wind Team', course_id=self.test_course_1.id) self.test_team_3 = CourseTeamFactory.create(name='Nuclear Team', course_id=self.test_course_1.id) self.test_team_4 = CourseTeamFactory.create(name='Coal Team', course_id=self.test_course_1.id, is_active=False) self.test_team_5 = CourseTeamFactory.create(name='Another Team', course_id=self.test_course_2.id) for user, course in [ ('student_enrolled', self.test_course_1), ('student_enrolled_not_on_team', self.test_course_1), ('student_enrolled_both_courses_other_team', self.test_course_1), ('student_enrolled_both_courses_other_team', self.test_course_2) ]: CourseEnrollment.enroll( self.users[user], course.id, check_access=True ) self.test_team_1.add_user(self.users['student_enrolled']) self.test_team_3.add_user(self.users['student_enrolled_both_courses_other_team']) self.test_team_5.add_user(self.users['student_enrolled_both_courses_other_team'])
def test_courseware_page_access_with_staff_user_after_passing_entrance_exam(self): """ Test courseware access page after passing entrance exam but with staff user """ self.logout() staff_user = StaffFactory.create(course_key=self.course.id) self.login(staff_user.email, 'test') CourseEnrollmentFactory(user=staff_user, course_id=self.course.id) self._assert_chapter_loaded(self.course, self.chapter)
def test__has_access_course_desc_can_enroll(self): yesterday = datetime.datetime.now(pytz.utc) - datetime.timedelta(days=1) tomorrow = datetime.datetime.now(pytz.utc) + datetime.timedelta(days=1) # Non-staff can enroll if authenticated and specifically allowed for that course # even outside the open enrollment period user = UserFactory.create() course = Mock( enrollment_start=tomorrow, enrollment_end=tomorrow, id=SlashSeparatedCourseKey("edX", "test", "2012_Fall"), enrollment_domain="", ) CourseEnrollmentAllowedFactory(email=user.email, course_id=course.id) self.assertTrue(access._has_access_course_desc(user, "enroll", course)) # Staff can always enroll even outside the open enrollment period user = StaffFactory.create(course_key=course.id) self.assertTrue(access._has_access_course_desc(user, "enroll", course)) # Non-staff cannot enroll if it is between the start and end dates and invitation only # and not specifically allowed course = Mock( enrollment_start=yesterday, enrollment_end=tomorrow, id=SlashSeparatedCourseKey("edX", "test", "2012_Fall"), enrollment_domain="", invitation_only=True, ) user = UserFactory.create() self.assertFalse(access._has_access_course_desc(user, "enroll", course)) # Non-staff can enroll if it is between the start and end dates and not invitation only course = Mock( enrollment_start=yesterday, enrollment_end=tomorrow, id=SlashSeparatedCourseKey("edX", "test", "2012_Fall"), enrollment_domain="", invitation_only=False, ) self.assertTrue(access._has_access_course_desc(user, "enroll", course)) # Non-staff cannot enroll outside the open enrollment period if not specifically allowed course = Mock( enrollment_start=tomorrow, enrollment_end=tomorrow, id=SlashSeparatedCourseKey("edX", "test", "2012_Fall"), enrollment_domain="", invitation_only=False, ) self.assertFalse(access._has_access_course_desc(user, "enroll", course))
def setUp(self): """ Creates a test course ID, mocks the runtime, and creates a fake storage engine for use in all tests """ super(StaffGradedAssignmentXblockTests, self).setUp() self.course = CourseFactory.create(org='foo', number='bar', display_name='baz') self.descriptor = ItemFactory(category="pure", parent=self.course) self.course_id = self.course.id self.instructor = StaffFactory.create(course_key=self.course_id) self.student_data = mock.Mock() self.staff = AdminFactory.create(password="******") self.runtime = self.make_runtime() self.scope_ids = self.make_scope_ids(self.runtime)
def setUp(self): super(TeamAPITestCase, self).setUp() self.topics_count = 4 self.users = { 'staff': AdminFactory.create(password=self.test_password), 'course_staff': StaffFactory.create(course_key=self.test_course_1.id, password=self.test_password) } self.create_and_enroll_student(username='******') self.create_and_enroll_student(username='******') self.create_and_enroll_student(username='******', courses=[]) # Make this student a community TA. self.create_and_enroll_student(username='******') seed_permissions_roles(self.test_course_1.id) community_ta_role = Role.objects.get(name=FORUM_ROLE_COMMUNITY_TA, course_id=self.test_course_1.id) community_ta_role.users.add(self.users['community_ta']) # This student is enrolled in both test courses and is a member of a team in each course, but is not on the # same team as student_enrolled. self.create_and_enroll_student( courses=[self.test_course_1, self.test_course_2], username='******' ) # 'solar team' is intentionally lower case to test case insensitivity in name ordering self.test_team_1 = CourseTeamFactory.create( name=u'sólar team', course_id=self.test_course_1.id, topic_id='topic_0' ) self.test_team_2 = CourseTeamFactory.create(name='Wind Team', course_id=self.test_course_1.id) self.test_team_3 = CourseTeamFactory.create(name='Nuclear Team', course_id=self.test_course_1.id) self.test_team_4 = CourseTeamFactory.create(name='Coal Team', course_id=self.test_course_1.id, is_active=False) self.test_team_5 = CourseTeamFactory.create(name='Another Team', course_id=self.test_course_2.id) for user, course in [ ('staff', self.test_course_1), ('course_staff', self.test_course_1), ]: CourseEnrollment.enroll( self.users[user], course.id, check_access=True ) self.test_team_1.add_user(self.users['student_enrolled']) self.test_team_3.add_user(self.users['student_enrolled_both_courses_other_team']) self.test_team_5.add_user(self.users['student_enrolled_both_courses_other_team'])
def test_runtime_user_is_staff(self, is_staff): course = CourseFactory.create(org='org', number='bar', display_name='baz') descriptor = ItemFactory(category="pure", parent=course) staff = StaffFactory.create(course_key=course.id) self.runtime, _ = render.get_module_system_for_user( staff if is_staff else User.objects.create(), self.student_data, descriptor, course.id, mock.Mock(), mock.Mock(), mock.Mock(), course=course ) block = self.make_one() assert block.runtime_user_is_staff() is is_staff
def test__has_access_course_can_enroll(self): yesterday = datetime.datetime.now( pytz.utc) - datetime.timedelta(days=1) tomorrow = datetime.datetime.now(pytz.utc) + datetime.timedelta(days=1) # Non-staff can enroll if authenticated and specifically allowed for that course # even outside the open enrollment period user = UserFactory.create() course = Mock(enrollment_start=tomorrow, enrollment_end=tomorrow, id=SlashSeparatedCourseKey('edX', 'test', '2012_Fall'), enrollment_domain='') CourseEnrollmentAllowedFactory(email=user.email, course_id=course.id) self.assertTrue(access._has_access_course(user, 'enroll', course)) # Staff can always enroll even outside the open enrollment period user = StaffFactory.create(course_key=course.id) self.assertTrue(access._has_access_course(user, 'enroll', course)) # Non-staff cannot enroll if it is between the start and end dates and invitation only # and not specifically allowed course = Mock(enrollment_start=yesterday, enrollment_end=tomorrow, id=SlashSeparatedCourseKey('edX', 'test', '2012_Fall'), enrollment_domain='', invitation_only=True) user = UserFactory.create() self.assertFalse(access._has_access_course(user, 'enroll', course)) # Non-staff can enroll if it is between the start and end dates and not invitation only course = Mock(enrollment_start=yesterday, enrollment_end=tomorrow, id=SlashSeparatedCourseKey('edX', 'test', '2012_Fall'), enrollment_domain='', invitation_only=False) self.assertTrue(access._has_access_course(user, 'enroll', course)) # Non-staff cannot enroll outside the open enrollment period if not specifically allowed course = Mock(enrollment_start=tomorrow, enrollment_end=tomorrow, id=SlashSeparatedCourseKey('edX', 'test', '2012_Fall'), enrollment_domain='', invitation_only=False) self.assertFalse(access._has_access_course(user, 'enroll', course))
def i_am_staff_or_instructor(step, role): # pylint: disable=unused-argument ## In summary: makes a test course, makes a new Staff or Instructor user ## (depending on `role`), and logs that user in to the course # Store the role assert_in(role, ['instructor', 'staff']) # Clear existing courses to avoid conflicts world.clear_courses() # Create a new course course = world.CourseFactory.create( org='edx', number='999', display_name='Test Course' ) world.course_id = 'edx/999/Test_Course' world.role = 'instructor' # Log in as the an instructor or staff for the course if role == 'instructor': # Make & register an instructor for the course world.instructor = InstructorFactory(course=course.location) world.enroll_user(world.instructor, world.course_id) world.log_in( username=world.instructor.username, password='******', email=world.instructor.email, name=world.instructor.profile.name ) else: world.role = 'staff' # Make & register a staff member world.staff = StaffFactory(course=course.location) world.enroll_user(world.staff, world.course_id) world.log_in( username=world.staff.username, password='******', email=world.staff.email, name=world.staff.profile.name )
def test_save_completion_staff_ended(self, store): """ Save a CourseModuleCompletion with the feature flag on a course that has not yet started but Staff should be able to write """ self._create_course(store=store, end=datetime(1999, 1, 1, tzinfo=UTC())) self.user = StaffFactory(course_key=self.course.id) module = self.get_module_for_user(self.user, self.course, self.problem4) module.system.publish(module, 'progress', {}) with self.assertRaises(CourseModuleCompletion.DoesNotExist): CourseModuleCompletion.objects.get( user=self.user.id, course_id=self.course.id, content_id=self.problem4.location)
def create_user_for_course(self, course, user_type=CourseUserType.ENROLLED): """ Create a test user for a course. """ if user_type is CourseUserType.ANONYMOUS: return AnonymousUser() is_enrolled = user_type is CourseUserType.ENROLLED is_unenrolled_staff = user_type is CourseUserType.UNENROLLED_STAFF # Set up the test user if is_unenrolled_staff: user = StaffFactory(course_key=course.id, password=self.TEST_PASSWORD) else: user = UserFactory(password=self.TEST_PASSWORD) self.client.login(username=user.username, password=self.TEST_PASSWORD) if is_enrolled: CourseEnrollment.enroll(user, course.id) return user
def make_populated_course(step): # pylint: disable=unused-argument ## This is different than the function defined in common.py because it enrolls ## a staff, instructor, and student member regardless of what `role` is, then ## logs `role` in. This is to ensure we have 3 class participants to email. # Clear existing courses to avoid conflicts world.clear_courses() # Create a new course course = world.CourseFactory.create(org='edx', number='888', display_name='Bulk Email Test Course') world.bulk_email_course_key = course.id try: # See if we've defined the instructor & staff user yet world.bulk_email_instructor except AttributeError: # Make & register an instructor for the course world.bulk_email_instructor = InstructorFactory( course_key=world.bulk_email_course_key) world.enroll_user(world.bulk_email_instructor, world.bulk_email_course_key) # Make & register a staff member world.bulk_email_staff = StaffFactory(course_key=course.id) world.enroll_user(world.bulk_email_staff, world.bulk_email_course_key) # Make & register a student world.register_by_course_key(course.id, username='******', password='******', is_staff=False) # Store the expected recipients # given each "send to" option staff_emails = [ world.bulk_email_staff.email, world.bulk_email_instructor.email ] world.expected_addresses = { 'course staff': staff_emails, 'students, staff, and instructors': staff_emails + ['*****@*****.**'] }
def test_preview(self): """ Verify the behavior of preview for the course outline. """ course = CourseFactory.create(start=datetime.datetime.now() - datetime.timedelta(days=30)) staff_user = StaffFactory(course_key=course.id, password=TEST_PASSWORD) CourseEnrollment.enroll(staff_user, course.id) future_date = datetime.datetime.now() + datetime.timedelta(days=30) with self.store.bulk_operations(course.id): chapter = ItemFactory.create( category='chapter', parent_location=course.location, display_name='First Chapter', ) sequential = ItemFactory.create(category='sequential', parent_location=chapter.location) ItemFactory.create(category='vertical', parent_location=sequential.location) chapter = ItemFactory.create( category='chapter', parent_location=course.location, display_name='Future Chapter', start=future_date, ) sequential = ItemFactory.create(category='sequential', parent_location=chapter.location) ItemFactory.create(category='vertical', parent_location=sequential.location) # Verify that a staff user sees a chapter with a due date in the future self.client.login(username=staff_user.username, password='******') url = course_home_url(course) response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertContains(response, 'Future Chapter') # Verify that staff masquerading as a learner does not see the future chapter. self.update_masquerade(course, role='student') response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertNotContains(response, 'Future Chapter')
def setUp(self): super(TestInlineAnalytics, self).setUp() self.user = UserFactory.create() self.request = RequestFactory().get('/') self.request.user = self.user self.request.session = {} self.course = CourseFactory.create( org='A', number='B', display_name='C', ) self.staff = StaffFactory(course_key=self.course.id) self.instructor = InstructorFactory(course_key=self.course.id) self.problem_xml = OptionResponseXMLFactory().build_xml( question_text='The correct answer is Correct', num_inputs=2, weight=2, options=['Correct', 'Incorrect'], correct_option='Correct', ) self.descriptor = ItemFactory.create( category='problem', data=self.problem_xml, display_name='Option Response Problem', rerandomize='never', ) self.location = self.descriptor.location self.field_data_cache = FieldDataCache.cache_for_descriptor_descendents( self.course.id, self.user, self.descriptor, ) self.field_data_cache_staff = FieldDataCache.cache_for_descriptor_descendents( self.course.id, self.staff, self.descriptor, ) self.field_data_cache_instructor = FieldDataCache.cache_for_descriptor_descendents( self.course.id, self.instructor, self.descriptor, )
def test__catalog_visibility(self): """ Tests the catalog visibility tri-states """ user = UserFactory.create() course_id = SlashSeparatedCourseKey('edX', 'test', '2012_Fall') staff = StaffFactory.create(course_key=course_id) course = Mock(id=course_id, catalog_visibility=CATALOG_VISIBILITY_CATALOG_AND_ABOUT) self.assertTrue( access._has_access_course_desc(user, 'see_in_catalog', course)) self.assertTrue( access._has_access_course_desc(user, 'see_about_page', course)) self.assertTrue( access._has_access_course_desc(staff, 'see_in_catalog', course)) self.assertTrue( access._has_access_course_desc(staff, 'see_about_page', course)) # Now set visibility to just about page course = Mock(id=SlashSeparatedCourseKey('edX', 'test', '2012_Fall'), catalog_visibility=CATALOG_VISIBILITY_ABOUT) self.assertFalse( access._has_access_course_desc(user, 'see_in_catalog', course)) self.assertTrue( access._has_access_course_desc(user, 'see_about_page', course)) self.assertTrue( access._has_access_course_desc(staff, 'see_in_catalog', course)) self.assertTrue( access._has_access_course_desc(staff, 'see_about_page', course)) # Now set visibility to none, which means neither in catalog nor about pages course = Mock(id=SlashSeparatedCourseKey('edX', 'test', '2012_Fall'), catalog_visibility=CATALOG_VISIBILITY_NONE) self.assertFalse( access._has_access_course_desc(user, 'see_in_catalog', course)) self.assertFalse( access._has_access_course_desc(user, 'see_about_page', course)) self.assertTrue( access._has_access_course_desc(staff, 'see_in_catalog', course)) self.assertTrue( access._has_access_course_desc(staff, 'see_about_page', course))
def setUp(self): super(TestWikiAccessForOldFormatCourseStaffGroups, self).setUp() self.course_math101c = CourseFactory.create(org='org', number='math101c', display_name='Course') Group.objects.get_or_create(name='instructor_math101c') self.course_math101c_staff = [ InstructorFactory(course=self.course_math101c.location), StaffFactory(course=self.course_math101c.location) ] wiki_math101c = self.create_urlpath( self.wiki, course_wiki_slug(self.course_math101c)) wiki_math101c_page = self.create_urlpath(wiki_math101c, 'Child') wiki_math101c_page_page = self.create_urlpath(wiki_math101c_page, 'Grandchild') self.wiki_math101c_pages = [ wiki_math101c, wiki_math101c_page, wiki_math101c_page_page ]
def setUp(self): self.wiki = get_or_create_root() self.course_math101 = CourseFactory.create(org='org', number='math101', display_name='Course') self.course_math101_staff = [ InstructorFactory(course=self.course_math101.location), StaffFactory(course=self.course_math101.location) ] wiki_math101 = self.create_urlpath( self.wiki, course_wiki_slug(self.course_math101)) wiki_math101_page = self.create_urlpath(wiki_math101, 'Child') wiki_math101_page_page = self.create_urlpath(wiki_math101_page, 'Grandchild') self.wiki_math101_pages = [ wiki_math101, wiki_math101_page, wiki_math101_page_page ]
def setUp(self): super(EmailSendFromDashboardTestCase, self).setUp() course_title = u"ẗëṡẗ title イ乇丂イ ᄊ乇丂丂ムg乇 キo尺 ムレレ тэѕт мэѕѕаБэ" self.course = CourseFactory.create(display_name=course_title) self.instructor = InstructorFactory(course_key=self.course.id) # Create staff self.staff = [ StaffFactory(course_key=self.course.id) for _ in xrange(STAFF_COUNT) ] # Create students self.students = [UserFactory() for _ in xrange(STUDENT_COUNT)] for student in self.students: CourseEnrollmentFactory.create(user=student, course_id=self.course.id) # load initial content (since we don't run migrations as part of tests): call_command("loaddata", "course_email_template.json") self.client.login(username=self.instructor.username, password="******") # Pull up email view on instructor dashboard self.url = reverse( 'instructor_dashboard', kwargs={'course_id': self.course.id.to_deprecated_string()}) # Response loads the whole instructor dashboard, so no need to explicitly # navigate to a particular email section response = self.client.get(self.url) email_section = '<div class="vert-left send-email" id="section-send-email">' # If this fails, it is likely because ENABLE_INSTRUCTOR_EMAIL is set to False self.assertTrue(email_section in response.content) self.send_mail_url = reverse( 'send_email', kwargs={'course_id': self.course.id.to_deprecated_string()}) self.success_content = { 'course_id': self.course.id.to_deprecated_string(), 'success': True, }
def test_entrance_exam_requirement_message_hidden(self): """ Unit Test: entrance exam message should not be present outside the context of entrance exam subsection. """ # Login as staff to avoid redirect to entrance exam self.client.logout() staff_user = StaffFactory(course_key=self.course.id) self.client.login(username=staff_user.username, password='******') CourseEnrollment.enroll(staff_user, self.course.id) url = reverse('courseware_section', kwargs={ 'course_id': unicode(self.course.id), 'chapter': self.chapter.location.name, 'section': self.chapter_subsection.location.name }) resp = self.client.get(url) self.assertEqual(resp.status_code, 200) self.assertNotIn('To access course materials, you must score', resp.content) self.assertNotIn('You have passed the entrance exam.', resp.content)
def test_student_admin_staff_instructor(self): """ Verify that staff users are not able to see course-wide options, while still seeing individual learner options. """ # Original (instructor) user can see both specific grades, and course-wide grade adjustment tools response = self.client.get(self.url) self.assertIn('<h4 class="hd hd-4">Adjust all enrolled learners', response.content) self.assertIn( '<h4 class="hd hd-4">View a specific learner's grades and progress', response.content) # But staff user can only see specific grades staff = StaffFactory(course_key=self.course.id) self.client.login(username=staff.username, password="******") response = self.client.get(self.url) self.assertNotIn('<h4 class="hd hd-4">Adjust all enrolled learners', response.content) self.assertIn( '<h4 class="hd hd-4">View a specific learner's grades and progress', response.content)
def setUp(self): super(TeamAPITestCase, self).setUp() self.topics_count = 4 self.users = { 'student_unenrolled': UserFactory.create(password=self.test_password), 'student_enrolled': UserFactory.create(password=self.test_password), 'student_enrolled_not_on_team': UserFactory.create(password=self.test_password), # This student is enrolled in both test courses and is a member of a team in each course, but is not on the # same team as student_enrolled. 'student_enrolled_both_courses_other_team': UserFactory.create(password=self.test_password), 'staff': AdminFactory.create(password=self.test_password), 'course_staff': StaffFactory.create(course_key=self.test_course_1.id, password=self.test_password) } # 'solar team' is intentionally lower case to test case insensitivity in name ordering self.test_team_1 = CourseTeamFactory.create( name=u'sólar team', course_id=self.test_course_1.id, topic_id='topic_0' ) self.test_team_2 = CourseTeamFactory.create(name='Wind Team', course_id=self.test_course_1.id) self.test_team_3 = CourseTeamFactory.create(name='Nuclear Team', course_id=self.test_course_1.id) self.test_team_4 = CourseTeamFactory.create(name='Coal Team', course_id=self.test_course_1.id, is_active=False) self.test_team_5 = CourseTeamFactory.create(name='Another Team', course_id=self.test_course_2.id) for user, course in [ ('student_enrolled', self.test_course_1), ('student_enrolled_not_on_team', self.test_course_1), ('student_enrolled_both_courses_other_team', self.test_course_1), ('student_enrolled_both_courses_other_team', self.test_course_2) ]: CourseEnrollment.enroll( self.users[user], course.id, check_access=True ) self.test_team_1.add_user(self.users['student_enrolled']) self.test_team_3.add_user(self.users['student_enrolled_both_courses_other_team']) self.test_team_5.add_user(self.users['student_enrolled_both_courses_other_team'])
def test_access_on_course_with_pre_requisites(self): """ Test course access when a course has pre-requisite course yet to be completed """ seed_milestone_relationship_types() user = UserFactory.create() pre_requisite_course = CourseFactory.create(org='test_org', number='788', run='test_run') pre_requisite_courses = [unicode(pre_requisite_course.id)] course = CourseFactory.create( org='test_org', number='786', run='test_run', pre_requisite_courses=pre_requisite_courses) set_prerequisite_courses(course.id, pre_requisite_courses) # user should not be able to load course even if enrolled CourseEnrollmentFactory(user=user, course_id=course.id) response = access._has_access_course( user, 'view_courseware_with_prerequisites', course) self.assertFalse(response) self.assertIsInstance(response, access_response.MilestoneError) # Staff can always access course staff = StaffFactory.create(course_key=course.id) self.assertTrue( access._has_access_course(staff, 'view_courseware_with_prerequisites', course)) # User should be able access after completing required course fulfill_course_milestone(pre_requisite_course.id, user) self.assertTrue( access._has_access_course(user, 'view_courseware_with_prerequisites', course))
def setUp(self): course_title = u"ẗëṡẗ title イ乇丂イ ᄊ乇丂丂ムg乇 キo尺 ムレレ тэѕт мэѕѕаБэ" self.course = CourseFactory.create(display_name=course_title) self.instructor = InstructorFactory(course=self.course.location) # Create staff self.staff = [ StaffFactory(course=self.course.location) for _ in xrange(STAFF_COUNT) ] # Create students self.students = [UserFactory() for _ in xrange(STUDENT_COUNT)] for student in self.students: CourseEnrollmentFactory.create(user=student, course_id=self.course.id) # load initial content (since we don't run migrations as part of tests): call_command("loaddata", "course_email_template.json") self.client.login(username=self.instructor.username, password="******") # Pull up email view on instructor dashboard self.url = reverse('instructor_dashboard', kwargs={'course_id': self.course.id}) response = self.client.get(self.url) email_link = '<a href="#" onclick="goto(\'Email\')" class="None">Email</a>' # If this fails, it is likely because ENABLE_INSTRUCTOR_EMAIL is set to False self.assertTrue(email_link in response.content) # Select the Email view of the instructor dash session = self.client.session session['idash_mode'] = 'Email' session.save() response = self.client.get(self.url) selected_email_link = '<a href="#" onclick="goto(\'Email\')" class="selectedmode">Email</a>' self.assertTrue(selected_email_link in response.content)
def test_closed_course_staff(self): """ Users marked as course staff should be able to submit grade events to a closed course """ course = self.setup_course_with_grading( start=datetime(2010, 1, 1, tzinfo=UTC()), end=datetime(2011, 1, 1, tzinfo=UTC()), ) self.user = StaffFactory(course_key=course.id) module = self.get_module_for_user(self.user, course, course.homework_assignment) grade_dict = {'value': 0.5, 'max_value': 1, 'user_id': self.user.id} module.system.publish(module, 'grade', grade_dict) with self.assertRaises(StudentGradebook.DoesNotExist): __ = StudentGradebook.objects.get(user=self.user, course_id=course.id) gradebook = StudentGradebook.objects.all() self.assertEqual(len(gradebook), 0) history = StudentGradebookHistory.objects.all() self.assertEqual(len(history), 0)
def test_not_authorized(self): """ Unauthorized users should get an empty list. """ user = StaffFactory(course_key=self.course.id) access_token = AccessTokenFactory.create( user=user, client=self.oauth_client).token auth_header = 'Bearer ' + access_token # If debug mode is enabled, the view should always return data. with override_settings(DEBUG=True): response = self.http_get(reverse(self.view), HTTP_AUTHORIZATION=auth_header) self.assertEqual(response.status_code, 200) # Data should be returned if the user is authorized. response = self.http_get(reverse(self.view), HTTP_AUTHORIZATION=auth_header) self.assertEqual(response.status_code, 200) url = "{}?course_id={}".format(reverse(self.view), self.course_id) response = self.http_get(url, HTTP_AUTHORIZATION=auth_header) self.assertEqual(response.status_code, 200) data = response.data['results'] self.assertEqual(len(data), 1) self.assertEqual(data[0]['name'], self.course.display_name) # The view should return an empty list if the user cannot access any courses. url = "{}?course_id={}".format(reverse(self.view), unicode(self.empty_course.id)) response = self.http_get(url, HTTP_AUTHORIZATION=auth_header) self.assertEqual(response.status_code, 200) self.assertDictContainsSubset({ 'count': 0, u'results': [] }, response.data)
def test_not_authorized(self): user = StaffFactory(course_key=self.course.id) access_token = AccessTokenFactory.create( user=user, client=self.oauth_client).token auth_header = 'Bearer ' + access_token # If debug mode is enabled, the view should always return data. with override_settings(DEBUG=True): response = self.http_get(reverse( self.view, kwargs={'course_id': self.course_id}), HTTP_AUTHORIZATION=auth_header) self.assertEqual(response.status_code, 200) # Access should be granted if the proper access token is supplied. response = self.http_get(reverse(self.view, kwargs={'course_id': self.course_id}), HTTP_AUTHORIZATION=auth_header) self.assertEqual(response.status_code, 200) # Access should be denied if the user is not course staff. response = self.http_get(reverse( self.view, kwargs={'course_id': unicode(self.empty_course.id)}), HTTP_AUTHORIZATION=auth_header) self.assertEqual(response.status_code, 403)
def test__catalog_visibility(self): """ Tests the catalog visibility tri-states """ user = UserFactory.create() course_id = CourseLocator('edX', 'test', '2012_Fall') staff = StaffFactory.create(course_key=course_id) course = Mock( id=course_id, catalog_visibility=CATALOG_VISIBILITY_CATALOG_AND_ABOUT ) self.assertTrue(access._has_access_course(user, 'see_in_catalog', course)) self.assertTrue(access._has_access_course(user, 'see_about_page', course)) self.assertTrue(access._has_access_course(staff, 'see_in_catalog', course)) self.assertTrue(access._has_access_course(staff, 'see_about_page', course)) # Now set visibility to just about page course = Mock( id=CourseLocator('edX', 'test', '2012_Fall'), catalog_visibility=CATALOG_VISIBILITY_ABOUT ) self.assertFalse(access._has_access_course(user, 'see_in_catalog', course)) self.assertTrue(access._has_access_course(user, 'see_about_page', course)) self.assertTrue(access._has_access_course(staff, 'see_in_catalog', course)) self.assertTrue(access._has_access_course(staff, 'see_about_page', course)) # Now set visibility to none, which means neither in catalog nor about pages course = Mock( id=CourseLocator('edX', 'test', '2012_Fall'), catalog_visibility=CATALOG_VISIBILITY_NONE ) self.assertFalse(access._has_access_course(user, 'see_in_catalog', course)) self.assertFalse(access._has_access_course(user, 'see_about_page', course)) self.assertTrue(access._has_access_course(staff, 'see_in_catalog', course)) self.assertTrue(access._has_access_course(staff, 'see_about_page', course))
def setUp(self): super(InlineAnalyticsAnswerDistributionWithOverrides, self).setUp() self.user = UserFactory.create() self.factory = RequestFactory() self.course = CourseFactory.create( org='A', number='B', display_name='C', ) self.staff = StaffFactory(course_key=self.course.id) self.instructor = InstructorFactory(course_key=self.course.id) analytics_data = { 'module_id': '123', 'question_types_by_part': 'radio', 'num_options_by_part': 6, 'course_id': 'A/B/C', } json_analytics_data = json.dumps(analytics_data) self.data = json_analytics_data self.zendesk_response = ( 'A problem has occurred retrieving the data, to report the problem click ' '<a href="{ZENDESK_URL}/hc/en-us/requests/new">here</a>').format( ZENDESK_URL=ZENDESK_URL)
def setUp(self): self.course = CourseFactory.create(number='999', display_name='Robot_Super_Course') self.overview_chapter = ItemFactory.create(display_name='Overview') self.courseware_chapter = ItemFactory.create(display_name='courseware') self.course = modulestore().get_course(self.course.id) self.test_course = CourseFactory.create( number='666', display_name='Robot_Sub_Course') self.other_org_course = CourseFactory.create(org='Other_Org_Course') self.sub_courseware_chapter = ItemFactory.create( parent_location=self.test_course.location, display_name='courseware') self.sub_overview_chapter = ItemFactory.create( parent_location=self.sub_courseware_chapter.location, display_name='Overview') self.welcome_section = ItemFactory.create( parent_location=self.overview_chapter.location, display_name='Welcome') self.test_course = modulestore().get_course(self.test_course.id) self.global_staff_user = GlobalStaffFactory() self.unenrolled_user = UserFactory(last_name="Unenrolled") self.enrolled_user = UserFactory(last_name="Enrolled") CourseEnrollmentFactory(user=self.enrolled_user, course_id=self.course.id) CourseEnrollmentFactory(user=self.enrolled_user, course_id=self.test_course.id) self.staff_user = StaffFactory(course_key=self.course.id) self.instructor_user = InstructorFactory(course_key=self.course.id) self.org_staff_user = OrgStaffFactory(course_key=self.course.id) self.org_instructor_user = OrgInstructorFactory( course_key=self.course.id)
def setUp(self): super(TeamAPITestCase, self).setUp() self.topics_count = 4 self.users = { "staff": AdminFactory.create(password=self.test_password), "course_staff": StaffFactory.create(course_key=self.test_course_1.id, password=self.test_password), } self.create_and_enroll_student(username="******") self.create_and_enroll_student(username="******") self.create_and_enroll_student(username="******", courses=[]) # Make this student a community TA. self.create_and_enroll_student(username="******") seed_permissions_roles(self.test_course_1.id) community_ta_role = Role.objects.get(name=FORUM_ROLE_COMMUNITY_TA, course_id=self.test_course_1.id) community_ta_role.users.add(self.users["community_ta"]) # This student is enrolled in both test courses and is a member of a team in each course, but is not on the # same team as student_enrolled. self.create_and_enroll_student( courses=[self.test_course_1, self.test_course_2], username="******" ) # Make this student have a public profile self.create_and_enroll_student(courses=[self.test_course_2], username="******") profile = self.users["student_enrolled_public_profile"].profile profile.year_of_birth = 1970 profile.save() # This student is enrolled in the other course, but not yet a member of a team. This is to allow # course_2 to use a max_team_size of 1 without breaking other tests on course_1 self.create_and_enroll_student( courses=[self.test_course_2], username="******" ) with skip_signal( post_save, receiver=course_team_post_save_callback, sender=CourseTeam, dispatch_uid="teams.signals.course_team_post_save_callback", ): # 'solar team' is intentionally lower case to test case insensitivity in name ordering self.test_team_1 = CourseTeamFactory.create( name=u"sólar team", course_id=self.test_course_1.id, topic_id="topic_0" ) self.test_team_2 = CourseTeamFactory.create(name="Wind Team", course_id=self.test_course_1.id) self.test_team_3 = CourseTeamFactory.create(name="Nuclear Team", course_id=self.test_course_1.id) self.test_team_4 = CourseTeamFactory.create( name="Coal Team", course_id=self.test_course_1.id, is_active=False ) self.test_team_5 = CourseTeamFactory.create(name="Another Team", course_id=self.test_course_2.id) self.test_team_6 = CourseTeamFactory.create( name="Public Profile Team", course_id=self.test_course_2.id, topic_id="topic_6" ) self.test_team_7 = CourseTeamFactory.create( name="Search", description="queryable text", country="GS", language="to", course_id=self.test_course_2.id, topic_id="topic_7", ) self.test_team_name_id_map = { team.name: team for team in ( self.test_team_1, self.test_team_2, self.test_team_3, self.test_team_4, self.test_team_5, self.test_team_6, self.test_team_7, ) } for user, course in [("staff", self.test_course_1), ("course_staff", self.test_course_1)]: CourseEnrollment.enroll(self.users[user], course.id, check_access=True) self.test_team_1.add_user(self.users["student_enrolled"]) self.test_team_3.add_user(self.users["student_enrolled_both_courses_other_team"]) self.test_team_5.add_user(self.users["student_enrolled_both_courses_other_team"]) self.test_team_6.add_user(self.users["student_enrolled_public_profile"])
def i_am_staff_or_instructor(step, role): # pylint: disable=unused-argument ## In summary: makes a test course, makes a new Staff or Instructor user ## (depending on `role`), and logs that user in to the course # Store the role assert_in(role, ['instructor', 'staff']) # Clear existing courses to avoid conflicts delete_pgreport_csv("edx/999/Test_Course") world.clear_courses() # Create a new course world.scenario_dict['COURSE'] = world.CourseFactory.create( org='edx', number='999', display_name='Test Course') section1 = world.ItemFactory.create( parent_location=world.scenario_dict['COURSE'].location, category='chapter', display_name="Test Section 1") subsec1 = world.ItemFactory.create(parent_location=section1.location, category='sequential', display_name="Test Subsection 1") vertical1 = world.ItemFactory.create( parent_location=subsec1.location, category='vertical', display_name="Test Vertical 1", ) problem_xml = PROBLEM_DICT['drop down']['factory'].build_xml( **PROBLEM_DICT['drop down']['kwargs']) problem1 = world.ItemFactory.create(parent_location=vertical1.location, category='problem', display_name="Problem 1", data=problem_xml) world.course_id = world.scenario_dict['COURSE'].id if not ProgressModules.objects.filter(location=problem1.location).exists(): world.pgmodule = world.ProgressModulesFactory.create( location=problem1.location, course_id=world.course_id, display_name="Problem 1") world.role = 'instructor' # Log in as the an instructor or staff for the course if role == 'instructor': # Make & register an instructor for the course world.instructor = InstructorFactory( course_key=world.scenario_dict['COURSE'].course_key) world.enroll_user(world.instructor, world.course_key) world.log_in(username=world.instructor.username, password='******', email=world.instructor.email, name=world.instructor.profile.name) else: world.role = 'staff' # Make & register a staff member world.staff = StaffFactory( course_key=world.scenario_dict['COURSE'].course_key) world.enroll_user(world.staff, world.course_key) world.log_in(username=world.staff.username, password='******', email=world.staff.email, name=world.staff.profile.name) create_pgreport_csv(world.course_id)
def setUp(self): super(TeamAPITestCase, self).setUp() teams_configuration = { 'topics': [{ 'id': 'topic_{}'.format(i), 'name': name, 'description': 'Description for topic {}.'.format(i) } for i, name in enumerate( [u'sólar power', 'Wind Power', 'Nuclear Power', 'Coal Power'])] } self.topics_count = 4 self.test_course_1 = CourseFactory.create( org='TestX', course='TS101', display_name='Test Course', teams_configuration=teams_configuration) self.test_course_2 = CourseFactory.create(org='MIT', course='6.002x', display_name='Circuits') self.users = { 'student_unenrolled': UserFactory.create(password=self.test_password), 'student_enrolled': UserFactory.create(password=self.test_password), 'student_enrolled_not_on_team': UserFactory.create(password=self.test_password), # This student is enrolled in both test courses and is a member of a team in each course, but is not on the # same team as student_enrolled. 'student_enrolled_both_courses_other_team': UserFactory.create(password=self.test_password), 'staff': AdminFactory.create(password=self.test_password), 'course_staff': StaffFactory.create(course_key=self.test_course_1.id, password=self.test_password) } # 'solar team' is intentionally lower case to test case insensitivity in name ordering self.test_team_1 = CourseTeamFactory.create( name=u'sólar team', course_id=self.test_course_1.id, topic_id='renewable') self.test_team_2 = CourseTeamFactory.create( name='Wind Team', course_id=self.test_course_1.id) self.test_team_3 = CourseTeamFactory.create( name='Nuclear Team', course_id=self.test_course_1.id) self.test_team_4 = CourseTeamFactory.create( name='Coal Team', course_id=self.test_course_1.id, is_active=False) self.test_team_4 = CourseTeamFactory.create( name='Another Team', course_id=self.test_course_2.id) for user, course in [ ('student_enrolled', self.test_course_1), ('student_enrolled_not_on_team', self.test_course_1), ('student_enrolled_both_courses_other_team', self.test_course_1), ('student_enrolled_both_courses_other_team', self.test_course_2) ]: CourseEnrollment.enroll(self.users[user], course.id, check_access=True) self.test_team_1.add_user(self.users['student_enrolled']) self.test_team_3.add_user( self.users['student_enrolled_both_courses_other_team']) self.test_team_4.add_user( self.users['student_enrolled_both_courses_other_team'])
def test_access_control(self): """ Test that only topics that a user has access to are returned. The ways in which a user may not have access are: * Module is visible to staff only * Module has a start date in the future * Module is accessible only to a group the user is not in Also, there is a case that ensures that a category with no accessible subcategories does not appear in the result. """ beta_tester = BetaTesterFactory.create(course_key=self.course.id) staff = StaffFactory.create(course_key=self.course.id) for user, group_idx in [(self.user, 0), (beta_tester, 1)]: cohort = CohortFactory.create( course_id=self.course.id, name=self.partition.groups[group_idx].name, users=[user] ) CourseUserGroupPartitionGroup.objects.create( course_user_group=cohort, partition_id=self.partition.id, group_id=self.partition.groups[group_idx].id ) self.make_discussion_module("courseware-1", "First", "Everybody") self.make_discussion_module( "courseware-2", "First", "Cohort A", group_access={self.partition.id: [self.partition.groups[0].id]} ) self.make_discussion_module( "courseware-3", "First", "Cohort B", group_access={self.partition.id: [self.partition.groups[1].id]} ) self.make_discussion_module("courseware-4", "Second", "Staff Only", visible_to_staff_only=True) self.make_discussion_module( "courseware-5", "Second", "Future Start Date", start=datetime.now(UTC) + timedelta(days=1) ) student_actual = self.get_course_topics() student_expected = { "courseware_topics": [ self.make_expected_tree( None, "First", [ self.make_expected_tree("courseware-2", "Cohort A"), self.make_expected_tree("courseware-1", "Everybody"), ] ), ], "non_courseware_topics": [], } self.assertEqual(student_actual, student_expected) beta_actual = self.get_course_topics(beta_tester) beta_expected = { "courseware_topics": [ self.make_expected_tree( None, "First", [ self.make_expected_tree("courseware-3", "Cohort B"), self.make_expected_tree("courseware-1", "Everybody"), ] ), self.make_expected_tree( None, "Second", [self.make_expected_tree("courseware-5", "Future Start Date")] ), ], "non_courseware_topics": [], } self.assertEqual(beta_actual, beta_expected) staff_actual = self.get_course_topics(staff) staff_expected = { "courseware_topics": [ self.make_expected_tree( None, "First", [ self.make_expected_tree("courseware-2", "Cohort A"), self.make_expected_tree("courseware-3", "Cohort B"), self.make_expected_tree("courseware-1", "Everybody"), ] ), self.make_expected_tree( None, "Second", [ self.make_expected_tree("courseware-5", "Future Start Date"), self.make_expected_tree("courseware-4", "Staff Only"), ] ), ], "non_courseware_topics": [], } self.assertEqual(staff_actual, staff_expected)
def setUp(self): self.output = StringIO.StringIO() self.gzipfile = StringIO.StringIO() self.course = CourseFactory.create( display_name=self.COURSE_NAME, ) self.course.raw_grader = [{ 'drop_count': 0, 'min_count': 1, 'short_label': 'Final', 'type': 'Final Exam', 'weight': 1.0 }] self.course.grade_cutoffs = {'Pass': 0.1} self.students = [ UserFactory.create(username='******'), UserFactory.create(username='******'), UserFactory.create(username='******'), UserFactory.create(username='******'), UserFactory.create(username='******'), StaffFactory.create(username='******', course_key=self.course.id), InstructorFactory.create(username='******', course_key=self.course.id), ] UserStandingFactory.create( user=self.students[4], account_status=UserStanding.ACCOUNT_DISABLED, changed_by=self.students[6] ) for user in self.students: CourseEnrollmentFactory.create(user=user, course_id=self.course.id) self.pgreport = ProgressReport(self.course.id) self.pgreport2 = ProgressReport(self.course.id, lambda state: state) self.chapter = ItemFactory.create( parent_location=self.course.location, category="chapter", display_name="Week 1" ) self.chapter.save() self.section = ItemFactory.create( parent_location=self.chapter.location, category="sequential", display_name="Lesson 1" ) self.section.save() self.vertical = ItemFactory.create( parent_location=self.section.location, category="vertical", display_name="Unit1" ) self.vertical.save() self.html = ItemFactory.create( parent_location=self.vertical.location, category="html", data={'data': "<html>foobar</html>"} ) self.html.save() """ course.children = [week1.location.url(), week2.location.url(), week3.location.url()] """ from capa.tests.response_xml_factory import OptionResponseXMLFactory self.problem_xml = OptionResponseXMLFactory().build_xml( question_text='The correct answer is Correct', num_inputs=2, weight=2, options=['Correct', 'Incorrect'], correct_option='Correct' ) self.problems = [] for num in xrange(1, 3): self.problems.append(ItemFactory.create( parent_location=self.vertical.location, category='problem', display_name='problem_' + str(num), metadata={'graded': True, 'format': 'Final Exam'}, data=self.problem_xml )) self.problems[num - 1].save() for problem in self.problems: problem.correct_map = { unicode(problem.location) + "_2_1": { "hint": "", "hintmode": "", "correctness": "correct", "npoints": "", "msg": "", "queuestate": "" }, unicode(problem.location) + "_2_2": { "hint": "", "hintmode": "", "correctness": "incorrect", "npoints": "", "msg": "", "queuestate": "" } } problem.student_answers = { unicode(problem.location) + "_2_1": "Correct", unicode(problem.location) + "_2_2": "Incorrect" } problem.input_state = { unicode(problem.location) + "_2_1": {}, unicode(problem.location) + "_2_2": {} } self.course.save() patcher = patch('pgreport.views.logging') self.log_mock = patcher.start() self.addCleanup(patcher.stop) """
def test_access_control(self): """ Test that only topics that a user has access to are returned. The ways in which a user may not have access are: * Module is visible to staff only * Module has a start date in the future * Module is accessible only to a group the user is not in Also, there is a case that ensures that a category with no accessible subcategories does not appear in the result. """ beta_tester = BetaTesterFactory.create(course_key=self.course.id) CourseEnrollmentFactory.create(user=beta_tester, course_id=self.course.id) staff = StaffFactory.create(course_key=self.course.id) for user, group_idx in [(self.user, 0), (beta_tester, 1)]: cohort = CohortFactory.create( course_id=self.course.id, name=self.partition.groups[group_idx].name, users=[user] ) CourseUserGroupPartitionGroup.objects.create( course_user_group=cohort, partition_id=self.partition.id, group_id=self.partition.groups[group_idx].id ) self.make_discussion_module("courseware-1", "First", "Everybody") self.make_discussion_module( "courseware-2", "First", "Cohort A", group_access={self.partition.id: [self.partition.groups[0].id]} ) self.make_discussion_module( "courseware-3", "First", "Cohort B", group_access={self.partition.id: [self.partition.groups[1].id]} ) self.make_discussion_module("courseware-4", "Second", "Staff Only", visible_to_staff_only=True) self.make_discussion_module( "courseware-5", "Second", "Future Start Date", start=datetime.now(UTC) + timedelta(days=1) ) student_actual = self.get_course_topics() student_expected = { "courseware_topics": [ self.make_expected_tree( None, "First", [ self.make_expected_tree("courseware-2", "Cohort A"), self.make_expected_tree("courseware-1", "Everybody"), ] ), ], "non_courseware_topics": [ self.make_expected_tree("non-courseware-topic-id", "Test Topic"), ], } self.assertEqual(student_actual, student_expected) beta_actual = self.get_course_topics(beta_tester) beta_expected = { "courseware_topics": [ self.make_expected_tree( None, "First", [ self.make_expected_tree("courseware-3", "Cohort B"), self.make_expected_tree("courseware-1", "Everybody"), ] ), self.make_expected_tree( None, "Second", [self.make_expected_tree("courseware-5", "Future Start Date")] ), ], "non_courseware_topics": [ self.make_expected_tree("non-courseware-topic-id", "Test Topic"), ], } self.assertEqual(beta_actual, beta_expected) staff_actual = self.get_course_topics(staff) staff_expected = { "courseware_topics": [ self.make_expected_tree( None, "First", [ self.make_expected_tree("courseware-2", "Cohort A"), self.make_expected_tree("courseware-3", "Cohort B"), self.make_expected_tree("courseware-1", "Everybody"), ] ), self.make_expected_tree( None, "Second", [ self.make_expected_tree("courseware-5", "Future Start Date"), self.make_expected_tree("courseware-4", "Staff Only"), ] ), ], "non_courseware_topics": [ self.make_expected_tree("non-courseware-topic-id", "Test Topic"), ], } self.assertEqual(staff_actual, staff_expected)
def setUp(self): super(TeamAPITestCase, self).setUp() self.topics_count = 4 self.users = { 'staff': AdminFactory.create(password=self.test_password), 'course_staff': StaffFactory.create(course_key=self.test_course_1.id, password=self.test_password) } self.create_and_enroll_student(username='******') self.create_and_enroll_student(username='******') self.create_and_enroll_student(username='******', courses=[]) # Make this student a community TA. self.create_and_enroll_student(username='******') seed_permissions_roles(self.test_course_1.id) community_ta_role = Role.objects.get(name=FORUM_ROLE_COMMUNITY_TA, course_id=self.test_course_1.id) community_ta_role.users.add(self.users['community_ta']) # This student is enrolled in both test courses and is a member of a team in each course, but is not on the # same team as student_enrolled. self.create_and_enroll_student( courses=[self.test_course_1, self.test_course_2], username='******' ) # Make this student have a public profile self.create_and_enroll_student( courses=[self.test_course_2], username='******' ) profile = self.users['student_enrolled_public_profile'].profile profile.year_of_birth = 1970 profile.save() # This student is enrolled in the other course, but not yet a member of a team. This is to allow # course_2 to use a max_team_size of 1 without breaking other tests on course_1 self.create_and_enroll_student( courses=[self.test_course_2], username='******' ) with skip_signal( post_save, receiver=course_team_post_save_callback, sender=CourseTeam, dispatch_uid='teams.signals.course_team_post_save_callback' ): self.solar_team = CourseTeamFactory.create( name=u'Sólar team', course_id=self.test_course_1.id, topic_id='topic_0' ) self.wind_team = CourseTeamFactory.create(name='Wind Team', course_id=self.test_course_1.id) self.nuclear_team = CourseTeamFactory.create(name='Nuclear Team', course_id=self.test_course_1.id) self.another_team = CourseTeamFactory.create(name='Another Team', course_id=self.test_course_2.id) self.public_profile_team = CourseTeamFactory.create( name='Public Profile Team', course_id=self.test_course_2.id, topic_id='topic_6' ) self.search_team = CourseTeamFactory.create( name='Search', description='queryable text', country='GS', language='to', course_id=self.test_course_2.id, topic_id='topic_7' ) self.test_team_name_id_map = {team.name: team for team in ( self.solar_team, self.wind_team, self.nuclear_team, self.another_team, self.public_profile_team, self.search_team, )} for user, course in [('staff', self.test_course_1), ('course_staff', self.test_course_1)]: CourseEnrollment.enroll( self.users[user], course.id, check_access=True ) self.solar_team.add_user(self.users['student_enrolled']) self.nuclear_team.add_user(self.users['student_enrolled_both_courses_other_team']) self.another_team.add_user(self.users['student_enrolled_both_courses_other_team']) self.public_profile_team.add_user(self.users['student_enrolled_public_profile'])
def setUp(self): super(TeamAPITestCase, self).setUp() self.topics_count = 4 self.users = { 'staff': AdminFactory.create(password=self.test_password), 'course_staff': StaffFactory.create(course_key=self.test_course_1.id, password=self.test_password) } self.create_and_enroll_student(username='******') self.create_and_enroll_student(username='******') self.create_and_enroll_student(username='******', courses=[]) # Make this student a community TA. self.create_and_enroll_student(username='******') seed_permissions_roles(self.test_course_1.id) community_ta_role = Role.objects.get(name=FORUM_ROLE_COMMUNITY_TA, course_id=self.test_course_1.id) community_ta_role.users.add(self.users['community_ta']) # This student is enrolled in both test courses and is a member of a team in each course, but is not on the # same team as student_enrolled. self.create_and_enroll_student( courses=[self.test_course_1, self.test_course_2], username='******' ) # Make this student have a public profile self.create_and_enroll_student( courses=[self.test_course_2], username='******' ) profile = self.users['student_enrolled_public_profile'].profile profile.year_of_birth = 1970 profile.save() # 'solar team' is intentionally lower case to test case insensitivity in name ordering self.test_team_1 = CourseTeamFactory.create( name=u'sólar team', course_id=self.test_course_1.id, topic_id='topic_0' ) self.test_team_2 = CourseTeamFactory.create(name='Wind Team', course_id=self.test_course_1.id) self.test_team_3 = CourseTeamFactory.create(name='Nuclear Team', course_id=self.test_course_1.id) self.test_team_4 = CourseTeamFactory.create(name='Coal Team', course_id=self.test_course_1.id, is_active=False) self.test_team_5 = CourseTeamFactory.create(name='Another Team', course_id=self.test_course_2.id) self.test_team_6 = CourseTeamFactory.create( name='Public Profile Team', course_id=self.test_course_2.id, topic_id='topic_6' ) self.test_team_name_id_map = {team.name: team for team in ( self.test_team_1, self.test_team_2, self.test_team_3, self.test_team_4, self.test_team_5, )} for user, course in [('staff', self.test_course_1), ('course_staff', self.test_course_1)]: CourseEnrollment.enroll( self.users[user], course.id, check_access=True ) self.test_team_1.add_user(self.users['student_enrolled']) self.test_team_3.add_user(self.users['student_enrolled_both_courses_other_team']) self.test_team_5.add_user(self.users['student_enrolled_both_courses_other_team']) self.test_team_6.add_user(self.users['student_enrolled_public_profile'])
def setUpTestData(cls): """Set up and enroll our fake user in the course.""" cls.staff_user = StaffFactory(course_key=cls.course.id, password=TEST_PASSWORD) cls.user = UserFactory(password=TEST_PASSWORD) CourseEnrollment.enroll(cls.user, cls.course.id)
def setUp(self): super(TestGetProblemGradeDistribution, self).setUp() self.request_factory = RequestFactory() self.instructor = AdminFactory.create() self.client.login(username=self.instructor.username, password='******') self.attempts = 3 self.users = [ UserFactory.create(username="******" + str(__)) for __ in xrange(USER_COUNT) ] for user in self.users: CourseEnrollmentFactory.create(user=user, course_id=self.course.id) # Adding an instructor and a staff to the site. These should not be included in any reports. instructor_member = InstructorFactory(course_key=self.course.id) CourseEnrollment.enroll(instructor_member, self.course.id) staff_member = StaffFactory(course_key=self.course.id) CourseEnrollment.enroll(staff_member, self.course.id) for i, item in enumerate(self.items): for j, user in enumerate(self.users): StudentModuleFactory.create( grade=1 if i < j else 0, max_grade=1, student=user, course_id=self.course.id, module_state_key=item.location, state=json.dumps({'attempts': self.attempts}), ) StudentModuleFactory.create( grade=1, max_grade=1, student=instructor_member, course_id=self.course.id, module_state_key=item.location, state=json.dumps({'attempts': self.attempts}), ) StudentModuleFactory.create( grade=1, max_grade=1, student=staff_member, course_id=self.course.id, module_state_key=item.location, state=json.dumps({'attempts': self.attempts}), ) for j, user in enumerate(self.users): StudentModuleFactory.create( course_id=self.course.id, student=user, module_type='sequential', module_state_key=self.sub_section.location, ) StudentModuleFactory.create( course_id=self.course.id, student=instructor_member, module_type='sequential', module_state_key=self.sub_section.location, ) StudentModuleFactory.create( course_id=self.course.id, student=staff_member, module_type='sequential', module_state_key=self.sub_section.location, )
def setUp(self): super(GroupAccessTestCase, self).setUp() UserPartition.scheme_extensions = ExtensionManager.make_test_instance( [ Extension( "memory", USER_PARTITION_SCHEME_NAMESPACE, MemoryUserPartitionScheme(), None ), Extension( "random", USER_PARTITION_SCHEME_NAMESPACE, MemoryUserPartitionScheme(), None ) ], namespace=USER_PARTITION_SCHEME_NAMESPACE ) self.cat_group = Group(10, 'cats') self.dog_group = Group(20, 'dogs') self.worm_group = Group(30, 'worms') self.animal_partition = UserPartition( 0, 'Pet Partition', 'which animal are you?', [self.cat_group, self.dog_group, self.worm_group], scheme=UserPartition.get_scheme("memory"), ) self.red_group = Group(1000, 'red') self.blue_group = Group(2000, 'blue') self.gray_group = Group(3000, 'gray') self.color_partition = UserPartition( 100, 'Color Partition', 'what color are you?', [self.red_group, self.blue_group, self.gray_group], scheme=UserPartition.get_scheme("memory"), ) self.course = CourseFactory.create( user_partitions=[self.animal_partition, self.color_partition], ) with self.store.bulk_operations(self.course.id, emit_signals=False): chapter = ItemFactory.create(category='chapter', parent=self.course) section = ItemFactory.create(category='sequential', parent=chapter) vertical = ItemFactory.create(category='vertical', parent=section) component = ItemFactory.create(category='problem', parent=vertical) self.chapter_location = chapter.location self.section_location = section.location self.vertical_location = vertical.location self.component_location = component.location self.red_cat = UserFactory() # student in red and cat groups self.set_user_group(self.red_cat, self.animal_partition, self.cat_group) self.set_user_group(self.red_cat, self.color_partition, self.red_group) self.blue_dog = UserFactory() # student in blue and dog groups self.set_user_group(self.blue_dog, self.animal_partition, self.dog_group) self.set_user_group(self.blue_dog, self.color_partition, self.blue_group) self.white_mouse = UserFactory() # student in no group self.gray_worm = UserFactory() # student in deleted group self.set_user_group(self.gray_worm, self.animal_partition, self.worm_group) self.set_user_group(self.gray_worm, self.color_partition, self.gray_group) # delete the gray/worm groups from the partitions now so we can test scenarios # for user whose group is missing. self.animal_partition.groups.pop() self.color_partition.groups.pop() # add a staff user, whose access will be unconditional in spite of group access. self.staff = StaffFactory.create(course_key=self.course.id)
def setUp(self): super(TeamAPITestCase, self).setUp() self.topics_count = 4 self.users = { 'staff': AdminFactory.create(password=self.test_password), 'course_staff': StaffFactory.create(course_key=self.test_course_1.id, password=self.test_password) } self.create_and_enroll_student(username='******') self.create_and_enroll_student(username='******') self.create_and_enroll_student(username='******', courses=[]) # Make this student a community TA. self.create_and_enroll_student(username='******') seed_permissions_roles(self.test_course_1.id) community_ta_role = Role.objects.get(name=FORUM_ROLE_COMMUNITY_TA, course_id=self.test_course_1.id) community_ta_role.users.add(self.users['community_ta']) # This student is enrolled in both test courses and is a member of a team in each course, but is not on the # same team as student_enrolled. self.create_and_enroll_student( courses=[self.test_course_1, self.test_course_2], username='******' ) # Make this student have a public profile self.create_and_enroll_student( courses=[self.test_course_2], username='******' ) profile = self.users['student_enrolled_public_profile'].profile profile.year_of_birth = 1970 profile.save() # This student is enrolled in the other course, but not yet a member of a team. This is to allow # course_2 to use a max_team_size of 1 without breaking other tests on course_1 self.create_and_enroll_student( courses=[self.test_course_2], username='******' ) # 'solar team' is intentionally lower case to test case insensitivity in name ordering self.test_team_1 = CourseTeamFactory.create( name=u'sólar team', course_id=self.test_course_1.id, topic_id='topic_0' ) self.test_team_2 = CourseTeamFactory.create(name='Wind Team', course_id=self.test_course_1.id) self.test_team_3 = CourseTeamFactory.create(name='Nuclear Team', course_id=self.test_course_1.id) self.test_team_4 = CourseTeamFactory.create(name='Coal Team', course_id=self.test_course_1.id, is_active=False) self.test_team_5 = CourseTeamFactory.create(name='Another Team', course_id=self.test_course_2.id) self.test_team_6 = CourseTeamFactory.create( name='Public Profile Team', course_id=self.test_course_2.id, topic_id='topic_6' ) self.test_team_name_id_map = {team.name: team for team in ( self.test_team_1, self.test_team_2, self.test_team_3, self.test_team_4, self.test_team_5, )} for user, course in [('staff', self.test_course_1), ('course_staff', self.test_course_1)]: CourseEnrollment.enroll( self.users[user], course.id, check_access=True ) self.test_team_1.add_user(self.users['student_enrolled']) self.test_team_3.add_user(self.users['student_enrolled_both_courses_other_team']) self.test_team_5.add_user(self.users['student_enrolled_both_courses_other_team']) self.test_team_6.add_user(self.users['student_enrolled_public_profile'])
def create_user(self): """ Creates a staff user. """ return StaffFactory(course_key=self.course.id)
def setUp(self): super(GroupAccessTestCase, self).setUp() UserPartition.scheme_extensions = ExtensionManager.make_test_instance( [ Extension("memory", USER_PARTITION_SCHEME_NAMESPACE, MemoryUserPartitionScheme(), None), Extension("random", USER_PARTITION_SCHEME_NAMESPACE, MemoryUserPartitionScheme(), None) ], namespace=USER_PARTITION_SCHEME_NAMESPACE) self.cat_group = Group(10, 'cats') self.dog_group = Group(20, 'dogs') self.worm_group = Group(30, 'worms') self.animal_partition = UserPartition( 0, 'Pet Partition', 'which animal are you?', [self.cat_group, self.dog_group, self.worm_group], scheme=UserPartition.get_scheme("memory"), ) self.red_group = Group(1000, 'red') self.blue_group = Group(2000, 'blue') self.gray_group = Group(3000, 'gray') self.color_partition = UserPartition( 100, 'Color Partition', 'what color are you?', [self.red_group, self.blue_group, self.gray_group], scheme=UserPartition.get_scheme("memory"), ) self.course = CourseFactory.create( user_partitions=[self.animal_partition, self.color_partition], ) with self.store.bulk_operations(self.course.id, emit_signals=False): chapter = ItemFactory.create(category='chapter', parent=self.course) section = ItemFactory.create(category='sequential', parent=chapter) vertical = ItemFactory.create(category='vertical', parent=section) component = ItemFactory.create(category='problem', parent=vertical) self.chapter_location = chapter.location self.section_location = section.location self.vertical_location = vertical.location self.component_location = component.location self.red_cat = UserFactory() # student in red and cat groups self.set_user_group(self.red_cat, self.animal_partition, self.cat_group) self.set_user_group(self.red_cat, self.color_partition, self.red_group) self.blue_dog = UserFactory() # student in blue and dog groups self.set_user_group(self.blue_dog, self.animal_partition, self.dog_group) self.set_user_group(self.blue_dog, self.color_partition, self.blue_group) self.white_mouse = UserFactory() # student in no group self.gray_worm = UserFactory() # student in deleted group self.set_user_group(self.gray_worm, self.animal_partition, self.worm_group) self.set_user_group(self.gray_worm, self.color_partition, self.gray_group) # delete the gray/worm groups from the partitions now so we can test scenarios # for user whose group is missing. self.animal_partition.groups.pop() self.color_partition.groups.pop() # add a staff user, whose access will be unconditional in spite of group access. self.staff = StaffFactory.create(course_key=self.course.id)