Exemplo n.º 1
0
    def wrapper(request, course_id):
        """
        Wraps the view function, performing access check, loading the course,
        and modifying the view's call signature.
        """
        course_key = CourseKey.from_string(course_id)
        ccx = None
        if isinstance(course_key, CCXLocator):
            ccx_id = course_key.ccx
            ccx = CustomCourseForEdX.objects.get(pk=ccx_id)
            course_key = ccx.course_id

        course = get_course_by_id(course_key, depth=None)
        is_staff = has_access(request.user, 'staff', course)
        is_instructor = has_access(request.user, 'instructor', course)

        if is_staff or is_instructor:
            # if user is staff or instructor then he can view ccx coach dashboard.
            return view(request, course, ccx)
        else:
            role = CourseCcxCoachRole(course_key)
            if not role.has_user(request.user):
                return HttpResponseForbidden(
                    _('You must be a CCX Coach to access this view.'))

            # if there is a ccx, we must validate that it is the ccx for this coach
            if ccx is not None:
                coach_ccx = get_ccx_by_ccx_id(course, request.user, ccx.id)
                if coach_ccx is None:
                    return HttpResponseForbidden(
                        _('You must be the coach for this ccx to access this view'
                          ))

        return view(request, course, ccx)
Exemplo n.º 2
0
 def setUp(self):
     super(CCXCoachTabTestCase, self).setUp()
     self.user = UserFactory.create()
     for course in [self.ccx_enabled_course, self.ccx_disabled_course]:
         CourseEnrollmentFactory.create(user=self.user, course_id=course.id)
         role = CourseCcxCoachRole(course.id)
         role.add_users(self.user)
Exemplo n.º 3
0
    def test_create_ccx(self):
        """
        Create CCX. Follow redirect to coach dashboard, confirm we see
        the coach dashboard for the new CCX.
        """

        self.make_coach()
        url = reverse('create_ccx',
                      kwargs={'course_id': unicode(self.course.id)})

        response = self.client.post(url, {'name': 'New CCX'})
        self.assertEqual(response.status_code, 302)
        url = response.get('location')  # pylint: disable=no-member
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)

        # Get the ccx_key
        path = urlparse.urlparse(url).path
        resolver = resolve(path)
        ccx_key = resolver.kwargs['course_id']

        course_key = CourseKey.from_string(ccx_key)

        self.assertTrue(CourseEnrollment.is_enrolled(self.coach, course_key))
        self.assertTrue(re.search('id="ccx-schedule"', response.content))

        # check if the max amount of student that can be enrolled has been overridden
        ccx = CustomCourseForEdX.objects.get()
        course_enrollments = get_override_for_ccx(
            ccx, self.course, 'max_student_enrollments_allowed')
        self.assertEqual(course_enrollments, settings.CCX_MAX_STUDENTS_ALLOWED)

        # assert ccx creator has role=ccx_coach
        role = CourseCcxCoachRole(course_key)
        self.assertTrue(role.has_user(self.coach, refresh=True))
Exemplo n.º 4
0
    def setUp(self):
        """
        Set up courses and enrollments.
        """
        super(TestStudentDashboardWithCCX, self).setUp()

        # Create a Draft Mongo and a Split Mongo course and enroll a student user in them.
        self.student_password = "******"
        self.student = UserFactory.create(username="******", password=self.student_password, is_staff=False)
        self.draft_course = CourseFactory.create(default_store=ModuleStoreEnum.Type.mongo)
        self.split_course = CourseFactory.create(default_store=ModuleStoreEnum.Type.split)
        CourseEnrollment.enroll(self.student, self.draft_course.id)
        CourseEnrollment.enroll(self.student, self.split_course.id)

        # Create a CCX coach.
        self.coach = AdminFactory.create()
        role = CourseCcxCoachRole(self.split_course.id)
        role.add_users(self.coach)

        # Create a CCX course and enroll the user in it.
        self.ccx = CcxFactory(course_id=self.split_course.id, coach=self.coach)
        last_week = datetime.datetime.now(UTC()) - datetime.timedelta(days=7)
        override_field_for_ccx(self.ccx, self.split_course, 'start', last_week)  # Required by self.ccx.has_started().
        course_key = CCXLocator.from_course_locator(self.split_course.id, self.ccx.id)
        CourseEnrollment.enroll(self.student, course_key)
Exemplo n.º 5
0
 def setUp(self):
     super(TestRenderMessageToString, self).setUp()
     coach = AdminFactory.create()
     role = CourseCcxCoachRole(self.course.id)
     role.add_users(coach)
     self.ccx = CcxFactory(course_id=self.course.id, coach=coach)
     self.course_key = CCXLocator.from_course_locator(self.course.id, self.ccx.id)
Exemplo n.º 6
0
 def setUp(self):
     """Set up a course, coach, ccx and user"""
     super(TestGetCCXFromCCXLocator, self).setUp()
     self.course = CourseFactory.create()
     coach = self.coach = AdminFactory.create()
     role = CourseCcxCoachRole(self.course.id)
     role.add_users(coach)
Exemplo n.º 7
0
 def test_patch_detail(self):
     """
     Test for successful patch
     """
     outbox = self.get_outbox()
     # create a new coach
     new_coach = AdminFactory.create()
     data = {
         'max_students_allowed': 111,
         'display_name': 'CCX Title',
         'coach_email': new_coach.email
     }
     resp = self.client.patch(self.detail_url,
                              data,
                              format='json',
                              HTTP_AUTHORIZATION=self.auth)
     self.assertEqual(resp.status_code, status.HTTP_204_NO_CONTENT)
     ccx_from_db = CustomCourseForEdX.objects.get(id=self.ccx.id)
     self.assertEqual(ccx_from_db.max_student_enrollments_allowed,
                      data['max_students_allowed'])
     self.assertEqual(ccx_from_db.display_name, data['display_name'])
     self.assertEqual(ccx_from_db.coach.email, data['coach_email'])
     # check that the coach user has coach role on the master course
     coach_role_on_master_course = CourseCcxCoachRole(
         self.master_course_key)
     self.assertTrue(coach_role_on_master_course.has_user(new_coach))
     # check that the coach has been enrolled in the ccx
     ccx_course_object = courses.get_course_by_id(self.ccx_key)
     self.assertTrue(
         CourseEnrollment.objects.filter(course_id=ccx_course_object.id,
                                         user=new_coach).exists())
     # check that an email has been sent to the coach
     self.assertEqual(len(outbox), 1)
     self.assertIn(new_coach.email, outbox[0].recipients())  # pylint: disable=no-member
Exemplo n.º 8
0
    def num_enrolled_in_exclude_admins(self, course_id):
        """
        Returns the count of active enrollments in a course excluding instructors, staff and CCX coaches.

        Arguments:
            course_id (CourseLocator): course_id to return enrollments (count).

        Returns:
            int: Count of enrollments excluding staff, instructors and CCX coaches.

        """
        # To avoid circular imports.
        from student.roles import CourseCcxCoachRole, CourseInstructorRole, CourseStaffRole
        course_locator = course_id

        if getattr(course_id, 'ccx', None):
            # We don't use CCX, so raising exception rather than support it
            raise Exception('CCX is not supported')

        staff = CourseStaffRole(course_locator).users_with_role()
        admins = CourseInstructorRole(course_locator).users_with_role()
        coaches = CourseCcxCoachRole(course_locator).users_with_role()

        qs = super(CourseEnrollmentManager, self).get_queryset()
        q2 = qs.filter(course_id=course_id, is_active=1)
        q3 = q2.exclude(user__in=staff).exclude(user__in=admins).exclude(user__in=coaches)
        return q3.count()
Exemplo n.º 9
0
def has_ccx_coach_role(user, course_key):
    """
    Check if user is a coach on this ccx.

    Arguments:
        user (User): the user whose descriptor access we are checking.
        course_key (CCXLocator): Key to CCX.

    Returns:
        bool: whether user is a coach on this ccx or not.
    """
    if hasattr(course_key, 'ccx'):
        ccx_id = course_key.ccx
        role = CourseCcxCoachRole(course_key)

        if role.has_user(user):
            list_ccx = CustomCourseForEdX.objects.filter(
                course_id=course_key.to_course_locator(),
                coach=user
            )
            if list_ccx.exists():
                coach_ccx = list_ccx[0]
                return str(coach_ccx.id) == ccx_id
    else:
        raise CCXLocatorValidationException("Invalid CCX key. To verify that "
                                            "user is a coach on CCX, you must provide key to CCX")
    return False
Exemplo n.º 10
0
 def setUp(self):
     super(CCXCoachTabTestCase, self).setUp()
     self.course = CourseFactory.create()
     self.user = UserFactory.create()
     CourseEnrollmentFactory.create(user=self.user,
                                    course_id=self.course.id)
     role = CourseCcxCoachRole(self.course.id)
     role.add_users(self.user)
Exemplo n.º 11
0
 def setUp(self):
     """Set up a course, coach, ccx and user"""
     super(TestGetMembershipTriplets, self).setUp()
     self.course = CourseFactory.create()
     coach = AdminFactory.create()
     role = CourseCcxCoachRole(self.course.id)
     role.add_users(coach)
     self.ccx = CcxFactory(course_id=self.course.id, coach=coach)
Exemplo n.º 12
0
 def test_ccx_tab_visibility_for_instructor_when_coach_master_course(self):
     """
     Instructor can view ccx coach dashboard only if he is coach on master course.
     """
     instructor = self.make_instructor()
     role = CourseCcxCoachRole(self.course.id)
     role.add_users(instructor)
     self.assertTrue(self.check_ccx_tab(self.course, instructor))
Exemplo n.º 13
0
 def setUp(self):
     """common setup for all tests"""
     super(TestCCX, self).setUp()
     self.course = course = CourseFactory.create()
     coach = AdminFactory.create()
     role = CourseCcxCoachRole(course.id)
     role.add_users(coach)
     self.ccx = CcxFactory(course_id=course.id, coach=coach)
Exemplo n.º 14
0
 def test_ccx_tab_visibility_for_staff_when_coach_master_course(self):
     """
     Staff can view ccx coach dashboard only if he is coach on master course.
     """
     staff = self.make_staff()
     role = CourseCcxCoachRole(self.course.id)
     role.add_users(staff)
     self.assertTrue(self.check_ccx_tab(self.course, staff))
Exemplo n.º 15
0
def assign_coach_role_to_ccx(ccx_locator, user, master_course_id):
    """
    Check if user has ccx_coach role on master course then assign him coach role on ccx only
    if role is not already assigned. Because of this coach can open dashboard from master course
    as well as ccx.
    :param ccx_locator: CCX key
    :param user: User to whom we want to assign role.
    :param master_course_id: Master course key
    """
    coach_role_on_master_course = CourseCcxCoachRole(master_course_id)
    # check if user has coach role on master course
    if coach_role_on_master_course.has_user(user):
        # Check if user has coach role on ccx.
        role = CourseCcxCoachRole(ccx_locator)
        if not role.has_user(user):
            # assign user role coach on ccx
            with ccx_course(ccx_locator) as course:
                allow_access(course, user, "ccx_coach", send_email=False)
Exemplo n.º 16
0
    def setUp(self):
        """
        Set up tests
        """
        super(TestCCXGrades, self).setUp()

        # Create instructor account
        self.coach = coach = AdminFactory.create()
        self.client.login(username=coach.username, password="******")

        # Create CCX
        role = CourseCcxCoachRole(self._course.id)
        role.add_users(coach)
        ccx = CcxFactory(course_id=self._course.id, coach=self.coach)

        # override course grading policy and make last section invisible to students
        override_field_for_ccx(
            ccx, self._course, 'grading_policy', {
                'GRADER': [{
                    'drop_count': 0,
                    'min_count': 2,
                    'short_label': 'HW',
                    'type': 'Homework',
                    'weight': 1
                }],
                'GRADE_CUTOFFS': {
                    'Pass': 0.75
                },
            })
        override_field_for_ccx(ccx, self.sections[-1], 'visible_to_staff_only',
                               True)

        # create a ccx locator and retrieve the course structure using that key
        # which emulates how a student would get access.
        self.ccx_key = CCXLocator.from_course_locator(self._course.id, ccx.id)
        self.course = get_course_by_id(self.ccx_key, depth=None)

        self.student = student = UserFactory.create()
        CourseEnrollmentFactory.create(user=student, course_id=self.course.id)

        # create grades for self.student as if they'd submitted the ccx
        for chapter in self.course.get_children():
            for i, section in enumerate(chapter.get_children()):
                for j, problem in enumerate(section.get_children()):
                    # if not problem.visible_to_staff_only:
                    StudentModuleFactory.create(
                        grade=1 if i < j else 0,
                        max_grade=1,
                        student=self.student,
                        course_id=self.course.id,
                        module_state_key=problem.location)

        self.client.login(username=coach.username, password="******")

        self.addCleanup(RequestCache.clear_request_cache)
Exemplo n.º 17
0
 def setUp(self):
     super(TestEnrollEmail, self).setUp()
     # unbind the user created by the parent, so we can create our own when
     # needed.
     self.user = None
     course = CourseFactory.create()
     coach = AdminFactory.create()
     role = CourseCcxCoachRole(course.id)
     role.add_users(coach)
     self.ccx = CcxFactory(course_id=course.id, coach=coach)
     self.outbox = self.get_outbox()
Exemplo n.º 18
0
 def setUp(self):
     super(TestSwitchActiveCCX, self).setUp()
     self.course = course = CourseFactory.create()
     coach = AdminFactory.create()
     role = CourseCcxCoachRole(course.id)
     role.add_users(coach)
     self.ccx = CcxFactory(course_id=course.id, coach=coach)
     enrollment = CourseEnrollmentFactory.create(course_id=course.id)
     self.user = enrollment.user
     self.target_url = reverse('course_root',
                               args=[course.id.to_deprecated_string()])
Exemplo n.º 19
0
 def setUp(self):
     """common setup for all tests"""
     super(TestCcxMembership, self).setUp()
     self.course = course = CourseFactory.create()
     coach = AdminFactory.create()
     role = CourseCcxCoachRole(course.id)
     role.add_users(coach)
     self.ccx = CcxFactory(course_id=course.id, coach=coach)
     enrollment = CourseEnrollmentFactory.create(course_id=course.id)
     self.enrolled_user = enrollment.user
     self.unenrolled_user = UserFactory.create()
Exemplo n.º 20
0
 def is_enabled(cls, course, user=None):
     """
     Returns true if CCX has been enabled and the specified user is a coach
     """
     if not user:
         return True
     if not settings.FEATURES.get('CUSTOM_COURSES_EDX',
                                  False) or not course.enable_ccx:
         return False
     role = CourseCcxCoachRole(course.id)
     return role.has_user(user)
Exemplo n.º 21
0
 def setUp(self):
     """Create required infrastructure for tests"""
     super(TestUserCCXList, self).setUp()
     self.course = CourseFactory.create()
     coach = AdminFactory.create()
     role = CourseCcxCoachRole(self.course.id)
     role.add_users(coach)
     self.ccx = CcxFactory(course_id=self.course.id, coach=coach)
     enrollment = CourseEnrollmentFactory.create(course_id=self.course.id)
     self.user = enrollment.user
     self.anonymous = AnonymousUserFactory.create()
Exemplo n.º 22
0
 def wrapper(request, course_id):
     """
     Wraps the view function, performing access check, loading the course,
     and modifying the view's call signature.
     """
     course_key = CourseKey.from_string(course_id)
     role = CourseCcxCoachRole(course_key)
     if not role.has_user(request.user):
         return HttpResponseForbidden(
             _('You must be a CCX Coach to access this view.'))
     course = get_course_by_id(course_key, depth=None)
     return view(request, course)
Exemplo n.º 23
0
def make_user_coach(user, master_course_key):
    """
    Makes an user coach on the master course.
    This function is needed because an user cannot become a coach of the CCX if s/he is not
    coach on the master course.

    Args:
        user (User): User object
        master_course_key (CourseKey): Key locator object for the course
    """
    coach_role_on_master_course = CourseCcxCoachRole(master_course_key)
    coach_role_on_master_course.add_users(user)
Exemplo n.º 24
0
 def setUp(self):
     """
     Set up tests
     """
     super(TestEmailEnrollmentState, self).setUp()
     # remove user provided by the parent test case so we can make our own
     # when needed.
     self.user = None
     course = CourseFactory.create()
     coach = AdminFactory.create()
     role = CourseCcxCoachRole(course.id)
     role.add_users(coach)
     self.ccx = CcxFactory(course_id=course.id, coach=coach)
Exemplo n.º 25
0
    def setUp(self):
        """
        Set up tests
        """
        super(CoachAccessTestCaseCCX, self).setUp()

        # Create ccx coach account
        self.coach = AdminFactory.create(password="******")
        self.client.login(username=self.coach.username, password="******")

        # assign role to coach
        role = CourseCcxCoachRole(self.course.id)
        role.add_users(self.coach)
        self.request_factory = RequestFactory()
Exemplo n.º 26
0
    def is_enabled(cls, course, user=None):
        """
        Returns true if CCX has been enabled and the specified user is a coach
        """
        if not settings.FEATURES.get('CUSTOM_COURSES_EDX', False) or not course.enable_ccx:
            # If ccx is not enable do not show ccx coach tab.
            return False

        if hasattr(course.id, 'ccx') and bool(user.has_perm(VIEW_CCX_COACH_DASHBOARD, course)):
            return True

        # check if user has coach access.
        role = CourseCcxCoachRole(course.id)
        return role.has_user(user)
Exemplo n.º 27
0
    def setUp(self):
        super(TestGetEmailParamsCCX, self).setUp()
        self.coach = AdminFactory.create()
        role = CourseCcxCoachRole(self.course.id)
        role.add_users(self.coach)
        self.ccx = CcxFactory(course_id=self.course.id, coach=self.coach)
        self.course_key = CCXLocator.from_course_locator(
            self.course.id, self.ccx.id)

        # Explicitly construct what we expect the course URLs to be
        site = settings.SITE_NAME
        self.course_url = u'https://{}/courses/{}/'.format(
            site, self.course_key)
        self.course_about_url = self.course_url + 'about'
        self.registration_url = u'https://{}/register'.format(site)
Exemplo n.º 28
0
    def make_ccx(self):
        """
        create ccx
        """
        ccx = CustomCourseForEdX(course_id=self.course.id,
                                 coach=self.coach,
                                 display_name="Test CCX")
        ccx.save()

        ccx_locator = CCXLocator.from_course_locator(self.course.id,
                                                     unicode(ccx.id))
        role = CourseCcxCoachRole(ccx_locator)
        role.add_users(self.coach)
        CourseEnrollment.enroll(self.coach, ccx_locator)
        return ccx_locator
Exemplo n.º 29
0
 def is_enabled(cls, course, user=None):
     """
     Returns true if CCX has been enabled and the specified user is a coach
     """
     if not settings.FEATURES.get('CUSTOM_COURSES_EDX',
                                  False) or not course.enable_ccx:
         # If ccx is not enable do not show ccx coach tab.
         return False
     if has_access(user, 'staff', course) or has_access(
             user, 'instructor', course):
         # if user is staff or instructor then he can always see ccx coach tab.
         return True
     # check if user has coach access.
     role = CourseCcxCoachRole(course.id)
     return role.has_user(user)
Exemplo n.º 30
0
 def setUp(self):
     """
     Set up tests
     """
     super(TestGetEmailParams, self).setUp()
     course = CourseFactory.create()
     coach = AdminFactory.create()
     role = CourseCcxCoachRole(course.id)
     role.add_users(coach)
     self.ccx = CcxFactory(course_id=course.id, coach=coach)
     self.all_keys = [
         'site_name', 'course', 'course_url', 'registration_url',
         'course_about_url', 'auto_enroll'
     ]
     self.url_keys = [k for k in self.all_keys if 'url' in k]
     self.course_keys = [k for k in self.url_keys if 'course' in k]