From 6443070901989c0b50273b35009c2038615f29eb Mon Sep 17 00:00:00 2001 From: Amir Qayyum Khan Date: Mon, 28 Dec 2015 17:58:46 +0500 Subject: [PATCH] Hide register to course page from student, so that only coach can invite students to join ccx --- lms/djangoapps/courseware/tests/test_about.py | 46 ++++++++++++++++++- .../courseware/tests/test_course_info.py | 46 ++++++++++++++++++- lms/djangoapps/courseware/views.py | 16 ++++++- 3 files changed, 104 insertions(+), 4 deletions(-) diff --git a/lms/djangoapps/courseware/tests/test_about.py b/lms/djangoapps/courseware/tests/test_about.py index fb457e079d..dd29ae866a 100644 --- a/lms/djangoapps/courseware/tests/test_about.py +++ b/lms/djangoapps/courseware/tests/test_about.py @@ -4,6 +4,7 @@ Test the about xblock import datetime import pytz +from ccx_keys.locator import CCXLocator from django.conf import settings from django.core.urlresolvers import reverse from django.test.utils import override_settings @@ -16,10 +17,14 @@ from track.tests import EventTrackingTestCase from xmodule.modulestore.tests.django_utils import TEST_DATA_MIXED_CLOSED_MODULESTORE from student.models import CourseEnrollment -from student.tests.factories import UserFactory, CourseEnrollmentAllowedFactory +from student.tests.factories import AdminFactory, CourseEnrollmentAllowedFactory, UserFactory from shoppingcart.models import Order, PaidCourseRegistration from xmodule.course_module import CATALOG_VISIBILITY_ABOUT, CATALOG_VISIBILITY_NONE -from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase +from xmodule.modulestore.tests.django_utils import ( + ModuleStoreTestCase, + SharedModuleStoreTestCase, + TEST_DATA_SPLIT_MODULESTORE +) from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory from util.milestones_helpers import ( set_prerequisite_courses, @@ -27,6 +32,7 @@ from util.milestones_helpers import ( get_prerequisite_courses_display, ) +from lms.djangoapps.ccx.tests.factories import CcxFactory from .helpers import LoginEnrollmentTestCase # HTML for registration button @@ -567,3 +573,39 @@ class AboutPurchaseCourseTestCase(LoginEnrollmentTestCase, ModuleStoreTestCase): self.assertEqual(resp.status_code, 200) self.assertNotIn("Add free to Cart (Free)", resp.content) self.assertNotIn('

Price

', resp.content) + + +class CourseAboutTestCaseCCX(SharedModuleStoreTestCase, LoginEnrollmentTestCase): + """ + Test for unenrolled student tries to access ccx. + Note: Only CCX coach can enroll a student in CCX. In sum self-registration not allowed. + """ + MODULESTORE = TEST_DATA_SPLIT_MODULESTORE + + @classmethod + def setUpClass(cls): + super(CourseAboutTestCaseCCX, cls).setUpClass() + cls.course = CourseFactory.create() + + def setUp(self): + super(CourseAboutTestCaseCCX, self).setUp() + + # Create ccx coach account + self.coach = coach = AdminFactory.create(password="test") + self.client.login(username=coach.username, password="test") + + def test_redirect_to_dashboard_unenrolled_ccx(self): + """ + Assert that when unenrolled user tries to access CCX do not allow the user to self-register. + Redirect him to his student dashboard + """ + + # create ccx + ccx = CcxFactory(course_id=self.course.id, coach=self.coach) + ccx_locator = CCXLocator.from_course_locator(self.course.id, unicode(ccx.id)) + + self.setup_user() + url = reverse('info', args=[ccx_locator]) + response = self.client.get(url) + expected = reverse('dashboard') + self.assertRedirects(response, expected, status_code=302, target_status_code=200) diff --git a/lms/djangoapps/courseware/tests/test_course_info.py b/lms/djangoapps/courseware/tests/test_course_info.py index 1c9217d495..a67bc96fca 100644 --- a/lms/djangoapps/courseware/tests/test_course_info.py +++ b/lms/djangoapps/courseware/tests/test_course_info.py @@ -5,19 +5,27 @@ import mock from nose.plugins.attrib import attr from urllib import urlencode +from ccx_keys.locator import CCXLocator from django.conf import settings from django.core.urlresolvers import reverse from django.test.utils import override_settings from opaque_keys.edx.locations import SlashSeparatedCourseKey from util.date_utils import strftime_localized -from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase, SharedModuleStoreTestCase +from xmodule.modulestore.tests.django_utils import ( + ModuleStoreTestCase, + SharedModuleStoreTestCase, + TEST_DATA_SPLIT_MODULESTORE +) from xmodule.modulestore.tests.django_utils import TEST_DATA_MIXED_CLOSED_MODULESTORE from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory, check_mongo_calls from student.models import CourseEnrollment +from student.tests.factories import AdminFactory from .helpers import LoginEnrollmentTestCase +from lms.djangoapps.ccx.tests.factories import CcxFactory + @attr('shard_1') class CourseInfoTestCase(LoginEnrollmentTestCase, ModuleStoreTestCase): @@ -85,6 +93,42 @@ class CourseInfoTestCase(LoginEnrollmentTestCase, ModuleStoreTestCase): self.assertEqual(response.status_code, 404) +class CourseInfoTestCaseCCX(SharedModuleStoreTestCase, LoginEnrollmentTestCase): + """ + Test for unenrolled student tries to access ccx. + Note: Only CCX coach can enroll a student in CCX. In sum self-registration not allowed. + """ + + MODULESTORE = TEST_DATA_SPLIT_MODULESTORE + + @classmethod + def setUpClass(cls): + super(CourseInfoTestCaseCCX, cls).setUpClass() + cls.course = CourseFactory.create() + + def setUp(self): + super(CourseInfoTestCaseCCX, self).setUp() + + # Create ccx coach account + self.coach = coach = AdminFactory.create(password="test") + self.client.login(username=coach.username, password="test") + + def test_redirect_to_dashboard_unenrolled_ccx(self): + """ + Assert that when unenroll student tries to access ccx do not allow him self-register. + Redirect him to his student dashboard + """ + # create ccx + ccx = CcxFactory(course_id=self.course.id, coach=self.coach) + ccx_locator = CCXLocator.from_course_locator(self.course.id, unicode(ccx.id)) + + self.setup_user() + url = reverse('info', args=[ccx_locator]) + response = self.client.get(url) + expected = reverse('dashboard') + self.assertRedirects(response, expected, status_code=302, target_status_code=200) + + @attr('shard_1') class CourseInfoTestCaseXML(LoginEnrollmentTestCase, ModuleStoreTestCase): """ diff --git a/lms/djangoapps/courseware/views.py b/lms/djangoapps/courseware/views.py index 18ec8a05c5..fd9368db90 100644 --- a/lms/djangoapps/courseware/views.py +++ b/lms/djangoapps/courseware/views.py @@ -686,6 +686,14 @@ def course_info(request, course_id): staff_access = has_access(request.user, 'staff', course) masquerade, user = setup_masquerade(request, course_key, staff_access, reset_masquerade_data=True) + # if user is not enrolled in a course then app will show enroll/get register link inside course info page. + show_enroll_banner = request.user.is_authenticated() and not CourseEnrollment.is_enrolled(user, course.id) + if show_enroll_banner and hasattr(course_key, 'ccx'): + # if course is CCX and user is not enrolled/registered then do not let him open course direct via link for + # self registration. Because only CCX coach can register/enroll a student. If un-enrolled user try + # to access CCX redirect him to dashboard. + return redirect(reverse('dashboard')) + # If the user needs to take an entrance exam to access this course, then we'll need # to send them to that specific course module before allowing them into other areas if user_must_complete_entrance_exam(request, user, course): @@ -704,7 +712,6 @@ def course_info(request, course_id): if settings.FEATURES.get('ENABLE_MKTG_SITE'): url_to_enroll = marketing_link('COURSES') - show_enroll_banner = request.user.is_authenticated() and not CourseEnrollment.is_enrolled(user, course.id) context = { 'request': request, 'masquerade_user': user, @@ -822,6 +829,13 @@ def course_about(request, course_id): course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id) + if hasattr(course_key, 'ccx'): + # if un-enrolled/non-registered user try to access CCX (direct for registration) + # then do not show him about page to avoid self registration. + # Note: About page will only be shown to user who is not register. So that he can register. But for + # CCX only CCX coach can enroll students. + return redirect(reverse('dashboard')) + with modulestore().bulk_operations(course_key): permission = get_permission_for_course_about() course = get_course_with_access(request.user, permission, course_key)