Skip to content
Snippets Groups Projects
Commit a5e55912 authored by Dave St.Germain's avatar Dave St.Germain
Browse files

Automatically add master's to the group access of verified content

parent d378260d
No related branches found
No related tags found
No related merge requests found
""" Helper methods for CourseModes. """
from __future__ import absolute_import, unicode_literals
import logging
from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from course_modes.models import CourseMode
from student.helpers import VERIFY_STATUS_APPROVED, VERIFY_STATUS_NEED_TO_VERIFY, VERIFY_STATUS_SUBMITTED
from xmodule.partitions.partitions import ENROLLMENT_TRACK_PARTITION_ID
DISPLAY_VERIFIED = "verified"
DISPLAY_HONOR = "honor"
DISPLAY_AUDIT = "audit"
DISPLAY_PROFESSIONAL = "professional"
MASTERS_ID = settings.COURSE_ENROLLMENT_MODES.get('masters', {}).get('id', None)
VERIFIED_ID = settings.COURSE_ENROLLMENT_MODES['verified']['id']
log = logging.getLogger(__name__)
def enrollment_mode_display(mode, verification_status, course_id):
""" Select appropriate display strings and CSS classes.
......@@ -80,3 +91,31 @@ def _enrollment_mode_display(enrollment_mode, verification_status, course_id):
display_mode = enrollment_mode
return display_mode
def update_masters_access(item):
"""
Update the XBlock's group access to allow the master's group,
in addition to the verified content group.
"""
group_access = item.group_access
enrollment_groups = group_access.get(ENROLLMENT_TRACK_PARTITION_ID, None)
if enrollment_groups is not None:
if VERIFIED_ID in enrollment_groups and MASTERS_ID not in enrollment_groups:
enrollment_groups.append(MASTERS_ID)
item.group_access = group_access
return True
def update_masters_access_course(store, course_id, user_id):
"""
Update all blocks in the verified content group to include the master's content group
"""
with store.bulk_operations(course_id):
items = store.get_items(course_id, settings={'group_access': {'$exists': True}}, include_orphans=False)
for item in items:
if update_masters_access(item):
log.info("Publishing %s with Master's group access", item.location)
store.update_item(item, user_id)
store.publish(item.location, user_id)
"""
Signal handler for setting default course mode expiration dates
"""
from __future__ import absolute_import, unicode_literals
from crum import get_current_user
from django.core.exceptions import ObjectDoesNotExist
from django.db.models.signals import post_save
from django.dispatch.dispatcher import receiver
from xmodule.modulestore.django import SignalHandler, modulestore
from .helpers import update_masters_access_course
from .models import CourseMode, CourseModeExpirationConfig
......@@ -35,3 +41,15 @@ def _listen_for_course_publish(sender, course_key, **kwargs): # pylint: disable
def _should_update_date(verified_mode):
""" Returns whether or not the verified mode should be updated. """
return not(verified_mode is None or verified_mode.expiration_datetime_is_explicit)
@receiver(post_save, sender=CourseMode)
def update_access_for_masters_mode(sender, instance=None, **kwargs): # pylint: disable=unused-argument
"""
Adds master's access to verified content when the master's mode is created
"""
if instance.mode_slug != CourseMode.MASTERS:
return
user = get_current_user()
user_id = user.id if user else None
update_masters_access_course(modulestore(), instance.course_id, user_id)
"""
Unit tests for the course_mode signals
"""
from __future__ import absolute_import, unicode_literals
from datetime import datetime, timedelta
......@@ -10,8 +11,9 @@ from pytz import UTC
from course_modes.models import CourseMode
from course_modes.signals import _listen_for_course_publish
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
@ddt.ddt
......@@ -87,3 +89,28 @@ class CourseModeSignalTest(ModuleStoreTestCase):
course_mode.refresh_from_db()
self.assertEqual(course_mode.expiration_datetime, self.end - timedelta(days=verification_window))
def test_masters_mode(self):
# create an xblock with verified group access
verified_section = ItemFactory.create(
category="sequential",
metadata={'group_access': {50: [2]}}
)
# and a section with no restriction
section2 = ItemFactory.create(
category="sequential",
)
section3 = ItemFactory.create(
category='sequential',
metadata={'group_access': {50: [1]}}
)
with self.store.branch_setting(ModuleStoreEnum.Branch.draft_preferred):
# create the master's mode. signal will add masters to the verified section
self.create_mode('masters', 'masters')
verified_section_ret = self.store.get_item(verified_section.location)
section2_ret = self.store.get_item(section2.location)
section3_ret = self.store.get_item(section3.location)
# group 2 is verified. 7 is masters
assert verified_section_ret.group_access[50] == [2, 7]
assert section2_ret.group_access == {}
assert section2_ret.group_access == {50: [1]}
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