def ungettext_min_max(singular, plural, range_text, min_val, max_val):

if min_val is None and max_val is None:<EOL><INDENT>return None<EOL><DEDENT>if min_val == max_val or min_val is None or max_val is None:<EOL><INDENT>return ungettext(singular, plural, min_val or max_val).format(min_val or max_val)<EOL><DEDENT>return range_text.format(min_val, max_val)<EOL>

Return grammatically correct, translated text based off of a minimum and maximum value.

Example:
    min = 1, max = 1, singular = '{} hour required for this course', plural = '{} hours required for this course'
    output = '1 hour required for this course'

    min = 2, max = 2, singular = '{} hour required for this course', plural = '{} hours required for this course'
    output = '2 hours required for this course'

    min = 2, max = 4, range_text = '{}-{} hours required for this course'
    output = '2-4 hours required for this course'

    min = None, max = 2, plural = '{} hours required for this course'
    output = '2 hours required for this course'

Expects ``range_text`` to already have a translation function called on it.

Returns:
    ``None`` if both of the input values are ``None``.
    ``singular`` formatted if both are equal or one of the inputs, but not both, are ``None``, and the value is 1.
    ``plural`` formatted if both are equal or one of its inputs, but not both, are ``None``, and the value is > 1.
    ``range_text`` formatted if min != max and both are valid values.


if int(price) == price:<EOL><INDENT>return '<STR_LIT>'.format(currency, int(price))<EOL><DEDENT>return '<STR_LIT>'.format(currency, price)<EOL>

Format the price to have the appropriate currency and digits..

:param price: The price amount.
:param currency: The currency for the price.
:return: A formatted price string, i.e. '$10', '$10.52'.


def get_configuration_value_for_site(site, key, default=None):

if hasattr(site, '<STR_LIT>'):<EOL><INDENT>return site.configuration.get_value(key, default)<EOL><DEDENT>return default<EOL>

Get the site configuration value for a key, unless a site configuration does not exist for that site.

Useful for testing when no Site Configuration exists in edx-enterprise or if a site in LMS doesn't have
a configuration tied to it.

:param site: A Site model object
:param key: The name of the value to retrieve
:param default: The default response if there's no key in site config or settings
:return: The value located at that key in the site configuration or settings file.


def get_configuration_value(val_name, default=None, **kwargs):

if kwargs.get('<STR_LIT:type>') == '<STR_LIT:url>':<EOL><INDENT>return get_url(val_name) or default if callable(get_url) else default<EOL><DEDENT>return configuration_helpers.get_value(val_name, default, **kwargs) if configuration_helpers else default<EOL>

Get a configuration value, or fall back to ``default`` if it doesn't exist.

Also takes a `type` argument to guide which particular upstream method to use when trying to retrieve a value.
Current types include:
    - `url` to specifically get a URL.


def get_request_value(request, key, default=None):

if request.method in ['<STR_LIT:GET>', '<STR_LIT>']:<EOL><INDENT>return request.query_params.get(key, request.data.get(key, default))<EOL><DEDENT>return request.data.get(key, request.query_params.get(key, default))<EOL>

Get the value in the request, either through query parameters or posted data, from a key.

:param request: The request from which the value should be gotten.
:param key: The key to use to get the desired value.
:param default: The backup value to use in case the input key cannot help us get the value.
:return: The value we're looking for.


return PROGRAM_TYPE_DESCRIPTION.get(program_type, '<STR_LIT>')<EOL>

Get the pre-set description associated with this program type.

:param program_type: The type of the program. Should be one of:

* "MicroMasters Certificate"
* "Professional Certificate"
* "XSeries Certificate"

:return: The description associated with the program type. If none exists, then the empty string.


return {<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': slugify(enterprise_customer.name)<EOL>}<EOL>


def track_event(user_id, event_name, properties):

<EOL>if segment:<EOL><INDENT>segment.track(user_id, event_name, properties)<EOL><DEDENT>

Emit a track event to segment (and forwarded to GA) for some parts of the Enterprise workflows.


def track_enrollment(pathway, user_id, course_run_id, url_path=None):

track_event(user_id, '<STR_LIT>', {<EOL>'<STR_LIT>': pathway,<EOL>'<STR_LIT>': url_path,<EOL>'<STR_LIT>': course_run_id,<EOL>})<EOL>

Emit a track event for enterprise course enrollment.


try:<EOL><INDENT>return parse_datetime(datetime_value).replace(tzinfo=pytz.UTC)<EOL><DEDENT>except TypeError:<EOL><INDENT>return None<EOL><DEDENT>

Return the parsed version of a datetime string. If the string is invalid, return None.


now = datetime.datetime.now(pytz.UTC)<EOL>end = parse_datetime_handle_invalid(course_run.get('<STR_LIT:end>'))<EOL>enrollment_start = parse_datetime_handle_invalid(course_run.get('<STR_LIT>'))<EOL>enrollment_end = parse_datetime_handle_invalid(course_run.get('<STR_LIT>'))<EOL>return (not end or end > now) and(not enrollment_start or enrollment_start < now) and(not enrollment_end or enrollment_end > now)<EOL>

Return true if the course run is enrollable, false otherwise.

We look for the following criteria:
- end is greater than now OR null
- enrollment_start is less than now OR null
- enrollment_end is greater than now OR null


now = datetime.datetime.now(pytz.UTC)<EOL>for seat in course_run.get('<STR_LIT>', []):<EOL><INDENT>if seat.get('<STR_LIT:type>') == '<STR_LIT>':<EOL><INDENT>upgrade_deadline = parse_datetime_handle_invalid(seat.get('<STR_LIT>'))<EOL>return not upgrade_deadline or upgrade_deadline > now<EOL><DEDENT><DEDENT>return False<EOL>

Return true if the course run has a verified seat with an unexpired upgrade deadline, false otherwise.


return parse_datetime_handle_invalid(course_run.get('<STR_LIT:start>')) or default<EOL>

Return the given course run's start date as a datetime.


if len(course_runs) == <NUM_LIT:1>:<EOL><INDENT>return course_runs[<NUM_LIT:0>]<EOL><DEDENT>now = datetime.datetime.now(pytz.UTC)<EOL>never = now - datetime.timedelta(days=<NUM_LIT>)<EOL>return min(course_runs, key=lambda x: abs(get_course_run_start(x, never) - now))<EOL>

Return course run with start date closest to now.


<EOL>enrolled_course_run_ids = [<EOL>enrolled_course_run['<STR_LIT>']['<STR_LIT>'] for enrolled_course_run in users_all_enrolled_courses<EOL>if enrolled_course_run['<STR_LIT>'] and enrolled_course_run.get('<STR_LIT>')<EOL>]<EOL>return [course_run for course_run in course['<STR_LIT>'] if course_run['<STR_LIT:key>'] in enrolled_course_run_ids]<EOL>

Return active course runs (user is enrolled in) of the given course.

This function will return the course_runs of 'course' which have
active enrollment by looking into 'users_all_enrolled_courses'


current_course_run = None<EOL>filtered_course_runs = []<EOL>all_course_runs = course['<STR_LIT>']<EOL>if users_active_course_runs:<EOL><INDENT>current_course_run = get_closest_course_run(users_active_course_runs)<EOL><DEDENT>else:<EOL><INDENT>for course_run in all_course_runs:<EOL><INDENT>if is_course_run_enrollable(course_run) and is_course_run_upgradeable(course_run):<EOL><INDENT>filtered_course_runs.append(course_run)<EOL><DEDENT><DEDENT>if not filtered_course_runs:<EOL><INDENT>filtered_course_runs = all_course_runs<EOL><DEDENT>if filtered_course_runs:<EOL><INDENT>current_course_run = get_closest_course_run(filtered_course_runs)<EOL><DEDENT><DEDENT>return current_course_run<EOL>

Return the current course run on the following conditions.

- If user has active course runs (already enrolled) then return course run with closest start date
Otherwise it will check the following logic:
- Course run is enrollable (see is_course_run_enrollable)
- Course run has a verified seat and the upgrade deadline has not expired.
- Course run start date is closer to now than any other enrollable/upgradeable course runs.
- If no enrollable/upgradeable course runs, return course run with most recent start date.


if text is None:<EOL><INDENT>return<EOL><DEDENT>if allowed_tags is None:<EOL><INDENT>allowed_tags = ALLOWED_TAGS<EOL><DEDENT>return bleach.clean(text, tags=allowed_tags, attributes=['<STR_LIT:id>', '<STR_LIT:class>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT:title>'], strip=True)<EOL>

Strip all tags from a string except those tags provided in `allowed_tags` parameter.

Args:
    text (str): string to strip html tags from
    allowed_tags (list): allowed list of html tags

Returns: a string without html tags


try:<EOL><INDENT>course_run_key = CourseKey.from_string(course_identifier)<EOL><DEDENT>except InvalidKeyError:<EOL><INDENT>return course_identifier<EOL><DEDENT>return quote_plus('<STR_LIT:U+0020>'.join([course_run_key.org, course_run_key.course]))<EOL>

Return the serialized course key given either a course run ID or course key.


if content_metadata_item['<STR_LIT>'] == '<STR_LIT>':<EOL><INDENT>return content_metadata_item['<STR_LIT>']<EOL><DEDENT>return content_metadata_item['<STR_LIT:key>']<EOL>

Return the unique identifier given a content metadata item dictionary.


return settings.ENTERPRISE_CUSTOMER_CATALOG_DEFAULT_CONTENT_FILTER or DEFAULT_CATALOG_CONTENT_FILTER<EOL>

Return default enterprise customer catalog content filter.


LOGGER.warning('<STR_LIT>')<EOL>super(NotConnectedToOpenEdX, self).__init__(*args, **kwargs)<EOL>

Log a warning and initialize the exception.


def __init__(self, programs_matched, *args, **kwargs):

super(MultipleProgramMatchError, self).__init__(*args, **kwargs)<EOL>self.programs_matched = programs_matched<EOL>

Initialize :class:`MultipleProgramMatchError`.

Arguments:
    programs_matched (int): number of programs matched where one  proram was expected.
    args (iterable): variable arguments
    kwargs (dict): keyword arguments


return join(abspath(dirname(__file__)), *args)<EOL>

Return the absolute path to a directory from this file.


return abspath(join(abspath(here('<STR_LIT>')), *args))<EOL>

Return the absolute path to some file from the project's root.


enterprise_customer_type, __ = EnterpriseCustomerType.objects.get_or_create(<EOL>name='<STR_LIT>'<EOL>)<EOL>return enterprise_customer_type.id<EOL>

Get default enterprise customer type id to use when creating a new EnterpriseCustomer model.


extension = os.path.splitext(filename)[<NUM_LIT:1>].lower()<EOL>instance_id = str(instance.id)<EOL>fullname = os.path.join("<STR_LIT>", instance_id, instance_id + "<STR_LIT>" + extension)<EOL>if default_storage.exists(fullname):<EOL><INDENT>default_storage.delete(fullname)<EOL><DEDENT>return fullname<EOL>

Delete the file if it already exist and returns the enterprise customer logo image path.

Arguments:
    instance (:class:`.EnterpriseCustomerBrandingConfiguration`): EnterpriseCustomerBrandingConfiguration object
    filename (str): file to upload

Returns:
    path: path of image file e.g. enterprise/branding/<model.id>/<model_id>_logo.<ext>.lower()


return super(EnterpriseCustomerManager, self).get_queryset().filter(active=True)<EOL>

Return a new QuerySet object. Filters out inactive Enterprise Customers.


return self.name<EOL>

Return human-readable string representation.


return self.__str__()<EOL>

Return uniquely identifying string representation.


try:<EOL><INDENT>return self.enterprise_customer_identity_provider and self.enterprise_customer_identity_provider.provider_id<EOL><DEDENT>except ObjectDoesNotExist:<EOL><INDENT>return None<EOL><DEDENT>

Return the unique slug for the identity provider associated with this enterprise customer.

Returns `None` if enterprise customer does not have any identity provider.


<EOL>return "<STR_LIT>".format(code=self.uuid.time_low, name=self.name)<EOL>


return self.__str__()<EOL>


return self.requests_data_sharing_consent and self.enforce_data_sharing_consent == enforcement_location<EOL>

Determine whether the enterprise customer enforce data sharing consent at the given point.

Args:
    enforcement_location (str): the point where to see data sharing consent state.
    argument can either be 'at_enrollment' or 'externally_managed'


return self.enable_data_sharing_consent and self.enforce_data_sharing_consent != self.EXTERNALLY_MANAGED<EOL>

Determine whether the enterprise customer has enabled the data sharing consent request.


return self.enable_audit_enrollment and self.enable_audit_data_reporting<EOL>

Determine whether the enterprise customer has enabled the ability to report/pass-back audit track data.


from enterprise.api.v1 import serializers<EOL>return serializers.EnterpriseCustomerSerializer(self).data<EOL>

Return a serialized version of this customer.


<EOL>DataSharingConsentTextOverrides = apps.get_model('<STR_LIT>', '<STR_LIT>')<EOL>queryset = DataSharingConsentTextOverrides.objects.filter(enterprise_customer=self)<EOL>if published_only:<EOL><INDENT>queryset = queryset.filter(published=True)<EOL><DEDENT>return queryset.first()<EOL>

Return DataSharingConsentTextOverrides associated with this instance.


url = urljoin(<EOL>get_configuration_value('<STR_LIT>', settings.LMS_ROOT_URL),<EOL>reverse(<EOL>'<STR_LIT>',<EOL>kwargs={'<STR_LIT>': self.uuid, '<STR_LIT>': course_key}<EOL>)<EOL>)<EOL>return utils.update_query_parameters(url, utils.get_enterprise_utm_context(self))<EOL>

Return enterprise landing page url for the given course.

Arguments:
    course_key (str): The course key for the course to be displayed.
Returns:
    (str): Enterprise landing page url.


url = urljoin(<EOL>get_configuration_value('<STR_LIT>', settings.LMS_ROOT_URL),<EOL>reverse(<EOL>'<STR_LIT>',<EOL>kwargs={'<STR_LIT>': self.uuid, '<STR_LIT>': course_run_key}<EOL>)<EOL>)<EOL>return utils.update_query_parameters(url, utils.get_enterprise_utm_context(self))<EOL>

Return enterprise landing page url for the given course.

Arguments:
    course_run_key (str): The course run id for the course to be displayed.
Returns:
    (str): Enterprise landing page url.


url = urljoin(<EOL>get_configuration_value('<STR_LIT>', settings.LMS_ROOT_URL),<EOL>reverse(<EOL>'<STR_LIT>',<EOL>kwargs={'<STR_LIT>': self.uuid, '<STR_LIT>': program_uuid}<EOL>)<EOL>)<EOL>return utils.update_query_parameters(url, utils.get_enterprise_utm_context(self))<EOL>

Return enterprise landing page url for the given program.

Arguments:
    program_uuid (str): The program UUID.
Returns:
    (str): Enterprise program landing page url.


if self.catalog:<EOL><INDENT>client = CourseCatalogApiServiceClient(self.site)<EOL>if client.is_course_in_catalog(self.catalog, course_run_id):<EOL><INDENT>return True<EOL><DEDENT><DEDENT>for catalog in self.enterprise_customer_catalogs.all():<EOL><INDENT>if catalog.contains_courses([course_run_id]):<EOL><INDENT>return True<EOL><DEDENT><DEDENT>return False<EOL>

Determine if the specified course run is contained in at least one of the enterprise's catalogs.

Arguments:
    course_run_id (str): The string ID of the course or course run in question

Returns:
    bool: Whether the enterprise catalog includes the given course run.


def enroll_user_pending_registration(self, email, course_mode, *course_ids, **kwargs):

pending_ecu, __ = PendingEnterpriseCustomerUser.objects.get_or_create(<EOL>enterprise_customer=self,<EOL>user_email=email<EOL>)<EOL>for course_id in course_ids:<EOL><INDENT>PendingEnrollment.objects.update_or_create(<EOL>user=pending_ecu,<EOL>course_id=course_id,<EOL>defaults={<EOL>'<STR_LIT>': course_mode,<EOL>'<STR_LIT>': kwargs.get('<STR_LIT>', None)<EOL>}<EOL>)<EOL><DEDENT>return pending_ecu<EOL>

Create pending enrollments for the user in any number of courses, which will take effect on registration.

Args:
    email: The email address for the pending link to be created
    course_mode: The mode with which the eventual enrollment should be created
    *course_ids: An iterable containing any number of course IDs to eventually enroll the user in.
    cohort (optional): name of cohort to assign
Returns:
    The PendingEnterpriseCustomerUser attached to the email address


def clear_pending_registration(self, email, *course_ids):

Clear pending enrollments for the user in the given courses.

Args:
    email: The email address which may have previously been used.
    course_ids: An iterable containing any number of course IDs.


def notify_enrolled_learners(self, catalog_api_user, course_id, users):

course_details = CourseCatalogApiClient(catalog_api_user, self.site).get_course_run(course_id)<EOL>if not course_details:<EOL><INDENT>LOGGER.warning(<EOL>ugettext("<STR_LIT>"<EOL>"<STR_LIT>").format(course_id)<EOL>)<EOL>return<EOL><DEDENT>course_path = urlquote(<EOL>'<STR_LIT>'.format(<EOL>course_id=course_id,<EOL>tpa_hint=self.identity_provider,<EOL>)<EOL>)<EOL>lms_root_url = utils.get_configuration_value_for_site(<EOL>self.site,<EOL>'<STR_LIT>',<EOL>settings.LMS_ROOT_URL<EOL>)<EOL>destination_url = '<STR_LIT>'.format(<EOL>site=lms_root_url,<EOL>login_or_register='<STR_LIT>',  <EOL>course_path=course_path<EOL>)<EOL>course_name = course_details.get('<STR_LIT:title>')<EOL>try:<EOL><INDENT>course_start = parse_lms_api_datetime(course_details.get('<STR_LIT:start>'))<EOL><DEDENT>except (TypeError, ValueError):<EOL><INDENT>course_start = None<EOL>LOGGER.exception(<EOL>'<STR_LIT>'.format(<EOL>course_details=course_details,<EOL>)<EOL>)<EOL><DEDENT>with mail.get_connection() as email_conn:<EOL><INDENT>for user in users:<EOL><INDENT>login_or_register = '<STR_LIT>' if isinstance(user, PendingEnterpriseCustomerUser) else '<STR_LIT>'<EOL>destination_url = destination_url.format(login_or_register=login_or_register)<EOL>utils.send_email_notification_message(<EOL>user=user,<EOL>enrolled_in={<EOL>'<STR_LIT:name>': course_name,<EOL>'<STR_LIT:url>': destination_url,<EOL>'<STR_LIT:type>': '<STR_LIT>',<EOL>'<STR_LIT:start>': course_start,<EOL>},<EOL>enterprise_customer=self,<EOL>email_connection=email_conn<EOL>)<EOL><DEDENT><DEDENT>

Notify learners about a course in which they've been enrolled.

Args:
    catalog_api_user: The user for calling the Catalog API
    course_id: The specific course the learners were enrolled in
    users: An iterable of the users or pending users who were enrolled


try:<EOL><INDENT>user = User.objects.get(email=user_email)<EOL>try:<EOL><INDENT>return self.get(user_id=user.id)<EOL><DEDENT>except EnterpriseCustomerUser.DoesNotExist:<EOL><INDENT>pass<EOL><DEDENT><DEDENT>except User.DoesNotExist:<EOL><INDENT>pass<EOL><DEDENT>try:<EOL><INDENT>return PendingEnterpriseCustomerUser.objects.get(user_email=user_email)<EOL><DEDENT>except PendingEnterpriseCustomerUser.DoesNotExist:<EOL><INDENT>pass<EOL><DEDENT>return None<EOL>


def link_user(self, enterprise_customer, user_email):

Link user email to Enterprise Customer.

If :class:`django.contrib.auth.models.User` instance with specified email does not exist,
:class:`.PendingEnterpriseCustomerUser` instance is created instead.


def unlink_user(self, enterprise_customer, user_email):

try:<EOL><INDENT>existing_user = User.objects.get(email=user_email)<EOL>link_record = self.get(enterprise_customer=enterprise_customer, user_id=existing_user.id)<EOL>link_record.delete()<EOL>if update_user:<EOL><INDENT>update_user.delay(<EOL>sailthru_vars={<EOL>'<STR_LIT>': False,<EOL>'<STR_LIT>': None,<EOL>},<EOL>email=user_email<EOL>)<EOL><DEDENT><DEDENT>except User.DoesNotExist:<EOL><INDENT>pending_link = PendingEnterpriseCustomerUser.objects.get(<EOL>enterprise_customer=enterprise_customer, user_email=user_email<EOL>)<EOL>pending_link.delete()<EOL><DEDENT>LOGGER.info(<EOL>'<STR_LIT>',<EOL>user_email,<EOL>enterprise_customer.name<EOL>)<EOL>

Unlink user email from Enterprise Customer.

If :class:`django.contrib.auth.models.User` instance with specified email does not exist,
:class:`.PendingEnterpriseCustomerUser` instance is deleted instead.

Raises EnterpriseCustomerUser.DoesNotExist if instance of :class:`django.contrib.auth.models.User` with
specified email exists and corresponding :class:`.EnterpriseCustomerUser` instance does not.

Raises PendingEnterpriseCustomerUser.DoesNotExist exception if instance of
:class:`django.contrib.auth.models.User` with specified email exists and corresponding
:class:`.PendingEnterpriseCustomerUser` instance does not.


try:<EOL><INDENT>return User.objects.get(pk=self.user_id)<EOL><DEDENT>except User.DoesNotExist:<EOL><INDENT>return None<EOL><DEDENT>

Return User associated with this instance.

Return :class:`django.contrib.auth.models.User` instance associated with this
:class:`EnterpriseCustomerUser` instance via email.


if self.user is not None:<EOL><INDENT>return self.user.email<EOL><DEDENT>return None<EOL>


if self.user is not None:<EOL><INDENT>return self.user.username<EOL><DEDENT>return None<EOL>


<EOL>DataSharingConsent = apps.get_model('<STR_LIT>', '<STR_LIT>')  <EOL>learner_consent_enabled = DataSharingConsent.objects.filter(<EOL>enterprise_customer=self.enterprise_customer,<EOL>username=self.username,<EOL>granted=True,<EOL>).exists()<EOL>entitlements = self.enterprise_customer.enterprise_customer_entitlements<EOL>if self.enterprise_customer.enforces_data_sharing_consent(EnterpriseCustomer.AT_ENROLLMENT):<EOL><INDENT>return [<EOL>{<EOL>"<STR_LIT>": entitlement.entitlement_id,<EOL>"<STR_LIT>": not learner_consent_enabled,<EOL>} for entitlement in entitlements.all()<EOL>]<EOL><DEDENT>return [<EOL>{<EOL>"<STR_LIT>": entitlement.entitlement_id,<EOL>"<STR_LIT>": False,<EOL>} for entitlement in entitlements.all()<EOL>]<EOL>

Return entitlement ids available to the learner along-with consent data.

Returns an empty list if enterprise customer requires data sharing consent and learner does not agree.

Returns:
    (list): A list of entitlements that learner can avail. Each item in the list is a dict with two
        key-value pairs,
        {
            "requires_consent": True ,
            "entitlement_id": 1
        }
        "requires_consent": True if learner must consent to data
            sharing in order to get benefits of entitlement.
        "entitlement_id: id of the entitlements available to the learner.


DataSharingConsent = apps.get_model('<STR_LIT>', '<STR_LIT>')  <EOL>return DataSharingConsent.objects.filter(<EOL>enterprise_customer=self.enterprise_customer,<EOL>username=self.username<EOL>)<EOL>

Return the DataSharingConsent records associated with this EnterpriseCustomerUser.

Returns:
    QuerySet (DataSharingConsent): The filtered DataSharingConsent QuerySet.


return "<STR_LIT>".format(<EOL>ID=self.id,<EOL>enterprise_name=self.enterprise_customer.name,<EOL>user_id=self.user_id,<EOL>)<EOL>

Return human-readable string representation.


return self.__str__()<EOL>

Return uniquely identifying string representation.


user = self.user<EOL>identity_provider = self.enterprise_customer.identity_provider<EOL>if user and identity_provider:<EOL><INDENT>client = ThirdPartyAuthApiClient()<EOL>return client.get_remote_id(self.enterprise_customer.identity_provider, user.username)<EOL><DEDENT>return None<EOL>

Retrieve the SSO provider's identifier for this user from the LMS Third Party API.

Returns None if:
* the user doesn't exist, or
* the associated EnterpriseCustomer has no identity_provider, or
* the remote identity is not found.


def enroll(self, course_run_id, mode, cohort=None):

enrollment_api_client = EnrollmentApiClient()<EOL>course_enrollment = enrollment_api_client.get_course_enrollment(self.username, course_run_id) or {}<EOL>enrolled_in_course = course_enrollment and course_enrollment.get('<STR_LIT>', False)<EOL>audit_modes = getattr(settings, '<STR_LIT>', ['<STR_LIT>', '<STR_LIT>'])<EOL>paid_modes = ['<STR_LIT>', '<STR_LIT>']<EOL>is_upgrading = mode in paid_modes and course_enrollment.get('<STR_LIT>') in audit_modes<EOL>if not enrolled_in_course or is_upgrading:<EOL><INDENT>if cohort and not self.enterprise_customer.enable_autocohorting:<EOL><INDENT>raise CourseEnrollmentPermissionError("<STR_LIT>")<EOL><DEDENT>enrollment_api_client.enroll_user_in_course(self.username, course_run_id, mode, cohort=cohort)<EOL>utils.track_event(self.user_id, '<STR_LIT>', {<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT:label>': course_run_id,<EOL>'<STR_LIT>': str(self.enterprise_customer.uuid),<EOL>'<STR_LIT>': self.enterprise_customer.name,<EOL>'<STR_LIT>': mode,<EOL>'<STR_LIT>': cohort,<EOL>'<STR_LIT>': is_upgrading,<EOL>})<EOL>EnterpriseCourseEnrollment.objects.get_or_create(<EOL>enterprise_customer_user=self,<EOL>course_id=course_run_id<EOL>)<EOL><DEDENT>elif enrolled_in_course and course_enrollment.get('<STR_LIT>') in paid_modes and mode in audit_modes:<EOL><INDENT>raise CourseEnrollmentDowngradeError(<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'.format(<EOL>course_run_id=course_run_id,<EOL>current_mode=course_enrollment.get('<STR_LIT>'),<EOL>given_mode=mode,<EOL>)<EOL>)<EOL><DEDENT>

Enroll a user into a course track, and register an enterprise course enrollment.


enrollment_api_client = EnrollmentApiClient()<EOL>if enrollment_api_client.unenroll_user_from_course(self.username, course_run_id):<EOL><INDENT>EnterpriseCourseEnrollment.objects.filter(enterprise_customer_user=self, course_id=course_run_id).delete()<EOL>return True<EOL><DEDENT>return False<EOL>


request.session['<STR_LIT>'] = self.enterprise_customer.serialized<EOL>

Update the session of a request for this learner.


return "<STR_LIT>".format(<EOL>ID=self.id,<EOL>enterprise_name=self.enterprise_customer.name,<EOL>user_email=self.user_email,<EOL>)<EOL>


return self.__str__()<EOL>


return '<STR_LIT>'.format(self.user.user_email, self.course_id)<EOL>

Create string representation of the enrollment.


return self.__str__()<EOL>

Return string representation of the enrollment.


if self.pk is None:<EOL><INDENT>logo_image = self.logo<EOL>self.logo = None<EOL>super(EnterpriseCustomerBrandingConfiguration, self).save(*args, **kwargs)<EOL>self.logo = logo_image<EOL><DEDENT>super(EnterpriseCustomerBrandingConfiguration, self).save(*args, **kwargs)<EOL>

Save the enterprise customer branding config.


return "<STR_LIT>".format(<EOL>ID=self.id,<EOL>enterprise_name=self.enterprise_customer.name,<EOL>)<EOL>


return "<STR_LIT>".format(<EOL>provider_id=self.provider_id,<EOL>enterprise_name=self.enterprise_customer.name,<EOL>)<EOL>


identity_provider = utils.get_identity_provider(self.provider_id)<EOL>return identity_provider and identity_provider.name<EOL>

Readable name for the identity provider.


return "<STR_LIT>".format(<EOL>customer=self.enterprise_customer,<EOL>id=self.entitlement_id<EOL>)<EOL>


if not self.enterprise_customer_user.enterprise_customer.enables_audit_data_reporting:<EOL><INDENT>return self.is_audit_enrollment<EOL><DEDENT>return False<EOL>

Specify whether audit track data reporting is disabled for this enrollment.

* If the enterprise customer associated with this enrollment enables audit track data reporting,
  simply return False.
* If the enterprise customer associated with this enrollment does not enable audit track data reporting,
  return True if we are dealing with an audit enrollment, and False otherwise.

:return: True if audit track data reporting is disabled, False otherwise.


course_enrollment_api = EnrollmentApiClient()<EOL>course_enrollment = course_enrollment_api.get_course_enrollment(<EOL>self.enterprise_customer_user.username,<EOL>self.course_id<EOL>)<EOL>audit_modes = getattr(settings, '<STR_LIT>', ['<STR_LIT>', '<STR_LIT>'])<EOL>return course_enrollment and course_enrollment.get('<STR_LIT>') in audit_modes<EOL>

Specify whether the course enrollment associated with this ``EnterpriseCourseEnrollment`` is in audit mode.

:return: Whether the course enrollment mode is of an audit type.


return '<STR_LIT>'.format(<EOL>self.enterprise_customer_user.user.username,<EOL>self.course_id<EOL>)<EOL>


return (<EOL>"<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>".format(<EOL>title=self.title,<EOL>uuid=self.uuid,<EOL>enterprise_customer_name=self.enterprise_customer.name<EOL>)<EOL>)<EOL>


return set(self.content_filter.get('<STR_LIT:key>', []) + self.content_filter.get('<STR_LIT>', []))<EOL>

Return the list of any content IDs specified in the catalog's content filter.


results = []<EOL>content_filter_query = self.content_filter.copy()<EOL>catalog_client = CourseCatalogApiServiceClient(self.enterprise_customer.site)<EOL>search_results = catalog_client.get_catalog_results(content_filter_query, query_parameters.dict())<EOL>for content in search_results['<STR_LIT>']:<EOL><INDENT>if content['<STR_LIT>'] == '<STR_LIT>' and content['<STR_LIT>']:<EOL><INDENT>results.append(content)<EOL><DEDENT>elif content['<STR_LIT>'] == '<STR_LIT>':<EOL><INDENT>results.append(content)<EOL><DEDENT>elif content['<STR_LIT>'] == '<STR_LIT>' and content['<STR_LIT>']:<EOL><INDENT>results.append(content)<EOL><DEDENT><DEDENT>response = {<EOL>'<STR_LIT:count>': len(results),<EOL>'<STR_LIT>': search_results['<STR_LIT>'],<EOL>'<STR_LIT>': search_results['<STR_LIT>'],<EOL>'<STR_LIT>': results,<EOL>}<EOL>return response<EOL>

Return paginated discovery service search results.

Arguments:
    query_parameters (dict): Additional query parameters to add to the search API call, e.g. page.
Returns:
    dict: The paginated discovery service search results.


def _filter_members(self, content_id_field_name, content_id_values):

updated_content_filter = self.content_filter.copy()<EOL>updated_content_filter[content_id_field_name] = content_id_values<EOL>response = CourseCatalogApiServiceClient().get_catalog_results(updated_content_filter, traverse_pagination=True)<EOL>results = response.get('<STR_LIT>', [])<EOL>return {x[content_id_field_name] for x in results}<EOL>

Filter the given list of content_id_values, returning only those that are members of the catalog.

A content ID is the unique identifier for a content metadata entity, e.g. course, course run, program.

Arguments:
    content_id_field_name (str): The name of the field on the catalog content item
                                 that stores the item's unique identifier, e.g. "key", "uuid".
    content_id_values (list): If provided, return only the content IDs that are members of this list
                              and members of the catalog.

Returns:
    list: The list of content IDs that are members of the catalog.


<EOL>course_keys = {parse_course_key(k) for k in content_ids}<EOL>content_ids_in_catalog = self.content_filter_ids<EOL>if not content_ids_in_catalog:<EOL><INDENT>content_ids_in_catalog = self._filter_members('<STR_LIT:key>', list(course_keys))<EOL><DEDENT>return set(content_ids).issubset(content_ids_in_catalog) or course_keys.issubset(content_ids_in_catalog)<EOL>

Return true if this catalog contains the given courses.

The content_ids parameter should be a list containing course keys
and/or course run ids.


content_ids_in_catalog = self.content_filter_ids<EOL>if not content_ids_in_catalog:<EOL><INDENT>content_ids_in_catalog = self._filter_members('<STR_LIT>', program_uuids)<EOL><DEDENT>return set(program_uuids).issubset(content_ids_in_catalog)<EOL>

Return true if this catalog contains the given programs.


if not self.contains_courses([course_key]):<EOL><INDENT>return None<EOL><DEDENT>return CourseCatalogApiServiceClient(self.enterprise_customer.site).get_course_details(course_key)<EOL>

Get all of the metadata for the given course.

Arguments:
    course_key (str): The course key which identifies the course.

Return:
    dict: The course metadata.


if not self.contains_courses([course_run_id]):<EOL><INDENT>return None<EOL><DEDENT>return CourseCatalogApiServiceClient(self.enterprise_customer.site).get_course_run(course_run_id)<EOL>

Get all of the metadata for the given course run.

Arguments:
    course_run_id (str): The course run key which identifies the course run.

Return:
    dict: The course run metadata.


if not self.contains_courses([course_run_id]):<EOL><INDENT>return None, None<EOL><DEDENT>return CourseCatalogApiServiceClient(self.enterprise_customer.site).get_course_and_course_run(course_run_id)<EOL>

Get course data and all of the metadata for the given course run.

Arguments:
    course_run_id (str): The course run key which identifies the course run.

Returns:
    tuple(course, course_run): The course and course run metadata.

Raises:
    ImproperlyConfigured: Missing or invalid catalog integration.


if not self.contains_programs([program_uuid]):<EOL><INDENT>return None<EOL><DEDENT>return CourseCatalogApiServiceClient(self.enterprise_customer.site).get_program_by_uuid(program_uuid)<EOL>

Get all of the metadata for the given program.

Arguments:
    program_uuid (str): The program UUID which identifies the program.

Return:
    dict: The program metadata.


url = self.enterprise_customer.get_course_enrollment_url(course_key)<EOL>if self.publish_audit_enrollment_urls:<EOL><INDENT>url = utils.update_query_parameters(url, {'<STR_LIT>': '<STR_LIT:true>'})<EOL><DEDENT>return utils.update_query_parameters(url, {'<STR_LIT>': self.uuid})<EOL>

Return enterprise course enrollment page url with the catalog information for the given course.

Arguments:
    course_key (str): The course key for the course to be displayed.

Returns:
    (str): Enterprise landing page url.


url = self.enterprise_customer.get_course_run_enrollment_url(course_run_key)<EOL>if self.publish_audit_enrollment_urls:<EOL><INDENT>url = utils.update_query_parameters(url, {'<STR_LIT>': '<STR_LIT:true>'})<EOL><DEDENT>return utils.update_query_parameters(url, {'<STR_LIT>': self.uuid})<EOL>

Return enterprise course enrollment page url with the catalog information for the given course.

Arguments:
    course_run_key (str): The course run id for the course to be displayed.

Returns:
    (str): Enterprise landing page url.


url = self.enterprise_customer.get_program_enrollment_url(program_uuid)<EOL>if self.publish_audit_enrollment_urls:<EOL><INDENT>url = utils.update_query_parameters(url, {'<STR_LIT>': '<STR_LIT:true>'})<EOL><DEDENT>return utils.update_query_parameters(url, {'<STR_LIT>': self.uuid})<EOL>

Return enterprise program enrollment page url with the catalog information for the given program.

Arguments:
    program_uuid (str): The program UUID.

Returns:
    (str): Enterprise program landing page url.


return self.render_template(mark_safe(self.html_template), kwargs)<EOL>

Render just the HTML template and return it as a string.


return self.render_template(self.plaintext_template, kwargs)<EOL>

Render just the plaintext template and return it as a string.


return self.render_plaintext_template(kwargs), self.render_html_template(kwargs)<EOL>


def render_template(self, template_text, kwargs):

template = Template(template_text)<EOL>context = Context(kwargs)<EOL>return template.render(context)<EOL>

Create a template from the DB-backed text and render it.


return '<STR_LIT>'.format(<EOL>self.enterprise_customer.uuid<EOL>)<EOL>

Return human-readable string representation.


return self.__str__()<EOL>

Return uniquely identifying string representation.


Return encrypted SFTP password as a string.


return "<STR_LIT>".format(<EOL>enterprise_name=self.enterprise_customer.name<EOL>)<EOL>


return self.__str__()<EOL>


validation_errors = {}<EOL>if self.frequency == self.FREQUENCY_TYPE_DAILY:<EOL><INDENT>self.day_of_month = None<EOL>self.day_of_week = None<EOL><DEDENT>elif self.frequency == self.FREQUENCY_TYPE_WEEKLY:<EOL><INDENT>if self.day_of_week is None or self.day_of_week == '<STR_LIT>':<EOL><INDENT>validation_errors['<STR_LIT>'] = _('<STR_LIT>')<EOL><DEDENT>self.day_of_month = None<EOL><DEDENT>elif self.frequency == self.FREQUENCY_TYPE_MONTHLY:<EOL><INDENT>if not self.day_of_month:<EOL><INDENT>validation_errors['<STR_LIT>'] = _('<STR_LIT>')<EOL><DEDENT>self.day_of_week = None<EOL><DEDENT>else:<EOL><INDENT>validation_errors[NON_FIELD_ERRORS] = _('<STR_LIT>')<EOL><DEDENT>if self.delivery_method == self.DELIVERY_METHOD_EMAIL:<EOL><INDENT>if not self.email:<EOL><INDENT>validation_errors['<STR_LIT:email>'] = _(<EOL>'<STR_LIT>'<EOL>)<EOL><DEDENT>if not self.decrypted_password:<EOL><INDENT>validation_errors['<STR_LIT>'] = _(<EOL>'<STR_LIT>'<EOL>)<EOL><DEDENT><DEDENT>elif self.delivery_method == self.DELIVERY_METHOD_SFTP:<EOL><INDENT>if not self.sftp_hostname:<EOL><INDENT>validation_errors['<STR_LIT>'] = _('<STR_LIT>')<EOL><DEDENT>if not self.sftp_username:<EOL><INDENT>validation_errors['<STR_LIT>'] = _('<STR_LIT>')<EOL><DEDENT>if not self.sftp_file_path:<EOL><INDENT>validation_errors['<STR_LIT>'] = _('<STR_LIT>')<EOL><DEDENT>if not self.decrypted_sftp_password:<EOL><INDENT>validation_errors['<STR_LIT>'] = _(<EOL>'<STR_LIT>'<EOL>)<EOL><DEDENT><DEDENT>if validation_errors:<EOL><INDENT>raise ValidationError(validation_errors)<EOL><DEDENT>

Override of clean method to perform additional validation on frequency and day_of_month/day_of week.


Get the enterprise customer uuid linked to the user.


return self.enterprise_customer_uuid<EOL>

Return the context for this role assignment class.


return "<STR_LIT>".format(role=self.name)<EOL>


<EOL>if self.role.name == ENTERPRISE_OPERATOR_ROLE:<EOL><INDENT>return ALL_ACCESS_CONTEXT<EOL><DEDENT>return super(SystemWideEnterpriseUserRoleAssignment, self).get_context()<EOL>


return "<STR_LIT>".format(<EOL>user=self.user.id,<EOL>role=self.role.name<EOL>)<EOL>


if JwtBuilder is None:<EOL><INDENT>raise NotConnectedToOpenEdX(<EOL>_("<STR_LIT>"<EOL>"<STR_LIT>")<EOL>)<EOL><DEDENT>jwt = JwtBuilder.create_jwt_for_user(user)<EOL>return EdxRestApiClient(catalog_url, jwt=jwt)<EOL>

Return a Course Discovery API client setup with authentication for the specified user.


if CatalogIntegration is None:<EOL><INDENT>raise NotConnectedToOpenEdX(<EOL>_("<STR_LIT>"<EOL>"<STR_LIT>")<EOL>)<EOL><DEDENT>if get_edx_api_data is None:<EOL><INDENT>raise NotConnectedToOpenEdX(<EOL>_("<STR_LIT>"<EOL>"<STR_LIT>")<EOL>)<EOL><DEDENT>self.user = user<EOL>self.catalog_url = get_configuration_value_for_site(<EOL>site,<EOL>'<STR_LIT>',<EOL>settings.COURSE_CATALOG_API_URL<EOL>)<EOL>self.client = course_discovery_api_client(user, self.catalog_url)<EOL>

Create an Course Catalog API client setup with authentication for the specified user.

This method retrieves an authenticated API client that can be used
to access the course catalog API. It raises an exception to be caught at
a higher level if the package doesn't have OpenEdX resources available.


@staticmethod<EOL><INDENT>def traverse_pagination(response, endpoint, content_filter_query, query_params):<DEDENT>

results = response.get('<STR_LIT>', [])<EOL>page = <NUM_LIT:1><EOL>while response.get('<STR_LIT>'):<EOL><INDENT>page += <NUM_LIT:1><EOL>response = endpoint().post(content_filter_query, **dict(query_params, page=page))<EOL>results += response.get('<STR_LIT>', [])<EOL><DEDENT>return results<EOL>

Traverse a paginated API response and extracts and concatenates "results" returned by API.

Arguments:
    response (dict): API response object.
    endpoint (Slumber.Resource): API endpoint object.
    content_filter_query (dict): query parameters used to filter catalog results.
    query_params (dict): query parameters used to paginate results.

Returns:
    list: all the results returned by the API.


def get_catalog_results(self, content_filter_query, query_params=None, traverse_pagination=False):

query_params = query_params or {}<EOL>try:<EOL><INDENT>endpoint = getattr(self.client, self.SEARCH_ALL_ENDPOINT)<EOL>response = endpoint().post(data=content_filter_query, **query_params)<EOL>if traverse_pagination:<EOL><INDENT>response['<STR_LIT>'] = self.traverse_pagination(response, endpoint, content_filter_query, query_params)<EOL>response['<STR_LIT>'] = response['<STR_LIT>'] = None<EOL><DEDENT><DEDENT>except Exception as ex:  <EOL><INDENT>LOGGER.exception(<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>',<EOL>content_filter_query,<EOL>query_params,<EOL>traverse_pagination,<EOL>getattr(ex, '<STR_LIT:content>', '<STR_LIT>')<EOL>)<EOL>raise ex<EOL><DEDENT>return response<EOL>

Return results from the discovery service's search/all endpoint.

Arguments:
    content_filter_query (dict): query parameters used to filter catalog results.
    query_params (dict): query parameters used to paginate results.
    traverse_pagination (bool): True to return all results, False to return the paginated response.
                                Defaults to False.

Returns:
    dict: Paginated response or all the records.


return self._load_data(<EOL>self.CATALOGS_ENDPOINT,<EOL>default=[]<EOL>)<EOL>

Return a list of all course catalogs, including name and ID.

Returns:
    list: List of catalogs available for the user.


return self._load_data(<EOL>self.CATALOGS_ENDPOINT,<EOL>default=[],<EOL>resource_id=catalog_id<EOL>)<EOL>

Return specified course catalog.

Returns:
    dict: catalog details if it is available for the user.


def get_paginated_catalog_courses(self, catalog_id, querystring=None):

return self._load_data(<EOL>self.CATALOGS_COURSES_ENDPOINT.format(catalog_id),<EOL>default=[],<EOL>querystring=querystring,<EOL>traverse_pagination=False,<EOL>many=False,<EOL>)<EOL>

Return paginated response for all catalog courses.

Returns:
    dict: API response with links to next and previous pages.


return self._load_data(<EOL>self.CATALOGS_ENDPOINT,<EOL>default=[],<EOL>querystring=querystring,<EOL>traverse_pagination=False,<EOL>many=False<EOL>)<EOL>

Return a paginated list of course catalogs, including name and ID.

Returns:
    dict: Paginated response containing catalogs available for the user.


return self._load_data(<EOL>self.CATALOGS_COURSES_ENDPOINT.format(catalog_id),<EOL>default=[]<EOL>)<EOL>

Return the courses included in a single course catalog by ID.

Args:
    catalog_id (int): The catalog ID we want to retrieve.

Returns:
    list: Courses of the catalog in question


<EOL>course_id = parse_course_key(course_run_id)<EOL>course = self.get_course_details(course_id)<EOL>course_run = None<EOL>if course:<EOL><INDENT>course_run = None<EOL>course_runs = [course_run for course_run in course['<STR_LIT>'] if course_run['<STR_LIT:key>'] == course_run_id]<EOL>if course_runs:<EOL><INDENT>course_run = course_runs[<NUM_LIT:0>]<EOL><DEDENT><DEDENT>return course, course_run<EOL>

Return the course and course run metadata for the given course run ID.

Arguments:
    course_run_id (str): The course run ID.

Returns:
    tuple: The course metadata and the course run metadata.


return self._load_data(<EOL>self.COURSES_ENDPOINT,<EOL>resource_id=course_id,<EOL>many=False<EOL>)<EOL>

Return the details of a single course by id - not a course run id.

Args:
    course_id (str): The unique id for the course in question.

Returns:
    dict: Details of the course in question.


return self._load_data(<EOL>self.COURSE_RUNS_ENDPOINT,<EOL>resource_id=course_run_id<EOL>)<EOL>

Return course_run data, including name, ID and seats.

Args:
    course_run_id(string): Course run ID (aka Course Key) in string format.

Returns:
    dict: Course run data provided by Course Catalog API.


all_programs = self._load_data(self.PROGRAMS_ENDPOINT, default=[])<EOL>matching_programs = [program for program in all_programs if program.get('<STR_LIT:title>') == program_title]<EOL>if len(matching_programs) > <NUM_LIT:1>:<EOL><INDENT>raise MultipleProgramMatchError(len(matching_programs))<EOL><DEDENT>elif len(matching_programs) == <NUM_LIT:1>:<EOL><INDENT>return matching_programs[<NUM_LIT:0>]<EOL><DEDENT>else:<EOL><INDENT>return None<EOL><DEDENT>

Return single program by name, or None if not found.

Arguments:
    program_title(string): Program title as seen by students and in Course Catalog Admin

Returns:
    dict: Program data provided by Course Catalog API


return self._load_data(<EOL>self.PROGRAMS_ENDPOINT,<EOL>resource_id=program_uuid,<EOL>default=None<EOL>)<EOL>

Return single program by UUID, or None if not found.

Arguments:
    program_uuid(string): Program UUID in string form

Returns:
    dict: Program data provided by Course Catalog API


program_details = self.get_program_by_uuid(program_uuid)<EOL>if not program_details:<EOL><INDENT>return []<EOL><DEDENT>return [course['<STR_LIT:key>'] for course in program_details.get('<STR_LIT>', [])]<EOL>

Get a list of the course IDs (not course run IDs) contained in the program.

Arguments:
    program_uuid (str): Program UUID in string form

Returns:
    list(str): List of course keys in string form that are included in the program


return self._load_data(<EOL>self.PROGRAM_TYPES_ENDPOINT,<EOL>resource_id=slug,<EOL>default=None,<EOL>)<EOL>

Get a program type by its slug.

Arguments:
    slug (str): The slug to identify the program type.

Returns:
    dict: A program type object.


available_course_modes = None<EOL>for course_run_id in course_run_ids:<EOL><INDENT>course_run = self.get_course_run(course_run_id) or {}<EOL>course_run_modes = {seat.get('<STR_LIT:type>') for seat in course_run.get('<STR_LIT>', [])}<EOL>if available_course_modes is None:<EOL><INDENT>available_course_modes = course_run_modes<EOL><DEDENT>else:<EOL><INDENT>available_course_modes &= course_run_modes<EOL><DEDENT>if not available_course_modes:<EOL><INDENT>return available_course_modes<EOL><DEDENT><DEDENT>return available_course_modes<EOL>

Find common course modes for a set of course runs.

This function essentially returns an intersection of types of seats available
for each course run.

Arguments:
    course_run_ids(Iterable[str]): Target Course run IDs.

Returns:
    set: course modes found in all given course runs

Examples:
    # run1 has prof and audit, run 2 has the same
    get_common_course_modes(['course-v1:run1', 'course-v1:run2'])
    {'prof', 'audit'}

    # run1 has prof and audit, run 2 has only prof
    get_common_course_modes(['course-v1:run1', 'course-v1:run2'])
    {'prof'}

    # run1 has prof and audit, run 2 honor
    get_common_course_modes(['course-v1:run1', 'course-v1:run2'])
    {}

    # run1 has nothing, run2 has prof
    get_common_course_modes(['course-v1:run1', 'course-v1:run2'])
    {}

    # run1 has prof and audit, run 2 prof, run3 has audit
    get_common_course_modes(['course-v1:run1', 'course-v1:run2', 'course-v1:run3'])
    {}

    # run1 has nothing, run 2 prof, run3 has prof
    get_common_course_modes(['course-v1:run1', 'course-v1:run2', 'course-v1:run3'])
    {}


def is_course_in_catalog(self, catalog_id, course_id):

try:<EOL><INDENT>course_run_id = str(CourseKey.from_string(course_id))<EOL><DEDENT>except InvalidKeyError:<EOL><INDENT>course_run_id = None<EOL><DEDENT>endpoint = self.client.catalogs(catalog_id).contains<EOL>if course_run_id:<EOL><INDENT>resp = endpoint.get(course_run_id=course_run_id)<EOL><DEDENT>else:<EOL><INDENT>resp = endpoint.get(course_id=course_id)<EOL><DEDENT>return resp.get('<STR_LIT>', {}).get(course_id, False)<EOL>

Determine if the given course or course run ID is contained in the catalog with the given ID.

Args:
    catalog_id (int): The ID of the catalog
    course_id (str): The ID of the course or course run

Returns:
    bool: Whether the course or course run is contained in the given catalog


def _load_data(self, resource, default=DEFAULT_VALUE_SAFEGUARD, **kwargs):

default_val = default if default != self.DEFAULT_VALUE_SAFEGUARD else {}<EOL>try:<EOL><INDENT>return get_edx_api_data(<EOL>api_config=CatalogIntegration.current(),<EOL>resource=resource,<EOL>api=self.client,<EOL>**kwargs<EOL>) or default_val<EOL><DEDENT>except (SlumberBaseException, ConnectionError, Timeout) as exc:<EOL><INDENT>LOGGER.exception(<EOL>'<STR_LIT>',<EOL>resource, kwargs, str(exc)<EOL>)<EOL>return default_val<EOL><DEDENT>

Load data from API client.

Arguments:
    resource(string): type of resource to load
    default(any): value to return if API query returned empty result. Sensible values: [], {}, None etc.

Returns:
    dict: Deserialized response from Course Catalog API


if CatalogIntegration is None:<EOL><INDENT>raise NotConnectedToOpenEdX(<EOL>_("<STR_LIT>"<EOL>"<STR_LIT>")<EOL>)<EOL><DEDENT>catalog_integration = CatalogIntegration.current()<EOL>if catalog_integration.enabled:<EOL><INDENT>try:<EOL><INDENT>user = catalog_integration.get_service_user()<EOL>super(CourseCatalogApiServiceClient, self).__init__(user, site)<EOL><DEDENT>except ObjectDoesNotExist:<EOL><INDENT>raise ImproperlyConfigured(_("<STR_LIT>"))<EOL><DEDENT><DEDENT>else:<EOL><INDENT>raise ImproperlyConfigured(_("<STR_LIT>"))<EOL><DEDENT>

Create an Course Catalog API client setup with authentication for the
configured catalog service user.


try:<EOL><INDENT>return bool(cls().get_program_by_uuid(program_uuid))<EOL><DEDENT>except ImproperlyConfigured:<EOL><INDENT>return False<EOL><DEDENT>


if ecommerce_api_client is None:<EOL><INDENT>raise NotConnectedToOpenEdX(<EOL>_('<STR_LIT>'<EOL>'<STR_LIT>')<EOL>)<EOL><DEDENT>self.user = user<EOL>self.client = ecommerce_api_client(user)<EOL>

Create an E-Commerce API client, authenticated with the API token from Django settings.

This method retrieves an authenticated API client that can be used
to access the ecommerce API. It raises an exception to be caught at
a higher level if the package doesn't have OpenEdX resources available.


def get_course_final_price(self, mode, currency='<STR_LIT:$>', enterprise_catalog_uuid=None):

try:<EOL><INDENT>price_details = self.client.baskets.calculate.get(<EOL>sku=[mode['<STR_LIT>']],<EOL>username=self.user.username,<EOL>catalog=enterprise_catalog_uuid,<EOL>)<EOL><DEDENT>except (SlumberBaseException, ConnectionError, Timeout) as exc:<EOL><INDENT>LOGGER.exception('<STR_LIT>', mode['<STR_LIT>'], str(exc))<EOL>price_details = {}<EOL><DEDENT>price = price_details.get('<STR_LIT>', mode['<STR_LIT>'])<EOL>if price != mode['<STR_LIT>']:<EOL><INDENT>return format_price(price, currency)<EOL><DEDENT>return mode['<STR_LIT>']<EOL>

Get course mode's SKU discounted price after applying any entitlement available for this user.

Returns:
    str: Discounted price of the course mode.


content_metadata = OrderedDict()<EOL>if enterprise_customer.catalog:<EOL><INDENT>response = self._load_data(<EOL>self.ENTERPRISE_CUSTOMER_ENDPOINT,<EOL>detail_resource='<STR_LIT>',<EOL>resource_id=str(enterprise_customer.uuid),<EOL>traverse_pagination=True,<EOL>)<EOL>for course in response['<STR_LIT>']:<EOL><INDENT>for course_run in course['<STR_LIT>']:<EOL><INDENT>course_run['<STR_LIT>'] = '<STR_LIT>'  <EOL>content_metadata[course_run['<STR_LIT:key>']] = course_run<EOL><DEDENT><DEDENT><DEDENT>for enterprise_customer_catalog in enterprise_customer.enterprise_customer_catalogs.all():<EOL><INDENT>response = self._load_data(<EOL>self.ENTERPRISE_CUSTOMER_CATALOGS_ENDPOINT,<EOL>resource_id=str(enterprise_customer_catalog.uuid),<EOL>traverse_pagination=True,<EOL>querystring={'<STR_LIT>': <NUM_LIT:1000>},<EOL>)<EOL>for item in response['<STR_LIT>']:<EOL><INDENT>content_id = utils.get_content_metadata_item_id(item)<EOL>content_metadata[content_id] = item<EOL><DEDENT><DEDENT>return content_metadata.values()<EOL>

Return all content metadata contained in the catalogs associated with the EnterpriseCustomer.

Arguments:
    enterprise_customer (EnterpriseCustomer): The EnterpriseCustomer to return content metadata for.

Returns:
    list: List of dicts containing content metadata.


default_val = default if default != self.DEFAULT_VALUE_SAFEGUARD else {}<EOL>querystring = querystring if querystring else {}<EOL>cache_key = utils.get_cache_key(<EOL>resource=resource,<EOL>querystring=querystring,<EOL>traverse_pagination=traverse_pagination,<EOL>resource_id=resource_id<EOL>)<EOL>response = cache.get(cache_key)<EOL>if not response:<EOL><INDENT>endpoint = getattr(self.client, resource)(resource_id)<EOL>endpoint = getattr(endpoint, detail_resource) if detail_resource else endpoint<EOL>response = endpoint.get(**querystring)<EOL>if traverse_pagination:<EOL><INDENT>results = utils.traverse_pagination(response, endpoint)<EOL>response = {<EOL>'<STR_LIT:count>': len(results),<EOL>'<STR_LIT>': '<STR_LIT:None>',<EOL>'<STR_LIT>': '<STR_LIT:None>',<EOL>'<STR_LIT>': results,<EOL>}<EOL><DEDENT>if response:<EOL><INDENT>cache.set(cache_key, response, settings.ENTERPRISE_API_CACHE_TIMEOUT)<EOL><DEDENT><DEDENT>return response or default_val<EOL>

Loads a response from a call to one of the Enterprise endpoints.

:param resource: The endpoint resource name.
:param detail_resource: The sub-resource to append to the path.
:param resource_id: The resource ID for the specific detail to get from the endpoint.
:param querystring: Optional query string parameters.
:param traverse_pagination: Whether to traverse pagination or return paginated response.
:param default: The default value to return in case of no response content.
:return: Data returned by the API.


if isinstance(datetime_string, datetime.datetime):<EOL><INDENT>date_time = datetime_string<EOL><DEDENT>else:<EOL><INDENT>try:<EOL><INDENT>date_time = datetime.datetime.strptime(datetime_string, datetime_format)<EOL><DEDENT>except ValueError:<EOL><INDENT>date_time = datetime.datetime.strptime(datetime_string, LMS_API_DATETIME_FORMAT_WITHOUT_TIMEZONE)<EOL><DEDENT><DEDENT>if date_time.tzinfo is None:<EOL><INDENT>date_time = date_time.replace(tzinfo=timezone.utc)<EOL><DEDENT>return date_time<EOL>

Parse a received datetime into a timezone-aware, Python datetime object.

Arguments:
    datetime_string: A string to be parsed.
    datetime_format: A datetime format string to be used for parsing


session = Session()<EOL>session.headers = {"<STR_LIT>": settings.EDX_API_KEY}<EOL>self.client = EdxRestApiClient(<EOL>self.API_BASE_URL, append_slash=self.APPEND_SLASH, session=session<EOL>)<EOL>

Create an LMS API client, authenticated with the API token from Django settings.


def __init__(self, user, expires_in=settings.OAUTH_ID_TOKEN_EXPIRATION):

self.user = user<EOL>self.expires_in = expires_in<EOL>self.expires_at = <NUM_LIT:0><EOL>self.client = None<EOL>


if JwtBuilder is None:<EOL><INDENT>raise NotConnectedToOpenEdX("<STR_LIT>")<EOL><DEDENT>now = int(time())<EOL>jwt = JwtBuilder.create_jwt_for_user(self.user)<EOL>self.client = EdxRestApiClient(<EOL>self.API_BASE_URL, append_slash=self.APPEND_SLASH, jwt=jwt,<EOL>)<EOL>self.expires_at = now + self.expires_in<EOL>

Connect to the REST API, authenticating with a JWT for the current user.


return int(time()) > self.expires_at<EOL>

Return True if the JWT token has expired, False if not.


@wraps(func)<EOL>def inner(self, *args, **kwargs):<EOL><INDENT>"""<STR_LIT>"""<EOL>if self.token_expired():<EOL><INDENT>self.connect()<EOL><DEDENT>return func(self, *args, **kwargs)<EOL><DEDENT>return inner<EOL>

Use this method decorator to ensure the JWT token is refreshed when needed.


@staticmethod<EOL><INDENT>def redirect_if_blocked(course_run_ids, user=None, ip_address=None, url=None):<DEDENT>

for course_run_id in course_run_ids:<EOL><INDENT>redirect_url = embargo_api.redirect_if_blocked(<EOL>CourseKey.from_string(course_run_id),<EOL>user=user,<EOL>ip_address=ip_address,<EOL>url=url<EOL>)<EOL>if redirect_url:<EOL><INDENT>return redirect_url<EOL><DEDENT><DEDENT>

Return redirect to embargo error page if the given user is blocked.


try:<EOL><INDENT>return self.client.course(course_id).get()<EOL><DEDENT>except (SlumberBaseException, ConnectionError, Timeout) as exc:<EOL><INDENT>LOGGER.exception(<EOL>'<STR_LIT>',<EOL>course_id, str(exc)<EOL>)<EOL>return {}<EOL><DEDENT>

Query the Enrollment API for the course details of the given course_id.

Args:
    course_id (str): The string value of the course's unique identifier

Returns:
    dict: A dictionary containing details about the course, in an enrollment context (allowed modes, etc.)


def slug_weight(mode):<EOL><INDENT>"""<STR_LIT>"""<EOL>sorting_slugs = COURSE_MODE_SORT_ORDER<EOL>sorting_slugs_size = len(sorting_slugs)<EOL>if mode['<STR_LIT>'] in sorting_slugs:<EOL><INDENT>return sorting_slugs_size - sorting_slugs.index(mode['<STR_LIT>'])<EOL><DEDENT>return <NUM_LIT:0><EOL><DEDENT>return sorted(modes, key=slug_weight, reverse=True)<EOL>

Sort the course mode dictionaries by slug according to the COURSE_MODE_SORT_ORDER constant.

Arguments:
    modes (list): A list of course mode dictionaries.
Returns:
    list: A list with the course modes dictionaries sorted by slug.


details = self.get_course_details(course_id)<EOL>modes = details.get('<STR_LIT>', [])<EOL>return self._sort_course_modes([mode for mode in modes if mode['<STR_LIT>'] not in EXCLUDED_COURSE_MODES])<EOL>

Query the Enrollment API for the specific course modes that are available for the given course_id.

Arguments:
    course_id (str): The string value of the course's unique identifier

Returns:
    list: A list of course mode dictionaries.


def has_course_mode(self, course_run_id, mode):

course_modes = self.get_course_modes(course_run_id)<EOL>return any(course_mode for course_mode in course_modes if course_mode['<STR_LIT>'] == mode)<EOL>

Query the Enrollment API to see whether a course run has a given course mode available.

Arguments:
    course_run_id (str): The string value of the course run's unique identifier

Returns:
    bool: Whether the course run has the given mode avaialble for enrollment.


def enroll_user_in_course(self, username, course_id, mode, cohort=None):

return self.client.enrollment.post(<EOL>{<EOL>'<STR_LIT:user>': username,<EOL>'<STR_LIT>': {'<STR_LIT>': course_id},<EOL>'<STR_LIT>': mode,<EOL>'<STR_LIT>': cohort,<EOL>}<EOL>)<EOL>

Call the enrollment API to enroll the user in the course specified by course_id.

Args:
    username (str): The username by which the user goes on the OpenEdX platform
    course_id (str): The string value of the course's unique identifier
    mode (str): The enrollment mode which should be used for the enrollment
    cohort (str): Add the user to this named cohort

Returns:
    dict: A dictionary containing details of the enrollment, including course details, mode, username, etc.


def unenroll_user_from_course(self, username, course_id):

enrollment = self.get_course_enrollment(username, course_id)<EOL>if enrollment and enrollment['<STR_LIT>']:<EOL><INDENT>response = self.client.enrollment.post({<EOL>'<STR_LIT:user>': username,<EOL>'<STR_LIT>': {'<STR_LIT>': course_id},<EOL>'<STR_LIT>': False,<EOL>'<STR_LIT>': enrollment['<STR_LIT>']<EOL>})<EOL>return not response['<STR_LIT>']<EOL><DEDENT>return False<EOL>

Call the enrollment API to unenroll the user in the course specified by course_id.
Args:
    username (str): The username by which the user goes on the OpenEdx platform
    course_id (str): The string value of the course's unique identifier
Returns:
    bool: Whether the unenrollment succeeded


def get_course_enrollment(self, username, course_id):

endpoint = getattr(<EOL>self.client.enrollment,<EOL>'<STR_LIT>'.format(username=username, course_id=course_id)<EOL>)<EOL>try:<EOL><INDENT>result = endpoint.get()<EOL><DEDENT>except HttpNotFoundError:<EOL><INDENT>LOGGER.error(<EOL>'<STR_LIT>',<EOL>username,<EOL>course_id<EOL>)<EOL>return None<EOL><DEDENT>if not result:<EOL><INDENT>LOGGER.info('<STR_LIT>', username, course_id)<EOL>return None<EOL><DEDENT>return result<EOL>

Query the enrollment API to get information about a single course enrollment.

Args:
    username (str): The username by which the user goes on the OpenEdX platform
    course_id (str): The string value of the course's unique identifier

Returns:
    dict: A dictionary containing details of the enrollment, including course details, mode, username, etc.


def is_enrolled(self, username, course_run_id):

enrollment = self.get_course_enrollment(username, course_run_id)<EOL>return enrollment is not None and enrollment.get('<STR_LIT>', False)<EOL>

Query the enrollment API and determine if a learner is enrolled in a course run.

Args:
    username (str): The username by which the user goes on the OpenEdX platform
    course_run_id (str): The string value of the course's unique identifier

Returns:
    bool: Indicating whether the user is enrolled in the course run. Returns False under any errors.


return self.client.enrollment.get(user=username)<EOL>

Query the enrollment API to get a list of the courses a user is enrolled in.

Args:
    username (str): The username by which the user goes on the OpenEdX platform

Returns:
    list: A list of course objects, along with relevant user-specific enrollment details.


try:<EOL><INDENT>return self.client.courses(course_id).get()<EOL><DEDENT>except (SlumberBaseException, ConnectionError, Timeout) as exc:<EOL><INDENT>LOGGER.exception('<STR_LIT>', course_id, str(exc))<EOL>return None<EOL><DEDENT>

Retrieve all available details about a course.

Args:
    course_id (str): The course ID identifying the course for which to retrieve details.

Returns:
    dict: Contains keys identifying those course details available from the courses API (e.g., name).


def get_remote_id(self, identity_provider, username):

return self._get_results(identity_provider, '<STR_LIT:username>', username, '<STR_LIT>')<EOL>

Retrieve the remote identifier for the given username.

Args:
* ``identity_provider`` (str): identifier slug for the third-party authentication service used during SSO.
* ``username`` (str): The username ID identifying the user for which to retrieve the remote name.

Returns:
    string or None: the remote name of the given user.  None if not found.


def get_username_from_remote_id(self, identity_provider, remote_id):

return self._get_results(identity_provider, '<STR_LIT>', remote_id, '<STR_LIT:username>')<EOL>

Retrieve the remote identifier for the given username.

Args:
* ``identity_provider`` (str): identifier slug for the third-party authentication service used during SSO.
* ``remote_id`` (str): The remote id identifying the user for which to retrieve the usernamename.

Returns:
    string or None: the username of the given user.  None if not found.


def _get_results(self, identity_provider, param_name, param_value, result_field_name):

try:<EOL><INDENT>kwargs = {param_name: param_value}<EOL>returned = self.client.providers(identity_provider).users.get(**kwargs)<EOL>results = returned.get('<STR_LIT>', [])<EOL><DEDENT>except HttpNotFoundError:<EOL><INDENT>LOGGER.error(<EOL>'<STR_LIT>'.format(<EOL>provider=identity_provider,<EOL>querystring_param=param_name,<EOL>id=param_value<EOL>)<EOL>)<EOL>results = []<EOL><DEDENT>for row in results:<EOL><INDENT>if row.get(param_name) == param_value:<EOL><INDENT>return row.get(result_field_name)<EOL><DEDENT><DEDENT>return None<EOL>

Calls the third party auth api endpoint to get the mapping between usernames and remote ids.


@JwtLmsApiClient.refresh_token<EOL><INDENT>def get_course_grade(self, course_id, username):<DEDENT>

results = self.client.courses(course_id).get(username=username)<EOL>for row in results:<EOL><INDENT>if row.get('<STR_LIT:username>') == username:<EOL><INDENT>return row<EOL><DEDENT><DEDENT>raise HttpNotFoundError('<STR_LIT>'.format(course_id, username))<EOL>

Retrieve the grade for the given username for the given course_id.

Args:
* ``course_id`` (str): The string value of the course's unique identifier
* ``username`` (str): The username ID identifying the user for which to retrieve the grade.

Raises:

HttpNotFoundError if no grade found for the given user+course.

Returns:

a dict containing:

* ``username``: A string representation of a user's username passed in the request.
* ``course_key``: A string representation of a Course ID.
* ``passed``: Boolean representing whether the course has been passed according the course's grading policy.
* ``percent``: A float representing the overall grade for the course
* ``letter_grade``: A letter grade as defined in grading_policy (e.g. 'A' 'B' 'C' for 6.002x) or None


@JwtLmsApiClient.refresh_token<EOL><INDENT>def get_course_certificate(self, course_id, username):<DEDENT>

return self.client.certificates(username).courses(course_id).get()<EOL>

Retrieve the certificate for the given username for the given course_id.

Args:
* ``course_id`` (str): The string value of the course's unique identifier
* ``username`` (str): The username ID identifying the user for which to retrieve the certificate

Raises:

HttpNotFoundError if no certificate found for the given user+course.

Returns:

a dict containing:

* ``username``: A string representation of an user's username passed in the request.
* ``course_id``: A string representation of a Course ID.
* ``certificate_type``: A string representation of the certificate type.
* ``created_date`: Datetime the certificate was created (tz-aware).
* ``status``: A string representation of the certificate status.
* ``is_passing``: True if the certificate has a passing status, False if not.
* ``download_url``: A string representation of the certificate url.
* ``grade``: A string representation of a float for the user's course grade.


def decorator(func):<EOL><INDENT>"""<STR_LIT>"""<EOL>@wraps(func)<EOL>def wrapper(*args, **kwargs):<EOL><INDENT>"""<STR_LIT>"""<EOL>message = '<STR_LIT>'.format(<EOL>function=func.__name__,<EOL>extra=extra<EOL>)<EOL>frame = inspect.currentframe().f_back<EOL>warnings.warn_explicit(<EOL>message,<EOL>category=DeprecationWarning,<EOL>filename=inspect.getfile(frame.f_code),<EOL>lineno=frame.f_lineno<EOL>)<EOL>return func(*args, **kwargs)<EOL><DEDENT>return wrapper<EOL><DEDENT>return decorator<EOL>

Flag a method as deprecated.

:param extra: Extra text you'd like to display after the default text.


def decorator(func):<EOL><INDENT>"""<STR_LIT>"""<EOL>@wraps(func)<EOL>def wrapper(*args, **kwargs):<EOL><INDENT>"""<STR_LIT>"""<EOL>warnings.simplefilter('<STR_LIT:ignore>', warning)<EOL>return func(*args, **kwargs)<EOL><DEDENT>return wrapper<EOL><DEDENT>return decorator<EOL>

Ignore any emitted warnings from a function.

:param warning: The category of warning to ignore.


<EOL>@wraps(signal_handler)<EOL>def wrapper(*args, **kwargs):<EOL><INDENT>"""<STR_LIT>"""<EOL>if kwargs.get('<STR_LIT>', False):<EOL><INDENT>return<EOL><DEDENT>signal_handler(*args, **kwargs)<EOL><DEDENT>return wrapper<EOL>

Use this decorator to turn off signal handlers when loading fixture data.

Django docs instruct to avoid further changes to the DB if raw=True as it might not be in a consistent state.
See https://docs.djangoproject.com/en/dev/ref/signals/#post-save


@wraps(view)<EOL>def wrapper(request, *args, **kwargs):<EOL><INDENT>"""<STR_LIT>"""<EOL>if '<STR_LIT>' not in kwargs:<EOL><INDENT>raise Http404<EOL><DEDENT>enterprise_uuid = kwargs['<STR_LIT>']<EOL>enterprise_customer = get_enterprise_customer_or_404(enterprise_uuid)<EOL>if not request.user.is_authenticated:<EOL><INDENT>parsed_current_url = urlparse(request.get_full_path())<EOL>parsed_query_string = parse_qs(parsed_current_url.query)<EOL>parsed_query_string.update({<EOL>'<STR_LIT>': enterprise_customer.identity_provider,<EOL>FRESH_LOGIN_PARAMETER: '<STR_LIT:yes>'<EOL>})<EOL>next_url = '<STR_LIT>'.format(<EOL>current_path=quote(parsed_current_url.path),<EOL>query_string=urlencode(parsed_query_string, doseq=True)<EOL>)<EOL>return redirect(<EOL>'<STR_LIT>'.format(<EOL>login_url='<STR_LIT>',<EOL>params=urlencode(<EOL>{'<STR_LIT>': next_url}<EOL>)<EOL>)<EOL>)<EOL><DEDENT>return view(request, *args, **kwargs)<EOL><DEDENT>return wrapper<EOL>

View decorator for allowing authenticated user with valid enterprise UUID.

This decorator requires enterprise identifier as a parameter
`enterprise_uuid`.

This decorator will throw 404 if no kwarg `enterprise_uuid` is provided to
the decorated view .

If there is no enterprise in database against the kwarg `enterprise_uuid`
or if the user is not authenticated then it will redirect the user to the
enterprise-linked SSO login page.

Usage::
    @enterprise_login_required()
    def my_view(request, enterprise_uuid):
        # Some functionality ...

    OR

    class MyView(View):
        ...
        @method_decorator(enterprise_login_required)
        def get(self, request, enterprise_uuid):
            # Some functionality ...


@wraps(view)<EOL>def wrapper(request, *args, **kwargs):<EOL><INDENT>"""<STR_LIT>"""<EOL>if not request.GET.get(FRESH_LOGIN_PARAMETER):<EOL><INDENT>enterprise_customer = get_enterprise_customer_or_404(kwargs.get('<STR_LIT>'))<EOL>provider_id = enterprise_customer.identity_provider or '<STR_LIT>'<EOL>sso_provider = get_identity_provider(provider_id)<EOL>if sso_provider:<EOL><INDENT>scheme, netloc, path, params, query, fragment = urlparse(request.get_full_path())<EOL>redirect_url = urlunparse((scheme, netloc, quote(path), params, query, fragment))<EOL>return redirect(<EOL>'<STR_LIT>'.format(<EOL>logout_url='<STR_LIT>',<EOL>params=urlencode(<EOL>{'<STR_LIT>': redirect_url}<EOL>)<EOL>)<EOL>)<EOL><DEDENT><DEDENT>return view(request, *args, **kwargs)<EOL><DEDENT>return wrapper<EOL>

View decorator which terminates stale TPA sessions.

This decorator forces the user to obtain a new session
the first time they access the decorated view. This prevents
TPA-authenticated users from hijacking the session of another
user who may have been previously logged in using the same
browser window.

This decorator should be used in conjunction with the
enterprise_login_required decorator.

Usage::
    @enterprise_login_required
    @force_fresh_session()
    def my_view(request, enterprise_uuid):
        # Some functionality ...

    OR

    class MyView(View):
        ...
        @method_decorator(enterprise_login_required)
        @method_decorator(force_fresh_session)
        def get(self, request, enterprise_uuid):
            # Some functionality ...


return func<EOL>

Use this decorator to stub out decorators for testing.

If we're unable to import social_core.pipeline.partial, which is the case in our CI platform,
we need to be able to wrap the function with something.


return "<STR_LIT>".format(<EOL>class_name=self.__class__.__name__,<EOL>username=self.username,<EOL>enterprise_name=self.enterprise_customer.name,<EOL>)<EOL>

Return a human-readable string representation.


return self.__str__()<EOL>

Return a uniquely identifying string representation.


children = getattr(self, '<STR_LIT>', [])<EOL>if children:<EOL><INDENT>return any((child.consent_required() for child in children))<EOL><DEDENT>if self.granted:<EOL><INDENT>return False<EOL><DEDENT>return bool(<EOL>(self.enterprise_customer.enforces_data_sharing_consent('<STR_LIT>')) and<EOL>(self.enterprise_customer.catalog_contains_course(self.course_id))<EOL>)<EOL>

Return a boolean value indicating whether a consent action must be taken.


Determine whether there exists an EnterpriseCourseEnrollment related to this consent record.


return self._exists or self.enterprise_enrollment_exists<EOL>

Determine whether a record related to the consent scenario exists.

First, check the instance's own `_exists` attribute; this is set to True
on database-backed instances that have a primary key, and may be manually
set to true on ProxyDataSharingConsent objects that have database-backed
children. If unsuccessful, check to see if an EnterpriseCourseEnrollment
related to this consent record exists; we treat that as though this record
exists for the purposes of serializable API responses.

We want to check for EnterpriseCourseEnrollment records because there are
cases where one will be created, but not the other. In particular, proxy
enrollments create an ECE but not any consent record. The LMS uses the
API's 'exists' key to determine if consent action should be taken for course
enrollments that have prior existence but for which consent has not been
granted. Thus, 'exists' is used as a proxy for the question "has any workflow
been entered which may involve a necessity for the learner to grant consent?"


details = {<EOL>'<STR_LIT:username>': self.username,<EOL>'<STR_LIT>': self.enterprise_customer.uuid,<EOL>'<STR_LIT>': self.exists,<EOL>'<STR_LIT>': self.granted,<EOL>'<STR_LIT>': self.consent_required(),<EOL>}<EOL>if self.course_id:<EOL><INDENT>details['<STR_LIT>'] = self.course_id<EOL><DEDENT>if getattr(self, '<STR_LIT>', None):<EOL><INDENT>details['<STR_LIT>'] = self.program_uuid<EOL><DEDENT>return details<EOL>

Return a dictionary that provides the core details of the consent record.


DataSharingConsent = apps.get_model('<STR_LIT>', '<STR_LIT>')<EOL>EnterpriseCourseEnrollment = apps.get_model('<STR_LIT>', '<STR_LIT>')<EOL>User = apps.get_model('<STR_LIT>', '<STR_LIT>')<EOL>for enrollment in EnterpriseCourseEnrollment.objects.all():<EOL><INDENT>user = User.objects.get(pk=enrollment.enterprise_customer_user.user_id)<EOL>data_sharing_consent, __ = DataSharingConsent.objects.get_or_create(<EOL>username=user.username,<EOL>enterprise_customer=enrollment.enterprise_customer_user.enterprise_customer,<EOL>course_id=enrollment.course_id,<EOL>)<EOL>if enrollment.consent_granted is not None:<EOL><INDENT>data_sharing_consent.granted = enrollment.consent_granted<EOL><DEDENT>else:<EOL><INDENT>consent_state = enrollment.enterprise_customer_user.data_sharing_consent.first()<EOL>if consent_state is not None:<EOL><INDENT>data_sharing_consent.granted = consent_state.state in ['<STR_LIT>', '<STR_LIT>']<EOL><DEDENT>else:<EOL><INDENT>data_sharing_consent.granted = False<EOL><DEDENT><DEDENT>data_sharing_consent.save()<EOL><DEDENT>

Populates the ``DataSharingConsent`` model with the ``enterprise`` application's consent data.

Consent data from the ``enterprise`` application come from the ``EnterpriseCourseEnrollment`` model.


def preview(self, consent_page, course_id='<STR_LIT>', program_uuid='<STR_LIT>'):

params = {<EOL>'<STR_LIT>': '<STR_LIT:true>',<EOL>'<STR_LIT>': course_id,<EOL>'<STR_LIT>': program_uuid,<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': consent_page.enterprise_customer.uuid<EOL>}<EOL>url = reverse('<STR_LIT>') + '<STR_LIT>'.format(urlencode(params))<EOL>return HttpResponseRedirect(url)<EOL>

Makes data sharing consent page url and querystring and redirects to it


def preview_as_course(self, request, consent_page):

return self.preview(consent_page, course_id='<STR_LIT>')<EOL>

Renders data sharing consent page in course context


def preview_as_program(self, request, consent_page):

return self.preview(consent_page, program_uuid='<STR_LIT>')<EOL>

Renders data sharing consent page in program context


username, course_id, program_uuid, enterprise_customer_uuid = self.get_required_query_params(request)<EOL>return get_data_sharing_consent(<EOL>username,<EOL>enterprise_customer_uuid,<EOL>course_id=course_id,<EOL>program_uuid=program_uuid<EOL>)<EOL>

Get the consent record relevant to the request at hand.


username = get_request_value(request, self.REQUIRED_PARAM_USERNAME, '<STR_LIT>')<EOL>course_id = get_request_value(request, self.REQUIRED_PARAM_COURSE_ID, '<STR_LIT>')<EOL>program_uuid = get_request_value(request, self.REQUIRED_PARAM_PROGRAM_UUID, '<STR_LIT>')<EOL>enterprise_customer_uuid = get_request_value(request, self.REQUIRED_PARAM_ENTERPRISE_CUSTOMER)<EOL>if not (username and (course_id or program_uuid) and enterprise_customer_uuid):<EOL><INDENT>raise ConsentAPIRequestError(<EOL>self.get_missing_params_message([<EOL>("<STR_LIT>", bool(username)),<EOL>("<STR_LIT>", bool(enterprise_customer_uuid)),<EOL>("<STR_LIT>", bool(course_id or program_uuid)),<EOL>])<EOL>)<EOL><DEDENT>return username, course_id, program_uuid, enterprise_customer_uuid<EOL>

Gets ``username``, ``course_id``, and ``enterprise_customer_uuid``,
which are the relevant query parameters for this API endpoint.

:param request: The request to this endpoint.
:return: The ``username``, ``course_id``, and ``enterprise_customer_uuid`` from the request.


params = '<STR_LIT:U+002CU+0020>'.join(name for name, present in parameter_state if not present)<EOL>return self.MISSING_REQUIRED_PARAMS_MSG.format(params)<EOL>

Get a user-friendly message indicating a missing parameter for the API endpoint.


username, course_id, program_uuid, enterprise_customer_uuid = self.get_required_query_params(request)<EOL>data = {<EOL>self.REQUIRED_PARAM_USERNAME: username,<EOL>self.REQUIRED_PARAM_ENTERPRISE_CUSTOMER: enterprise_customer_uuid,<EOL>self.CONSENT_EXISTS: False,<EOL>self.CONSENT_GRANTED: False,<EOL>self.CONSENT_REQUIRED: False,<EOL>}<EOL>if course_id:<EOL><INDENT>data[self.REQUIRED_PARAM_COURSE_ID] = course_id<EOL><DEDENT>if program_uuid:<EOL><INDENT>data[self.REQUIRED_PARAM_PROGRAM_UUID] = program_uuid<EOL><DEDENT>return Response(data, status=HTTP_200_OK)<EOL>

Get an HTTPResponse that can be used when there's no related EnterpriseCustomer.


try:<EOL><INDENT>consent_record = self.get_consent_record(request)<EOL>if consent_record is None:<EOL><INDENT>return self.get_no_record_response(request)<EOL><DEDENT><DEDENT>except ConsentAPIRequestError as invalid_request:<EOL><INDENT>return Response({'<STR_LIT:error>': str(invalid_request)}, status=HTTP_400_BAD_REQUEST)<EOL><DEDENT>return Response(consent_record.serialize(), status=HTTP_200_OK)<EOL>

GET /consent/api/v1/data_sharing_consent?username=bob&course_id=id&enterprise_customer_uuid=uuid
*username*
    The edX username from whom to get consent.
*course_id*
    The course for which consent is granted.
*enterprise_customer_uuid*
    The UUID of the enterprise customer that requires consent.


try:<EOL><INDENT>consent_record = self.get_consent_record(request)<EOL>if consent_record is None:<EOL><INDENT>return self.get_no_record_response(request)<EOL><DEDENT>if consent_record.consent_required():<EOL><INDENT>consent_record.granted = True<EOL>consent_record = consent_record.save() or consent_record<EOL><DEDENT><DEDENT>except ConsentAPIRequestError as invalid_request:<EOL><INDENT>return Response({'<STR_LIT:error>': str(invalid_request)}, status=HTTP_400_BAD_REQUEST)<EOL><DEDENT>return Response(consent_record.serialize())<EOL>

POST /consent/api/v1/data_sharing_consent

Requires a JSON object of the following format:
>>> {
>>>     "username": "bob",
>>>     "course_id": "course-v1:edX+DemoX+Demo_Course",
>>>     "enterprise_customer_uuid": "enterprise-uuid-goes-right-here"
>>> }

Keys:
*username*
    The edX username from whom to get consent.
*course_id*
    The course for which consent is granted.
*enterprise_customer_uuid*
    The UUID of the enterprise customer that requires consent.


try:<EOL><INDENT>consent_record = self.get_consent_record(request)<EOL>if consent_record is None:<EOL><INDENT>return self.get_no_record_response(request)<EOL><DEDENT>consent_record.granted = False<EOL>consent_record = consent_record.save() or consent_record<EOL><DEDENT>except ConsentAPIRequestError as invalid_request:<EOL><INDENT>return Response({'<STR_LIT:error>': str(invalid_request)}, status=HTTP_400_BAD_REQUEST)<EOL><DEDENT>return Response(consent_record.serialize())<EOL>

DELETE /consent/api/v1/data_sharing_consent

Requires a JSON object of the following format:
>>> {
>>>     "username": "bob",
>>>     "course_id": "course-v1:edX+DemoX+Demo_Course",
>>>     "enterprise_customer_uuid": "enterprise-uuid-goes-right-here"
>>> }

Keys:
*username*
    The edX username from whom to get consent.
*course_id*
    The course for which consent is granted.
*enterprise_customer_uuid*
    The UUID of the enterprise customer that requires consent.


def get_data_sharing_consent(username, enterprise_customer_uuid, course_id=None, program_uuid=None):

EnterpriseCustomer = apps.get_model('<STR_LIT>', '<STR_LIT>')  <EOL>try:<EOL><INDENT>if course_id:<EOL><INDENT>return get_course_data_sharing_consent(username, course_id, enterprise_customer_uuid)<EOL><DEDENT>return get_program_data_sharing_consent(username, program_uuid, enterprise_customer_uuid)<EOL><DEDENT>except EnterpriseCustomer.DoesNotExist:<EOL><INDENT>return None<EOL><DEDENT>

Get the data sharing consent object associated with a certain user, enterprise customer, and other scope.

:param username: The user that grants consent
:param enterprise_customer_uuid: The consent requester
:param course_id (optional): A course ID to which consent may be related
:param program_uuid (optional): A program to which consent may be related
:return: The data sharing consent object, or None if the enterprise customer for the given UUID does not exist.


def get_course_data_sharing_consent(username, course_id, enterprise_customer_uuid):

<EOL>DataSharingConsent = apps.get_model('<STR_LIT>', '<STR_LIT>')  <EOL>return DataSharingConsent.objects.proxied_get(<EOL>username=username,<EOL>course_id=course_id,<EOL>enterprise_customer__uuid=enterprise_customer_uuid<EOL>)<EOL>

Get the data sharing consent object associated with a certain user of a customer for a course.

:param username: The user that grants consent.
:param course_id: The course for which consent is granted.
:param enterprise_customer_uuid: The consent requester.
:return: The data sharing consent object


def get_program_data_sharing_consent(username, program_uuid, enterprise_customer_uuid):

enterprise_customer = get_enterprise_customer(enterprise_customer_uuid)<EOL>discovery_client = CourseCatalogApiServiceClient(enterprise_customer.site)<EOL>course_ids = discovery_client.get_program_course_keys(program_uuid)<EOL>child_consents = (<EOL>get_data_sharing_consent(username, enterprise_customer_uuid, course_id=individual_course_id)<EOL>for individual_course_id in course_ids<EOL>)<EOL>return ProxyDataSharingConsent.from_children(program_uuid, *child_consents)<EOL>

Get the data sharing consent object associated with a certain user of a customer for a program.

:param username: The user that grants consent.
:param program_uuid: The program for which consent is granted.
:param enterprise_customer_uuid: The consent requester.
:return: The data sharing consent object


original_kwargs = kwargs.copy()<EOL>if '<STR_LIT>' in kwargs:<EOL><INDENT>try:<EOL><INDENT>course_run_key = str(CourseKey.from_string(kwargs['<STR_LIT>']))<EOL><DEDENT>except InvalidKeyError:<EOL><INDENT>pass<EOL><DEDENT>else:<EOL><INDENT>try:<EOL><INDENT>return self.get(*args, **kwargs)<EOL><DEDENT>except DataSharingConsent.DoesNotExist:<EOL><INDENT>kwargs['<STR_LIT>'] = parse_course_key(course_run_key)<EOL><DEDENT><DEDENT><DEDENT>try:<EOL><INDENT>return self.get(*args, **kwargs)<EOL><DEDENT>except DataSharingConsent.DoesNotExist:<EOL><INDENT>return ProxyDataSharingConsent(**original_kwargs)<EOL><DEDENT>

Perform the query and returns a single object matching the given keyword arguments.

This customizes the queryset to return an instance of ``ProxyDataSharingConsent`` when
the searched-for ``DataSharingConsent`` instance does not exist.


ec_keys = {}<EOL>for key in kwargs:<EOL><INDENT>if str(key).startswith('<STR_LIT>'):<EOL><INDENT>enterprise_customer_detail = key[len('<STR_LIT>'):]<EOL>ec_keys[enterprise_customer_detail] = kwargs[key]<EOL><DEDENT><DEDENT>if ec_keys:<EOL><INDENT>enterprise_customer = EnterpriseCustomer.objects.get(**ec_keys)  <EOL><DEDENT>self.enterprise_customer = enterprise_customer<EOL>self.username = username<EOL>self.course_id = course_id<EOL>self.program_uuid = program_uuid<EOL>self.granted = granted<EOL>self._exists = exists<EOL>self._child_consents = child_consents or []<EOL>

Initialize a proxy version of ``DataSharingConsent`` which behaves similarly but does not exist in the DB.


@classmethod<EOL><INDENT>def from_children(cls, program_uuid, *children):<DEDENT>

if not children or any(child is None for child in children):<EOL><INDENT>return None<EOL><DEDENT>granted = all((child.granted for child in children))<EOL>exists = any((child.exists for child in children))<EOL>usernames = set([child.username for child in children])<EOL>enterprises = set([child.enterprise_customer for child in children])<EOL>if not len(usernames) == len(enterprises) == <NUM_LIT:1>:<EOL><INDENT>raise InvalidProxyConsent(<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>)<EOL><DEDENT>username = children[<NUM_LIT:0>].username<EOL>enterprise_customer = children[<NUM_LIT:0>].enterprise_customer<EOL>return cls(<EOL>enterprise_customer=enterprise_customer,<EOL>username=username,<EOL>program_uuid=program_uuid,<EOL>exists=exists,<EOL>granted=granted,<EOL>child_consents=children<EOL>)<EOL>

Build a ProxyDataSharingConsent using the details of the received consent records.


if self._child_consents:<EOL><INDENT>consents = []<EOL>for consent in self._child_consents:<EOL><INDENT>consent.granted = self.granted<EOL>consents.append(consent.save() or consent)<EOL><DEDENT>return ProxyDataSharingConsent.from_children(self.program_uuid, *consents)<EOL><DEDENT>consent, _ = DataSharingConsent.objects.update_or_create(<EOL>enterprise_customer=self.enterprise_customer,<EOL>username=self.username,<EOL>course_id=self.course_id,<EOL>defaults={<EOL>'<STR_LIT>': self.granted<EOL>}<EOL>)<EOL>self._exists = consent.exists<EOL>return consent<EOL>

Commit a real ``DataSharingConsent`` object to the database, mirroring current field settings.

:return: A ``DataSharingConsent`` object if validation is successful, otherwise ``None``.


return self.commit()<EOL>


return bool(self.pk)<EOL>

Return whether the instance exists or not.


return '<STR_LIT>'.format(<EOL>self.enterprise_customer.uuid<EOL>)<EOL>

Return human-readable string representation.


return self.__str__()<EOL>

Return uniquely identifying string representation.


super(TestEnterpriseConfig, self).setUp()<EOL>self.post_save_mock = mock.Mock()<EOL>patcher = mock.patch('<STR_LIT>', self.post_save_mock)<EOL>patcher.start()<EOL>self.app_config = enterprise.apps.EnterpriseConfig('<STR_LIT>', enterprise)<EOL>self.addCleanup(patcher.stop)<EOL>


super(TestIntegratedChannelConfig, self).setUp()<EOL>self.app_config = integrated_channels.integrated_channel.apps.IntegratedChannelConfig(<EOL>'<STR_LIT>', integrated_channels.integrated_channel<EOL>)<EOL>


super(TestSAPSuccessFactorsConfig, self).setUp()<EOL>self.app_config = integrated_channels.sap_success_factors.apps.SAPSuccessFactorsConfig(<EOL>'<STR_LIT>', integrated_channels.sap_success_factors<EOL>)<EOL>


super(TestDegreedConfig, self).setUp()<EOL>self.app_config = integrated_channels.degreed.apps.DegreedConfig(<EOL>'<STR_LIT>', integrated_channels.degreed<EOL>)<EOL>


super(TestXAPIConfig, self).setUp()<EOL>self.app_config = integrated_channels.xapi.apps.XAPIConfig(<EOL>'<STR_LIT>', integrated_channels.xapi<EOL>)<EOL>


super(TestEnterpriseDecorators, self).setUp()<EOL>faker = FakerFactory.create()<EOL>self.provider_id = faker.slug()  <EOL>self.uuid = faker.uuid4()  <EOL>self.customer = EnterpriseCustomerFactory(uuid=self.uuid)<EOL>EnterpriseCustomerIdentityProviderFactory(provider_id=self.provider_id, enterprise_customer=self.customer)<EOL>self.session_engine = import_module(settings.SESSION_ENGINE)<EOL>


request = RequestFactory().get(url)<EOL>request.user = user<EOL>session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME)<EOL>request.session = self.session_engine.SessionStore(session_key)<EOL>return request<EOL>


<EOL>self.request._messages = fallback.FallbackStorage(self.request)<EOL>strategy_mock = mock.MagicMock(request=self.request)<EOL>backend = mock.MagicMock(<EOL>name=None,<EOL>strategy=strategy_mock,<EOL>)<EOL>return backend<EOL>

Get a mocked request backend with mocked strategy.


@staticmethod<EOL><INDENT>def _make_file_mock(name="<STR_LIT>", size=<NUM_LIT> * <NUM_LIT>):<DEDENT>

file_mock = mock.MagicMock(spec=File, name="<STR_LIT>")<EOL>file_mock.name = name<EOL>file_mock.size = size<EOL>return file_mock<EOL>


self.faker = FakerFactory.create()<EOL>self.catalog_uuid = self.faker.uuid4()  <EOL>self.enterprise_uuid = self.faker.uuid4()  <EOL>self.enterprise_name = '<STR_LIT>'<EOL>super(TestEnterpriseCustomerCatalog, self).setUp()<EOL>


def _():<EOL><INDENT>"""<STR_LIT>"""<EOL>idp_list = []<EOL>for idp in idps:<EOL><INDENT>mock_idp = mock.Mock()<EOL>mock_idp.configure_mock(provider_id=idp, name=idp)<EOL>idp_list.append(mock_idp)<EOL><DEDENT>return idp_list<EOL><DEDENT>return _<EOL>


super(TestEnterpriseUtils, self).setUp()<EOL>faker = FakerFactory.create()<EOL>self.provider_id = faker.slug()  <EOL>self.uuid = faker.uuid4()  <EOL>self.customer = EnterpriseCustomerFactory(uuid=self.uuid)<EOL>EnterpriseCustomerIdentityProviderFactory(provider_id=self.provider_id, enterprise_customer=self.customer)<EOL>


super(TestSAPSuccessFactorsUtils, self).setUp()<EOL>faker = FakerFactory.create()<EOL>self.user = UserFactory()<EOL>self.uuid = faker.uuid4()  <EOL>self.customer = EnterpriseCustomerFactory(uuid=self.uuid)<EOL>self.enterprise_configuration = SAPSuccessFactorsEnterpriseCustomerConfiguration(<EOL>enterprise_customer=self.customer,<EOL>sapsf_base_url='<STR_LIT>',<EOL>key='<STR_LIT:key>',<EOL>secret='<STR_LIT>',<EOL>)<EOL>


self.executor.loader.build_graph()<EOL>self.executor.migrate(self.migrate_origin)<EOL>

Performs the migration to the designated origin.

This only really does anything if you have migrated forward
in some way or no migrations were performed at all.


self.executor.loader.build_graph()<EOL>self.executor.migrate(self.migrate_dest)<EOL>

Performs the migration to the designated destination.


self.migrate_to_dest()<EOL>self.migrate_to_origin()<EOL>

Migrates to the destination and back to the origin.

Can be used as a shortcut to test a forward- and backward-migration in one-go.


return self.executor.loader.project_state(self.migrate_origin).apps<EOL>

Returns the app in its original state -- the one that'd exist before migration.


return self.executor.loader.project_state(self.migrate_dest).apps<EOL>

Returns the app in a future state -- the one that'd exist after migration.


return self.model._meta.get_field('<STR_LIT:name>')<EOL>


def _assert_expectations(self, response, expected_body, expected_status):

response_body = self.load_json(response.content)<EOL>self.assertEqual(response.status_code, expected_status)<EOL>self.assertEqual(response_body, expected_body)<EOL>

Assert that the response's status code and body match our expectations.


self.enterprise_learner_role, __ = SystemWideEnterpriseRole.objects.get_or_create(name=ENTERPRISE_LEARNER_ROLE)<EOL>self.learner_user = UserFactory(id=<NUM_LIT:2>, email='<STR_LIT>')<EOL>self.enterprise_customer = EnterpriseCustomerFactory(<EOL>catalog=<NUM_LIT:1>,<EOL>name='<STR_LIT>',<EOL>)<EOL>super(TestEnterpriseLearnerRoleSignals, self).setUp()<EOL>

Setup for `TestEnterpriseLearnerRoleSignals` test.


def get_request(self, user=None, data=None):

request = APIRequestFactory().post('<STR_LIT:/>', data)<EOL>if user:<EOL><INDENT>force_authenticate(request, user=user)<EOL><DEDENT>return Request(request, parsers=(JSONParser(),))<EOL>


super(TestIsAdminUserOrInGroupPermissions, self).setUp()<EOL>self.user = UserFactory(email='<STR_LIT>', password='<STR_LIT:test>', is_staff=True)<EOL>


super(TestIsInEnterpriseGroupPermissions, self).setUp()<EOL>self.user = UserFactory(email='<STR_LIT>', password='<STR_LIT:test>', is_staff=True)<EOL>


super(TestEnterpriseAPIPagination, self).setUp()<EOL>self.request = APIRequestFactory().get(<EOL>reverse('<STR_LIT>'),<EOL>SERVER_NAME="<STR_LIT>",<EOL>)<EOL>self.data = {<EOL>"<STR_LIT:count>": <NUM_LIT:1>,<EOL>"<STR_LIT>": None,<EOL>"<STR_LIT>": None,<EOL>"<STR_LIT>": [<EOL>{<EOL>"<STR_LIT>": [<EOL>{<EOL>"<STR_LIT:description>": None,<EOL>"<STR_LIT>": [],<EOL>"<STR_LIT:name>": "<STR_LIT>",<EOL>"<STR_LIT>": None,<EOL>"<STR_LIT:key>": "<STR_LIT>",<EOL>"<STR_LIT>": None,<EOL>"<STR_LIT>": None,<EOL>"<STR_LIT>": None,<EOL>"<STR_LIT>": "<STR_LIT>"<EOL>}<EOL>],<EOL>"<STR_LIT>": "<STR_LIT>",<EOL>"<STR_LIT:title>": "<STR_LIT>",<EOL>"<STR_LIT>": [],<EOL>"<STR_LIT:image>": None,<EOL>"<STR_LIT>": [],<EOL>"<STR_LIT>": [],<EOL>"<STR_LIT>": "<STR_LIT>",<EOL>"<STR_LIT>": None,<EOL>"<STR_LIT>": [],<EOL>"<STR_LIT>": None,<EOL>"<STR_LIT:key>": "<STR_LIT>",<EOL>"<STR_LIT>": None,<EOL>"<STR_LIT>": None,<EOL>"<STR_LIT>": None,<EOL>"<STR_LIT>": []<EOL>}<EOL>]<EOL>}<EOL>


if any(key in ['<STR_LIT>', '<STR_LIT>'] for key in query_parameters):<EOL><INDENT>return url<EOL><DEDENT>scheme, netloc, path, query_string, fragment = urlsplit(url)<EOL>url_params = parse_qs(query_string)<EOL>url_params.update(query_parameters)<EOL>return urlunsplit(<EOL>(scheme, netloc, path, urlencode(url_params, doseq=True), fragment),<EOL>)<EOL>

returns a url with updated query parameters.


for item in items:<EOL><INDENT>factory.create(**item)<EOL><DEDENT>

Create model instances using given factory


enterprise_customer = factories.EnterpriseCustomerFactory(<EOL>uuid=FAKE_UUIDS[<NUM_LIT:0>],<EOL>name="<STR_LIT>",<EOL>enable_autocohorting=enable_autocohorting<EOL>)<EOL>permission = Permission.objects.get(name='<STR_LIT>')<EOL>self.user.user_permissions.add(permission)<EOL>user = None<EOL>if user_exists:<EOL><INDENT>if lms_user_id:<EOL><INDENT>user = factories.UserFactory(id=lms_user_id)<EOL><DEDENT>elif tpa_user_id:<EOL><INDENT>user = factories.UserFactory(username=tpa_user_id)<EOL><DEDENT>elif user_email:<EOL><INDENT>user = factories.UserFactory(email=user_email)<EOL><DEDENT>factories.EnterpriseCustomerUserFactory(<EOL>user_id=user.id,<EOL>enterprise_customer=enterprise_customer,<EOL>)<EOL><DEDENT>if tpa_user_id:<EOL><INDENT>mock_tpa_client.return_value = mock.Mock()<EOL>mock_tpa_client.return_value.get_username_from_remote_id = mock.Mock()<EOL>mock_tpa_client.return_value.get_username_from_remote_id.return_value = tpa_user_id<EOL><DEDENT>mock_enrollment_client.return_value = mock.Mock(<EOL>get_course_enrollment=mock.Mock(return_value=course_enrollment),<EOL>enroll_user_in_course=mock.Mock()<EOL>)<EOL>mock_catalog_contains_course.return_value = course_in_catalog<EOL>return enterprise_customer, user<EOL>

Set up for tests that call the enterprise customer course enrollments detail route.


super(TestEnterpriseAPIDecorators, self).setUp()<EOL>faker = FakerFactory.create()<EOL>self.provider_id = faker.slug()  <EOL>self.uuid = faker.uuid4()  <EOL>self.customer = EnterpriseCustomerFactory(uuid=self.uuid)<EOL>self.user = UserFactory()<EOL>self.session_engine = import_module(settings.SESSION_ENGINE)<EOL>


request = RequestFactory().get(url)<EOL>request.user = user<EOL>session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME)<EOL>request.session = self.session_engine.SessionStore(session_key)<EOL>return request<EOL>


super(TestEnterpriseAPIThrottling, self).setUp()<EOL>user = factories.UserFactory()<EOL>enterprise_customer = factories.EnterpriseCustomerFactory()<EOL>factories.EnterpriseCustomerUserFactory(enterprise_customer=enterprise_customer, user_id=user.id)<EOL>self.url = settings.TEST_SERVER + reverse('<STR_LIT>')<EOL>

Perform operations common for all tests.

Populate data base for api testing.


for item in range(throttle_limit):  <EOL><INDENT>response = self.client.get(self.url)<EOL>assert response.status_code == status.HTTP_200_OK<EOL><DEDENT>

Call enterprise api so that throttle limit is exhausted.


super(TestImmutableStateSerializer, self).setUp()<EOL>self.instance = None<EOL>self.data = {"<STR_LIT:data>": "<STR_LIT:data>"}<EOL>self.validated_data = self.data<EOL>self.serializer = ImmutableStateSerializer(self.data)<EOL>


super(TestEnterpriseCatalogCoursesSerializer, self).setUp()<EOL>faker = FakerFactory.create()<EOL>self.provider_id = faker.slug()  <EOL>self.user = factories.UserFactory()<EOL>self.enterprise_customer = factories.EnterpriseCustomerFactory(uuid='<STR_LIT>',<EOL>name="<STR_LIT>")<EOL>self.ecu = factories.EnterpriseCustomerUserFactory(<EOL>user_id=self.user.id,<EOL>enterprise_customer=self.enterprise_customer,<EOL>)<EOL>factories.EnterpriseCustomerIdentityProviderFactory(<EOL>enterprise_customer=self.ecu.enterprise_customer,<EOL>provider_id=self.provider_id,<EOL>)<EOL>self.request = APIRequestFactory().get(reverse('<STR_LIT>'))<EOL>self.request.user = self.user<EOL>self.instance = None<EOL>self.data = {<EOL>'<STR_LIT:count>': <NUM_LIT:1>,<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': [<EOL>{<EOL>'<STR_LIT>': [<EOL>{<EOL>'<STR_LIT:description>': None,<EOL>'<STR_LIT>': [],<EOL>'<STR_LIT:name>': '<STR_LIT>',<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT:key>': '<STR_LIT>',<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': '<STR_LIT>'<EOL>}<EOL>],<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT:title>': '<STR_LIT>',<EOL>'<STR_LIT>': [],<EOL>'<STR_LIT:image>': None,<EOL>'<STR_LIT>': [],<EOL>'<STR_LIT>': [],<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': [],<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT:key>': '<STR_LIT>',<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': [<EOL>{<EOL>'<STR_LIT:key>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT:title>': '<STR_LIT>',<EOL>'<STR_LIT:image>': {<EOL>'<STR_LIT:width>': None,<EOL>'<STR_LIT:src>': '<STR_LIT>',<EOL>'<STR_LIT:description>': None,<EOL>'<STR_LIT>': None<EOL>},<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT:start>': '<STR_LIT>',<EOL>'<STR_LIT:end>': '<STR_LIT>',<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT:type>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': [<EOL>{<EOL>'<STR_LIT:type>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': '<STR_LIT>'<EOL>}<EOL>],<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': [],<EOL>'<STR_LIT>': [],<EOL>'<STR_LIT>': [],<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': False,<EOL>'<STR_LIT>': False,<EOL>'<STR_LIT>': '<STR_LIT>'<EOL>}<EOL>]<EOL>}<EOL>]<EOL>}<EOL>self.validated_data = self.data<EOL>self.serializer = EnterpriseCatalogCoursesReadOnlySerializer(<EOL>self.data<EOL>)<EOL>


description = mock.MagicMock()<EOL>description.__iter__.return_value = (('<STR_LIT>',), ('<STR_LIT>',), ('<STR_LIT>',))<EOL>fetchall = mock.MagicMock()<EOL>fetchall.__iter__.return_value = [(self.user.id, self.enterprise_customer.uuid, self.course_run_id)]<EOL>connection_mock.cursor.return_value = mock.MagicMock(<EOL>__enter__=mock.MagicMock(<EOL>return_value=mock.MagicMock(<EOL>description=description,<EOL>fetchall=mock.MagicMock(<EOL>side_effect=lambda: fetchall<EOL>)<EOL>)<EOL>)<EOL>)<EOL>


def _setup_ecommerce_api_client(self, client_mock, method_name, return_value):

mocked_attributes = {<EOL>method_name: mock.MagicMock(return_value=return_value),<EOL>}<EOL>api_mock = mock.MagicMock(**mocked_attributes)<EOL>client_mock.return_value = api_mock<EOL>


return {<EOL>"<STR_LIT:key>": key,<EOL>"<STR_LIT>": [{"<STR_LIT:type>": seat_type} for seat_type in seat_types]<EOL>}<EOL>

Return course_run json representation expected by CourseCatalogAPI.


super(TestCourseCatalogApiService, self).setUp()<EOL>self.user_mock = mock.Mock(spec=User)<EOL>self.get_data_mock = self._make_patch(self._make_catalog_api_location("<STR_LIT>"))<EOL>self.jwt_builder_mock = self._make_patch(self._make_catalog_api_location("<STR_LIT>"))<EOL>self.integration_config_mock = mock.Mock(enabled=True)<EOL>self.integration_config_mock.get_service_user.return_value = self.user_mock<EOL>self.integration_mock = self._make_patch(self._make_catalog_api_location("<STR_LIT>"))<EOL>self.integration_mock.current.return_value = self.integration_config_mock<EOL>self.api = CourseCatalogApiServiceClient()<EOL>


self.enterprise_customer = EnterpriseCustomerFactory(<EOL>catalog=<NUM_LIT:1>,<EOL>name='<STR_LIT>',<EOL>)<EOL>super(TestEnterpriseApiClient, self).setUp()<EOL>self.catalog_api_config_mock = self._make_patch(self._make_catalog_api_location("<STR_LIT>"))<EOL>self.user = UserFactory(is_staff=True)<EOL>


cache.clear()<EOL>super(TestEnterpriseApiClient, self).tearDown()<EOL>