Skip to content
Snippets Groups Projects
Commit 1d9b3842 authored by Albert St. Aubin's avatar Albert St. Aubin
Browse files

Corrects issue with Entitlement Auto upgrade and Soft Upgrade deadline

issues

[LEARNER-4493]
parent 81ba82b5
No related branches found
No related tags found
No related merge requests found
......@@ -4,19 +4,23 @@ import unittest
import uuid
from datetime import datetime, timedelta
from courseware.models import (
DynamicUpgradeDeadlineConfiguration
)
from django.conf import settings
from django.core.urlresolvers import reverse
from django.utils.timezone import now
from mock import patch
from opaque_keys.edx.locator import CourseKey
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
from course_modes.models import CourseMode
from course_modes.tests.factories import CourseModeFactory
from openedx.core.djangoapps.schedules.tests.factories import ScheduleFactory
from openedx.core.djangoapps.site_configuration.tests.factories import SiteFactory
from student.models import CourseEnrollment
from student.tests.factories import TEST_PASSWORD, CourseEnrollmentFactory, UserFactory
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory
from student.tests.factories import (TEST_PASSWORD, CourseEnrollmentFactory, UserFactory)
log = logging.getLogger(__name__)
......@@ -52,7 +56,7 @@ class EntitlementViewSetTest(ModuleStoreTestCase):
"""
return {
"user": user.username,
"mode": "verified",
"mode": CourseMode.VERIFIED,
"course_uuid": course_uuid,
"order_number": "EDX-1001",
}
......@@ -362,6 +366,55 @@ class EntitlementViewSetTest(ModuleStoreTestCase):
assert course_entitlement.enrollment_course_run == enrollment
assert results == CourseEntitlementSerializer(course_entitlement).data
@patch("entitlements.api.v1.views.get_course_runs_for_course")
def test_add_entitlement_and_upgrade_audit_enrollment_with_dynamic_deadline(self, mock_get_course_runs):
"""
Verify that if an entitlement is added for a user, if the user has one upgradeable enrollment
that enrollment is upgraded to the mode of the entitlement and linked to the entitlement regardless of
dynamic upgrade deadline being set.
"""
DynamicUpgradeDeadlineConfiguration.objects.create(enabled=True)
course = CourseFactory.create(self_paced=True)
course_uuid = uuid.uuid4()
course_mode = CourseModeFactory(
course_id=course.id,
mode_slug=CourseMode.VERIFIED,
# This must be in the future to ensure it is returned by downstream code.
expiration_datetime=now() + timedelta(days=1)
)
# Set up Entitlement
entitlement_data = self._get_data_set(self.user, str(course_uuid))
mock_get_course_runs.return_value = [{'key': str(course.id)}]
# Add an audit course enrollment for user.
enrollment = CourseEnrollment.enroll(self.user, course.id, mode=CourseMode.AUDIT)
# Set an upgrade schedule so that dynamic upgrade deadlines are used
ScheduleFactory.create(
enrollment=enrollment,
upgrade_deadline=course_mode.expiration_datetime + timedelta(days=-3)
)
# The upgrade should complete and ignore the deadline
response = self.client.post(
self.entitlements_list_url,
data=json.dumps(entitlement_data),
content_type='application/json',
)
assert response.status_code == 201
results = response.data
course_entitlement = CourseEntitlement.objects.get(
user=self.user,
course_uuid=course_uuid
)
# Assert that enrollment mode is now verified
enrollment_mode = CourseEnrollment.enrollment_mode_for_user(self.user, course.id)[0]
assert enrollment_mode == course_entitlement.mode
assert course_entitlement.enrollment_course_run == enrollment
assert results == CourseEntitlementSerializer(course_entitlement).data
@patch("entitlements.api.v1.views.get_course_runs_for_course")
def test_add_entitlement_inactive_audit_enrollment(self, mock_get_course_runs):
"""
......
......@@ -141,6 +141,32 @@ class EntitlementViewSet(viewsets.ModelViewSet):
# to Admin users
return CourseEntitlement.objects.all().select_related('user').select_related('enrollment_course_run')
def get_upgradeable_enrollments_for_entitlement(self, entitlement):
"""
Retrieve all the CourseEnrollments that are upgradeable for a given CourseEntitlement
Arguments:
entitlement: CourseEntitlement that we are requesting the CourseEnrollments for.
Returns:
list: List of upgradeable CourseEnrollments
"""
# find all course_runs within the course
course_runs = get_course_runs_for_course(entitlement.course_uuid)
# check if the user has enrollments for any of the course_runs
upgradeable_enrollments = []
for course_run in course_runs:
course_run_id = CourseKey.from_string(course_run.get('key'))
enrollment = CourseEnrollment.get_enrollment(entitlement.user, course_run_id)
if (enrollment and
enrollment.is_active and
is_course_run_entitlement_fulfillable(course_run_id, entitlement)):
upgradeable_enrollments.append(enrollment)
return upgradeable_enrollments
def create(self, request, *args, **kwargs):
support_details = request.data.pop('support_details', [])
serializer = self.get_serializer(data=request.data)
......@@ -157,29 +183,12 @@ class EntitlementViewSet(viewsets.ModelViewSet):
CourseEntitlementSupportDetail.objects.create(**support_detail)
else:
user = entitlement.user
upgradeable_enrollments = self.get_upgradeable_enrollments_for_entitlement(entitlement)
# find all course_runs within the course
course_runs = get_course_runs_for_course(entitlement.course_uuid)
# check if the user has enrollments for any of the course_runs
user_run_enrollments = [
CourseEnrollment.get_enrollment(user, CourseKey.from_string(course_run.get('key')))
for course_run
in course_runs
if CourseEnrollment.get_enrollment(user, CourseKey.from_string(course_run.get('key')))
]
# filter to just enrollments that can be upgraded.
upgradeable_enrollments = [
enrollment
for enrollment
in user_run_enrollments
if enrollment.is_active and enrollment.upgrade_deadline and enrollment.upgrade_deadline > timezone.now()
]
# if there is only one upgradeable enrollment, convert it from audit to the entitlement.mode
# if there is only one upgradeable enrollment, update the mode to the paid entitlement.mode
# if there is any ambiguity about which enrollment to upgrade
# (i.e. multiple upgradeable enrollments or no available upgradeable enrollment), dont enroll
# (i.e. multiple upgradeable enrollments or no available upgradeable enrollment), don't alter
# the enrollment
if len(upgradeable_enrollments) == 1:
enrollment = upgradeable_enrollments[0]
log.info(
......
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