Add history table for course access rule changes. Provide test utility for simulating restricted access. Provide `redirect_if_blocked` method for integration with other parts of the system (will be used for blocking enrollment). Add info-level logging explaining when and why users are blocked.
83 lines
2.7 KiB
Python
83 lines
2.7 KiB
Python
"""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
|
|
from embargo.models import Country, CountryAccessRule, RestrictedCourse
|
|
|
|
|
|
@contextlib.contextmanager
|
|
def restrict_course(course_key, access_point="enrollment"):
|
|
"""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'
|
|
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
|