Use the Django TestClient for courseware unit tests, so that middleware is cleaned up properly
This commit is contained in:
@@ -30,7 +30,6 @@ from courseware.tests.factories import (
|
||||
)
|
||||
import courseware.views.views as views
|
||||
from courseware.tests.helpers import LoginEnrollmentTestCase
|
||||
from edxmako.tests import mako_middleware_process_request
|
||||
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
|
||||
from student.models import CourseEnrollment
|
||||
from student.roles import CourseCcxCoachRole
|
||||
@@ -137,21 +136,13 @@ class CoachAccessTestCaseCCX(SharedModuleStoreTestCase, LoginEnrollmentTestCase)
|
||||
CourseEnrollment.enroll(student, ccx_locator)
|
||||
|
||||
# Test for access of a coach
|
||||
request = self.request_factory.get(reverse('about_course', args=[unicode(ccx_locator)]))
|
||||
request.user = self.coach
|
||||
mako_middleware_process_request(request)
|
||||
resp = views.progress(request, course_id=unicode(ccx_locator), student_id=student.id)
|
||||
resp = self.client.get(reverse('student_progress', args=[unicode(ccx_locator), student.id]))
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
|
||||
# Assert access of a student
|
||||
request = self.request_factory.get(reverse('about_course', args=[unicode(ccx_locator)]))
|
||||
request.user = student
|
||||
mako_middleware_process_request(request)
|
||||
|
||||
with self.assertRaises(Http404) as context:
|
||||
views.progress(request, course_id=unicode(ccx_locator), student_id=self.coach.id)
|
||||
|
||||
self.assertIsNotNone(context.exception)
|
||||
self.client.login(username=student.username, password='test')
|
||||
resp = self.client.get(reverse('student_progress', args=[unicode(ccx_locator), self.coach.id]))
|
||||
self.assertEqual(resp.status_code, 404)
|
||||
|
||||
|
||||
@attr('shard_1')
|
||||
|
||||
@@ -43,7 +43,6 @@ from courseware.tests.factories import StudentModuleFactory, GlobalStaffFactory
|
||||
from courseware.url_helpers import get_redirect_url
|
||||
from courseware.user_state_client import DjangoXBlockUserStateClient
|
||||
from courseware.views.index import render_accordion, CoursewareIndex
|
||||
from edxmako.tests import mako_middleware_process_request
|
||||
from lms.djangoapps.commerce.utils import EcommerceService # pylint: disable=import-error
|
||||
from milestones.tests.utils import MilestonesTestCaseMixin
|
||||
from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration
|
||||
@@ -242,15 +241,13 @@ class ViewsTestCase(ModuleStoreTestCase):
|
||||
self.enrollment = CourseEnrollment.enroll(self.user, self.course_key)
|
||||
self.enrollment.created = self.date
|
||||
self.enrollment.save()
|
||||
self.request_factory = RequestFactory()
|
||||
chapter = 'Overview'
|
||||
self.chapter_url = '%s/%s/%s' % ('/courses', self.course_key, chapter)
|
||||
|
||||
self.org = u"ꜱᴛᴀʀᴋ ɪɴᴅᴜꜱᴛʀɪᴇꜱ"
|
||||
self.org_html = "<p>'+Stark/Industries+'</p>"
|
||||
|
||||
self.request = self.request_factory.get("foo")
|
||||
self.request.user = self.user
|
||||
self.assertTrue(self.client.login(username=self.user.username, password=self.password))
|
||||
|
||||
# refresh the course from the modulestore so that it has children
|
||||
self.course = modulestore().get_course(self.course.id)
|
||||
@@ -290,7 +287,6 @@ class ViewsTestCase(ModuleStoreTestCase):
|
||||
Verifies the response when the courseware index page is accessed with
|
||||
the given chapter and section names.
|
||||
"""
|
||||
self.client.login(username=self.user.username, password=self.password)
|
||||
url = reverse(
|
||||
'courseware_section',
|
||||
kwargs={
|
||||
@@ -304,7 +300,6 @@ class ViewsTestCase(ModuleStoreTestCase):
|
||||
return response
|
||||
|
||||
def test_index_no_visible_section_in_chapter(self):
|
||||
self.client.login(username=self.user.username, password=self.password)
|
||||
|
||||
# reload the chapter from the store so its children information is updated
|
||||
self.chapter = self.store.get_item(self.chapter.location)
|
||||
@@ -328,7 +323,7 @@ class ViewsTestCase(ModuleStoreTestCase):
|
||||
Create global staff user and log them in
|
||||
"""
|
||||
self.global_staff = GlobalStaffFactory.create() # pylint: disable=attribute-defined-outside-init
|
||||
self.client.login(username=self.global_staff.username, password='test')
|
||||
self.assertTrue(self.client.login(username=self.global_staff.username, password='test'))
|
||||
|
||||
def _create_url_for_enroll_staff(self):
|
||||
"""
|
||||
@@ -428,25 +423,22 @@ class ViewsTestCase(ModuleStoreTestCase):
|
||||
in_cart_span = '<span class="add-to-cart">'
|
||||
# don't mock this course due to shopping cart existence checking
|
||||
course = CourseFactory.create(org="new", number="unenrolled", display_name="course")
|
||||
request = self.request_factory.get(reverse('about_course', args=[unicode(course.id)]))
|
||||
request.user = AnonymousUser()
|
||||
|
||||
# Set up the edxmako middleware for this request to create the RequestContext
|
||||
mako_middleware_process_request(request)
|
||||
response = views.course_about(request, unicode(course.id))
|
||||
self.client.logout()
|
||||
response = self.client.get(reverse('about_course', args=[unicode(course.id)]))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertNotIn(in_cart_span, response.content)
|
||||
|
||||
# authenticated user with nothing in cart
|
||||
request.user = self.user
|
||||
response = views.course_about(request, unicode(course.id))
|
||||
self.assertTrue(self.client.login(username=self.user.username, password=self.password))
|
||||
response = self.client.get(reverse('about_course', args=[unicode(course.id)]))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertNotIn(in_cart_span, response.content)
|
||||
|
||||
# now add the course to the cart
|
||||
cart = shoppingcart.models.Order.get_cart_for_user(self.user)
|
||||
shoppingcart.models.PaidCourseRegistration.add_to_order(cart, course.id)
|
||||
response = views.course_about(request, unicode(course.id))
|
||||
response = self.client.get(reverse('about_course', args=[unicode(course.id)]))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertIn(in_cart_span, response.content)
|
||||
|
||||
@@ -468,19 +460,18 @@ class ViewsTestCase(ModuleStoreTestCase):
|
||||
course = CourseFactory.create()
|
||||
CourseModeFactory(mode_slug=CourseMode.PROFESSIONAL, course_id=course.id, sku=sku, min_price=1)
|
||||
|
||||
request = self.request_factory.get(reverse('about_course', args=[unicode(course.id)]))
|
||||
request.user = AnonymousUser() if is_anonymous else self.user
|
||||
|
||||
# Set up the edxmako middleware for this request to create the RequestContext
|
||||
mako_middleware_process_request(request)
|
||||
|
||||
# Generate the course about page content
|
||||
response = views.course_about(request, unicode(course.id))
|
||||
if is_anonymous:
|
||||
self.client.logout()
|
||||
else:
|
||||
self.assertTrue(self.client.login(username=self.user.username, password=self.password))
|
||||
|
||||
# Construct the link according the following scenarios and verify its presence in the response:
|
||||
# (1) shopping cart is enabled and the user is not logged in
|
||||
# (2) shopping cart is enabled and the user is logged in
|
||||
href = '<a href="{uri_stem}?sku={sku}" class="add-to-cart">'.format(uri_stem=checkout_page, sku=sku)
|
||||
|
||||
# Generate the course about page content
|
||||
response = self.client.get(reverse('about_course', args=[unicode(course.id)]))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertIn(href, response.content)
|
||||
|
||||
@@ -489,7 +480,6 @@ class ViewsTestCase(ModuleStoreTestCase):
|
||||
if not is_anonymous:
|
||||
self.assert_enrollment_link_present(is_anonymous=is_anonymous)
|
||||
else:
|
||||
request = self.request_factory.get("foo")
|
||||
self.assertEqual(EcommerceService().is_enabled(AnonymousUser()), False)
|
||||
|
||||
@ddt.data(True, False)
|
||||
@@ -504,7 +494,6 @@ class ViewsTestCase(ModuleStoreTestCase):
|
||||
if not is_anonymous:
|
||||
self.assert_enrollment_link_present(is_anonymous=is_anonymous)
|
||||
else:
|
||||
request = self.request_factory.get("foo")
|
||||
self.assertEqual(EcommerceService().is_enabled(AnonymousUser()), False)
|
||||
|
||||
def test_user_groups(self):
|
||||
@@ -553,7 +542,7 @@ class ViewsTestCase(ModuleStoreTestCase):
|
||||
self.section.location.name,
|
||||
'f'
|
||||
])
|
||||
self.client.login(username=self.user.username, password=self.password)
|
||||
self.assertTrue(self.client.login(username=self.user.username, password=self.password))
|
||||
response = self.client.get(request_url)
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
@@ -566,7 +555,7 @@ class ViewsTestCase(ModuleStoreTestCase):
|
||||
self.section.location.name,
|
||||
'1'
|
||||
]
|
||||
self.client.login(username=self.user.username, password=self.password)
|
||||
self.assertTrue(self.client.login(username=self.user.username, password=self.password))
|
||||
for idx, val in enumerate(url_parts):
|
||||
url_parts_copy = url_parts[:]
|
||||
url_parts_copy[idx] = val + u'χ'
|
||||
@@ -595,9 +584,8 @@ class ViewsTestCase(ModuleStoreTestCase):
|
||||
def test_jump_to_invalid(self):
|
||||
# TODO add a test for invalid location
|
||||
# TODO add a test for no data *
|
||||
request = self.request_factory.get(self.chapter_url)
|
||||
self.assertRaisesRegexp(Http404, 'Invalid course_key or usage_key', views.jump_to,
|
||||
request, 'bar', ())
|
||||
response = self.client.get(reverse('jump_to', args=['foo/bar/baz', 'baz']))
|
||||
self.assertEquals(response.status_code, 404)
|
||||
|
||||
@unittest.skip
|
||||
def test_no_end_on_about_page(self):
|
||||
@@ -623,13 +611,7 @@ class ViewsTestCase(ModuleStoreTestCase):
|
||||
If `expected_end_text` is None, verifies that the about page *does not* contain the text
|
||||
"Classes End".
|
||||
"""
|
||||
request = self.request_factory.get("foo")
|
||||
request.user = self.user
|
||||
|
||||
# TODO: Remove the dependency on MakoMiddleware (by making the views explicitly supply a RequestContext)
|
||||
mako_middleware_process_request(request)
|
||||
|
||||
result = views.course_about(request, course_id)
|
||||
result = self.client.get(reverse('about_course', args=[unicode(course.id)]))
|
||||
if expected_end_text is not None:
|
||||
self.assertContains(result, "Classes End")
|
||||
self.assertContains(result, expected_end_text)
|
||||
@@ -640,7 +622,7 @@ class ViewsTestCase(ModuleStoreTestCase):
|
||||
# log into a staff account
|
||||
admin = AdminFactory()
|
||||
|
||||
self.client.login(username=admin.username, password='test')
|
||||
self.assertTrue(self.client.login(username=admin.username, password='test'))
|
||||
|
||||
url = reverse('submission_history', kwargs={
|
||||
'course_id': unicode(self.course_key),
|
||||
@@ -655,7 +637,7 @@ class ViewsTestCase(ModuleStoreTestCase):
|
||||
# log into a staff account
|
||||
admin = AdminFactory()
|
||||
|
||||
self.client.login(username=admin.username, password='test')
|
||||
self.assertTrue(self.client.login(username=admin.username, password='test'))
|
||||
|
||||
# try it with an existing user and a malicious location
|
||||
url = reverse('submission_history', kwargs={
|
||||
@@ -679,7 +661,7 @@ class ViewsTestCase(ModuleStoreTestCase):
|
||||
# log into a staff account
|
||||
admin = AdminFactory.create()
|
||||
|
||||
self.client.login(username=admin.username, password='test')
|
||||
self.assertTrue(self.client.login(username=admin.username, password='test'))
|
||||
|
||||
usage_key = self.course_key.make_usage_key('problem', 'test-history')
|
||||
state_client = DjangoXBlockUserStateClient(admin)
|
||||
@@ -733,7 +715,7 @@ class ViewsTestCase(ModuleStoreTestCase):
|
||||
course_key = course.id
|
||||
client = Client()
|
||||
admin = AdminFactory.create()
|
||||
client.login(username=admin.username, password='test')
|
||||
self.assertTrue(client.login(username=admin.username, password='test'))
|
||||
state_client = DjangoXBlockUserStateClient(admin)
|
||||
usage_key = course_key.make_usage_key('problem', 'test-history')
|
||||
state_client.set(
|
||||
@@ -766,7 +748,6 @@ class ViewsTestCase(ModuleStoreTestCase):
|
||||
self.assertNotContains(response, checkbox_html, html=True)
|
||||
|
||||
def test_financial_assistance_page(self):
|
||||
self.client.login(username=self.user.username, password=self.password)
|
||||
url = reverse('financial_assistance')
|
||||
response = self.client.get(url)
|
||||
# This is a static page, so just assert that it is returned correctly
|
||||
@@ -796,7 +777,6 @@ class ViewsTestCase(ModuleStoreTestCase):
|
||||
)
|
||||
CourseEnrollmentFactory(course_id=course, user=self.user, mode=mode)
|
||||
|
||||
self.client.login(username=self.user.username, password=self.password)
|
||||
url = reverse('financial_assistance_form')
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
@@ -815,7 +795,6 @@ class ViewsTestCase(ModuleStoreTestCase):
|
||||
|
||||
def _submit_financial_assistance_form(self, data):
|
||||
"""Submit a financial assistance request."""
|
||||
self.client.login(username=self.user.username, password=self.password)
|
||||
url = reverse('submit_financial_assistance_request')
|
||||
return self.client.post(url, json.dumps(data), content_type='application/json')
|
||||
|
||||
@@ -898,53 +877,38 @@ class ViewsTestCase(ModuleStoreTestCase):
|
||||
reverse('financial_assistance_form'),
|
||||
reverse('submit_financial_assistance_request')
|
||||
):
|
||||
self.client.logout()
|
||||
response = self.client.get(url)
|
||||
self.assertRedirects(response, reverse('signin_user') + '?next=' + url)
|
||||
|
||||
def test_bypass_course_info(self):
|
||||
course_id = unicode(self.course_key)
|
||||
request = self.request_factory.get(
|
||||
reverse('info', args=[course_id])
|
||||
)
|
||||
|
||||
# Middleware is not supported by the request factory. Simulate a
|
||||
# logged-in user by setting request.user manually.
|
||||
request.user = self.user
|
||||
|
||||
# Set up the edxmako middleware for this request to create the RequestContext
|
||||
mako_middleware_process_request(request)
|
||||
|
||||
self.assertFalse(self.course.bypass_home)
|
||||
|
||||
self.assertIsNone(request.META.get('HTTP_REFERER')) # pylint: disable=no-member
|
||||
response = views.course_info(request, course_id)
|
||||
response = self.client.get(reverse('info', args=[course_id]))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
request.META['HTTP_REFERER'] = reverse('dashboard') # pylint: disable=no-member
|
||||
response = views.course_info(request, course_id)
|
||||
response = self.client.get(reverse('info', args=[course_id]), HTTP_REFERER=reverse('dashboard'))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
self.course.bypass_home = True
|
||||
self.store.update_item(self.course, self.user.id) # pylint: disable=no-member
|
||||
self.assertTrue(self.course.bypass_home)
|
||||
|
||||
response = views.course_info(request, course_id)
|
||||
response = self.client.get(reverse('info', args=[course_id]), HTTP_REFERER=reverse('dashboard'))
|
||||
|
||||
# assertRedirects would be great here, but it forces redirections to be absolute URLs.
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.assertEqual(
|
||||
response.url,
|
||||
reverse('courseware', args=[course_id])
|
||||
)
|
||||
self.assertRedirects(response, reverse('courseware', args=[course_id]), fetch_redirect_response=False)
|
||||
|
||||
request.META['HTTP_REFERER'] = 'foo' # pylint: disable=no-member
|
||||
response = views.course_info(request, course_id)
|
||||
response = self.client.get(reverse('info', args=[course_id]), HTTP_REFERER='foo')
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_accordion(self):
|
||||
request = RequestFactory().get('foo')
|
||||
request.user = self.user
|
||||
table_of_contents = toc_for_course(
|
||||
self.request.user,
|
||||
self.request,
|
||||
request.user,
|
||||
request,
|
||||
self.course,
|
||||
unicode(self.course.get_children()[0].scope_ids.usage_id),
|
||||
None,
|
||||
@@ -952,7 +916,7 @@ class ViewsTestCase(ModuleStoreTestCase):
|
||||
)
|
||||
|
||||
# removes newlines and whitespace from the returned view string
|
||||
view = ''.join(render_accordion(self.request, self.course, table_of_contents['chapters']).split())
|
||||
view = ''.join(render_accordion(request, self.course, table_of_contents['chapters']).split())
|
||||
# the course id unicode is re-encoded here because the quote function does not accept unicode
|
||||
course_id = quote(unicode(self.course.id).encode("utf-8"))
|
||||
|
||||
@@ -978,7 +942,7 @@ class BaseDueDateTests(ModuleStoreTestCase):
|
||||
"""
|
||||
__test__ = False
|
||||
|
||||
def get_text(self, course):
|
||||
def get_response(self, course):
|
||||
"""Return the rendered text for the page to be verified"""
|
||||
raise NotImplementedError
|
||||
|
||||
@@ -1005,10 +969,8 @@ class BaseDueDateTests(ModuleStoreTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(BaseDueDateTests, self).setUp()
|
||||
self.request_factory = RequestFactory()
|
||||
self.user = UserFactory.create()
|
||||
self.request = self.request_factory.get("foo")
|
||||
self.request.user = self.user
|
||||
self.assertTrue(self.client.login(username=self.user.username, password='test'))
|
||||
|
||||
self.time_with_tz = "due Sep 18, 2013 at 11:30 UTC"
|
||||
self.time_without_tz = "due Sep 18, 2013 at 11:30"
|
||||
@@ -1019,50 +981,50 @@ class BaseDueDateTests(ModuleStoreTestCase):
|
||||
# in course_module's init method, the date_display_format will be set accordingly to
|
||||
# remove the timezone.
|
||||
course = self.set_up_course(due_date_display_format=None, show_timezone=False)
|
||||
text = self.get_text(course)
|
||||
self.assertIn(self.time_without_tz, text)
|
||||
self.assertNotIn(self.time_with_tz, text)
|
||||
response = self.get_response(course)
|
||||
self.assertContains(response, self.time_without_tz)
|
||||
self.assertNotContains(response, self.time_with_tz)
|
||||
# Test that show_timezone has been cleared (which means you get the default value of True).
|
||||
self.assertTrue(course.show_timezone)
|
||||
|
||||
def test_defaults(self):
|
||||
course = self.set_up_course()
|
||||
text = self.get_text(course)
|
||||
self.assertIn(self.time_with_tz, text)
|
||||
response = self.get_response(course)
|
||||
self.assertContains(response, self.time_with_tz)
|
||||
|
||||
def test_format_none(self):
|
||||
# Same for setting the due date to None
|
||||
course = self.set_up_course(due_date_display_format=None)
|
||||
text = self.get_text(course)
|
||||
self.assertIn(self.time_with_tz, text)
|
||||
response = self.get_response(course)
|
||||
self.assertContains(response, self.time_with_tz)
|
||||
|
||||
def test_format_plain_text(self):
|
||||
# plain text due date
|
||||
course = self.set_up_course(due_date_display_format="foobar")
|
||||
text = self.get_text(course)
|
||||
self.assertNotIn(self.time_with_tz, text)
|
||||
self.assertIn("due foobar", text)
|
||||
response = self.get_response(course)
|
||||
self.assertNotContains(response, self.time_with_tz)
|
||||
self.assertContains(response, "due foobar")
|
||||
|
||||
def test_format_date(self):
|
||||
# due date with no time
|
||||
course = self.set_up_course(due_date_display_format=u"%b %d %y")
|
||||
text = self.get_text(course)
|
||||
self.assertNotIn(self.time_with_tz, text)
|
||||
self.assertIn("due Sep 18 13", text)
|
||||
response = self.get_response(course)
|
||||
self.assertNotContains(response, self.time_with_tz)
|
||||
self.assertContains(response, "due Sep 18 13")
|
||||
|
||||
def test_format_hidden(self):
|
||||
# hide due date completely
|
||||
course = self.set_up_course(due_date_display_format=u"")
|
||||
text = self.get_text(course)
|
||||
self.assertNotIn("due ", text)
|
||||
response = self.get_response(course)
|
||||
self.assertNotContains(response, "due ")
|
||||
|
||||
def test_format_invalid(self):
|
||||
# improperly formatted due_date_display_format falls through to default
|
||||
# (value of show_timezone does not matter-- setting to False to make that clear).
|
||||
course = self.set_up_course(due_date_display_format=u"%%%", show_timezone=False)
|
||||
text = self.get_text(course)
|
||||
self.assertNotIn("%%%", text)
|
||||
self.assertIn(self.time_with_tz, text)
|
||||
response = self.get_response(course)
|
||||
self.assertNotContains(response, "%%%")
|
||||
self.assertContains(response, self.time_with_tz)
|
||||
|
||||
|
||||
class TestProgressDueDate(BaseDueDateTests):
|
||||
@@ -1071,12 +1033,9 @@ class TestProgressDueDate(BaseDueDateTests):
|
||||
"""
|
||||
__test__ = True
|
||||
|
||||
def get_text(self, course):
|
||||
def get_response(self, course):
|
||||
""" Returns the HTML for the progress page """
|
||||
|
||||
# Set up the edxmako middleware for this request to create the RequestContext
|
||||
mako_middleware_process_request(self.request)
|
||||
return views.progress(self.request, course_id=unicode(course.id), student_id=self.user.id).content
|
||||
return self.client.get(reverse('progress', args=[unicode(course.id)]))
|
||||
|
||||
|
||||
class TestAccordionDueDate(BaseDueDateTests):
|
||||
@@ -1085,12 +1044,9 @@ class TestAccordionDueDate(BaseDueDateTests):
|
||||
"""
|
||||
__test__ = True
|
||||
|
||||
def get_text(self, course):
|
||||
def get_response(self, course):
|
||||
""" Returns the HTML for the accordion """
|
||||
table_of_contents = toc_for_course(
|
||||
self.request.user, self.request, course, unicode(course.get_children()[0].scope_ids.usage_id), None, None
|
||||
)
|
||||
return render_accordion(self.request, course, table_of_contents['chapters'])
|
||||
return self.client.get(reverse('courseware', args=[unicode(course.id)]), follow=True)
|
||||
|
||||
|
||||
@attr('shard_1')
|
||||
@@ -1102,13 +1058,7 @@ class StartDateTests(ModuleStoreTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(StartDateTests, self).setUp()
|
||||
self.request_factory = RequestFactory()
|
||||
self.user = UserFactory.create()
|
||||
self.request = self.request_factory.get("foo")
|
||||
|
||||
# Set up the edxmako middleware for this request to create the RequestContext
|
||||
mako_middleware_process_request(self.request)
|
||||
self.request.user = self.user
|
||||
|
||||
def set_up_course(self):
|
||||
"""
|
||||
@@ -1120,12 +1070,11 @@ class StartDateTests(ModuleStoreTestCase):
|
||||
course = modulestore().get_course(course.id)
|
||||
return course
|
||||
|
||||
def get_about_text(self, course_key):
|
||||
def get_about_response(self, course_key):
|
||||
"""
|
||||
Get the text of the /about page for the course.
|
||||
"""
|
||||
text = views.course_about(self.request, unicode(course_key)).content
|
||||
return text
|
||||
return self.client.get(reverse('about_course', args=[unicode(course_key)]))
|
||||
|
||||
@patch('util.date_utils.pgettext', fake_pgettext(translations={
|
||||
("abbreviated month name", "Sep"): "SEPTEMBER",
|
||||
@@ -1135,9 +1084,9 @@ class StartDateTests(ModuleStoreTestCase):
|
||||
}))
|
||||
def test_format_localized_in_studio_course(self):
|
||||
course = self.set_up_course()
|
||||
text = self.get_about_text(course.id)
|
||||
response = self.get_about_response(course.id)
|
||||
# The start date is set in the set_up_course function above.
|
||||
self.assertIn("2013-SEPTEMBER-16", text)
|
||||
self.assertContains(response, "2013-SEPTEMBER-16")
|
||||
|
||||
@patch('util.date_utils.pgettext', fake_pgettext(translations={
|
||||
("abbreviated month name", "Jul"): "JULY",
|
||||
@@ -1147,9 +1096,9 @@ class StartDateTests(ModuleStoreTestCase):
|
||||
}))
|
||||
@unittest.skip
|
||||
def test_format_localized_in_xml_course(self):
|
||||
text = self.get_about_text(SlashSeparatedCourseKey('edX', 'toy', 'TT_2012_Fall'))
|
||||
response = self.get_about_response(SlashSeparatedCourseKey('edX', 'toy', 'TT_2012_Fall'))
|
||||
# The start date is set in common/test/data/two_toys/policies/TT_2012_Fall/policy.json
|
||||
self.assertIn("2015-JULY-17", text)
|
||||
self.assertContains(response, "2015-JULY-17")
|
||||
|
||||
|
||||
@attr('shard_1')
|
||||
@@ -1163,13 +1112,8 @@ class ProgressPageTests(ModuleStoreTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(ProgressPageTests, self).setUp()
|
||||
self.request_factory = RequestFactory()
|
||||
self.user = UserFactory.create()
|
||||
self.request = self.request_factory.get("foo")
|
||||
self.request.user = self.user
|
||||
|
||||
# Set up the edxmako middleware for this request to create the RequestContext
|
||||
mako_middleware_process_request(self.request)
|
||||
self.assertTrue(self.client.login(username=self.user.username, password='test'))
|
||||
|
||||
self.setup_course()
|
||||
|
||||
@@ -1193,7 +1137,9 @@ class ProgressPageTests(ModuleStoreTestCase):
|
||||
"""
|
||||
Test that XSS attack is prevented
|
||||
"""
|
||||
resp = views.progress(self.request, course_id=unicode(self.course.id), student_id=self.user.id)
|
||||
resp = self.client.get(
|
||||
reverse('student_progress', args=[unicode(self.course.id), self.user.id])
|
||||
)
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
# Test that malicious code does not appear in html
|
||||
self.assertNotIn(malicious_code, resp.content)
|
||||
@@ -1201,7 +1147,9 @@ class ProgressPageTests(ModuleStoreTestCase):
|
||||
def test_pure_ungraded_xblock(self):
|
||||
ItemFactory.create(category='acid', parent_location=self.vertical.location)
|
||||
|
||||
resp = views.progress(self.request, course_id=unicode(self.course.id))
|
||||
resp = self.client.get(
|
||||
reverse('progress', args=[unicode(self.course.id)])
|
||||
)
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
|
||||
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
|
||||
@@ -1212,7 +1160,9 @@ class ProgressPageTests(ModuleStoreTestCase):
|
||||
"""
|
||||
|
||||
# Create new course with respect to 'default_store'
|
||||
# Enroll student into course
|
||||
self.course = CourseFactory.create(default_store=default_store)
|
||||
CourseEnrollmentFactory(user=self.user, course_id=self.course.id, mode=CourseMode.HONOR)
|
||||
|
||||
# Invalid Student Ids (Integer and Non-int)
|
||||
invalid_student_ids = [
|
||||
@@ -1220,16 +1170,15 @@ class ProgressPageTests(ModuleStoreTestCase):
|
||||
'azU3N_8$',
|
||||
]
|
||||
for invalid_id in invalid_student_ids:
|
||||
self.assertRaises(
|
||||
Http404, views.progress,
|
||||
self.request,
|
||||
course_id=unicode(self.course.id),
|
||||
student_id=invalid_id
|
||||
)
|
||||
|
||||
# Enroll student into course
|
||||
CourseEnrollment.enroll(self.user, self.course.id)
|
||||
resp = views.progress(self.request, course_id=unicode(self.course.id), student_id=self.user.id)
|
||||
resp = self.client.get(
|
||||
reverse('student_progress', args=[unicode(self.course.id), invalid_id])
|
||||
)
|
||||
self.assertEquals(resp.status_code, 404)
|
||||
|
||||
resp = self.client.get(
|
||||
reverse('student_progress', args=[unicode(self.course.id), self.user.id])
|
||||
)
|
||||
# Assert that valid 'student_id' returns 200 status
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
|
||||
@@ -1244,7 +1193,8 @@ class ProgressPageTests(ModuleStoreTestCase):
|
||||
# Create a new course, a user which will not be enrolled in course, admin user for staff access
|
||||
course = CourseFactory.create(default_store=default_store)
|
||||
not_enrolled_user = UserFactory.create()
|
||||
self.request.user = AdminFactory.create()
|
||||
admin = AdminFactory.create()
|
||||
self.assertTrue(self.client.login(username=admin.username, password='test'))
|
||||
|
||||
# Create and enable Credit course
|
||||
CreditCourse.objects.create(course_key=course.id, enabled=True)
|
||||
@@ -1265,25 +1215,38 @@ class ProgressPageTests(ModuleStoreTestCase):
|
||||
# Add a single credit requirement (final grade)
|
||||
set_credit_requirements(course.id, requirements)
|
||||
|
||||
resp = views.progress(self.request, course_id=unicode(course.id), student_id=not_enrolled_user.id)
|
||||
resp = self.client.get(
|
||||
reverse('student_progress', args=[unicode(course.id), not_enrolled_user.id])
|
||||
)
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
|
||||
def test_non_ascii_grade_cutoffs(self):
|
||||
resp = views.progress(self.request, course_id=unicode(self.course.id))
|
||||
resp = self.client.get(
|
||||
reverse('progress', args=[unicode(self.course.id)])
|
||||
)
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
|
||||
def test_generate_cert_config(self):
|
||||
resp = views.progress(self.request, course_id=unicode(self.course.id))
|
||||
|
||||
resp = self.client.get(
|
||||
reverse('progress', args=[unicode(self.course.id)])
|
||||
)
|
||||
self.assertNotContains(resp, 'Request Certificate')
|
||||
|
||||
# Enable the feature, but do not enable it for this course
|
||||
CertificateGenerationConfiguration(enabled=True).save()
|
||||
resp = views.progress(self.request, course_id=unicode(self.course.id))
|
||||
|
||||
resp = self.client.get(
|
||||
reverse('progress', args=[unicode(self.course.id)])
|
||||
)
|
||||
self.assertNotContains(resp, 'Request Certificate')
|
||||
|
||||
# Enable certificate generation for this course
|
||||
certs_api.set_cert_generation_enabled(self.course.id, True)
|
||||
resp = views.progress(self.request, course_id=unicode(self.course.id))
|
||||
|
||||
resp = self.client.get(
|
||||
reverse('progress', args=[unicode(self.course.id)])
|
||||
)
|
||||
self.assertNotContains(resp, 'Request Certificate')
|
||||
|
||||
@patch.dict('django.conf.settings.FEATURES', {'CERTIFICATES_HTML_VIEW': True})
|
||||
@@ -1326,7 +1289,9 @@ class ProgressPageTests(ModuleStoreTestCase):
|
||||
self.course.save()
|
||||
self.store.update_item(self.course, self.user.id)
|
||||
|
||||
resp = views.progress(self.request, course_id=unicode(self.course.id))
|
||||
resp = self.client.get(
|
||||
reverse('progress', args=[unicode(self.course.id)])
|
||||
)
|
||||
self.assertContains(resp, u"View Certificate")
|
||||
|
||||
self.assertContains(resp, u"You can keep working for a higher grade")
|
||||
@@ -1337,7 +1302,9 @@ class ProgressPageTests(ModuleStoreTestCase):
|
||||
certificates[0]['is_active'] = False
|
||||
self.store.update_item(self.course, self.user.id)
|
||||
|
||||
resp = views.progress(self.request, course_id=unicode(self.course.id))
|
||||
resp = self.client.get(
|
||||
reverse('progress', args=[unicode(self.course.id)])
|
||||
)
|
||||
self.assertNotContains(resp, u"View Your Certificate")
|
||||
self.assertNotContains(resp, u"You can now view your certificate")
|
||||
self.assertContains(resp, u"We're creating your certificate.")
|
||||
@@ -1364,11 +1331,13 @@ class ProgressPageTests(ModuleStoreTestCase):
|
||||
# Enable certificate generation for this course
|
||||
certs_api.set_cert_generation_enabled(self.course.id, True)
|
||||
|
||||
resp = views.progress(self.request, course_id=unicode(self.course.id))
|
||||
resp = self.client.get(
|
||||
reverse('progress', args=[unicode(self.course.id)])
|
||||
)
|
||||
self.assertContains(resp, u"Download Your Certificate")
|
||||
|
||||
@ddt.data(
|
||||
*itertools.product(((41, 4, True), (41, 4, False)), (True, False))
|
||||
*itertools.product(((55, 4, True), (55, 4, False)), (True, False))
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_query_counts(self, (sql_calls, mongo_calls, self_paced), self_paced_enabled):
|
||||
@@ -1376,7 +1345,9 @@ class ProgressPageTests(ModuleStoreTestCase):
|
||||
SelfPacedConfiguration(enabled=self_paced_enabled).save()
|
||||
self.setup_course(self_paced=self_paced)
|
||||
with self.assertNumQueries(sql_calls), check_mongo_calls(mongo_calls):
|
||||
resp = views.progress(self.request, course_id=unicode(self.course.id))
|
||||
resp = self.client.get(
|
||||
reverse('progress', args=[unicode(self.course.id)])
|
||||
)
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
|
||||
@patch('courseware.grades.grade', Mock(return_value={
|
||||
@@ -1405,7 +1376,9 @@ class ProgressPageTests(ModuleStoreTestCase):
|
||||
'lms.djangoapps.verify_student.models.SoftwareSecurePhotoVerification.user_is_verified'
|
||||
) as user_verify:
|
||||
user_verify.return_value = user_verified
|
||||
resp = views.progress(self.request, course_id=unicode(self.course.id))
|
||||
resp = self.client.get(
|
||||
reverse('progress', args=[unicode(self.course.id)])
|
||||
)
|
||||
|
||||
cert_button_hidden = course_mode is CourseMode.AUDIT or \
|
||||
course_mode in CourseMode.VERIFIED_MODES and not user_verified
|
||||
@@ -1503,8 +1476,7 @@ class GenerateUserCertTests(ModuleStoreTestCase):
|
||||
grade_cutoffs={'cutoff': 0.75, 'Pass': 0.5}
|
||||
)
|
||||
self.enrollment = CourseEnrollment.enroll(self.student, self.course.id, mode='honor')
|
||||
self.request = RequestFactory()
|
||||
self.client.login(username=self.student, password='123456')
|
||||
self.assertTrue(self.client.login(username=self.student, password='123456'))
|
||||
self.url = reverse('generate_user_cert', kwargs={'course_id': unicode(self.course.id)})
|
||||
|
||||
def test_user_with_out_passing_grades(self):
|
||||
@@ -1671,7 +1643,8 @@ class TestIndexView(ModuleStoreTestCase):
|
||||
|
||||
CourseEnrollmentFactory(user=user, course_id=course.id)
|
||||
|
||||
request = RequestFactory().get(
|
||||
self.assertTrue(self.client.login(username=user.username, password='test'))
|
||||
response = self.client.get(
|
||||
reverse(
|
||||
'courseware_section',
|
||||
kwargs={
|
||||
@@ -1681,15 +1654,8 @@ class TestIndexView(ModuleStoreTestCase):
|
||||
}
|
||||
)
|
||||
)
|
||||
request.user = user
|
||||
|
||||
# Set up the edxmako middleware for this request to create the RequestContext
|
||||
mako_middleware_process_request(request)
|
||||
|
||||
# Trigger the assertions embedded in the ViewCheckerBlocks
|
||||
response = CoursewareIndex.as_view()(
|
||||
request, unicode(course.id), chapter=chapter.url_name, section=section.url_name
|
||||
)
|
||||
self.assertEquals(response.content.count("ViewCheckerPassed"), 3)
|
||||
|
||||
@XBlock.register_temp_plugin(ActivateIDCheckerBlock, 'id_checker')
|
||||
@@ -1704,7 +1670,8 @@ class TestIndexView(ModuleStoreTestCase):
|
||||
|
||||
CourseEnrollmentFactory(user=user, course_id=course.id)
|
||||
|
||||
request = RequestFactory().get(
|
||||
self.assertTrue(self.client.login(username=user.username, password='test'))
|
||||
response = self.client.get(
|
||||
reverse(
|
||||
'courseware_section',
|
||||
kwargs={
|
||||
@@ -1714,14 +1681,6 @@ class TestIndexView(ModuleStoreTestCase):
|
||||
}
|
||||
) + '?activate_block_id=test_block_id'
|
||||
)
|
||||
request.user = user
|
||||
|
||||
# Set up the edxmako middleware for this request to create the RequestContext
|
||||
mako_middleware_process_request(request)
|
||||
|
||||
response = CoursewareIndex.as_view()(
|
||||
request, unicode(course.id), chapter=chapter.url_name, section=section.url_name
|
||||
)
|
||||
self.assertIn("Activate Block ID: test_block_id", response.content)
|
||||
|
||||
|
||||
@@ -1818,7 +1777,8 @@ class TestIndexViewWithGating(ModuleStoreTestCase, MilestonesTestCaseMixin):
|
||||
"""
|
||||
Test index view with a gated sequential raises Http404
|
||||
"""
|
||||
request = RequestFactory().get(
|
||||
self.assertTrue(self.client.login(username=self.user.username, password='test'))
|
||||
response = self.client.get(
|
||||
reverse(
|
||||
'courseware_section',
|
||||
kwargs={
|
||||
@@ -1828,18 +1788,8 @@ class TestIndexViewWithGating(ModuleStoreTestCase, MilestonesTestCaseMixin):
|
||||
}
|
||||
)
|
||||
)
|
||||
request.user = self.user
|
||||
|
||||
# Set up the edxmako middleware for this request to create the RequestContext
|
||||
mako_middleware_process_request(request)
|
||||
|
||||
with self.assertRaises(Http404):
|
||||
CoursewareIndex.as_view()(
|
||||
request,
|
||||
unicode(self.course.id),
|
||||
chapter=self.chapter.url_name,
|
||||
section=self.gated_seq.url_name
|
||||
)
|
||||
self.assertEquals(response.status_code, 404)
|
||||
|
||||
|
||||
class TestRenderXBlock(RenderXBlockTestMixin, ModuleStoreTestCase):
|
||||
|
||||
@@ -658,7 +658,6 @@ def course_about(request, course_id):
|
||||
@ensure_valid_course_key
|
||||
def progress(request, course_id, student_id=None):
|
||||
""" Display the progress page. """
|
||||
|
||||
course_key = CourseKey.from_string(course_id)
|
||||
|
||||
with modulestore().bulk_operations(course_key):
|
||||
@@ -673,6 +672,14 @@ def _progress(request, course_key, student_id):
|
||||
|
||||
Course staff are allowed to see the progress of students in their class.
|
||||
"""
|
||||
|
||||
if student_id is not None:
|
||||
try:
|
||||
student_id = int(student_id)
|
||||
# Check for ValueError if 'student_id' cannot be converted to integer.
|
||||
except ValueError:
|
||||
raise Http404
|
||||
|
||||
course = get_course_with_access(request.user, 'load', course_key, depth=None, check_if_enrolled=True)
|
||||
|
||||
# check to see if there is a required survey that must be taken before
|
||||
@@ -697,8 +704,7 @@ def _progress(request, course_key, student_id):
|
||||
raise Http404
|
||||
try:
|
||||
student = User.objects.get(id=student_id)
|
||||
# Check for ValueError if 'student_id' cannot be converted to integer.
|
||||
except (ValueError, User.DoesNotExist):
|
||||
except User.DoesNotExist:
|
||||
raise Http404
|
||||
|
||||
# NOTE: To make sure impersonation by instructor works, use
|
||||
|
||||
Reference in New Issue
Block a user