Add credit modein support enrollment tool.

Currently, enrollment support tool is only allowing support members
to change course enrollment only one of the two modes i.e. audit and
verified.To move a learner other than these modes,they need to ping
devops.To broaden the scope of enrollment support tool,changes have
been done so that enrollment would be changed to other modes as well.

PROD-305
This commit is contained in:
uzairr
2019-07-17 15:39:03 +05:00
parent f293b74fca
commit 07821927e2
3 changed files with 45 additions and 30 deletions

View File

@@ -333,7 +333,9 @@ class CourseMode(models.Model):
@classmethod
@request_cached(CACHE_NAMESPACE)
def modes_for_course(cls, course_id=None, include_expired=False, only_selectable=True, course=None):
def modes_for_course(
cls, course_id=None, include_expired=False, only_selectable=True, course=None, exclude_credit=True
):
"""
Returns a list of the non-expired modes for a given course id
@@ -384,7 +386,7 @@ class CourseMode(models.Model):
if only_selectable:
if course is not None and hasattr(course, 'selectable_modes'):
found_course_modes = course.selectable_modes
else:
elif exclude_credit:
found_course_modes = found_course_modes.exclude(mode_slug__in=cls.CREDIT_MODES)
modes = ([mode.to_tuple() for mode in found_course_modes])

View File

@@ -15,13 +15,14 @@ import six
from django.contrib.auth.models import User
from django.db.models import signals
from django.urls import reverse
from mock import patch
from pytz import UTC
from common.test.utils import disable_signal
from course_modes.models import CourseMode
from course_modes.tests.factories import CourseModeFactory
from lms.djangoapps.verify_student.models import VerificationDeadline
from student.models import ENROLLED_TO_ENROLLED, CourseEnrollment, ManualEnrollmentAudit
from student.models import ENROLLED_TO_ENROLLED, CourseEnrollment, CourseEnrollmentAttribute, ManualEnrollmentAudit
from student.roles import GlobalStaff, SupportStaffRole
from student.tests.factories import CourseEnrollmentFactory, UserFactory
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase, SharedModuleStoreTestCase
@@ -257,7 +258,8 @@ class SupportViewEnrollmentsTests(SharedModuleStoreTestCase, SupportViewTestCase
}, data[0])
self.assertEqual(
{CourseMode.VERIFIED, CourseMode.AUDIT, CourseMode.HONOR,
CourseMode.NO_ID_PROFESSIONAL_MODE, CourseMode.PROFESSIONAL},
CourseMode.NO_ID_PROFESSIONAL_MODE, CourseMode.PROFESSIONAL,
CourseMode.CREDIT_MODE},
{mode['slug'] for mode in data[0]['course_modes']}
)
@@ -329,10 +331,9 @@ class SupportViewEnrollmentsTests(SharedModuleStoreTestCase, SupportViewTestCase
self.assertIsNone(ManualEnrollmentAudit.get_manual_enrollment_by_email(self.student.email))
@disable_signal(signals, 'post_save')
@ddt.data('honor', 'audit', 'verified', 'professional', 'no-id-professional')
@ddt.data('honor', 'audit', 'verified', 'professional', 'no-id-professional', 'credit')
def test_update_enrollment_for_all_modes(self, new_mode):
""" Verify support can changed the enrollment to all available modes
except credit. """
""" Verify support can changed the enrollment to all available modes"""
self.assert_update_enrollment('username', new_mode)
@disable_signal(signals, 'post_save')
@@ -342,10 +343,6 @@ class SupportViewEnrollmentsTests(SharedModuleStoreTestCase, SupportViewTestCase
self.set_course_end_date_and_expiry()
self.assert_update_enrollment('username', new_mode)
def test_update_enrollment_with_credit_mode_throws_error(self):
""" Verify that enrollment cannot be changed to credit mode. """
self.assert_update_enrollment('username', CourseMode.CREDIT_MODE)
@ddt.data('username', 'email')
def test_get_enrollments_with_expired_mode(self, search_string_type):
""" Verify that page can get the all modes with archived course. """
@@ -367,7 +364,7 @@ class SupportViewEnrollmentsTests(SharedModuleStoreTestCase, SupportViewTestCase
def _assert_generated_modes(self, response):
"""Dry method to generate course modes dict and test with response data."""
modes = CourseMode.modes_for_course(self.course.id, include_expired=True)
modes = CourseMode.modes_for_course(self.course.id, include_expired=True, exclude_credit=False)
modes_data = []
for mode in modes:
expiry = mode.expiration_datetime.strftime('%Y-%m-%dT%H:%M:%SZ') if mode.expiration_datetime else None
@@ -394,7 +391,7 @@ class SupportViewEnrollmentsTests(SharedModuleStoreTestCase, SupportViewTestCase
self.assertEqual(
{CourseMode.VERIFIED, CourseMode.AUDIT, CourseMode.NO_ID_PROFESSIONAL_MODE,
CourseMode.PROFESSIONAL, CourseMode.HONOR},
CourseMode.PROFESSIONAL, CourseMode.HONOR, CourseMode.CREDIT_MODE},
{mode['slug'] for mode in data[0]['course_modes']}
)
@@ -405,19 +402,25 @@ class SupportViewEnrollmentsTests(SharedModuleStoreTestCase, SupportViewTestCase
'support:enrollment_list',
kwargs={'username_or_email': getattr(self.student, search_string_type)}
)
response = self.client.post(url, data={
'course_id': six.text_type(self.course.id),
'old_mode': CourseMode.AUDIT,
'new_mode': new_mode,
'reason': 'Financial Assistance'
})
# Enrollment cannot be changed to credit mode.
if new_mode == CourseMode.CREDIT_MODE:
self.assertEqual(response.status_code, 400)
else:
self.assertEqual(response.status_code, 200)
self.assertIsNotNone(ManualEnrollmentAudit.get_manual_enrollment_by_email(self.student.email))
self.assert_enrollment(new_mode)
with patch('support.views.enrollments.get_credit_provider_attribute_values') as mock_method:
credit_provider = (
[u'Arizona State University'], 'You are now eligible for credit from Arizona State University'
)
mock_method.return_value = credit_provider
response = self.client.post(url, data={
'course_id': six.text_type(self.course.id),
'old_mode': CourseMode.AUDIT,
'new_mode': new_mode,
'reason': 'Financial Assistance'
})
self.assertEqual(response.status_code, 200)
self.assertIsNotNone(ManualEnrollmentAudit.get_manual_enrollment_by_email(self.student.email))
self.assert_enrollment(new_mode)
if new_mode == 'credit':
enrollment_attr = CourseEnrollmentAttribute.objects.first()
self.assertEqual(enrollment_attr.value, unicode(credit_provider[0]))
def set_course_end_date_and_expiry(self):
""" Set the course-end date and expire its verified mode."""

View File

@@ -21,10 +21,11 @@ from edxmako.shortcuts import render_to_response
from lms.djangoapps.support.decorators import require_support_permission
from lms.djangoapps.support.serializers import ManualEnrollmentSerializer
from lms.djangoapps.verify_student.models import VerificationDeadline
from openedx.core.djangoapps.credit.email_utils import get_credit_provider_attribute_values
from openedx.core.djangoapps.enrollments.api import get_enrollments, update_enrollment
from openedx.core.djangoapps.enrollments.errors import CourseModeNotFoundError
from openedx.core.djangoapps.enrollments.serializers import ModeSerializer
from student.models import ENROLLED_TO_ENROLLED, CourseEnrollment, ManualEnrollmentAudit
from student.models import ENROLLED_TO_ENROLLED, CourseEnrollment, CourseEnrollmentAttribute, ManualEnrollmentAudit
from util.json_request import JsonResponse
@@ -94,8 +95,6 @@ class EnrollmentSupportListView(GenericAPIView):
username=user.username,
old_mode=old_mode
))
if new_mode == CourseMode.CREDIT_MODE:
return HttpResponseBadRequest(u'Enrollment cannot be changed to credit mode.')
except KeyError as err:
return HttpResponseBadRequest(u'The field {} is required.'.format(text_type(err)))
except InvalidKeyError:
@@ -119,6 +118,16 @@ class EnrollmentSupportListView(GenericAPIView):
reason=reason,
enrollment=enrollment
)
if new_mode == CourseMode.CREDIT_MODE:
provider_ids = get_credit_provider_attribute_values(course_key, 'id')
credit_provider_attr = {
'namespace': 'credit',
'name': 'provider_id',
'value': provider_ids[0],
}
CourseEnrollmentAttribute.add_enrollment_attr(
enrollment=enrollment, data_list=[credit_provider_attr]
)
return JsonResponse(ManualEnrollmentSerializer(instance=manual_enrollment).data)
except CourseModeNotFoundError as err:
return HttpResponseBadRequest(text_type(err))
@@ -178,7 +187,8 @@ class EnrollmentSupportListView(GenericAPIView):
"""
course_modes = CourseMode.modes_for_course(
course_key,
include_expired=True
include_expired=True,
exclude_credit=False
)
return [
ModeSerializer(mode).data