Skip to content

Commit

Permalink
Merge pull request openedx#20702 from edx/bom/enrollment-readme
Browse files Browse the repository at this point in the history
Enrollments README and refactor
  • Loading branch information
nasthagiri authored May 28, 2019
2 parents 2de1e99 + d3b79ae commit 01ccd87
Show file tree
Hide file tree
Showing 33 changed files with 137 additions and 87 deletions.
4 changes: 2 additions & 2 deletions common/djangoapps/student/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,16 @@
from slumber.exceptions import HttpClientError, HttpServerError
from user_util import user_util

import openedx.core.djangoapps.django_comment_common.comment_client as cc
from course_modes.models import CourseMode, get_cosmetic_verified_display_price
from courseware.models import (
CourseDynamicUpgradeDeadlineConfiguration,
DynamicUpgradeDeadlineConfiguration,
OrgDynamicUpgradeDeadlineConfiguration
)
from enrollment.api import _default_course_mode
from lms.djangoapps.certificates.models import GeneratedCertificate
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
import openedx.core.djangoapps.django_comment_common.comment_client as cc
from openedx.core.djangoapps.enrollments.api import _default_course_mode
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
from openedx.core.djangoapps.xmodule_django.models import NoneToEmptyManager
from openedx.core.djangolib.model_mixins import DeletableByUserValue
Expand Down
4 changes: 2 additions & 2 deletions lms/djangoapps/bulk_email/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
from six import text_type

from course_modes.models import CourseMode
from enrollment.api import validate_course_mode
from enrollment.errors import CourseModeNotFoundError
from openedx.core.djangoapps.course_groups.cohorts import get_cohort_by_name
from openedx.core.djangoapps.course_groups.models import CourseUserGroup
from openedx.core.djangoapps.enrollments.api import validate_course_mode
from openedx.core.djangoapps.enrollments.errors import CourseModeNotFoundError
from openedx.core.lib.html_to_text import html_to_text
from openedx.core.lib.mail_utils import wrap_message
from student.roles import CourseInstructorRole, CourseStaffRole
Expand Down
2 changes: 1 addition & 1 deletion lms/djangoapps/bulk_email/tests/test_email.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@
from bulk_email.tasks import _get_course_email_context, _get_source_address
from course_modes.models import CourseMode
from courseware.tests.factories import InstructorFactory, StaffFactory
from enrollment.api import update_enrollment
from lms.djangoapps.instructor_task.subtasks import update_subtask_status
from openedx.core.djangoapps.course_groups.cohorts import add_user_to_cohort
from openedx.core.djangoapps.course_groups.models import CourseCohort
from openedx.core.djangoapps.enrollments.api import update_enrollment
from student.models import CourseEnrollment
from student.roles import CourseStaffRole
from student.tests.factories import CourseEnrollmentFactory, UserFactory
Expand Down
2 changes: 1 addition & 1 deletion lms/djangoapps/bulk_enroll/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
from rest_framework.views import APIView

from bulk_enroll.serializers import BulkEnrollmentSerializer
from enrollment.views import EnrollmentUserThrottle
from instructor.views.api import students_update_enrollment
from openedx.core.djangoapps.course_groups.cohorts import add_user_to_cohort, get_cohort_by_name
from openedx.core.djangoapps.course_groups.models import CourseUserGroup
from openedx.core.djangoapps.enrollments.views import EnrollmentUserThrottle
from openedx.core.lib.api.authentication import OAuth2Authentication
from openedx.core.lib.api.permissions import IsStaff
from util.disable_rate_limit import can_disable_rate_limit
Expand Down
2 changes: 1 addition & 1 deletion lms/djangoapps/commerce/api/v0/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@

from course_modes.models import CourseMode
from course_modes.tests.factories import CourseModeFactory
from enrollment.api import get_enrollment
from openedx.core.djangoapps.embargo.test_utils import restrict_course
from openedx.core.djangoapps.enrollments.api import get_enrollment
from openedx.core.lib.django_test_client_utils import get_absolute_url
from student.models import CourseEnrollment
from student.tests.tests import EnrollmentEventTestMixin
Expand Down
4 changes: 2 additions & 2 deletions lms/djangoapps/commerce/api/v0/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@

from course_modes.models import CourseMode
from courseware import courses
from enrollment.api import add_enrollment
from enrollment.views import EnrollmentCrossDomainSessionAuth
from entitlements.models import CourseEntitlement
from openedx.core.djangoapps.commerce.utils import ecommerce_api_client
from openedx.core.djangoapps.embargo import api as embargo_api
from openedx.core.djangoapps.enrollments.api import add_enrollment
from openedx.core.djangoapps.enrollments.views import EnrollmentCrossDomainSessionAuth
from openedx.core.djangoapps.user_api.preferences.api import update_email_opt_in
from openedx.core.lib.api.authentication import OAuth2AuthenticationAllowInactiveUser
from student.models import CourseEnrollment
Expand Down
2 changes: 1 addition & 1 deletion lms/djangoapps/courseware/courses.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
from django.db.models import Prefetch
from django.urls import reverse
from django.http import Http404, QueryDict
from enrollment.api import get_course_enrollment_details
from edxmako.shortcuts import render_to_string
from fs.errors import ResourceNotFound
from lms.djangoapps.certificates import api as certs_api
Expand All @@ -37,6 +36,7 @@
from opaque_keys.edx.keys import UsageKey
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
from openedx.core.djangoapps.enrollments.api import get_course_enrollment_details
from openedx.core.lib.api.view_utils import LazySequence
from openedx.features.course_experience import COURSE_ENABLE_UNENROLLED_ACCESS_FLAG
from path import Path as path
Expand Down
2 changes: 1 addition & 1 deletion lms/djangoapps/courseware/views/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@
from courseware.url_helpers import get_redirect_url
from courseware.user_state_client import DjangoXBlockUserStateClient
from edxmako.shortcuts import marketing_link, render_to_response, render_to_string
from enrollment.api import add_enrollment
from ipware.ip import get_ip
from lms.djangoapps.ccx.custom_exception import CCXLocatorValidationException
from lms.djangoapps.certificates import api as certs_api
Expand All @@ -80,6 +79,7 @@
is_credit_course,
is_user_eligible_for_credit
)
from openedx.core.djangoapps.enrollments.api import add_enrollment
from openedx.core.djangoapps.models.course_details import CourseDetails
from openedx.core.djangoapps.plugin_api.views import EdxFragmentView
from openedx.core.djangoapps.programs.utils import ProgramMarketingDataExtender
Expand Down
6 changes: 3 additions & 3 deletions lms/djangoapps/support/views/enrollments.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@

from course_modes.models import CourseMode
from edxmako.shortcuts import render_to_response
from enrollment.api import get_enrollments, update_enrollment
from enrollment.errors import CourseModeNotFoundError
from enrollment.serializers import ModeSerializer
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.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 util.json_request import JsonResponse

Expand Down
2 changes: 1 addition & 1 deletion lms/envs/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -2156,7 +2156,7 @@ def _make_locale_paths(settings):
'course_modes.apps.CourseModesConfig',

# Enrollment API
'enrollment',
'openedx.core.djangoapps.enrollments',

# Entitlement API
'entitlements.apps.EntitlementsConfig',
Expand Down
2 changes: 1 addition & 1 deletion lms/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@
url(r'^submit_feedback$', util_views.submit_feedback),

# Enrollment API RESTful endpoints
url(r'^api/enrollment/v1/', include('enrollment.urls')),
url(r'^api/enrollment/v1/', include('openedx.core.djangoapps.enrollments.urls')),

# Entitlement API RESTful endpoints
url(r'^api/entitlements/', include('entitlements.api.urls', namespace='entitlements_api')),
Expand Down
16 changes: 16 additions & 0 deletions openedx/core/djangoapps/enrollments/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Status: Maintenance

Responsibilities
================
The enrollments app provides basic CRUD functionality and APIs for managing Course-Run enrollments.
Enrollments in Programs is managed by the ``lms/djangoapps/program_enrollments\`` app.

Direction: Keep
===============


Glossary
========

More Documentation
==================
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@
from opaque_keys.edx.keys import CourseKey

from course_modes.models import CourseMode
from enrollment import errors
from openedx.core.djangoapps.enrollments import errors

log = logging.getLogger(__name__)

DEFAULT_DATA_API = 'enrollment.data'
DEFAULT_DATA_API = 'openedx.core.djangoapps.enrollments.data'


def get_enrollments(user_id, include_inactive=False):
Expand Down Expand Up @@ -324,7 +324,7 @@ def get_course_enrollment_details(course_id, include_expired=False):
cached_enrollment_data = None
try:
cached_enrollment_data = cache.get(cache_key)
except Exception:
except Exception: # pylint: disable=broad-except
# The cache backend could raise an exception (for example, memcache keys that contain spaces)
log.exception(u"Error occurred while retrieving course enrollment details from the cache")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@
from opaque_keys.edx.keys import CourseKey
from six import text_type

from enrollment.errors import (
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
from openedx.core.djangoapps.enrollments.errors import (
CourseEnrollmentClosedError,
CourseEnrollmentExistsError,
CourseEnrollmentFullError,
InvalidEnrollmentAttribute,
UserNotFoundError
)
from enrollment.serializers import CourseEnrollmentSerializer, CourseSerializer
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
from openedx.core.djangoapps.enrollments.serializers import CourseEnrollmentSerializer, CourseSerializer
from openedx.core.lib.exceptions import CourseNotFoundError
from student.models import (
AlreadyEnrolledError,
Expand Down Expand Up @@ -348,6 +348,7 @@ def get_user_roles(user_id):
:param user_id: The id of the selected user.
:return: All roles for all courses that this user has.
"""
# pylint: disable=protected-access
user = _get_user(user_id)
if not hasattr(user, '_roles'):
user._roles = RoleCache(user)
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def clean_course_id(self):
try:
return CourseKey.from_string(course_id)
except InvalidKeyError:
raise ValidationError("'{}' is not a valid course id.".format(course_id))
raise ValidationError(u"'{}' is not a valid course id.".format(course_id))
return course_id

def clean_username(self):
Expand All @@ -40,7 +40,7 @@ def clean_username(self):
usernames = usernames_csv_string.split(',')
if len(usernames) > self.MAX_USERNAME_COUNT:
raise ValidationError(
"Too many usernames in a single request - {}. A maximum of {} is allowed".format(
u"Too many usernames in a single request - {}. A maximum of {} is allowed".format(
len(usernames),
self.MAX_USERNAME_COUNT,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
from __future__ import absolute_import
from django.contrib.auth.models import User
from django.core.management.base import BaseCommand
from enrollment.data import CourseEnrollmentExistsError
from enrollment.api import add_enrollment
from openedx.core.djangoapps.enrollments.data import CourseEnrollmentExistsError
from openedx.core.djangoapps.enrollments.api import add_enrollment


class Command(BaseCommand):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
""" Test the change_enrollment command line script."""

from __future__ import absolute_import
import ddt
import unittest
from uuid import uuid4
import ddt

from django.conf import settings
from django.core.management import call_command
from django.core.management.base import CommandError

from enrollment.api import get_enrollment
from openedx.core.djangoapps.enrollments.api import get_enrollment
from student.tests.factories import UserFactory

from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class StringListField(serializers.CharField):
[1,2,3]
"""
def field_to_native(self, obj, field_name):
def field_to_native(self, obj, field_name): # pylint: disable=unused-argument
"""
Serialize the object's class name.
"""
Expand Down Expand Up @@ -99,7 +99,7 @@ class Meta(CourseEnrollmentSerializer.Meta):
fields = CourseEnrollmentSerializer.Meta.fields + ('course_id', )


class ModeSerializer(serializers.Serializer):
class ModeSerializer(serializers.Serializer): # pylint: disable=abstract-method
"""Serializes a course's 'Mode' tuples
Returns a serialized representation of the modes available for course enrollment. The course
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,16 @@
from mock import Mock, patch

from course_modes.models import CourseMode
from enrollment import api
from enrollment.errors import CourseModeNotFoundError, EnrollmentApiLoadError, EnrollmentNotFoundError
from enrollment.tests import fake_data_api
from openedx.core.djangoapps.enrollments import api
from openedx.core.djangoapps.enrollments.errors import (
CourseModeNotFoundError, EnrollmentApiLoadError, EnrollmentNotFoundError,
)
from openedx.core.djangoapps.enrollments.tests import fake_data_api
from openedx.core.djangolib.testing.utils import CacheIsolationTestCase


@ddt.ddt
@override_settings(ENROLLMENT_DATA_API="enrollment.tests.fake_data_api")
@override_settings(ENROLLMENT_DATA_API="openedx.core.djangoapps.enrollments.tests.fake_data_api")
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
class EnrollmentTest(CacheIsolationTestCase):
"""
Expand Down Expand Up @@ -71,7 +73,7 @@ def test_enroll(self, course_modes, mode):
def test_enroll_no_mode_success(self, course_modes, expected_mode):
# Add a fake course enrollment information to the fake data API
fake_data_api.add_course(self.COURSE_ID, course_modes=course_modes)
with patch('enrollment.api.CourseMode.modes_for_course') as mock_modes_for_course:
with patch('openedx.core.djangoapps.enrollments.api.CourseMode.modes_for_course') as mock_modes_for_course:
mock_course_modes = [Mock(slug=mode) for mode in course_modes]
mock_modes_for_course.return_value = mock_course_modes
# Enroll in the course and verify the URL we get sent to
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@

from course_modes.models import CourseMode
from course_modes.tests.factories import CourseModeFactory
from enrollment import data
from enrollment.errors import (
from openedx.core.djangoapps.enrollments import data
from openedx.core.djangoapps.enrollments.errors import (
CourseEnrollmentClosedError,
CourseEnrollmentExistsError,
CourseEnrollmentFullError,
UserNotFoundError
)
from enrollment.serializers import CourseEnrollmentSerializer
from openedx.core.djangoapps.enrollments.serializers import CourseEnrollmentSerializer
from openedx.core.lib.exceptions import CourseNotFoundError
from student.models import AlreadyEnrolledError, CourseEnrollment, CourseFullError, EnrollmentClosedError
from student.tests.factories import CourseAccessRoleFactory, UserFactory
Expand Down Expand Up @@ -385,7 +385,9 @@ def assert_enrollment_modes(self, expected_modes, include_expired):

def test_get_roles(self):
"""Create a role for a user, then get it"""
expected_role = CourseAccessRoleFactory.create(course_id=self.course.id, user=self.user, role="SuperCoolTestRole")
expected_role = CourseAccessRoleFactory.create(
course_id=self.course.id, user=self.user, role="SuperCoolTestRole",
)
roles = data.get_user_roles(self.user.username)
self.assertEqual(roles, {expected_role})

Expand Down
Loading

0 comments on commit 01ccd87

Please sign in to comment.