PLA-749 Fix student dashboard for users enrolled in CCX courses
This commit is contained in:
@@ -557,9 +557,9 @@ class TestGetMembershipTriplets(ModuleStoreTestCase):
|
||||
self.make_ccx_membership()
|
||||
triplets = self.call_fut()
|
||||
self.assertEqual(len(triplets), 1)
|
||||
ccx, membership, course = triplets[0]
|
||||
ccx, membership, course_overview = triplets[0]
|
||||
self.assertEqual(ccx.id, self.ccx.id)
|
||||
self.assertEqual(unicode(course.id), unicode(self.course.id))
|
||||
self.assertEqual(unicode(course_overview.id), unicode(self.course.id))
|
||||
self.assertEqual(membership.student, self.user)
|
||||
|
||||
def test_has_membership_org_filtered(self):
|
||||
|
||||
@@ -16,9 +16,11 @@ from courseware.tests.factories import StudentModuleFactory # pylint: disable=i
|
||||
from courseware.tests.helpers import LoginEnrollmentTestCase # pylint: disable=import-error
|
||||
from courseware.tabs import get_course_tab_list
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.utils.timezone import UTC
|
||||
from django.test.utils import override_settings
|
||||
from django.test import RequestFactory
|
||||
from edxmako.shortcuts import render_to_response # pylint: disable=import-error
|
||||
from student.models import CourseEnrollment
|
||||
from student.roles import CourseCcxCoachRole # pylint: disable=import-error
|
||||
from student.tests.factories import ( # pylint: disable=import-error
|
||||
AdminFactory,
|
||||
@@ -27,6 +29,7 @@ from student.tests.factories import ( # pylint: disable=import-error
|
||||
)
|
||||
|
||||
from xmodule.x_module import XModuleMixin
|
||||
from xmodule.modulestore import ModuleStoreEnum
|
||||
from xmodule.modulestore.tests.django_utils import (
|
||||
ModuleStoreTestCase,
|
||||
TEST_DATA_SPLIT_MODULESTORE)
|
||||
@@ -655,6 +658,43 @@ class CCXCoachTabTestCase(ModuleStoreTestCase):
|
||||
)
|
||||
|
||||
|
||||
class TestStudentDashboardWithCCX(ModuleStoreTestCase):
|
||||
"""
|
||||
Test to ensure that the student dashboard works for users enrolled in CCX
|
||||
courses.
|
||||
"""
|
||||
|
||||
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 = "foobar"
|
||||
self.student = UserFactory.create(username="test", 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().
|
||||
CcxMembershipFactory(ccx=self.ccx, student=self.student, active=True)
|
||||
|
||||
def test_load_student_dashboard(self):
|
||||
self.client.login(username=self.student.username, password=self.student_password)
|
||||
response = self.client.get(reverse('dashboard'))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
|
||||
def flatten(seq):
|
||||
"""
|
||||
For [[1, 2], [3, 4]] returns [1, 2, 3, 4]. Does not recurse.
|
||||
|
||||
@@ -10,6 +10,7 @@ from django.core.urlresolvers import reverse
|
||||
from django.core.mail import send_mail
|
||||
from edxmako.shortcuts import render_to_string # pylint: disable=import-error
|
||||
from microsite_configuration import microsite # pylint: disable=import-error
|
||||
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.error_module import ErrorDescriptor
|
||||
from ccx_keys.locator import CCXLocator
|
||||
@@ -240,38 +241,46 @@ def send_mail_to_student(student, param_dict):
|
||||
|
||||
def get_ccx_membership_triplets(user, course_org_filter, org_filter_out_set):
|
||||
"""
|
||||
Get the relevant set of (CustomCourseForEdX, CcxMembership, Course)
|
||||
Get the relevant set of (CustomCourseForEdX, CcxMembership, CourseOverview)
|
||||
triplets to be displayed on a student's dashboard.
|
||||
"""
|
||||
error_message_format = "User {0} enrolled in {2} course {1}"
|
||||
|
||||
# only active memberships for now
|
||||
for membership in CcxMembership.memberships_for_user(user):
|
||||
ccx = membership.ccx
|
||||
store = modulestore()
|
||||
with store.bulk_operations(ccx.course_id):
|
||||
course = store.get_course(ccx.course_id)
|
||||
if course and not isinstance(course, ErrorDescriptor):
|
||||
# if we are in a Microsite, then filter out anything that is not
|
||||
# attributed (by ORG) to that Microsite
|
||||
if course_org_filter and course_org_filter != course.location.org:
|
||||
continue
|
||||
# Conversely, if we are not in a Microsite, then let's filter out any enrollments
|
||||
# with courses attributed (by ORG) to Microsites
|
||||
elif course.location.org in org_filter_out_set:
|
||||
continue
|
||||
|
||||
# If, somehow, we've got a ccx that has been created for a
|
||||
# course with a deprecated ID, we must filter it out. Emit a
|
||||
# warning to the log so we can clean up.
|
||||
if course.location.deprecated:
|
||||
log.warning(
|
||||
"CCX %s exists for course %s with deprecated id",
|
||||
ccx,
|
||||
ccx.course_id
|
||||
)
|
||||
continue
|
||||
try:
|
||||
course_overview = CourseOverview.get_from_id(ccx.course_id)
|
||||
except CourseOverview.DoesNotExist:
|
||||
log.error(error_message_format.format( # pylint: disable=logging-format-interpolation
|
||||
user.username, ccx.course_id, "non-existent"
|
||||
))
|
||||
continue
|
||||
except IOError:
|
||||
log.error(error_message_format.format( # pylint: disable=logging-format-interpolation
|
||||
user.username, ccx.course_id, "broken"
|
||||
))
|
||||
continue
|
||||
|
||||
yield (ccx, membership, course)
|
||||
else:
|
||||
log.error("User {0} enrolled in {2} course {1}".format( # pylint: disable=logging-format-interpolation
|
||||
user.username, ccx.course_id, "broken" if course else "non-existent"
|
||||
))
|
||||
# if we are in a Microsite, then filter out anything that is not
|
||||
# attributed (by ORG) to that Microsite
|
||||
if course_org_filter and course_org_filter != course_overview.location.org:
|
||||
continue
|
||||
# Conversely, if we are not in a Microsite, then let's filter out any enrollments
|
||||
# with courses attributed (by ORG) to Microsites
|
||||
elif course_overview.location.org in org_filter_out_set:
|
||||
continue
|
||||
|
||||
# If, somehow, we've got a ccx that has been created for a
|
||||
# course with a deprecated ID, we must filter it out. Emit a
|
||||
# warning to the log so we can clean up.
|
||||
if course_overview.location.deprecated:
|
||||
log.warning(
|
||||
"CCX %s exists for course %s with deprecated id",
|
||||
ccx,
|
||||
ccx.course_id
|
||||
)
|
||||
continue
|
||||
|
||||
yield (ccx, membership, course_overview)
|
||||
|
||||
@@ -42,7 +42,7 @@ from ccx_keys.locator import CCXLocator
|
||||
% endif
|
||||
</h3>
|
||||
<div class="course-info">
|
||||
<span class="info-university">${get_course_about_section(course, 'university')} - </span>
|
||||
<span class="info-university">${get_course_about_section(course_overview, 'university')} - </span>
|
||||
<span class="info-course-id">${course_overview.display_number_with_default | h}</span>
|
||||
<span class="info-date-block" data-tooltip="Hi">
|
||||
% if ccx.has_ended():
|
||||
|
||||
@@ -88,10 +88,10 @@ from django.core.urlresolvers import reverse
|
||||
% endfor
|
||||
|
||||
% if settings.FEATURES.get('CUSTOM_COURSES_EDX', False):
|
||||
% for ccx, membership, course in ccx_membership_triplets:
|
||||
% for ccx, membership, course_overview in ccx_membership_triplets:
|
||||
<% show_courseware_link = ccx.has_started() %>
|
||||
<% is_course_blocked = False %>
|
||||
<%include file='ccx/_dashboard_ccx_listing.html' args="ccx=ccx, membership=membership, course_overview=enrollment.course_overview, show_courseware_link=show_courseware_link, is_course_blocked=is_course_blocked" />
|
||||
<%include file='ccx/_dashboard_ccx_listing.html' args="ccx=ccx, membership=membership, course_overview=course_overview, show_courseware_link=show_courseware_link, is_course_blocked=is_course_blocked" />
|
||||
% endfor
|
||||
% endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user