Files
edx-platform/lms/djangoapps/program_enrollments/tests/test_tasks.py
Feanil Patel 9cf2f9f298 Run 2to3 -f future . -w
This will remove imports from __future__ that are no longer needed.

https://docs.python.org/3.5/library/2to3.html#2to3fixer-future
2019-12-30 10:35:30 -05:00

152 lines
6.7 KiB
Python

"""
Unit tests for program_course_enrollments tasks
"""
from datetime import timedelta
from django.db.models.base import ObjectDoesNotExist
from django.test import TestCase
from django.utils import timezone
from freezegun import freeze_time
from opaque_keys.edx.keys import CourseKey
from testfixtures import LogCapture
from course_modes.models import CourseMode
from lms.djangoapps.program_enrollments.models import ProgramCourseEnrollment, ProgramEnrollment
from lms.djangoapps.program_enrollments.tasks import expire_waiting_enrollments, log
from lms.djangoapps.program_enrollments.tests.factories import ProgramCourseEnrollmentFactory, ProgramEnrollmentFactory
from openedx.core.djangoapps.content.course_overviews.tests.factories import CourseOverviewFactory
from student.tests.factories import CourseEnrollmentFactory, UserFactory
class ExpireWaitingEnrollmentsTest(TestCase):
""" Test expire_waiting_enrollments task """
@classmethod
def setUpClass(cls):
super(cls, ExpireWaitingEnrollmentsTest).setUpClass()
cls.timed_course_key = CourseKey.from_string('course-v1:edX+TestExpire+Timed')
cls.fresh_course_key = CourseKey.from_string('course-v1:edX+TestExpire+Fresh')
CourseOverviewFactory(id=cls.timed_course_key)
CourseOverviewFactory(id=cls.fresh_course_key)
def _set_up_course_enrollment(self, user, program_enrollment, course_key):
""" helper function to set up a program course enrollment """
if user:
ProgramCourseEnrollmentFactory(
program_enrollment=program_enrollment,
course_enrollment=CourseEnrollmentFactory(
course_id=course_key, user=user, mode=CourseMode.MASTERS
)
)
else:
ProgramCourseEnrollmentFactory(
program_enrollment=program_enrollment,
course_key=course_key,
)
def _set_up_enrollments(self, external_user_key, user, created_date):
""" helper function to setup enrollments """
with freeze_time(created_date):
program_enrollment = ProgramEnrollmentFactory(
user=user,
external_user_key=external_user_key,
)
self._set_up_course_enrollment(
user, program_enrollment, self.timed_course_key
)
# additional course enrollment that is always fresh
self._set_up_course_enrollment(
user, program_enrollment, self.fresh_course_key
)
def test_expire(self):
self._set_up_enrollments('student_expired_waiting', None, timezone.now() - timedelta(60))
self._set_up_enrollments('student_waiting', None, timezone.now() - timedelta(59))
self._set_up_enrollments('student_actualized', UserFactory(), timezone.now() - timedelta(90))
expired_program_enrollment = ProgramEnrollment.objects.get(
external_user_key='student_expired_waiting'
)
expired_course_enrollments = list(ProgramCourseEnrollment.objects.filter(
program_enrollment=expired_program_enrollment
))
# assert deleted enrollments are logged (without pii)
with LogCapture(log.name) as log_capture:
expire_waiting_enrollments(60)
program_enrollment_message_tmpl = 'Found expired program_enrollment (id={}) for program_uuid={}'
course_enrollment_message_tmpl = (
'Found expired program_course_enrollment (id={}) for program_uuid={}, course_key={}'
)
log_capture.check_present(
(
log.name,
'INFO',
program_enrollment_message_tmpl.format(
expired_program_enrollment.id,
expired_program_enrollment.program_uuid,
)
),
(
log.name,
'INFO',
course_enrollment_message_tmpl.format(
expired_course_enrollments[0].id,
expired_program_enrollment.program_uuid,
expired_course_enrollments[0].course_key,
)
),
(
log.name,
'INFO',
course_enrollment_message_tmpl.format(
expired_course_enrollments[1].id,
expired_program_enrollment.program_uuid,
expired_course_enrollments[1].course_key,
)
),
)
self.assertIn('Removed 3 expired records:', log_capture.records[3].getMessage())
self.assertIn("program_enrollments.ProgramCourseEnrollment': 2", log_capture.records[3].getMessage())
self.assertIn("program_enrollments.ProgramEnrollment': 1", log_capture.records[3].getMessage())
program_enrollments = ProgramEnrollment.objects.all()
program_course_enrollments = ProgramCourseEnrollment.objects.all()
historical_program_enrollments = ProgramEnrollment.historical_records.all() # pylint: disable=no-member
historical_program_course_enrollments = ProgramCourseEnrollment.historical_records.all() # pylint: disable=no-member
# assert expired records no longer exist
with self.assertRaises(ProgramEnrollment.DoesNotExist):
program_enrollments.get(external_user_key='student_expired_waiting')
self.assertEqual(len(program_course_enrollments), 4)
# assert fresh waiting records are not affected
waiting_enrollment = program_enrollments.get(external_user_key='student_waiting')
self.assertEqual(len(waiting_enrollment.program_course_enrollments.all()), 2)
# assert actualized enrollments are not affected
actualized_enrollment = program_enrollments.get(external_user_key='student_actualized')
self.assertEqual(len(actualized_enrollment.program_course_enrollments.all()), 2)
# assert expired historical records are also removed
with self.assertRaises(ObjectDoesNotExist):
historical_program_enrollments.get(external_user_key='student_expired_waiting')
self.assertEqual(
len(historical_program_course_enrollments.filter(program_enrollment_id=expired_program_enrollment.id)),
0
)
# assert other historical records are not affected
self.assertEqual(len(historical_program_enrollments), 2)
self.assertEqual(len(historical_program_course_enrollments), 4)
def test_expire_none(self):
""" Asserts no exceptions are thrown if no enrollments are found """
expire_waiting_enrollments(60)
self.assertEqual(len(ProgramEnrollment.objects.all()), 0)