diff --git a/lms/djangoapps/courseware/access_response.py b/lms/djangoapps/courseware/access_response.py index 323a8c8f64..abfdf61db2 100644 --- a/lms/djangoapps/courseware/access_response.py +++ b/lms/djangoapps/courseware/access_response.py @@ -144,33 +144,6 @@ class StartDateError(AccessError): ) -class StartDateEnterpriseLearnerError(AccessError): - """ - Access denied because the course has not started yet and the user is not staff. Use this error when this user is - also an enterprise learner and enrolled in the requested course. - """ - def __init__(self, start_date, display_error_to_user=True): - """ - Arguments: - display_error_to_user: If True, display this error to users in the UI. - """ - error_code = "course_not_started_enterprise_learner" - if start_date == DEFAULT_START_DATE: - developer_message = "Course has not started, and the learner is enrolled via an enterprise subsidy." - user_message = _("Course has not started") - else: - developer_message = ( - f"Course does not start until {start_date}, and the learner is enrolled via an enterprise subsidy." - ) - user_message = _("Course does not start until {}" # lint-amnesty, pylint: disable=translation-of-non-string - .format(f"{start_date:%B %d, %Y}")) - super().__init__( - error_code, - developer_message, - user_message if display_error_to_user else None - ) - - class MilestoneAccessError(AccessError): """ Access denied because the user has unfulfilled milestones diff --git a/lms/djangoapps/courseware/access_utils.py b/lms/djangoapps/courseware/access_utils.py index 9c0bee9996..6e5699f4e2 100644 --- a/lms/djangoapps/courseware/access_utils.py +++ b/lms/djangoapps/courseware/access_utils.py @@ -20,7 +20,6 @@ from lms.djangoapps.courseware.access_response import ( DataSharingConsentRequiredAccessError, EnrollmentRequiredAccessError, IncorrectActiveEnterpriseAccessError, - StartDateEnterpriseLearnerError, StartDateError ) from lms.djangoapps.courseware.masquerade import get_course_masquerade, is_masquerading_as_student @@ -76,7 +75,6 @@ def check_start_date(user, days_early_for_beta, start, course_key, display_error Returns: AccessResponse: Either ACCESS_GRANTED or StartDateError. """ - from openedx.features.enterprise_support.api import enterprise_customer_from_session_or_learner_data start_dates_disabled = settings.FEATURES['DISABLE_START_DATES'] masquerading_as_student = is_masquerading_as_student(user, course_key) @@ -94,30 +92,6 @@ def check_start_date(user, days_early_for_beta, start, course_key, display_error if should_grant_access: return ACCESS_GRANTED - # Before returning a StartDateError, determine if the learner should be redirected to the enterprise learner - # portal by returning StartDateEnterpriseLearnerError instead. - if user.is_authenticated: - # enterprise_customer_data is either None (if learner is not linked to any customer) or a serialized - # EnterpriseCustomer representing the learner's active linked customer. - enterprise_customer_data = enterprise_customer_from_session_or_learner_data(get_current_request()) - learner_portal_enabled = enterprise_customer_data and enterprise_customer_data['enable_learner_portal'] - if learner_portal_enabled: - # Additionally make sure the enterprise learner is actually enrolled in the requested course, subsidized - # via the discovered customer. - enterprise_enrollments = EnterpriseCourseEnrollment.objects.filter( - course_id=course_key, - enterprise_customer_user__user_id=user.id, - enterprise_customer_user__enterprise_customer__uuid=enterprise_customer_data['uuid'], - ) - if enterprise_enrollments.exists(): - # Finally, we have established: - # * The learner is linked to an enterprise customer, - # * The enterprise customer has subsidized the learner's enrollment in the requested course, - # * The enterprise customer has the learner portal enabled. - # - # We are now safe to kick the learner over to the enterprise learner dashboard. - return StartDateEnterpriseLearnerError(start, display_error_to_user=display_error_to_user) - return StartDateError(start, display_error_to_user=display_error_to_user) diff --git a/lms/djangoapps/courseware/tests/test_access.py b/lms/djangoapps/courseware/tests/test_access.py index b4101a94d8..ba93ec6762 100644 --- a/lms/djangoapps/courseware/tests/test_access.py +++ b/lms/djangoapps/courseware/tests/test_access.py @@ -57,14 +57,6 @@ from xmodule.modulestore.tests.django_utils import ( # lint-amnesty, pylint: di ) from xmodule.modulestore.tests.factories import CourseFactory, BlockFactory # lint-amnesty, pylint: disable=wrong-import-order from xmodule.partitions.partitions import MINIMUM_STATIC_PARTITION_ID, Group, UserPartition # lint-amnesty, pylint: disable=wrong-import-order -from openedx.features.enterprise_support.api import add_enterprise_customer_to_session -from enterprise.api.v1.serializers import EnterpriseCustomerSerializer -from openedx.features.enterprise_support.tests.factories import ( - EnterpriseCourseEnrollmentFactory, - EnterpriseCustomerUserFactory, - EnterpriseCustomerFactory -) -from crum import set_current_request QUERY_COUNT_TABLE_IGNORELIST = WAFFLE_TABLES @@ -855,7 +847,7 @@ class CourseOverviewAccessTestCase(ModuleStoreTestCase): ) @ddt.unpack @patch.dict('django.conf.settings.FEATURES', {'DISABLE_START_DATES': False}) - def test_course_catalog_access_num_queries_no_enterprise(self, user_attr_name, action, course_attr_name): + def test_course_catalog_access_num_queries(self, user_attr_name, action, course_attr_name): ContentTypeGatingConfig.objects.create(enabled=True, enabled_as_of=datetime.datetime(2018, 1, 1)) course = getattr(self, course_attr_name) @@ -894,71 +886,3 @@ class CourseOverviewAccessTestCase(ModuleStoreTestCase): course_overview = CourseOverview.get_from_id(course.id) with self.assertNumQueries(num_queries, table_ignorelist=QUERY_COUNT_TABLE_IGNORELIST): bool(access.has_access(user, action, course_overview, course_key=course.id)) - - @ddt.data( - *itertools.product( - ['user_normal', 'user_staff', 'user_anonymous'], - ['course_started', 'course_not_started'], - ) - ) - @ddt.unpack - @patch.dict('django.conf.settings.FEATURES', {'DISABLE_START_DATES': False, 'ENABLE_ENTERPRISE_INTEGRATION': True}) - def test_course_catalog_access_num_queries_enterprise(self, user_attr_name, course_attr_name): - """ - Similar to test_course_catalog_access_num_queries_no_enterprise, except enable enterprise features and make the - basic enrollment look like an enterprise-subsidized enrollment, setting up one of each: - - * EnterpriseCustomer - * EnterpriseCustomerUser - * EnterpriseCourseEnrollment - * A mock request session to pre-cache the enterprise customer data. - """ - ContentTypeGatingConfig.objects.create(enabled=True, enabled_as_of=datetime.datetime(2018, 1, 1)) - - course = getattr(self, course_attr_name) - - request = RequestFactory().get('/') - request.session = {} - - # get a fresh user object that won't have any cached role information - if user_attr_name == 'user_anonymous': - user = AnonymousUserFactory() - request.user = user - else: - user = getattr(self, user_attr_name) - user = User.objects.get(id=user.id) - request.user = user - course_enrollment = CourseEnrollmentFactory(user=user, course_id=course.id) - enterprise_customer = EnterpriseCustomerFactory(enable_learner_portal=True) - add_enterprise_customer_to_session(request, EnterpriseCustomerSerializer(enterprise_customer).data) - enterprise_customer_user = EnterpriseCustomerUserFactory( - user_id=user.id, - enterprise_customer=enterprise_customer, - ) - EnterpriseCourseEnrollmentFactory(enterprise_customer_user=enterprise_customer_user, course_id=course.id) - set_current_request(request) - - if user_attr_name == 'user_staff': - if course_attr_name == 'course_started': - # read: CourseAccessRole + django_comment_client.Role - num_queries = 2 - else: - # read: CourseAccessRole + EnterpriseCourseEnrollment - num_queries = 2 - elif user_attr_name == 'user_normal': - if course_attr_name == 'course_started': - # read: CourseAccessRole + django_comment_client.Role + FBEEnrollmentExclusion + CourseMode - num_queries = 4 - else: - # read: CourseAccessRole + CourseEnrollmentAllowed + EnterpriseCourseEnrollment - num_queries = 3 - elif user_attr_name == 'user_anonymous': - if course_attr_name == 'course_started': - # read: CourseMode - num_queries = 1 - else: - num_queries = 0 - - course_overview = CourseOverview.get_from_id(course.id) - with self.assertNumQueries(num_queries, table_ignorelist=QUERY_COUNT_TABLE_IGNORELIST): - bool(access.has_access(user, 'see_exists', course_overview, course_key=course.id)) diff --git a/lms/djangoapps/courseware/tests/test_views.py b/lms/djangoapps/courseware/tests/test_views.py index 6d991d181e..e170e85766 100644 --- a/lms/djangoapps/courseware/tests/test_views.py +++ b/lms/djangoapps/courseware/tests/test_views.py @@ -110,14 +110,7 @@ from openedx.features.course_experience.url_helpers import ( get_learning_mfe_home_url, make_learning_mfe_courseware_url ) -from openedx.features.enterprise_support.tests.factories import ( - EnterpriseCourseEnrollmentFactory, - EnterpriseCustomerUserFactory, - EnterpriseCustomerFactory -) from openedx.features.enterprise_support.tests.mixins.enterprise import EnterpriseTestConsentRequired -from openedx.features.enterprise_support.api import add_enterprise_customer_to_session -from enterprise.api.v1.serializers import EnterpriseCustomerSerializer QUERY_COUNT_TABLE_IGNORELIST = WAFFLE_TABLES @@ -3230,70 +3223,17 @@ class AccessUtilsTestCase(ModuleStoreTestCase): Test access utilities """ @ddt.data( - { - 'start_date_modifier': 1, # course starts in future - 'setup_enterprise_enrollment': False, - 'expected_has_access': False, - 'expected_error_code': 'course_not_started', - }, - { - 'start_date_modifier': -1, # course already started - 'setup_enterprise_enrollment': False, - 'expected_has_access': True, - 'expected_error_code': None, - }, - { - 'start_date_modifier': 1, # course starts in future - 'setup_enterprise_enrollment': True, - 'expected_has_access': False, - 'expected_error_code': 'course_not_started_enterprise_learner', - }, - { - 'start_date_modifier': -1, # course already started - 'setup_enterprise_enrollment': True, - 'expected_has_access': True, - 'expected_error_code': None, - }, + (1, False), + (-1, True) ) @ddt.unpack - @patch.dict('django.conf.settings.FEATURES', {'DISABLE_START_DATES': False, 'ENABLE_ENTERPRISE_INTEGRATION': True}) - def test_is_course_open_for_learner( - self, - start_date_modifier, - setup_enterprise_enrollment, - expected_has_access, - expected_error_code, - ): - """ - Test is_course_open_for_learner(). - - When setup_enterprise_enrollment == True, make an enterprise-subsidized enrollment, setting up one of each: - * CourseEnrollment - * EnterpriseCustomer - * EnterpriseCustomerUser - * EnterpriseCourseEnrollment - * A mock request session to pre-cache the enterprise customer data. - """ + @patch.dict('django.conf.settings.FEATURES', {'DISABLE_START_DATES': False}) + def test_is_course_open_for_learner(self, start_date_modifier, expected_value): staff_user = AdminFactory() start_date = datetime.now(UTC) + timedelta(days=start_date_modifier) course = CourseFactory.create(start=start_date) - request = RequestFactory().get('/') - request.user = staff_user - request.session = {} - if setup_enterprise_enrollment: - course_enrollment = CourseEnrollmentFactory(mode=CourseMode.VERIFIED, user=staff_user, course_id=course.id) - enterprise_customer = EnterpriseCustomerFactory(enable_learner_portal=True) - add_enterprise_customer_to_session(request, EnterpriseCustomerSerializer(enterprise_customer).data) - enterprise_customer_user = EnterpriseCustomerUserFactory( - user_id=staff_user.id, - enterprise_customer=enterprise_customer, - ) - EnterpriseCourseEnrollmentFactory(enterprise_customer_user=enterprise_customer_user, course_id=course.id) - set_current_request(request) - access_response = check_course_open_for_learner(staff_user, course) - assert bool(access_response) == expected_has_access - assert access_response.error_code == expected_error_code + assert bool(check_course_open_for_learner(staff_user, course)) == expected_value class DatesTabTestCase(TestCase):