diff --git a/openedx/features/content_type_gating/admin.py b/openedx/features/content_type_gating/admin.py index 55001af551..2af443bbb8 100644 --- a/openedx/features/content_type_gating/admin.py +++ b/openedx/features/content_type_gating/admin.py @@ -3,12 +3,13 @@ Django Admin pages for ContentTypeGatingConfig. """ -from __future__ import unicode_literals +from __future__ import absolute_import, unicode_literals from django.contrib import admin from django.utils.translation import ugettext_lazy as _ from openedx.core.djangoapps.config_model_utils.admin import StackedConfigModelAdmin + from .models import ContentTypeGatingConfig diff --git a/openedx/features/content_type_gating/apps.py b/openedx/features/content_type_gating/apps.py index 00f3730cfb..5f082c7373 100644 --- a/openedx/features/content_type_gating/apps.py +++ b/openedx/features/content_type_gating/apps.py @@ -3,7 +3,7 @@ Define the content_type_gating Django App. """ # -*- coding: utf-8 -*- -from __future__ import unicode_literals +from __future__ import absolute_import, unicode_literals from django.apps import AppConfig diff --git a/openedx/features/content_type_gating/block_transformers.py b/openedx/features/content_type_gating/block_transformers.py index 01527bb9e5..9abf210305 100644 --- a/openedx/features/content_type_gating/block_transformers.py +++ b/openedx/features/content_type_gating/block_transformers.py @@ -2,11 +2,11 @@ Content Type Gate Transformer implementation. Limits access for certain users to certain types of content. """ +from __future__ import absolute_import + from django.conf import settings -from openedx.core.djangoapps.content.block_structure.transformer import ( - BlockStructureTransformer, -) +from openedx.core.djangoapps.content.block_structure.transformer import BlockStructureTransformer from openedx.features.content_type_gating.helpers import CONTENT_GATING_PARTITION_ID from openedx.features.content_type_gating.models import ContentTypeGatingConfig diff --git a/openedx/features/content_type_gating/field_override.py b/openedx/features/content_type_gating/field_override.py index c0c6c38903..b028567091 100644 --- a/openedx/features/content_type_gating/field_override.py +++ b/openedx/features/content_type_gating/field_override.py @@ -2,6 +2,8 @@ FieldOverride that forces graded components to be only accessible to students in the Unlocked Group of the ContentTypeGating partition. """ +from __future__ import absolute_import + from django.conf import settings from lms.djangoapps.courseware.field_overrides import FieldOverrideProvider diff --git a/openedx/features/content_type_gating/helpers.py b/openedx/features/content_type_gating/helpers.py index f1cf20d3e0..a3bf1072c2 100644 --- a/openedx/features/content_type_gating/helpers.py +++ b/openedx/features/content_type_gating/helpers.py @@ -1,10 +1,12 @@ """ Helper functions used by both content_type_gating and course_duration_limits. """ +from __future__ import absolute_import + import logging -from xmodule.partitions.partitions import Group from course_modes.models import CourseMode +from xmodule.partitions.partitions import Group # Studio generates partition IDs starting at 100. There is already a manually generated # partition for Enrollment Track that uses ID 50, so we'll use 51. diff --git a/openedx/features/content_type_gating/migrations/0001_initial.py b/openedx/features/content_type_gating/migrations/0001_initial.py index ab0e3f13df..99b8ba81e1 100644 --- a/openedx/features/content_type_gating/migrations/0001_initial.py +++ b/openedx/features/content_type_gating/migrations/0001_initial.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.16 on 2018-11-08 19:43 -from __future__ import unicode_literals +from __future__ import absolute_import, unicode_literals +import django.db.models.deletion from django.conf import settings from django.db import migrations, models -import django.db.models.deletion class Migration(migrations.Migration): diff --git a/openedx/features/content_type_gating/migrations/0002_auto_20181119_0959.py b/openedx/features/content_type_gating/migrations/0002_auto_20181119_0959.py index a71bec3f61..0d1f852d64 100644 --- a/openedx/features/content_type_gating/migrations/0002_auto_20181119_0959.py +++ b/openedx/features/content_type_gating/migrations/0002_auto_20181119_0959.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.16 on 2018-11-19 14:59 -from __future__ import unicode_literals +from __future__ import absolute_import, unicode_literals from django.db import migrations, models diff --git a/openedx/features/content_type_gating/migrations/0003_auto_20181128_1407.py b/openedx/features/content_type_gating/migrations/0003_auto_20181128_1407.py index 9a37b67076..d3238b15d1 100644 --- a/openedx/features/content_type_gating/migrations/0003_auto_20181128_1407.py +++ b/openedx/features/content_type_gating/migrations/0003_auto_20181128_1407.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.16 on 2018-11-28 19:07 -from __future__ import unicode_literals +from __future__ import absolute_import, unicode_literals from django.db import migrations, models diff --git a/openedx/features/content_type_gating/migrations/0004_auto_20181128_1521.py b/openedx/features/content_type_gating/migrations/0004_auto_20181128_1521.py index d963f0a1a7..c3ced64ef9 100644 --- a/openedx/features/content_type_gating/migrations/0004_auto_20181128_1521.py +++ b/openedx/features/content_type_gating/migrations/0004_auto_20181128_1521.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.16 on 2018-11-28 20:21 -from __future__ import unicode_literals +from __future__ import absolute_import, unicode_literals from django.db import migrations, models diff --git a/openedx/features/content_type_gating/migrations/0005_auto_20190306_1547.py b/openedx/features/content_type_gating/migrations/0005_auto_20190306_1547.py index 8259b40266..849fd29dc7 100644 --- a/openedx/features/content_type_gating/migrations/0005_auto_20190306_1547.py +++ b/openedx/features/content_type_gating/migrations/0005_auto_20190306_1547.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.20 on 2019-03-06 15:47 -from __future__ import unicode_literals +from __future__ import absolute_import, unicode_literals from django.db import migrations, models diff --git a/openedx/features/content_type_gating/migrations/0006_auto_20190308_1447.py b/openedx/features/content_type_gating/migrations/0006_auto_20190308_1447.py index 6e3792e462..040d343e66 100644 --- a/openedx/features/content_type_gating/migrations/0006_auto_20190308_1447.py +++ b/openedx/features/content_type_gating/migrations/0006_auto_20190308_1447.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.20 on 2019-03-08 14:47 -from __future__ import unicode_literals +from __future__ import absolute_import, unicode_literals from django.db import migrations, models diff --git a/openedx/features/content_type_gating/migrations/0007_auto_20190311_1919.py b/openedx/features/content_type_gating/migrations/0007_auto_20190311_1919.py index 1c2d2e18d9..e124fe7879 100644 --- a/openedx/features/content_type_gating/migrations/0007_auto_20190311_1919.py +++ b/openedx/features/content_type_gating/migrations/0007_auto_20190311_1919.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.20 on 2019-03-11 19:19 -from __future__ import unicode_literals +from __future__ import absolute_import, unicode_literals -from django.db import migrations, models import django.db.models.deletion +from django.db import migrations, models class Migration(migrations.Migration): diff --git a/openedx/features/content_type_gating/migrations/0008_auto_20190313_1634.py b/openedx/features/content_type_gating/migrations/0008_auto_20190313_1634.py index f0af785f80..69ae7282f0 100644 --- a/openedx/features/content_type_gating/migrations/0008_auto_20190313_1634.py +++ b/openedx/features/content_type_gating/migrations/0008_auto_20190313_1634.py @@ -1,8 +1,9 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.20 on 2019-03-13 16:34 -from __future__ import unicode_literals +from __future__ import absolute_import, unicode_literals from django.db import migrations, models + import openedx.core.djangoapps.config_model_utils.models diff --git a/openedx/features/content_type_gating/models.py b/openedx/features/content_type_gating/models.py index 6817e6d2b4..b3093f0450 100644 --- a/openedx/features/content_type_gating/models.py +++ b/openedx/features/content_type_gating/models.py @@ -3,20 +3,20 @@ Content Type Gating Configuration Models """ # -*- coding: utf-8 -*- -from __future__ import unicode_literals +from __future__ import absolute_import, unicode_literals from django.conf import settings from django.core.exceptions import ValidationError from django.db import models +from django.utils import timezone from django.utils.encoding import python_2_unicode_compatible from django.utils.translation import ugettext_lazy as _ -from django.utils import timezone from course_modes.models import CourseMode from lms.djangoapps.courseware.masquerade import ( get_course_masquerade, get_masquerading_user_group, - is_masquerading_as_specific_student, + is_masquerading_as_specific_student ) from openedx.core.djangoapps.config_model_utils.models import StackedConfigurationModel from openedx.core.djangoapps.config_model_utils.utils import is_in_holdback diff --git a/openedx/features/content_type_gating/partitions.py b/openedx/features/content_type_gating/partitions.py index 691260e26c..b3e8c492da 100644 --- a/openedx/features/content_type_gating/partitions.py +++ b/openedx/features/content_type_gating/partitions.py @@ -5,21 +5,22 @@ These are used together to allow course content to be blocked for a subset of audit learners. """ +from __future__ import absolute_import + import logging import crum -from django.apps import apps -from django.conf import settings +import six from django.template.loader import render_to_string from django.utils.translation import ugettext_lazy as _ from web_fragments.fragment import Fragment from course_modes.models import CourseMode from lms.djangoapps.commerce.utils import EcommerceService -from xmodule.partitions.partitions import UserPartition, UserPartitionError, ENROLLMENT_TRACK_PARTITION_ID from openedx.core.lib.mobile_utils import is_request_from_mobile_app -from openedx.features.content_type_gating.models import ContentTypeGatingConfig from openedx.features.content_type_gating.helpers import CONTENT_GATING_PARTITION_ID, FULL_ACCESS, LIMITED_ACCESS +from openedx.features.content_type_gating.models import ContentTypeGatingConfig +from xmodule.partitions.partitions import UserPartition, UserPartitionError LOG = logging.getLogger(__name__) @@ -55,7 +56,7 @@ def create_content_gating_partition(course): CONTENT_TYPE_GATING_SCHEME, CONTENT_GATING_PARTITION_ID, _get_partition_from_id(course.user_partitions, CONTENT_GATING_PARTITION_ID).name, - unicode(course.id), + six.text_type(course.id), ) return None @@ -63,7 +64,7 @@ def create_content_gating_partition(course): id=CONTENT_GATING_PARTITION_ID, name=_(u"Feature-based Enrollments"), description=_(u"Partition for segmenting users by access to gated content types"), - parameters={"course_id": unicode(course.id)} + parameters={"course_id": six.text_type(course.id)} ) return partition @@ -157,8 +158,8 @@ class ContentTypeGatingPartitionScheme(object): """ return ContentTypeGatingPartition( id, - unicode(name), - unicode(description), + six.text_type(name), + six.text_type(description), [ LIMITED_ACCESS, FULL_ACCESS, diff --git a/openedx/features/content_type_gating/tests/test_access.py b/openedx/features/content_type_gating/tests/test_access.py index dd769c6e7a..65413d2907 100644 --- a/openedx/features/content_type_gating/tests/test_access.py +++ b/openedx/features/content_type_gating/tests/test_access.py @@ -1,9 +1,13 @@ """ Test audit user's access to various content based on content-gating features. """ +from __future__ import absolute_import + import json from datetime import datetime, timedelta + import ddt +import six from django.conf import settings from django.test.client import RequestFactory from django.test.utils import override_settings @@ -12,47 +16,38 @@ from django.utils import timezone from mock import patch from course_api.blocks.api import get_blocks -from lms.djangoapps.discussion.django_comment_client.tests.factories import RoleFactory from course_modes.tests.factories import CourseModeFactory from experiments.models import ExperimentData, ExperimentKeyValue -from xmodule.partitions.partitions import ENROLLMENT_TRACK_PARTITION_ID - from lms.djangoapps.courseware.module_render import load_single_xblock from lms.djangoapps.courseware.tests.factories import ( - InstructorFactory, - StaffFactory, BetaTesterFactory, - OrgStaffFactory, - OrgInstructorFactory, GlobalStaffFactory, + InstructorFactory, + OrgInstructorFactory, + OrgStaffFactory, + StaffFactory ) +from lms.djangoapps.discussion.django_comment_client.tests.factories import RoleFactory from openedx.core.djangoapps.django_comment_common.models import ( FORUM_ROLE_ADMINISTRATOR, - FORUM_ROLE_MODERATOR, - FORUM_ROLE_GROUP_MODERATOR, FORUM_ROLE_COMMUNITY_TA, + FORUM_ROLE_GROUP_MODERATOR, + FORUM_ROLE_MODERATOR, Role ) from openedx.core.djangoapps.user_api.tests.factories import UserCourseTagFactory from openedx.core.djangoapps.util.testing import TestConditionalContent from openedx.core.lib.url_utils import quote_slashes from openedx.features.content_type_gating.helpers import CONTENT_GATING_PARTITION_ID, CONTENT_TYPE_GATE_GROUP_IDS -from openedx.features.content_type_gating.partitions import ContentTypeGatingPartition from openedx.features.content_type_gating.models import ContentTypeGatingConfig -from openedx.features.course_duration_limits.config import ( - EXPERIMENT_DATA_HOLDBACK_KEY, - EXPERIMENT_ID, -) +from openedx.features.content_type_gating.partitions import ContentTypeGatingPartition +from openedx.features.course_duration_limits.config import EXPERIMENT_DATA_HOLDBACK_KEY, EXPERIMENT_ID from student.models import CourseEnrollment from student.roles import CourseInstructorRole -from student.tests.factories import ( - CourseEnrollmentFactory, - UserFactory, - TEST_PASSWORD -) +from student.tests.factories import TEST_PASSWORD, CourseEnrollmentFactory, UserFactory from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase, SharedModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory - +from xmodule.partitions.partitions import ENROLLMENT_TRACK_PARTITION_ID METADATA = { 'group_access': { @@ -77,8 +72,8 @@ def _get_fragment_from_block(block, user_id, course, request_factory, mock_get_c vertical_xblock = load_single_xblock( request=fake_request, user_id=user_id, - course_id=unicode(course.id), - usage_key_string=unicode(course.scope_ids.usage_id), + course_id=six.text_type(course.id), + usage_key_string=six.text_type(course.scope_ids.usage_id), course=course ) runtime = vertical_xblock.runtime @@ -476,8 +471,8 @@ class TestProblemTypeAccess(SharedModuleStoreTestCase): url = reverse( 'xblock_handler', kwargs={ - 'course_id': unicode(self.course.id), - 'usage_id': quote_slashes(unicode(problem_location)), + 'course_id': six.text_type(self.course.id), + 'usage_id': quote_slashes(six.text_type(problem_location)), 'handler': 'xmodule_handler', 'suffix': 'problem_show', } @@ -594,7 +589,7 @@ class TestProblemTypeAccess(SharedModuleStoreTestCase): self.update_masquerade(**masquerade_config) block = self.blocks_dict['problem'] - block_view_url = reverse('render_xblock', kwargs={'usage_key_string': unicode(block.scope_ids.usage_id)}) + block_view_url = reverse('render_xblock', kwargs={'usage_key_string': six.text_type(block.scope_ids.usage_id)}) response = self.client.get(block_view_url) if is_gated: self.assertEquals(response.status_code, 404) @@ -608,7 +603,7 @@ class TestProblemTypeAccess(SharedModuleStoreTestCase): masquerade_url = reverse( 'masquerade_update', kwargs={ - 'course_key_string': unicode(self.course.id), + 'course_key_string': six.text_type(self.course.id), } ) response = self.client.post( @@ -654,7 +649,7 @@ class TestProblemTypeAccess(SharedModuleStoreTestCase): self.update_masquerade(username=user.username) block = self.blocks_dict['problem'] - block_view_url = reverse('render_xblock', kwargs={'usage_key_string': unicode(block.scope_ids.usage_id)}) + block_view_url = reverse('render_xblock', kwargs={'usage_key_string': six.text_type(block.scope_ids.usage_id)}) response = self.client.get(block_view_url) self.assertEquals(response.status_code, 200) diff --git a/openedx/features/content_type_gating/tests/test_models.py b/openedx/features/content_type_gating/tests/test_models.py index bc5fbb8861..59e3bc8c71 100644 --- a/openedx/features/content_type_gating/tests/test_models.py +++ b/openedx/features/content_type_gating/tests/test_models.py @@ -1,12 +1,13 @@ -from datetime import timedelta, datetime +from __future__ import absolute_import + import itertools +from datetime import datetime, timedelta import ddt -from django.utils import timezone -from mock import Mock import pytz - +from django.utils import timezone from edx_django_utils.cache import RequestCache +from mock import Mock from opaque_keys.edx.locator import CourseLocator from course_modes.tests.factories import CourseModeFactory diff --git a/openedx/features/content_type_gating/tests/test_partitions.py b/openedx/features/content_type_gating/tests/test_partitions.py index 1fdd41442d..a6e6a6f8f8 100644 --- a/openedx/features/content_type_gating/tests/test_partitions.py +++ b/openedx/features/content_type_gating/tests/test_partitions.py @@ -1,20 +1,20 @@ +from __future__ import absolute_import + from datetime import datetime -from mock import Mock, patch + from django.conf import settings from django.test import RequestFactory +from mock import Mock, patch +from opaque_keys.edx.keys import CourseKey from course_modes.tests.factories import CourseModeFactory from lms.djangoapps.courseware.tests.factories import GlobalStaffFactory -from opaque_keys.edx.keys import CourseKey from openedx.core.djangolib.testing.utils import CacheIsolationTestCase from openedx.features.content_type_gating.helpers import CONTENT_GATING_PARTITION_ID, FULL_ACCESS, LIMITED_ACCESS -from openedx.features.content_type_gating.partitions import ( - create_content_gating_partition, - ContentTypeGatingPartition -) from openedx.features.content_type_gating.models import ContentTypeGatingConfig +from openedx.features.content_type_gating.partitions import ContentTypeGatingPartition, create_content_gating_partition from student.tests.factories import GroupFactory -from xmodule.partitions.partitions import UserPartitionError, ENROLLMENT_TRACK_PARTITION_ID +from xmodule.partitions.partitions import ENROLLMENT_TRACK_PARTITION_ID, UserPartitionError class TestContentTypeGatingPartition(CacheIsolationTestCase):