Skip to content
Snippets Groups Projects
Commit 33fab4b1 authored by noraiz-anwar's avatar noraiz-anwar Committed by Noraiz Anwar
Browse files

audit track content gating for staff preview

parent f9a7295a
No related branches found
No related tags found
No related merge requests found
......@@ -9,13 +9,19 @@ import logging
import crum
from django.apps import apps
from django.conf import settings
from django.template.loader import render_to_string
from django.utils.translation import ugettext_lazy as _
from web_fragments.fragment import Fragment
from course_modes.models import CourseMode
from courseware.masquerade import (
is_masquerading_as_specific_student,
is_masquerading_as_student,
get_course_masquerade,
)
from lms.djangoapps.commerce.utils import EcommerceService
from xmodule.partitions.partitions import UserPartition, UserPartitionError
from xmodule.partitions.partitions import UserPartition, UserPartitionError, ENROLLMENT_TRACK_PARTITION_ID
from openedx.core.lib.mobile_utils import is_request_from_mobile_app
from openedx.features.content_type_gating.models import ContentTypeGatingConfig
from openedx.features.content_type_gating.helpers import CONTENT_GATING_PARTITION_ID, FULL_ACCESS, LIMITED_ACCESS
......@@ -73,7 +79,8 @@ class ContentTypeGatingPartition(UserPartition):
to gated content.
"""
def access_denied_fragment(self, block, user, user_group, allowed_groups):
modes = CourseMode.modes_for_course_dict(block.scope_ids.usage_id.course_key)
course_key = self._get_course_key_from_course_block(block)
modes = CourseMode.modes_for_course_dict(course_key)
verified_mode = modes.get(CourseMode.VERIFIED)
if verified_mode is None or not self._is_audit_enrollment(user, block):
return None
......@@ -93,8 +100,41 @@ class ContentTypeGatingPartition(UserPartition):
return None
def _is_audit_enrollment(self, user, block):
"""
Checks if user is enrolled in `Audit` track of course or any staff member is
viewing course as in `Audit` enrollment.
"""
course_key = self._get_course_key_from_course_block(block)
if self._is_masquerading_as_generic_student(user, course_key):
return self._is_masquerading_audit_enrollment(user, course_key)
return self._has_active_enrollment_in_audit_mode(user, course_key)
def _is_masquerading_as_generic_student(self, user, course_key):
"""
Checks if user is masquerading as a generic student.
"""
return (
is_masquerading_as_student(user, course_key) and
not is_masquerading_as_specific_student(user, course_key)
)
def _is_masquerading_audit_enrollment(self, user, course_key):
"""
Checks if user is masquerading as learners in `Audit` enrollment track.
"""
course_masquerade = get_course_masquerade(user, course_key)
if course_masquerade.user_partition_id == ENROLLMENT_TRACK_PARTITION_ID:
audit_mode_id = settings.COURSE_ENROLLMENT_MODES.get(CourseMode.AUDIT, {}).get('id')
return course_masquerade.group_id == audit_mode_id
return False
def _has_active_enrollment_in_audit_mode(self, user, course_key):
"""
Checks if user has an audit and active enrollment in the given course.
"""
course_enrollment = apps.get_model('student.CourseEnrollment')
mode_slug, is_active = course_enrollment.enrollment_mode_for_user(user, block.scope_ids.usage_id.course_key)
mode_slug, is_active = course_enrollment.enrollment_mode_for_user(user, course_key)
return mode_slug == CourseMode.AUDIT and is_active
def _get_checkout_link(self, user, sku):
......@@ -103,6 +143,12 @@ class ContentTypeGatingPartition(UserPartition):
if ecommerce_checkout and sku:
return ecomm_service.get_checkout_page_url(sku) or ''
def _get_course_key_from_course_block(self, block):
"""
Extracts and returns `course_key` from `block`
"""
return block.scope_ids.usage_id.course_key
class ContentTypeGatingPartitionScheme(object):
"""
......
from datetime import datetime
from mock import Mock, patch
from django.conf import settings
from django.test import RequestFactory
from courseware.masquerade import CourseMasquerade
from course_modes.tests.factories import CourseModeFactory
from lms.djangoapps.courseware.tests.factories import GlobalStaffFactory
from opaque_keys.edx.keys import CourseKey
from openedx.core.djangolib.testing.utils import CacheIsolationTestCase
from openedx.features.content_type_gating.helpers import CONTENT_GATING_PARTITION_ID
from openedx.features.content_type_gating.partitions import create_content_gating_partition
from openedx.features.content_type_gating.partitions import (
create_content_gating_partition,
ContentTypeGatingPartition
)
from openedx.features.content_type_gating.models import ContentTypeGatingConfig
from xmodule.partitions.partitions import UserPartitionError
from xmodule.partitions.partitions import UserPartitionError, ENROLLMENT_TRACK_PARTITION_ID
class TestContentTypeGatingPartition(CacheIsolationTestCase):
......@@ -53,3 +61,38 @@ class TestContentTypeGatingPartition(CacheIsolationTestCase):
partition = create_content_gating_partition(mock_course)
mock_log.warning.assert_called()
self.assertIsNone(partition)
def test_access_denied_fragment_for_masquerading(self):
"""
Test that a global staff sees gated content flag when viewing course as `Learner in Audit`
Note: Global staff doesn't require to be enrolled in course.
"""
mock_request = RequestFactory().get('/')
mock_course = Mock(id=self.course_key, user_partitions={})
mock_block = Mock(scope_ids=Mock(usage_id=Mock(course_key=mock_course.id)))
mock_course_masquerade = Mock(
role='student',
user_partition_id=ENROLLMENT_TRACK_PARTITION_ID,
group_id=settings.COURSE_ENROLLMENT_MODES['audit']['id'],
user_name=None
)
CourseModeFactory.create(course_id=mock_course.id, mode_slug='verified')
global_staff = GlobalStaffFactory.create()
ContentTypeGatingConfig.objects.create(enabled=False, studio_override_enabled=True)
partition = create_content_gating_partition(mock_course)
with patch(
'courseware.masquerade.get_course_masquerade',
return_value=mock_course_masquerade
), patch(
'openedx.features.content_type_gating.partitions.get_course_masquerade',
return_value=mock_course_masquerade
), patch(
'crum.get_current_request',
return_value=mock_request
):
fragment = partition.access_denied_fragment(mock_block, global_staff, 'test_group', 'test_allowed_group')
self.assertIsNotNone(fragment)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment