test_utils.py 2.81 KB
Newer Older
1 2 3 4 5 6 7 8
"""Utilities for writing unit tests that involve course embargos. """
import contextlib
import mock

import pygeoip

from django.core.urlresolvers import reverse
from django.core.cache import cache
9
from .models import Country, CountryAccessRule, RestrictedCourse
10 11 12


@contextlib.contextmanager
13
def restrict_course(course_key, access_point="enrollment", disable_access_check=False):
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
    """Simulate that a course is restricted.

    This does two things:
    1) Configures country access rules so that the course is restricted.
    2) Mocks the GeoIP call so the user appears to be coming
        from a country that's blocked from the course.

    This is useful for tests that need to verify
    that restricted users won't be able to access
    particular views.

    Arguments:
        course_key (CourseKey): The location of the course to block.

    Keyword Arguments:
        access_point (str): Either "courseware" or "enrollment"

    Yields:
        str: A URL to the page in the embargo app that explains
            why the user was blocked.

    Example Usage:
    >>> with restrict_course(course_key) as redirect_url:
    >>>     # The client will appear to be coming from
    >>>     # an IP address that is blocked.
    >>>     resp = self.client.get(url)
    >>>     self.assertRedirects(resp, redirect_url)

    """
    # Clear the cache to ensure that previous tests don't interfere
    # with this test.
    cache.clear()

    with mock.patch.object(pygeoip.GeoIP, 'country_code_by_addr') as mock_ip:

        # Remove all existing rules for the course
        CountryAccessRule.objects.all().delete()

        # Create the country object
        # Ordinarily, we'd create models for every country,
        # but that would slow down the test suite.
        country, __ = Country.objects.get_or_create(country='IR')

        # Create a model for the restricted course
        restricted_course, __ = RestrictedCourse.objects.get_or_create(course_key=course_key)
        restricted_course.enroll_msg_key = 'default'
        restricted_course.access_msg_key = 'default'
61
        restricted_course.disable_access_check = disable_access_check
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
        restricted_course.save()

        # Ensure that there is a blacklist rule for the country
        CountryAccessRule.objects.get_or_create(
            restricted_course=restricted_course,
            country=country,
            rule_type='blacklist'
        )

        # Simulate that the user is coming from the blacklisted country
        mock_ip.return_value = 'IR'

        # Yield the redirect url so the tests don't need to know
        # the embargo messaging URL structure.
        redirect_url = reverse(
            'embargo_blocked_message',
            kwargs={
                'access_point': access_point,
                'message_key': 'default'
            }
        )
        yield redirect_url