diff --git a/openedx/features/course_experience/tests/views/helpers.py b/openedx/features/course_experience/tests/views/helpers.py index 435d562862..7faa9a9a70 100644 --- a/openedx/features/course_experience/tests/views/helpers.py +++ b/openedx/features/course_experience/tests/views/helpers.py @@ -1,6 +1,8 @@ """ Test helpers for the course experience. """ +from __future__ import absolute_import + from datetime import timedelta from django.core.exceptions import ObjectDoesNotExist diff --git a/openedx/features/course_experience/tests/views/test_course_dates.py b/openedx/features/course_experience/tests/views/test_course_dates.py index 1df810ec55..36f0f9e577 100644 --- a/openedx/features/course_experience/tests/views/test_course_dates.py +++ b/openedx/features/course_experience/tests/views/test_course_dates.py @@ -1,7 +1,11 @@ """ Tests for course dates fragment. """ -from datetime import timedelta, datetime +from __future__ import absolute_import + +from datetime import datetime, timedelta + +import six from django.urls import reverse from student.tests.factories import UserFactory @@ -9,7 +13,6 @@ from xmodule.modulestore import ModuleStoreEnum from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory - TEST_PASSWORD = 'test' @@ -32,7 +35,7 @@ class TestCourseDatesFragmentView(ModuleStoreTestCase): self.dates_fragment_url = reverse( 'openedx.course_experience.mobile_dates_fragment_view', kwargs={ - 'course_id': unicode(self.course.id) + 'course_id': six.text_type(self.course.id) } ) diff --git a/openedx/features/course_experience/tests/views/test_course_home.py b/openedx/features/course_experience/tests/views/test_course_home.py index e30b359900..3b179f894c 100644 --- a/openedx/features/course_experience/tests/views/test_course_home.py +++ b/openedx/features/course_experience/tests/views/test_course_home.py @@ -2,40 +2,43 @@ """ Tests for the course home page. """ +from __future__ import absolute_import + from datetime import datetime, timedelta import ddt import mock +import six from django.conf import settings -from django.urls import reverse from django.http import QueryDict +from django.urls import reverse from django.utils.http import urlquote_plus from django.utils.timezone import now from pytz import UTC from waffle.models import Flag from waffle.testutils import override_flag -from django_comment_common.models import ( - FORUM_ROLE_ADMINISTRATOR, - FORUM_ROLE_MODERATOR, - FORUM_ROLE_GROUP_MODERATOR, - FORUM_ROLE_COMMUNITY_TA -) -from django_comment_client.tests.factories import RoleFactory from course_modes.models import CourseMode from course_modes.tests.factories import CourseModeFactory from courseware.tests.helpers import get_expiration_banner_text +from django_comment_client.tests.factories import RoleFactory +from django_comment_common.models import ( + FORUM_ROLE_ADMINISTRATOR, + FORUM_ROLE_COMMUNITY_TA, + FORUM_ROLE_GROUP_MODERATOR, + FORUM_ROLE_MODERATOR +) from experiments.models import ExperimentData from lms.djangoapps.commerce.models import CommerceConfiguration from lms.djangoapps.commerce.utils import EcommerceService from lms.djangoapps.course_goals.api import add_course_goal, remove_course_goal from lms.djangoapps.courseware.tests.factories import ( - InstructorFactory, - StaffFactory, BetaTesterFactory, - OrgStaffFactory, - OrgInstructorFactory, GlobalStaffFactory, + InstructorFactory, + OrgInstructorFactory, + OrgStaffFactory, + StaffFactory ) from openedx.core.djangoapps.content.course_overviews.models import CourseOverview from openedx.core.djangoapps.dark_lang.models import DarkLangConfig @@ -44,15 +47,15 @@ from openedx.core.djangoapps.waffle_utils.testutils import WAFFLE_TABLES, overri from openedx.features.course_duration_limits.config import EXPERIMENT_DATA_HOLDBACK_KEY, EXPERIMENT_ID from openedx.features.course_duration_limits.models import CourseDurationLimitConfig from openedx.features.course_experience import ( + COURSE_ENABLE_UNENROLLED_ACCESS_FLAG, SHOW_REVIEWS_TOOL_FLAG, SHOW_UPGRADE_MSG_ON_COURSE_HOME, - UNIFIED_COURSE_TAB_FLAG, - COURSE_ENABLE_UNENROLLED_ACCESS_FLAG, + UNIFIED_COURSE_TAB_FLAG ) from student.models import CourseEnrollment from student.tests.factories import UserFactory from util.date_utils import strftime_localized -from xmodule.course_module import COURSE_VISIBILITY_PRIVATE, COURSE_VISIBILITY_PUBLIC_OUTLINE, COURSE_VISIBILITY_PUBLIC +from xmodule.course_module import COURSE_VISIBILITY_PRIVATE, COURSE_VISIBILITY_PUBLIC, COURSE_VISIBILITY_PUBLIC_OUTLINE from xmodule.modulestore import ModuleStoreEnum from xmodule.modulestore.tests.django_utils import CourseUserType, ModuleStoreTestCase, SharedModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory, check_mongo_calls @@ -89,7 +92,7 @@ def course_home_url(course): Arguments: course (CourseDescriptor): The course being tested. """ - return course_home_url_from_string(unicode(course.id)) + return course_home_url_from_string(six.text_type(course.id)) def course_home_url_from_string(course_key_string): diff --git a/openedx/features/course_experience/tests/views/test_course_outline.py b/openedx/features/course_experience/tests/views/test_course_outline.py index 9f89403a30..6b7266c5c3 100644 --- a/openedx/features/course_experience/tests/views/test_course_outline.py +++ b/openedx/features/course_experience/tests/views/test_course_outline.py @@ -1,17 +1,23 @@ """ Tests for the Course Outline view and supporting views. """ +from __future__ import absolute_import + import datetime import json import re +import six from completion import waffle from completion.models import BlockCompletion from completion.test_utils import CompletionWaffleTestMixin from django.contrib.sites.models import Site -from django.urls import reverse from django.test import override_settings +from django.urls import reverse +from milestones.tests.utils import MilestonesTestCaseMixin from mock import Mock, patch +from opaque_keys.edx.keys import CourseKey, UsageKey +from pyquery import PyQuery as pq from six import text_type from waffle.models import Switch from waffle.testutils import override_switch @@ -19,13 +25,11 @@ from waffle.testutils import override_switch from courseware.tests.factories import StaffFactory from gating import api as lms_gating_api from lms.djangoapps.course_api.blocks.transformers.milestones import MilestonesAndSpecialExamsTransformer -from milestones.tests.utils import MilestonesTestCaseMixin -from opaque_keys.edx.keys import CourseKey, UsageKey from openedx.core.lib.gating import api as gating_api from openedx.features.course_experience.views.course_outline import ( - CourseOutlineFragmentView, DEFAULT_COMPLETION_TRACKING_START + DEFAULT_COMPLETION_TRACKING_START, + CourseOutlineFragmentView ) -from pyquery import PyQuery as pq from student.models import CourseEnrollment from student.tests.factories import UserFactory from xmodule.modulestore import ModuleStoreEnum @@ -212,7 +216,7 @@ class TestCourseOutlinePageWithPrerequisites(SharedModuleStoreTestCase, Mileston gating_block: (The prerequisite) The block that must be completed to get access to the gated block """ - gating_api.add_prerequisite(self.course.id, unicode(gating_block.location)) + gating_api.add_prerequisite(self.course.id, six.text_type(gating_block.location)) gating_api.set_required_content(self.course.id, gated_block.location, gating_block.location, 100) def test_content_locked(self): @@ -362,7 +366,7 @@ class TestCourseOutlineResumeCourse(SharedModuleStoreTestCase, CompletionWaffleT """ course_key = CourseKey.from_string(str(course.id)) # Fake a visit to sequence2/vertical2 - block_key = UsageKey.from_string(unicode(sequential.location)) + block_key = UsageKey.from_string(six.text_type(sequential.location)) completion = 1.0 BlockCompletion.objects.submit_completion( user=self.user, @@ -595,7 +599,7 @@ class TestCourseOutlinePreview(SharedModuleStoreTestCase): masquerade_url = reverse( 'masquerade_update', kwargs={ - 'course_key_string': unicode(course.id), + 'course_key_string': six.text_type(course.id), } ) response = self.client.post( diff --git a/openedx/features/course_experience/tests/views/test_course_sock.py b/openedx/features/course_experience/tests/views/test_course_sock.py index a2992cf638..78d2ca3f10 100644 --- a/openedx/features/course_experience/tests/views/test_course_sock.py +++ b/openedx/features/course_experience/tests/views/test_course_sock.py @@ -2,6 +2,8 @@ Tests for course verification sock """ +from __future__ import absolute_import + import ddt from course_modes.models import CourseMode diff --git a/openedx/features/course_experience/tests/views/test_course_updates.py b/openedx/features/course_experience/tests/views/test_course_updates.py index 41f5f8932f..19cbee92f2 100644 --- a/openedx/features/course_experience/tests/views/test_course_updates.py +++ b/openedx/features/course_experience/tests/views/test_course_updates.py @@ -1,10 +1,14 @@ """ Tests for the course updates page. """ +from __future__ import absolute_import + from datetime import datetime -from courseware.courses import get_course_info_usage_key +import six from django.urls import reverse + +from courseware.courses import get_course_info_usage_key from openedx.core.djangoapps.waffle_utils.testutils import WAFFLE_TABLES from openedx.features.content_type_gating.models import ContentTypeGatingConfig from openedx.features.course_experience.views.course_updates import STATUS_VISIBLE @@ -28,7 +32,7 @@ def course_updates_url(course): return reverse( 'openedx.course_experience.course_updates', kwargs={ - 'course_id': unicode(course.id), + 'course_id': six.text_type(course.id), } ) diff --git a/openedx/features/course_experience/tests/views/test_welcome_message.py b/openedx/features/course_experience/tests/views/test_welcome_message.py index 4d908e7cca..5253444bf6 100644 --- a/openedx/features/course_experience/tests/views/test_welcome_message.py +++ b/openedx/features/course_experience/tests/views/test_welcome_message.py @@ -1,7 +1,10 @@ """ Tests for course welcome messages. """ +from __future__ import absolute_import + import ddt +import six from django.urls import reverse from student.models import CourseEnrollment @@ -23,7 +26,7 @@ def welcome_message_url(course): return reverse( 'openedx.course_experience.welcome_message_fragment_view', kwargs={ - 'course_id': unicode(course.id), + 'course_id': six.text_type(course.id), } ) @@ -35,7 +38,7 @@ def latest_update_url(course): return reverse( 'openedx.course_experience.latest_update_fragment_view', kwargs={ - 'course_id': unicode(course.id), + 'course_id': six.text_type(course.id), } ) @@ -47,7 +50,7 @@ def dismiss_message_url(course): return reverse( 'openedx.course_experience.dismiss_welcome_message', kwargs={ - 'course_id': unicode(course.id), + 'course_id': six.text_type(course.id), } ) diff --git a/openedx/features/course_experience/views/course_dates.py b/openedx/features/course_experience/views/course_dates.py index 5c634144fe..d272c037da 100644 --- a/openedx/features/course_experience/views/course_dates.py +++ b/openedx/features/course_experience/views/course_dates.py @@ -1,6 +1,8 @@ """ Fragment for rendering the course dates sidebar. """ +from __future__ import absolute_import + from django.http import Http404 from django.template.loader import render_to_string from django.utils.translation import get_language_bidi diff --git a/openedx/features/course_experience/views/course_home.py b/openedx/features/course_experience/views/course_home.py index a8ac5536ad..e740fd8cc5 100644 --- a/openedx/features/course_experience/views/course_home.py +++ b/openedx/features/course_experience/views/course_home.py @@ -2,9 +2,12 @@ Views for the course home page. """ -from django.urls import reverse +from __future__ import absolute_import + +import six from django.template.context_processors import csrf from django.template.loader import render_to_string +from django.urls import reverse from django.utils.decorators import method_decorator from django.views.decorators.cache import cache_control from django.views.decorators.csrf import ensure_csrf_cookie @@ -23,17 +26,20 @@ from lms.djangoapps.course_goals.api import ( ) from lms.djangoapps.courseware.exceptions import CourseAccessRedirect from lms.djangoapps.courseware.views.views import CourseTabView +from openedx.core.djangoapps.content.course_overviews.models import CourseOverview from openedx.core.djangoapps.plugin_api.views import EdxFragmentView from openedx.core.djangoapps.util.maintenance_banner import add_maintenance_banner -from openedx.core.djangoapps.content.course_overviews.models import CourseOverview -from openedx.features.course_experience.course_tools import CourseToolsPluginManager from openedx.features.course_duration_limits.access import generate_course_expired_fragment +from openedx.features.course_experience.course_tools import CourseToolsPluginManager from student.models import CourseEnrollment from util.views import ensure_valid_course_key -from xmodule.course_module import COURSE_VISIBILITY_PUBLIC_OUTLINE, COURSE_VISIBILITY_PUBLIC +from xmodule.course_module import COURSE_VISIBILITY_PUBLIC, COURSE_VISIBILITY_PUBLIC_OUTLINE from .. import ( - LATEST_UPDATE_FLAG, SHOW_UPGRADE_MSG_ON_COURSE_HOME, USE_BOOTSTRAP_FLAG, COURSE_ENABLE_UNENROLLED_ACCESS_FLAG + COURSE_ENABLE_UNENROLLED_ACCESS_FLAG, + LATEST_UPDATE_FLAG, + SHOW_UPGRADE_MSG_ON_COURSE_HOME, + USE_BOOTSTRAP_FLAG ) from ..utils import get_course_outline_block_tree, get_resume_block from .course_dates import CourseDatesFragmentView @@ -43,7 +49,6 @@ from .course_sock import CourseSockFragmentView from .latest_update import LatestUpdateFragmentView from .welcome_message import WelcomeMessageFragmentView - EMPTY_HANDOUTS_HTML = u'
    ' @@ -68,7 +73,7 @@ class CourseHomeView(CourseTabView): return USE_BOOTSTRAP_FLAG.is_enabled(course.id) def render_to_fragment(self, request, course=None, tab=None, **kwargs): - course_id = unicode(course.id) + course_id = six.text_type(course.id) home_fragment_view = CourseHomeFragmentView() return home_fragment_view.render_to_fragment(request, course_id=course_id, **kwargs) diff --git a/openedx/features/course_experience/views/course_home_messages.py b/openedx/features/course_experience/views/course_home_messages.py index 3edce019e9..655fb14092 100644 --- a/openedx/features/course_experience/views/course_home_messages.py +++ b/openedx/features/course_experience/views/course_home_messages.py @@ -2,16 +2,22 @@ View logic for handling course messages. """ +from __future__ import absolute_import + from datetime import datetime from babel.dates import format_date, format_timedelta -from course_modes.models import CourseMode -from courseware.courses import get_course_date_blocks, get_course_with_access from django.contrib import auth from django.template.loader import render_to_string from django.utils.http import urlquote_plus from django.utils.translation import get_language, to_locale from django.utils.translation import ugettext as _ +from opaque_keys.edx.keys import CourseKey +from pytz import UTC +from web_fragments.fragment import Fragment + +from course_modes.models import CourseMode +from courseware.courses import get_course_date_blocks, get_course_with_access from lms.djangoapps.course_goals.api import ( get_course_goal, get_course_goal_options, @@ -21,13 +27,10 @@ from lms.djangoapps.course_goals.api import ( ) from lms.djangoapps.course_goals.models import GOAL_KEY_CHOICES from lms.djangoapps.courseware.courses import allow_public_access -from opaque_keys.edx.keys import CourseKey from openedx.core.djangoapps.plugin_api.views import EdxFragmentView from openedx.core.djangolib.markup import HTML, Text from openedx.features.course_experience import CourseHomeMessages -from pytz import UTC from student.models import CourseEnrollment -from web_fragments.fragment import Fragment from xmodule.course_module import COURSE_VISIBILITY_PUBLIC diff --git a/openedx/features/course_experience/views/course_outline.py b/openedx/features/course_experience/views/course_outline.py index d63ce19411..f97b01972e 100644 --- a/openedx/features/course_experience/views/course_outline.py +++ b/openedx/features/course_experience/views/course_outline.py @@ -1,8 +1,10 @@ """ Views to show a course outline. """ -import re +from __future__ import absolute_import + import datetime +import re from completion import waffle as completion_waffle from django.contrib.auth.models import User @@ -16,12 +18,11 @@ from web_fragments.fragment import Fragment from courseware.courses import get_course_overview_with_access from openedx.core.djangoapps.plugin_api.views import EdxFragmentView from student.models import CourseEnrollment - from util.milestones_helpers import get_course_content_milestones from xmodule.course_module import COURSE_VISIBILITY_PUBLIC from xmodule.modulestore.django import modulestore -from ..utils import get_course_outline_block_tree, get_resume_block +from ..utils import get_course_outline_block_tree, get_resume_block DEFAULT_COMPLETION_TRACKING_START = datetime.datetime(2018, 1, 24, tzinfo=UTC) diff --git a/openedx/features/course_experience/views/course_reviews.py b/openedx/features/course_experience/views/course_reviews.py index 11ae627d10..5fac94e7c1 100644 --- a/openedx/features/course_experience/views/course_reviews.py +++ b/openedx/features/course_experience/views/course_reviews.py @@ -1,20 +1,23 @@ """ Fragment for rendering the course reviews panel """ +from __future__ import absolute_import + +import six from django.conf import settings from django.contrib.auth.decorators import login_required -from django.urls import reverse from django.template.loader import render_to_string +from django.urls import reverse from django.utils.decorators import method_decorator from django.views.decorators.cache import cache_control from opaque_keys.edx.keys import CourseKey from web_fragments.fragment import Fragment from courseware.courses import get_course_with_access -from student.models import CourseEnrollment from lms.djangoapps.courseware.views.views import CourseTabView from openedx.core.djangoapps.plugin_api.views import EdxFragmentView from openedx.features.course_experience import default_course_url_name +from student.models import CourseEnrollment from .. import USE_BOOTSTRAP_FLAG @@ -38,7 +41,7 @@ class CourseReviewsView(CourseTabView): return USE_BOOTSTRAP_FLAG.is_enabled(course.id) def render_to_fragment(self, request, course=None, tab=None, **kwargs): - course_id = unicode(course.id) + course_id = six.text_type(course.id) reviews_fragment_view = CourseReviewsFragmentView() return reviews_fragment_view.render_to_fragment(request, course_id=course_id, **kwargs) @@ -55,7 +58,7 @@ class CourseReviewsFragmentView(EdxFragmentView): course_key = CourseKey.from_string(course_id) course = get_course_with_access(request.user, 'load', course_key, check_if_enrolled=False) course_url_name = default_course_url_name(course.id) - course_url = reverse(course_url_name, kwargs={'course_id': unicode(course.id)}) + course_url = reverse(course_url_name, kwargs={'course_id': six.text_type(course.id)}) is_enrolled = CourseEnrollment.is_enrolled(request.user, course.id) diff --git a/openedx/features/course_experience/views/course_sock.py b/openedx/features/course_experience/views/course_sock.py index 461a0616c1..7d73db331b 100644 --- a/openedx/features/course_experience/views/course_sock.py +++ b/openedx/features/course_experience/views/course_sock.py @@ -1,6 +1,8 @@ """ Fragment for rendering the course's sock and associated toggle button. """ +from __future__ import absolute_import + from django.template.loader import render_to_string from web_fragments.fragment import Fragment diff --git a/openedx/features/course_experience/views/course_updates.py b/openedx/features/course_experience/views/course_updates.py index b385ba2ad7..e6a417fbc5 100644 --- a/openedx/features/course_experience/views/course_updates.py +++ b/openedx/features/course_experience/views/course_updates.py @@ -1,12 +1,15 @@ """ Views that handle course updates. """ +from __future__ import absolute_import + from datetime import datetime +import six from django.contrib.auth.decorators import login_required from django.template.context_processors import csrf -from django.urls import reverse from django.template.loader import render_to_string +from django.urls import reverse from django.utils.decorators import method_decorator from django.views.decorators.cache import cache_control from opaque_keys.edx.keys import CourseKey @@ -70,7 +73,7 @@ class CourseUpdatesView(CourseTabView): return USE_BOOTSTRAP_FLAG.is_enabled(course.id) def render_to_fragment(self, request, course=None, tab=None, **kwargs): - course_id = unicode(course.id) + course_id = six.text_type(course.id) updates_fragment_view = CourseUpdatesFragmentView() return updates_fragment_view.render_to_fragment(request, course_id=course_id, **kwargs) @@ -86,7 +89,7 @@ class CourseUpdatesFragmentView(EdxFragmentView): course_key = CourseKey.from_string(course_id) course = get_course_with_access(request.user, 'load', course_key, check_if_enrolled=True) course_url_name = default_course_url_name(course.id) - course_url = reverse(course_url_name, kwargs={'course_id': unicode(course.id)}) + course_url = reverse(course_url_name, kwargs={'course_id': six.text_type(course.id)}) ordered_updates = get_ordered_updates(request, course) plain_html_updates = '' diff --git a/openedx/features/course_experience/views/latest_update.py b/openedx/features/course_experience/views/latest_update.py index 765760761d..c70b154c15 100644 --- a/openedx/features/course_experience/views/latest_update.py +++ b/openedx/features/course_experience/views/latest_update.py @@ -6,6 +6,8 @@ this fragment dismisses the message for a limited time so new updates will continue to appear, where the welcome message gets permanently dismissed. """ +from __future__ import absolute_import + from django.template.loader import render_to_string from opaque_keys.edx.keys import CourseKey from web_fragments.fragment import Fragment diff --git a/openedx/features/course_experience/views/welcome_message.py b/openedx/features/course_experience/views/welcome_message.py index f9be8070e2..5edcf5d7e2 100644 --- a/openedx/features/course_experience/views/welcome_message.py +++ b/openedx/features/course_experience/views/welcome_message.py @@ -2,17 +2,21 @@ View logic for handling course welcome messages. """ -from django.urls import reverse +from __future__ import absolute_import + +import six from django.http import HttpResponse from django.template.loader import render_to_string +from django.urls import reverse from django.views.decorators.csrf import ensure_csrf_cookie from opaque_keys.edx.keys import CourseKey from web_fragments.fragment import Fragment -from course_updates import get_ordered_updates from courseware.courses import get_course_with_access from openedx.core.djangoapps.plugin_api.views import EdxFragmentView -from openedx.core.djangoapps.user_api.course_tag.api import set_course_tag, get_course_tag +from openedx.core.djangoapps.user_api.course_tag.api import get_course_tag, set_course_tag + +from .course_updates import get_ordered_updates PREFERENCE_KEY = 'view-welcome-message' @@ -34,7 +38,7 @@ class WelcomeMessageFragmentView(EdxFragmentView): return None dismiss_url = reverse( - 'openedx.course_experience.dismiss_welcome_message', kwargs={'course_id': unicode(course_key)} + 'openedx.course_experience.dismiss_welcome_message', kwargs={'course_id': six.text_type(course_key)} ) context = {