Files
edx-platform/lms/djangoapps/courseware/tests/helpers.py
2016-10-20 15:08:54 -04:00

192 lines
6.5 KiB
Python

"""
Helpers for courseware tests.
"""
import crum
import json
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
from django.test import TestCase
from django.test.client import RequestFactory
from courseware.access import has_access
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
from student.models import Registration
def get_request_for_user(user):
"""Create a request object for user."""
request = RequestFactory()
request.user = user
request.COOKIES = {}
request.META = {}
request.is_secure = lambda: True
request.get_host = lambda: "edx.org"
request.method = 'GET'
request.GET = {}
request.POST = {}
crum.set_current_request(request)
return request
class LoginEnrollmentTestCase(TestCase):
"""
Provides support for user creation,
activation, login, and course enrollment.
"""
user = None
def setup_user(self):
"""
Create a user account, activate, and log in.
"""
self.email = 'foo@test.com'
self.password = 'bar'
self.username = 'test'
self.user = self.create_account(
self.username,
self.email,
self.password,
)
self.activate_user(self.email)
self.login(self.email, self.password)
def assert_request_status_code(self, status_code, url, method="GET", **kwargs):
make_request = getattr(self.client, method.lower())
response = make_request(url, **kwargs)
self.assertEqual(
response.status_code, status_code,
"{method} request to {url} returned status code {actual}, "
"expected status code {expected}".format(
method=method, url=url,
actual=response.status_code, expected=status_code
)
)
return response
# ============ User creation and login ==============
def login(self, email, password):
"""
Login, check that the corresponding view's response has a 200 status code.
"""
resp = self.client.post(reverse('login'),
{'email': email, 'password': password})
self.assertEqual(resp.status_code, 200)
data = json.loads(resp.content)
self.assertTrue(data['success'])
def logout(self):
"""
Logout; check that the HTTP response code indicates redirection
as expected.
"""
# should redirect
self.assert_request_status_code(302, reverse('logout'))
def create_account(self, username, email, password):
"""
Create the account and check that it worked.
"""
url = reverse('create_account')
request_data = {
'username': username,
'email': email,
'password': password,
'name': 'username',
'terms_of_service': 'true',
'honor_code': 'true',
}
resp = self.assert_request_status_code(200, url, method="POST", data=request_data)
data = json.loads(resp.content)
self.assertEqual(data['success'], True)
# Check both that the user is created, and inactive
user = User.objects.get(email=email)
self.assertFalse(user.is_active)
return user
def activate_user(self, email):
"""
Look up the activation key for the user, then hit the activate view.
No error checking.
"""
activation_key = Registration.objects.get(user__email=email).activation_key
# and now we try to activate
url = reverse('activate', kwargs={'key': activation_key})
self.assert_request_status_code(200, url)
# Now make sure that the user is now actually activated
self.assertTrue(User.objects.get(email=email).is_active)
def enroll(self, course, verify=False):
"""
Try to enroll and return boolean indicating result.
`course` is an instance of CourseDescriptor.
`verify` is an optional boolean parameter specifying whether we
want to verify that the student was successfully enrolled
in the course.
"""
resp = self.client.post(reverse('change_enrollment'), {
'enrollment_action': 'enroll',
'course_id': course.id.to_deprecated_string(),
'check_access': True,
})
result = resp.status_code == 200
if verify:
self.assertTrue(result)
return result
def unenroll(self, course):
"""
Unenroll the currently logged-in user, and check that it worked.
`course` is an instance of CourseDescriptor.
"""
url = reverse('change_enrollment')
request_data = {
'enrollment_action': 'unenroll',
'course_id': course.id.to_deprecated_string(),
}
self.assert_request_status_code(200, url, method="POST", data=request_data)
class CourseAccessTestMixin(TestCase):
"""
Utility mixin for asserting access (or lack thereof) to courses.
If relevant, also checks access for courses' corresponding CourseOverviews.
"""
def assertCanAccessCourse(self, user, action, course):
"""
Assert that a user has access to the given action for a given course.
Test with both the given course and with a CourseOverview of the given
course.
Arguments:
user (User): a user.
action (str): type of access to test.
course (CourseDescriptor): a course.
"""
self.assertTrue(has_access(user, action, course))
self.assertTrue(has_access(user, action, CourseOverview.get_from_id(course.id)))
def assertCannotAccessCourse(self, user, action, course):
"""
Assert that a user lacks access to the given action the given course.
Test with both the given course and with a CourseOverview of the given
course.
Arguments:
user (User): a user.
action (str): type of access to test.
course (CourseDescriptor): a course.
Note:
It may seem redundant to have one method for testing access
and another method for testing lack thereof (why not just combine
them into one method with a boolean flag?), but it makes reading
stack traces of failed tests easier to understand at a glance.
"""
self.assertFalse(has_access(user, action, course))
self.assertFalse(has_access(user, action, CourseOverview.get_from_id(course.id)))