Commit dc280977 by Albert St. Aubin

Updated tests WIP

parent 242e058f
...@@ -7,6 +7,9 @@ from django.core.urlresolvers import reverse ...@@ -7,6 +7,9 @@ from django.core.urlresolvers import reverse
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory from xmodule.modulestore.tests.factories import CourseFactory
from entitlements.tests.factories import CourseEntitlementFactory
from entitlements.models import CourseEntitlement
from entitlements.api.v1.serializers import CourseEntitlementSerializer
from student.tests.factories import CourseEnrollmentFactory, UserFactory, TEST_PASSWORD from student.tests.factories import CourseEnrollmentFactory, UserFactory, TEST_PASSWORD
# Entitlements is not in CMS' INSTALLED_APPS so these imports will error during test collection # Entitlements is not in CMS' INSTALLED_APPS so these imports will error during test collection
...@@ -151,6 +154,7 @@ class EntitlementViewSetTest(ModuleStoreTestCase): ...@@ -151,6 +154,7 @@ class EntitlementViewSetTest(ModuleStoreTestCase):
entitlement = CourseEntitlementFactory() entitlement = CourseEntitlementFactory()
CourseEntitlementFactory.create_batch(2) CourseEntitlementFactory.create_batch(2)
CourseEntitlementFactory()
url = reverse(self.ENTITLEMENTS_DETAILS_PATH, args=[str(entitlement.uuid)]) url = reverse(self.ENTITLEMENTS_DETAILS_PATH, args=[str(entitlement.uuid)])
response = self.client.get( response = self.client.get(
...@@ -195,3 +199,124 @@ class EntitlementViewSetTest(ModuleStoreTestCase): ...@@ -195,3 +199,124 @@ class EntitlementViewSetTest(ModuleStoreTestCase):
course_entitlement.refresh_from_db() course_entitlement.refresh_from_db()
assert course_entitlement.expired_at is not None assert course_entitlement.expired_at is not None
assert course_entitlement.enrollment_course_run is None assert course_entitlement.enrollment_course_run is None
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
@patch("openedx.core.djangoapps.catalog.utils.get_course_runs_for_course")
class EntitlementEnrollmentViewSetTest(ModuleStoreTestCase):
ENTITLEMENTS_ENROLLMENT_NAMESPACE = 'entitlements_api:v1:enrollments'
def setUp(self):
super(EntitlementEnrollmentViewSetTest, self).setUp()
self.user = UserFactory()
self.client.login(username=self.user.username, password=TEST_PASSWORD)
self.course = CourseFactory.create(org='edX', number='DemoX', display_name='Demo_Course')
self.course2 = CourseFactory.create(org='edX', number='DemoX2', display_name='Demo_Course 2')
def test_user_can_enroll(self, mock_get_course_runs):
course_entitlement = CourseEntitlementFactory(
user=self.user
)
url = reverse(
self.ENTITLEMENTS_ENROLLMENT_NAMESPACE,
args=[str(course_entitlement.uuid)]
)
assert course_entitlement.enrollment_course_run is None
mock_get_course_runs.method.return_value = [
{'key': str(self.course.id)}
]
data = {
'course_run_id': str(self.course.id)
}
response = self.client.post(
url,
data=json.dumps(data),
content_type='application/json',
)
course_entitlement.refresh_from_db()
assert response.status_code == 201
assert CourseEnrollment.is_enrolled(self.user, self.course.id)
assert course_entitlement.enrollment_course_run is not None
def test_user_can_unenroll(self, mock_get_course_runs):
course_entitlement = CourseEntitlementFactory(
user=self.user
)
url = reverse(
self.ENTITLEMENTS_ENROLLMENT_NAMESPACE,
args=[str(course_entitlement.uuid)]
)
assert course_entitlement.enrollment_course_run is None
mock_get_course_runs.return_value = [
{'key': str(self.course.id)}
]
data = {
'course_run_id': str(self.course.id)
}
response = self.client.post(
url,
data=json.dumps(data),
content_type='application/json',
)
course_entitlement.refresh_from_db()
assert response.status_code == 201
assert CourseEnrollment.is_enrolled(self.user, self.course.id)
response = self.client.delete(
url,
content_type='application/json',
)
assert response.status_code == 204
course_entitlement.refresh_from_db()
assert not CourseEnrollment.is_enrolled(self.user, self.course.id)
assert course_entitlement.enrollment_course_run is None
def test_user_can_switch(self, mock_get_course_runs):
course_entitlement = CourseEntitlementFactory(
user=self.user
)
url = reverse(
self.ENTITLEMENTS_ENROLLMENT_NAMESPACE,
args=[str(course_entitlement.uuid)]
)
assert course_entitlement.enrollment_course_run is None
mock_get_course_runs.return_value = [
{'key': str(self.course.id)},
{'key': str(self.course2.id)}
]
data = {
'course_run_id': str(self.course.id)
}
response = self.client.post(
url,
data=json.dumps(data),
content_type='application/json',
)
course_entitlement.refresh_from_db()
assert response.status_code == 201
assert CourseEnrollment.is_enrolled(self.user, self.course.id)
data = {
'course_run_id': str(self.course2.id)
}
response = self.client.post(
url,
data=json.dumps(data),
content_type='application/json',
)
assert response.status_code == 201
course_entitlement.refresh_from_db()
assert CourseEnrollment.is_enrolled(self.user, self.course2.id)
assert course_entitlement.enrollment_course_run is not None
print course_entitlement.enrollment_course_run.course_id
...@@ -3,9 +3,13 @@ import logging ...@@ -3,9 +3,13 @@ import logging
from django.utils import timezone from django.utils import timezone
from django_filters.rest_framework import DjangoFilterBackend from django_filters.rest_framework import DjangoFilterBackend
from edx_rest_framework_extensions.authentication import JwtAuthentication from edx_rest_framework_extensions.authentication import JwtAuthentication
from opaque_keys.edx.keys import CourseKey
from rest_framework import permissions, viewsets, status from rest_framework import permissions, viewsets, status
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.authentication import SessionAuthentication from rest_framework.authentication import SessionAuthentication
from student.models import CourseEnrollmentException
# from enrollment.errors import CourseEnrollmentError, CourseEnrollmentExistsError, CourseModeNotFoundError
# from openedx.core.lib.exceptions import CourseNotFoundError
from openedx.core.djangoapps.catalog.utils import get_course_runs_for_course from openedx.core.djangoapps.catalog.utils import get_course_runs_for_course
from entitlements.api.v1.filters import CourseEntitlementFilter from entitlements.api.v1.filters import CourseEntitlementFilter
...@@ -22,8 +26,9 @@ log = logging.getLogger(__name__) ...@@ -22,8 +26,9 @@ log = logging.getLogger(__name__)
class EntitlementViewSet(viewsets.ModelViewSet): class EntitlementViewSet(viewsets.ModelViewSet):
authentication_classes = (JwtAuthentication, SessionAuthenticationCrossDomainCsrf,) authentication_classes = (JwtAuthentication, SessionAuthentication,)
permission_classes = (permissions.IsAuthenticated, IsAdminOrAuthenticatedReadOnly,) permission_classes = (permissions.IsAuthenticated, permissions.IsAdminUser,)
queryset = CourseEntitlement.objects.all().select_related('user')
lookup_value_regex = '[0-9a-f-]+' lookup_value_regex = '[0-9a-f-]+'
lookup_field = 'uuid' lookup_field = 'uuid'
serializer_class = CourseEntitlementSerializer serializer_class = CourseEntitlementSerializer
...@@ -71,12 +76,36 @@ class EntitlementEnrollmentViewSet(viewsets.GenericViewSet): ...@@ -71,12 +76,36 @@ class EntitlementEnrollmentViewSet(viewsets.GenericViewSet):
queryset = CourseEntitlement.objects.all() queryset = CourseEntitlement.objects.all()
serializer_class = CourseEntitlementSerializer serializer_class = CourseEntitlementSerializer
def _verify_course_run_for_entitlement(self, entitlement, course_session_id):
course_run_valid = False
course_runs = get_course_runs_for_course(entitlement.course_uuid)
for run in course_runs:
if course_session_id == run.get('key', ''):
course_run_valid = True
break
return course_run_valid
def _enroll_entitlement(self, entitlement, course_session_key, user): def _enroll_entitlement(self, entitlement, course_session_key, user):
try:
enrollment = CourseEnrollment.enroll( enrollment = CourseEnrollment.enroll(
user=user, user=user,
course_key=course_session_key, course_key=course_session_key,
mode=entitlement.mode, mode=entitlement.mode,
) )
except CourseEnrollmentException:
message = (
'Course Entitlement Enroll for {username} failed for course: {course_id}, '
'mode: {mode}, and entitlement: {entitlement}'
).format(
username=user.username,
course_id=course_session_key,
mode=entitlement.mode,
entitlement=entitlement.uuid
)
return Response(
status=status.HTTP_400_BAD_REQUEST,
data={'message': message}
)
CourseEntitlement.set_enrollment(entitlement, enrollment) CourseEntitlement.set_enrollment(entitlement, enrollment)
...@@ -103,27 +132,32 @@ class EntitlementEnrollmentViewSet(viewsets.GenericViewSet): ...@@ -103,27 +132,32 @@ class EntitlementEnrollmentViewSet(viewsets.GenericViewSet):
) )
# Verify the course run ID is of the same type as the Course entitlement. # Verify the course run ID is of the same type as the Course entitlement.
course_run_valid = False course_run_valid = self._verify_course_run_for_entitlement(entitlement, course_session_id)
course_runs = get_course_runs_for_course(entitlement.course_uuid)
for run in course_runs:
if course_session_id == run.get('key', ''):
course_run_valid = True
if not course_run_valid: if not course_run_valid:
return Response( return Response(
status=status.HTTP_400_BAD_REQUEST, status=status.HTTP_400_BAD_REQUEST,
data="The Course Run ID is not a match for this Course Entitlement." data={
'message': "The Course Run ID is not a match for this Course Entitlement."
}
) )
# Determine if this is a Switch session or a simple enroll and handle both. # Determine if this is a Switch session or a simple enroll and handle both.
try:
course_run_string = CourseKey.from_string(course_session_id)
except CourseKey.InvalidKeyError:
return Response(
status=status.HTTP_400_BAD_REQUEST,
data={
'message': u"Invalid '{course_id}'".format(course_id=course_session_id)
}
)
if entitlement.enrollment_course_run is None: if entitlement.enrollment_course_run is None:
self._enroll_entitlement( self._enroll_entitlement(
entitlement=entitlement, entitlement=entitlement,
course_session_key=CourseKey.from_string(course_session_id), course_session_key=course_run_string,
user=request.user user=request.user
) )
else: elif entitlement.enrollment_course_run.course_id != course_session_id:
if entitlement.enrollment_course_run.course_id != course_session_id:
self._unenroll_entitlement( self._unenroll_entitlement(
entitlement=entitlement, entitlement=entitlement,
course_session_key=entitlement.enrollment_course_run.course_id, course_session_key=entitlement.enrollment_course_run.course_id,
...@@ -131,7 +165,7 @@ class EntitlementEnrollmentViewSet(viewsets.GenericViewSet): ...@@ -131,7 +165,7 @@ class EntitlementEnrollmentViewSet(viewsets.GenericViewSet):
) )
self._enroll_entitlement( self._enroll_entitlement(
entitlement=entitlement, entitlement=entitlement,
course_session_key=CourseKey.from_string(course_session_id), course_session_key=course_run_string,
user=request.user user=request.user
) )
...@@ -157,7 +191,7 @@ class EntitlementEnrollmentViewSet(viewsets.GenericViewSet): ...@@ -157,7 +191,7 @@ class EntitlementEnrollmentViewSet(viewsets.GenericViewSet):
) )
if entitlement.enrollment_course_run is None: if entitlement.enrollment_course_run is None:
return Response() return Response(status=status.HTTP_204_NO_CONTENT)
self._unenroll_entitlement( self._unenroll_entitlement(
entitlement=entitlement, entitlement=entitlement,
......
...@@ -26,21 +26,6 @@ class CourseEntitlement(TimeStampedModel): ...@@ -26,21 +26,6 @@ class CourseEntitlement(TimeStampedModel):
order_number = models.CharField(max_length=128, null=True) order_number = models.CharField(max_length=128, null=True)
@classmethod @classmethod
def get_active_user_course_entitlements(cls, user, course_uuid):
"""
Returns all the available sessions for a given course.
"""
try:
entitlement = cls.objects.get(
user=user,
course_uuid=course_uuid,
)
return entitlement
except cls.DoesNotExist:
return None
@classmethod
def set_enrollment(cls, entitlement, enrollment): def set_enrollment(cls, entitlement, enrollment):
""" """
Fulfills an entitlement by specifying a session. Fulfills an entitlement by specifying a session.
......
...@@ -319,7 +319,7 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin): ...@@ -319,7 +319,7 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin):
If we remove the prerequisite and access the dashboard again, the prerequisite If we remove the prerequisite and access the dashboard again, the prerequisite
should not appear. should not appear.
""" """
self.pre_requisite_course = CourseFactory.create(org='edx', number='999', display_name='Pre requisite Course') self.pre_requisite_course =CourseFactory.create(org='edx', number='999', display_name='Pre requisite Course')
self.course = CourseFactory.create( self.course = CourseFactory.create(
org='edx', org='edx',
number='998', number='998',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment