reafctor: ran pyupgrade on lms/djangoapps/courseware (#26739)
This commit is contained in:
@@ -31,7 +31,7 @@ from common.djangoapps.student.tests.factories import UserProfileFactory as Stud
|
||||
# TODO fix this (course_id and location are invalid names as constants, and course_id should really be COURSE_KEY)
|
||||
# pylint: disable=invalid-name
|
||||
course_id = CourseKey.from_string('edX/test_course/test')
|
||||
location = partial(course_id.make_usage_key, u'problem')
|
||||
location = partial(course_id.make_usage_key, 'problem')
|
||||
|
||||
|
||||
class UserProfileFactory(StudentUserProfileFactory):
|
||||
@@ -126,7 +126,7 @@ class GlobalStaffFactory(UserFactory):
|
||||
|
||||
|
||||
class StudentModuleFactory(DjangoModelFactory): # lint-amnesty, pylint: disable=missing-class-docstring
|
||||
class Meta(object):
|
||||
class Meta:
|
||||
model = StudentModule
|
||||
|
||||
module_type = "problem"
|
||||
@@ -139,7 +139,7 @@ class StudentModuleFactory(DjangoModelFactory): # lint-amnesty, pylint: disable
|
||||
|
||||
|
||||
class UserStateSummaryFactory(DjangoModelFactory): # lint-amnesty, pylint: disable=missing-class-docstring
|
||||
class Meta(object):
|
||||
class Meta:
|
||||
model = XModuleUserStateSummaryField
|
||||
|
||||
field_name = 'existing_field'
|
||||
@@ -148,7 +148,7 @@ class UserStateSummaryFactory(DjangoModelFactory): # lint-amnesty, pylint: disa
|
||||
|
||||
|
||||
class StudentPrefsFactory(DjangoModelFactory): # lint-amnesty, pylint: disable=missing-class-docstring
|
||||
class Meta(object):
|
||||
class Meta:
|
||||
model = XModuleStudentPrefsField
|
||||
|
||||
field_name = 'existing_field'
|
||||
@@ -158,7 +158,7 @@ class StudentPrefsFactory(DjangoModelFactory): # lint-amnesty, pylint: disable=
|
||||
|
||||
|
||||
class StudentInfoFactory(DjangoModelFactory): # lint-amnesty, pylint: disable=missing-class-docstring
|
||||
class Meta(object):
|
||||
class Meta:
|
||||
model = XModuleStudentInfoField
|
||||
|
||||
field_name = 'existing_field'
|
||||
@@ -171,6 +171,6 @@ class RequestFactoryNoCsrf(RequestFactory):
|
||||
RequestFactory, which disables csrf checks.
|
||||
"""
|
||||
def request(self, **kwargs):
|
||||
request = super(RequestFactoryNoCsrf, self).request(**kwargs) # lint-amnesty, pylint: disable=super-with-arguments
|
||||
request = super().request(**kwargs)
|
||||
setattr(request, '_dont_enforce_csrf_checks', True) # pylint: disable=literal-used-as-attribute
|
||||
return request
|
||||
|
||||
@@ -8,15 +8,12 @@ import json
|
||||
from collections import OrderedDict
|
||||
from datetime import timedelta
|
||||
|
||||
import six
|
||||
from django.contrib import messages
|
||||
from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user
|
||||
from django.test import TestCase
|
||||
from django.test.client import Client, RequestFactory
|
||||
from django.urls import reverse
|
||||
from django.utils.timezone import now
|
||||
from six import text_type
|
||||
from six.moves import range
|
||||
from xblock.field_data import DictFieldData
|
||||
|
||||
from common.djangoapps.edxmako.shortcuts import render_to_string
|
||||
@@ -94,7 +91,7 @@ class BaseTestXmodule(ModuleStoreTestCase):
|
||||
|
||||
self.item_descriptor.xmodule_runtime = self.new_module_runtime()
|
||||
|
||||
self.item_url = six.text_type(self.item_descriptor.location)
|
||||
self.item_url = str(self.item_descriptor.location)
|
||||
|
||||
def setup_course(self): # lint-amnesty, pylint: disable=missing-function-docstring
|
||||
self.course = CourseFactory.create(data=self.COURSE_DATA)
|
||||
@@ -132,7 +129,7 @@ class BaseTestXmodule(ModuleStoreTestCase):
|
||||
assert all(self.login_statuses)
|
||||
|
||||
def setUp(self):
|
||||
super(BaseTestXmodule, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.setup_course()
|
||||
self.initialize_module(metadata=self.METADATA, data=self.DATA)
|
||||
|
||||
@@ -140,7 +137,7 @@ class BaseTestXmodule(ModuleStoreTestCase):
|
||||
"""Return item url with dispatch."""
|
||||
return reverse(
|
||||
'xblock_handler',
|
||||
args=(six.text_type(self.course.id), quote_slashes(self.item_url), 'xmodule_handler', dispatch)
|
||||
args=(str(self.course.id), quote_slashes(self.item_url), 'xmodule_handler', dispatch)
|
||||
)
|
||||
|
||||
|
||||
@@ -150,7 +147,7 @@ class XModuleRenderingTestBase(BaseTestXmodule): # lint-amnesty, pylint: disabl
|
||||
"""
|
||||
Create a runtime that actually does html rendering
|
||||
"""
|
||||
runtime = super(XModuleRenderingTestBase, self).new_module_runtime() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
runtime = super().new_module_runtime()
|
||||
runtime.render_template = render_to_string
|
||||
return runtime
|
||||
|
||||
@@ -185,7 +182,7 @@ class LoginEnrollmentTestCase(TestCase):
|
||||
"""
|
||||
make_request = getattr(self.client, method.lower())
|
||||
response = make_request(url, **kwargs)
|
||||
assert response.status_code == status_code, u'{method} request to {url} returned status code {actual}, expected status code {expected}'.format(method=method, url=url, actual=response.status_code, expected=status_code) # pylint: disable=line-too-long
|
||||
assert response.status_code == status_code, f'{method} request to {url} returned status code {response.status_code}, expected status code {status_code}' # pylint: disable=line-too-long
|
||||
return response
|
||||
|
||||
def assert_account_activated(self, url, method="GET", **kwargs): # lint-amnesty, pylint: disable=missing-function-docstring
|
||||
@@ -257,7 +254,7 @@ class LoginEnrollmentTestCase(TestCase):
|
||||
"""
|
||||
resp = self.client.post(reverse('change_enrollment'), {
|
||||
'enrollment_action': 'enroll',
|
||||
'course_id': text_type(course.id),
|
||||
'course_id': str(course.id),
|
||||
'check_access': True,
|
||||
})
|
||||
result = resp.status_code == 200
|
||||
@@ -273,7 +270,7 @@ class LoginEnrollmentTestCase(TestCase):
|
||||
url = reverse('change_enrollment')
|
||||
request_data = {
|
||||
'enrollment_action': 'unenroll',
|
||||
'course_id': text_type(course.id),
|
||||
'course_id': str(course.id),
|
||||
}
|
||||
self.assert_request_status_code(200, url, method="POST", data=request_data)
|
||||
|
||||
@@ -387,7 +384,7 @@ def masquerade_as_group_member(user, course, partition_id, group_id):
|
||||
user,
|
||||
data={"role": "student", "user_partition_id": partition_id, "group_id": group_id}
|
||||
)
|
||||
response = MasqueradeView.as_view()(request, six.text_type(course.id))
|
||||
response = MasqueradeView.as_view()(request, str(course.id))
|
||||
setup_masquerade(request, course.id, True)
|
||||
return response.status_code
|
||||
|
||||
@@ -419,7 +416,7 @@ def get_expiration_banner_text(user, course, language='en'): # lint-amnesty, py
|
||||
if upgrade_deadline:
|
||||
formatted_upgrade_deadline = strftime_localized_html(upgrade_deadline, 'SHORT_DATE')
|
||||
|
||||
bannerText = u'<strong>Audit Access Expires {expiration_date}</strong><br>\
|
||||
bannerText = '<strong>Audit Access Expires {expiration_date}</strong><br>\
|
||||
You lose all access to this course, including your progress, on {expiration_date}.\
|
||||
<br>Upgrade by {upgrade_deadline} to get unlimited access to the course as long as it exists\
|
||||
on the site. <a id="FBE_banner" href="{upgrade_link}">Upgrade now<span class="sr-only"> to retain access past\
|
||||
@@ -429,7 +426,7 @@ def get_expiration_banner_text(user, course, language='en'): # lint-amnesty, py
|
||||
upgrade_deadline=formatted_upgrade_deadline
|
||||
)
|
||||
else:
|
||||
bannerText = u'<strong>Audit Access Expires {expiration_date}</strong><br>\
|
||||
bannerText = '<strong>Audit Access Expires {expiration_date}</strong><br>\
|
||||
You lose all access to this course, including your progress, on {expiration_date}.\
|
||||
'.format(
|
||||
expiration_date=formatted_expiration_date
|
||||
|
||||
@@ -5,17 +5,15 @@ Test the about xblock
|
||||
|
||||
import datetime
|
||||
|
||||
from unittest import mock
|
||||
from unittest.mock import patch
|
||||
import ddt
|
||||
import mock
|
||||
import pytz
|
||||
import six
|
||||
from ccx_keys.locator import CCXLocator
|
||||
from django.conf import settings
|
||||
from django.test.utils import override_settings
|
||||
from django.urls import reverse
|
||||
from milestones.tests.utils import MilestonesTestCaseMixin
|
||||
from mock import patch
|
||||
from six import text_type
|
||||
from waffle.testutils import override_switch
|
||||
|
||||
from common.djangoapps.course_modes.models import CourseMode
|
||||
@@ -59,7 +57,7 @@ class AboutTestCase(LoginEnrollmentTestCase, SharedModuleStoreTestCase, EventTra
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(AboutTestCase, cls).setUpClass()
|
||||
super().setUpClass()
|
||||
cls.course = CourseFactory.create()
|
||||
cls.course_without_about = CourseFactory.create(catalog_visibility=CATALOG_VISIBILITY_NONE)
|
||||
cls.course_with_about = CourseFactory.create(catalog_visibility=CATALOG_VISIBILITY_ABOUT)
|
||||
@@ -78,7 +76,7 @@ class AboutTestCase(LoginEnrollmentTestCase, SharedModuleStoreTestCase, EventTra
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
super(AboutTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
self.course_mode = CourseMode(
|
||||
course_id=self.purchase_course.id,
|
||||
@@ -92,7 +90,7 @@ class AboutTestCase(LoginEnrollmentTestCase, SharedModuleStoreTestCase, EventTra
|
||||
"""
|
||||
This test asserts that a non-logged in user can visit the course about page
|
||||
"""
|
||||
url = reverse('about_course', args=[text_type(self.course.id)])
|
||||
url = reverse('about_course', args=[str(self.course.id)])
|
||||
resp = self.client.get(url)
|
||||
self.assertContains(resp, "OOGIE BLOOGIE")
|
||||
|
||||
@@ -104,7 +102,7 @@ class AboutTestCase(LoginEnrollmentTestCase, SharedModuleStoreTestCase, EventTra
|
||||
This test asserts that a logged-in user can visit the course about page
|
||||
"""
|
||||
self.setup_user()
|
||||
url = reverse('about_course', args=[text_type(self.course.id)])
|
||||
url = reverse('about_course', args=[str(self.course.id)])
|
||||
resp = self.client.get(url)
|
||||
self.assertContains(resp, "OOGIE BLOOGIE")
|
||||
|
||||
@@ -115,7 +113,7 @@ class AboutTestCase(LoginEnrollmentTestCase, SharedModuleStoreTestCase, EventTra
|
||||
"""
|
||||
self.setup_user()
|
||||
self.enroll(self.course, True)
|
||||
url = reverse('about_course', args=[text_type(self.course.id)])
|
||||
url = reverse('about_course', args=[str(self.course.id)])
|
||||
resp = self.client.get(url)
|
||||
self.assertContains(resp, "You are enrolled in this course")
|
||||
self.assertContains(resp, "View Course")
|
||||
@@ -125,25 +123,25 @@ class AboutTestCase(LoginEnrollmentTestCase, SharedModuleStoreTestCase, EventTra
|
||||
"""
|
||||
Verify that the About Page honors the permission settings in the course module
|
||||
"""
|
||||
url = reverse('about_course', args=[text_type(self.course_with_about.id)])
|
||||
url = reverse('about_course', args=[str(self.course_with_about.id)])
|
||||
resp = self.client.get(url)
|
||||
self.assertContains(resp, "WITH ABOUT")
|
||||
|
||||
url = reverse('about_course', args=[text_type(self.course_without_about.id)])
|
||||
url = reverse('about_course', args=[str(self.course_without_about.id)])
|
||||
resp = self.client.get(url)
|
||||
assert resp.status_code == 404
|
||||
|
||||
@patch.dict(settings.FEATURES, {'ENABLE_MKTG_SITE': True})
|
||||
def test_logged_in_marketing(self):
|
||||
self.setup_user()
|
||||
url = reverse('about_course', args=[text_type(self.course.id)])
|
||||
url = reverse('about_course', args=[str(self.course.id)])
|
||||
resp = self.client.get(url)
|
||||
# should be redirected
|
||||
assert resp.status_code == 302
|
||||
# follow this time, and check we're redirected to the course home page
|
||||
resp = self.client.get(url, follow=True)
|
||||
target_url = resp.redirect_chain[-1][0]
|
||||
course_home_url = reverse('openedx.course_experience.course_home', args=[text_type(self.course.id)])
|
||||
course_home_url = reverse('openedx.course_experience.course_home', args=[str(self.course.id)])
|
||||
assert target_url.endswith(course_home_url)
|
||||
|
||||
@patch.dict(settings.FEATURES, {'ENABLE_COURSE_HOME_REDIRECT': False})
|
||||
@@ -154,7 +152,7 @@ class AboutTestCase(LoginEnrollmentTestCase, SharedModuleStoreTestCase, EventTra
|
||||
ENABLE_COURSE_HOME_REDIRECT is set to False
|
||||
"""
|
||||
self.setup_user()
|
||||
url = reverse('about_course', args=[text_type(self.course.id)])
|
||||
url = reverse('about_course', args=[str(self.course.id)])
|
||||
resp = self.client.get(url)
|
||||
# should not be redirected
|
||||
self.assertContains(resp, "OOGIE BLOOGIE")
|
||||
@@ -167,7 +165,7 @@ class AboutTestCase(LoginEnrollmentTestCase, SharedModuleStoreTestCase, EventTra
|
||||
ENABLE_MKTG_SITE is set to False
|
||||
"""
|
||||
self.setup_user()
|
||||
url = reverse('about_course', args=[text_type(self.course.id)])
|
||||
url = reverse('about_course', args=[str(self.course.id)])
|
||||
resp = self.client.get(url)
|
||||
# should not be redirected
|
||||
self.assertContains(resp, "OOGIE BLOOGIE")
|
||||
@@ -175,14 +173,14 @@ class AboutTestCase(LoginEnrollmentTestCase, SharedModuleStoreTestCase, EventTra
|
||||
@patch.dict(settings.FEATURES, {'ENABLE_PREREQUISITE_COURSES': True})
|
||||
def test_pre_requisite_course(self):
|
||||
pre_requisite_course = CourseFactory.create(org='edX', course='900', display_name='pre requisite course')
|
||||
course = CourseFactory.create(pre_requisite_courses=[text_type(pre_requisite_course.id)])
|
||||
course = CourseFactory.create(pre_requisite_courses=[str(pre_requisite_course.id)])
|
||||
self.setup_user()
|
||||
url = reverse('about_course', args=[text_type(course.id)])
|
||||
url = reverse('about_course', args=[str(course.id)])
|
||||
resp = self.client.get(url)
|
||||
assert resp.status_code == 200
|
||||
pre_requisite_courses = get_prerequisite_courses_display(course)
|
||||
pre_requisite_course_about_url = reverse('about_course', args=[text_type(pre_requisite_courses[0]['key'])])
|
||||
assert u'<span class="important-dates-item-text pre-requisite"><a href="{}">{}</a></span>'.format(pre_requisite_course_about_url, pre_requisite_courses[0]['display']) in resp.content.decode(resp.charset).strip('\n') # pylint: disable=line-too-long
|
||||
pre_requisite_course_about_url = reverse('about_course', args=[str(pre_requisite_courses[0]['key'])])
|
||||
assert '<span class="important-dates-item-text pre-requisite"><a href="{}">{}</a></span>'.format(pre_requisite_course_about_url, pre_requisite_courses[0]['display']) in resp.content.decode(resp.charset).strip('\n') # pylint: disable=line-too-long
|
||||
|
||||
@patch.dict(settings.FEATURES, {'ENABLE_PREREQUISITE_COURSES': True})
|
||||
def test_about_page_unfulfilled_prereqs(self):
|
||||
@@ -192,7 +190,7 @@ class AboutTestCase(LoginEnrollmentTestCase, SharedModuleStoreTestCase, EventTra
|
||||
display_name='pre requisite course',
|
||||
)
|
||||
|
||||
pre_requisite_courses = [text_type(pre_requisite_course.id)]
|
||||
pre_requisite_courses = [str(pre_requisite_course.id)]
|
||||
|
||||
# for this failure to occur, the enrollment window needs to be in the past
|
||||
course = CourseFactory.create(
|
||||
@@ -211,14 +209,14 @@ class AboutTestCase(LoginEnrollmentTestCase, SharedModuleStoreTestCase, EventTra
|
||||
self.enroll(self.course, True)
|
||||
self.enroll(pre_requisite_course, True)
|
||||
|
||||
url = reverse('about_course', args=[text_type(course.id)])
|
||||
url = reverse('about_course', args=[str(course.id)])
|
||||
resp = self.client.get(url)
|
||||
assert resp.status_code == 200
|
||||
pre_requisite_courses = get_prerequisite_courses_display(course)
|
||||
pre_requisite_course_about_url = reverse('about_course', args=[text_type(pre_requisite_courses[0]['key'])])
|
||||
assert u'<span class="important-dates-item-text pre-requisite"><a href="{}">{}</a></span>'.format(pre_requisite_course_about_url, pre_requisite_courses[0]['display']) in resp.content.decode(resp.charset).strip('\n') # pylint: disable=line-too-long
|
||||
pre_requisite_course_about_url = reverse('about_course', args=[str(pre_requisite_courses[0]['key'])])
|
||||
assert '<span class="important-dates-item-text pre-requisite"><a href="{}">{}</a></span>'.format(pre_requisite_course_about_url, pre_requisite_courses[0]['display']) in resp.content.decode(resp.charset).strip('\n') # pylint: disable=line-too-long
|
||||
|
||||
url = reverse('about_course', args=[six.text_type(pre_requisite_course.id)])
|
||||
url = reverse('about_course', args=[str(pre_requisite_course.id)])
|
||||
resp = self.client.get(url)
|
||||
assert resp.status_code == 200
|
||||
|
||||
@@ -235,7 +233,7 @@ class AboutTestCase(LoginEnrollmentTestCase, SharedModuleStoreTestCase, EventTra
|
||||
"""
|
||||
with mock.patch('xmodule.course_module.CourseBlock.course_visibility', course_visibility):
|
||||
with override_waffle_flag(COURSE_ENABLE_UNENROLLED_ACCESS_FLAG, active=True):
|
||||
url = reverse('about_course', args=[text_type(self.course.id)])
|
||||
url = reverse('about_course', args=[str(self.course.id)])
|
||||
resp = self.client.get(url)
|
||||
if course_visibility == COURSE_VISIBILITY_PUBLIC or course_visibility == COURSE_VISIBILITY_PUBLIC_OUTLINE: # lint-amnesty, pylint: disable=consider-using-in
|
||||
self.assertContains(resp, "View Course")
|
||||
@@ -253,7 +251,7 @@ class AboutTestCaseXML(LoginEnrollmentTestCase, ModuleStoreTestCase):
|
||||
"""
|
||||
Set up the tests
|
||||
"""
|
||||
super(AboutTestCaseXML, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
# The following test course (which lives at common/test/data/2014)
|
||||
# is closed; we're testing that an about page still appears when
|
||||
@@ -277,13 +275,13 @@ class AboutTestCaseXML(LoginEnrollmentTestCase, ModuleStoreTestCase):
|
||||
@patch.dict('django.conf.settings.FEATURES', {'DISABLE_START_DATES': False})
|
||||
def test_logged_in_xml(self):
|
||||
self.setup_user()
|
||||
url = reverse('about_course', args=[text_type(self.xml_course_id)])
|
||||
url = reverse('about_course', args=[str(self.xml_course_id)])
|
||||
resp = self.client.get(url)
|
||||
self.assertContains(resp, self.xml_data)
|
||||
|
||||
@patch.dict('django.conf.settings.FEATURES', {'DISABLE_START_DATES': False})
|
||||
def test_anonymous_user_xml(self):
|
||||
url = reverse('about_course', args=[text_type(self.xml_course_id)])
|
||||
url = reverse('about_course', args=[str(self.xml_course_id)])
|
||||
resp = self.client.get(url)
|
||||
self.assertContains(resp, self.xml_data)
|
||||
|
||||
@@ -294,7 +292,7 @@ class AboutWithCappedEnrollmentsTestCase(LoginEnrollmentTestCase, SharedModuleSt
|
||||
"""
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(AboutWithCappedEnrollmentsTestCase, cls).setUpClass()
|
||||
super().setUpClass()
|
||||
cls.course = CourseFactory.create(metadata={"max_student_enrollments_allowed": 1})
|
||||
cls.about = ItemFactory.create(
|
||||
category="about", parent_location=cls.course.location,
|
||||
@@ -306,7 +304,7 @@ class AboutWithCappedEnrollmentsTestCase(LoginEnrollmentTestCase, SharedModuleSt
|
||||
This test will make sure that enrollment caps are enforced
|
||||
"""
|
||||
self.setup_user()
|
||||
url = reverse('about_course', args=[text_type(self.course.id)])
|
||||
url = reverse('about_course', args=[str(self.course.id)])
|
||||
resp = self.client.get(url)
|
||||
self.assertContains(resp, '<a href="#" class="register">')
|
||||
|
||||
@@ -339,7 +337,7 @@ class AboutWithInvitationOnly(SharedModuleStoreTestCase):
|
||||
"""
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(AboutWithInvitationOnly, cls).setUpClass()
|
||||
super().setUpClass()
|
||||
cls.course = CourseFactory.create(metadata={"invitation_only": True})
|
||||
cls.about = ItemFactory.create(
|
||||
category="about", parent_location=cls.course.location,
|
||||
@@ -351,7 +349,7 @@ class AboutWithInvitationOnly(SharedModuleStoreTestCase):
|
||||
Test for user not logged in, invitation only course.
|
||||
"""
|
||||
|
||||
url = reverse('about_course', args=[text_type(self.course.id)])
|
||||
url = reverse('about_course', args=[str(self.course.id)])
|
||||
resp = self.client.get(url)
|
||||
self.assertContains(resp, "Enrollment in this course is by invitation only")
|
||||
|
||||
@@ -368,9 +366,9 @@ class AboutWithInvitationOnly(SharedModuleStoreTestCase):
|
||||
CourseEnrollmentAllowedFactory(email=user.email, course_id=self.course.id)
|
||||
self.client.login(username=user.username, password='test')
|
||||
|
||||
url = reverse('about_course', args=[text_type(self.course.id)])
|
||||
url = reverse('about_course', args=[str(self.course.id)])
|
||||
resp = self.client.get(url)
|
||||
self.assertContains(resp, u"Enroll Now")
|
||||
self.assertContains(resp, "Enroll Now")
|
||||
|
||||
# Check that registration button is present
|
||||
self.assertContains(resp, REG_STR)
|
||||
@@ -382,7 +380,7 @@ class AboutWithClosedEnrollment(ModuleStoreTestCase):
|
||||
set but it is currently outside of that period.
|
||||
"""
|
||||
def setUp(self):
|
||||
super(AboutWithClosedEnrollment, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
self.course = CourseFactory.create(metadata={"invitation_only": False})
|
||||
|
||||
@@ -401,7 +399,7 @@ class AboutWithClosedEnrollment(ModuleStoreTestCase):
|
||||
)
|
||||
|
||||
def test_closed_enrollmement(self):
|
||||
url = reverse('about_course', args=[text_type(self.course.id)])
|
||||
url = reverse('about_course', args=[str(self.course.id)])
|
||||
resp = self.client.get(url)
|
||||
self.assertContains(resp, "Enrollment is Closed")
|
||||
|
||||
@@ -409,7 +407,7 @@ class AboutWithClosedEnrollment(ModuleStoreTestCase):
|
||||
self.assertNotContains(resp, REG_STR)
|
||||
|
||||
def test_course_price_is_not_visble_in_sidebar(self):
|
||||
url = reverse('about_course', args=[text_type(self.course.id)])
|
||||
url = reverse('about_course', args=[str(self.course.id)])
|
||||
resp = self.client.get(url)
|
||||
# course price is not visible ihe course_about page when the course
|
||||
# mode is not set to honor
|
||||
@@ -422,7 +420,7 @@ class AboutSidebarHTMLTestCase(SharedModuleStoreTestCase):
|
||||
This test case will check the About page for the content in the HTML sidebar.
|
||||
"""
|
||||
def setUp(self):
|
||||
super(AboutSidebarHTMLTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.course = CourseFactory.create()
|
||||
|
||||
@ddt.data(
|
||||
@@ -449,7 +447,7 @@ class AboutSidebarHTMLTestCase(SharedModuleStoreTestCase):
|
||||
display_name=itemfactory_display_name,
|
||||
data=itemfactory_data,
|
||||
)
|
||||
url = reverse('about_course', args=[text_type(self.course.id)])
|
||||
url = reverse('about_course', args=[str(self.course.id)])
|
||||
resp = self.client.get(url)
|
||||
if waffle_switch_value and itemfactory_display_name and itemfactory_data:
|
||||
self.assertContains(resp, '<section class="about-sidebar-html">')
|
||||
@@ -467,11 +465,11 @@ class CourseAboutTestCaseCCX(SharedModuleStoreTestCase, LoginEnrollmentTestCase)
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(CourseAboutTestCaseCCX, cls).setUpClass()
|
||||
super().setUpClass()
|
||||
cls.course = CourseFactory.create()
|
||||
|
||||
def setUp(self):
|
||||
super(CourseAboutTestCaseCCX, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
# Create ccx coach account
|
||||
self.coach = coach = AdminFactory.create(password="test")
|
||||
@@ -485,7 +483,7 @@ class CourseAboutTestCaseCCX(SharedModuleStoreTestCase, LoginEnrollmentTestCase)
|
||||
|
||||
# create ccx
|
||||
ccx = CcxFactory(course_id=self.course.id, coach=self.coach)
|
||||
ccx_locator = CCXLocator.from_course_locator(self.course.id, six.text_type(ccx.id))
|
||||
ccx_locator = CCXLocator.from_course_locator(self.course.id, str(ccx.id))
|
||||
|
||||
self.setup_user()
|
||||
url = reverse('openedx.course_experience.course_home', args=[ccx_locator])
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Test the access control framework
|
||||
"""
|
||||
@@ -7,17 +6,16 @@ Test the access control framework
|
||||
import datetime
|
||||
import itertools
|
||||
|
||||
from unittest.mock import Mock, patch
|
||||
import pytest
|
||||
import ddt
|
||||
import pytz
|
||||
import six
|
||||
from ccx_keys.locator import CCXLocator
|
||||
from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user
|
||||
from django.test import TestCase
|
||||
from django.test.client import RequestFactory
|
||||
from django.urls import reverse
|
||||
from milestones.tests.utils import MilestonesTestCaseMixin
|
||||
from mock import Mock, patch
|
||||
from opaque_keys.edx.locator import CourseLocator
|
||||
|
||||
import lms.djangoapps.courseware.access as access
|
||||
@@ -75,14 +73,14 @@ class CoachAccessTestCaseCCX(SharedModuleStoreTestCase, LoginEnrollmentTestCase)
|
||||
"""
|
||||
Set up course for tests
|
||||
"""
|
||||
super(CoachAccessTestCaseCCX, cls).setUpClass()
|
||||
super().setUpClass()
|
||||
cls.course = CourseFactory.create()
|
||||
|
||||
def setUp(self):
|
||||
"""
|
||||
Set up tests
|
||||
"""
|
||||
super(CoachAccessTestCaseCCX, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
# Create ccx coach account
|
||||
self.coach = AdminFactory.create(password="test")
|
||||
@@ -104,7 +102,7 @@ class CoachAccessTestCaseCCX(SharedModuleStoreTestCase, LoginEnrollmentTestCase)
|
||||
)
|
||||
ccx.save()
|
||||
|
||||
ccx_locator = CCXLocator.from_course_locator(self.course.id, six.text_type(ccx.id))
|
||||
ccx_locator = CCXLocator.from_course_locator(self.course.id, str(ccx.id))
|
||||
role = CourseCcxCoachRole(ccx_locator)
|
||||
role.add_users(self.coach)
|
||||
CourseEnrollment.enroll(self.coach, ccx_locator)
|
||||
@@ -151,12 +149,12 @@ class CoachAccessTestCaseCCX(SharedModuleStoreTestCase, LoginEnrollmentTestCase)
|
||||
CourseEnrollment.enroll(student, ccx_locator)
|
||||
|
||||
# Test for access of a coach
|
||||
resp = self.client.get(reverse('student_progress', args=[six.text_type(ccx_locator), student.id]))
|
||||
resp = self.client.get(reverse('student_progress', args=[str(ccx_locator), student.id]))
|
||||
assert resp.status_code == 200
|
||||
|
||||
# Assert access of a student
|
||||
self.client.login(username=student.username, password='test')
|
||||
resp = self.client.get(reverse('student_progress', args=[six.text_type(ccx_locator), self.coach.id]))
|
||||
resp = self.client.get(reverse('student_progress', args=[str(ccx_locator), self.coach.id]))
|
||||
assert resp.status_code == 404
|
||||
|
||||
|
||||
@@ -175,7 +173,7 @@ class AccessTestCase(LoginEnrollmentTestCase, ModuleStoreTestCase, MilestonesTes
|
||||
}
|
||||
|
||||
def setUp(self):
|
||||
super(AccessTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.course = CourseFactory.create(org='edX', course='toy', run='test_run')
|
||||
self.anonymous_user = AnonymousUserFactory()
|
||||
self.beta_user = BetaTesterFactory(course_key=self.course.id)
|
||||
@@ -554,7 +552,7 @@ class AccessTestCase(LoginEnrollmentTestCase, ModuleStoreTestCase, MilestonesTes
|
||||
org='test_org', number='788', run='test_run'
|
||||
)
|
||||
|
||||
pre_requisite_courses = [six.text_type(pre_requisite_course.id)]
|
||||
pre_requisite_courses = [str(pre_requisite_course.id)]
|
||||
course = CourseFactory.create(
|
||||
org='test_org', number='786', run='test_run', pre_requisite_courses=pre_requisite_courses
|
||||
)
|
||||
@@ -600,7 +598,7 @@ class AccessTestCase(LoginEnrollmentTestCase, ModuleStoreTestCase, MilestonesTes
|
||||
run='test_run',
|
||||
)
|
||||
|
||||
pre_requisite_courses = [six.text_type(pre_requisite_course.id)]
|
||||
pre_requisite_courses = [str(pre_requisite_course.id)]
|
||||
course = CourseFactory.create(
|
||||
org='edX',
|
||||
course='1000',
|
||||
@@ -616,7 +614,7 @@ class AccessTestCase(LoginEnrollmentTestCase, ModuleStoreTestCase, MilestonesTes
|
||||
self.login(user.email, test_password)
|
||||
CourseEnrollmentFactory(user=user, course_id=course.id)
|
||||
|
||||
url = reverse('courseware', args=[six.text_type(course.id)])
|
||||
url = reverse('courseware', args=[str(course.id)])
|
||||
response = self.client.get(url)
|
||||
self.assertRedirects(
|
||||
response,
|
||||
@@ -637,7 +635,7 @@ class UserRoleTestCase(TestCase):
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(UserRoleTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.course_key = CourseLocator('edX', 'toy', '2012_Fall')
|
||||
self.anonymous_user = AnonymousUserFactory()
|
||||
self.student = UserFactory()
|
||||
@@ -680,7 +678,7 @@ class CourseOverviewAccessTestCase(ModuleStoreTestCase):
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(CourseOverviewAccessTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
today = datetime.datetime.now(pytz.UTC)
|
||||
last_week = today - datetime.timedelta(days=7)
|
||||
|
||||
@@ -15,7 +15,7 @@ class TestComprehensiveTheming(TestCase):
|
||||
"""Test comprehensive theming."""
|
||||
|
||||
def setUp(self):
|
||||
super(TestComprehensiveTheming, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
# Clear the internal staticfiles caches, to get test isolation.
|
||||
staticfiles.finders.get_finder.cache_clear()
|
||||
|
||||
@@ -3,8 +3,8 @@ Unit tests for courseware context_processor
|
||||
"""
|
||||
|
||||
|
||||
from unittest.mock import Mock
|
||||
from django.contrib.auth.models import AnonymousUser
|
||||
from mock import Mock
|
||||
|
||||
from lms.djangoapps.courseware.context_processor import user_timezone_locale_prefs
|
||||
from openedx.core.djangoapps.user_api.preferences.api import set_user_preference
|
||||
@@ -18,7 +18,7 @@ class UserPrefContextProcessorUnitTest(ModuleStoreTestCase):
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(UserPrefContextProcessorUnitTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
self.user = UserFactory.create()
|
||||
self.request = Mock()
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# coding=utf-8
|
||||
"""
|
||||
Test the course_info xblock
|
||||
"""
|
||||
@@ -6,16 +5,14 @@ Test the course_info xblock
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from unittest import mock
|
||||
import ddt
|
||||
import mock
|
||||
import six
|
||||
from ccx_keys.locator import CCXLocator
|
||||
from django.conf import settings
|
||||
from django.http import QueryDict
|
||||
from django.test.utils import override_settings
|
||||
from django.urls import reverse
|
||||
from edx_toggles.toggles.testutils import override_waffle_flag
|
||||
from six import text_type
|
||||
|
||||
from lms.djangoapps.ccx.tests.factories import CcxFactory
|
||||
from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration
|
||||
@@ -51,7 +48,7 @@ class CourseInfoTestCase(EnterpriseTestConsentRequired, LoginEnrollmentTestCase,
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(CourseInfoTestCase, cls).setUpClass()
|
||||
super().setUpClass()
|
||||
cls.course = CourseFactory.create()
|
||||
cls.page = ItemFactory.create(
|
||||
category="course_info", parent_location=cls.course.location,
|
||||
@@ -60,14 +57,14 @@ class CourseInfoTestCase(EnterpriseTestConsentRequired, LoginEnrollmentTestCase,
|
||||
|
||||
def test_logged_in_unenrolled(self):
|
||||
self.setup_user()
|
||||
url = reverse('info', args=[text_type(self.course.id)])
|
||||
url = reverse('info', args=[str(self.course.id)])
|
||||
resp = self.client.get(url)
|
||||
self.assertContains(resp, "OOGIE BLOOGIE")
|
||||
self.assertContains(resp, "You are not currently enrolled in this course")
|
||||
|
||||
def test_logged_in_enrolled(self):
|
||||
self.enroll(self.course)
|
||||
url = reverse('info', args=[text_type(self.course.id)])
|
||||
url = reverse('info', args=[str(self.course.id)])
|
||||
resp = self.client.get(url)
|
||||
assert b'You are not currently enrolled in this course' not in resp.content
|
||||
|
||||
@@ -85,19 +82,19 @@ class CourseInfoTestCase(EnterpriseTestConsentRequired, LoginEnrollmentTestCase,
|
||||
self.setup_user()
|
||||
self.enroll(self.course)
|
||||
|
||||
url = reverse('info', args=[text_type(self.course.id)])
|
||||
url = reverse('info', args=[str(self.course.id)])
|
||||
|
||||
self.verify_consent_required(self.client, url) # lint-amnesty, pylint: disable=no-value-for-parameter
|
||||
|
||||
def test_anonymous_user(self):
|
||||
url = reverse('info', args=[text_type(self.course.id)])
|
||||
url = reverse('info', args=[str(self.course.id)])
|
||||
resp = self.client.get(url)
|
||||
assert resp.status_code == 200
|
||||
assert b'OOGIE BLOOGIE' not in resp.content
|
||||
|
||||
def test_logged_in_not_enrolled(self):
|
||||
self.setup_user()
|
||||
url = reverse('info', args=[text_type(self.course.id)])
|
||||
url = reverse('info', args=[str(self.course.id)])
|
||||
self.client.get(url)
|
||||
|
||||
# Check whether the user has been enrolled in the course.
|
||||
@@ -116,7 +113,7 @@ class CourseInfoTestCase(EnterpriseTestConsentRequired, LoginEnrollmentTestCase,
|
||||
"""
|
||||
self.setup_user()
|
||||
self.enroll(self.course)
|
||||
url = reverse('info', args=[text_type(self.course.id)])
|
||||
url = reverse('info', args=[str(self.course.id)])
|
||||
response = self.client.get(url)
|
||||
start_date = strftime_localized(self.course.start, 'SHORT_DATE')
|
||||
expected_params = QueryDict(mutable=True)
|
||||
@@ -135,14 +132,14 @@ class CourseInfoTestCase(EnterpriseTestConsentRequired, LoginEnrollmentTestCase,
|
||||
"""
|
||||
self.setup_user()
|
||||
self.enroll(self.course)
|
||||
fake_unicode_start_time = u"üñîçø∂é_ßtå®t_tîµé"
|
||||
fake_unicode_start_time = "üñîçø∂é_ßtå®t_tîµé"
|
||||
mock_strftime_localized.return_value = fake_unicode_start_time
|
||||
|
||||
url = reverse('info', args=[text_type(self.course.id)])
|
||||
url = reverse('info', args=[str(self.course.id)])
|
||||
response = self.client.get(url)
|
||||
expected_params = QueryDict(mutable=True)
|
||||
expected_params['notlive'] = fake_unicode_start_time
|
||||
expected_url = u'{url}?{params}'.format(
|
||||
expected_url = '{url}?{params}'.format(
|
||||
url=reverse('dashboard'),
|
||||
params=expected_params.urlencode()
|
||||
)
|
||||
@@ -162,7 +159,7 @@ class CourseInfoLastAccessedTestCase(LoginEnrollmentTestCase, ModuleStoreTestCas
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(CourseInfoLastAccessedTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.course = CourseFactory.create()
|
||||
self.page = ItemFactory.create(
|
||||
category="course_info", parent_location=self.course.location,
|
||||
@@ -175,7 +172,7 @@ class CourseInfoLastAccessedTestCase(LoginEnrollmentTestCase, ModuleStoreTestCas
|
||||
is no course content.
|
||||
"""
|
||||
SelfPacedConfiguration(enable_course_home_improvements=True).save()
|
||||
url = reverse('info', args=(six.text_type(self.course.id),))
|
||||
url = reverse('info', args=(str(self.course.id),))
|
||||
response = self.client.get(url)
|
||||
content = pq(response.content)
|
||||
assert content('.page-header-secondary a').length == 0
|
||||
@@ -206,7 +203,7 @@ class CourseInfoLastAccessedTestCase(LoginEnrollmentTestCase, ModuleStoreTestCas
|
||||
}
|
||||
)
|
||||
self.client.get(section_url)
|
||||
info_url = reverse('info', args=(six.text_type(self.course.id),))
|
||||
info_url = reverse('info', args=(str(self.course.id),))
|
||||
|
||||
# Assuring a non-authenticated user cannot see the resume course button.
|
||||
resume_course_url = self.get_resume_course_url(info_url)
|
||||
@@ -230,7 +227,7 @@ class CourseInfoTitleTestCase(LoginEnrollmentTestCase, ModuleStoreTestCase):
|
||||
Tests of the CourseInfo page title site configuration options.
|
||||
"""
|
||||
def setUp(self):
|
||||
super(CourseInfoTitleTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.course = CourseFactory.create(
|
||||
org="HogwartZ",
|
||||
number="Potions_3",
|
||||
@@ -292,7 +289,7 @@ class CourseInfoTitleTestCase(LoginEnrollmentTestCase, ModuleStoreTestCase):
|
||||
Test the info page on a course with all the multiple display options
|
||||
depeding on the current site configuration
|
||||
"""
|
||||
url = reverse('info', args=(six.text_type(self.course.id),))
|
||||
url = reverse('info', args=(str(self.course.id),))
|
||||
with with_site_configuration_context(configuration=site_config):
|
||||
response = self.client.get(url)
|
||||
|
||||
@@ -317,11 +314,11 @@ class CourseInfoTestCaseCCX(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(CourseInfoTestCaseCCX, cls).setUpClass()
|
||||
super().setUpClass()
|
||||
cls.course = CourseFactory.create()
|
||||
|
||||
def setUp(self):
|
||||
super(CourseInfoTestCaseCCX, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
# Create ccx coach account
|
||||
self.coach = coach = AdminFactory.create(password="test")
|
||||
@@ -334,7 +331,7 @@ class CourseInfoTestCaseCCX(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
"""
|
||||
# create ccx
|
||||
ccx = CcxFactory(course_id=self.course.id, coach=self.coach)
|
||||
ccx_locator = CCXLocator.from_course_locator(self.course.id, six.text_type(ccx.id))
|
||||
ccx_locator = CCXLocator.from_course_locator(self.course.id, str(ccx.id))
|
||||
|
||||
self.setup_user()
|
||||
url = reverse('info', args=[ccx_locator])
|
||||
@@ -354,7 +351,7 @@ class CourseInfoTestCaseXML(LoginEnrollmentTestCase, ModuleStoreTestCase):
|
||||
"""
|
||||
Set up the tests
|
||||
"""
|
||||
super(CourseInfoTestCaseXML, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
# The following test course (which lives at common/test/data/2014)
|
||||
# is closed; we're testing that a course info page still appears when
|
||||
@@ -378,13 +375,13 @@ class CourseInfoTestCaseXML(LoginEnrollmentTestCase, ModuleStoreTestCase):
|
||||
@mock.patch.dict('django.conf.settings.FEATURES', {'DISABLE_START_DATES': False})
|
||||
def test_logged_in_xml(self):
|
||||
self.setup_user()
|
||||
url = reverse('info', args=[text_type(self.xml_course_key)])
|
||||
url = reverse('info', args=[str(self.xml_course_key)])
|
||||
resp = self.client.get(url)
|
||||
self.assertContains(resp, self.xml_data)
|
||||
|
||||
@mock.patch.dict('django.conf.settings.FEATURES', {'DISABLE_START_DATES': False})
|
||||
def test_anonymous_user_xml(self):
|
||||
url = reverse('info', args=[text_type(self.xml_course_key)])
|
||||
url = reverse('info', args=[str(self.xml_course_key)])
|
||||
resp = self.client.get(url)
|
||||
self.assertNotContains(resp, self.xml_data)
|
||||
|
||||
@@ -399,12 +396,12 @@ class SelfPacedCourseInfoTestCase(LoginEnrollmentTestCase, SharedModuleStoreTest
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(SelfPacedCourseInfoTestCase, cls).setUpClass()
|
||||
super().setUpClass()
|
||||
cls.instructor_paced_course = CourseFactory.create(self_paced=False)
|
||||
cls.self_paced_course = CourseFactory.create(self_paced=True)
|
||||
|
||||
def setUp(self):
|
||||
super(SelfPacedCourseInfoTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
ContentTypeGatingConfig.objects.create(enabled=True, enabled_as_of=datetime(2018, 1, 1))
|
||||
|
||||
self.setup_user()
|
||||
@@ -414,7 +411,7 @@ class SelfPacedCourseInfoTestCase(LoginEnrollmentTestCase, SharedModuleStoreTest
|
||||
Fetch the given course's info page, asserting the number of SQL
|
||||
and Mongo queries.
|
||||
"""
|
||||
url = reverse('info', args=[text_type(course.id)])
|
||||
url = reverse('info', args=[str(course.id)])
|
||||
with self.assertNumQueries(sql_queries, table_blacklist=QUERY_COUNT_TABLE_BLACKLIST):
|
||||
with check_mongo_calls(mongo_queries):
|
||||
with mock.patch("openedx.core.djangoapps.theming.helpers.get_current_site", return_value=None):
|
||||
|
||||
@@ -6,10 +6,8 @@ Python tests for the Survey workflows
|
||||
from collections import OrderedDict
|
||||
from copy import deepcopy
|
||||
|
||||
import six
|
||||
from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user
|
||||
from django.urls import reverse
|
||||
from six.moves import range
|
||||
|
||||
from common.test.utils import XssTestMixin
|
||||
from lms.djangoapps.courseware.tests.helpers import LoginEnrollmentTestCase
|
||||
@@ -26,7 +24,7 @@ class SurveyViewsTests(LoginEnrollmentTestCase, SharedModuleStoreTestCase, XssTe
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(SurveyViewsTests, cls).setUpClass()
|
||||
super().setUpClass()
|
||||
cls.test_survey_name = 'TestSurvey'
|
||||
cls.course = CourseFactory.create(
|
||||
display_name='<script>alert("XSS")</script>',
|
||||
@@ -45,20 +43,20 @@ class SurveyViewsTests(LoginEnrollmentTestCase, SharedModuleStoreTestCase, XssTe
|
||||
"""
|
||||
Set up the test data used in the specific tests
|
||||
"""
|
||||
super(SurveyViewsTests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
self.test_form = '<input name="field1"></input>'
|
||||
self.survey = SurveyForm.create(self.test_survey_name, self.test_form)
|
||||
|
||||
self.student_answers = OrderedDict({
|
||||
u'field1': u'value1',
|
||||
u'field2': u'value2',
|
||||
'field1': 'value1',
|
||||
'field2': 'value2',
|
||||
})
|
||||
|
||||
# Create student accounts and activate them.
|
||||
for i in range(len(self.STUDENT_INFO)):
|
||||
email, password = self.STUDENT_INFO[i]
|
||||
username = 'u{0}'.format(i)
|
||||
username = f'u{i}'
|
||||
self.create_account(username, email, password)
|
||||
self.activate_user(email)
|
||||
|
||||
@@ -81,12 +79,12 @@ class SurveyViewsTests(LoginEnrollmentTestCase, SharedModuleStoreTestCase, XssTe
|
||||
resp = self.client.get(
|
||||
reverse(
|
||||
view_name,
|
||||
kwargs={'course_id': six.text_type(course.id)}
|
||||
kwargs={'course_id': str(course.id)}
|
||||
)
|
||||
)
|
||||
self.assertRedirects(
|
||||
resp,
|
||||
reverse('course_survey', kwargs={'course_id': six.text_type(course.id)})
|
||||
reverse('course_survey', kwargs={'course_id': str(course.id)})
|
||||
)
|
||||
|
||||
def _assert_no_redirect(self, course):
|
||||
@@ -98,7 +96,7 @@ class SurveyViewsTests(LoginEnrollmentTestCase, SharedModuleStoreTestCase, XssTe
|
||||
resp = self.client.get(
|
||||
reverse(
|
||||
view_name,
|
||||
kwargs={'course_id': six.text_type(course.id)}
|
||||
kwargs={'course_id': str(course.id)}
|
||||
)
|
||||
)
|
||||
assert resp.status_code == 200
|
||||
@@ -125,7 +123,7 @@ class SurveyViewsTests(LoginEnrollmentTestCase, SharedModuleStoreTestCase, XssTe
|
||||
resp = self.client.get(
|
||||
reverse(
|
||||
'openedx.course_experience.course_home',
|
||||
kwargs={'course_id': six.text_type(self.course.id)}
|
||||
kwargs={'course_id': str(self.course.id)}
|
||||
)
|
||||
)
|
||||
assert resp.status_code == 200
|
||||
@@ -150,13 +148,13 @@ class SurveyViewsTests(LoginEnrollmentTestCase, SharedModuleStoreTestCase, XssTe
|
||||
resp = self.client.get(
|
||||
reverse(
|
||||
'course_survey',
|
||||
kwargs={'course_id': six.text_type(self.course.id)}
|
||||
kwargs={'course_id': str(self.course.id)}
|
||||
)
|
||||
)
|
||||
|
||||
assert resp.status_code == 200
|
||||
expected = u'<input type="hidden" name="course_id" value="{course_id}" />'.format(
|
||||
course_id=six.text_type(self.course.id)
|
||||
expected = '<input type="hidden" name="course_id" value="{course_id}" />'.format(
|
||||
course_id=str(self.course.id)
|
||||
)
|
||||
|
||||
self.assertContains(resp, expected)
|
||||
@@ -168,7 +166,7 @@ class SurveyViewsTests(LoginEnrollmentTestCase, SharedModuleStoreTestCase, XssTe
|
||||
|
||||
answers = deepcopy(self.student_answers)
|
||||
answers.update({
|
||||
'course_id': six.text_type(self.course.id)
|
||||
'course_id': str(self.course.id)
|
||||
})
|
||||
|
||||
resp = self.client.post(
|
||||
@@ -202,13 +200,13 @@ class SurveyViewsTests(LoginEnrollmentTestCase, SharedModuleStoreTestCase, XssTe
|
||||
resp = self.client.get(
|
||||
reverse(
|
||||
'course_survey',
|
||||
kwargs={'course_id': six.text_type(self.course_with_bogus_survey.id)}
|
||||
kwargs={'course_id': str(self.course_with_bogus_survey.id)}
|
||||
)
|
||||
)
|
||||
course_home_path = 'openedx.course_experience.course_home'
|
||||
self.assertRedirects(
|
||||
resp,
|
||||
reverse(course_home_path, kwargs={'course_id': six.text_type(self.course_with_bogus_survey.id)})
|
||||
reverse(course_home_path, kwargs={'course_id': str(self.course_with_bogus_survey.id)})
|
||||
)
|
||||
|
||||
def test_visiting_survey_with_no_course_survey(self):
|
||||
@@ -219,13 +217,13 @@ class SurveyViewsTests(LoginEnrollmentTestCase, SharedModuleStoreTestCase, XssTe
|
||||
resp = self.client.get(
|
||||
reverse(
|
||||
'course_survey',
|
||||
kwargs={'course_id': six.text_type(self.course_without_survey.id)}
|
||||
kwargs={'course_id': str(self.course_without_survey.id)}
|
||||
)
|
||||
)
|
||||
course_home_path = 'openedx.course_experience.course_home'
|
||||
self.assertRedirects(
|
||||
resp,
|
||||
reverse(course_home_path, kwargs={'course_id': six.text_type(self.course_without_survey.id)})
|
||||
reverse(course_home_path, kwargs={'course_id': str(self.course_without_survey.id)})
|
||||
)
|
||||
|
||||
def test_survey_xss(self):
|
||||
@@ -233,7 +231,7 @@ class SurveyViewsTests(LoginEnrollmentTestCase, SharedModuleStoreTestCase, XssTe
|
||||
response = self.client.get(
|
||||
reverse(
|
||||
'course_survey',
|
||||
kwargs={'course_id': six.text_type(self.course.id)}
|
||||
kwargs={'course_id': str(self.course.id)}
|
||||
)
|
||||
)
|
||||
self.assert_no_xss(response, '<script>alert("XSS")</script>')
|
||||
|
||||
@@ -5,10 +5,10 @@ Unit tests for course tools.
|
||||
|
||||
import datetime
|
||||
|
||||
from unittest.mock import patch
|
||||
import crum
|
||||
import pytz
|
||||
from django.test import RequestFactory
|
||||
from mock import patch
|
||||
|
||||
from common.djangoapps.course_modes.models import CourseMode
|
||||
from common.djangoapps.course_modes.tests.factories import CourseModeFactory
|
||||
@@ -24,7 +24,7 @@ class VerifiedUpgradeToolTest(SharedModuleStoreTestCase): # lint-amnesty, pylin
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(VerifiedUpgradeToolTest, cls).setUpClass()
|
||||
super().setUpClass()
|
||||
cls.now = datetime.datetime.now(pytz.UTC)
|
||||
|
||||
cls.course = CourseFactory.create(
|
||||
@@ -37,7 +37,7 @@ class VerifiedUpgradeToolTest(SharedModuleStoreTestCase): # lint-amnesty, pylin
|
||||
cls.course_overview = CourseOverview.get_from_id(cls.course.id)
|
||||
|
||||
def setUp(self):
|
||||
super(VerifiedUpgradeToolTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
self.course_verified_mode = CourseModeFactory(
|
||||
course_id=self.course.id,
|
||||
@@ -102,7 +102,7 @@ class FinancialAssistanceToolTest(SharedModuleStoreTestCase):
|
||||
"""
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(FinancialAssistanceToolTest, cls).setUpClass()
|
||||
super().setUpClass()
|
||||
cls.now = datetime.datetime.now(pytz.UTC)
|
||||
|
||||
cls.course = CourseFactory.create(
|
||||
@@ -114,7 +114,7 @@ class FinancialAssistanceToolTest(SharedModuleStoreTestCase):
|
||||
cls.course_overview = CourseOverview.get_from_id(cls.course.id)
|
||||
|
||||
def setUp(self):
|
||||
super(FinancialAssistanceToolTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
self.course_financial_mode = CourseModeFactory(
|
||||
course_id=self.course.id,
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Tests for course access
|
||||
"""
|
||||
@@ -7,11 +6,10 @@ Tests for course access
|
||||
import datetime
|
||||
import itertools
|
||||
|
||||
from unittest import mock
|
||||
import pytest
|
||||
import ddt
|
||||
import mock
|
||||
import pytz
|
||||
import six
|
||||
from completion.models import BlockCompletion
|
||||
from completion.test_utils import CompletionWaffleTestMixin
|
||||
from crum import set_current_request
|
||||
@@ -20,8 +18,6 @@ from django.test.client import RequestFactory
|
||||
from django.test.utils import override_settings
|
||||
from django.urls import reverse
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
from six import text_type
|
||||
from six.moves import range
|
||||
|
||||
from lms.djangoapps.courseware.courses import (
|
||||
course_open_for_self_enrollment,
|
||||
@@ -75,9 +71,9 @@ class CoursesTest(ModuleStoreTestCase):
|
||||
org='org', number='num', display_name='name'
|
||||
)
|
||||
|
||||
cms_url = u"//{}/course/{}".format(CMS_BASE_TEST, six.text_type(self.course.id))
|
||||
cms_url = "//{}/course/{}".format(CMS_BASE_TEST, str(self.course.id))
|
||||
assert cms_url == get_cms_course_link(self.course)
|
||||
cms_url = u"//{}/course/{}".format(CMS_BASE_TEST, six.text_type(self.course.location))
|
||||
cms_url = "//{}/course/{}".format(CMS_BASE_TEST, str(self.course.location))
|
||||
assert cms_url == get_cms_block_link(self.course, 'course')
|
||||
|
||||
@ddt.data(GET_COURSE_WITH_ACCESS, GET_COURSE_OVERVIEW_WITH_ACCESS)
|
||||
@@ -88,7 +84,7 @@ class CoursesTest(ModuleStoreTestCase):
|
||||
|
||||
with pytest.raises(CoursewareAccessException) as error:
|
||||
course_access_func(user, 'load', course.id)
|
||||
assert text_type(error.value) == 'Course not found.'
|
||||
assert str(error.value) == 'Course not found.'
|
||||
assert error.value.access_response.error_code == 'not_visible_to_user'
|
||||
assert not error.value.access_response.has_access
|
||||
|
||||
@@ -130,10 +126,10 @@ class CoursesTest(ModuleStoreTestCase):
|
||||
|
||||
unfiltered_courses = get_courses(user)
|
||||
for org in [primary_course.org, alternate_course.org]:
|
||||
assert any(((course.org == org) for course in unfiltered_courses))
|
||||
assert any((course.org == org) for course in unfiltered_courses)
|
||||
|
||||
filtered_courses = get_courses(user, org=primary)
|
||||
assert all(((course.org == primary_course.org) for course in filtered_courses))
|
||||
assert all((course.org == primary_course.org) for course in filtered_courses)
|
||||
|
||||
with mock.patch(
|
||||
'openedx.core.djangoapps.site_configuration.helpers.get_value',
|
||||
@@ -147,7 +143,7 @@ class CoursesTest(ModuleStoreTestCase):
|
||||
|
||||
# Request filtering for an org matching the designated org.
|
||||
site_courses = get_courses(user, org=alternate)
|
||||
assert all(((course.org == alternate_course.org) for course in site_courses))
|
||||
assert all((course.org == alternate_course.org) for course in site_courses)
|
||||
|
||||
def test_get_courses_with_filter(self):
|
||||
"""
|
||||
@@ -165,7 +161,7 @@ class CoursesTest(ModuleStoreTestCase):
|
||||
)
|
||||
for filter_, expected_courses in test_cases:
|
||||
assert {course.id for course in get_courses(user, filter_=filter_)} ==\
|
||||
expected_courses, u'testing get_courses with filter_={}'.format(filter_)
|
||||
expected_courses, f'testing get_courses with filter_={filter_}'
|
||||
|
||||
def test_get_current_child(self):
|
||||
mock_xmodule = mock.MagicMock()
|
||||
@@ -217,17 +213,17 @@ class MongoCourseImageTestCase(ModuleStoreTestCase):
|
||||
def test_get_image_url(self):
|
||||
"""Test image URL formatting."""
|
||||
course = CourseFactory.create(org='edX', course='999')
|
||||
assert course_image_url(course) == '/c4x/edX/999/asset/{0}'.format(course.course_image)
|
||||
assert course_image_url(course) == f'/c4x/edX/999/asset/{course.course_image}'
|
||||
|
||||
def test_non_ascii_image_name(self):
|
||||
# Verify that non-ascii image names are cleaned
|
||||
course = CourseFactory.create(course_image=u'before_\N{SNOWMAN}_after.jpg')
|
||||
assert course_image_url(course) == '/c4x/{org}/{course}/asset/before___after.jpg'.format(org=course.location.org, course=course.location.course) # pylint: disable=line-too-long
|
||||
course = CourseFactory.create(course_image='before_\N{SNOWMAN}_after.jpg')
|
||||
assert course_image_url(course) == f'/c4x/{course.location.org}/{course.location.course}/asset/before___after.jpg' # pylint: disable=line-too-long
|
||||
|
||||
def test_spaces_in_image_name(self):
|
||||
# Verify that image names with spaces in them are cleaned
|
||||
course = CourseFactory.create(course_image=u'before after.jpg')
|
||||
assert course_image_url(course) == '/c4x/{org}/{course}/asset/before_after.jpg'.format(org=course.location.org, course=course.location.course) # pylint: disable=line-too-long
|
||||
course = CourseFactory.create(course_image='before after.jpg')
|
||||
assert course_image_url(course) == f'/c4x/{course.location.org}/{course.location.course}/asset/before_after.jpg' # pylint: disable=line-too-long
|
||||
|
||||
def test_static_asset_path_course_image_default(self):
|
||||
"""
|
||||
@@ -242,7 +238,7 @@ class MongoCourseImageTestCase(ModuleStoreTestCase):
|
||||
Test that with course_image and static_asset_path both
|
||||
being set, that we get the right course_image url.
|
||||
"""
|
||||
course = CourseFactory.create(course_image=u'things_stuff.jpg',
|
||||
course = CourseFactory.create(course_image='things_stuff.jpg',
|
||||
static_asset_path="foo")
|
||||
assert course_image_url(course) == '/static/foo/things_stuff.jpg'
|
||||
|
||||
@@ -256,12 +252,12 @@ class XmlCourseImageTestCase(XModuleXmlImportTest):
|
||||
assert course_image_url(course) == '/static/xml_test_course/images/course_image.jpg'
|
||||
|
||||
def test_non_ascii_image_name(self):
|
||||
course = self.process_xml(xml.CourseFactory.build(course_image=u'before_\N{SNOWMAN}_after.jpg'))
|
||||
assert course_image_url(course) == u'/static/xml_test_course/before_☃_after.jpg'
|
||||
course = self.process_xml(xml.CourseFactory.build(course_image='before_\N{SNOWMAN}_after.jpg'))
|
||||
assert course_image_url(course) == '/static/xml_test_course/before_☃_after.jpg'
|
||||
|
||||
def test_spaces_in_image_name(self):
|
||||
course = self.process_xml(xml.CourseFactory.build(course_image=u'before after.jpg'))
|
||||
assert course_image_url(course) == u'/static/xml_test_course/before after.jpg'
|
||||
course = self.process_xml(xml.CourseFactory.build(course_image='before after.jpg'))
|
||||
assert course_image_url(course) == '/static/xml_test_course/before after.jpg'
|
||||
|
||||
|
||||
class CoursesRenderTest(ModuleStoreTestCase):
|
||||
@@ -273,7 +269,7 @@ class CoursesRenderTest(ModuleStoreTestCase):
|
||||
"""
|
||||
Set up the course and user context
|
||||
"""
|
||||
super(CoursesRenderTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
store = modulestore()
|
||||
course_items = import_course_from_xml(store, self.user.id, TEST_DATA_DIR, ['toy'])
|
||||
@@ -285,7 +281,7 @@ class CoursesRenderTest(ModuleStoreTestCase):
|
||||
def test_get_course_info_section_render(self):
|
||||
# Test render works okay
|
||||
course_info = get_course_info_section(self.request, self.request.user, self.course, 'handouts')
|
||||
assert course_info == u"<a href='/c4x/edX/toy/asset/handouts_sample_handout.txt'>Sample</a>"
|
||||
assert course_info == "<a href='/c4x/edX/toy/asset/handouts_sample_handout.txt'>Sample</a>"
|
||||
|
||||
# Test when render raises an exception
|
||||
with mock.patch('lms.djangoapps.courseware.courses.get_module') as mock_module_render:
|
||||
@@ -312,7 +308,7 @@ class CoursesRenderTest(ModuleStoreTestCase):
|
||||
|
||||
class CourseEnrollmentOpenTests(ModuleStoreTestCase): # lint-amnesty, pylint: disable=missing-class-docstring
|
||||
def setUp(self):
|
||||
super(CourseEnrollmentOpenTests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.now = datetime.datetime.now().replace(tzinfo=pytz.UTC)
|
||||
|
||||
def test_course_enrollment_open(self):
|
||||
@@ -362,7 +358,7 @@ class CourseInstantiationTests(ModuleStoreTestCase):
|
||||
Tests around instantiating a course multiple times in the same request.
|
||||
"""
|
||||
def setUp(self):
|
||||
super(CourseInstantiationTests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
self.factory = RequestFactory()
|
||||
|
||||
@@ -377,7 +373,7 @@ class CourseInstantiationTests(ModuleStoreTestCase):
|
||||
__ = ItemFactory(parent=section, category='problem')
|
||||
|
||||
fake_request = self.factory.get(
|
||||
reverse('progress', kwargs={'course_id': six.text_type(course.id)})
|
||||
reverse('progress', kwargs={'course_id': str(course.id)})
|
||||
)
|
||||
|
||||
course = modulestore().get_course(course.id, depth=course_depth)
|
||||
@@ -423,7 +419,7 @@ class TestGetCourseChapters(ModuleStoreTestCase):
|
||||
ItemFactory(parent=course, category='chapter')
|
||||
course_chapter_ids = get_course_chapter_ids(course.location.course_key)
|
||||
assert len(course_chapter_ids) == 2
|
||||
assert course_chapter_ids == [six.text_type(child) for child in course.children]
|
||||
assert course_chapter_ids == [str(child) for child in course.children]
|
||||
|
||||
|
||||
class TestGetCourseAssignments(CompletionWaffleTestMixin, ModuleStoreTestCase):
|
||||
|
||||
@@ -3,11 +3,10 @@ Tests for credit requirement display on the progress page.
|
||||
"""
|
||||
|
||||
|
||||
from unittest.mock import patch
|
||||
import ddt
|
||||
import six
|
||||
from django.conf import settings
|
||||
from django.urls import reverse
|
||||
from mock import patch
|
||||
|
||||
from common.djangoapps.course_modes.models import CourseMode
|
||||
from openedx.core.djangoapps.credit import api as credit_api
|
||||
@@ -33,11 +32,11 @@ class ProgressPageCreditRequirementsTest(SharedModuleStoreTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(ProgressPageCreditRequirementsTest, cls).setUpClass()
|
||||
super().setUpClass()
|
||||
cls.course = CourseFactory.create()
|
||||
|
||||
def setUp(self):
|
||||
super(ProgressPageCreditRequirementsTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
# Configure course as a credit course
|
||||
CreditCourse.objects.create(course_key=self.course.id, enabled=True)
|
||||
@@ -89,7 +88,7 @@ class ProgressPageCreditRequirementsTest(SharedModuleStoreTestCase):
|
||||
self.assertContains(response, "Upcoming")
|
||||
self.assertContains(
|
||||
response,
|
||||
u"{}, you have not yet met the requirements for credit".format(self.USER_FULL_NAME)
|
||||
f"{self.USER_FULL_NAME}, you have not yet met the requirements for credit"
|
||||
)
|
||||
|
||||
def test_credit_requirements_eligible(self):
|
||||
@@ -116,13 +115,13 @@ class ProgressPageCreditRequirementsTest(SharedModuleStoreTestCase):
|
||||
self.assertContains(response, self.VERIFICATION_REQ_DISPLAY)
|
||||
self.assertContains(
|
||||
response,
|
||||
u"{}, you have met the requirements for credit in this course.".format(self.USER_FULL_NAME)
|
||||
f"{self.USER_FULL_NAME}, you have met the requirements for credit in this course."
|
||||
)
|
||||
self.assertContains(response, u"Completed by {date}")
|
||||
self.assertContains(response, "Completed by {date}")
|
||||
|
||||
credit_requirements = credit_api.get_credit_requirement_status(self.course.id, self.user.username)
|
||||
for requirement in credit_requirements:
|
||||
self.assertContains(response, requirement['status_date'].strftime(u'%Y-%m-%d %H:%M'))
|
||||
self.assertContains(response, requirement['status_date'].strftime('%Y-%m-%d %H:%M'))
|
||||
self.assertNotContains(response, "95%")
|
||||
|
||||
def test_credit_requirements_not_eligible(self):
|
||||
@@ -142,7 +141,7 @@ class ProgressPageCreditRequirementsTest(SharedModuleStoreTestCase):
|
||||
self.assertContains(response, self.VERIFICATION_REQ_DISPLAY)
|
||||
self.assertContains(
|
||||
response,
|
||||
u"{}, you are no longer eligible for credit in this course.".format(self.USER_FULL_NAME)
|
||||
f"{self.USER_FULL_NAME}, you are no longer eligible for credit in this course."
|
||||
)
|
||||
self.assertContains(response, "Verification Failed")
|
||||
|
||||
@@ -170,5 +169,5 @@ class ProgressPageCreditRequirementsTest(SharedModuleStoreTestCase):
|
||||
|
||||
def _get_progress_page(self):
|
||||
"""Load the progress page for the course the user is enrolled in. """
|
||||
url = reverse("progress", kwargs={"course_id": six.text_type(self.course.id)})
|
||||
url = reverse("progress", kwargs={"course_id": str(self.course.id)})
|
||||
return self.client.get(url)
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# lint-amnesty, pylint: disable=django-not-configured
|
||||
"""Tests for course home page date summary blocks."""
|
||||
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from unittest.mock import patch
|
||||
import crum
|
||||
import ddt
|
||||
import waffle
|
||||
@@ -11,7 +12,6 @@ from django.contrib.messages.middleware import MessageMiddleware
|
||||
from django.test import RequestFactory
|
||||
from django.urls import reverse
|
||||
from edx_toggles.toggles.testutils import override_waffle_flag
|
||||
from mock import patch
|
||||
from pytz import utc
|
||||
|
||||
from common.djangoapps.course_modes.models import CourseMode
|
||||
@@ -41,7 +41,7 @@ from lms.djangoapps.verify_student.services import IDVerificationService
|
||||
from lms.djangoapps.verify_student.tests.factories import SoftwareSecurePhotoVerificationFactory
|
||||
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
|
||||
from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration
|
||||
from openedx.core.djangoapps.site_configuration.tests.factories import SiteFactory
|
||||
from openedx.core.djangoapps.site_configuration.tests.factories import SiteFactory # pylint: disable=unused-import
|
||||
from openedx.core.djangoapps.user_api.preferences.api import set_user_preference
|
||||
from openedx.features.course_duration_limits.models import CourseDurationLimitConfig
|
||||
from openedx.features.course_experience import (
|
||||
@@ -62,7 +62,7 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase):
|
||||
MODULESTORE = TEST_DATA_SPLIT_MODULESTORE
|
||||
|
||||
def setUp(self):
|
||||
super(CourseDateSummaryTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
SelfPacedConfiguration.objects.create(enable_course_home_improvements=True)
|
||||
|
||||
def make_request(self, user):
|
||||
@@ -95,7 +95,7 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase):
|
||||
"""Assert that the enabled block types for this course are as expected."""
|
||||
blocks = get_course_date_blocks(course, user)
|
||||
assert len(blocks) == len(expected_blocks)
|
||||
assert set((type(b) for b in blocks)) == set(expected_blocks)
|
||||
assert {type(b) for b in blocks} == set(expected_blocks)
|
||||
|
||||
@ddt.data(
|
||||
# Verified enrollment with no photo-verification before course start
|
||||
@@ -241,8 +241,10 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase):
|
||||
)
|
||||
blocks = get_course_date_blocks(course, user, request, num_assignments=2)
|
||||
assert len(blocks) == len(expected_blocks)
|
||||
assert set((type(b) for b in blocks)) == set(expected_blocks)
|
||||
assignment_blocks = filter(lambda b: isinstance(b, CourseAssignmentDate), blocks)
|
||||
assert {type(b) for b in blocks} == set(expected_blocks)
|
||||
assignment_blocks = filter( # pylint: disable=filter-builtin-not-iterating
|
||||
lambda b: isinstance(b, CourseAssignmentDate), blocks
|
||||
)
|
||||
for assignment in assignment_blocks:
|
||||
assignment_title = str(assignment.title_html) or str(assignment.title)
|
||||
assert assignment_title != 'Third nearest assignment'
|
||||
@@ -265,8 +267,10 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase):
|
||||
)
|
||||
blocks = get_course_date_blocks(course, user, request, include_past_dates=True)
|
||||
assert len(blocks) == len(expected_blocks)
|
||||
assert set((type(b) for b in blocks)) == set(expected_blocks)
|
||||
assignment_blocks = filter(lambda b: isinstance(b, CourseAssignmentDate), blocks)
|
||||
assert {type(b) for b in blocks} == set(expected_blocks)
|
||||
assignment_blocks = filter( # pylint: disable=filter-builtin-not-iterating
|
||||
lambda b: isinstance(b, CourseAssignmentDate), blocks
|
||||
)
|
||||
for assignment in assignment_blocks:
|
||||
assignment_title = str(assignment.title_html) or str(assignment.title)
|
||||
assert assignment_title != 'Not returned since we do not get non-graded subsections'
|
||||
@@ -576,7 +580,7 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase):
|
||||
CourseEnrollmentFactory(course_id=course.id, user=user, mode=CourseMode.VERIFIED)
|
||||
|
||||
block = VerifiedUpgradeDeadlineDate(course, user)
|
||||
assert block.link == '{}?sku={}'.format(configuration.basket_checkout_page, sku)
|
||||
assert block.link == f'{configuration.basket_checkout_page}?sku={sku}'
|
||||
|
||||
## CertificateAvailableDate
|
||||
@waffle.testutils.override_switch('certificates.auto_certificate_generation', True)
|
||||
@@ -702,8 +706,8 @@ class CourseDateSummaryTest(SharedModuleStoreTestCase):
|
||||
assert block.link == ''
|
||||
|
||||
@ddt.data(
|
||||
(-1, u'1 day ago - {date}'),
|
||||
(1, u'in 1 day - {date}')
|
||||
(-1, '1 day ago - {date}'),
|
||||
(1, 'in 1 day - {date}')
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_render_date_string_past(self, delta, expected_date_string):
|
||||
@@ -770,7 +774,7 @@ class TestDateAlerts(SharedModuleStoreTestCase):
|
||||
Unit tests for date alerts.
|
||||
"""
|
||||
def setUp(self):
|
||||
super(TestDateAlerts, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
with freeze_time('2017-07-01 09:00:00'):
|
||||
self.course = create_course_run(days_till_start=0)
|
||||
self.course.certificate_available_date = self.course.start + timedelta(days=21)
|
||||
@@ -782,11 +786,11 @@ class TestDateAlerts(SharedModuleStoreTestCase):
|
||||
MessageMiddleware().process_request(self.request)
|
||||
|
||||
@ddt.data(
|
||||
['2017-01-01 09:00:00', u'in 6 months on <span class="date localized-datetime" data-format="shortDate"'],
|
||||
['2017-06-17 09:00:00', u'in 2 weeks on <span class="date localized-datetime" data-format="shortDate"'],
|
||||
['2017-06-30 10:00:00', u'in 1 day at <span class="date localized-datetime" data-format="shortTime"'],
|
||||
['2017-07-01 08:00:00', u'in 1 hour at <span class="date localized-datetime" data-format="shortTime"'],
|
||||
['2017-07-01 08:55:00', u'in 5 minutes at <span class="date localized-datetime" data-format="shortTime"'],
|
||||
['2017-01-01 09:00:00', 'in 6 months on <span class="date localized-datetime" data-format="shortDate"'],
|
||||
['2017-06-17 09:00:00', 'in 2 weeks on <span class="date localized-datetime" data-format="shortDate"'],
|
||||
['2017-06-30 10:00:00', 'in 1 day at <span class="date localized-datetime" data-format="shortTime"'],
|
||||
['2017-07-01 08:00:00', 'in 1 hour at <span class="date localized-datetime" data-format="shortTime"'],
|
||||
['2017-07-01 08:55:00', 'in 5 minutes at <span class="date localized-datetime" data-format="shortTime"'],
|
||||
['2017-07-01 09:00:00', None],
|
||||
['2017-08-01 09:00:00', None],
|
||||
)
|
||||
@@ -807,10 +811,10 @@ class TestDateAlerts(SharedModuleStoreTestCase):
|
||||
|
||||
@ddt.data(
|
||||
['2017-06-30 09:00:00', None],
|
||||
['2017-07-01 09:00:00', u'in 2 weeks on <span class="date localized-datetime" data-format="shortDate"'],
|
||||
['2017-07-14 10:00:00', u'in 1 day at <span class="date localized-datetime" data-format="shortTime"'],
|
||||
['2017-07-15 08:00:00', u'in 1 hour at <span class="date localized-datetime" data-format="shortTime"'],
|
||||
['2017-07-15 08:55:00', u'in 5 minutes at <span class="date localized-datetime" data-format="shortTime"'],
|
||||
['2017-07-01 09:00:00', 'in 2 weeks on <span class="date localized-datetime" data-format="shortDate"'],
|
||||
['2017-07-14 10:00:00', 'in 1 day at <span class="date localized-datetime" data-format="shortTime"'],
|
||||
['2017-07-15 08:00:00', 'in 1 hour at <span class="date localized-datetime" data-format="shortTime"'],
|
||||
['2017-07-15 08:55:00', 'in 5 minutes at <span class="date localized-datetime" data-format="shortTime"'],
|
||||
['2017-07-15 09:00:00', None],
|
||||
['2017-08-15 09:00:00', None],
|
||||
)
|
||||
@@ -831,10 +835,10 @@ class TestDateAlerts(SharedModuleStoreTestCase):
|
||||
|
||||
@ddt.data(
|
||||
['2017-06-20 09:00:00', None],
|
||||
['2017-06-21 09:00:00', u'Don't forget, you have 2 weeks left to upgrade to a Verified Certificate.'],
|
||||
['2017-07-04 10:00:00', u'Don't forget, you have 1 day left to upgrade to a Verified Certificate.'],
|
||||
['2017-07-05 08:00:00', u'Don't forget, you have 1 hour left to upgrade to a Verified Certificate.'],
|
||||
['2017-07-05 08:55:00', u'Don't forget, you have 5 minutes left to upgrade to a Verified Certificate.'],
|
||||
['2017-06-21 09:00:00', 'Don't forget, you have 2 weeks left to upgrade to a Verified Certificate.'],
|
||||
['2017-07-04 10:00:00', 'Don't forget, you have 1 day left to upgrade to a Verified Certificate.'],
|
||||
['2017-07-05 08:00:00', 'Don't forget, you have 1 hour left to upgrade to a Verified Certificate.'],
|
||||
['2017-07-05 08:55:00', 'Don't forget, you have 5 minutes left to upgrade to a Verified Certificate.'],
|
||||
['2017-07-05 09:00:00', None],
|
||||
['2017-08-05 09:00:00', None],
|
||||
)
|
||||
@@ -856,9 +860,9 @@ class TestDateAlerts(SharedModuleStoreTestCase):
|
||||
|
||||
@ddt.data(
|
||||
['2017-07-15 08:00:00', None],
|
||||
['2017-07-15 09:00:00', u'If you have earned a certificate, you will be able to access it 1 week from now.'],
|
||||
['2017-07-21 09:00:00', u'If you have earned a certificate, you will be able to access it 1 day from now.'],
|
||||
['2017-07-22 08:00:00', u'If you have earned a certificate, you will be able to access it 1 hour from now.'],
|
||||
['2017-07-15 09:00:00', 'If you have earned a certificate, you will be able to access it 1 week from now.'],
|
||||
['2017-07-21 09:00:00', 'If you have earned a certificate, you will be able to access it 1 day from now.'],
|
||||
['2017-07-22 08:00:00', 'If you have earned a certificate, you will be able to access it 1 hour from now.'],
|
||||
['2017-07-22 09:00:00', None],
|
||||
['2017-07-23 09:00:00', None],
|
||||
)
|
||||
@@ -901,7 +905,7 @@ class TestScheduleOverrides(SharedModuleStoreTestCase):
|
||||
assert upgrade_date_summary.description ==\
|
||||
"Don't miss the opportunity to highlight your new knowledge and skills by earning a verified" \
|
||||
" certificate."
|
||||
assert upgrade_date_summary.relative_datestring == u'by {date}'
|
||||
assert upgrade_date_summary.relative_datestring == 'by {date}'
|
||||
|
||||
def test_date_with_self_paced_with_enrollment_after_course_start(self):
|
||||
""" Enrolling after a course begins should result in the upgrade deadline being set relative to the
|
||||
@@ -1116,10 +1120,10 @@ def enable_course_certificates(course):
|
||||
Enable course certificate configuration.
|
||||
"""
|
||||
course.certificates = {
|
||||
u'certificates': [{
|
||||
u'course_title': u'Test',
|
||||
u'name': u'',
|
||||
u'is_active': True,
|
||||
'certificates': [{
|
||||
'course_title': 'Test',
|
||||
'name': '',
|
||||
'is_active': True,
|
||||
}]
|
||||
}
|
||||
course.save()
|
||||
|
||||
@@ -10,11 +10,9 @@ functionalities.
|
||||
import json
|
||||
import uuid
|
||||
|
||||
from unittest import mock
|
||||
import ddt
|
||||
import mock
|
||||
import six
|
||||
from django.urls import reverse
|
||||
from six.moves import range
|
||||
from web_fragments.fragment import Fragment
|
||||
from xblock.field_data import DictFieldData
|
||||
|
||||
@@ -40,7 +38,7 @@ class TestDiscussionXBlock(XModuleRenderingTestBase):
|
||||
"""
|
||||
Set up the xblock runtime, test course, discussion, and user.
|
||||
"""
|
||||
super(TestDiscussionXBlock, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.patchers = []
|
||||
self.course_id = "test_course"
|
||||
self.runtime = self.new_module_runtime()
|
||||
@@ -77,7 +75,7 @@ class TestDiscussionXBlock(XModuleRenderingTestBase):
|
||||
"""
|
||||
Tears down any patchers added during tests.
|
||||
"""
|
||||
super(TestDiscussionXBlock, self).tearDown() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().tearDown()
|
||||
for patcher in self.patchers:
|
||||
patcher.stop()
|
||||
|
||||
@@ -93,7 +91,7 @@ class TestGetDjangoUser(TestDiscussionXBlock):
|
||||
"""
|
||||
Mock the user service and runtime.
|
||||
"""
|
||||
super(TestGetDjangoUser, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.django_user = object()
|
||||
self.user_service = mock.Mock()
|
||||
self.add_patcher(
|
||||
@@ -129,8 +127,8 @@ class TestViews(TestDiscussionXBlock):
|
||||
"""
|
||||
Mock the methods needed for these tests.
|
||||
"""
|
||||
super(TestViews, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
self.template_canary = u'canary'
|
||||
super().setUp()
|
||||
self.template_canary = 'canary'
|
||||
self.render_template = mock.Mock()
|
||||
self.render_template.return_value = self.template_canary
|
||||
self.block.runtime.render_template = self.render_template
|
||||
@@ -227,7 +225,7 @@ class TestTemplates(TestDiscussionXBlock):
|
||||
def test_studio_view(self):
|
||||
"""Test for studio view."""
|
||||
fragment = self.block.author_view({})
|
||||
assert 'data-discussion-id="{}"'.format(self.discussion_id) in fragment.content
|
||||
assert f'data-discussion-id="{self.discussion_id}"' in fragment.content
|
||||
|
||||
@ddt.data(
|
||||
(True, False, False),
|
||||
@@ -247,10 +245,10 @@ class TestTemplates(TestDiscussionXBlock):
|
||||
self.block.has_permission = lambda perm: permission_dict[perm]
|
||||
fragment = self.block.student_view()
|
||||
read_only = 'false' if permissions[0] else 'true'
|
||||
assert 'data-discussion-id="{}"'.format(self.discussion_id) in fragment.content
|
||||
assert f'data-discussion-id="{self.discussion_id}"' in fragment.content
|
||||
assert 'data-user-create-comment="{}"'.format(json.dumps(permissions[1])) in fragment.content
|
||||
assert 'data-user-create-subcomment="{}"'.format(json.dumps(permissions[2])) in fragment.content
|
||||
assert 'data-read-only="{read_only}"'.format(read_only=read_only) in fragment.content
|
||||
assert f'data-read-only="{read_only}"' in fragment.content
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@@ -264,7 +262,7 @@ class TestXBlockInCourse(SharedModuleStoreTestCase):
|
||||
"""
|
||||
Set up a user, course, and discussion XBlock for use by tests.
|
||||
"""
|
||||
super(TestXBlockInCourse, cls).setUpClass()
|
||||
super().setUpClass()
|
||||
cls.user = UserFactory()
|
||||
cls.course = ToyCourseFactory.create()
|
||||
cls.course_key = cls.course.id
|
||||
@@ -359,7 +357,7 @@ class TestXBlockInCourse(SharedModuleStoreTestCase):
|
||||
Tests that course block api returns student_view_data for discussion xblock
|
||||
"""
|
||||
self.client.login(username=self.user.username, password='test')
|
||||
url = reverse('blocks_in_block_tree', kwargs={'usage_key_string': six.text_type(self.course_usage_key)})
|
||||
url = reverse('blocks_in_block_tree', kwargs={'usage_key_string': str(self.course_usage_key)})
|
||||
query_params = {
|
||||
'depth': 'all',
|
||||
'username': self.user.username,
|
||||
@@ -368,8 +366,8 @@ class TestXBlockInCourse(SharedModuleStoreTestCase):
|
||||
}
|
||||
response = self.client.get(url, query_params)
|
||||
assert response.status_code == 200
|
||||
assert response.data['root'] == six.text_type(self.course_usage_key)
|
||||
for block_key_string, block_data in six.iteritems(response.data['blocks']):
|
||||
assert response.data['root'] == str(self.course_usage_key)
|
||||
for block_key_string, block_data in response.data['blocks'].items():
|
||||
block_key = deserialize_usage_key(block_key_string, self.course_key)
|
||||
assert block_data['id'] == block_key_string
|
||||
assert block_data['type'] == block_key.block_type
|
||||
@@ -393,7 +391,7 @@ class TestXBlockQueryLoad(SharedModuleStoreTestCase):
|
||||
discussions = []
|
||||
|
||||
for counter in range(5):
|
||||
discussion_id = 'test_discussion_{}'.format(counter)
|
||||
discussion_id = f'test_discussion_{counter}'
|
||||
discussions.append(ItemFactory.create(
|
||||
parent_location=course_usage_key,
|
||||
category='discussion',
|
||||
|
||||
@@ -3,11 +3,10 @@ Tests use cases related to LMS Entrance Exam behavior, such as gated content acc
|
||||
"""
|
||||
|
||||
|
||||
import six
|
||||
from unittest.mock import Mock, patch
|
||||
from crum import set_current_request
|
||||
from django.urls import reverse
|
||||
from milestones.tests.utils import MilestonesTestCaseMixin
|
||||
from mock import Mock, patch
|
||||
|
||||
from capa.tests.response_xml_factory import MultipleChoiceResponseXMLFactory
|
||||
from edx_toggles.toggles.testutils import override_waffle_flag # lint-amnesty, pylint: disable=wrong-import-order
|
||||
@@ -52,7 +51,7 @@ class EntranceExamTestCases(LoginEnrollmentTestCase, ModuleStoreTestCase, Milest
|
||||
"""
|
||||
Test case scaffolding
|
||||
"""
|
||||
super(EntranceExamTestCases, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.course = CourseFactory.create(
|
||||
metadata={
|
||||
'entrance_exam_enabled': True,
|
||||
@@ -139,7 +138,7 @@ class EntranceExamTestCases(LoginEnrollmentTestCase, ModuleStoreTestCase, Milest
|
||||
|
||||
self.course.entrance_exam_enabled = True
|
||||
self.course.entrance_exam_minimum_score_pct = 0.50
|
||||
self.course.entrance_exam_id = six.text_type(self.entrance_exam.scope_ids.usage_id)
|
||||
self.course.entrance_exam_id = str(self.entrance_exam.scope_ids.usage_id)
|
||||
|
||||
self.anonymous_user = AnonymousUserFactory()
|
||||
self.addCleanup(set_current_request, None)
|
||||
@@ -155,17 +154,17 @@ class EntranceExamTestCases(LoginEnrollmentTestCase, ModuleStoreTestCase, Milest
|
||||
'active': True,
|
||||
'sections': [
|
||||
{
|
||||
'url_name': u'Exam_Sequential_-_Subsection_1',
|
||||
'display_name': u'Exam Sequential - Subsection 1',
|
||||
'url_name': 'Exam_Sequential_-_Subsection_1',
|
||||
'display_name': 'Exam Sequential - Subsection 1',
|
||||
'graded': True,
|
||||
'format': '',
|
||||
'due': None,
|
||||
'active': True
|
||||
}
|
||||
],
|
||||
'url_name': u'Entrance_Exam_Section_-_Chapter_1',
|
||||
'display_name': u'Entrance Exam Section - Chapter 1',
|
||||
'display_id': u'entrance-exam-section-chapter-1',
|
||||
'url_name': 'Entrance_Exam_Section_-_Chapter_1',
|
||||
'display_name': 'Entrance Exam Section - Chapter 1',
|
||||
'display_id': 'entrance-exam-section-chapter-1',
|
||||
}
|
||||
]
|
||||
)
|
||||
@@ -175,55 +174,55 @@ class EntranceExamTestCases(LoginEnrollmentTestCase, ModuleStoreTestCase, Milest
|
||||
'active': False,
|
||||
'sections': [
|
||||
{
|
||||
'url_name': u'Welcome',
|
||||
'display_name': u'Welcome',
|
||||
'url_name': 'Welcome',
|
||||
'display_name': 'Welcome',
|
||||
'graded': False,
|
||||
'format': '',
|
||||
'due': None,
|
||||
'active': False
|
||||
},
|
||||
{
|
||||
'url_name': u'Lesson_1',
|
||||
'display_name': u'Lesson 1',
|
||||
'url_name': 'Lesson_1',
|
||||
'display_name': 'Lesson 1',
|
||||
'graded': False,
|
||||
'format': '',
|
||||
'due': None,
|
||||
'active': False
|
||||
}
|
||||
],
|
||||
'url_name': u'Overview',
|
||||
'display_name': u'Overview',
|
||||
'display_id': u'overview'
|
||||
'url_name': 'Overview',
|
||||
'display_name': 'Overview',
|
||||
'display_id': 'overview'
|
||||
},
|
||||
{
|
||||
'active': False,
|
||||
'sections': [],
|
||||
'url_name': u'Week_1',
|
||||
'display_name': u'Week 1',
|
||||
'display_id': u'week-1'
|
||||
'url_name': 'Week_1',
|
||||
'display_name': 'Week 1',
|
||||
'display_id': 'week-1'
|
||||
},
|
||||
{
|
||||
'active': False,
|
||||
'sections': [],
|
||||
'url_name': u'Instructor',
|
||||
'display_name': u'Instructor',
|
||||
'display_id': u'instructor'
|
||||
'url_name': 'Instructor',
|
||||
'display_name': 'Instructor',
|
||||
'display_id': 'instructor'
|
||||
},
|
||||
{
|
||||
'active': True,
|
||||
'sections': [
|
||||
{
|
||||
'url_name': u'Exam_Sequential_-_Subsection_1',
|
||||
'display_name': u'Exam Sequential - Subsection 1',
|
||||
'url_name': 'Exam_Sequential_-_Subsection_1',
|
||||
'display_name': 'Exam Sequential - Subsection 1',
|
||||
'graded': True,
|
||||
'format': '',
|
||||
'due': None,
|
||||
'active': True
|
||||
}
|
||||
],
|
||||
'url_name': u'Entrance_Exam_Section_-_Chapter_1',
|
||||
'display_name': u'Entrance Exam Section - Chapter 1',
|
||||
'display_id': u'entrance-exam-section-chapter-1'
|
||||
'url_name': 'Entrance_Exam_Section_-_Chapter_1',
|
||||
'display_name': 'Entrance Exam Section - Chapter 1',
|
||||
'display_id': 'entrance-exam-section-chapter-1'
|
||||
}
|
||||
]
|
||||
)
|
||||
@@ -232,10 +231,10 @@ class EntranceExamTestCases(LoginEnrollmentTestCase, ModuleStoreTestCase, Milest
|
||||
"""
|
||||
Unit Test: if entrance exam is required. Should return a redirect.
|
||||
"""
|
||||
url = reverse('courseware', kwargs={'course_id': six.text_type(self.course.id)})
|
||||
url = reverse('courseware', kwargs={'course_id': str(self.course.id)})
|
||||
expected_url = reverse('courseware_section',
|
||||
kwargs={
|
||||
'course_id': six.text_type(self.course.id),
|
||||
'course_id': str(self.course.id),
|
||||
'chapter': self.entrance_exam.location.block_id,
|
||||
'section': self.exam_1.location.block_id
|
||||
})
|
||||
@@ -247,10 +246,10 @@ class EntranceExamTestCases(LoginEnrollmentTestCase, ModuleStoreTestCase, Milest
|
||||
"""
|
||||
Unit Test: If entrance exam is not enabled then page should be redirected with chapter contents.
|
||||
"""
|
||||
url = reverse('courseware', kwargs={'course_id': six.text_type(self.course.id)})
|
||||
url = reverse('courseware', kwargs={'course_id': str(self.course.id)})
|
||||
expected_url = reverse('courseware_section',
|
||||
kwargs={
|
||||
'course_id': six.text_type(self.course.id),
|
||||
'course_id': str(self.course.id),
|
||||
'chapter': self.chapter.location.block_id,
|
||||
'section': self.welcome.location.block_id
|
||||
})
|
||||
@@ -264,10 +263,10 @@ class EntranceExamTestCases(LoginEnrollmentTestCase, ModuleStoreTestCase, Milest
|
||||
Unit Test: If entrance exam is enabled then its content e.g. problems should be loaded and redirection will
|
||||
occur with entrance exam contents.
|
||||
"""
|
||||
url = reverse('courseware', kwargs={'course_id': six.text_type(self.course.id)})
|
||||
url = reverse('courseware', kwargs={'course_id': str(self.course.id)})
|
||||
expected_url = reverse('courseware_section',
|
||||
kwargs={
|
||||
'course_id': six.text_type(self.course.id),
|
||||
'course_id': str(self.course.id),
|
||||
'chapter': self.entrance_exam.location.block_id,
|
||||
'section': self.exam_1.location.block_id
|
||||
})
|
||||
@@ -298,7 +297,7 @@ class EntranceExamTestCases(LoginEnrollmentTestCase, ModuleStoreTestCase, Milest
|
||||
url = reverse(
|
||||
'courseware_section',
|
||||
kwargs={
|
||||
'course_id': six.text_type(self.course.id),
|
||||
'course_id': str(self.course.id),
|
||||
'chapter': self.entrance_exam.location.block_id,
|
||||
'section': self.exam_1.location.block_id,
|
||||
}
|
||||
@@ -321,7 +320,7 @@ class EntranceExamTestCases(LoginEnrollmentTestCase, ModuleStoreTestCase, Milest
|
||||
url = reverse(
|
||||
'courseware_section',
|
||||
kwargs={
|
||||
'course_id': six.text_type(self.course.id),
|
||||
'course_id': str(self.course.id),
|
||||
'chapter': self.entrance_exam.location.block_id,
|
||||
'section': self.exam_1.location.block_id
|
||||
}
|
||||
@@ -329,9 +328,9 @@ class EntranceExamTestCases(LoginEnrollmentTestCase, ModuleStoreTestCase, Milest
|
||||
resp = self.client.get(url)
|
||||
self.assertContains(
|
||||
resp,
|
||||
u'To access course materials, you must score {}% or higher'.format(minimum_score_pct),
|
||||
f'To access course materials, you must score {minimum_score_pct}% or higher',
|
||||
)
|
||||
assert u'Your current score is 20%.' in resp.content.decode(resp.charset)
|
||||
assert 'Your current score is 20%.' in resp.content.decode(resp.charset)
|
||||
|
||||
def test_entrance_exam_requirement_message_hidden(self):
|
||||
"""
|
||||
@@ -346,7 +345,7 @@ class EntranceExamTestCases(LoginEnrollmentTestCase, ModuleStoreTestCase, Milest
|
||||
url = reverse(
|
||||
'courseware_section',
|
||||
kwargs={
|
||||
'course_id': six.text_type(self.course.id),
|
||||
'course_id': str(self.course.id),
|
||||
'chapter': self.chapter.location.block_id,
|
||||
'section': self.chapter_subsection.location.block_id
|
||||
}
|
||||
@@ -366,7 +365,7 @@ class EntranceExamTestCases(LoginEnrollmentTestCase, ModuleStoreTestCase, Milest
|
||||
url = reverse(
|
||||
'courseware_section',
|
||||
kwargs={
|
||||
'course_id': six.text_type(self.course.id),
|
||||
'course_id': str(self.course.id),
|
||||
'chapter': self.entrance_exam.location.block_id,
|
||||
'section': self.exam_1.location.block_id
|
||||
}
|
||||
@@ -377,7 +376,7 @@ class EntranceExamTestCases(LoginEnrollmentTestCase, ModuleStoreTestCase, Milest
|
||||
|
||||
resp = self.client.get(url)
|
||||
self.assertNotContains(resp, 'To access course materials, you must score')
|
||||
self.assertContains(resp, u'Your score is 100%. You have passed the entrance exam.')
|
||||
self.assertContains(resp, 'Your score is 100%. You have passed the entrance exam.')
|
||||
self.assertContains(resp, 'Lesson 1')
|
||||
|
||||
def test_entrance_exam_gating(self):
|
||||
@@ -412,7 +411,7 @@ class EntranceExamTestCases(LoginEnrollmentTestCase, ModuleStoreTestCase, Milest
|
||||
# hit skip entrance exam api in instructor app
|
||||
instructor = InstructorFactory(course_key=self.course.id)
|
||||
self.client.login(username=instructor.username, password='test')
|
||||
url = reverse('mark_student_can_skip_entrance_exam', kwargs={'course_id': six.text_type(self.course.id)})
|
||||
url = reverse('mark_student_can_skip_entrance_exam', kwargs={'course_id': str(self.course.id)})
|
||||
response = self.client.post(url, {
|
||||
'unique_student_identifier': self.request.user.email,
|
||||
})
|
||||
@@ -445,12 +444,12 @@ class EntranceExamTestCases(LoginEnrollmentTestCase, ModuleStoreTestCase, Milest
|
||||
"""
|
||||
url = reverse(
|
||||
'courseware_chapter',
|
||||
kwargs={'course_id': six.text_type(self.course.id), 'chapter': self.chapter.url_name}
|
||||
kwargs={'course_id': str(self.course.id), 'chapter': self.chapter.url_name}
|
||||
)
|
||||
response = self.client.get(url)
|
||||
expected_url = reverse('courseware_section',
|
||||
kwargs={
|
||||
'course_id': six.text_type(self.course.id),
|
||||
'course_id': str(self.course.id),
|
||||
'chapter': self.entrance_exam.location.block_id,
|
||||
'section': self.exam_1.location.block_id
|
||||
})
|
||||
@@ -461,9 +460,9 @@ class EntranceExamTestCases(LoginEnrollmentTestCase, ModuleStoreTestCase, Milest
|
||||
"""
|
||||
Test courseware access page without passing entrance exam
|
||||
"""
|
||||
url = reverse('info', args=[six.text_type(self.course.id)])
|
||||
url = reverse('info', args=[str(self.course.id)])
|
||||
response = self.client.get(url)
|
||||
redirect_url = reverse('courseware', args=[six.text_type(self.course.id)])
|
||||
redirect_url = reverse('courseware', args=[str(self.course.id)])
|
||||
self.assertRedirects(response, redirect_url, status_code=302, target_status_code=302)
|
||||
response = self.client.get(redirect_url)
|
||||
exam_url = response.get('Location')
|
||||
@@ -536,7 +535,7 @@ class EntranceExamTestCases(LoginEnrollmentTestCase, ModuleStoreTestCase, Milest
|
||||
Tests entrance exam xblock has `entrance_exam_passed` key in json response.
|
||||
"""
|
||||
request_factory = RequestFactoryNoCsrf()
|
||||
data = {'input_{}_2_1'.format(six.text_type(self.problem_1.location.html_id())): 'choice_2'}
|
||||
data = {'input_{}_2_1'.format(str(self.problem_1.location.html_id())): 'choice_2'}
|
||||
request = request_factory.post(
|
||||
'problem_check',
|
||||
data=data
|
||||
@@ -544,8 +543,8 @@ class EntranceExamTestCases(LoginEnrollmentTestCase, ModuleStoreTestCase, Milest
|
||||
request.user = self.user
|
||||
response = handle_xblock_callback(
|
||||
request,
|
||||
six.text_type(self.course.id),
|
||||
six.text_type(self.problem_1.location),
|
||||
str(self.course.id),
|
||||
str(self.problem_1.location),
|
||||
'xmodule_handler',
|
||||
'problem_check',
|
||||
)
|
||||
@@ -558,7 +557,7 @@ class EntranceExamTestCases(LoginEnrollmentTestCase, ModuleStoreTestCase, Milest
|
||||
"""
|
||||
url = reverse(
|
||||
'courseware_chapter',
|
||||
kwargs={'course_id': six.text_type(course.id), 'chapter': chapter.url_name}
|
||||
kwargs={'course_id': str(course.id), 'chapter': chapter.url_name}
|
||||
)
|
||||
response = self.client.get(url)
|
||||
assert response.status_code == 200
|
||||
@@ -640,13 +639,13 @@ def add_entrance_exam_milestone(course, entrance_exam):
|
||||
}
|
||||
)
|
||||
add_course_milestone(
|
||||
six.text_type(course.id),
|
||||
str(course.id),
|
||||
milestone_relationship_types['REQUIRES'],
|
||||
milestone
|
||||
)
|
||||
add_course_content_milestone(
|
||||
six.text_type(course.id),
|
||||
six.text_type(entrance_exam.location),
|
||||
str(course.id),
|
||||
str(entrance_exam.location),
|
||||
milestone_relationship_types['FULFILLS'],
|
||||
milestone
|
||||
)
|
||||
|
||||
@@ -54,7 +54,7 @@ class OverrideFieldBase(SharedModuleStoreTestCase):
|
||||
"""
|
||||
Course is created here and shared by all the class's tests.
|
||||
"""
|
||||
super(OverrideFieldBase, cls).setUpClass()
|
||||
super().setUpClass()
|
||||
cls.course = CourseFactory.create(enable_ccx=True)
|
||||
|
||||
|
||||
@@ -66,11 +66,11 @@ class OverrideFieldDataTests(OverrideFieldBase):
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(OverrideFieldDataTests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
OverrideFieldData.provider_classes = None
|
||||
|
||||
def tearDown(self):
|
||||
super(OverrideFieldDataTests, self).tearDown() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().tearDown()
|
||||
OverrideFieldData.provider_classes = None
|
||||
|
||||
def make_one(self):
|
||||
|
||||
@@ -6,7 +6,6 @@ edx.org uses an edx footer but other instances use an Open edX footer.
|
||||
|
||||
import unittest
|
||||
|
||||
import six
|
||||
from django.conf import settings
|
||||
from django.test import TestCase
|
||||
from django.test.utils import override_settings
|
||||
@@ -67,7 +66,7 @@ class TestFooter(TestCase):
|
||||
)
|
||||
def test_edx_footer_social_links(self):
|
||||
resp = self.client.get('/')
|
||||
for name, url in six.iteritems(self.SOCIAL_MEDIA_URLS):
|
||||
for name, url in self.SOCIAL_MEDIA_URLS.items():
|
||||
self.assertContains(resp, url)
|
||||
self.assertContains(resp, settings.SOCIAL_MEDIA_FOOTER_DISPLAY[name]['title'])
|
||||
self.assertContains(resp, settings.SOCIAL_MEDIA_FOOTER_DISPLAY[name]['icon'])
|
||||
|
||||
@@ -15,7 +15,7 @@ from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
|
||||
from xmodule.partitions.partitions import USER_PARTITION_SCHEME_NAMESPACE, Group, UserPartition
|
||||
|
||||
|
||||
class MemoryUserPartitionScheme(object):
|
||||
class MemoryUserPartitionScheme:
|
||||
"""
|
||||
In-memory partition scheme for testing.
|
||||
"""
|
||||
@@ -80,7 +80,7 @@ class GroupAccessTestCase(ModuleStoreTestCase):
|
||||
modulestore().update_item(block, 1)
|
||||
|
||||
def setUp(self):
|
||||
super(GroupAccessTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
UserPartition.scheme_extensions = ExtensionManager.make_test_instance(
|
||||
[
|
||||
@@ -176,7 +176,7 @@ class GroupAccessTestCase(ModuleStoreTestCase):
|
||||
side-effects in other tests.
|
||||
"""
|
||||
UserPartition.scheme_extensions = None
|
||||
super(GroupAccessTestCase, self).tearDown() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().tearDown()
|
||||
|
||||
def check_access(self, user, block_location, is_accessible):
|
||||
"""
|
||||
|
||||
@@ -5,7 +5,6 @@ Tests i18n in courseware
|
||||
|
||||
import json
|
||||
import re
|
||||
import six
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user
|
||||
@@ -29,17 +28,17 @@ class BaseI18nTestCase(CacheIsolationTestCase):
|
||||
url = reverse_lazy('dashboard')
|
||||
|
||||
def setUp(self):
|
||||
super(BaseI18nTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.addCleanup(translation.deactivate)
|
||||
self.client = Client()
|
||||
self.create_user()
|
||||
|
||||
def assert_tag_has_attr(self, content, tag, attname, value):
|
||||
"""Assert that a tag in `content` has a certain value in a certain attribute."""
|
||||
regex_string = six.text_type(r"""<{tag} [^>]*\b{attname}=['"]([\w\d\- ]+)['"][^>]*>""") # noqa: W605,E501
|
||||
regex_string = r"""<{tag} [^>]*\b{attname}=['"]([\w\d\- ]+)['"][^>]*>""" # noqa: W605,E501
|
||||
regex = regex_string.format(tag=tag, attname=attname)
|
||||
match = re.search(regex, content)
|
||||
assert match, (u"Couldn't find desired tag '%s' with attr '%s' in %r" % (tag, attname, content))
|
||||
assert match, (f"Couldn't find desired tag '{tag}' with attr '{attname}' in {content!r}")
|
||||
attvalues = match.group(1).split()
|
||||
assert value in attvalues
|
||||
|
||||
@@ -166,7 +165,7 @@ class I18nLangPrefTests(BaseI18nTestCase):
|
||||
and use the dark lang preview functionality.
|
||||
"""
|
||||
def setUp(self):
|
||||
super(I18nLangPrefTests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.user_login()
|
||||
|
||||
def set_lang_preference(self, language):
|
||||
|
||||
@@ -4,12 +4,11 @@
|
||||
import json
|
||||
from collections import OrderedDict
|
||||
|
||||
import mock
|
||||
from unittest import mock
|
||||
import urllib
|
||||
import oauthlib
|
||||
import six
|
||||
from django.conf import settings
|
||||
from django.urls import reverse
|
||||
from six import text_type
|
||||
|
||||
from lms.djangoapps.courseware.tests.helpers import BaseTestXmodule
|
||||
from lms.djangoapps.courseware.views.views import get_course_lti_endpoints
|
||||
@@ -33,44 +32,42 @@ class TestLTI(BaseTestXmodule):
|
||||
"""
|
||||
Mock oauth1 signing of requests library for testing.
|
||||
"""
|
||||
super(TestLTI, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
mocked_nonce = u'135685044251684026041377608307'
|
||||
mocked_timestamp = u'1234567890'
|
||||
mocked_signature_after_sign = u'my_signature%3D'
|
||||
mocked_decoded_signature = u'my_signature='
|
||||
super().setUp()
|
||||
mocked_nonce = '135685044251684026041377608307'
|
||||
mocked_timestamp = '1234567890'
|
||||
mocked_signature_after_sign = 'my_signature%3D'
|
||||
mocked_decoded_signature = 'my_signature='
|
||||
|
||||
# Note: this course_id is actually a course_key
|
||||
context_id = text_type(self.item_descriptor.course_id)
|
||||
user_id = text_type(self.item_descriptor.xmodule_runtime.anonymous_student_id)
|
||||
context_id = str(self.item_descriptor.course_id)
|
||||
user_id = str(self.item_descriptor.xmodule_runtime.anonymous_student_id)
|
||||
hostname = self.item_descriptor.xmodule_runtime.hostname
|
||||
resource_link_id = text_type(six.moves.urllib.parse.quote('{}-{}'.format(hostname,
|
||||
self.item_descriptor.location.html_id()
|
||||
)))
|
||||
resource_link_id = str(urllib.parse.quote('{}-{}'.format(hostname, self.item_descriptor.location.html_id())))
|
||||
|
||||
sourcedId = "{context}:{resource_link}:{user_id}".format(
|
||||
context=six.moves.urllib.parse.quote(context_id),
|
||||
context=urllib.parse.quote(context_id),
|
||||
resource_link=resource_link_id,
|
||||
user_id=user_id
|
||||
)
|
||||
|
||||
self.correct_headers = {
|
||||
u'user_id': user_id,
|
||||
u'oauth_callback': u'about:blank',
|
||||
u'launch_presentation_return_url': '',
|
||||
u'lti_message_type': u'basic-lti-launch-request',
|
||||
u'lti_version': 'LTI-1p0',
|
||||
u'roles': u'Student',
|
||||
u'context_id': context_id,
|
||||
'user_id': user_id,
|
||||
'oauth_callback': 'about:blank',
|
||||
'launch_presentation_return_url': '',
|
||||
'lti_message_type': 'basic-lti-launch-request',
|
||||
'lti_version': 'LTI-1p0',
|
||||
'roles': 'Student',
|
||||
'context_id': context_id,
|
||||
|
||||
u'resource_link_id': resource_link_id,
|
||||
u'lis_result_sourcedid': sourcedId,
|
||||
'resource_link_id': resource_link_id,
|
||||
'lis_result_sourcedid': sourcedId,
|
||||
|
||||
u'oauth_nonce': mocked_nonce,
|
||||
u'oauth_timestamp': mocked_timestamp,
|
||||
u'oauth_consumer_key': u'',
|
||||
u'oauth_signature_method': u'HMAC-SHA1',
|
||||
u'oauth_version': u'1.0',
|
||||
u'oauth_signature': mocked_decoded_signature
|
||||
'oauth_nonce': mocked_nonce,
|
||||
'oauth_timestamp': mocked_timestamp,
|
||||
'oauth_consumer_key': '',
|
||||
'oauth_signature_method': 'HMAC-SHA1',
|
||||
'oauth_version': '1.0',
|
||||
'oauth_signature': mocked_decoded_signature
|
||||
}
|
||||
|
||||
saved_sign = oauthlib.oauth1.Client.sign
|
||||
@@ -80,14 +77,14 @@ class TestLTI(BaseTestXmodule):
|
||||
'input_fields': self.correct_headers,
|
||||
'element_class': self.item_descriptor.category,
|
||||
'element_id': self.item_descriptor.location.html_id(),
|
||||
'launch_url': u'http://www.example.com', # default value
|
||||
'launch_url': 'http://www.example.com', # default value
|
||||
'open_in_a_new_page': True,
|
||||
'form_url': self.item_descriptor.xmodule_runtime.handler_url(self.item_descriptor,
|
||||
'preview_handler').rstrip('/?'),
|
||||
'hide_launch': False,
|
||||
'has_score': False,
|
||||
'module_score': None,
|
||||
'comment': u'',
|
||||
'comment': '',
|
||||
'weight': 1.0,
|
||||
'ask_to_send_username': self.item_descriptor.ask_to_send_username,
|
||||
'ask_to_send_email': self.item_descriptor.ask_to_send_email,
|
||||
@@ -103,12 +100,12 @@ class TestLTI(BaseTestXmodule):
|
||||
# self is <oauthlib.oauth1.rfc5849.Client object> here:
|
||||
__, headers, __ = saved_sign(self, *args, **kwargs)
|
||||
# we should replace nonce, timestamp and signed_signature in headers:
|
||||
old = headers[u'Authorization']
|
||||
old = headers['Authorization']
|
||||
old_parsed = OrderedDict([param.strip().replace('"', '').split('=') for param in old.split(',')])
|
||||
old_parsed[u'OAuth oauth_nonce'] = mocked_nonce
|
||||
old_parsed[u'oauth_timestamp'] = mocked_timestamp
|
||||
old_parsed[u'oauth_signature'] = mocked_signature_after_sign
|
||||
headers[u'Authorization'] = ', '.join([k + '="' + v + '"' for k, v in old_parsed.items()])
|
||||
old_parsed['OAuth oauth_nonce'] = mocked_nonce
|
||||
old_parsed['oauth_timestamp'] = mocked_timestamp
|
||||
old_parsed['oauth_signature'] = mocked_signature_after_sign
|
||||
headers['Authorization'] = ', '.join([k + '="' + v + '"' for k, v in old_parsed.items()])
|
||||
return None, headers, None
|
||||
|
||||
patcher = mock.patch.object(oauthlib.oauth1.Client, "sign", mocked_sign)
|
||||
@@ -136,7 +133,7 @@ class TestLTIBlockListing(SharedModuleStoreTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestLTIBlockListing, cls).setUpClass()
|
||||
super().setUpClass()
|
||||
cls.course = CourseFactory.create(display_name=cls.COURSE_NAME, number=cls.COURSE_SLUG)
|
||||
cls.chapter1 = ItemFactory.create(
|
||||
parent_location=cls.course.location,
|
||||
@@ -175,17 +172,17 @@ class TestLTIBlockListing(SharedModuleStoreTestCase):
|
||||
return "https://{}{}".format(settings.SITE_NAME, reverse(
|
||||
'xblock_handler_noauth',
|
||||
args=[
|
||||
text_type(self.course.id),
|
||||
quote_slashes(text_type(self.lti_published.scope_ids.usage_id)),
|
||||
str(self.course.id),
|
||||
quote_slashes(str(self.lti_published.scope_ids.usage_id)),
|
||||
handler
|
||||
]
|
||||
))
|
||||
|
||||
def test_lti_rest_bad_course(self):
|
||||
"""Tests what happens when the lti listing rest endpoint gets a bad course_id"""
|
||||
bad_ids = [u"sf", u"dne/dne/dne", u"fo/ey/\\u5305"]
|
||||
bad_ids = ["sf", "dne/dne/dne", "fo/ey/\\u5305"]
|
||||
for bad_course_id in bad_ids:
|
||||
lti_rest_endpoints_url = 'courses/{}/lti_rest_endpoints/'.format(bad_course_id)
|
||||
lti_rest_endpoints_url = f'courses/{bad_course_id}/lti_rest_endpoints/'
|
||||
response = self.client.get(lti_rest_endpoints_url)
|
||||
assert 404 == response.status_code
|
||||
|
||||
@@ -193,7 +190,7 @@ class TestLTIBlockListing(SharedModuleStoreTestCase):
|
||||
"""tests that the draft lti module is part of the endpoint response"""
|
||||
request = mock.Mock()
|
||||
request.method = 'GET'
|
||||
response = get_course_lti_endpoints(request, course_id=text_type(self.course.id))
|
||||
response = get_course_lti_endpoints(request, course_id=str(self.course.id))
|
||||
|
||||
assert 200 == response.status_code
|
||||
assert 'application/json' == response['Content-Type']
|
||||
@@ -212,5 +209,5 @@ class TestLTIBlockListing(SharedModuleStoreTestCase):
|
||||
for method in DISALLOWED_METHODS:
|
||||
request = mock.Mock()
|
||||
request.method = method
|
||||
response = get_course_lti_endpoints(request, text_type(self.course.id))
|
||||
response = get_course_lti_endpoints(request, str(self.course.id))
|
||||
assert 405 == response.status_code
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Unit tests for masquerade.
|
||||
"""
|
||||
@@ -7,14 +6,13 @@ Unit tests for masquerade.
|
||||
import json
|
||||
import pickle
|
||||
from datetime import datetime
|
||||
from unittest.mock import patch
|
||||
import pytest
|
||||
import ddt
|
||||
import six
|
||||
from django.conf import settings
|
||||
from django.test import TestCase
|
||||
from django.urls import reverse
|
||||
from edx_toggles.toggles.testutils import override_waffle_flag
|
||||
from mock import patch
|
||||
from pytz import UTC
|
||||
from xblock.runtime import DictKeyValueStore
|
||||
|
||||
@@ -45,7 +43,7 @@ class MasqueradeTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase, Mas
|
||||
"""
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(MasqueradeTestCase, cls).setUpClass()
|
||||
super().setUpClass()
|
||||
cls.course = CourseFactory.create(number='masquerade-test', metadata={'start': datetime.now(UTC)})
|
||||
cls.info_page = ItemFactory.create(
|
||||
category="course_info", parent_location=cls.course.location,
|
||||
@@ -83,7 +81,7 @@ class MasqueradeTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase, Mas
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
super(MasqueradeTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
self.test_user = self.create_user()
|
||||
self.login(self.test_user.email, 'test')
|
||||
@@ -96,7 +94,7 @@ class MasqueradeTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase, Mas
|
||||
url = reverse(
|
||||
'courseware_section',
|
||||
kwargs={
|
||||
'course_id': six.text_type(self.course.id),
|
||||
'course_id': str(self.course.id),
|
||||
'chapter': self.chapter.location.block_id,
|
||||
'section': self.sequential.location.block_id,
|
||||
}
|
||||
@@ -110,7 +108,7 @@ class MasqueradeTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase, Mas
|
||||
url = reverse(
|
||||
'info',
|
||||
kwargs={
|
||||
'course_id': six.text_type(self.course.id),
|
||||
'course_id': str(self.course.id),
|
||||
}
|
||||
)
|
||||
return self.client.get(url)
|
||||
@@ -122,7 +120,7 @@ class MasqueradeTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase, Mas
|
||||
url = reverse(
|
||||
'progress',
|
||||
kwargs={
|
||||
'course_id': six.text_type(self.course.id),
|
||||
'course_id': str(self.course.id),
|
||||
}
|
||||
)
|
||||
return self.client.get(url)
|
||||
@@ -142,8 +140,8 @@ class MasqueradeTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase, Mas
|
||||
problem_url = reverse(
|
||||
'xblock_handler',
|
||||
kwargs={
|
||||
'course_id': six.text_type(self.course.id),
|
||||
'usage_id': six.text_type(self.problem.location),
|
||||
'course_id': str(self.course.id),
|
||||
'usage_id': str(self.problem.location),
|
||||
'handler': 'xmodule_handler',
|
||||
'suffix': 'problem_get'
|
||||
}
|
||||
@@ -251,7 +249,7 @@ class TestStaffMasqueradeAsSpecificStudent(StaffMasqueradeTestCase, ProblemSubmi
|
||||
Check for staff being able to masquerade as a specific student.
|
||||
"""
|
||||
def setUp(self):
|
||||
super(TestStaffMasqueradeAsSpecificStudent, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.student_user = self.create_user()
|
||||
self.login_student()
|
||||
self.enroll(self.course, True)
|
||||
@@ -282,7 +280,7 @@ class TestStaffMasqueradeAsSpecificStudent(StaffMasqueradeTestCase, ProblemSubmi
|
||||
The return value is a string like u'1/2'.
|
||||
"""
|
||||
json_data = json.loads(self.look_at_question(self.problem_display_name).content.decode('utf-8'))
|
||||
progress = '%s/%s' % (str(json_data['current_score']), str(json_data['total_possible']))
|
||||
progress = '{}/{}'.format(str(json_data['current_score']), str(json_data['total_possible']))
|
||||
return progress
|
||||
|
||||
def assertExpectedLanguageInPreference(self, user, expected_language_code):
|
||||
@@ -320,7 +318,7 @@ class TestStaffMasqueradeAsSpecificStudent(StaffMasqueradeTestCase, ProblemSubmi
|
||||
|
||||
@ddt.data(
|
||||
'john', # Non-unicode username
|
||||
u'fôô@bar', # Unicode username with @, which is what the ENABLE_UNICODE_USERNAME feature allows
|
||||
'fôô@bar', # Unicode username with @, which is what the ENABLE_UNICODE_USERNAME feature allows
|
||||
)
|
||||
@patch.dict('django.conf.settings.FEATURES', {'DISABLE_START_DATES': False})
|
||||
def test_masquerade_as_specific_student(self, username):
|
||||
@@ -336,32 +334,32 @@ class TestStaffMasqueradeAsSpecificStudent(StaffMasqueradeTestCase, ProblemSubmi
|
||||
self.login(student.email, 'test')
|
||||
# Answer correctly as the student, and check progress.
|
||||
self.submit_answer('Correct', 'Correct')
|
||||
assert self.get_progress_detail() == u'2/2'
|
||||
assert self.get_progress_detail() == '2/2'
|
||||
|
||||
# Log in as staff, and check the problem is unanswered.
|
||||
self.login_staff()
|
||||
assert self.get_progress_detail() == u'0/2'
|
||||
assert self.get_progress_detail() == '0/2'
|
||||
|
||||
# Masquerade as the student, and check we can see the student state.
|
||||
self.update_masquerade(role='student', username=student.username)
|
||||
assert self.get_progress_detail() == u'2/2'
|
||||
assert self.get_progress_detail() == '2/2'
|
||||
|
||||
# Temporarily override the student state.
|
||||
self.submit_answer('Correct', 'Incorrect')
|
||||
assert self.get_progress_detail() == u'1/2'
|
||||
assert self.get_progress_detail() == '1/2'
|
||||
|
||||
# Reload the page and check we see the student state again.
|
||||
self.get_courseware_page()
|
||||
assert self.get_progress_detail() == u'2/2'
|
||||
assert self.get_progress_detail() == '2/2'
|
||||
|
||||
# Become the staff user again, and check the problem is still unanswered.
|
||||
self.update_masquerade(role='staff')
|
||||
assert self.get_progress_detail() == u'0/2'
|
||||
assert self.get_progress_detail() == '0/2'
|
||||
|
||||
# Verify the student state did not change.
|
||||
self.logout()
|
||||
self.login(student.email, 'test')
|
||||
assert self.get_progress_detail() == u'2/2'
|
||||
assert self.get_progress_detail() == '2/2'
|
||||
|
||||
def test_masquerading_with_language_preference(self):
|
||||
"""
|
||||
@@ -437,7 +435,7 @@ class TestGetMasqueradingGroupId(StaffMasqueradeTestCase):
|
||||
Check for staff being able to masquerade as belonging to a group.
|
||||
"""
|
||||
def setUp(self):
|
||||
super(TestGetMasqueradingGroupId, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.user_partition = UserPartition(
|
||||
0, 'Test User Partition', '',
|
||||
[Group(0, 'Group 1'), Group(1, 'Group 2')],
|
||||
@@ -489,7 +487,7 @@ class MasqueradingKeyValueStoreTest(TestCase):
|
||||
Unit tests for the MasqueradingKeyValueStore class.
|
||||
"""
|
||||
def setUp(self):
|
||||
super(MasqueradingKeyValueStoreTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.ro_kvs = ReadOnlyKeyValueStore({'a': 42, 'b': None, 'c': 'OpenCraft'})
|
||||
self.session = FakeSession()
|
||||
self.kvs = MasqueradingKeyValueStore(self.ro_kvs, self.session)
|
||||
|
||||
@@ -17,7 +17,7 @@ class CoursewareMiddlewareTestCase(SharedModuleStoreTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(CoursewareMiddlewareTestCase, cls).setUpClass()
|
||||
super().setUpClass()
|
||||
cls.course = CourseFactory.create()
|
||||
|
||||
def test_process_404(self):
|
||||
|
||||
@@ -5,10 +5,10 @@ Test for lms courseware app, module data (runtime data storage for XBlocks)
|
||||
|
||||
import json
|
||||
from functools import partial
|
||||
from unittest.mock import Mock, patch
|
||||
import pytest
|
||||
from django.db import connections, DatabaseError
|
||||
from django.test import TestCase
|
||||
from mock import Mock, patch
|
||||
from xblock.core import XBlock
|
||||
from xblock.exceptions import KeyValueMultiSaveError
|
||||
from xblock.fields import BlockScope, Scope, ScopeIds
|
||||
@@ -58,7 +58,7 @@ class StudentModuleFactory(cmfStudentModuleFactory):
|
||||
|
||||
class TestInvalidScopes(TestCase): # lint-amnesty, pylint: disable=missing-class-docstring
|
||||
def setUp(self):
|
||||
super(TestInvalidScopes, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.user = UserFactory.create(username='user')
|
||||
self.field_data_cache = FieldDataCache([mock_descriptor([mock_field(Scope.user_state, 'a_field')])], course_id, self.user) # lint-amnesty, pylint: disable=line-too-long
|
||||
self.kvs = DjangoKeyValueStore(self.field_data_cache)
|
||||
@@ -76,7 +76,7 @@ class TestInvalidScopes(TestCase): # lint-amnesty, pylint: disable=missing-clas
|
||||
self.assertRaises(InvalidScopeError, self.kvs.set_many, {key: 'value'})
|
||||
|
||||
|
||||
class OtherUserFailureTestMixin(object):
|
||||
class OtherUserFailureTestMixin:
|
||||
"""
|
||||
Mixin class to add test cases for failures when a user trying to use the kvs is not
|
||||
the one that instantiated the kvs.
|
||||
@@ -108,7 +108,7 @@ class TestStudentModuleStorage(OtherUserFailureTestMixin, TestCase):
|
||||
databases = {alias for alias in connections} # lint-amnesty, pylint: disable=unnecessary-comprehension
|
||||
|
||||
def setUp(self):
|
||||
super(TestStudentModuleStorage, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
student_module = StudentModuleFactory(state=json.dumps({'a_field': 'a_value', 'b_field': 'b_value'}))
|
||||
self.user = student_module.student
|
||||
assert self.user.id == 1
|
||||
@@ -236,7 +236,7 @@ class TestMissingStudentModule(TestCase): # lint-amnesty, pylint: disable=missi
|
||||
databases = {alias for alias in connections} # lint-amnesty, pylint: disable=unnecessary-comprehension
|
||||
|
||||
def setUp(self):
|
||||
super(TestMissingStudentModule, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
self.user = UserFactory.create(username='user')
|
||||
assert self.user.id == 1
|
||||
@@ -267,7 +267,7 @@ class TestMissingStudentModule(TestCase): # lint-amnesty, pylint: disable=missi
|
||||
with self.assertNumQueries(1, using='student_module_history'):
|
||||
self.kvs.set(user_state_key('a_field'), 'a_value')
|
||||
|
||||
assert 1 == sum((len(cache) for cache in self.field_data_cache.cache.values()))
|
||||
assert 1 == sum(len(cache) for cache in self.field_data_cache.cache.values())
|
||||
assert 1 == StudentModule.objects.all().count()
|
||||
|
||||
student_module = StudentModule.objects.all()[0]
|
||||
@@ -287,7 +287,7 @@ class TestMissingStudentModule(TestCase): # lint-amnesty, pylint: disable=missi
|
||||
assert not self.kvs.has(user_state_key('a_field'))
|
||||
|
||||
|
||||
class StorageTestBase(object):
|
||||
class StorageTestBase:
|
||||
"""
|
||||
A base class for that gets subclassed when testing each of the scopes.
|
||||
"""
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Test for lms courseware app, module render unit
|
||||
"""
|
||||
@@ -12,7 +11,6 @@ from functools import partial
|
||||
import pytest
|
||||
import ddt
|
||||
import pytz
|
||||
import six
|
||||
from bson import ObjectId
|
||||
from completion.waffle import ENABLE_COMPLETION_TRACKING_SWITCH # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from completion.models import BlockCompletion # lint-amnesty, pylint: disable=wrong-import-order
|
||||
@@ -30,12 +28,10 @@ from edx_toggles.toggles.testutils import override_waffle_switch # lint-amnesty
|
||||
from edx_when.field_data import DateLookupFieldData # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from freezegun import freeze_time # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from milestones.tests.utils import MilestonesTestCaseMixin # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from mock import MagicMock, Mock, patch # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from unittest.mock import MagicMock, Mock, patch # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from opaque_keys.edx.asides import AsideUsageKeyV2 # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from opaque_keys.edx.keys import CourseKey, UsageKey # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from pyquery import PyQuery # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from six import text_type # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from six.moves import range # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from web_fragments.fragment import Fragment # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from xblock.completable import CompletableXBlockMixin # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from xblock.core import XBlock, XBlockAside # lint-amnesty, pylint: disable=wrong-import-order
|
||||
@@ -188,7 +184,7 @@ class ModuleRenderTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(ModuleRenderTestCase, cls).setUpClass()
|
||||
super().setUpClass()
|
||||
cls.course_key = ToyCourseFactory.create().id
|
||||
cls.toy_course = modulestore().get_course(cls.course_key)
|
||||
|
||||
@@ -198,7 +194,7 @@ class ModuleRenderTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
"""
|
||||
Set up the course and user context
|
||||
"""
|
||||
super(ModuleRenderTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
OverrideFieldData.provider_classes = None
|
||||
|
||||
self.mock_user = UserFactory()
|
||||
@@ -214,7 +210,7 @@ class ModuleRenderTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
self.callback_url = reverse(
|
||||
'xqueue_callback',
|
||||
kwargs=dict(
|
||||
course_id=text_type(self.course_key),
|
||||
course_id=str(self.course_key),
|
||||
userid=str(self.mock_user.id),
|
||||
mod_id=self.mock_module.id,
|
||||
dispatch=self.dispatch
|
||||
@@ -223,7 +219,7 @@ class ModuleRenderTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
|
||||
def tearDown(self):
|
||||
OverrideFieldData.provider_classes = None
|
||||
super(ModuleRenderTestCase, self).tearDown() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().tearDown()
|
||||
|
||||
def test_get_module(self):
|
||||
assert render.get_module('dummyuser', None, 'invalid location', None) is None
|
||||
@@ -254,7 +250,7 @@ class ModuleRenderTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
|
||||
# See if the url got rewritten to the target link
|
||||
# note if the URL mapping changes then this assertion will break
|
||||
assert '/courses/' + text_type(self.course_key) + '/jump_to_id/vertical_test' in html
|
||||
assert '/courses/' + str(self.course_key) + '/jump_to_id/vertical_test' in html
|
||||
|
||||
def test_xqueue_callback_success(self):
|
||||
"""
|
||||
@@ -273,7 +269,7 @@ class ModuleRenderTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
request = self.request_factory.post(self.callback_url, data)
|
||||
render.xqueue_callback(
|
||||
request,
|
||||
text_type(self.course_key),
|
||||
str(self.course_key),
|
||||
self.mock_user.id,
|
||||
self.mock_module.id,
|
||||
self.dispatch
|
||||
@@ -296,7 +292,7 @@ class ModuleRenderTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
request = self.request_factory.post(self.callback_url, {})
|
||||
render.xqueue_callback(
|
||||
request,
|
||||
text_type(self.course_key),
|
||||
str(self.course_key),
|
||||
self.mock_user.id,
|
||||
self.mock_module.id,
|
||||
self.dispatch
|
||||
@@ -307,7 +303,7 @@ class ModuleRenderTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
request = self.request_factory.post(self.callback_url, data)
|
||||
render.xqueue_callback(
|
||||
request,
|
||||
text_type(self.course_key),
|
||||
str(self.course_key),
|
||||
self.mock_user.id,
|
||||
self.mock_module.id,
|
||||
self.dispatch
|
||||
@@ -318,8 +314,8 @@ class ModuleRenderTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
return reverse(
|
||||
'xblock_handler',
|
||||
args=[
|
||||
text_type(self.course_key),
|
||||
quote_slashes(text_type(self.course_key.make_usage_key('videosequence', 'Toy_Videos'))),
|
||||
str(self.course_key),
|
||||
quote_slashes(str(self.course_key.make_usage_key('videosequence', 'Toy_Videos'))),
|
||||
'xmodule_handler',
|
||||
'goto_position'
|
||||
]
|
||||
@@ -385,7 +381,7 @@ class ModuleRenderTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
assert 200 == response.status_code
|
||||
assert json.loads(response.content.decode('utf-8')) == {'success': True}
|
||||
|
||||
response = self.client.post(dispatch_url, {'position': u"Φυσικά"})
|
||||
response = self.client.post(dispatch_url, {'position': "Φυσικά"})
|
||||
assert 200 == response.status_code
|
||||
assert json.loads(response.content.decode('utf-8')) == {'success': True}
|
||||
|
||||
@@ -503,7 +499,7 @@ class ModuleRenderTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
Ensure that the resource hasher works and does not fail on unicode,
|
||||
decoded or otherwise.
|
||||
"""
|
||||
resources = ['ASCII text', u'❄ I am a special snowflake.', "❄ So am I, but I didn't tell you."]
|
||||
resources = ['ASCII text', '❄ I am a special snowflake.', "❄ So am I, but I didn't tell you."]
|
||||
assert hash_resource(resources) == '50c2ae79fbce9980e0803848914b0a09'
|
||||
|
||||
|
||||
@@ -514,12 +510,12 @@ class TestHandleXBlockCallback(SharedModuleStoreTestCase, LoginEnrollmentTestCas
|
||||
"""
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestHandleXBlockCallback, cls).setUpClass()
|
||||
super().setUpClass()
|
||||
cls.course_key = ToyCourseFactory.create().id
|
||||
cls.toy_course = modulestore().get_course(cls.course_key)
|
||||
|
||||
def setUp(self):
|
||||
super(TestHandleXBlockCallback, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
self.location = self.course_key.make_usage_key('chapter', 'Overview')
|
||||
self.mock_user = UserFactory.create()
|
||||
@@ -533,7 +529,7 @@ class TestHandleXBlockCallback(SharedModuleStoreTestCase, LoginEnrollmentTestCas
|
||||
# Construct a 'standard' xqueue_callback url
|
||||
self.callback_url = reverse(
|
||||
'xqueue_callback', kwargs={
|
||||
'course_id': text_type(self.course_key),
|
||||
'course_id': str(self.course_key),
|
||||
'userid': str(self.mock_user.id),
|
||||
'mod_id': self.mock_module.id,
|
||||
'dispatch': self.dispatch
|
||||
@@ -563,8 +559,8 @@ class TestHandleXBlockCallback(SharedModuleStoreTestCase, LoginEnrollmentTestCas
|
||||
request.user = self.mock_user
|
||||
response = render.handle_xblock_callback(
|
||||
request,
|
||||
text_type(course.id),
|
||||
quote_slashes(text_type(block.scope_ids.usage_id)),
|
||||
str(course.id),
|
||||
quote_slashes(str(block.scope_ids.usage_id)),
|
||||
handler,
|
||||
'',
|
||||
)
|
||||
@@ -577,12 +573,12 @@ class TestHandleXBlockCallback(SharedModuleStoreTestCase, LoginEnrollmentTestCas
|
||||
"""
|
||||
request = RequestFactory().post('dummy_url', data={'position': 1})
|
||||
csrf_token = get_token(request)
|
||||
request._post = {'csrfmiddlewaretoken': '{}-dummy'.format(csrf_token)} # pylint: disable=protected-access
|
||||
request._post = {'csrfmiddlewaretoken': f'{csrf_token}-dummy'} # pylint: disable=protected-access
|
||||
request.user = self.mock_user
|
||||
response = render.handle_xblock_callback(
|
||||
request,
|
||||
text_type(self.course_key),
|
||||
quote_slashes(text_type(self.location)),
|
||||
str(self.course_key),
|
||||
quote_slashes(str(self.location)),
|
||||
'xmodule_handler',
|
||||
'goto_position',
|
||||
)
|
||||
@@ -598,8 +594,8 @@ class TestHandleXBlockCallback(SharedModuleStoreTestCase, LoginEnrollmentTestCas
|
||||
request.user = self.mock_user
|
||||
response = render.handle_xblock_callback(
|
||||
request,
|
||||
text_type(self.course_key),
|
||||
quote_slashes(text_type(self.location)),
|
||||
str(self.course_key),
|
||||
quote_slashes(str(self.location)),
|
||||
'xmodule_handler',
|
||||
'goto_position',
|
||||
)
|
||||
@@ -611,7 +607,7 @@ class TestHandleXBlockCallback(SharedModuleStoreTestCase, LoginEnrollmentTestCas
|
||||
with pytest.raises(Http404):
|
||||
render.handle_xblock_callback(
|
||||
request,
|
||||
text_type(self.course_key),
|
||||
str(self.course_key),
|
||||
'invalid Location',
|
||||
'dummy_handler'
|
||||
'dummy_dispatch'
|
||||
@@ -623,7 +619,7 @@ class TestHandleXBlockCallback(SharedModuleStoreTestCase, LoginEnrollmentTestCas
|
||||
data={'file_id': (self._mock_file(), ) * (settings.MAX_FILEUPLOADS_PER_INPUT + 1)}
|
||||
)
|
||||
request.user = self.mock_user
|
||||
assert render.handle_xblock_callback(request, text_type(self.course_key), quote_slashes(text_type(self.location)), 'dummy_handler').content.decode('utf-8') == json.dumps({'success': (f'Submission aborted! Maximum {settings.MAX_FILEUPLOADS_PER_INPUT:d} files may be submitted at once')}, indent=2) # pylint: disable=line-too-long
|
||||
assert render.handle_xblock_callback(request, str(self.course_key), quote_slashes(str(self.location)), 'dummy_handler').content.decode('utf-8') == json.dumps({'success': (f'Submission aborted! Maximum {settings.MAX_FILEUPLOADS_PER_INPUT:d} files may be submitted at once')}, indent=2) # pylint: disable=line-too-long
|
||||
|
||||
def test_too_large_file(self):
|
||||
inputfile = self._mock_file(size=1 + settings.STUDENT_FILEUPLOAD_MAX_SIZE)
|
||||
@@ -632,15 +628,15 @@ class TestHandleXBlockCallback(SharedModuleStoreTestCase, LoginEnrollmentTestCas
|
||||
data={'file_id': inputfile}
|
||||
)
|
||||
request.user = self.mock_user
|
||||
assert render.handle_xblock_callback(request, text_type(self.course_key), quote_slashes(text_type(self.location)), 'dummy_handler').content.decode('utf-8') == json.dumps({'success': (u'Submission aborted! Your file "%s" is too large (max size: %d MB)' % (inputfile.name, (settings.STUDENT_FILEUPLOAD_MAX_SIZE / (1000 ** 2))))}, indent=2) # pylint: disable=line-too-long
|
||||
assert render.handle_xblock_callback(request, str(self.course_key), quote_slashes(str(self.location)), 'dummy_handler').content.decode('utf-8') == json.dumps({'success': ('Submission aborted! Your file "%s" is too large (max size: %d MB)' % (inputfile.name, (settings.STUDENT_FILEUPLOAD_MAX_SIZE / (1000 ** 2))))}, indent=2) # pylint: disable=line-too-long
|
||||
|
||||
def test_xmodule_dispatch(self):
|
||||
request = self.request_factory.post('dummy_url', data={'position': 1})
|
||||
request.user = self.mock_user
|
||||
response = render.handle_xblock_callback(
|
||||
request,
|
||||
text_type(self.course_key),
|
||||
quote_slashes(text_type(self.location)),
|
||||
str(self.course_key),
|
||||
quote_slashes(str(self.location)),
|
||||
'xmodule_handler',
|
||||
'goto_position',
|
||||
)
|
||||
@@ -653,7 +649,7 @@ class TestHandleXBlockCallback(SharedModuleStoreTestCase, LoginEnrollmentTestCas
|
||||
render.handle_xblock_callback(
|
||||
request,
|
||||
'bad_course_id',
|
||||
quote_slashes(text_type(self.location)),
|
||||
quote_slashes(str(self.location)),
|
||||
'xmodule_handler',
|
||||
'goto_position',
|
||||
)
|
||||
@@ -664,8 +660,8 @@ class TestHandleXBlockCallback(SharedModuleStoreTestCase, LoginEnrollmentTestCas
|
||||
with pytest.raises(Http404):
|
||||
render.handle_xblock_callback(
|
||||
request,
|
||||
text_type(self.course_key),
|
||||
quote_slashes(text_type(self.course_key.make_usage_key('chapter', 'bad_location'))),
|
||||
str(self.course_key),
|
||||
quote_slashes(str(self.course_key.make_usage_key('chapter', 'bad_location'))),
|
||||
'xmodule_handler',
|
||||
'goto_position',
|
||||
)
|
||||
@@ -676,8 +672,8 @@ class TestHandleXBlockCallback(SharedModuleStoreTestCase, LoginEnrollmentTestCas
|
||||
with pytest.raises(Http404):
|
||||
render.handle_xblock_callback(
|
||||
request,
|
||||
text_type(self.course_key),
|
||||
quote_slashes(text_type(self.location)),
|
||||
str(self.course_key),
|
||||
quote_slashes(str(self.location)),
|
||||
'xmodule_handler',
|
||||
'bad_dispatch',
|
||||
)
|
||||
@@ -688,8 +684,8 @@ class TestHandleXBlockCallback(SharedModuleStoreTestCase, LoginEnrollmentTestCas
|
||||
with pytest.raises(Http404):
|
||||
render.handle_xblock_callback(
|
||||
request,
|
||||
text_type(self.course_key),
|
||||
quote_slashes(text_type(self.location)),
|
||||
str(self.course_key),
|
||||
quote_slashes(str(self.location)),
|
||||
'bad_handler',
|
||||
'bad_dispatch',
|
||||
)
|
||||
@@ -708,8 +704,8 @@ class TestHandleXBlockCallback(SharedModuleStoreTestCase, LoginEnrollmentTestCas
|
||||
|
||||
response = render.handle_xblock_callback(
|
||||
request,
|
||||
text_type(course.id),
|
||||
quote_slashes(text_type(block.scope_ids.usage_id)),
|
||||
str(course.id),
|
||||
quote_slashes(str(block.scope_ids.usage_id)),
|
||||
'set_score',
|
||||
'',
|
||||
)
|
||||
@@ -740,8 +736,8 @@ class TestHandleXBlockCallback(SharedModuleStoreTestCase, LoginEnrollmentTestCas
|
||||
with patch('completion.models.BlockCompletionManager.submit_completion') as mock_complete:
|
||||
render.handle_xblock_callback(
|
||||
request,
|
||||
text_type(course.id),
|
||||
quote_slashes(text_type(block.scope_ids.usage_id)),
|
||||
str(course.id),
|
||||
quote_slashes(str(block.scope_ids.usage_id)),
|
||||
signal,
|
||||
'',
|
||||
)
|
||||
@@ -781,9 +777,9 @@ class TestHandleXBlockCallback(SharedModuleStoreTestCase, LoginEnrollmentTestCas
|
||||
def get_usage_key():
|
||||
"""return usage key"""
|
||||
return (
|
||||
quote_slashes(text_type(AsideUsageKeyV2(block.scope_ids.usage_id, "aside")))
|
||||
quote_slashes(str(AsideUsageKeyV2(block.scope_ids.usage_id, "aside")))
|
||||
if is_xblock_aside
|
||||
else text_type(block.scope_ids.usage_id)
|
||||
else str(block.scope_ids.usage_id)
|
||||
)
|
||||
|
||||
with patch(
|
||||
@@ -796,7 +792,7 @@ class TestHandleXBlockCallback(SharedModuleStoreTestCase, LoginEnrollmentTestCas
|
||||
) as mocked_webob_to_django_response:
|
||||
render.handle_xblock_callback(
|
||||
request,
|
||||
text_type(course.id),
|
||||
str(course.id),
|
||||
get_usage_key(),
|
||||
'complete',
|
||||
'',
|
||||
@@ -822,7 +818,7 @@ class TestHandleXBlockCallback(SharedModuleStoreTestCase, LoginEnrollmentTestCas
|
||||
), self.assertRaises(Http404):
|
||||
render.handle_xblock_callback(
|
||||
request,
|
||||
text_type(course.id),
|
||||
str(course.id),
|
||||
"foo@bar",
|
||||
'complete',
|
||||
'',
|
||||
@@ -873,8 +869,8 @@ class TestHandleXBlockCallback(SharedModuleStoreTestCase, LoginEnrollmentTestCas
|
||||
mock_masq.return_value = True
|
||||
response = render.handle_xblock_callback(
|
||||
request,
|
||||
text_type(course.id),
|
||||
quote_slashes(text_type(block.scope_ids.usage_id)),
|
||||
str(course.id),
|
||||
quote_slashes(str(block.scope_ids.usage_id)),
|
||||
'complete',
|
||||
'',
|
||||
)
|
||||
@@ -896,8 +892,8 @@ class TestHandleXBlockCallback(SharedModuleStoreTestCase, LoginEnrollmentTestCas
|
||||
|
||||
render.handle_xblock_callback(
|
||||
request,
|
||||
text_type(course.id),
|
||||
quote_slashes(text_type(descriptor.location)),
|
||||
str(course.id),
|
||||
quote_slashes(str(descriptor.location)),
|
||||
'xmodule_handler',
|
||||
'problem_check',
|
||||
)
|
||||
@@ -912,17 +908,17 @@ class TestXBlockView(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
"""
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestXBlockView, cls).setUpClass()
|
||||
super().setUpClass()
|
||||
cls.course_key = ToyCourseFactory.create().id
|
||||
cls.toy_course = modulestore().get_course(cls.course_key)
|
||||
|
||||
def setUp(self):
|
||||
super(TestXBlockView, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
self.location = text_type(self.course_key.make_usage_key('html', 'toyhtml'))
|
||||
self.location = str(self.course_key.make_usage_key('html', 'toyhtml'))
|
||||
self.request_factory = RequestFactory()
|
||||
|
||||
self.view_args = [text_type(self.course_key), quote_slashes(self.location), 'student_view']
|
||||
self.view_args = [str(self.course_key), quote_slashes(self.location), 'student_view']
|
||||
self.xblock_view_url = reverse('xblock_view', args=self.view_args)
|
||||
|
||||
def test_xblock_view_handler(self):
|
||||
@@ -972,7 +968,7 @@ class TestTOC(ModuleStoreTestCase):
|
||||
"""
|
||||
self.course_key = ToyCourseFactory.create().id # pylint: disable=attribute-defined-outside-init
|
||||
self.chapter = 'Overview' # lint-amnesty, pylint: disable=attribute-defined-outside-init
|
||||
chapter_url = '%s/%s/%s' % ('/courses', self.course_key, self.chapter)
|
||||
chapter_url = '{}/{}/{}'.format('/courses', self.course_key, self.chapter)
|
||||
factory = RequestFactoryNoCsrf()
|
||||
self.request = factory.get(chapter_url) # lint-amnesty, pylint: disable=attribute-defined-outside-init
|
||||
self.request.user = UserFactory()
|
||||
@@ -1000,15 +996,15 @@ class TestTOC(ModuleStoreTestCase):
|
||||
self.setup_request_and_course(setup_finds, setup_sends)
|
||||
|
||||
expected = ([{'active': True, 'sections':
|
||||
[{'url_name': 'Toy_Videos', 'display_name': u'Toy Videos', 'graded': True,
|
||||
'format': u'Lecture Sequence', 'due': None, 'active': False},
|
||||
{'url_name': 'Welcome', 'display_name': u'Welcome', 'graded': True,
|
||||
[{'url_name': 'Toy_Videos', 'display_name': 'Toy Videos', 'graded': True,
|
||||
'format': 'Lecture Sequence', 'due': None, 'active': False},
|
||||
{'url_name': 'Welcome', 'display_name': 'Welcome', 'graded': True,
|
||||
'format': '', 'due': None, 'active': False},
|
||||
{'url_name': 'video_123456789012', 'display_name': 'Test Video', 'graded': True,
|
||||
'format': '', 'due': None, 'active': False},
|
||||
{'url_name': 'video_4f66f493ac8f', 'display_name': 'Video', 'graded': True,
|
||||
'format': '', 'due': None, 'active': False}],
|
||||
'url_name': 'Overview', 'display_name': u'Overview', 'display_id': u'overview'},
|
||||
'url_name': 'Overview', 'display_name': 'Overview', 'display_id': 'overview'},
|
||||
{'active': False, 'sections':
|
||||
[{'url_name': 'toyvideo', 'display_name': 'toyvideo', 'graded': True,
|
||||
'format': '', 'due': None, 'active': False}],
|
||||
@@ -1040,15 +1036,15 @@ class TestTOC(ModuleStoreTestCase):
|
||||
self.setup_request_and_course(setup_finds, setup_sends)
|
||||
section = 'Welcome'
|
||||
expected = ([{'active': True, 'sections':
|
||||
[{'url_name': 'Toy_Videos', 'display_name': u'Toy Videos', 'graded': True,
|
||||
'format': u'Lecture Sequence', 'due': None, 'active': False},
|
||||
{'url_name': 'Welcome', 'display_name': u'Welcome', 'graded': True,
|
||||
[{'url_name': 'Toy_Videos', 'display_name': 'Toy Videos', 'graded': True,
|
||||
'format': 'Lecture Sequence', 'due': None, 'active': False},
|
||||
{'url_name': 'Welcome', 'display_name': 'Welcome', 'graded': True,
|
||||
'format': '', 'due': None, 'active': True},
|
||||
{'url_name': 'video_123456789012', 'display_name': 'Test Video', 'graded': True,
|
||||
'format': '', 'due': None, 'active': False},
|
||||
{'url_name': 'video_4f66f493ac8f', 'display_name': 'Video', 'graded': True,
|
||||
'format': '', 'due': None, 'active': False}],
|
||||
'url_name': 'Overview', 'display_name': u'Overview', 'display_id': u'overview'},
|
||||
'url_name': 'Overview', 'display_name': 'Overview', 'display_id': 'overview'},
|
||||
{'active': False, 'sections':
|
||||
[{'url_name': 'toyvideo', 'display_name': 'toyvideo', 'graded': True,
|
||||
'format': '', 'due': None, 'active': False}],
|
||||
@@ -1070,16 +1066,16 @@ class TestProctoringRendering(SharedModuleStoreTestCase):
|
||||
"""Check the Table of Contents for a course"""
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestProctoringRendering, cls).setUpClass()
|
||||
super().setUpClass()
|
||||
cls.course_key = ToyCourseFactory.create(enable_proctored_exams=True).id
|
||||
|
||||
def setUp(self):
|
||||
"""
|
||||
Set up the initial mongo datastores
|
||||
"""
|
||||
super(TestProctoringRendering, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.chapter = 'Overview'
|
||||
chapter_url = '%s/%s/%s' % ('/courses', self.course_key, self.chapter)
|
||||
chapter_url = '{}/{}/{}'.format('/courses', self.course_key, self.chapter)
|
||||
factory = RequestFactoryNoCsrf()
|
||||
self.request = factory.get(chapter_url)
|
||||
self.request.user = UserFactory.create()
|
||||
@@ -1218,7 +1214,7 @@ class TestProctoringRendering(SharedModuleStoreTestCase):
|
||||
# we expect there not to be a 'proctoring' key in the dict
|
||||
assert 'proctoring' not in section_actual
|
||||
assert actual['previous_of_active_section'] is None
|
||||
assert actual['next_of_active_section']['url_name'] == u'Welcome'
|
||||
assert actual['next_of_active_section']['url_name'] == 'Welcome'
|
||||
|
||||
@ddt.data(
|
||||
(
|
||||
@@ -1344,8 +1340,8 @@ class TestProctoringRendering(SharedModuleStoreTestCase):
|
||||
)
|
||||
|
||||
exam_id = create_exam(
|
||||
course_id=text_type(self.course_key),
|
||||
content_id=text_type(sequence.location),
|
||||
course_id=str(self.course_key),
|
||||
content_id=str(sequence.location),
|
||||
exam_name='foo',
|
||||
time_limit_mins=10,
|
||||
is_proctored=True,
|
||||
@@ -1354,7 +1350,7 @@ class TestProctoringRendering(SharedModuleStoreTestCase):
|
||||
|
||||
if attempt_status:
|
||||
attempt_id = create_exam_attempt(
|
||||
six.text_type(exam_id).encode('utf-8'),
|
||||
str(exam_id).encode('utf-8'),
|
||||
self.request.user.id,
|
||||
taking_as_proctored=True
|
||||
)
|
||||
@@ -1392,7 +1388,7 @@ class TestGatedSubsectionRendering(SharedModuleStoreTestCase, MilestonesTestCase
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestGatedSubsectionRendering, cls).setUpClass()
|
||||
super().setUpClass()
|
||||
cls.course = CourseFactory.create()
|
||||
cls.course.enable_subsection_gating = True
|
||||
cls.course.save()
|
||||
@@ -1402,7 +1398,7 @@ class TestGatedSubsectionRendering(SharedModuleStoreTestCase, MilestonesTestCase
|
||||
"""
|
||||
Set up the initial test data
|
||||
"""
|
||||
super(TestGatedSubsectionRendering, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
self.chapter = ItemFactory.create(
|
||||
parent=self.course,
|
||||
@@ -1419,7 +1415,7 @@ class TestGatedSubsectionRendering(SharedModuleStoreTestCase, MilestonesTestCase
|
||||
category='sequential',
|
||||
display_name="Gated Sequential"
|
||||
)
|
||||
self.request = RequestFactoryNoCsrf().get('%s/%s/%s' % ('/courses', self.course.id, self.chapter.display_name))
|
||||
self.request = RequestFactoryNoCsrf().get(f'/courses/{self.course.id}/{self.chapter.display_name}')
|
||||
self.request.user = UserFactory()
|
||||
self.field_data_cache = FieldDataCache.cache_for_descriptor_descendents(
|
||||
self.course.id, self.request.user, self.course, depth=2
|
||||
@@ -1476,7 +1472,7 @@ class TestHtmlModifiers(ModuleStoreTestCase):
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(TestHtmlModifiers, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.course = CourseFactory.create()
|
||||
self.request = RequestFactoryNoCsrf().get('/')
|
||||
self.request.user = self.user
|
||||
@@ -1598,7 +1594,7 @@ class TestHtmlModifiers(ModuleStoreTestCase):
|
||||
)
|
||||
result_fragment = module.render(STUDENT_VIEW)
|
||||
|
||||
assert '/courses/{course_id}/bar/content'.format(course_id=text_type(self.course.id)) in result_fragment.content
|
||||
assert '/courses/{course_id}/bar/content'.format(course_id=str(self.course.id)) in result_fragment.content
|
||||
|
||||
|
||||
class XBlockWithJsonInitData(XBlock):
|
||||
@@ -1611,8 +1607,8 @@ class XBlockWithJsonInitData(XBlock):
|
||||
"""
|
||||
A simple view that returns just enough to test.
|
||||
"""
|
||||
frag = Fragment(u"Hello there!")
|
||||
frag.add_javascript(u'alert("Hi!");')
|
||||
frag = Fragment("Hello there!")
|
||||
frag.add_javascript('alert("Hi!");')
|
||||
frag.initialize_js('ThumbsBlock', self.the_json_data)
|
||||
return frag
|
||||
|
||||
@@ -1659,7 +1655,7 @@ class DetachedXBlock(XBlock):
|
||||
"""
|
||||
A simple view that returns just enough to test.
|
||||
"""
|
||||
frag = Fragment(u"Hello there!")
|
||||
frag = Fragment("Hello there!")
|
||||
return frag
|
||||
|
||||
|
||||
@@ -1670,11 +1666,11 @@ class TestStaffDebugInfo(SharedModuleStoreTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestStaffDebugInfo, cls).setUpClass()
|
||||
super().setUpClass()
|
||||
cls.course = CourseFactory.create()
|
||||
|
||||
def setUp(self):
|
||||
super(TestStaffDebugInfo, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.user = UserFactory.create()
|
||||
self.request = RequestFactoryNoCsrf().get('/')
|
||||
self.request.user = self.user
|
||||
@@ -1865,12 +1861,12 @@ class TestAnonymousStudentId(SharedModuleStoreTestCase, LoginEnrollmentTestCase)
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestAnonymousStudentId, cls).setUpClass()
|
||||
super().setUpClass()
|
||||
cls.course_key = ToyCourseFactory.create().id
|
||||
cls.course = modulestore().get_course(cls.course_key)
|
||||
|
||||
def setUp(self):
|
||||
super(TestAnonymousStudentId, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.user = UserFactory()
|
||||
|
||||
@patch('lms.djangoapps.courseware.module_render.has_access', Mock(return_value=True, autospec=True))
|
||||
@@ -1935,11 +1931,11 @@ class TestModuleTrackingContext(SharedModuleStoreTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestModuleTrackingContext, cls).setUpClass()
|
||||
super().setUpClass()
|
||||
cls.course = CourseFactory.create()
|
||||
|
||||
def setUp(self):
|
||||
super(TestModuleTrackingContext, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
self.user = UserFactory.create()
|
||||
self.request = RequestFactoryNoCsrf().get('/')
|
||||
@@ -1956,7 +1952,7 @@ class TestModuleTrackingContext(SharedModuleStoreTestCase):
|
||||
)
|
||||
|
||||
def test_context_contains_display_name(self, mock_tracker):
|
||||
problem_display_name = u'Option Response Problem'
|
||||
problem_display_name = 'Option Response Problem'
|
||||
module_info = self.handle_callback_and_get_module_info(mock_tracker, problem_display_name)
|
||||
assert problem_display_name == module_info['display_name']
|
||||
|
||||
@@ -1970,7 +1966,7 @@ class TestModuleTrackingContext(SharedModuleStoreTestCase):
|
||||
Check that related xblock asides populate information in the 'problem_check' event in case
|
||||
the 'get_event_context' method is exist
|
||||
"""
|
||||
problem_display_name = u'Test Problem'
|
||||
problem_display_name = 'Test Problem'
|
||||
|
||||
def get_event_context(self, event_type, event): # pylint: disable=unused-argument
|
||||
"""
|
||||
@@ -2011,8 +2007,8 @@ class TestModuleTrackingContext(SharedModuleStoreTestCase):
|
||||
with patch('lms.djangoapps.courseware.module_render.tracker') as mock_tracker_for_context:
|
||||
render.handle_xblock_callback(
|
||||
self.request,
|
||||
text_type(self.course.id),
|
||||
quote_slashes(text_type(descriptor.location)),
|
||||
str(self.course.id),
|
||||
quote_slashes(str(descriptor.location)),
|
||||
'xmodule_handler',
|
||||
'problem_check',
|
||||
)
|
||||
@@ -2051,15 +2047,15 @@ class TestModuleTrackingContext(SharedModuleStoreTestCase):
|
||||
information about their library block source in events.
|
||||
We patch the modulestore to avoid having to create a library.
|
||||
"""
|
||||
original_usage_key = UsageKey.from_string(u'block-v1:A+B+C+type@problem+block@abcd1234')
|
||||
original_usage_key = UsageKey.from_string('block-v1:A+B+C+type@problem+block@abcd1234')
|
||||
original_usage_version = ObjectId()
|
||||
mock_get_original_usage = lambda _, key: (original_usage_key, original_usage_version)
|
||||
with patch('xmodule.modulestore.mixed.MixedModuleStore.get_block_original_usage', mock_get_original_usage):
|
||||
module_info = self.handle_callback_and_get_module_info(mock_tracker)
|
||||
assert 'original_usage_key' in module_info
|
||||
assert module_info['original_usage_key'] == text_type(original_usage_key)
|
||||
assert module_info['original_usage_key'] == str(original_usage_key)
|
||||
assert 'original_usage_version' in module_info
|
||||
assert module_info['original_usage_version'] == text_type(original_usage_version)
|
||||
assert module_info['original_usage_version'] == str(original_usage_version)
|
||||
|
||||
|
||||
class TestXmoduleRuntimeEvent(TestSubmittingProblems):
|
||||
@@ -2068,7 +2064,7 @@ class TestXmoduleRuntimeEvent(TestSubmittingProblems):
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(TestXmoduleRuntimeEvent, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.homework = self.add_graded_section_to_course('homework')
|
||||
self.problem = self.add_dropdown_to_section(self.homework.location, 'p1', 1)
|
||||
self.grade_dict = {'value': 0.18, 'max_value': 32}
|
||||
@@ -2120,8 +2116,8 @@ class TestXmoduleRuntimeEvent(TestSubmittingProblems):
|
||||
'raw_earned': self.grade_dict['value'],
|
||||
'weight': None,
|
||||
'user_id': self.student_user.id,
|
||||
'course_id': text_type(self.course.id),
|
||||
'usage_id': text_type(self.problem.location),
|
||||
'course_id': str(self.course.id),
|
||||
'usage_id': str(self.problem.location),
|
||||
'only_if_higher': None,
|
||||
'modified': datetime.now().replace(tzinfo=pytz.UTC),
|
||||
'score_db_table': 'csm',
|
||||
@@ -2138,7 +2134,7 @@ class TestRebindModule(TestSubmittingProblems):
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(TestRebindModule, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.homework = self.add_graded_section_to_course('homework')
|
||||
self.lti = ItemFactory.create(category='lti', parent=self.homework)
|
||||
self.problem = ItemFactory.create(category='problem', parent=self.homework)
|
||||
@@ -2218,7 +2214,7 @@ class TestEventPublishing(ModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
"""
|
||||
Set up the course and user context
|
||||
"""
|
||||
super(TestEventPublishing, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
self.mock_user = UserFactory()
|
||||
self.mock_user.id = 1
|
||||
@@ -2254,14 +2250,14 @@ class LMSXBlockServiceBindingTest(SharedModuleStoreTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(LMSXBlockServiceBindingTest, cls).setUpClass()
|
||||
super().setUpClass()
|
||||
cls.course = CourseFactory.create()
|
||||
|
||||
def setUp(self):
|
||||
"""
|
||||
Set up the user and other fields that will be used to instantiate the runtime.
|
||||
"""
|
||||
super(LMSXBlockServiceBindingTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.user = UserFactory()
|
||||
self.student_data = Mock()
|
||||
self.track_function = Mock()
|
||||
@@ -2345,12 +2341,12 @@ class TestFilteredChildren(SharedModuleStoreTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestFilteredChildren, cls).setUpClass()
|
||||
super().setUpClass()
|
||||
cls.course = CourseFactory.create()
|
||||
|
||||
# pylint: disable=attribute-defined-outside-init
|
||||
def setUp(self):
|
||||
super(TestFilteredChildren, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.users = {number: UserFactory() for number in USER_NUMBERS}
|
||||
|
||||
self._old_has_access = render.has_access
|
||||
@@ -2429,7 +2425,7 @@ class TestFilteredChildren(SharedModuleStoreTestCase):
|
||||
ItemFactory(category=child_type, parent=self.parent).scope_ids.usage_id # lint-amnesty, pylint: disable=no-member
|
||||
for child_type in BLOCK_TYPES
|
||||
]
|
||||
for user in six.itervalues(self.users)
|
||||
for user in self.users.values()
|
||||
}
|
||||
|
||||
self.all_children = sum(list(self.children_for_user.values()), [])
|
||||
@@ -2487,7 +2483,7 @@ class TestFilteredChildren(SharedModuleStoreTestCase):
|
||||
"""
|
||||
Used to assert that sets of children are equivalent.
|
||||
"""
|
||||
assert set(child_usage_ids) == set((child.scope_ids.usage_id for child in block.get_children()))
|
||||
assert set(child_usage_ids) == {child.scope_ids.usage_id for child in block.get_children()}
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@@ -2497,7 +2493,7 @@ class TestDisabledXBlockTypes(ModuleStoreTestCase):
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(TestDisabledXBlockTypes, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
XBlockConfiguration(name='video', enabled=False).save()
|
||||
|
||||
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
|
||||
|
||||
@@ -5,12 +5,10 @@ This test file will run through some LMS test scenarios regarding access and nav
|
||||
|
||||
import time
|
||||
|
||||
from unittest.mock import patch
|
||||
from django.conf import settings
|
||||
from django.test.utils import override_settings
|
||||
from django.urls import reverse
|
||||
from mock import patch
|
||||
from six import text_type
|
||||
from six.moves import range
|
||||
|
||||
from edx_toggles.toggles.testutils import override_waffle_flag
|
||||
from lms.djangoapps.courseware.tests.factories import GlobalStaffFactory
|
||||
@@ -31,7 +29,7 @@ class TestNavigation(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
# pylint: disable=super-method-not-called
|
||||
with super(TestNavigation, cls).setUpClassAndTestData():
|
||||
with super().setUpClassAndTestData():
|
||||
cls.test_course = CourseFactory.create()
|
||||
cls.test_course_proctored = CourseFactory.create()
|
||||
cls.course = CourseFactory.create()
|
||||
@@ -75,12 +73,12 @@ class TestNavigation(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
cls.user = UserFactory()
|
||||
|
||||
def setUp(self):
|
||||
super(TestNavigation, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
# Create student accounts and activate them.
|
||||
for i in range(len(self.STUDENT_INFO)):
|
||||
email, password = self.STUDENT_INFO[i]
|
||||
username = 'u{0}'.format(i)
|
||||
username = f'u{i}'
|
||||
self.create_account(username, email, password)
|
||||
self.activate_user(email)
|
||||
|
||||
@@ -89,7 +87,7 @@ class TestNavigation(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
for line in response.content.decode('utf-8').split('\n'):
|
||||
if tabname in line and 'active' in line:
|
||||
return
|
||||
raise AssertionError(u"assertTabActive failed: {} not active".format(tabname))
|
||||
raise AssertionError(f"assertTabActive failed: {tabname} not active")
|
||||
|
||||
def assertTabInactive(self, tabname, response): # lint-amnesty, pylint: disable=useless-return
|
||||
''' Check if the progress tab is active in the tab set '''
|
||||
@@ -118,7 +116,7 @@ class TestNavigation(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
)
|
||||
for (displayname, accordion, tabs) in test_data:
|
||||
response = self.client.get(reverse('courseware_section', kwargs={
|
||||
'course_id': text_type(self.course.id),
|
||||
'course_id': str(self.course.id),
|
||||
'chapter': 'Chrome',
|
||||
'section': displayname,
|
||||
}))
|
||||
@@ -129,7 +127,7 @@ class TestNavigation(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
self.assertTabActive('courseware', response)
|
||||
|
||||
response = self.client.get(reverse('courseware_section', kwargs={
|
||||
'course_id': text_type(self.course.id),
|
||||
'course_id': str(self.course.id),
|
||||
'chapter': 'Chrome',
|
||||
'section': 'pdf_textbooks_tab',
|
||||
}))
|
||||
@@ -169,9 +167,9 @@ class TestNavigation(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
self.enroll(self.test_course, True)
|
||||
|
||||
resp = self.client.get(reverse('courseware',
|
||||
kwargs={'course_id': text_type(self.course.id)}))
|
||||
kwargs={'course_id': str(self.course.id)}))
|
||||
self.assertRedirects(resp, reverse(
|
||||
'courseware_section', kwargs={'course_id': text_type(self.course.id),
|
||||
'courseware_section', kwargs={'course_id': str(self.course.id),
|
||||
'chapter': 'Overview',
|
||||
'section': 'Welcome'}))
|
||||
|
||||
@@ -188,14 +186,14 @@ class TestNavigation(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
section_url = reverse(
|
||||
'courseware_section',
|
||||
kwargs={
|
||||
'course_id': text_type(self.course.id),
|
||||
'course_id': str(self.course.id),
|
||||
'chapter': 'Overview',
|
||||
'section': 'Welcome',
|
||||
},
|
||||
)
|
||||
self.client.get(section_url)
|
||||
resp = self.client.get(
|
||||
reverse('courseware', kwargs={'course_id': text_type(self.course.id)}),
|
||||
reverse('courseware', kwargs={'course_id': str(self.course.id)}),
|
||||
)
|
||||
self.assertRedirects(resp, section_url)
|
||||
|
||||
@@ -212,7 +210,7 @@ class TestNavigation(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
section_url = reverse(
|
||||
'courseware_section',
|
||||
kwargs={
|
||||
'course_id': text_type(self.course.id),
|
||||
'course_id': str(self.course.id),
|
||||
'chapter': 'factory_chapter',
|
||||
'section': 'factory_section',
|
||||
}
|
||||
@@ -222,7 +220,7 @@ class TestNavigation(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
# And now hitting the courseware tab should redirect to 'factory_chapter'
|
||||
url = reverse(
|
||||
'courseware',
|
||||
kwargs={'course_id': text_type(self.course.id)}
|
||||
kwargs={'course_id': str(self.course.id)}
|
||||
)
|
||||
resp = self.client.get(url)
|
||||
self.assertRedirects(resp, section_url)
|
||||
@@ -235,7 +233,7 @@ class TestNavigation(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
self.login(email, password)
|
||||
self.enroll(self.test_course, True)
|
||||
|
||||
test_course_id = text_type(self.test_course.id)
|
||||
test_course_id = str(self.test_course.id)
|
||||
|
||||
url = reverse(
|
||||
'courseware',
|
||||
@@ -289,7 +287,7 @@ class TestNavigation(SharedModuleStoreTestCase, LoginEnrollmentTestCase):
|
||||
self.login(email, password)
|
||||
self.enroll(self.test_course_proctored, True)
|
||||
|
||||
test_course_id = text_type(self.test_course_proctored.id)
|
||||
test_course_id = str(self.test_course_proctored.id)
|
||||
|
||||
with patch.dict(settings.FEATURES, {'ENABLE_SPECIAL_EXAMS': False}):
|
||||
url = reverse(
|
||||
|
||||
@@ -3,8 +3,8 @@ Tests for permissions defined in courseware.rules
|
||||
"""
|
||||
|
||||
|
||||
from unittest.mock import patch
|
||||
import ddt
|
||||
from mock import patch
|
||||
|
||||
from common.djangoapps.course_modes.tests.factories import CourseModeFactory
|
||||
from common.djangoapps.student.models import CourseEnrollment
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
import datetime
|
||||
|
||||
from unittest.mock import patch
|
||||
import pytz
|
||||
from django.test.utils import override_settings
|
||||
from mock import patch
|
||||
|
||||
from lms.djangoapps.courseware.access import has_access
|
||||
from lms.djangoapps.courseware.tests.factories import BetaTesterFactory
|
||||
@@ -28,7 +28,7 @@ class SelfPacedDateOverrideTest(ModuleStoreTestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.reset_setting_cache_variables()
|
||||
super(SelfPacedDateOverrideTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
self.non_staff_user, __ = self.create_non_staff_user()
|
||||
self.now = datetime.datetime.now(pytz.UTC).replace(microsecond=0)
|
||||
@@ -36,7 +36,7 @@ class SelfPacedDateOverrideTest(ModuleStoreTestCase):
|
||||
|
||||
def tearDown(self):
|
||||
self.reset_setting_cache_variables()
|
||||
super(SelfPacedDateOverrideTest, self).tearDown() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().tearDown()
|
||||
|
||||
def reset_setting_cache_variables(self):
|
||||
"""
|
||||
@@ -122,7 +122,7 @@ class SelfPacedDateOverrideTest(ModuleStoreTestCase):
|
||||
|
||||
# Only the released xblocks should be visible when the course is instructor-paced.
|
||||
xblocks = get_accessible_discussion_xblocks(course, self.non_staff_user)
|
||||
assert all(((xblock.display_name == 'released') for xblock in xblocks))
|
||||
assert all((xblock.display_name == 'released') for xblock in xblocks)
|
||||
|
||||
@patch.dict('lms.djangoapps.courseware.access.settings.FEATURES', {'DISABLE_START_DATES': False})
|
||||
def test_self_paced_discussion_xblock_visibility(self):
|
||||
@@ -136,4 +136,4 @@ class SelfPacedDateOverrideTest(ModuleStoreTestCase):
|
||||
# The scheduled xblocks should be visible when the course is self-paced.
|
||||
xblocks = get_accessible_discussion_xblocks(course, self.non_staff_user)
|
||||
assert len(xblocks) == 2
|
||||
assert any(((xblock.display_name == 'scheduled') for xblock in xblocks))
|
||||
assert any((xblock.display_name == 'scheduled') for xblock in xblocks)
|
||||
|
||||
@@ -24,7 +24,7 @@ class TestUserStateService(ModuleStoreTestCase):
|
||||
"""
|
||||
Creating pre-requisites for the test cases.
|
||||
"""
|
||||
super(TestUserStateService, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.user = UserFactory.create()
|
||||
self.course = CourseFactory.create()
|
||||
chapter = ItemFactory.create(
|
||||
|
||||
@@ -3,10 +3,8 @@ Test for split test XModule
|
||||
"""
|
||||
|
||||
|
||||
import six
|
||||
from unittest.mock import MagicMock
|
||||
from django.urls import reverse
|
||||
from mock import MagicMock
|
||||
from six import text_type
|
||||
|
||||
from lms.djangoapps.courseware.model_data import FieldDataCache
|
||||
from lms.djangoapps.courseware.module_render import get_module_for_descriptor
|
||||
@@ -30,7 +28,7 @@ class SplitTestBase(SharedModuleStoreTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(SplitTestBase, cls).setUpClass()
|
||||
super().setUpClass()
|
||||
cls.partition = UserPartition(
|
||||
0,
|
||||
'first_partition',
|
||||
@@ -58,7 +56,7 @@ class SplitTestBase(SharedModuleStoreTestCase):
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
super(SplitTestBase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
self.student = UserFactory.create()
|
||||
CourseEnrollmentFactory.create(user=self.student, course_id=self.course.id)
|
||||
@@ -75,7 +73,7 @@ class SplitTestBase(SharedModuleStoreTestCase):
|
||||
return ItemFactory.create(
|
||||
parent_location=parent.location,
|
||||
category="video",
|
||||
display_name=u"Group {} Sees This Video".format(group),
|
||||
display_name=f"Group {group} Sees This Video",
|
||||
)
|
||||
|
||||
def _problem(self, parent, group):
|
||||
@@ -86,7 +84,7 @@ class SplitTestBase(SharedModuleStoreTestCase):
|
||||
return ItemFactory.create(
|
||||
parent_location=parent.location,
|
||||
category="problem",
|
||||
display_name=u"Group {} Sees This Problem".format(group),
|
||||
display_name=f"Group {group} Sees This Problem",
|
||||
data="<h1>No Problem Defined Yet!</h1>",
|
||||
)
|
||||
|
||||
@@ -98,8 +96,8 @@ class SplitTestBase(SharedModuleStoreTestCase):
|
||||
return ItemFactory.create(
|
||||
parent_location=parent.location,
|
||||
category="html",
|
||||
display_name=u"Group {} Sees This HTML".format(group),
|
||||
data=u"Some HTML for group {}".format(group),
|
||||
display_name=f"Group {group} Sees This HTML",
|
||||
data=f"Some HTML for group {group}",
|
||||
)
|
||||
|
||||
def test_split_test_0(self):
|
||||
@@ -114,30 +112,30 @@ class SplitTestBase(SharedModuleStoreTestCase):
|
||||
UserCourseTagFactory(
|
||||
user=self.student,
|
||||
course_id=self.course.id,
|
||||
key='xblock.partition_service.partition_{0}'.format(self.partition.id),
|
||||
key=f'xblock.partition_service.partition_{self.partition.id}',
|
||||
value=str(user_tag)
|
||||
)
|
||||
|
||||
resp = self.client.get(reverse(
|
||||
'courseware_section',
|
||||
kwargs={'course_id': text_type(self.course.id),
|
||||
kwargs={'course_id': str(self.course.id),
|
||||
'chapter': self.chapter.url_name,
|
||||
'section': self.sequential.url_name}
|
||||
))
|
||||
unicode_content = resp.content.decode(resp.charset)
|
||||
|
||||
# Assert we see the proper icon in the top display
|
||||
assert u'<button class="{} inactive nav-item tab"'.format(self.ICON_CLASSES[user_tag]) in unicode_content
|
||||
assert '<button class="{} inactive nav-item tab"'.format(self.ICON_CLASSES[user_tag]) in unicode_content
|
||||
|
||||
# And proper tooltips
|
||||
for tooltip in self.TOOLTIPS[user_tag]:
|
||||
assert tooltip in unicode_content
|
||||
|
||||
for key in self.included_usage_keys[user_tag]:
|
||||
assert six.text_type(key) in unicode_content
|
||||
assert str(key) in unicode_content
|
||||
|
||||
for key in self.excluded_usage_keys[user_tag]:
|
||||
assert six.text_type(key) not in unicode_content
|
||||
assert str(key) not in unicode_content
|
||||
|
||||
# Assert that we can see the data from the appropriate test condition
|
||||
for visible in self.VISIBLE_CONTENT[user_tag]:
|
||||
@@ -169,7 +167,7 @@ class TestSplitTestVert(SplitTestBase):
|
||||
|
||||
def setUp(self):
|
||||
# We define problem compenents that we need but don't explicitly call elsewhere.
|
||||
super(TestSplitTestVert, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
c0_url = self.course.id.make_usage_key("vertical", "split_test_cond0")
|
||||
c1_url = self.course.id.make_usage_key("vertical", "split_test_cond1")
|
||||
@@ -237,7 +235,7 @@ class TestVertSplitTestVert(SplitTestBase):
|
||||
|
||||
def setUp(self):
|
||||
# We define problem compenents that we need but don't explicitly call elsewhere.
|
||||
super(TestVertSplitTestVert, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
vert1 = ItemFactory.create(
|
||||
parent_location=self.sequential.location,
|
||||
@@ -291,7 +289,7 @@ class SplitTestPosition(SharedModuleStoreTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(SplitTestPosition, cls).setUpClass()
|
||||
super().setUpClass()
|
||||
cls.partition = UserPartition(
|
||||
0,
|
||||
'first_partition',
|
||||
@@ -313,7 +311,7 @@ class SplitTestPosition(SharedModuleStoreTestCase):
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
super(SplitTestPosition, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
self.student = UserFactory.create()
|
||||
CourseEnrollmentFactory.create(user=self.student, course_id=self.course.id)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Integration tests for submitting problem responses and getting grades.
|
||||
"""
|
||||
@@ -10,8 +9,8 @@ import json
|
||||
import os
|
||||
from textwrap import dedent
|
||||
|
||||
from unittest.mock import patch
|
||||
import ddt
|
||||
import six
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user
|
||||
from django.db import connections
|
||||
@@ -19,8 +18,6 @@ from django.test import TestCase
|
||||
from django.test.client import RequestFactory
|
||||
from django.urls import reverse
|
||||
from django.utils.timezone import now
|
||||
from mock import patch
|
||||
from six import text_type
|
||||
from submissions import api as submissions_api
|
||||
|
||||
from capa.tests.response_xml_factory import (
|
||||
@@ -71,8 +68,8 @@ class ProblemSubmissionTestMixin(TestCase):
|
||||
return reverse(
|
||||
'xblock_handler',
|
||||
kwargs={
|
||||
'course_id': text_type(self.course.id),
|
||||
'usage_id': quote_slashes(text_type(problem_location)),
|
||||
'course_id': str(self.course.id),
|
||||
'usage_id': quote_slashes(str(problem_location)),
|
||||
'handler': 'xmodule_handler',
|
||||
'suffix': dispatch,
|
||||
}
|
||||
@@ -89,7 +86,7 @@ class ProblemSubmissionTestMixin(TestCase):
|
||||
problem_location = self.problem_location(problem_url_name)
|
||||
modx_url = self.modx_url(problem_location, 'problem_check')
|
||||
|
||||
answer_key_prefix = 'input_{}_'.format(problem_location.html_id())
|
||||
answer_key_prefix = f'input_{problem_location.html_id()}_'
|
||||
|
||||
# format the response dictionary to be sent in the post request by adding the above prefix to each key
|
||||
response_dict = {(answer_key_prefix + k): v for k, v in responses.items()}
|
||||
@@ -149,7 +146,7 @@ class TestSubmittingProblems(ModuleStoreTestCase, LoginEnrollmentTestCase, Probl
|
||||
ENABLED_SIGNALS = ['course_published']
|
||||
|
||||
def setUp(self):
|
||||
super(TestSubmittingProblems, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
# create a test student
|
||||
self.course = CourseFactory.create(display_name=self.COURSE_NAME, number=self.COURSE_SLUG)
|
||||
@@ -177,7 +174,7 @@ class TestSubmittingProblems(ModuleStoreTestCase, LoginEnrollmentTestCase, Probl
|
||||
question_text='The correct answer is Correct',
|
||||
num_inputs=num_inputs,
|
||||
weight=num_inputs,
|
||||
options=['Correct', 'Incorrect', u'ⓤⓝⓘⓒⓞⓓⓔ'],
|
||||
options=['Correct', 'Incorrect', 'ⓤⓝⓘⓒⓞⓓⓔ'],
|
||||
correct_option='Correct'
|
||||
)
|
||||
|
||||
@@ -278,15 +275,14 @@ class TestSubmittingProblems(ModuleStoreTestCase, LoginEnrollmentTestCase, Probl
|
||||
Returns list of scores: [<points on hw_1>, <points on hw_2>, ..., <points on hw_n>]
|
||||
"""
|
||||
return [
|
||||
s.graded_total.earned for s in six.itervalues(
|
||||
self.get_course_grade().graded_subsections_by_format['Homework'])
|
||||
s.graded_total.earned for s in self.get_course_grade().graded_subsections_by_format['Homework'].values()
|
||||
]
|
||||
|
||||
def hw_grade(self, hw_url_name):
|
||||
"""
|
||||
Returns SubsectionGrade for given url.
|
||||
"""
|
||||
for chapter in six.itervalues(self.get_course_grade().chapter_grades):
|
||||
for chapter in self.get_course_grade().chapter_grades.values():
|
||||
for section in chapter['sections']:
|
||||
if section.url_name == hw_url_name:
|
||||
return section
|
||||
@@ -307,7 +303,7 @@ class TestCourseGrades(TestSubmittingProblems):
|
||||
Tests grades are updated correctly when manipulating problems.
|
||||
"""
|
||||
def setUp(self):
|
||||
super(TestCourseGrades, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.homework = self.add_graded_section_to_course('homework')
|
||||
self.problem = self.add_dropdown_to_section(self.homework.location, 'p1', 1)
|
||||
|
||||
@@ -409,7 +405,7 @@ class TestCourseGrader(TestSubmittingProblems):
|
||||
]
|
||||
}
|
||||
self.add_grading_policy(grading_policy)
|
||||
task_compute_all_grades_for_course.apply_async(kwargs={'course_key': six.text_type(self.course.id)})
|
||||
task_compute_all_grades_for_course.apply_async(kwargs={'course_key': str(self.course.id)})
|
||||
|
||||
def dropping_setup(self):
|
||||
"""
|
||||
@@ -485,7 +481,7 @@ class TestCourseGrader(TestSubmittingProblems):
|
||||
|
||||
def test_show_answer_doesnt_write_to_csm(self):
|
||||
self.basic_setup()
|
||||
self.submit_question_answer('p1', {'2_1': u'Correct'})
|
||||
self.submit_question_answer('p1', {'2_1': 'Correct'})
|
||||
|
||||
# Now fetch the state entry for that problem.
|
||||
student_module = StudentModule.objects.filter(
|
||||
@@ -581,8 +577,8 @@ class TestCourseGrader(TestSubmittingProblems):
|
||||
|
||||
student_item = {
|
||||
'student_id': anonymous_id_for_user(self.student_user, self.course.id),
|
||||
'course_id': six.text_type(self.course.id),
|
||||
'item_id': six.text_type(self.problem_location('p3')),
|
||||
'course_id': str(self.course.id),
|
||||
'item_id': str(self.problem_location('p3')),
|
||||
'item_type': 'problem'
|
||||
}
|
||||
submission = submissions_api.create_submission(student_item, 'any answer')
|
||||
@@ -600,7 +596,7 @@ class TestCourseGrader(TestSubmittingProblems):
|
||||
|
||||
with patch('submissions.api.get_scores') as mock_get_scores:
|
||||
mock_get_scores.return_value = {
|
||||
text_type(self.problem_location('p3')): {
|
||||
str(self.problem_location('p3')): {
|
||||
'points_earned': 1,
|
||||
'points_possible': 1,
|
||||
'created_at': now(),
|
||||
@@ -610,7 +606,7 @@ class TestCourseGrader(TestSubmittingProblems):
|
||||
|
||||
# Verify that the submissions API was sent an anonymized student ID
|
||||
mock_get_scores.assert_called_with(
|
||||
text_type(self.course.id),
|
||||
str(self.course.id),
|
||||
anonymous_id_for_user(self.student_user, self.course.id)
|
||||
)
|
||||
|
||||
@@ -759,7 +755,7 @@ class ProblemWithUploadedFilesTest(TestSubmittingProblems):
|
||||
databases = {alias for alias in connections} # lint-amnesty, pylint: disable=unnecessary-comprehension
|
||||
|
||||
def setUp(self):
|
||||
super(ProblemWithUploadedFilesTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.section = self.add_graded_section_to_course('section')
|
||||
|
||||
def problem_setup(self, name, files):
|
||||
@@ -803,8 +799,8 @@ class ProblemWithUploadedFilesTest(TestSubmittingProblems):
|
||||
assert name == 'post'
|
||||
assert len(args) == 1
|
||||
assert args[0].endswith('/submit/')
|
||||
six.assertCountEqual(self, list(kwargs.keys()), ["files", "data", "timeout"])
|
||||
six.assertCountEqual(self, list(kwargs['files'].keys()), filenames.split())
|
||||
self.assertCountEqual(list(kwargs.keys()), ["files", "data", "timeout"])
|
||||
self.assertCountEqual(list(kwargs['files'].keys()), filenames.split())
|
||||
|
||||
|
||||
class TestPythonGradedResponse(TestSubmittingProblems):
|
||||
@@ -903,7 +899,7 @@ class TestPythonGradedResponse(TestSubmittingProblems):
|
||||
COMPUTED_ANSWER_INCORRECT = "because we never let them in"
|
||||
|
||||
def setUp(self):
|
||||
super(TestPythonGradedResponse, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.section = self.add_graded_section_to_course('section')
|
||||
self.correct_responses = {}
|
||||
self.incorrect_responses = {}
|
||||
@@ -1067,7 +1063,7 @@ class TestConditionalContent(TestSubmittingProblems):
|
||||
One section is pre-populated with a problem (with 2 inputs), visible to all students.
|
||||
The second section is empty. Test cases should add conditional content to it.
|
||||
"""
|
||||
super(TestConditionalContent, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
self.user_partition_group_0 = 0
|
||||
self.user_partition_group_1 = 1
|
||||
@@ -1143,7 +1139,7 @@ class TestConditionalContent(TestSubmittingProblems):
|
||||
UserCourseTagFactory(
|
||||
user=self.student_user,
|
||||
course_id=self.course.id,
|
||||
key='xblock.partition_service.partition_{0}'.format(self.partition.id),
|
||||
key=f'xblock.partition_service.partition_{self.partition.id}',
|
||||
value=str(user_partition_group)
|
||||
)
|
||||
|
||||
|
||||
@@ -2,16 +2,13 @@
|
||||
Test cases for tabs.
|
||||
"""
|
||||
|
||||
from unittest.mock import MagicMock, Mock, patch
|
||||
import pytest
|
||||
import six
|
||||
from crum import set_current_request
|
||||
from django.contrib.auth.models import AnonymousUser
|
||||
from django.http import Http404
|
||||
from django.urls import reverse
|
||||
from milestones.tests.utils import MilestonesTestCaseMixin
|
||||
from mock import MagicMock, Mock, patch
|
||||
from six import text_type
|
||||
from six.moves import range
|
||||
|
||||
from edx_toggles.toggles.testutils import override_waffle_flag
|
||||
from lms.djangoapps.courseware.courses import get_course_by_id
|
||||
@@ -52,15 +49,15 @@ class TabTestCase(SharedModuleStoreTestCase):
|
||||
"""Base class for Tab-related test cases."""
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TabTestCase, cls).setUpClass()
|
||||
super().setUpClass()
|
||||
|
||||
cls.course = CourseFactory.create(org='edX', course='toy', run='2012_Fall')
|
||||
cls.fake_dict_tab = {'fake_key': 'fake_value'}
|
||||
cls.books = None
|
||||
|
||||
def setUp(self):
|
||||
super(TabTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
self.reverse = lambda name, args: "name/{0}/args/{1}".format(name, ",".join(str(a) for a in args))
|
||||
super().setUp()
|
||||
self.reverse = lambda name, args: "name/{}/args/{}".format(name, ",".join(str(a) for a in args))
|
||||
|
||||
def create_mock_user(self, is_staff=True, is_enrolled=True):
|
||||
"""
|
||||
@@ -80,7 +77,7 @@ class TabTestCase(SharedModuleStoreTestCase):
|
||||
"""Initializes the textbooks in the course and adds the given number of books to each textbook"""
|
||||
self.books = [MagicMock() for _ in range(num_books)]
|
||||
for book_index, book in enumerate(self.books):
|
||||
book.title = 'Book{0}'.format(book_index)
|
||||
book.title = f'Book{book_index}'
|
||||
self.course.textbooks = self.books
|
||||
self.course.pdf_textbooks = self.books
|
||||
self.course.html_textbooks = self.books
|
||||
@@ -200,7 +197,7 @@ class TextbooksTestCase(TabTestCase):
|
||||
"""Test cases for Textbook Tab."""
|
||||
|
||||
def setUp(self):
|
||||
super(TextbooksTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
self.set_up_books(2)
|
||||
|
||||
@@ -228,10 +225,10 @@ class TextbooksTestCase(TabTestCase):
|
||||
book_type, book_index = tab.tab_id.split("/", 1)
|
||||
expected_link = self.reverse(
|
||||
type_to_reverse_name[book_type],
|
||||
args=[text_type(self.course.id), book_index]
|
||||
args=[str(self.course.id), book_index]
|
||||
)
|
||||
assert tab.link_func(self.course, self.reverse) == expected_link
|
||||
assert tab.name.startswith('Book{0}'.format(book_index))
|
||||
assert tab.name.startswith(f'Book{book_index}')
|
||||
num_textbooks_found = num_textbooks_found + 1
|
||||
assert num_textbooks_found == self.num_textbooks
|
||||
|
||||
@@ -243,7 +240,7 @@ class StaticTabDateTestCase(LoginEnrollmentTestCase, SharedModuleStoreTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(StaticTabDateTestCase, cls).setUpClass()
|
||||
super().setUpClass()
|
||||
cls.course = CourseFactory.create()
|
||||
cls.page = ItemFactory.create(
|
||||
category="static_tab", parent_location=cls.course.location,
|
||||
@@ -254,12 +251,12 @@ class StaticTabDateTestCase(LoginEnrollmentTestCase, SharedModuleStoreTestCase):
|
||||
|
||||
def test_logged_in(self):
|
||||
self.setup_user()
|
||||
url = reverse('static_tab', args=[text_type(self.course.id), 'new_tab'])
|
||||
url = reverse('static_tab', args=[str(self.course.id), 'new_tab'])
|
||||
resp = self.client.get(url)
|
||||
self.assertContains(resp, "OOGIE BLOOGIE")
|
||||
|
||||
def test_anonymous_user(self):
|
||||
url = reverse('static_tab', args=[text_type(self.course.id), 'new_tab'])
|
||||
url = reverse('static_tab', args=[str(self.course.id), 'new_tab'])
|
||||
resp = self.client.get(url)
|
||||
self.assertContains(resp, "OOGIE BLOOGIE")
|
||||
|
||||
@@ -279,7 +276,7 @@ class StaticTabDateTestCase(LoginEnrollmentTestCase, SharedModuleStoreTestCase):
|
||||
|
||||
# Test render works okay
|
||||
tab_content = get_static_tab_fragment(request, course, tab).content
|
||||
assert text_type(self.course.id) in tab_content
|
||||
assert str(self.course.id) in tab_content
|
||||
assert 'static_tab' in tab_content
|
||||
|
||||
# Test when render raises an exception
|
||||
@@ -302,7 +299,7 @@ class StaticTabDateTestCaseXML(LoginEnrollmentTestCase, ModuleStoreTestCase):
|
||||
"""
|
||||
Set up the tests
|
||||
"""
|
||||
super(StaticTabDateTestCaseXML, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
# The following XML test course (which lives at common/test/data/2014)
|
||||
# is closed; we're testing that tabs still appear when
|
||||
@@ -327,13 +324,13 @@ class StaticTabDateTestCaseXML(LoginEnrollmentTestCase, ModuleStoreTestCase):
|
||||
@patch.dict('django.conf.settings.FEATURES', {'DISABLE_START_DATES': False})
|
||||
def test_logged_in_xml(self):
|
||||
self.setup_user()
|
||||
url = reverse('static_tab', args=[text_type(self.xml_course_key), self.xml_url])
|
||||
url = reverse('static_tab', args=[str(self.xml_course_key), self.xml_url])
|
||||
resp = self.client.get(url)
|
||||
self.assertContains(resp, self.xml_data)
|
||||
|
||||
@patch.dict('django.conf.settings.FEATURES', {'DISABLE_START_DATES': False})
|
||||
def test_anonymous_user_xml(self):
|
||||
url = reverse('static_tab', args=[text_type(self.xml_course_key), self.xml_url])
|
||||
url = reverse('static_tab', args=[str(self.xml_course_key), self.xml_url])
|
||||
resp = self.client.get(url)
|
||||
self.assertContains(resp, self.xml_data)
|
||||
|
||||
@@ -350,7 +347,7 @@ class EntranceExamsTabsTestCase(LoginEnrollmentTestCase, ModuleStoreTestCase, Mi
|
||||
"""
|
||||
Test case scaffolding
|
||||
"""
|
||||
super(EntranceExamsTabsTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
self.course = CourseFactory.create()
|
||||
self.instructor_tab = ItemFactory.create(
|
||||
@@ -384,21 +381,21 @@ class EntranceExamsTabsTestCase(LoginEnrollmentTestCase, ModuleStoreTestCase, Mi
|
||||
)
|
||||
milestone = {
|
||||
'name': 'Test Milestone',
|
||||
'namespace': '{}.entrance_exams'.format(six.text_type(self.course.id)),
|
||||
'namespace': '{}.entrance_exams'.format(str(self.course.id)),
|
||||
'description': 'Testing Courseware Tabs'
|
||||
}
|
||||
self.user.is_staff = False
|
||||
self.course.entrance_exam_enabled = True
|
||||
self.course.entrance_exam_id = six.text_type(entrance_exam.location)
|
||||
self.course.entrance_exam_id = str(entrance_exam.location)
|
||||
milestone = add_milestone(milestone)
|
||||
add_course_milestone(
|
||||
six.text_type(self.course.id),
|
||||
str(self.course.id),
|
||||
self.relationship_types['REQUIRES'],
|
||||
milestone
|
||||
)
|
||||
add_course_content_milestone(
|
||||
six.text_type(self.course.id),
|
||||
six.text_type(entrance_exam.location),
|
||||
str(self.course.id),
|
||||
str(entrance_exam.location),
|
||||
self.relationship_types['FULFILLS'],
|
||||
milestone
|
||||
)
|
||||
@@ -418,7 +415,7 @@ class EntranceExamsTabsTestCase(LoginEnrollmentTestCase, ModuleStoreTestCase, Mi
|
||||
self.client.logout()
|
||||
self.client.login(username=instructor.username, password='test')
|
||||
|
||||
url = reverse('mark_student_can_skip_entrance_exam', kwargs={'course_id': six.text_type(self.course.id)})
|
||||
url = reverse('mark_student_can_skip_entrance_exam', kwargs={'course_id': str(self.course.id)})
|
||||
response = self.client.post(url, {
|
||||
'unique_student_identifier': student.email,
|
||||
})
|
||||
@@ -451,11 +448,11 @@ class TextBookCourseViewsTestCase(LoginEnrollmentTestCase, SharedModuleStoreTest
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TextBookCourseViewsTestCase, cls).setUpClass()
|
||||
super().setUpClass()
|
||||
cls.course = CourseFactory.create()
|
||||
|
||||
def setUp(self):
|
||||
super(TextBookCourseViewsTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
self.set_up_books(2)
|
||||
self.setup_user()
|
||||
@@ -469,7 +466,7 @@ class TextBookCourseViewsTestCase(LoginEnrollmentTestCase, SharedModuleStoreTest
|
||||
"""Initializes the textbooks in the course and adds the given number of books to each textbook"""
|
||||
self.books = [MagicMock() for _ in range(num_books)]
|
||||
for book_index, book in enumerate(self.books):
|
||||
book.title = 'Book{0}'.format(book_index)
|
||||
book.title = f'Book{book_index}'
|
||||
self.course.textbooks = self.books
|
||||
self.course.pdf_textbooks = self.books
|
||||
self.course.html_textbooks = self.books
|
||||
@@ -488,7 +485,7 @@ class TextBookCourseViewsTestCase(LoginEnrollmentTestCase, SharedModuleStoreTest
|
||||
book_type, book_index = tab.tab_id.split("/", 1)
|
||||
expected_link = reverse(
|
||||
type_to_reverse_name[book_type],
|
||||
args=[text_type(self.course.id), book_index]
|
||||
args=[str(self.course.id), book_index]
|
||||
)
|
||||
tab_link = tab.link_func(self.course, reverse)
|
||||
assert tab_link == expected_link
|
||||
@@ -505,7 +502,7 @@ class TabListTestCase(TabTestCase):
|
||||
"""Base class for Test cases involving tab lists."""
|
||||
|
||||
def setUp(self):
|
||||
super(TabListTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
# invalid tabs
|
||||
self.invalid_tabs = [
|
||||
@@ -596,7 +593,7 @@ class CourseTabListTestCase(TabListTestCase):
|
||||
"""Testing the generator method for iterating through displayable tabs"""
|
||||
|
||||
def setUp(self):
|
||||
super(CourseTabListTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.addCleanup(set_current_request, None)
|
||||
|
||||
def has_tab(self, tab_list, tab_type):
|
||||
@@ -723,7 +720,7 @@ class ProgressTestCase(TabTestCase):
|
||||
return self.check_tab(
|
||||
tab_class=ProgressTab,
|
||||
dict_tab={'type': ProgressTab.type, 'name': 'same'},
|
||||
expected_link=self.reverse('progress', args=[text_type(self.course.id)]),
|
||||
expected_link=self.reverse('progress', args=[str(self.course.id)]),
|
||||
expected_tab_id=ProgressTab.type,
|
||||
invalid_dict_tab=None,
|
||||
)
|
||||
@@ -754,7 +751,7 @@ class StaticTabTestCase(TabTestCase):
|
||||
tab = self.check_tab(
|
||||
tab_class=xmodule_tabs.StaticTab,
|
||||
dict_tab={'type': xmodule_tabs.StaticTab.type, 'name': 'same', 'url_slug': url_slug},
|
||||
expected_link=self.reverse('static_tab', args=[text_type(self.course.id), url_slug]),
|
||||
expected_link=self.reverse('static_tab', args=[str(self.course.id), url_slug]),
|
||||
expected_tab_id='static_tab_schmug',
|
||||
invalid_dict_tab=self.fake_dict_tab,
|
||||
)
|
||||
@@ -798,7 +795,7 @@ class DiscussionLinkTestCase(TabTestCase):
|
||||
"""Test cases for discussion link tab."""
|
||||
|
||||
def setUp(self):
|
||||
super(DiscussionLinkTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
self.tabs_with_discussion = [
|
||||
xmodule_tabs.CourseTab.load('discussion'),
|
||||
@@ -811,7 +808,7 @@ class DiscussionLinkTestCase(TabTestCase):
|
||||
"""Custom reverse function"""
|
||||
def reverse_discussion_link(viewname, args):
|
||||
"""reverse lookup for discussion link"""
|
||||
if viewname == "forum_form_discussion" and args == [six.text_type(course.id)]:
|
||||
if viewname == "forum_form_discussion" and args == [str(course.id)]:
|
||||
return "default_discussion_link"
|
||||
return reverse_discussion_link
|
||||
|
||||
|
||||
@@ -33,6 +33,6 @@ class TestDjangoUserStateClient(UserStateClientTestBase, ModuleStoreTestCase):
|
||||
return 'problem'
|
||||
|
||||
def setUp(self):
|
||||
super(TestDjangoUserStateClient, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.client = DjangoXBlockUserStateClient()
|
||||
self.users = defaultdict(UserFactory.create)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Video xmodule tests in mongo."""
|
||||
|
||||
|
||||
@@ -7,14 +6,13 @@ import os
|
||||
import tempfile
|
||||
import textwrap
|
||||
from datetime import timedelta
|
||||
from unittest.mock import MagicMock, Mock, patch
|
||||
import pytest
|
||||
import ddt
|
||||
import freezegun
|
||||
import six
|
||||
from django.core.files.base import ContentFile
|
||||
from django.utils.timezone import now
|
||||
from edxval import api
|
||||
from mock import MagicMock, Mock, patch
|
||||
from webob import Request, Response
|
||||
|
||||
from common.test.utils import normalize_repr
|
||||
@@ -38,7 +36,7 @@ from .test_video_xml import SOURCE_XML
|
||||
|
||||
TRANSCRIPT = {"start": [10], "end": [100], "text": ["Hi, welcome to Edx."]}
|
||||
BUMPER_TRANSCRIPT = {"start": [1], "end": [10], "text": ["A bumper"]}
|
||||
SRT_content = textwrap.dedent(u"""
|
||||
SRT_content = textwrap.dedent("""
|
||||
0
|
||||
00:00:00,12 --> 00:00:00,100
|
||||
Привіт, edX вітає вас.
|
||||
@@ -145,10 +143,10 @@ class BaseTestVideoXBlock(BaseTestXmodule):
|
||||
# a lot of tests code, parse and set the values as fields.
|
||||
fields_data = VideoBlock.parse_video_xml(data)
|
||||
kwargs.update(fields_data)
|
||||
super(BaseTestVideoXBlock, self).initialize_module(**kwargs) # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().initialize_module(**kwargs)
|
||||
|
||||
def setUp(self):
|
||||
super(BaseTestVideoXBlock, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.initialize_block(data=self.DATA, metadata=self.METADATA)
|
||||
|
||||
|
||||
@@ -181,7 +179,7 @@ class TestVideo(BaseTestVideoXBlock):
|
||||
)
|
||||
|
||||
assert not json.loads(response)['success']
|
||||
expected_error = u"Invalid speed value nan, must be a float."
|
||||
expected_error = "Invalid speed value nan, must be a float."
|
||||
assert json.loads(response)['error'] == expected_error
|
||||
|
||||
# verify that the speed and global speed are still 1.0
|
||||
@@ -191,12 +189,12 @@ class TestVideo(BaseTestVideoXBlock):
|
||||
def test_handle_ajax(self):
|
||||
|
||||
data = [
|
||||
{u'speed': 2.0},
|
||||
{u'saved_video_position': "00:00:10"},
|
||||
{u'transcript_language': 'uk'},
|
||||
{u'bumper_do_not_show_again': True},
|
||||
{u'bumper_last_view_date': True},
|
||||
{u'demoo<EFBFBD>': 'sample'}
|
||||
{'speed': 2.0},
|
||||
{'saved_video_position': "00:00:10"},
|
||||
{'transcript_language': 'uk'},
|
||||
{'bumper_do_not_show_again': True},
|
||||
{'bumper_last_view_date': True},
|
||||
{'demoo<EFBFBD>': 'sample'}
|
||||
]
|
||||
for sample in data:
|
||||
response = self.clients[self.users[0].username].post(
|
||||
@@ -227,7 +225,7 @@ class TestVideo(BaseTestVideoXBlock):
|
||||
self.item_descriptor.handle_ajax('save_user_state', {'bumper_last_view_date': True})
|
||||
assert self.item_descriptor.bumper_last_view_date == now()
|
||||
|
||||
response = self.item_descriptor.handle_ajax('save_user_state', {u'demoo<EFBFBD>': "sample"})
|
||||
response = self.item_descriptor.handle_ajax('save_user_state', {'demoo<EFBFBD>': "sample"})
|
||||
assert json.loads(response)['success'] is True
|
||||
|
||||
def get_handler_url(self, handler, suffix):
|
||||
@@ -240,7 +238,7 @@ class TestVideo(BaseTestVideoXBlock):
|
||||
|
||||
def tearDown(self):
|
||||
_clear_assets(self.item_descriptor.location)
|
||||
super(TestVideo, self).tearDown() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().tearDown()
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@@ -251,7 +249,7 @@ class TestTranscriptAvailableTranslationsDispatch(TestVideo): # lint-amnesty, p
|
||||
Tests for `available_translations` dispatch.
|
||||
"""
|
||||
srt_file = _create_srt_file()
|
||||
DATA = u"""
|
||||
DATA = """
|
||||
<video show_captions="true"
|
||||
display_name="A Name"
|
||||
>
|
||||
@@ -266,7 +264,7 @@ class TestTranscriptAvailableTranslationsDispatch(TestVideo): # lint-amnesty, p
|
||||
}
|
||||
|
||||
def setUp(self):
|
||||
super(TestTranscriptAvailableTranslationsDispatch, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.item_descriptor.render(STUDENT_VIEW)
|
||||
self.item = self.item_descriptor
|
||||
self.subs = {"start": [10], "end": [100], "text": ["Hi, welcome to Edx."]}
|
||||
@@ -361,7 +359,7 @@ class TestTranscriptAvailableTranslationsDispatch(TestVideo): # lint-amnesty, p
|
||||
Tests available translations with video component's and val's transcript languages
|
||||
while the feature is enabled.
|
||||
"""
|
||||
for lang_code, in_content_store in six.iteritems(dict(transcripts)):
|
||||
for lang_code, in_content_store in dict(transcripts).items():
|
||||
if in_content_store:
|
||||
file_name, __ = os.path.split(self.srt_file.name)
|
||||
_upload_file(self.srt_file, self.item_descriptor.location, file_name)
|
||||
@@ -388,7 +386,7 @@ class TestTranscriptAvailableTranslationsDispatch(TestVideo): # lint-amnesty, p
|
||||
# Make request to available translations dispatch.
|
||||
request = Request.blank('/available_translations')
|
||||
response = self.item.transcript(request=request, dispatch='available_translations')
|
||||
six.assertCountEqual(self, json.loads(response.body.decode('utf-8')), result)
|
||||
self.assertCountEqual(json.loads(response.body.decode('utf-8')), result)
|
||||
|
||||
@patch('xmodule.video_module.transcripts_utils.edxval_api.get_available_transcript_languages')
|
||||
def test_val_available_translations_feature_disabled(self, mock_get_available_transcript_languages):
|
||||
@@ -409,7 +407,7 @@ class TestTranscriptAvailableTranslationsBumperDispatch(TestVideo): # lint-amne
|
||||
Tests for `available_translations_bumper` dispatch.
|
||||
"""
|
||||
srt_file = _create_srt_file()
|
||||
DATA = u"""
|
||||
DATA = """
|
||||
<video show_captions="true"
|
||||
display_name="A Name"
|
||||
>
|
||||
@@ -424,7 +422,7 @@ class TestTranscriptAvailableTranslationsBumperDispatch(TestVideo): # lint-amne
|
||||
}
|
||||
|
||||
def setUp(self):
|
||||
super(TestTranscriptAvailableTranslationsBumperDispatch, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.item_descriptor.render(STUDENT_VIEW)
|
||||
self.item = self.item_descriptor
|
||||
self.dispatch = "available_translations/?is_bumper=1"
|
||||
@@ -490,7 +488,7 @@ class TestTranscriptDownloadDispatch(TestVideo): # lint-amnesty, pylint: disabl
|
||||
}
|
||||
|
||||
def setUp(self):
|
||||
super(TestTranscriptDownloadDispatch, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.item_descriptor.render(STUDENT_VIEW)
|
||||
self.item = self.item_descriptor
|
||||
|
||||
@@ -531,7 +529,7 @@ class TestTranscriptDownloadDispatch(TestVideo): # lint-amnesty, pylint: disabl
|
||||
|
||||
@patch(
|
||||
'xmodule.video_module.transcripts_utils.get_transcript_for_video',
|
||||
return_value=(Transcript.SRT, u"塞", 'Subs!')
|
||||
return_value=(Transcript.SRT, "塞", 'Subs!')
|
||||
)
|
||||
def test_download_non_en_non_ascii_filename(self, __):
|
||||
request = Request.blank('/download')
|
||||
@@ -560,17 +558,17 @@ class TestTranscriptDownloadDispatch(TestVideo): # lint-amnesty, pylint: disabl
|
||||
response = self.item.transcript(request=request, dispatch='download')
|
||||
|
||||
# Expected response
|
||||
expected_content = u'0\n00:00:00,010 --> 00:00:00,100\nHi, welcome to Edx.\n\n'
|
||||
expected_content = '0\n00:00:00,010 --> 00:00:00,100\nHi, welcome to Edx.\n\n'
|
||||
expected_headers = {
|
||||
'Content-Disposition': 'attachment; filename="edx.srt"',
|
||||
'Content-Language': u'en',
|
||||
'Content-Language': 'en',
|
||||
'Content-Type': 'application/x-subrip; charset=utf-8'
|
||||
}
|
||||
|
||||
# Assert the actual response
|
||||
assert response.status_code == 200
|
||||
assert response.text == expected_content
|
||||
for attribute, value in six.iteritems(expected_headers):
|
||||
for attribute, value in expected_headers.items():
|
||||
assert response.headers[attribute] == value
|
||||
|
||||
|
||||
@@ -583,7 +581,7 @@ class TestTranscriptTranslationGetDispatch(TestVideo): # lint-amnesty, pylint:
|
||||
"""
|
||||
|
||||
srt_file = _create_srt_file()
|
||||
DATA = u"""
|
||||
DATA = """
|
||||
<video
|
||||
show_captions="true"
|
||||
display_name="A Name"
|
||||
@@ -600,7 +598,7 @@ class TestTranscriptTranslationGetDispatch(TestVideo): # lint-amnesty, pylint:
|
||||
}
|
||||
|
||||
def setUp(self):
|
||||
super(TestTranscriptTranslationGetDispatch, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.item_descriptor.render(STUDENT_VIEW)
|
||||
self.item = self.item_descriptor
|
||||
self.item.video_bumper = {"transcripts": {"en": ""}}
|
||||
@@ -642,10 +640,10 @@ class TestTranscriptTranslationGetDispatch(TestVideo): # lint-amnesty, pylint:
|
||||
|
||||
def test_translation_non_en_youtube_success(self):
|
||||
subs = {
|
||||
u'end': [100],
|
||||
u'start': [12],
|
||||
u'text': [
|
||||
u'\u041f\u0440\u0438\u0432\u0456\u0442, edX \u0432\u0456\u0442\u0430\u0454 \u0432\u0430\u0441.'
|
||||
'end': [100],
|
||||
'start': [12],
|
||||
'text': [
|
||||
'\u041f\u0440\u0438\u0432\u0456\u0442, edX \u0432\u0456\u0442\u0430\u0454 \u0432\u0430\u0441.'
|
||||
]
|
||||
}
|
||||
self.srt_file.seek(0)
|
||||
@@ -656,7 +654,7 @@ class TestTranscriptTranslationGetDispatch(TestVideo): # lint-amnesty, pylint:
|
||||
self.item.youtube_id_1_0 = subs_id
|
||||
self.item.youtube_id_0_75 = '0_75'
|
||||
self.store.update_item(self.item, self.user.id)
|
||||
request = Request.blank('/translation/uk?videoId={}'.format(subs_id))
|
||||
request = Request.blank(f'/translation/uk?videoId={subs_id}')
|
||||
response = self.item.transcript(request=request, dispatch='translation/uk')
|
||||
self.assertDictEqual(json.loads(response.body.decode('utf-8')), subs)
|
||||
|
||||
@@ -664,10 +662,10 @@ class TestTranscriptTranslationGetDispatch(TestVideo): # lint-amnesty, pylint:
|
||||
request = Request.blank('/translation/uk?videoId={}'.format('0_75'))
|
||||
response = self.item.transcript(request=request, dispatch='translation/uk')
|
||||
calculated_0_75 = {
|
||||
u'end': [75],
|
||||
u'start': [9],
|
||||
u'text': [
|
||||
u'\u041f\u0440\u0438\u0432\u0456\u0442, edX \u0432\u0456\u0442\u0430\u0454 \u0432\u0430\u0441.'
|
||||
'end': [75],
|
||||
'start': [9],
|
||||
'text': [
|
||||
'\u041f\u0440\u0438\u0432\u0456\u0442, edX \u0432\u0456\u0442\u0430\u0454 \u0432\u0430\u0441.'
|
||||
]
|
||||
}
|
||||
|
||||
@@ -678,10 +676,10 @@ class TestTranscriptTranslationGetDispatch(TestVideo): # lint-amnesty, pylint:
|
||||
request = Request.blank('/translation/uk?videoId={}'.format('1_5'))
|
||||
response = self.item.transcript(request=request, dispatch='translation/uk')
|
||||
calculated_1_5 = {
|
||||
u'end': [150],
|
||||
u'start': [18],
|
||||
u'text': [
|
||||
u'\u041f\u0440\u0438\u0432\u0456\u0442, edX \u0432\u0456\u0442\u0430\u0454 \u0432\u0430\u0441.'
|
||||
'end': [150],
|
||||
'start': [18],
|
||||
'text': [
|
||||
'\u041f\u0440\u0438\u0432\u0456\u0442, edX \u0432\u0456\u0442\u0430\u0454 \u0432\u0430\u0441.'
|
||||
]
|
||||
}
|
||||
self.assertDictEqual(json.loads(response.body.decode('utf-8')), calculated_1_5)
|
||||
@@ -703,10 +701,10 @@ class TestTranscriptTranslationGetDispatch(TestVideo): # lint-amnesty, pylint:
|
||||
|
||||
def test_translaton_non_en_html5_success(self):
|
||||
subs = {
|
||||
u'end': [100],
|
||||
u'start': [12],
|
||||
u'text': [
|
||||
u'\u041f\u0440\u0438\u0432\u0456\u0442, edX \u0432\u0456\u0442\u0430\u0454 \u0432\u0430\u0441.'
|
||||
'end': [100],
|
||||
'start': [12],
|
||||
'text': [
|
||||
'\u041f\u0440\u0438\u0432\u0456\u0442, edX \u0432\u0456\u0442\u0430\u0454 \u0432\u0430\u0441.'
|
||||
]
|
||||
}
|
||||
self.srt_file.seek(0)
|
||||
@@ -778,7 +776,7 @@ class TestTranscriptTranslationGetDispatch(TestVideo): # lint-amnesty, pylint:
|
||||
response = self.item.transcript(request=request, dispatch=dispatch)
|
||||
assert response.status == status_code
|
||||
if sub:
|
||||
assert ('Location', '/static/dummy/static/subs_{}.srt.sjson'.format(sub)) in response.headerlist
|
||||
assert ('Location', f'/static/dummy/static/subs_{sub}.srt.sjson') in response.headerlist
|
||||
|
||||
@patch('xmodule.video_module.VideoBlock.course_id', return_value='not_a_course_locator')
|
||||
def test_translation_static_non_course(self, __):
|
||||
@@ -831,7 +829,7 @@ class TestTranscriptTranslationGetDispatch(TestVideo): # lint-amnesty, pylint:
|
||||
# Assert the actual response
|
||||
assert response.status_code == 200
|
||||
assert response.text == transcript['content']
|
||||
for attribute, value in six.iteritems(expected_headers):
|
||||
for attribute, value in expected_headers.items():
|
||||
assert response.headers[attribute] == value
|
||||
|
||||
@patch('xmodule.video_module.VideoBlock.translation', Mock(side_effect=NotFoundError))
|
||||
@@ -853,7 +851,7 @@ class TestStudioTranscriptTranslationGetDispatch(TestVideo): # lint-amnesty, py
|
||||
Tests for `translation` dispatch GET HTTP method.
|
||||
"""
|
||||
srt_file = _create_srt_file()
|
||||
DATA = u"""
|
||||
DATA = """
|
||||
<video show_captions="true"
|
||||
display_name="A Name"
|
||||
>
|
||||
@@ -862,7 +860,7 @@ class TestStudioTranscriptTranslationGetDispatch(TestVideo): # lint-amnesty, py
|
||||
<transcript language="uk" src="{}"/>
|
||||
<transcript language="zh" src="{}"/>
|
||||
</video>
|
||||
""".format(os.path.split(srt_file.name)[1], u"塞.srt")
|
||||
""".format(os.path.split(srt_file.name)[1], "塞.srt")
|
||||
|
||||
MODEL_DATA = {'data': DATA}
|
||||
|
||||
@@ -881,17 +879,17 @@ class TestStudioTranscriptTranslationGetDispatch(TestVideo): # lint-amnesty, py
|
||||
# Correct case:
|
||||
filename = os.path.split(self.srt_file.name)[1]
|
||||
_upload_file(self.srt_file, self.item_descriptor.location, filename)
|
||||
request = Request.blank(u"translation?language_code=uk")
|
||||
request = Request.blank("translation?language_code=uk")
|
||||
response = self.item_descriptor.studio_transcript(request=request, dispatch="translation?language_code=uk")
|
||||
self.srt_file.seek(0)
|
||||
assert response.body == self.srt_file.read()
|
||||
assert response.headers['Content-Type'] == 'application/x-subrip; charset=utf-8'
|
||||
assert response.headers['Content-Disposition'] == u'attachment; filename="uk_{}"'.format(filename)
|
||||
assert response.headers['Content-Disposition'] == f'attachment; filename="uk_{filename}"'
|
||||
assert response.headers['Content-Language'] == 'uk'
|
||||
|
||||
# Non ascii file name download:
|
||||
self.srt_file.seek(0)
|
||||
_upload_file(self.srt_file, self.item_descriptor.location, u"塞.srt")
|
||||
_upload_file(self.srt_file, self.item_descriptor.location, "塞.srt")
|
||||
request = Request.blank("translation?language_code=zh")
|
||||
response = self.item_descriptor.studio_transcript(request=request, dispatch="translation?language_code=zh")
|
||||
self.srt_file.seek(0)
|
||||
@@ -1011,7 +1009,7 @@ class TestStudioTranscriptTranslationDeleteDispatch(TestVideo): # lint-amnesty,
|
||||
|
||||
Tests for `translation` dispatch DELETE HTTP method.
|
||||
"""
|
||||
EDX_VIDEO_ID, LANGUAGE_CODE_UK, LANGUAGE_CODE_EN = u'an_edx_video_id', u'uk', u'en'
|
||||
EDX_VIDEO_ID, LANGUAGE_CODE_UK, LANGUAGE_CODE_EN = 'an_edx_video_id', 'uk', 'en'
|
||||
REQUEST_META = {'wsgi.url_scheme': 'http', 'REQUEST_METHOD': 'DELETE'}
|
||||
SRT_FILE = _create_srt_file()
|
||||
|
||||
@@ -1046,7 +1044,7 @@ class TestStudioTranscriptTranslationDeleteDispatch(TestVideo): # lint-amnesty,
|
||||
'client_video_id': 'awesome.mp4',
|
||||
'duration': 0,
|
||||
'encoded_videos': [],
|
||||
'courses': [six.text_type(self.course.id)]
|
||||
'courses': [str(self.course.id)]
|
||||
})
|
||||
api.create_video_transcript(
|
||||
video_id=self.EDX_VIDEO_ID,
|
||||
@@ -1120,7 +1118,7 @@ class TestStudioTranscriptTranslationDeleteDispatch(TestVideo): # lint-amnesty,
|
||||
request = Request(self.REQUEST_META, body=request_body.encode('utf-8'))
|
||||
|
||||
# sub should not be empy
|
||||
assert not self.item_descriptor.sub == u''
|
||||
assert not self.item_descriptor.sub == ''
|
||||
# lint-amnesty, pylint: disable=wrong-assert-type
|
||||
|
||||
# upload and verify that srt file exists in assets
|
||||
@@ -1132,7 +1130,7 @@ class TestStudioTranscriptTranslationDeleteDispatch(TestVideo): # lint-amnesty,
|
||||
assert response.status_code == 200
|
||||
|
||||
# verify that sub is empty and transcript is deleted also
|
||||
assert self.item_descriptor.sub == u''
|
||||
assert self.item_descriptor.sub == ''
|
||||
# lint-amnesty, pylint: disable=wrong-assert-type
|
||||
assert not _check_asset(self.item_descriptor.location, sub_file_name)
|
||||
|
||||
@@ -1142,7 +1140,7 @@ class TestGetTranscript(TestVideo): # lint-amnesty, pylint: disable=test-inheri
|
||||
Make sure that `get_transcript` method works correctly
|
||||
"""
|
||||
srt_file = _create_srt_file()
|
||||
DATA = u"""
|
||||
DATA = """
|
||||
<video show_captions="true"
|
||||
display_name="A Name"
|
||||
>
|
||||
@@ -1151,7 +1149,7 @@ class TestGetTranscript(TestVideo): # lint-amnesty, pylint: disable=test-inheri
|
||||
<transcript language="uk" src="{}"/>
|
||||
<transcript language="zh" src="{}"/>
|
||||
</video>
|
||||
""".format(os.path.split(srt_file.name)[1], u"塞.srt")
|
||||
""".format(os.path.split(srt_file.name)[1], "塞.srt")
|
||||
|
||||
MODEL_DATA = {
|
||||
'data': DATA
|
||||
@@ -1159,7 +1157,7 @@ class TestGetTranscript(TestVideo): # lint-amnesty, pylint: disable=test-inheri
|
||||
METADATA = {}
|
||||
|
||||
def setUp(self):
|
||||
super(TestGetTranscript, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.item_descriptor.render(STUDENT_VIEW)
|
||||
self.item = self.item_descriptor
|
||||
|
||||
@@ -1285,17 +1283,17 @@ class TestGetTranscript(TestVideo): # lint-amnesty, pylint: disable=test-inheri
|
||||
def test_non_en_with_non_ascii_filename(self):
|
||||
self.item.transcript_language = 'zh'
|
||||
self.srt_file.seek(0)
|
||||
_upload_file(self.srt_file, self.item_descriptor.location, u"塞.srt")
|
||||
_upload_file(self.srt_file, self.item_descriptor.location, "塞.srt")
|
||||
|
||||
transcripts = self.item.get_transcripts_info() # lint-amnesty, pylint: disable=unused-variable
|
||||
text, filename, mime_type = get_transcript(self.item)
|
||||
expected_text = textwrap.dedent(u"""
|
||||
expected_text = textwrap.dedent("""
|
||||
0
|
||||
00:00:00,12 --> 00:00:00,100
|
||||
Привіт, edX вітає вас.
|
||||
""")
|
||||
assert text == expected_text
|
||||
assert filename == u'zh_塞.srt'
|
||||
assert filename == 'zh_塞.srt'
|
||||
assert mime_type == 'application/x-subrip; charset=utf-8'
|
||||
|
||||
def test_value_error(self):
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Video xmodule tests in mongo.
|
||||
"""
|
||||
|
||||
|
||||
import io
|
||||
import json
|
||||
import shutil
|
||||
from collections import OrderedDict
|
||||
from tempfile import mkdtemp
|
||||
from uuid import uuid4
|
||||
from unittest.mock import MagicMock, Mock, patch
|
||||
import pytest
|
||||
import ddt
|
||||
import six
|
||||
from django.conf import settings
|
||||
from django.core.files import File
|
||||
from django.core.files.base import ContentFile
|
||||
@@ -33,7 +31,6 @@ from edxval.utils import create_file_in_fs
|
||||
from fs.osfs import OSFS
|
||||
from fs.path import combine
|
||||
from lxml import etree
|
||||
from mock import MagicMock, Mock, patch
|
||||
from path import Path as path
|
||||
from waffle.testutils import override_flag
|
||||
|
||||
@@ -61,7 +58,7 @@ MODULESTORES = {
|
||||
ModuleStoreEnum.Type.split: TEST_DATA_SPLIT_MODULESTORE,
|
||||
}
|
||||
|
||||
TRANSCRIPT_FILE_SRT_DATA = u"""
|
||||
TRANSCRIPT_FILE_SRT_DATA = """
|
||||
1
|
||||
00:00:14,370 --> 00:00:16,530
|
||||
I am overwatch.
|
||||
@@ -80,7 +77,7 @@ class TestVideoYouTube(TestVideo): # lint-amnesty, pylint: disable=missing-clas
|
||||
def test_video_constructor(self):
|
||||
"""Make sure that all parameters extracted correctly from xml"""
|
||||
context = self.item_descriptor.render(STUDENT_VIEW).content
|
||||
sources = [u'example.mp4', u'example.webm']
|
||||
sources = ['example.mp4', 'example.webm']
|
||||
|
||||
expected_context = {
|
||||
'autoadvance_enabled': False,
|
||||
@@ -89,8 +86,8 @@ class TestVideoYouTube(TestVideo): # lint-amnesty, pylint: disable=missing-clas
|
||||
'bumper_metadata': 'null',
|
||||
'cdn_eval': False,
|
||||
'cdn_exp_group': None,
|
||||
'display_name': u'A Name',
|
||||
'download_video_link': u'example.mp4',
|
||||
'display_name': 'A Name',
|
||||
'download_video_link': 'example.mp4',
|
||||
'handout': None,
|
||||
'id': self.item_descriptor.location.html_id(),
|
||||
'metadata': json.dumps(OrderedDict({
|
||||
@@ -110,7 +107,7 @@ class TestVideoYouTube(TestVideo): # lint-amnesty, pylint: disable=missing-clas
|
||||
'start': 3603.0,
|
||||
'end': 3610.0,
|
||||
'transcriptLanguage': 'en',
|
||||
'transcriptLanguages': OrderedDict({'en': 'English', 'uk': u'Українська'}),
|
||||
'transcriptLanguages': OrderedDict({'en': 'English', 'uk': 'Українська'}),
|
||||
'ytMetadataEndpoint': '',
|
||||
'ytTestTimeout': 1500,
|
||||
'ytApiUrl': 'https://www.youtube.com/iframe_api',
|
||||
@@ -125,7 +122,7 @@ class TestVideoYouTube(TestVideo): # lint-amnesty, pylint: disable=missing-clas
|
||||
'prioritizeHls': False,
|
||||
})),
|
||||
'track': None,
|
||||
'transcript_download_format': u'srt',
|
||||
'transcript_download_format': 'srt',
|
||||
'transcript_download_formats_list': [
|
||||
{'display_name': 'SubRip (.srt) file', 'value': 'srt'},
|
||||
{'display_name': 'Text (.txt) file', 'value': 'txt'}
|
||||
@@ -161,7 +158,7 @@ class TestVideoNonYouTube(TestVideo): # pylint: disable=test-inherits-tests
|
||||
the template generates an empty string for the YouTube streams.
|
||||
"""
|
||||
context = self.item_descriptor.render(STUDENT_VIEW).content
|
||||
sources = [u'example.mp4', u'example.webm']
|
||||
sources = ['example.mp4', 'example.webm']
|
||||
|
||||
expected_context = {
|
||||
'autoadvance_enabled': False,
|
||||
@@ -170,8 +167,8 @@ class TestVideoNonYouTube(TestVideo): # pylint: disable=test-inherits-tests
|
||||
'bumper_metadata': 'null',
|
||||
'cdn_eval': False,
|
||||
'cdn_exp_group': None,
|
||||
'display_name': u'A Name',
|
||||
'download_video_link': u'example.mp4',
|
||||
'display_name': 'A Name',
|
||||
'download_video_link': 'example.mp4',
|
||||
'handout': None,
|
||||
'id': self.item_descriptor.location.html_id(),
|
||||
'metadata': json.dumps(OrderedDict({
|
||||
@@ -206,7 +203,7 @@ class TestVideoNonYouTube(TestVideo): # pylint: disable=test-inherits-tests
|
||||
'prioritizeHls': False,
|
||||
})),
|
||||
'track': None,
|
||||
'transcript_download_format': u'srt',
|
||||
'transcript_download_format': 'srt',
|
||||
'transcript_download_formats_list': [
|
||||
{'display_name': 'SubRip (.srt) file', 'value': 'srt'},
|
||||
{'display_name': 'Text (.txt) file', 'value': 'txt'}
|
||||
@@ -233,7 +230,7 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
|
||||
METADATA = {}
|
||||
|
||||
def setUp(self):
|
||||
super(TestGetHtmlMethod, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.setup_course()
|
||||
self.default_metadata_dict = OrderedDict({
|
||||
'autoAdvance': False,
|
||||
@@ -294,42 +291,42 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
|
||||
|
||||
cases = [
|
||||
{
|
||||
'download_track': u'true',
|
||||
'track': u'<track src="http://www.example.com/track"/>',
|
||||
'sub': u'a_sub_file.srt.sjson',
|
||||
'expected_track_url': u'http://www.example.com/track',
|
||||
'download_track': 'true',
|
||||
'track': '<track src="http://www.example.com/track"/>',
|
||||
'sub': 'a_sub_file.srt.sjson',
|
||||
'expected_track_url': 'http://www.example.com/track',
|
||||
'transcripts': '',
|
||||
},
|
||||
{
|
||||
'download_track': u'true',
|
||||
'track': u'',
|
||||
'sub': u'a_sub_file.srt.sjson',
|
||||
'expected_track_url': u'a_sub_file.srt.sjson',
|
||||
'download_track': 'true',
|
||||
'track': '',
|
||||
'sub': 'a_sub_file.srt.sjson',
|
||||
'expected_track_url': 'a_sub_file.srt.sjson',
|
||||
'transcripts': '',
|
||||
},
|
||||
{
|
||||
'download_track': u'true',
|
||||
'track': u'',
|
||||
'sub': u'',
|
||||
'download_track': 'true',
|
||||
'track': '',
|
||||
'sub': '',
|
||||
'expected_track_url': None,
|
||||
'transcripts': '',
|
||||
},
|
||||
{
|
||||
'download_track': u'false',
|
||||
'track': u'<track src="http://www.example.com/track"/>',
|
||||
'sub': u'a_sub_file.srt.sjson',
|
||||
'download_track': 'false',
|
||||
'track': '<track src="http://www.example.com/track"/>',
|
||||
'sub': 'a_sub_file.srt.sjson',
|
||||
'expected_track_url': None,
|
||||
'transcripts': '',
|
||||
},
|
||||
{
|
||||
'download_track': u'true',
|
||||
'track': u'',
|
||||
'sub': u'',
|
||||
'expected_track_url': u'a_sub_file.srt.sjson',
|
||||
'download_track': 'true',
|
||||
'track': '',
|
||||
'sub': '',
|
||||
'expected_track_url': 'a_sub_file.srt.sjson',
|
||||
'transcripts': '<transcript language="uk" src="ukrainian.srt" />',
|
||||
},
|
||||
]
|
||||
sources = [u'example.mp4', u'example.webm']
|
||||
sources = ['example.mp4', 'example.webm']
|
||||
|
||||
expected_context = {
|
||||
'autoadvance_enabled': False,
|
||||
@@ -338,13 +335,13 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
|
||||
'bumper_metadata': 'null',
|
||||
'cdn_eval': False,
|
||||
'cdn_exp_group': None,
|
||||
'display_name': u'A Name',
|
||||
'download_video_link': u'example.mp4',
|
||||
'display_name': 'A Name',
|
||||
'download_video_link': 'example.mp4',
|
||||
'handout': None,
|
||||
'id': self.item_descriptor.location.html_id(),
|
||||
'metadata': '',
|
||||
'track': None,
|
||||
'transcript_download_format': u'srt',
|
||||
'transcript_download_format': 'srt',
|
||||
'transcript_download_formats_list': [
|
||||
{'display_name': 'SubRip (.srt) file', 'value': 'srt'},
|
||||
{'display_name': 'Text (.txt) file', 'value': 'txt'}
|
||||
@@ -368,8 +365,8 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
|
||||
|
||||
context = self.item_descriptor.render(STUDENT_VIEW).content
|
||||
metadata.update({
|
||||
'transcriptLanguages': {"en": "English"} if not data['transcripts'] else {"uk": u'Українська'},
|
||||
'transcriptLanguage': u'en' if not data['transcripts'] or data.get('sub') else u'uk',
|
||||
'transcriptLanguages': {"en": "English"} if not data['transcripts'] else {"uk": 'Українська'},
|
||||
'transcriptLanguage': 'en' if not data['transcripts'] or data.get('sub') else 'uk',
|
||||
'transcriptTranslationUrl': self.get_handler_url('transcript', 'translation/__lang__'),
|
||||
'transcriptAvailableTranslationsUrl': self.get_handler_url('transcript', 'available_translations'),
|
||||
'publishCompletionUrl': self.get_handler_url('publish_completion', ''),
|
||||
@@ -377,10 +374,10 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
|
||||
})
|
||||
expected_context.update({
|
||||
'transcript_download_format': (
|
||||
None if self.item_descriptor.track and self.item_descriptor.download_track else u'srt'
|
||||
None if self.item_descriptor.track and self.item_descriptor.download_track else 'srt'
|
||||
),
|
||||
'track': (
|
||||
track_url if data['expected_track_url'] == u'a_sub_file.srt.sjson' else data['expected_track_url']
|
||||
track_url if data['expected_track_url'] == 'a_sub_file.srt.sjson' else data['expected_track_url']
|
||||
),
|
||||
'id': self.item_descriptor.location.html_id(),
|
||||
'metadata': json.dumps(metadata)
|
||||
@@ -412,8 +409,8 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
|
||||
<source src="example.webm"/>
|
||||
""",
|
||||
'result': {
|
||||
'download_video_link': u'example.mp4',
|
||||
'sources': [u'example.mp4', u'example.webm'],
|
||||
'download_video_link': 'example.mp4',
|
||||
'sources': ['example.mp4', 'example.webm'],
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -424,8 +421,8 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
|
||||
<source src="example.webm"/>
|
||||
""",
|
||||
'result': {
|
||||
'download_video_link': u'example.mp4',
|
||||
'sources': [u'example.mp4', u'example.webm'],
|
||||
'download_video_link': 'example.mp4',
|
||||
'sources': ['example.mp4', 'example.webm'],
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -444,7 +441,7 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
|
||||
<source src="example.webm"/>
|
||||
""",
|
||||
'result': {
|
||||
'sources': [u'example.mp4', u'example.webm'],
|
||||
'sources': ['example.mp4', 'example.webm'],
|
||||
},
|
||||
},
|
||||
]
|
||||
@@ -456,13 +453,13 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
|
||||
'bumper_metadata': 'null',
|
||||
'cdn_eval': False,
|
||||
'cdn_exp_group': None,
|
||||
'display_name': u'A Name',
|
||||
'download_video_link': u'example.mp4',
|
||||
'display_name': 'A Name',
|
||||
'download_video_link': 'example.mp4',
|
||||
'handout': None,
|
||||
'id': self.item_descriptor.location.html_id(),
|
||||
'metadata': self.default_metadata_dict,
|
||||
'track': None,
|
||||
'transcript_download_format': u'srt',
|
||||
'transcript_download_format': 'srt',
|
||||
'transcript_download_formats_list': [
|
||||
{'display_name': 'SubRip (.srt) file', 'value': 'srt'},
|
||||
{'display_name': 'Text (.txt) file', 'value': 'txt'}
|
||||
@@ -504,7 +501,7 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
|
||||
"""
|
||||
# pylint: disable=invalid-name
|
||||
# lint-amnesty, pylint: disable=redefined-outer-name
|
||||
SOURCE_XML = u"""
|
||||
SOURCE_XML = """
|
||||
<video show_captions="true"
|
||||
display_name="A Name"
|
||||
sub="a_sub_file.srt.sjson" source="{source}"
|
||||
@@ -524,8 +521,8 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
|
||||
""",
|
||||
'edx_video_id': "meow",
|
||||
'result': {
|
||||
'download_video_link': u'example.mp4',
|
||||
'sources': [u'example.mp4', u'example.webm'],
|
||||
'download_video_link': 'example.mp4',
|
||||
'sources': ['example.mp4', 'example.webm'],
|
||||
}
|
||||
}
|
||||
DATA = SOURCE_XML.format(
|
||||
@@ -566,7 +563,7 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
|
||||
'result': {
|
||||
'download_video_link': None,
|
||||
# make sure the desktop_mp4 url is included as part of the alternative sources.
|
||||
'sources': [u'example.mp4', u'example.webm', u'http://www.meowmix.com'],
|
||||
'sources': ['example.mp4', 'example.webm', 'http://www.meowmix.com'],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -581,12 +578,12 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
|
||||
'bumper_metadata': 'null',
|
||||
'cdn_eval': False,
|
||||
'cdn_exp_group': None,
|
||||
'display_name': u'A Name',
|
||||
'download_video_link': u'example.mp4',
|
||||
'display_name': 'A Name',
|
||||
'download_video_link': 'example.mp4',
|
||||
'handout': None,
|
||||
'id': self.item_descriptor.location.html_id(),
|
||||
'track': None,
|
||||
'transcript_download_format': u'srt',
|
||||
'transcript_download_format': 'srt',
|
||||
'transcript_download_formats_list': [
|
||||
{'display_name': 'SubRip (.srt) file', 'value': 'srt'},
|
||||
{'display_name': 'Text (.txt) file', 'value': 'txt'}
|
||||
@@ -606,15 +603,15 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
|
||||
with patch('edxval.api.get_video_info') as mock_get_video_info:
|
||||
mock_get_video_info.return_value = {
|
||||
'url': '/edxval/video/example',
|
||||
'edx_video_id': u'example',
|
||||
'edx_video_id': 'example',
|
||||
'duration': 111.0,
|
||||
'client_video_id': u'The example video',
|
||||
'client_video_id': 'The example video',
|
||||
'encoded_videos': [
|
||||
{
|
||||
'url': u'http://www.meowmix.com',
|
||||
'url': 'http://www.meowmix.com',
|
||||
'file_size': 25556,
|
||||
'bitrate': 9600,
|
||||
'profile': u'desktop_mp4'
|
||||
'profile': 'desktop_mp4'
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -655,8 +652,8 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
|
||||
""",
|
||||
'edx_video_id': edx_video_id,
|
||||
'result': {
|
||||
'download_video_link': u'http://fake-video.edx.org/{}.mp4'.format(edx_video_id),
|
||||
'sources': [u'example.mp4', u'example.webm'] + [video['url'] for video in encoded_videos],
|
||||
'download_video_link': f'http://fake-video.edx.org/{edx_video_id}.mp4',
|
||||
'sources': ['example.mp4', 'example.webm'] + [video['url'] for video in encoded_videos],
|
||||
},
|
||||
}
|
||||
# context returned by get_html when provided with above data
|
||||
@@ -683,10 +680,10 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
|
||||
<source src="example.mp4"/>
|
||||
<source src="example.webm"/>
|
||||
""",
|
||||
'edx_video_id': "{}\t".format(edx_video_id),
|
||||
'edx_video_id': f"{edx_video_id}\t",
|
||||
'result': {
|
||||
'download_video_link': u'http://fake-video.edx.org/{}.mp4'.format(edx_video_id),
|
||||
'sources': [u'example.mp4', u'example.webm'] + [video['url'] for video in encoded_videos],
|
||||
'download_video_link': f'http://fake-video.edx.org/{edx_video_id}.mp4',
|
||||
'sources': ['example.mp4', 'example.webm'] + [video['url'] for video in encoded_videos],
|
||||
},
|
||||
}
|
||||
# context returned by get_html when provided with above data
|
||||
@@ -706,7 +703,7 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
|
||||
create_profile(profile)
|
||||
encoded_videos.append(
|
||||
dict(
|
||||
url=u"http://fake-video.edx.org/{}.{}".format(edx_video_id, extension),
|
||||
url=f"http://fake-video.edx.org/{edx_video_id}.{extension}",
|
||||
file_size=9000,
|
||||
bitrate=42,
|
||||
profile=profile,
|
||||
@@ -730,7 +727,7 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
|
||||
"""
|
||||
# make sure the urls for the various encodings are included as part of the alternative sources.
|
||||
# lint-amnesty, pylint: disable=invalid-name, redefined-outer-name
|
||||
SOURCE_XML = u"""
|
||||
SOURCE_XML = """
|
||||
<video show_captions="true"
|
||||
display_name="A Name"
|
||||
sub="a_sub_file.srt.sjson" source="{source}"
|
||||
@@ -752,12 +749,12 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
|
||||
'bumper_metadata': 'null',
|
||||
'cdn_eval': False,
|
||||
'cdn_exp_group': None,
|
||||
'display_name': u'A Name',
|
||||
'download_video_link': u'example.mp4',
|
||||
'display_name': 'A Name',
|
||||
'download_video_link': 'example.mp4',
|
||||
'handout': None,
|
||||
'id': self.item_descriptor.location.html_id(),
|
||||
'track': None,
|
||||
'transcript_download_format': u'srt',
|
||||
'transcript_download_format': 'srt',
|
||||
'transcript_download_formats_list': [
|
||||
{'display_name': 'SubRip (.srt) file', 'value': 'srt'},
|
||||
{'display_name': 'Text (.txt) file', 'value': 'txt'}
|
||||
@@ -818,7 +815,7 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
|
||||
|
||||
mocked_get_video.side_effect = side_effect
|
||||
|
||||
source_xml = u"""
|
||||
source_xml = """
|
||||
<video show_captions="true"
|
||||
display_name="A Name"
|
||||
sub="a_sub_file.srt.sjson" source="{source}"
|
||||
@@ -838,10 +835,10 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
|
||||
<source src="http://example.com/example.webm"/>
|
||||
""",
|
||||
'result': {
|
||||
'download_video_link': u'http://example.com/example.mp4',
|
||||
'download_video_link': 'http://example.com/example.mp4',
|
||||
'sources': [
|
||||
u'http://cdn-example.com/example.mp4',
|
||||
u'http://cdn-example.com/example.webm'
|
||||
'http://cdn-example.com/example.mp4',
|
||||
'http://cdn-example.com/example.webm'
|
||||
],
|
||||
},
|
||||
}
|
||||
@@ -863,13 +860,13 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
|
||||
'bumper_metadata': 'null',
|
||||
'cdn_eval': False,
|
||||
'cdn_exp_group': None,
|
||||
'display_name': u'A Name',
|
||||
'display_name': 'A Name',
|
||||
'download_video_link': None,
|
||||
'handout': None,
|
||||
'id': None,
|
||||
'metadata': self.default_metadata_dict,
|
||||
'track': None,
|
||||
'transcript_download_format': u'srt',
|
||||
'transcript_download_format': 'srt',
|
||||
'transcript_download_formats_list': [
|
||||
{'display_name': 'SubRip (.srt) file', 'value': 'srt'},
|
||||
{'display_name': 'Text (.txt) file', 'value': 'txt'}
|
||||
@@ -916,7 +913,7 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
|
||||
remain unchanged in the get_html() method.
|
||||
"""
|
||||
|
||||
source_xml = u"""
|
||||
source_xml = """
|
||||
<video show_captions="true"
|
||||
display_name="A Name"
|
||||
sub="a_sub_file.srt.sjson" source="{source}"
|
||||
@@ -935,9 +932,9 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
|
||||
<source src="http://example.com/example.mp4"/>
|
||||
""",
|
||||
'result': {
|
||||
'download_video_link': u'http://example.com/example.mp4',
|
||||
'download_video_link': 'http://example.com/example.mp4',
|
||||
'sources': [
|
||||
u'http://example.com/example.mp4',
|
||||
'http://example.com/example.mp4',
|
||||
],
|
||||
},
|
||||
}
|
||||
@@ -953,13 +950,13 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
|
||||
'bumper_metadata': 'null',
|
||||
'cdn_eval': False,
|
||||
'cdn_exp_group': None,
|
||||
'display_name': u'A Name',
|
||||
'display_name': 'A Name',
|
||||
'download_video_link': None,
|
||||
'handout': None,
|
||||
'id': None,
|
||||
'metadata': self.default_metadata_dict,
|
||||
'track': None,
|
||||
'transcript_download_format': u'srt',
|
||||
'transcript_download_format': 'srt',
|
||||
'transcript_download_formats_list': [
|
||||
{'display_name': 'SubRip (.srt) file', 'value': 'srt'},
|
||||
{'display_name': 'Text (.txt) file', 'value': 'txt'}
|
||||
@@ -983,10 +980,10 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
|
||||
with patch('edxval.api.get_video_info') as mock_get_video_info:
|
||||
mock_get_video_info.return_value = {
|
||||
'url': 'http://example.com/example.mp4',
|
||||
'edx_video_id': u'vid-v1:12345',
|
||||
'status': u'external',
|
||||
'edx_video_id': 'vid-v1:12345',
|
||||
'status': 'external',
|
||||
'duration': None,
|
||||
'client_video_id': u'external video',
|
||||
'client_video_id': 'external video',
|
||||
'encoded_videos': {}
|
||||
}
|
||||
context = self.item_descriptor.render(STUDENT_VIEW).content
|
||||
@@ -1171,7 +1168,7 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
|
||||
metadata = {
|
||||
'html5_sources': ['http://youtu.be/3_yD_cEKoCk.mp4'] + data['hls'],
|
||||
}
|
||||
video_xml = u'<video display_name="Video" edx_video_id="12345-67890" youtube_id_1_0="{}">[]</video>'.format(
|
||||
video_xml = '<video display_name="Video" edx_video_id="12345-67890" youtube_id_1_0="{}">[]</video>'.format(
|
||||
data['youtube']
|
||||
)
|
||||
DEPRECATE_YOUTUBE_FLAG = waffle_flags()[DEPRECATE_YOUTUBE]
|
||||
@@ -1179,7 +1176,7 @@ class TestGetHtmlMethod(BaseTestVideoXBlock):
|
||||
with override_flag(DEPRECATE_YOUTUBE_FLAG.name, active=data['waffle_enabled']):
|
||||
self.initialize_block(data=video_xml, metadata=metadata)
|
||||
context = self.item_descriptor.render(STUDENT_VIEW).content
|
||||
assert u'"prioritizeHls": {}'.format(data['result']) in context
|
||||
assert '"prioritizeHls": {}'.format(data['result']) in context
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@@ -1192,7 +1189,7 @@ class TestVideoBlockInitialization(BaseTestVideoXBlock):
|
||||
METADATA = {}
|
||||
|
||||
def setUp(self):
|
||||
super(TestVideoBlockInitialization, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.setup_course()
|
||||
|
||||
@ddt.data(
|
||||
@@ -1294,7 +1291,7 @@ class TestEditorSavedMethod(BaseTestVideoXBlock):
|
||||
METADATA = {}
|
||||
|
||||
def setUp(self):
|
||||
super(TestEditorSavedMethod, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.setup_course()
|
||||
self.metadata = {
|
||||
'source': 'http://youtu.be/3_yD_cEKoCk',
|
||||
@@ -1353,8 +1350,8 @@ class TestEditorSavedMethod(BaseTestVideoXBlock):
|
||||
Verify editor saved when video id contains spaces/tabs.
|
||||
"""
|
||||
self.MODULESTORE = MODULESTORES[default_store]
|
||||
stripped_video_id = six.text_type(uuid4())
|
||||
unstripped_video_id = u'{video_id}{tabs}'.format(video_id=stripped_video_id, tabs=u'\t\t\t')
|
||||
stripped_video_id = str(uuid4())
|
||||
unstripped_video_id = '{video_id}{tabs}'.format(video_id=stripped_video_id, tabs='\t\t\t')
|
||||
self.metadata.update({
|
||||
'edx_video_id': unstripped_video_id
|
||||
})
|
||||
@@ -1364,7 +1361,7 @@ class TestEditorSavedMethod(BaseTestVideoXBlock):
|
||||
|
||||
# Now, modifying and saving the video module should strip the video id.
|
||||
old_metadata = own_metadata(item)
|
||||
item.display_name = u'New display name'
|
||||
item.display_name = 'New display name'
|
||||
item.editor_saved(self.user, old_metadata, None)
|
||||
assert item.edx_video_id == stripped_video_id
|
||||
|
||||
@@ -1382,7 +1379,7 @@ class TestEditorSavedMethod(BaseTestVideoXBlock):
|
||||
|
||||
# Now, modify `edx_video_id` and save should override `youtube_id_1_0`.
|
||||
old_metadata = own_metadata(item)
|
||||
item.edx_video_id = six.text_type(uuid4())
|
||||
item.edx_video_id = str(uuid4())
|
||||
item.editor_saved(self.user, old_metadata, None)
|
||||
assert item.youtube_id_1_0 == 'test_yt_id'
|
||||
|
||||
@@ -1394,8 +1391,8 @@ class TestVideoBlockStudentViewJson(BaseTestVideoXBlock, CacheIsolationTestCase)
|
||||
"""
|
||||
TEST_DURATION = 111.0
|
||||
TEST_PROFILE = "mobile"
|
||||
TEST_SOURCE_URL = u"http://www.example.com/source.mp4"
|
||||
TEST_LANGUAGE = u"ge"
|
||||
TEST_SOURCE_URL = "http://www.example.com/source.mp4"
|
||||
TEST_LANGUAGE = "ge"
|
||||
TEST_ENCODED_VIDEO = {
|
||||
'profile': TEST_PROFILE,
|
||||
'bitrate': 333,
|
||||
@@ -1404,10 +1401,10 @@ class TestVideoBlockStudentViewJson(BaseTestVideoXBlock, CacheIsolationTestCase)
|
||||
}
|
||||
TEST_EDX_VIDEO_ID = 'test_edx_video_id'
|
||||
TEST_YOUTUBE_ID = 'test_youtube_id'
|
||||
TEST_YOUTUBE_EXPECTED_URL = u'https://www.youtube.com/watch?v=test_youtube_id'
|
||||
TEST_YOUTUBE_EXPECTED_URL = 'https://www.youtube.com/watch?v=test_youtube_id'
|
||||
|
||||
def setUp(self):
|
||||
super(TestVideoBlockStudentViewJson, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
video_declaration = (
|
||||
"<video display_name='Test Video' edx_video_id='123' youtube_id_1_0=\'" + self.TEST_YOUTUBE_ID + "\'>"
|
||||
)
|
||||
@@ -1436,7 +1433,7 @@ class TestVideoBlockStudentViewJson(BaseTestVideoXBlock, CacheIsolationTestCase)
|
||||
'duration': self.TEST_DURATION,
|
||||
'status': 'dummy',
|
||||
'encoded_videos': [self.TEST_ENCODED_VIDEO],
|
||||
'courses': [six.text_type(self.video.location.course_key)] if associate_course_in_val else [],
|
||||
'courses': [str(self.video.location.course_key)] if associate_course_in_val else [],
|
||||
})
|
||||
self.val_video = get_video_info(self.TEST_EDX_VIDEO_ID) # pylint: disable=attribute-defined-outside-init
|
||||
|
||||
@@ -1513,7 +1510,7 @@ class TestVideoBlockStudentViewJson(BaseTestVideoXBlock, CacheIsolationTestCase)
|
||||
self.verify_result_with_fallback_and_youtube(result)
|
||||
|
||||
def test_no_edx_video_id_and_no_fallback(self):
|
||||
video_declaration = "<video display_name='Test Video' youtube_id_1_0=\'{}\'>".format(self.TEST_YOUTUBE_ID)
|
||||
video_declaration = f"<video display_name='Test Video' youtube_id_1_0=\'{self.TEST_YOUTUBE_ID}\'>"
|
||||
# the video has no source listed, only a youtube link, so no fallback url will be provided
|
||||
sample_xml = ''.join([
|
||||
video_declaration,
|
||||
@@ -1581,7 +1578,7 @@ class TestVideoBlockStudentViewJson(BaseTestVideoXBlock, CacheIsolationTestCase)
|
||||
self.video.transcripts = transcripts
|
||||
self.video.sub = english_sub
|
||||
student_view_response = self.get_result()
|
||||
six.assertCountEqual(self, list(student_view_response['transcripts'].keys()), expected_transcripts)
|
||||
self.assertCountEqual(list(student_view_response['transcripts'].keys()), expected_transcripts)
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@@ -1590,7 +1587,7 @@ class VideoBlockTest(TestCase, VideoBlockTestBase):
|
||||
Tests for video descriptor that requires access to django settings.
|
||||
"""
|
||||
def setUp(self):
|
||||
super(VideoBlockTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.descriptor.runtime.handler_url = MagicMock()
|
||||
self.descriptor.runtime.course_id = MagicMock()
|
||||
self.temp_dir = mkdtemp()
|
||||
@@ -1667,7 +1664,7 @@ class VideoBlockTest(TestCase, VideoBlockTestBase):
|
||||
)
|
||||
|
||||
actual = self.descriptor.definition_to_xml(resource_fs=self.file_system)
|
||||
expected_str = u"""
|
||||
expected_str = """
|
||||
<video url_name="SampleProblem" transcripts='{transcripts}'>
|
||||
<video_asset client_video_id="test_client_video_id" duration="111.0" image="">
|
||||
<encoded_video profile="mobile" url="http://example.com/video" file_size="222" bitrate="333"/>
|
||||
@@ -1690,7 +1687,7 @@ class VideoBlockTest(TestCase, VideoBlockTestBase):
|
||||
assert [transcript_file_name] == self.file_system.listdir(EXPORT_IMPORT_STATIC_DIR)
|
||||
|
||||
# Also verify the content of created transcript file.
|
||||
expected_transcript_content = File(io.open(expected_transcript_path)).read()
|
||||
expected_transcript_content = File(open(expected_transcript_path)).read()
|
||||
transcript = get_video_transcript_data(video_id=self.descriptor.edx_video_id, language_code=language_code)
|
||||
|
||||
assert transcript['content'].decode('utf-8') == expected_transcript_content
|
||||
@@ -1751,7 +1748,7 @@ class VideoBlockTest(TestCase, VideoBlockTestBase):
|
||||
combine(self.temp_dir, EXPORT_IMPORT_COURSE_DIR),
|
||||
combine(EXPORT_IMPORT_STATIC_DIR, expected_transcripts[language])
|
||||
)
|
||||
expected_transcript_content = File(io.open(expected_transcript_path)).read()
|
||||
expected_transcript_content = File(open(expected_transcript_path)).read()
|
||||
transcript = get_video_transcript_data(video_id=self.descriptor.edx_video_id, language_code=language)
|
||||
|
||||
assert transcript['content'].decode('utf-8') == expected_transcript_content
|
||||
@@ -1823,7 +1820,7 @@ class VideoBlockTest(TestCase, VideoBlockTestBase):
|
||||
EXPORT_IMPORT_STATIC_DIR
|
||||
)
|
||||
|
||||
xml_data = u"""
|
||||
xml_data = """
|
||||
<video edx_video_id='{edx_video_id}' sub='{sub_id}' transcripts='{transcripts}'>
|
||||
<video_asset client_video_id="test_client_video_id" duration="111.0">
|
||||
<encoded_video profile="mobile" url="http://example.com/video" file_size="222" bitrate="333"/>
|
||||
@@ -1891,12 +1888,12 @@ class VideoBlockTest(TestCase, VideoBlockTestBase):
|
||||
id_generator = Mock()
|
||||
|
||||
# Verify edx_video_id is empty before.
|
||||
assert self.descriptor.edx_video_id == u''
|
||||
assert self.descriptor.edx_video_id == ''
|
||||
|
||||
video = self.descriptor.from_xml(xml_data, module_system, id_generator)
|
||||
|
||||
# Verify edx_video_id is populated after the import.
|
||||
assert video.edx_video_id != u''
|
||||
assert video.edx_video_id != ''
|
||||
|
||||
video_data = get_video_info(video.edx_video_id)
|
||||
assert video_data['client_video_id'] == 'External Video'
|
||||
@@ -1910,7 +1907,7 @@ class VideoBlockTest(TestCase, VideoBlockTestBase):
|
||||
edx_video_id = 'test_edx_video_id'
|
||||
val_transcript_language_code = 'es'
|
||||
val_transcript_provider = 'Cielo24'
|
||||
xml_data = u"""
|
||||
xml_data = """
|
||||
<video edx_video_id='{edx_video_id}'>
|
||||
<video_asset client_video_id="test_client_video_id" duration="111.0">
|
||||
<transcripts>
|
||||
@@ -1938,12 +1935,12 @@ class VideoBlockTest(TestCase, VideoBlockTestBase):
|
||||
)
|
||||
|
||||
# Verify edx_video_id is empty before.
|
||||
assert self.descriptor.edx_video_id == u''
|
||||
assert self.descriptor.edx_video_id == ''
|
||||
|
||||
video = self.descriptor.from_xml(xml_data, module_system, id_generator)
|
||||
|
||||
# Verify edx_video_id is populated after the import.
|
||||
assert video.edx_video_id != u''
|
||||
assert video.edx_video_id != ''
|
||||
|
||||
video_data = get_video_info(video.edx_video_id)
|
||||
assert video_data['status'] == 'external'
|
||||
@@ -1965,8 +1962,8 @@ class VideoBlockTest(TestCase, VideoBlockTestBase):
|
||||
'<transcripts><transcript file_format="srt" language_code="en" provider="Cielo24"/></transcripts>',
|
||||
# VAL transcript takes priority
|
||||
{
|
||||
'video_id': u'test_edx_video_id',
|
||||
'language_code': u'en',
|
||||
'video_id': 'test_edx_video_id',
|
||||
'language_code': 'en',
|
||||
'file_format': 'srt',
|
||||
'provider': 'Cielo24'
|
||||
}
|
||||
@@ -1977,8 +1974,8 @@ class VideoBlockTest(TestCase, VideoBlockTestBase):
|
||||
'<transcripts><transcript file_format="srt" language_code="en" provider="Cielo24"/></transcripts>',
|
||||
# VAL transcript takes priority
|
||||
{
|
||||
'video_id': u'test_edx_video_id',
|
||||
'language_code': u'en',
|
||||
'video_id': 'test_edx_video_id',
|
||||
'language_code': 'en',
|
||||
'file_format': 'srt',
|
||||
'provider': 'Cielo24'
|
||||
}
|
||||
@@ -1989,8 +1986,8 @@ class VideoBlockTest(TestCase, VideoBlockTestBase):
|
||||
'<transcripts><transcript file_format="srt" language_code="en" provider="Cielo24"/></transcripts>',
|
||||
# VAL transcript takes priority
|
||||
{
|
||||
'video_id': u'test_edx_video_id',
|
||||
'language_code': u'en',
|
||||
'video_id': 'test_edx_video_id',
|
||||
'language_code': 'en',
|
||||
'file_format': 'srt',
|
||||
'provider': 'Cielo24'
|
||||
}
|
||||
@@ -2001,8 +1998,8 @@ class VideoBlockTest(TestCase, VideoBlockTestBase):
|
||||
'',
|
||||
# self.sub transcript takes priority
|
||||
{
|
||||
'video_id': u'test_edx_video_id',
|
||||
'language_code': u'en',
|
||||
'video_id': 'test_edx_video_id',
|
||||
'language_code': 'en',
|
||||
'file_format': 'sjson',
|
||||
'provider': 'Custom'
|
||||
}
|
||||
@@ -2013,8 +2010,8 @@ class VideoBlockTest(TestCase, VideoBlockTestBase):
|
||||
'',
|
||||
# self.transcripts would be saved.
|
||||
{
|
||||
'video_id': u'test_edx_video_id',
|
||||
'language_code': u'en',
|
||||
'video_id': 'test_edx_video_id',
|
||||
'language_code': 'en',
|
||||
'file_format': 'srt',
|
||||
'provider': 'Custom'
|
||||
}
|
||||
@@ -2045,7 +2042,7 @@ class VideoBlockTest(TestCase, VideoBlockTestBase):
|
||||
module_system.resources_fs,
|
||||
EXPORT_IMPORT_STATIC_DIR
|
||||
)
|
||||
xml_data += u" sub='{sub_id}'".format(
|
||||
xml_data += " sub='{sub_id}'".format(
|
||||
sub_id=sub_id
|
||||
)
|
||||
|
||||
@@ -2057,7 +2054,7 @@ class VideoBlockTest(TestCase, VideoBlockTestBase):
|
||||
module_system.resources_fs,
|
||||
EXPORT_IMPORT_STATIC_DIR
|
||||
)
|
||||
xml_data += u" transcripts='{transcripts}'".format(
|
||||
xml_data += " transcripts='{transcripts}'".format(
|
||||
transcripts=json.dumps(external_transcripts),
|
||||
)
|
||||
|
||||
@@ -2079,12 +2076,12 @@ class VideoBlockTest(TestCase, VideoBlockTestBase):
|
||||
xml_data += '</video_asset></video>'
|
||||
|
||||
# Verify edx_video_id is empty before import.
|
||||
assert self.descriptor.edx_video_id == u''
|
||||
assert self.descriptor.edx_video_id == ''
|
||||
|
||||
video = self.descriptor.from_xml(xml_data, module_system, id_generator)
|
||||
|
||||
# Verify edx_video_id is not empty after import.
|
||||
assert video.edx_video_id != u''
|
||||
assert video.edx_video_id != ''
|
||||
|
||||
video_data = get_video_info(video.edx_video_id)
|
||||
assert video_data['status'] == 'external'
|
||||
@@ -2166,7 +2163,7 @@ class TestVideoWithBumper(TestVideo): # pylint: disable=test-inherits-tests
|
||||
is_bumper_enabled.return_value = True
|
||||
|
||||
content = self.item_descriptor.render(STUDENT_VIEW).content
|
||||
sources = [u'example.mp4', u'example.webm']
|
||||
sources = ['example.mp4', 'example.webm']
|
||||
expected_context = {
|
||||
'autoadvance_enabled': False,
|
||||
'branding_info': None,
|
||||
@@ -2190,8 +2187,8 @@ class TestVideoWithBumper(TestVideo): # pylint: disable=test-inherits-tests
|
||||
})),
|
||||
'cdn_eval': False,
|
||||
'cdn_exp_group': None,
|
||||
'display_name': u'A Name',
|
||||
'download_video_link': u'example.mp4',
|
||||
'display_name': 'A Name',
|
||||
'download_video_link': 'example.mp4',
|
||||
'handout': None,
|
||||
'id': self.item_descriptor.location.html_id(),
|
||||
'metadata': json.dumps(OrderedDict({
|
||||
@@ -2211,7 +2208,7 @@ class TestVideoWithBumper(TestVideo): # pylint: disable=test-inherits-tests
|
||||
'start': 3603.0,
|
||||
'end': 3610.0,
|
||||
'transcriptLanguage': 'en',
|
||||
'transcriptLanguages': OrderedDict({'en': 'English', 'uk': u'Українська'}),
|
||||
'transcriptLanguages': OrderedDict({'en': 'English', 'uk': 'Українська'}),
|
||||
'ytMetadataEndpoint': '',
|
||||
'ytTestTimeout': 1500,
|
||||
'ytApiUrl': 'https://www.youtube.com/iframe_api',
|
||||
@@ -2226,7 +2223,7 @@ class TestVideoWithBumper(TestVideo): # pylint: disable=test-inherits-tests
|
||||
'prioritizeHls': False,
|
||||
})),
|
||||
'track': None,
|
||||
'transcript_download_format': u'srt',
|
||||
'transcript_download_format': 'srt',
|
||||
'transcript_download_formats_list': [
|
||||
{'display_name': 'SubRip (.srt) file', 'value': 'srt'},
|
||||
{'display_name': 'Text (.txt) file', 'value': 'txt'}
|
||||
@@ -2263,8 +2260,8 @@ class TestAutoAdvanceVideo(TestVideo): # lint-amnesty, pylint: disable=test-inh
|
||||
'license': None,
|
||||
'cdn_eval': False,
|
||||
'cdn_exp_group': None,
|
||||
'display_name': u'A Name',
|
||||
'download_video_link': u'example.mp4',
|
||||
'display_name': 'A Name',
|
||||
'download_video_link': 'example.mp4',
|
||||
'handout': None,
|
||||
'id': self.item_descriptor.location.html_id(),
|
||||
'bumper_metadata': 'null',
|
||||
@@ -2274,7 +2271,7 @@ class TestAutoAdvanceVideo(TestVideo): # lint-amnesty, pylint: disable=test-inh
|
||||
'saveStateUrl': self.item_descriptor.ajax_url + '/save_user_state',
|
||||
'autoplay': False,
|
||||
'streams': '0.75:jNCf2gIqpeE,1.00:ZwkTiUPN0mg,1.25:rsq9auxASqI,1.50:kMyNdzVHHgg',
|
||||
'sources': [u'example.mp4', u'example.webm'],
|
||||
'sources': ['example.mp4', 'example.webm'],
|
||||
'duration': None,
|
||||
'poster': None,
|
||||
'captionDataDir': None,
|
||||
@@ -2285,7 +2282,7 @@ class TestAutoAdvanceVideo(TestVideo): # lint-amnesty, pylint: disable=test-inh
|
||||
'start': 3603.0,
|
||||
'end': 3610.0,
|
||||
'transcriptLanguage': 'en',
|
||||
'transcriptLanguages': OrderedDict({'en': 'English', 'uk': u'Українська'}),
|
||||
'transcriptLanguages': OrderedDict({'en': 'English', 'uk': 'Українська'}),
|
||||
'ytMetadataEndpoint': '',
|
||||
'ytTestTimeout': 1500,
|
||||
'ytApiUrl': 'https://www.youtube.com/iframe_api',
|
||||
@@ -2304,7 +2301,7 @@ class TestAutoAdvanceVideo(TestVideo): # lint-amnesty, pylint: disable=test-inh
|
||||
'prioritizeHls': False,
|
||||
})),
|
||||
'track': None,
|
||||
'transcript_download_format': u'srt',
|
||||
'transcript_download_format': 'srt',
|
||||
'transcript_download_formats_list': [
|
||||
{'display_name': 'SubRip (.srt) file', 'value': 'srt'},
|
||||
{'display_name': 'Text (.txt) file', 'value': 'txt'}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# pylint: disable=protected-access
|
||||
|
||||
"""Test for Video Xmodule functional logic.
|
||||
|
||||
@@ -5,11 +5,9 @@ Check that view authentication works properly.
|
||||
|
||||
import datetime
|
||||
|
||||
from unittest.mock import patch
|
||||
import pytz
|
||||
from django.urls import reverse
|
||||
from mock import patch
|
||||
from six import text_type
|
||||
from six.moves import range
|
||||
|
||||
from lms.djangoapps.courseware.access import has_access
|
||||
from lms.djangoapps.courseware.tests.factories import (
|
||||
@@ -48,7 +46,7 @@ class TestViewAuth(EnterpriseTestConsentRequired, ModuleStoreTestCase, LoginEnro
|
||||
Returns a list URLs corresponding to section in the passed in course.
|
||||
|
||||
"""
|
||||
return [reverse(name, kwargs={'course_id': text_type(course.id)})
|
||||
return [reverse(name, kwargs={'course_id': str(course.id)})
|
||||
for name in names]
|
||||
|
||||
def _check_non_staff_light(self, course):
|
||||
@@ -57,7 +55,7 @@ class TestViewAuth(EnterpriseTestConsentRequired, ModuleStoreTestCase, LoginEnro
|
||||
|
||||
`course` is an instance of CourseBlock.
|
||||
"""
|
||||
urls = [reverse('about_course', kwargs={'course_id': text_type(course.id)}),
|
||||
urls = [reverse('about_course', kwargs={'course_id': str(course.id)}),
|
||||
reverse('courses')]
|
||||
for url in urls:
|
||||
self.assert_request_status_code(200, url)
|
||||
@@ -70,7 +68,7 @@ class TestViewAuth(EnterpriseTestConsentRequired, ModuleStoreTestCase, LoginEnro
|
||||
names = ['courseware', 'progress']
|
||||
urls = self._reverse_urls(names, course)
|
||||
urls.extend([
|
||||
reverse('book', kwargs={'course_id': text_type(course.id),
|
||||
reverse('book', kwargs={'course_id': str(course.id),
|
||||
'book_index': index})
|
||||
for index, __ in enumerate(course.textbooks)
|
||||
])
|
||||
@@ -78,7 +76,7 @@ class TestViewAuth(EnterpriseTestConsentRequired, ModuleStoreTestCase, LoginEnro
|
||||
self.assert_request_status_code(302, url)
|
||||
|
||||
self.assert_request_status_code(
|
||||
404, reverse('instructor_dashboard', kwargs={'course_id': text_type(course.id)})
|
||||
404, reverse('instructor_dashboard', kwargs={'course_id': str(course.id)})
|
||||
)
|
||||
|
||||
def _check_staff(self, course):
|
||||
@@ -88,7 +86,7 @@ class TestViewAuth(EnterpriseTestConsentRequired, ModuleStoreTestCase, LoginEnro
|
||||
names = ['about_course', 'instructor_dashboard', 'progress']
|
||||
urls = self._reverse_urls(names, course)
|
||||
urls.extend([
|
||||
reverse('book', kwargs={'course_id': text_type(course.id),
|
||||
reverse('book', kwargs={'course_id': str(course.id),
|
||||
'book_index': index})
|
||||
for index in range(len(course.textbooks))
|
||||
])
|
||||
@@ -104,7 +102,7 @@ class TestViewAuth(EnterpriseTestConsentRequired, ModuleStoreTestCase, LoginEnro
|
||||
url = reverse(
|
||||
'student_progress',
|
||||
kwargs={
|
||||
'course_id': text_type(course.id),
|
||||
'course_id': str(course.id),
|
||||
'student_id': self.enrolled_user.id,
|
||||
}
|
||||
)
|
||||
@@ -115,10 +113,10 @@ class TestViewAuth(EnterpriseTestConsentRequired, ModuleStoreTestCase, LoginEnro
|
||||
self.assert_request_status_code(302, url)
|
||||
|
||||
def login(self, user): # lint-amnesty, pylint: disable=arguments-differ
|
||||
return super(TestViewAuth, self).login(user.email, 'test') # lint-amnesty, pylint: disable=super-with-arguments
|
||||
return super().login(user.email, 'test')
|
||||
|
||||
def setUp(self):
|
||||
super(TestViewAuth, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
self.course = CourseFactory.create(number='999', display_name='Robot_Super_Course')
|
||||
self.courseware_chapter = ItemFactory.create(display_name='courseware')
|
||||
@@ -175,12 +173,12 @@ class TestViewAuth(EnterpriseTestConsentRequired, ModuleStoreTestCase, LoginEnro
|
||||
"""
|
||||
self.login(self.unenrolled_user)
|
||||
response = self.client.get(reverse('courseware',
|
||||
kwargs={'course_id': text_type(self.course.id)}))
|
||||
kwargs={'course_id': str(self.course.id)}))
|
||||
self.assertRedirects(
|
||||
response,
|
||||
reverse(
|
||||
'about_course',
|
||||
args=[text_type(self.course.id)]
|
||||
args=[str(self.course.id)]
|
||||
)
|
||||
)
|
||||
|
||||
@@ -194,7 +192,7 @@ class TestViewAuth(EnterpriseTestConsentRequired, ModuleStoreTestCase, LoginEnro
|
||||
response = self.client.get(
|
||||
reverse(
|
||||
'courseware',
|
||||
kwargs={'course_id': text_type(self.course.id)}
|
||||
kwargs={'course_id': str(self.course.id)}
|
||||
)
|
||||
)
|
||||
|
||||
@@ -202,7 +200,7 @@ class TestViewAuth(EnterpriseTestConsentRequired, ModuleStoreTestCase, LoginEnro
|
||||
response,
|
||||
reverse(
|
||||
'courseware_section',
|
||||
kwargs={'course_id': text_type(self.course.id),
|
||||
kwargs={'course_id': str(self.course.id),
|
||||
'chapter': self.overview_chapter.url_name,
|
||||
'section': self.welcome_section.url_name}
|
||||
)
|
||||
@@ -217,7 +215,7 @@ class TestViewAuth(EnterpriseTestConsentRequired, ModuleStoreTestCase, LoginEnro
|
||||
self.login(self.enrolled_user)
|
||||
url = reverse(
|
||||
'courseware',
|
||||
kwargs={'course_id': text_type(self.course.id)}
|
||||
kwargs={'course_id': str(self.course.id)}
|
||||
)
|
||||
self.verify_consent_required(self.client, url, status_code=302) # lint-amnesty, pylint: disable=no-value-for-parameter
|
||||
|
||||
@@ -228,8 +226,8 @@ class TestViewAuth(EnterpriseTestConsentRequired, ModuleStoreTestCase, LoginEnro
|
||||
"""
|
||||
self.login(self.enrolled_user)
|
||||
|
||||
urls = [reverse('instructor_dashboard', kwargs={'course_id': text_type(self.course.id)}),
|
||||
reverse('instructor_dashboard', kwargs={'course_id': text_type(self.test_course.id)})]
|
||||
urls = [reverse('instructor_dashboard', kwargs={'course_id': str(self.course.id)}),
|
||||
reverse('instructor_dashboard', kwargs={'course_id': str(self.test_course.id)})]
|
||||
|
||||
# Shouldn't be able to get to the instructor pages
|
||||
for url in urls:
|
||||
@@ -243,10 +241,10 @@ class TestViewAuth(EnterpriseTestConsentRequired, ModuleStoreTestCase, LoginEnro
|
||||
self.login(self.staff_user)
|
||||
|
||||
# Now should be able to get to self.course, but not self.test_course
|
||||
url = reverse('instructor_dashboard', kwargs={'course_id': text_type(self.course.id)})
|
||||
url = reverse('instructor_dashboard', kwargs={'course_id': str(self.course.id)})
|
||||
self.assert_request_status_code(200, url)
|
||||
|
||||
url = reverse('instructor_dashboard', kwargs={'course_id': text_type(self.test_course.id)})
|
||||
url = reverse('instructor_dashboard', kwargs={'course_id': str(self.test_course.id)})
|
||||
self.assert_request_status_code(404, url)
|
||||
|
||||
def test_instructor_course_access(self):
|
||||
@@ -257,10 +255,10 @@ class TestViewAuth(EnterpriseTestConsentRequired, ModuleStoreTestCase, LoginEnro
|
||||
self.login(self.instructor_user)
|
||||
|
||||
# Now should be able to get to self.course, but not self.test_course
|
||||
url = reverse('instructor_dashboard', kwargs={'course_id': text_type(self.course.id)})
|
||||
url = reverse('instructor_dashboard', kwargs={'course_id': str(self.course.id)})
|
||||
self.assert_request_status_code(200, url)
|
||||
|
||||
url = reverse('instructor_dashboard', kwargs={'course_id': text_type(self.test_course.id)})
|
||||
url = reverse('instructor_dashboard', kwargs={'course_id': str(self.test_course.id)})
|
||||
self.assert_request_status_code(404, url)
|
||||
|
||||
def test_org_staff_access(self):
|
||||
@@ -269,13 +267,13 @@ class TestViewAuth(EnterpriseTestConsentRequired, ModuleStoreTestCase, LoginEnro
|
||||
and student profile pages for course in their org.
|
||||
"""
|
||||
self.login(self.org_staff_user)
|
||||
url = reverse('instructor_dashboard', kwargs={'course_id': text_type(self.course.id)})
|
||||
url = reverse('instructor_dashboard', kwargs={'course_id': str(self.course.id)})
|
||||
self.assert_request_status_code(200, url)
|
||||
|
||||
url = reverse('instructor_dashboard', kwargs={'course_id': text_type(self.test_course.id)})
|
||||
url = reverse('instructor_dashboard', kwargs={'course_id': str(self.test_course.id)})
|
||||
self.assert_request_status_code(200, url)
|
||||
|
||||
url = reverse('instructor_dashboard', kwargs={'course_id': text_type(self.other_org_course.id)})
|
||||
url = reverse('instructor_dashboard', kwargs={'course_id': str(self.other_org_course.id)})
|
||||
self.assert_request_status_code(404, url)
|
||||
|
||||
def test_org_instructor_access(self):
|
||||
@@ -284,13 +282,13 @@ class TestViewAuth(EnterpriseTestConsentRequired, ModuleStoreTestCase, LoginEnro
|
||||
and student profile pages for course in their org.
|
||||
"""
|
||||
self.login(self.org_instructor_user)
|
||||
url = reverse('instructor_dashboard', kwargs={'course_id': text_type(self.course.id)})
|
||||
url = reverse('instructor_dashboard', kwargs={'course_id': str(self.course.id)})
|
||||
self.assert_request_status_code(200, url)
|
||||
|
||||
url = reverse('instructor_dashboard', kwargs={'course_id': text_type(self.test_course.id)})
|
||||
url = reverse('instructor_dashboard', kwargs={'course_id': str(self.test_course.id)})
|
||||
self.assert_request_status_code(200, url)
|
||||
|
||||
url = reverse('instructor_dashboard', kwargs={'course_id': text_type(self.other_org_course.id)})
|
||||
url = reverse('instructor_dashboard', kwargs={'course_id': str(self.other_org_course.id)})
|
||||
self.assert_request_status_code(404, url)
|
||||
|
||||
def test_global_staff_access(self):
|
||||
@@ -300,8 +298,8 @@ class TestViewAuth(EnterpriseTestConsentRequired, ModuleStoreTestCase, LoginEnro
|
||||
self.login(self.global_staff_user)
|
||||
|
||||
# and now should be able to load both
|
||||
urls = [reverse('instructor_dashboard', kwargs={'course_id': text_type(self.course.id)}),
|
||||
reverse('instructor_dashboard', kwargs={'course_id': text_type(self.test_course.id)})]
|
||||
urls = [reverse('instructor_dashboard', kwargs={'course_id': str(self.course.id)}),
|
||||
reverse('instructor_dashboard', kwargs={'course_id': str(self.test_course.id)})]
|
||||
|
||||
for url in urls:
|
||||
self.assert_request_status_code(200, url)
|
||||
@@ -420,7 +418,7 @@ class TestBetatesterAccess(ModuleStoreTestCase, CourseAccessTestMixin):
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(TestBetatesterAccess, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
now = datetime.datetime.now(pytz.UTC)
|
||||
tomorrow = now + datetime.timedelta(days=1)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# coding=UTF-8
|
||||
"""
|
||||
Tests courseware views.py
|
||||
"""
|
||||
@@ -10,8 +9,9 @@ import json
|
||||
from datetime import datetime, timedelta
|
||||
from uuid import uuid4
|
||||
|
||||
from unittest.mock import MagicMock, PropertyMock, call, create_autospec, patch
|
||||
from urllib.parse import quote, urlencode
|
||||
import ddt
|
||||
import six
|
||||
from completion.test_utils import CompletionWaffleTestMixin
|
||||
from crum import set_current_request
|
||||
from django.conf import settings
|
||||
@@ -24,13 +24,9 @@ from django.urls import reverse, reverse_lazy
|
||||
from edx_toggles.toggles.testutils import override_waffle_flag, override_waffle_switch
|
||||
from markupsafe import escape
|
||||
from milestones.tests.utils import MilestonesTestCaseMixin
|
||||
from mock import MagicMock, PropertyMock, call, create_autospec, patch
|
||||
from opaque_keys.edx.keys import CourseKey, UsageKey
|
||||
from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator
|
||||
from pytz import UTC, utc
|
||||
from six import text_type
|
||||
from six.moves import range
|
||||
from six.moves.urllib.parse import quote, urlencode
|
||||
from web_fragments.fragment import Fragment
|
||||
from xblock.core import XBlock
|
||||
from xblock.fields import Scope, String
|
||||
@@ -122,7 +118,7 @@ class TestJumpTo(ModuleStoreTestCase):
|
||||
MODULESTORE = TEST_DATA_MIXED_MODULESTORE
|
||||
|
||||
def setUp(self):
|
||||
super(TestJumpTo, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
# Use toy course from XML
|
||||
self.course_key = CourseKey.from_string('edX/toy/2012_Fall')
|
||||
|
||||
@@ -130,7 +126,7 @@ class TestJumpTo(ModuleStoreTestCase):
|
||||
location = self.course_key.make_usage_key(None, 'NoSuchPlace')
|
||||
# This is fragile, but unfortunately the problem is that within the LMS we
|
||||
# can't use the reverse calls from the CMS
|
||||
jumpto_url = '{0}/{1}/jump_to/{2}'.format('/courses', six.text_type(self.course_key), six.text_type(location))
|
||||
jumpto_url = '{}/{}/jump_to/{}'.format('/courses', str(self.course_key), str(location))
|
||||
response = self.client.get(jumpto_url)
|
||||
assert response.status_code == 404
|
||||
|
||||
@@ -139,15 +135,15 @@ class TestJumpTo(ModuleStoreTestCase):
|
||||
chapter = ItemFactory.create(category='chapter', parent_location=course.location)
|
||||
section = ItemFactory.create(category='sequential', parent_location=chapter.location)
|
||||
expected = '/courses/{course_id}/courseware/{chapter_id}/{section_id}/?{activate_block_id}'.format(
|
||||
course_id=six.text_type(course.id),
|
||||
course_id=str(course.id),
|
||||
chapter_id=chapter.url_name,
|
||||
section_id=section.url_name,
|
||||
activate_block_id=urlencode({'activate_block_id': six.text_type(section.location)})
|
||||
activate_block_id=urlencode({'activate_block_id': str(section.location)})
|
||||
)
|
||||
jumpto_url = '{0}/{1}/jump_to/{2}'.format(
|
||||
jumpto_url = '{}/{}/jump_to/{}'.format(
|
||||
'/courses',
|
||||
six.text_type(course.id),
|
||||
six.text_type(section.location),
|
||||
str(course.id),
|
||||
str(section.location),
|
||||
)
|
||||
response = self.client.get(jumpto_url)
|
||||
self.assertRedirects(response, expected, status_code=302, target_status_code=302)
|
||||
@@ -162,29 +158,29 @@ class TestJumpTo(ModuleStoreTestCase):
|
||||
module2 = ItemFactory.create(category='html', parent_location=vertical2.location)
|
||||
|
||||
expected = '/courses/{course_id}/courseware/{chapter_id}/{section_id}/1?{activate_block_id}'.format(
|
||||
course_id=six.text_type(course.id),
|
||||
course_id=str(course.id),
|
||||
chapter_id=chapter.url_name,
|
||||
section_id=section.url_name,
|
||||
activate_block_id=urlencode({'activate_block_id': six.text_type(module1.location)})
|
||||
activate_block_id=urlencode({'activate_block_id': str(module1.location)})
|
||||
)
|
||||
jumpto_url = '{0}/{1}/jump_to/{2}'.format(
|
||||
jumpto_url = '{}/{}/jump_to/{}'.format(
|
||||
'/courses',
|
||||
six.text_type(course.id),
|
||||
six.text_type(module1.location),
|
||||
str(course.id),
|
||||
str(module1.location),
|
||||
)
|
||||
response = self.client.get(jumpto_url)
|
||||
self.assertRedirects(response, expected, status_code=302, target_status_code=302)
|
||||
|
||||
expected = '/courses/{course_id}/courseware/{chapter_id}/{section_id}/2?{activate_block_id}'.format(
|
||||
course_id=six.text_type(course.id),
|
||||
course_id=str(course.id),
|
||||
chapter_id=chapter.url_name,
|
||||
section_id=section.url_name,
|
||||
activate_block_id=urlencode({'activate_block_id': six.text_type(module2.location)})
|
||||
activate_block_id=urlencode({'activate_block_id': str(module2.location)})
|
||||
)
|
||||
jumpto_url = '{0}/{1}/jump_to/{2}'.format(
|
||||
jumpto_url = '{}/{}/jump_to/{}'.format(
|
||||
'/courses',
|
||||
six.text_type(course.id),
|
||||
six.text_type(module2.location),
|
||||
str(course.id),
|
||||
str(module2.location),
|
||||
)
|
||||
response = self.client.get(jumpto_url)
|
||||
self.assertRedirects(response, expected, status_code=302, target_status_code=302)
|
||||
@@ -203,15 +199,15 @@ class TestJumpTo(ModuleStoreTestCase):
|
||||
|
||||
# internal position of module2 will be 1_2 (2nd item withing 1st item)
|
||||
expected = '/courses/{course_id}/courseware/{chapter_id}/{section_id}/1?{activate_block_id}'.format(
|
||||
course_id=six.text_type(course.id),
|
||||
course_id=str(course.id),
|
||||
chapter_id=chapter.url_name,
|
||||
section_id=section.url_name,
|
||||
activate_block_id=urlencode({'activate_block_id': six.text_type(module2.location)})
|
||||
activate_block_id=urlencode({'activate_block_id': str(module2.location)})
|
||||
)
|
||||
jumpto_url = '{0}/{1}/jump_to/{2}'.format(
|
||||
jumpto_url = '{}/{}/jump_to/{}'.format(
|
||||
'/courses',
|
||||
six.text_type(course.id),
|
||||
six.text_type(module2.location),
|
||||
str(course.id),
|
||||
str(module2.location),
|
||||
)
|
||||
response = self.client.get(jumpto_url)
|
||||
self.assertRedirects(response, expected, status_code=302, target_status_code=302)
|
||||
@@ -219,9 +215,7 @@ class TestJumpTo(ModuleStoreTestCase):
|
||||
def test_jumpto_id_invalid_location(self):
|
||||
location = BlockUsageLocator(CourseLocator('edX', 'toy', 'NoSuchPlace', deprecated=True),
|
||||
None, None, deprecated=True)
|
||||
jumpto_url = '{0}/{1}/jump_to_id/{2}'.format('/courses',
|
||||
six.text_type(self.course_key),
|
||||
six.text_type(location))
|
||||
jumpto_url = '{}/{}/jump_to_id/{}'.format('/courses', str(self.course_key), str(location))
|
||||
response = self.client.get(jumpto_url)
|
||||
assert response.status_code == 404
|
||||
|
||||
@@ -238,7 +232,7 @@ class TestJumpTo(ModuleStoreTestCase):
|
||||
request = RequestFactory().get('/')
|
||||
request.user = UserFactory(is_staff=is_staff_user, username="staff")
|
||||
request.session = {}
|
||||
course_key = CourseKey.from_string(six.text_type(course.id))
|
||||
course_key = CourseKey.from_string(str(course.id))
|
||||
chapter = ItemFactory.create(category='chapter', parent_location=course.location)
|
||||
section = ItemFactory.create(category='sequential', parent_location=chapter.location)
|
||||
__ = ItemFactory.create(category='vertical', parent_location=section.location)
|
||||
@@ -246,17 +240,17 @@ class TestJumpTo(ModuleStoreTestCase):
|
||||
metadata=dict(visible_to_staff_only=True))
|
||||
__ = ItemFactory.create(category='vertical', parent_location=section.location)
|
||||
|
||||
usage_key = UsageKey.from_string(six.text_type(staff_only_vertical.location)).replace(course_key=course_key)
|
||||
usage_key = UsageKey.from_string(str(staff_only_vertical.location)).replace(course_key=course_key)
|
||||
expected_url = reverse(
|
||||
'courseware_position',
|
||||
kwargs={
|
||||
'course_id': six.text_type(course.id),
|
||||
'course_id': str(course.id),
|
||||
'chapter': chapter.url_name,
|
||||
'section': section.url_name,
|
||||
'position': position,
|
||||
}
|
||||
)
|
||||
expected_url += "?{}".format(urlencode({'activate_block_id': six.text_type(staff_only_vertical.location)}))
|
||||
expected_url += "?{}".format(urlencode({'activate_block_id': str(staff_only_vertical.location)}))
|
||||
|
||||
assert expected_url == get_legacy_courseware_url(usage_key, request)
|
||||
|
||||
@@ -295,9 +289,9 @@ class IndexQueryTestCase(ModuleStoreTestCase):
|
||||
url = reverse(
|
||||
'courseware_section',
|
||||
kwargs={
|
||||
'course_id': six.text_type(course.id),
|
||||
'chapter': six.text_type(chapter.location.block_id),
|
||||
'section': six.text_type(section.location.block_id),
|
||||
'course_id': str(course.id),
|
||||
'chapter': str(chapter.location.block_id),
|
||||
'section': str(section.location.block_id),
|
||||
}
|
||||
)
|
||||
response = self.client.get(url)
|
||||
@@ -306,8 +300,8 @@ class IndexQueryTestCase(ModuleStoreTestCase):
|
||||
|
||||
class BaseViewsTestCase(ModuleStoreTestCase): # lint-amnesty, pylint: disable=missing-class-docstring
|
||||
def setUp(self):
|
||||
super(BaseViewsTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
self.course = CourseFactory.create(display_name=u'teꜱᴛ course', run="Testing_course")
|
||||
super().setUp()
|
||||
self.course = CourseFactory.create(display_name='teꜱᴛ course', run="Testing_course")
|
||||
with self.store.bulk_operations(self.course.id):
|
||||
self.chapter = ItemFactory.create(
|
||||
category='chapter',
|
||||
@@ -356,9 +350,9 @@ class BaseViewsTestCase(ModuleStoreTestCase): # lint-amnesty, pylint: disable=m
|
||||
self.enrollment.created = self.date
|
||||
self.enrollment.save()
|
||||
chapter = 'Overview'
|
||||
self.chapter_url = '%s/%s/%s' % ('/courses', self.course_key, chapter)
|
||||
self.chapter_url = '{}/{}/{}'.format('/courses', self.course_key, chapter)
|
||||
|
||||
self.org = u"ꜱᴛᴀʀᴋ ɪɴᴅᴜꜱᴛʀɪᴇꜱ"
|
||||
self.org = "ꜱᴛᴀʀᴋ ɪɴᴅᴜꜱᴛʀɪᴇꜱ"
|
||||
self.org_html = "<p>'+Stark/Industries+'</p>"
|
||||
|
||||
assert self.client.login(username=self.user.username, password=TEST_PASSWORD)
|
||||
@@ -390,7 +384,7 @@ class ViewsTestCase(BaseViewsTestCase):
|
||||
self.assertContains(response, self.problem2.location)
|
||||
|
||||
# re-access to the main course page redirects to last accessed view.
|
||||
url = reverse('courseware', kwargs={'course_id': six.text_type(self.course_key)})
|
||||
url = reverse('courseware', kwargs={'course_id': str(self.course_key)})
|
||||
response = self.client.get(url)
|
||||
assert response.status_code == 302
|
||||
response = self.client.get(response.url)
|
||||
@@ -423,9 +417,9 @@ class ViewsTestCase(BaseViewsTestCase):
|
||||
url = reverse(
|
||||
'courseware_section',
|
||||
kwargs={
|
||||
'course_id': six.text_type(self.course_key),
|
||||
'chapter': six.text_type(self.chapter.location.block_id) if chapter_name is None else chapter_name,
|
||||
'section': six.text_type(self.section2.location.block_id) if section_name is None else section_name,
|
||||
'course_id': str(self.course_key),
|
||||
'chapter': str(self.chapter.location.block_id) if chapter_name is None else chapter_name,
|
||||
'section': str(self.section2.location.block_id) if section_name is None else section_name,
|
||||
}
|
||||
)
|
||||
response = self.client.get(url)
|
||||
@@ -444,8 +438,8 @@ class ViewsTestCase(BaseViewsTestCase):
|
||||
|
||||
url = reverse(
|
||||
'courseware_chapter',
|
||||
kwargs={'course_id': six.text_type(self.course.id),
|
||||
'chapter': six.text_type(self.chapter.location.block_id)},
|
||||
kwargs={'course_id': str(self.course.id),
|
||||
'chapter': str(self.chapter.location.block_id)},
|
||||
)
|
||||
response = self.client.get(url)
|
||||
assert response.status_code == 200
|
||||
@@ -460,14 +454,14 @@ class ViewsTestCase(BaseViewsTestCase):
|
||||
courseware_url = reverse(
|
||||
'courseware_section',
|
||||
kwargs={
|
||||
'course_id': six.text_type(self.course_key),
|
||||
'chapter': six.text_type(self.chapter.location.block_id),
|
||||
'section': six.text_type(self.section.location.block_id),
|
||||
'course_id': str(self.course_key),
|
||||
'chapter': str(self.chapter.location.block_id),
|
||||
'section': str(self.section.location.block_id),
|
||||
}
|
||||
)
|
||||
# create the url for enroll_staff view
|
||||
enroll_url = "{enroll_url}?next={courseware_url}".format(
|
||||
enroll_url=reverse('enroll_staff', kwargs={'course_id': six.text_type(self.course.id)}),
|
||||
enroll_url=reverse('enroll_staff', kwargs={'course_id': str(self.course.id)}),
|
||||
courseware_url=courseware_url
|
||||
)
|
||||
return courseware_url, enroll_url
|
||||
@@ -491,7 +485,7 @@ class ViewsTestCase(BaseViewsTestCase):
|
||||
if enrollment:
|
||||
self.assertRedirects(response, courseware_url)
|
||||
else:
|
||||
self.assertRedirects(response, '/courses/{}/about'.format(six.text_type(self.course_key)))
|
||||
self.assertRedirects(response, '/courses/{}/about'.format(str(self.course_key)))
|
||||
|
||||
def test_enroll_staff_with_invalid_data(self):
|
||||
"""
|
||||
@@ -502,7 +496,7 @@ class ViewsTestCase(BaseViewsTestCase):
|
||||
__, enroll_url = self._create_url_for_enroll_staff()
|
||||
response = self.client.post(enroll_url, data={'test': "test"})
|
||||
assert response.status_code == 302
|
||||
self.assertRedirects(response, '/courses/{}/about'.format(six.text_type(self.course_key)))
|
||||
self.assertRedirects(response, '/courses/{}/about'.format(str(self.course_key)))
|
||||
|
||||
def assert_enrollment_link_present(self, is_anonymous):
|
||||
"""
|
||||
@@ -524,13 +518,13 @@ class ViewsTestCase(BaseViewsTestCase):
|
||||
# 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 = u'<a href="{uri_stem}?sku={sku}" class="add-to-cart">'.format(
|
||||
href = '<a href="{uri_stem}?sku={sku}" class="add-to-cart">'.format(
|
||||
uri_stem=configuration.basket_checkout_page,
|
||||
sku=sku,
|
||||
)
|
||||
|
||||
# Generate the course about page content
|
||||
response = self.client.get(reverse('about_course', args=[six.text_type(course.id)]))
|
||||
response = self.client.get(reverse('about_course', args=[str(course.id)]))
|
||||
self.assertContains(response, href)
|
||||
|
||||
@ddt.data(True, False)
|
||||
@@ -548,9 +542,9 @@ class ViewsTestCase(BaseViewsTestCase):
|
||||
|
||||
def test_get_redirect_url(self):
|
||||
# test the course location
|
||||
assert u'/courses/{course_key}/courseware?{activate_block_id}'.format(course_key=text_type(self.course_key), activate_block_id=urlencode({'activate_block_id': text_type(self.course.location)})) == get_legacy_courseware_url(self.course.location) # pylint: disable=line-too-long
|
||||
assert '/courses/{course_key}/courseware?{activate_block_id}'.format(course_key=str(self.course_key), activate_block_id=urlencode({'activate_block_id': str(self.course.location)})) == get_legacy_courseware_url(self.course.location) # pylint: disable=line-too-long
|
||||
# test a section location
|
||||
assert u'/courses/{course_key}/courseware/Chapter_1/Sequential_1/?{activate_block_id}'.format(course_key=text_type(self.course_key), activate_block_id=urlencode({'activate_block_id': text_type(self.section.location)})) == get_legacy_courseware_url(self.section.location) # pylint: disable=line-too-long
|
||||
assert '/courses/{course_key}/courseware/Chapter_1/Sequential_1/?{activate_block_id}'.format(course_key=str(self.course_key), activate_block_id=urlencode({'activate_block_id': str(self.section.location)})) == get_legacy_courseware_url(self.section.location) # pylint: disable=line-too-long
|
||||
|
||||
def test_invalid_course_id(self):
|
||||
response = self.client.get('/courses/MITx/3.091X/')
|
||||
@@ -563,7 +557,7 @@ class ViewsTestCase(BaseViewsTestCase):
|
||||
def test_index_invalid_position(self):
|
||||
request_url = '/'.join([
|
||||
'/courses',
|
||||
six.text_type(self.course.id),
|
||||
str(self.course.id),
|
||||
'courseware',
|
||||
self.chapter.location.block_id,
|
||||
self.section.location.block_id,
|
||||
@@ -576,7 +570,7 @@ class ViewsTestCase(BaseViewsTestCase):
|
||||
def test_unicode_handling_in_url(self):
|
||||
url_parts = [
|
||||
'/courses',
|
||||
six.text_type(self.course.id),
|
||||
str(self.course.id),
|
||||
'courseware',
|
||||
self.chapter.location.block_id,
|
||||
self.section.location.block_id,
|
||||
@@ -585,7 +579,7 @@ class ViewsTestCase(BaseViewsTestCase):
|
||||
assert self.client.login(username=self.user.username, password=TEST_PASSWORD)
|
||||
for idx, val in enumerate(url_parts):
|
||||
url_parts_copy = url_parts[:]
|
||||
url_parts_copy[idx] = val + u'χ'
|
||||
url_parts_copy[idx] = val + 'χ'
|
||||
request_url = '/'.join(url_parts_copy)
|
||||
response = self.client.get(request_url)
|
||||
assert response.status_code == 404
|
||||
@@ -603,7 +597,7 @@ class ViewsTestCase(BaseViewsTestCase):
|
||||
If `expected_end_text` is None, verifies that the about page *does not* contain the text
|
||||
"Classes End".
|
||||
"""
|
||||
result = self.client.get(reverse('about_course', args=[six.text_type(course_id)]))
|
||||
result = self.client.get(reverse('about_course', args=[str(course_id)]))
|
||||
if expected_end_text is not None:
|
||||
self.assertContains(result, "Classes End")
|
||||
self.assertContains(result, expected_end_text)
|
||||
@@ -617,9 +611,9 @@ class ViewsTestCase(BaseViewsTestCase):
|
||||
assert self.client.login(username=admin.username, password='test')
|
||||
|
||||
url = reverse('submission_history', kwargs={
|
||||
'course_id': six.text_type(self.course_key),
|
||||
'course_id': str(self.course_key),
|
||||
'student_username': 'dummy',
|
||||
'location': six.text_type(self.problem.location),
|
||||
'location': str(self.problem.location),
|
||||
})
|
||||
response = self.client.get(url)
|
||||
# Tests that we do not get an "Invalid x" response when passing correct arguments to view
|
||||
@@ -633,7 +627,7 @@ class ViewsTestCase(BaseViewsTestCase):
|
||||
|
||||
# try it with an existing user and a malicious location
|
||||
url = reverse('submission_history', kwargs={
|
||||
'course_id': six.text_type(self.course_key),
|
||||
'course_id': str(self.course_key),
|
||||
'student_username': 'dummy',
|
||||
'location': '<script>alert("hello");</script>'
|
||||
})
|
||||
@@ -642,7 +636,7 @@ class ViewsTestCase(BaseViewsTestCase):
|
||||
|
||||
# try it with a malicious user and a non-existent location
|
||||
url = reverse('submission_history', kwargs={
|
||||
'course_id': six.text_type(self.course_key),
|
||||
'course_id': str(self.course_key),
|
||||
'student_username': '<script>alert("hello");</script>',
|
||||
'location': 'dummy'
|
||||
})
|
||||
@@ -675,9 +669,9 @@ class ViewsTestCase(BaseViewsTestCase):
|
||||
set_score(admin.id, usage_key, 3, 3)
|
||||
|
||||
url = reverse('submission_history', kwargs={
|
||||
'course_id': six.text_type(self.course_key),
|
||||
'course_id': str(self.course_key),
|
||||
'student_username': admin.username,
|
||||
'location': six.text_type(usage_key),
|
||||
'location': str(usage_key),
|
||||
})
|
||||
response = self.client.get(url)
|
||||
response_content = html.unescape(response.content.decode('utf-8'))
|
||||
@@ -716,9 +710,9 @@ class ViewsTestCase(BaseViewsTestCase):
|
||||
state={'field_a': 'x', 'field_b': 'y'}
|
||||
)
|
||||
url = reverse('submission_history', kwargs={
|
||||
'course_id': six.text_type(course_key),
|
||||
'course_id': str(course_key),
|
||||
'student_username': admin.username,
|
||||
'location': six.text_type(usage_key),
|
||||
'location': str(usage_key),
|
||||
})
|
||||
response = client.get(url)
|
||||
expected_time = datetime.now() + timedelta(hours=hour_diff)
|
||||
@@ -812,7 +806,7 @@ class ViewsTestCase(BaseViewsTestCase):
|
||||
@patch.object(views, 'create_zendesk_ticket', return_value=200)
|
||||
def test_submit_financial_assistance_request(self, mock_create_zendesk_ticket):
|
||||
username = self.user.username
|
||||
course = six.text_type(self.course_key)
|
||||
course = str(self.course_key)
|
||||
legal_name = 'Jesse Pinkman'
|
||||
country = 'United States'
|
||||
income = '1234567890'
|
||||
@@ -846,7 +840,7 @@ class ViewsTestCase(BaseViewsTestCase):
|
||||
|
||||
assert additional_info['Allowed for marketing purposes'] == 'No'
|
||||
|
||||
assert ticket_subject == u'Financial assistance request for learner {username} in course {course}'.format(username=username, course=self.course.display_name) # pylint: disable=line-too-long
|
||||
assert ticket_subject == f'Financial assistance request for learner {username} in course {self.course.display_name}' # pylint: disable=line-too-long
|
||||
self.assertDictContainsSubset({'course_id': course}, tags)
|
||||
assert 'Client IP' in additional_info
|
||||
assert group_name == 'Financial Assistance'
|
||||
@@ -855,7 +849,7 @@ class ViewsTestCase(BaseViewsTestCase):
|
||||
def test_zendesk_submission_failed(self, _mock_create_zendesk_ticket):
|
||||
response = self._submit_financial_assistance_form({
|
||||
'username': self.user.username,
|
||||
'course': six.text_type(self.course.id),
|
||||
'course': str(self.course.id),
|
||||
'name': '',
|
||||
'email': '',
|
||||
'country': '',
|
||||
@@ -889,7 +883,7 @@ class ViewsTestCase(BaseViewsTestCase):
|
||||
|
||||
@override_waffle_flag(DISABLE_UNIFIED_COURSE_TAB_FLAG, active=True)
|
||||
def test_bypass_course_info(self):
|
||||
course_id = six.text_type(self.course_key)
|
||||
course_id = str(self.course_key)
|
||||
|
||||
response = self.client.get(reverse('info', args=[course_id]))
|
||||
assert response.status_code == 200
|
||||
@@ -908,9 +902,9 @@ class ViewsTestCase(BaseViewsTestCase):
|
||||
returning a render_to_string, so we will render via the courseware URL in order to include
|
||||
the needed context
|
||||
"""
|
||||
course_id = quote(six.text_type(self.course.id).encode("utf-8"))
|
||||
course_id = quote(str(self.course.id).encode("utf-8"))
|
||||
response = self.client.get(
|
||||
reverse('courseware', args=[six.text_type(course_id)]),
|
||||
reverse('courseware', args=[str(course_id)]),
|
||||
follow=True
|
||||
)
|
||||
test_responses = [
|
||||
@@ -931,10 +925,10 @@ class TestProgramMarketingView(SharedModuleStoreTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestProgramMarketingView, cls).setUpClass()
|
||||
super().setUpClass()
|
||||
|
||||
modulestore_course = CourseFactory()
|
||||
course_run = CourseRunFactory(key=six.text_type(modulestore_course.id)) # lint-amnesty, pylint: disable=no-member
|
||||
course_run = CourseRunFactory(key=str(modulestore_course.id)) # lint-amnesty, pylint: disable=no-member
|
||||
course = CatalogCourseFactory(course_runs=[course_run])
|
||||
|
||||
cls.data = ProgramFactory(
|
||||
@@ -998,7 +992,7 @@ class BaseDueDateTests(ModuleStoreTestCase):
|
||||
return course
|
||||
|
||||
def setUp(self):
|
||||
super(BaseDueDateTests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.user = UserFactory.create()
|
||||
assert self.client.login(username=self.user.username, password='test')
|
||||
|
||||
@@ -1028,14 +1022,14 @@ class BaseDueDateTests(ModuleStoreTestCase):
|
||||
|
||||
def test_format_date(self):
|
||||
# due date with no time
|
||||
course = self.set_up_course(due_date_display_format=u"%b %d %y")
|
||||
course = self.set_up_course(due_date_display_format="%b %d %y")
|
||||
response = self.get_response(course)
|
||||
self.assertContains(response, self.time_with_tz)
|
||||
|
||||
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)
|
||||
course = self.set_up_course(due_date_display_format="%%%", show_timezone=False)
|
||||
response = self.get_response(course)
|
||||
self.assertNotContains(response, "%%%")
|
||||
self.assertContains(response, self.time_with_tz)
|
||||
@@ -1049,7 +1043,7 @@ class TestProgressDueDate(BaseDueDateTests):
|
||||
|
||||
def get_response(self, course):
|
||||
""" Returns the HTML for the progress page """
|
||||
return self.client.get(reverse('progress', args=[six.text_type(course.id)]))
|
||||
return self.client.get(reverse('progress', args=[str(course.id)]))
|
||||
|
||||
|
||||
# TODO: LEARNER-71: Delete entire TestAccordionDueDate class
|
||||
@@ -1062,34 +1056,34 @@ class TestAccordionDueDate(BaseDueDateTests):
|
||||
def get_response(self, course):
|
||||
""" Returns the HTML for the accordion """
|
||||
return self.client.get(
|
||||
reverse('courseware', args=[six.text_type(course.id)]),
|
||||
reverse('courseware', args=[str(course.id)]),
|
||||
follow=True
|
||||
)
|
||||
|
||||
# TODO: LEARNER-71: Delete entire TestAccordionDueDate class
|
||||
@override_waffle_flag(DISABLE_COURSE_OUTLINE_PAGE_FLAG, active=True)
|
||||
def test_backwards_compatibility(self):
|
||||
super(TestAccordionDueDate, self).test_backwards_compatibility() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().test_backwards_compatibility()
|
||||
|
||||
# TODO: LEARNER-71: Delete entire TestAccordionDueDate class
|
||||
@override_waffle_flag(DISABLE_COURSE_OUTLINE_PAGE_FLAG, active=True)
|
||||
def test_defaults(self):
|
||||
super(TestAccordionDueDate, self).test_defaults() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().test_defaults()
|
||||
|
||||
# TODO: LEARNER-71: Delete entire TestAccordionDueDate class
|
||||
@override_waffle_flag(DISABLE_COURSE_OUTLINE_PAGE_FLAG, active=True)
|
||||
def test_format_date(self):
|
||||
super(TestAccordionDueDate, self).test_format_date() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().test_format_date()
|
||||
|
||||
# TODO: LEARNER-71: Delete entire TestAccordionDueDate class
|
||||
@override_waffle_flag(DISABLE_COURSE_OUTLINE_PAGE_FLAG, active=True)
|
||||
def test_format_invalid(self):
|
||||
super(TestAccordionDueDate, self).test_format_invalid() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().test_format_invalid()
|
||||
|
||||
# TODO: LEARNER-71: Delete entire TestAccordionDueDate class
|
||||
@override_waffle_flag(DISABLE_COURSE_OUTLINE_PAGE_FLAG, active=True)
|
||||
def test_format_none(self):
|
||||
super(TestAccordionDueDate, self).test_format_none() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().test_format_none()
|
||||
|
||||
|
||||
class StartDateTests(ModuleStoreTestCase):
|
||||
@@ -1099,7 +1093,7 @@ class StartDateTests(ModuleStoreTestCase):
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(StartDateTests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.user = UserFactory.create()
|
||||
|
||||
def set_up_course(self):
|
||||
@@ -1115,7 +1109,7 @@ class StartDateTests(ModuleStoreTestCase):
|
||||
"""
|
||||
Get the text of the /about page for the course.
|
||||
"""
|
||||
return self.client.get(reverse('about_course', args=[six.text_type(course_key)]))
|
||||
return self.client.get(reverse('about_course', args=[str(course_key)]))
|
||||
|
||||
@patch('common.djangoapps.util.date_utils.pgettext', fake_pgettext(translations={
|
||||
("abbreviated month name", "Sep"): "SEPTEMBER",
|
||||
@@ -1140,7 +1134,7 @@ class ProgressPageBaseTests(ModuleStoreTestCase):
|
||||
ENABLED_SIGNALS = ['course_published']
|
||||
|
||||
def setUp(self):
|
||||
super(ProgressPageBaseTests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.user = UserFactory.create()
|
||||
assert self.client.login(username=self.user.username, password='test')
|
||||
|
||||
@@ -1150,7 +1144,7 @@ class ProgressPageBaseTests(ModuleStoreTestCase):
|
||||
"""Create the test course."""
|
||||
self.course = CourseFactory.create( # lint-amnesty, pylint: disable=attribute-defined-outside-init
|
||||
start=datetime(2013, 9, 16, 7, 17, 28),
|
||||
grade_cutoffs={u'çü†øƒƒ': 0.75, 'Pass': 0.5},
|
||||
grade_cutoffs={'çü†øƒƒ': 0.75, 'Pass': 0.5},
|
||||
end=datetime.now(),
|
||||
certificate_available_date=datetime.now(UTC),
|
||||
**options
|
||||
@@ -1171,7 +1165,7 @@ class ProgressPageBaseTests(ModuleStoreTestCase):
|
||||
Gets the progress page for the currently logged-in user.
|
||||
"""
|
||||
resp = self.client.get(
|
||||
reverse('progress', args=[six.text_type(self.course.id)])
|
||||
reverse('progress', args=[str(self.course.id)])
|
||||
)
|
||||
assert resp.status_code == expected_status_code
|
||||
return resp
|
||||
@@ -1181,7 +1175,7 @@ class ProgressPageBaseTests(ModuleStoreTestCase):
|
||||
Gets the progress page for the user in the course.
|
||||
"""
|
||||
resp = self.client.get(
|
||||
reverse('student_progress', args=[six.text_type(self.course.id), self.user.id])
|
||||
reverse('student_progress', args=[str(self.course.id), self.user.id])
|
||||
)
|
||||
assert resp.status_code == expected_status_code
|
||||
return resp
|
||||
@@ -1227,7 +1221,7 @@ class ProgressPageTests(ProgressPageBaseTests):
|
||||
for invalid_id in invalid_student_ids:
|
||||
|
||||
resp = self.client.get(
|
||||
reverse('student_progress', args=[six.text_type(self.course.id), invalid_id])
|
||||
reverse('student_progress', args=[str(self.course.id), invalid_id])
|
||||
)
|
||||
assert resp.status_code == 404
|
||||
|
||||
@@ -1315,8 +1309,8 @@ class ProgressPageTests(ProgressPageBaseTests):
|
||||
course_grade.summary = {'grade': 'Pass', 'percent': 0.75, 'section_breakdown': [],
|
||||
'grade_breakdown': {}}
|
||||
resp = self._get_progress_page()
|
||||
self.assertNotContains(resp, u"Certificate unavailable")
|
||||
self.assertContains(resp, u"Your certificate is available")
|
||||
self.assertNotContains(resp, "Certificate unavailable")
|
||||
self.assertContains(resp, "Your certificate is available")
|
||||
|
||||
@patch.dict('django.conf.settings.FEATURES', {'CERTIFICATES_HTML_VIEW': True})
|
||||
def test_view_certificate_link(self):
|
||||
@@ -1363,9 +1357,9 @@ class ProgressPageTests(ProgressPageBaseTests):
|
||||
|
||||
resp = self._get_progress_page()
|
||||
|
||||
self.assertContains(resp, u"View Certificate")
|
||||
self.assertContains(resp, "View Certificate")
|
||||
|
||||
self.assertContains(resp, u"earned a certificate for this course")
|
||||
self.assertContains(resp, "earned a certificate for this course")
|
||||
cert_url = certs_api.get_certificate_url(course_id=self.course.id, uuid=certificate.verify_uuid)
|
||||
self.assertContains(resp, cert_url)
|
||||
|
||||
@@ -1374,8 +1368,8 @@ class ProgressPageTests(ProgressPageBaseTests):
|
||||
self.store.update_item(self.course, self.user.id)
|
||||
|
||||
resp = self._get_progress_page()
|
||||
self.assertNotContains(resp, u"View Your Certificate")
|
||||
self.assertNotContains(resp, u"You can now view your certificate")
|
||||
self.assertNotContains(resp, "View Your Certificate")
|
||||
self.assertNotContains(resp, "You can now view your certificate")
|
||||
self.assertContains(resp, "Your certificate is available")
|
||||
self.assertContains(resp, "earned a certificate for this course.")
|
||||
|
||||
@@ -1405,7 +1399,7 @@ class ProgressPageTests(ProgressPageBaseTests):
|
||||
course_grade.summary = {'grade': 'Pass', 'percent': 0.75, 'section_breakdown': [], 'grade_breakdown': {}}
|
||||
|
||||
resp = self._get_progress_page()
|
||||
self.assertContains(resp, u"Download Your Certificate")
|
||||
self.assertContains(resp, "Download Your Certificate")
|
||||
|
||||
@ddt.data(
|
||||
(True, 54),
|
||||
@@ -1514,7 +1508,7 @@ class ProgressPageTests(ProgressPageBaseTests):
|
||||
}
|
||||
|
||||
resp = self._get_progress_page()
|
||||
self.assertContains(resp, u"View Certificate")
|
||||
self.assertContains(resp, "View Certificate")
|
||||
self.assert_invalidate_certificate(generated_certificate)
|
||||
|
||||
@patch.dict('django.conf.settings.FEATURES', {'CERTIFICATES_HTML_VIEW': True})
|
||||
@@ -1557,7 +1551,7 @@ class ProgressPageTests(ProgressPageBaseTests):
|
||||
}
|
||||
|
||||
resp = self._get_progress_page()
|
||||
self.assertContains(resp, u"View Certificate")
|
||||
self.assertContains(resp, "View Certificate")
|
||||
self.assert_invalidate_certificate(generated_certificate)
|
||||
|
||||
def test_page_with_invalidated_certificate_with_pdf(self):
|
||||
@@ -1575,7 +1569,7 @@ class ProgressPageTests(ProgressPageBaseTests):
|
||||
course_grade.summary = {'grade': 'Pass', 'percent': 0.75, 'section_breakdown': [], 'grade_breakdown': {}}
|
||||
|
||||
resp = self._get_progress_page()
|
||||
self.assertContains(resp, u'Download Your Certificate')
|
||||
self.assertContains(resp, 'Download Your Certificate')
|
||||
self.assert_invalidate_certificate(generated_certificate)
|
||||
|
||||
@ddt.data(
|
||||
@@ -1660,8 +1654,8 @@ class ProgressPageTests(ProgressPageBaseTests):
|
||||
|
||||
response = self._get_progress_page()
|
||||
|
||||
expected_message = (u'You are enrolled in the {mode} track for this course. '
|
||||
u'The {mode} track does not include a certificate.').format(mode=course_mode)
|
||||
expected_message = ('You are enrolled in the {mode} track for this course. '
|
||||
'The {mode} track does not include a certificate.').format(mode=course_mode)
|
||||
self.assertContains(response, expected_message)
|
||||
|
||||
def test_invalidated_cert_data(self):
|
||||
@@ -1764,11 +1758,11 @@ class ProgressPageTests(ProgressPageBaseTests):
|
||||
certificate.invalidate()
|
||||
resp = self._get_progress_page()
|
||||
|
||||
self.assertNotContains(resp, u'Request Certificate')
|
||||
self.assertContains(resp, u'Your certificate has been invalidated')
|
||||
self.assertContains(resp, u'Please contact your course team if you have any questions.')
|
||||
self.assertNotContains(resp, u'View Your Certificate')
|
||||
self.assertNotContains(resp, u'Download Your Certificate')
|
||||
self.assertNotContains(resp, 'Request Certificate')
|
||||
self.assertContains(resp, 'Your certificate has been invalidated')
|
||||
self.assertContains(resp, 'Please contact your course team if you have any questions.')
|
||||
self.assertNotContains(resp, 'View Your Certificate')
|
||||
self.assertNotContains(resp, 'Download Your Certificate')
|
||||
|
||||
def generate_certificate(self, url, mode):
|
||||
""" Dry method to generate certificate. """
|
||||
@@ -1819,7 +1813,7 @@ class ProgressPageShowCorrectnessTests(ProgressPageBaseTests):
|
||||
}
|
||||
|
||||
def setUp(self):
|
||||
super(ProgressPageShowCorrectnessTests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.staff_user = UserFactory.create(is_staff=True)
|
||||
|
||||
def setup_course(self, show_correctness='', due_date=None, graded=False, **course_options): # lint-amnesty, pylint: disable=arguments-differ
|
||||
@@ -1903,7 +1897,7 @@ class ProgressPageShowCorrectnessTests(ProgressPageBaseTests):
|
||||
Ensures that grades and scores are shown or not shown on the progress page as required.
|
||||
"""
|
||||
|
||||
expected_score = u"<dd>{score}/{max_score}</dd>".format(score=score, max_score=max_score)
|
||||
expected_score = f"<dd>{score}/{max_score}</dd>"
|
||||
percent = score / float(max_score)
|
||||
|
||||
# Test individual problem scores
|
||||
@@ -1912,31 +1906,31 @@ class ProgressPageShowCorrectnessTests(ProgressPageBaseTests):
|
||||
self.assertContains(response, expected_score)
|
||||
|
||||
if graded:
|
||||
expected_summary_text = u"Problem Scores:"
|
||||
expected_summary_text = "Problem Scores:"
|
||||
else:
|
||||
expected_summary_text = u"Practice Scores:"
|
||||
expected_summary_text = "Practice Scores:"
|
||||
|
||||
else:
|
||||
# If grades are hidden, we should not be able to see the current problem scores.
|
||||
self.assertNotContains(response, expected_score)
|
||||
|
||||
if graded:
|
||||
expected_summary_text = u"Problem scores are hidden"
|
||||
expected_summary_text = "Problem scores are hidden"
|
||||
else:
|
||||
expected_summary_text = u"Practice scores are hidden"
|
||||
expected_summary_text = "Practice scores are hidden"
|
||||
|
||||
if show_correctness == ShowCorrectness.PAST_DUE and due_date:
|
||||
expected_summary_text += u' until the due date.'
|
||||
expected_summary_text += ' until the due date.'
|
||||
else:
|
||||
expected_summary_text += u'.'
|
||||
expected_summary_text += '.'
|
||||
|
||||
# Ensure that expected text is present
|
||||
self.assertContains(response, expected_summary_text)
|
||||
|
||||
# Test overall sequential score
|
||||
if graded and max_score > 0:
|
||||
percentageString = "{0:.0%}".format(percent) if max_score > 0 else ""
|
||||
template = u'<span> ({0:.3n}/{1:.3n}) {2}</span>'
|
||||
percentageString = f"{percent:.0%}" if max_score > 0 else ""
|
||||
template = '<span> ({0:.3n}/{1:.3n}) {2}</span>'
|
||||
expected_grade_summary = template.format(float(score),
|
||||
float(max_score),
|
||||
percentageString)
|
||||
@@ -2097,7 +2091,7 @@ class VerifyCourseKeyDecoratorTests(TestCase):
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(VerifyCourseKeyDecoratorTests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
self.request = RequestFactoryNoCsrf().get("foo")
|
||||
self.valid_course_id = "edX/test/1"
|
||||
@@ -2122,7 +2116,7 @@ class GenerateUserCertTests(ModuleStoreTestCase):
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(GenerateUserCertTests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
self.student = UserFactory()
|
||||
self.course = CourseFactory.create(
|
||||
@@ -2135,7 +2129,7 @@ class GenerateUserCertTests(ModuleStoreTestCase):
|
||||
)
|
||||
self.enrollment = CourseEnrollment.enroll(self.student, self.course.id, mode='honor')
|
||||
assert self.client.login(username=self.student, password=TEST_PASSWORD)
|
||||
self.url = reverse('generate_user_cert', kwargs={'course_id': six.text_type(self.course.id)})
|
||||
self.url = reverse('generate_user_cert', kwargs={'course_id': str(self.course.id)})
|
||||
|
||||
def test_user_with_out_passing_grades(self):
|
||||
# If user has no grading then json will return failed message and badrequest code
|
||||
@@ -2169,7 +2163,7 @@ class GenerateUserCertTests(ModuleStoreTestCase):
|
||||
'edx.bi.user.certificate.generate',
|
||||
{
|
||||
'category': 'certificates',
|
||||
'label': six.text_type(self.course.id)
|
||||
'label': str(self.course.id)
|
||||
},
|
||||
)
|
||||
mock_tracker.reset_mock()
|
||||
@@ -2232,7 +2226,7 @@ class GenerateUserCertTests(ModuleStoreTestCase):
|
||||
resp = self.client.post(self.url)
|
||||
self.assertContains(
|
||||
resp,
|
||||
u"You must be signed in to {platform_name} to create a certificate.".format(
|
||||
"You must be signed in to {platform_name} to create a certificate.".format(
|
||||
platform_name=settings.PLATFORM_NAME
|
||||
),
|
||||
status_code=HttpResponseBadRequest.status_code,
|
||||
@@ -2252,7 +2246,7 @@ class ActivateIDCheckerBlock(XBlock):
|
||||
"""
|
||||
result = Fragment()
|
||||
if 'activate_block_id' in context:
|
||||
result.add_content(u"Activate Block ID: {block_id}</p>".format(block_id=context['activate_block_id']))
|
||||
result.add_content("Activate Block ID: {block_id}</p>".format(block_id=context['activate_block_id']))
|
||||
return result
|
||||
|
||||
|
||||
@@ -2269,12 +2263,12 @@ class ViewCheckerBlock(XBlock):
|
||||
A student_view that asserts that the ``state`` field for this block
|
||||
matches the block's usage_id.
|
||||
"""
|
||||
msg = u"{} != {}".format(self.state, self.scope_ids.usage_id)
|
||||
assert self.state == six.text_type(self.scope_ids.usage_id), msg
|
||||
msg = f"{self.state} != {self.scope_ids.usage_id}"
|
||||
assert self.state == str(self.scope_ids.usage_id), msg
|
||||
fragments = self.runtime.render_children(self)
|
||||
result = Fragment(
|
||||
content=u"<p>ViewCheckerPassed: {}</p>\n{}".format(
|
||||
six.text_type(self.scope_ids.usage_id),
|
||||
content="<p>ViewCheckerPassed: {}</p>\n{}".format(
|
||||
str(self.scope_ids.usage_id),
|
||||
"\n".join(fragment.content for fragment in fragments),
|
||||
)
|
||||
)
|
||||
@@ -2307,7 +2301,7 @@ class TestIndexView(ModuleStoreTestCase):
|
||||
student=user,
|
||||
course_id=course.id,
|
||||
module_state_key=item.scope_ids.usage_id,
|
||||
state=json.dumps({'state': six.text_type(item.scope_ids.usage_id)})
|
||||
state=json.dumps({'state': str(item.scope_ids.usage_id)})
|
||||
)
|
||||
|
||||
CourseOverview.load_from_module_store(course.id)
|
||||
@@ -2318,7 +2312,7 @@ class TestIndexView(ModuleStoreTestCase):
|
||||
reverse(
|
||||
'courseware_section',
|
||||
kwargs={
|
||||
'course_id': six.text_type(course.id),
|
||||
'course_id': str(course.id),
|
||||
'chapter': chapter.url_name,
|
||||
'section': section.url_name,
|
||||
}
|
||||
@@ -2346,7 +2340,7 @@ class TestIndexView(ModuleStoreTestCase):
|
||||
reverse(
|
||||
'courseware_section',
|
||||
kwargs={
|
||||
'course_id': six.text_type(course.id),
|
||||
'course_id': str(course.id),
|
||||
'chapter': chapter.url_name,
|
||||
'section': section.url_name,
|
||||
}
|
||||
@@ -2569,7 +2563,7 @@ class TestIndexViewCompleteOnView(ModuleStoreTestCase, CompletionWaffleTestMixin
|
||||
self.section_1_url = reverse(
|
||||
'courseware_section',
|
||||
kwargs={
|
||||
'course_id': six.text_type(self.course.id),
|
||||
'course_id': str(self.course.id),
|
||||
'chapter': self.chapter.url_name,
|
||||
'section': self.section_1.url_name,
|
||||
}
|
||||
@@ -2578,7 +2572,7 @@ class TestIndexViewCompleteOnView(ModuleStoreTestCase, CompletionWaffleTestMixin
|
||||
self.section_2_url = reverse(
|
||||
'courseware_section',
|
||||
kwargs={
|
||||
'course_id': six.text_type(self.course.id),
|
||||
'course_id': str(self.course.id),
|
||||
'chapter': self.chapter.url_name,
|
||||
'section': self.section_2.url_name,
|
||||
}
|
||||
@@ -2619,8 +2613,8 @@ class TestIndexViewCompleteOnView(ModuleStoreTestCase, CompletionWaffleTestMixin
|
||||
request.user = self.user
|
||||
response = handle_xblock_callback(
|
||||
request,
|
||||
six.text_type(self.course.id),
|
||||
quote_slashes(six.text_type(self.html_1_1.scope_ids.usage_id)),
|
||||
str(self.course.id),
|
||||
quote_slashes(str(self.html_1_1.scope_ids.usage_id)),
|
||||
'publish_completion',
|
||||
)
|
||||
assert json.loads(response.content.decode('utf-8')) == {'result': 'ok'}
|
||||
@@ -2637,8 +2631,8 @@ class TestIndexViewCompleteOnView(ModuleStoreTestCase, CompletionWaffleTestMixin
|
||||
request.user = self.user
|
||||
response = handle_xblock_callback(
|
||||
request,
|
||||
six.text_type(self.course.id),
|
||||
quote_slashes(six.text_type(self.html_1_2.scope_ids.usage_id)),
|
||||
str(self.course.id),
|
||||
quote_slashes(str(self.html_1_2.scope_ids.usage_id)),
|
||||
'publish_completion',
|
||||
)
|
||||
assert json.loads(response.content.decode('utf-8')) == {'result': 'ok'}
|
||||
@@ -2661,7 +2655,7 @@ class TestIndexViewWithVerticalPositions(ModuleStoreTestCase):
|
||||
"""
|
||||
Set up initial test data
|
||||
"""
|
||||
super(TestIndexViewWithVerticalPositions, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
self.user = UserFactory()
|
||||
|
||||
@@ -2687,7 +2681,7 @@ class TestIndexViewWithVerticalPositions(ModuleStoreTestCase):
|
||||
reverse(
|
||||
'courseware_position',
|
||||
kwargs={
|
||||
'course_id': six.text_type(self.course.id),
|
||||
'course_id': str(self.course.id),
|
||||
'chapter': self.chapter.url_name,
|
||||
'section': self.section.url_name,
|
||||
'position': input_position,
|
||||
@@ -2699,7 +2693,7 @@ class TestIndexViewWithVerticalPositions(ModuleStoreTestCase):
|
||||
"""
|
||||
Asserts that the expected position and the position in the response are the same
|
||||
"""
|
||||
self.assertContains(response, 'data-position="{}"'.format(expected_position))
|
||||
self.assertContains(response, f'data-position="{expected_position}"')
|
||||
|
||||
@ddt.data(("-1", 1), ("0", 1), ("-0", 1), ("2", 2), ("5", 1))
|
||||
@ddt.unpack
|
||||
@@ -2724,7 +2718,7 @@ class TestIndexViewWithGating(ModuleStoreTestCase, MilestonesTestCaseMixin):
|
||||
"""
|
||||
Set up the initial test data
|
||||
"""
|
||||
super(TestIndexViewWithGating, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
self.user = UserFactory()
|
||||
self.course = CourseFactory.create()
|
||||
@@ -2756,7 +2750,7 @@ class TestIndexViewWithGating(ModuleStoreTestCase, MilestonesTestCaseMixin):
|
||||
reverse(
|
||||
'courseware_section',
|
||||
kwargs={
|
||||
'course_id': six.text_type(self.course.id),
|
||||
'course_id': str(self.course.id),
|
||||
'chapter': self.chapter.url_name,
|
||||
'section': self.gated_seq.url_name,
|
||||
}
|
||||
@@ -2775,7 +2769,7 @@ class TestIndexViewWithCourseDurationLimits(ModuleStoreTestCase):
|
||||
"""
|
||||
Set up the initial test data.
|
||||
"""
|
||||
super(TestIndexViewWithCourseDurationLimits, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
self.user = UserFactory()
|
||||
self.course = CourseFactory.create(start=datetime.now() - timedelta(weeks=1))
|
||||
@@ -2799,7 +2793,7 @@ class TestIndexViewWithCourseDurationLimits(ModuleStoreTestCase):
|
||||
reverse(
|
||||
'courseware_section',
|
||||
kwargs={
|
||||
'course_id': six.text_type(self.course.id),
|
||||
'course_id': str(self.course.id),
|
||||
'chapter': self.chapter.url_name,
|
||||
'section': self.sequential.url_name,
|
||||
}
|
||||
@@ -2825,7 +2819,7 @@ class TestIndexViewWithCourseDurationLimits(ModuleStoreTestCase):
|
||||
reverse(
|
||||
'courseware_section',
|
||||
kwargs={
|
||||
'course_id': six.text_type(self.course.id),
|
||||
'course_id': str(self.course.id),
|
||||
'chapter': self.chapter.url_name,
|
||||
'section': self.sequential.url_name,
|
||||
}
|
||||
@@ -2843,7 +2837,7 @@ class TestRenderXBlock(RenderXBlockTestMixin, ModuleStoreTestCase, CompletionWaf
|
||||
"""
|
||||
def setUp(self):
|
||||
reload_django_url_config()
|
||||
super(TestRenderXBlock, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
def test_render_xblock_with_invalid_usage_key(self):
|
||||
"""
|
||||
@@ -2895,8 +2889,8 @@ class TestRenderXBlock(RenderXBlockTestMixin, ModuleStoreTestCase, CompletionWaf
|
||||
request.user = self.user
|
||||
response = handle_xblock_callback(
|
||||
request,
|
||||
six.text_type(self.course.id),
|
||||
quote_slashes(six.text_type(self.html_block.location)),
|
||||
str(self.course.id),
|
||||
quote_slashes(str(self.html_block.location)),
|
||||
'publish_completion',
|
||||
)
|
||||
assert response.status_code == 200
|
||||
@@ -2963,10 +2957,10 @@ class TestRenderXBlockSelfPaced(TestRenderXBlock): # lint-amnesty, pylint: disa
|
||||
count assertions in the tests defined by RenderXBlockMixin.
|
||||
"""
|
||||
def setUp(self): # lint-amnesty, pylint: disable=useless-super-delegation
|
||||
super(TestRenderXBlockSelfPaced, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
def course_options(self):
|
||||
options = super(TestRenderXBlockSelfPaced, self).course_options() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
options = super().course_options()
|
||||
options['self_paced'] = True
|
||||
return options
|
||||
|
||||
@@ -2983,7 +2977,7 @@ class TestIndexViewCrawlerStudentStateWrites(SharedModuleStoreTestCase):
|
||||
"""Set up the simplest course possible."""
|
||||
# setUpClassAndTestData() already calls setUpClass on SharedModuleStoreTestCase
|
||||
# pylint: disable=super-method-not-called
|
||||
with super(TestIndexViewCrawlerStudentStateWrites, cls).setUpClassAndTestData():
|
||||
with super().setUpClassAndTestData():
|
||||
cls.course = CourseFactory.create()
|
||||
with cls.store.bulk_operations(cls.course.id):
|
||||
cls.chapter = ItemFactory.create(category='chapter', parent_location=cls.course.location)
|
||||
@@ -2998,7 +2992,7 @@ class TestIndexViewCrawlerStudentStateWrites(SharedModuleStoreTestCase):
|
||||
|
||||
def setUp(self):
|
||||
"""Do the client login."""
|
||||
super(TestIndexViewCrawlerStudentStateWrites, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.client.login(username=self.user.username, password=TEST_PASSWORD)
|
||||
|
||||
def test_write_by_default(self):
|
||||
@@ -3038,9 +3032,9 @@ class TestIndexViewCrawlerStudentStateWrites(SharedModuleStoreTestCase):
|
||||
url = reverse(
|
||||
'courseware_section',
|
||||
kwargs={
|
||||
'course_id': six.text_type(self.course.id),
|
||||
'chapter': six.text_type(self.chapter.location.block_id),
|
||||
'section': six.text_type(self.section.location.block_id),
|
||||
'course_id': str(self.course.id),
|
||||
'chapter': str(self.chapter.location.block_id),
|
||||
'section': str(self.section.location.block_id),
|
||||
}
|
||||
)
|
||||
response = self.client.get(url, HTTP_USER_AGENT=user_agent)
|
||||
@@ -3054,7 +3048,7 @@ class EnterpriseConsentTestCase(EnterpriseTestConsentRequired, ModuleStoreTestCa
|
||||
Ensure that the Enterprise Data Consent redirects are in place only when consent is required.
|
||||
"""
|
||||
def setUp(self):
|
||||
super(EnterpriseConsentTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.user = UserFactory.create()
|
||||
assert self.client.login(username=self.user.username, password='test')
|
||||
self.course = CourseFactory.create()
|
||||
@@ -3069,7 +3063,7 @@ class EnterpriseConsentTestCase(EnterpriseTestConsentRequired, ModuleStoreTestCa
|
||||
# ENT-924: Temporary solution to replace sensitive SSO usernames.
|
||||
mock_enterprise_customer_for_request.return_value = None
|
||||
|
||||
course_id = six.text_type(self.course.id)
|
||||
course_id = str(self.course.id)
|
||||
for url in (
|
||||
reverse("courseware", kwargs=dict(course_id=course_id)),
|
||||
reverse("progress", kwargs=dict(course_id=course_id)),
|
||||
@@ -3104,7 +3098,7 @@ class DatesTabTestCase(ModuleStoreTestCase):
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(DatesTabTestCase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
|
||||
now = datetime.now(utc)
|
||||
self.course = CourseFactory.create(start=now + timedelta(days=-1), self_paced=True)
|
||||
@@ -3128,7 +3122,7 @@ class DatesTabTestCase(ModuleStoreTestCase):
|
||||
|
||||
def _get_response(self, course):
|
||||
""" Returns the HTML for the dates page """
|
||||
return self.client.get(reverse('dates', args=[six.text_type(course.id)]))
|
||||
return self.client.get(reverse('dates', args=[str(course.id)]))
|
||||
|
||||
def test_tab_redirects_if_not_logged_in(self):
|
||||
self.client.logout()
|
||||
@@ -3201,7 +3195,7 @@ class DatesTabTestCase(ModuleStoreTestCase):
|
||||
}
|
||||
|
||||
expected_calls = [
|
||||
call('course_id', text_type(self.course.id)),
|
||||
call('course_id', str(self.course.id)),
|
||||
call('user_id', self.user.id),
|
||||
call('is_staff', self.user.is_staff),
|
||||
]
|
||||
@@ -3409,7 +3403,7 @@ class ContentOptimizationTestCase(ModuleStoreTestCase):
|
||||
self.math_html_usage_keys = []
|
||||
|
||||
with self.store.default_store(ModuleStoreEnum.Type.split):
|
||||
self.course = CourseFactory.create(display_name=u'teꜱᴛ course', run="Testing_course")
|
||||
self.course = CourseFactory.create(display_name='teꜱᴛ course', run="Testing_course")
|
||||
with self.store.bulk_operations(self.course.id):
|
||||
chapter = ItemFactory.create(
|
||||
category='chapter',
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Word cloud integration tests using mongo modulestore."""
|
||||
|
||||
|
||||
@@ -63,7 +62,7 @@ class TestWordCloud(BaseTestXmodule):
|
||||
|
||||
# We should compare top_words for manually,
|
||||
# because they are unsorted.
|
||||
keys_to_compare = set(content.keys()).difference(set(['top_words']))
|
||||
keys_to_compare = set(content.keys()).difference({'top_words'})
|
||||
self.assertDictEqual(
|
||||
{k: content[k] for k in keys_to_compare},
|
||||
{k: correct_jsons[username][k] for k in keys_to_compare})
|
||||
@@ -90,12 +89,12 @@ class TestWordCloud(BaseTestXmodule):
|
||||
|
||||
# correct initial data:
|
||||
correct_initial_data = {
|
||||
u'status': u'success',
|
||||
u'student_words': {},
|
||||
u'total_count': 0,
|
||||
u'submitted': False,
|
||||
u'top_words': {},
|
||||
u'display_student_percents': False
|
||||
'status': 'success',
|
||||
'student_words': {},
|
||||
'total_count': 0,
|
||||
'submitted': False,
|
||||
'top_words': {},
|
||||
'display_student_percents': False
|
||||
}
|
||||
|
||||
for _, response_content in users_state.items():
|
||||
@@ -113,10 +112,10 @@ class TestWordCloud(BaseTestXmodule):
|
||||
]
|
||||
|
||||
correct_words = [
|
||||
u"small",
|
||||
u"big",
|
||||
u"spaced",
|
||||
u"few words",
|
||||
"small",
|
||||
"big",
|
||||
"spaced",
|
||||
"few words",
|
||||
]
|
||||
|
||||
users_state = self._post_words(input_words)
|
||||
@@ -127,15 +126,15 @@ class TestWordCloud(BaseTestXmodule):
|
||||
for index, user in enumerate(self.users):
|
||||
|
||||
correct_state[user.username] = {
|
||||
u'status': u'success',
|
||||
u'submitted': True,
|
||||
u'display_student_percents': True,
|
||||
u'student_words': {word: 1 + index for word in correct_words},
|
||||
u'total_count': len(input_words) * (1 + index),
|
||||
u'top_words': [
|
||||
'status': 'success',
|
||||
'submitted': True,
|
||||
'display_student_percents': True,
|
||||
'student_words': {word: 1 + index for word in correct_words},
|
||||
'total_count': len(input_words) * (1 + index),
|
||||
'top_words': [
|
||||
{
|
||||
u'text': word, u'percent': 100 / len(input_words),
|
||||
u'size': (1 + index)
|
||||
'text': word, 'percent': 100 / len(input_words),
|
||||
'size': (1 + index)
|
||||
}
|
||||
for word in correct_words
|
||||
]
|
||||
@@ -186,8 +185,8 @@ class TestWordCloud(BaseTestXmodule):
|
||||
self._check_response(users_state_before_fail, current_users_state)
|
||||
|
||||
def test_unicode(self):
|
||||
input_words = [u" this is unicode Юникод"]
|
||||
correct_words = [u"this is unicode юникод"]
|
||||
input_words = [" this is unicode Юникод"]
|
||||
correct_words = ["this is unicode юникод"]
|
||||
|
||||
users_state = self._post_words(input_words)
|
||||
|
||||
|
||||
@@ -6,10 +6,9 @@ Test for LMS courseware app.
|
||||
from textwrap import dedent
|
||||
from unittest import TestCase
|
||||
|
||||
import mock
|
||||
from unittest import mock
|
||||
from django.urls import reverse
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
from six import text_type
|
||||
|
||||
from lms.djangoapps.courseware.tests.helpers import LoginEnrollmentTestCase
|
||||
from lms.djangoapps.lms_xblock.field_data import LmsFieldData
|
||||
@@ -24,7 +23,7 @@ class ActivateLoginTest(LoginEnrollmentTestCase):
|
||||
Test logging in and logging out.
|
||||
"""
|
||||
def setUp(self):
|
||||
super(ActivateLoginTest, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.setup_user()
|
||||
|
||||
def test_activate_login(self):
|
||||
@@ -76,22 +75,22 @@ class PageLoaderTestCase(LoginEnrollmentTestCase):
|
||||
|
||||
if descriptor.location.category == 'about':
|
||||
self._assert_loads('about_course',
|
||||
{'course_id': text_type(course_key)},
|
||||
{'course_id': str(course_key)},
|
||||
descriptor)
|
||||
|
||||
elif descriptor.location.category == 'static_tab':
|
||||
kwargs = {'course_id': text_type(course_key),
|
||||
kwargs = {'course_id': str(course_key),
|
||||
'tab_slug': descriptor.location.name}
|
||||
self._assert_loads('static_tab', kwargs, descriptor)
|
||||
|
||||
elif descriptor.location.category == 'course_info':
|
||||
self._assert_loads('info', {'course_id': text_type(course_key)},
|
||||
self._assert_loads('info', {'course_id': str(course_key)},
|
||||
descriptor)
|
||||
|
||||
else:
|
||||
|
||||
kwargs = {'course_id': text_type(course_key),
|
||||
'location': text_type(descriptor.location)}
|
||||
kwargs = {'course_id': str(course_key),
|
||||
'location': str(descriptor.location)}
|
||||
|
||||
self._assert_loads('jump_to', kwargs, descriptor,
|
||||
expect_redirect=True,
|
||||
@@ -111,7 +110,7 @@ class PageLoaderTestCase(LoginEnrollmentTestCase):
|
||||
response = self.client.get(url, follow=True)
|
||||
|
||||
if response.status_code != 200:
|
||||
self.fail(u'Status %d for page %s' %
|
||||
self.fail('Status %d for page %s' %
|
||||
(response.status_code, descriptor.location))
|
||||
|
||||
if expect_redirect:
|
||||
@@ -129,7 +128,7 @@ class TestMongoCoursesLoad(ModuleStoreTestCase, PageLoaderTestCase):
|
||||
MODULESTORE = TEST_DATA_MIXED_MODULESTORE
|
||||
|
||||
def setUp(self):
|
||||
super(TestMongoCoursesLoad, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp()
|
||||
self.setup_user()
|
||||
self.toy_course_key = ToyCourseFactory.create().id
|
||||
|
||||
|
||||
Reference in New Issue
Block a user