diff --git a/cms/djangoapps/contentstore/course_group_config.py b/cms/djangoapps/contentstore/course_group_config.py index 6bcbee47a7..7335c16ae2 100644 --- a/cms/djangoapps/contentstore/course_group_config.py +++ b/cms/djangoapps/contentstore/course_group_config.py @@ -4,13 +4,12 @@ Class for manipulating groups configuration on a course object. import json import logging -from util.db import generate_int_id, MYSQL_MAX_INT - -from django.utils.translation import ugettext as _ from contentstore.utils import reverse_usage_url +from django.utils.translation import ugettext as _ from openedx.core.djangoapps.course_groups.partition_scheme import get_cohorted_user_partition -from xmodule.partitions.partitions import UserPartition, MINIMUM_STATIC_PARTITION_ID -from xmodule.partitions.partitions_service import get_all_partitions_for_course +from openedx.core.lib.partitions.partitions import MINIMUM_STATIC_PARTITION_ID, UserPartition +from openedx.core.lib.partitions.partitions_service import get_all_partitions_for_course +from util.db import MYSQL_MAX_INT, generate_int_id from xmodule.split_test_module import get_split_user_partitions MINIMUM_GROUP_ID = MINIMUM_STATIC_PARTITION_ID diff --git a/cms/djangoapps/contentstore/tests/test_course_settings.py b/cms/djangoapps/contentstore/tests/test_course_settings.py index 5fe8f575e4..73f473b950 100644 --- a/cms/djangoapps/contentstore/tests/test_course_settings.py +++ b/cms/djangoapps/contentstore/tests/test_course_settings.py @@ -1,35 +1,34 @@ """ Tests for Studio Course Settings. """ -import datetime -import ddt -import json import copy -import mock -from mock import Mock, patch +import datetime +import json import unittest -from django.conf import settings -from django.utils.timezone import UTC -from django.test.utils import override_settings - +import ddt +import mock from contentstore.utils import reverse_course_url, reverse_usage_url +from django.conf import settings +from django.test.utils import override_settings +from django.utils.timezone import UTC +from milestones.tests.utils import MilestonesTestCaseMixin +from mock import Mock, patch from models.settings.course_grading import CourseGradingModel from models.settings.course_metadata import CourseMetadata from models.settings.encoder import CourseSettingsEncoder -from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration from openedx.core.djangoapps.models.course_details import CourseDetails +from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration +from openedx.core.lib.xblock_fields.fields import Date from student.roles import CourseInstructorRole, CourseStaffRole from student.tests.factories import UserFactory from xblock_django.models import XBlockStudioConfigurationFlag -from xmodule.fields import Date from xmodule.modulestore import ModuleStoreEnum from xmodule.modulestore.django import modulestore from xmodule.modulestore.tests.factories import CourseFactory from xmodule.tabs import InvalidTabsException -from milestones.tests.utils import MilestonesTestCaseMixin -from .utils import CourseTestCase, AjaxEnabledTestClient +from .utils import AjaxEnabledTestClient, CourseTestCase def get_url(course_id, handler_name='settings_handler'): diff --git a/cms/djangoapps/contentstore/tests/test_courseware_index.py b/cms/djangoapps/contentstore/tests/test_courseware_index.py index aaa305f0c3..0c438ccc16 100644 --- a/cms/djangoapps/contentstore/tests/test_courseware_index.py +++ b/cms/djangoapps/contentstore/tests/test_courseware_index.py @@ -1,52 +1,52 @@ """ Testing indexing of the courseware as it is changed """ -import ddt import json -from lazy.lazy import lazy import time from datetime import datetime -from dateutil.tz import tzutc -from mock import patch -from pytz import UTC -from uuid import uuid4 from unittest import skip +from uuid import uuid4 -from django.conf import settings - +import ddt +from contentstore.courseware_index import ( + CourseAboutSearchIndexer, + CoursewareSearchIndexer, + LibrarySearchIndexer, + SearchIndexingError +) +from contentstore.signals.handlers import listen_for_course_publish, listen_for_library_update +from contentstore.tests.utils import CourseTestCase +from contentstore.utils import reverse_course_url, reverse_usage_url from course_modes.models import CourseMode +from dateutil.tz import tzutc +from django.conf import settings +from lazy.lazy import lazy +from mock import patch from openedx.core.djangoapps.models.course_details import CourseDetails +from openedx.core.lib.partitions.partitions import UserPartition +from openedx.core.lib.xblock_fields.inherited_fields import InheritanceMixin +from pytz import UTC +from search.search_engine_base import SearchEngine from xmodule.library_tools import normalize_key_for_search from xmodule.modulestore import ModuleStoreEnum from xmodule.modulestore.django import SignalHandler, modulestore from xmodule.modulestore.edit_info import EditInfoMixin -from xmodule.modulestore.inheritance import InheritanceMixin from xmodule.modulestore.mixed import MixedModuleStore from xmodule.modulestore.tests.django_utils import ( TEST_DATA_MONGO_MODULESTORE, TEST_DATA_SPLIT_MODULESTORE, - SharedModuleStoreTestCase) + SharedModuleStoreTestCase +) from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory, LibraryFactory -from xmodule.modulestore.tests.mongo_connection import MONGO_PORT_NUM, MONGO_HOST +from xmodule.modulestore.tests.mongo_connection import MONGO_HOST, MONGO_PORT_NUM from xmodule.modulestore.tests.utils import ( - create_modulestore_instance, LocationMixin, - MixedSplitTestCase, MongoContentstoreBuilder + LocationMixin, + MixedSplitTestCase, + MongoContentstoreBuilder, + create_modulestore_instance ) from xmodule.tests import DATA_DIR from xmodule.x_module import XModuleMixin -from xmodule.partitions.partitions import UserPartition - -from search.search_engine_base import SearchEngine - -from contentstore.courseware_index import ( - CoursewareSearchIndexer, - LibrarySearchIndexer, - SearchIndexingError, - CourseAboutSearchIndexer, -) -from contentstore.signals.handlers import listen_for_course_publish, listen_for_library_update -from contentstore.utils import reverse_course_url, reverse_usage_url -from contentstore.tests.utils import CourseTestCase COURSE_CHILD_STRUCTURE = { "course": "chapter", diff --git a/cms/djangoapps/contentstore/tests/test_utils.py b/cms/djangoapps/contentstore/tests/test_utils.py index f73447e4b2..de8fa67b75 100644 --- a/cms/djangoapps/contentstore/tests/test_utils.py +++ b/cms/djangoapps/contentstore/tests/test_utils.py @@ -2,19 +2,17 @@ import collections from datetime import datetime, timedelta -from pytz import UTC -from django.test import TestCase -from xmodule.modulestore import ModuleStoreEnum -from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory -from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase, SharedModuleStoreTestCase -from opaque_keys.edx.locations import SlashSeparatedCourseKey -from xmodule.modulestore.django import modulestore -from xmodule.partitions.partitions import UserPartition, Group - -from openedx.core.djangoapps.site_configuration.tests.test_util import with_site_configuration_context - from contentstore import utils from contentstore.tests.utils import CourseTestCase +from django.test import TestCase +from opaque_keys.edx.locations import SlashSeparatedCourseKey +from openedx.core.djangoapps.site_configuration.tests.test_util import with_site_configuration_context +from openedx.core.lib.partitions.partitions import Group, UserPartition +from pytz import UTC +from xmodule.modulestore import ModuleStoreEnum +from xmodule.modulestore.django import modulestore +from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase, SharedModuleStoreTestCase +from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory class LMSLinksTestCase(TestCase): diff --git a/cms/djangoapps/contentstore/utils.py b/cms/djangoapps/contentstore/utils.py index a414f5815c..cc5079bcb2 100644 --- a/cms/djangoapps/contentstore/utils.py +++ b/cms/djangoapps/contentstore/utils.py @@ -4,26 +4,23 @@ Common utility functions useful throughout the contentstore import logging from datetime import datetime -from pytz import UTC from django.conf import settings from django.core.urlresolvers import reverse from django.utils.translation import ugettext as _ from django_comment_common.models import assign_default_role from django_comment_common.utils import seed_permissions_roles - +from opaque_keys.edx.keys import CourseKey, UsageKey from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration from openedx.core.djangoapps.site_configuration.models import SiteConfiguration -from xmodule.partitions.partitions_service import get_all_partitions_for_course - +from openedx.core.lib.partitions.partitions_service import get_all_partitions_for_course +from pytz import UTC +from student import auth +from student.models import CourseEnrollment +from student.roles import CourseInstructorRole, CourseStaffRole from xmodule.modulestore import ModuleStoreEnum from xmodule.modulestore.django import modulestore from xmodule.modulestore.exceptions import ItemNotFoundError -from opaque_keys.edx.keys import UsageKey, CourseKey -from student.roles import CourseInstructorRole, CourseStaffRole -from student.models import CourseEnrollment -from student import auth - log = logging.getLogger(__name__) diff --git a/cms/djangoapps/contentstore/views/course.py b/cms/djangoapps/contentstore/views/course.py index 35d8ef367c..a040e5df71 100644 --- a/cms/djangoapps/contentstore/views/course.py +++ b/cms/djangoapps/contentstore/views/course.py @@ -70,6 +70,7 @@ from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers from openedx.core.lib.course_tabs import CourseTabPluginManager from openedx.core.lib.courses import course_image_url +from openedx.core.lib.xblock_fields.inherited_fields import DEFAULT_START_DATE from openedx.core.djangolib.js_utils import dump_js_escaped_json from student import auth from student.auth import has_course_author_access, has_studio_write_access, has_studio_read_access @@ -94,7 +95,6 @@ from util.string_utils import _has_non_ascii_characters from xblock_django.api import deprecated_xblocks from xmodule.contentstore.content import StaticContent from xmodule.course_module import CourseFields -from xmodule.course_module import DEFAULT_START_DATE from xmodule.error_module import ErrorDescriptor from xmodule.modulestore import EdxJSONEncoder from xmodule.modulestore.django import modulestore diff --git a/cms/djangoapps/contentstore/views/item.py b/cms/djangoapps/contentstore/views/item.py index e6510be15a..234dc3e223 100644 --- a/cms/djangoapps/contentstore/views/item.py +++ b/cms/djangoapps/contentstore/views/item.py @@ -38,16 +38,16 @@ from contentstore.views.helpers import is_unit, xblock_studio_url, xblock_primar from contentstore.views.preview import get_preview_fragment from contentstore.utils import is_self_paced -from openedx.core.lib.gating import api as gating_api from edxmako.shortcuts import render_to_string from models.settings.course_grading import CourseGradingModel +from openedx.core.lib.gating import api as gating_api from openedx.core.lib.xblock_utils import wrap_xblock, request_token +from openedx.core.lib.xblock_fields.inherited_fields import DEFAULT_START_DATE from static_replace import replace_static_urls from student.auth import has_studio_write_access, has_studio_read_access from util.date_utils import get_default_time_display from util.json_request import expect_json, JsonResponse from util.milestones_helpers import is_entrance_exams_enabled -from xmodule.course_module import DEFAULT_START_DATE from xmodule.modulestore import ModuleStoreEnum, EdxJSONEncoder from xmodule.modulestore.django import modulestore from xmodule.modulestore.draft_and_published import DIRECT_ONLY_CATEGORIES diff --git a/cms/djangoapps/contentstore/views/preview.py b/cms/djangoapps/contentstore/views/preview.py index 5d728c4aa9..a10e263856 100644 --- a/cms/djangoapps/contentstore/views/preview.py +++ b/cms/djangoapps/contentstore/views/preview.py @@ -3,45 +3,45 @@ from __future__ import absolute_import import logging from functools import partial +import static_replace +from cms.lib.xblock.field_data import CmsFieldData +from contentstore.utils import get_visibility_partition_info +from contentstore.views.access import get_user_role from django.conf import settings +from django.contrib.auth.decorators import login_required from django.core.urlresolvers import reverse from django.http import Http404, HttpResponseBadRequest -from django.contrib.auth.decorators import login_required from django.utils.translation import ugettext as _ from edxmako.shortcuts import render_to_string - +from lms.djangoapps.lms_xblock.field_data import LmsFieldData +from opaque_keys.edx.keys import UsageKey +from openedx.core.lib.partitions.partitions_service import PartitionService from openedx.core.lib.xblock_utils import ( - replace_static_urls, wrap_xblock, wrap_fragment, wrap_xblock_aside, request_token, xblock_local_resource_url, + replace_static_urls, + request_token, + wrap_fragment, + wrap_xblock, + wrap_xblock_aside, + xblock_local_resource_url ) -from xmodule.x_module import PREVIEW_VIEWS, STUDENT_VIEW, AUTHOR_VIEW +from util.sandboxing import can_execute_unsafe_code, get_python_lib_zip +from xblock.django.request import django_to_webob_request, webob_to_django_response +from xblock.exceptions import NoSuchHandlerError +from xblock.fragment import Fragment +from xblock.runtime import KvsFieldData +from xblock_config.models import StudioConfig +from xblock_django.user_service import DjangoXBlockUserService from xmodule.contentstore.django import contentstore from xmodule.error_module import ErrorDescriptor from xmodule.exceptions import NotFoundError, ProcessingError -from xmodule.partitions.partitions_service import PartitionService -from xmodule.studio_editable import has_author_view -from xmodule.services import SettingsService -from xmodule.modulestore.django import modulestore, ModuleI18nService from xmodule.mixin import wrap_with_license -from opaque_keys.edx.keys import UsageKey -from xmodule.x_module import ModuleSystem -from xblock.runtime import KvsFieldData -from xblock.django.request import webob_to_django_response, django_to_webob_request -from xblock.exceptions import NoSuchHandlerError -from xblock.fragment import Fragment -from xblock_django.user_service import DjangoXBlockUserService +from xmodule.modulestore.django import ModuleI18nService, modulestore +from xmodule.services import SettingsService +from xmodule.studio_editable import has_author_view +from xmodule.x_module import AUTHOR_VIEW, PREVIEW_VIEWS, STUDENT_VIEW, ModuleSystem -from lms.djangoapps.lms_xblock.field_data import LmsFieldData -from cms.lib.xblock.field_data import CmsFieldData - -from util.sandboxing import can_execute_unsafe_code, get_python_lib_zip - -import static_replace -from .session_kv_store import SessionKeyValueStore from .helpers import render_from_lms - -from contentstore.utils import get_visibility_partition_info -from contentstore.views.access import get_user_role -from xblock_config.models import StudioConfig +from .session_kv_store import SessionKeyValueStore __all__ = ['preview_handler'] diff --git a/cms/djangoapps/contentstore/views/tests/test_group_configurations.py b/cms/djangoapps/contentstore/views/tests/test_group_configurations.py index ff2710c3ef..f065bf58ed 100644 --- a/cms/djangoapps/contentstore/views/tests/test_group_configurations.py +++ b/cms/djangoapps/contentstore/views/tests/test_group_configurations.py @@ -4,17 +4,17 @@ Group Configuration Tests. """ import json -import ddt -from mock import patch -from contentstore.utils import reverse_course_url, reverse_usage_url -from contentstore.course_group_config import GroupConfiguration, CONTENT_GROUP_CONFIGURATION_NAME +import ddt +from contentstore.course_group_config import CONTENT_GROUP_CONFIGURATION_NAME, GroupConfiguration from contentstore.tests.utils import CourseTestCase -from xmodule.partitions.partitions import Group, UserPartition +from contentstore.utils import reverse_course_url, reverse_usage_url +from mock import patch +from openedx.core.lib.partitions.partitions import Group, UserPartition +from xmodule.modulestore import ModuleStoreEnum +from xmodule.modulestore.django import modulestore from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory from xmodule.validation import StudioValidation, StudioValidationMessage -from xmodule.modulestore.django import modulestore -from xmodule.modulestore import ModuleStoreEnum GROUP_CONFIGURATION_JSON = { u'name': u'Test name', diff --git a/cms/djangoapps/contentstore/views/tests/test_item.py b/cms/djangoapps/contentstore/views/tests/test_item.py index 11c675b719..3c41a7b01c 100644 --- a/cms/djangoapps/contentstore/views/tests/test_item.py +++ b/cms/djangoapps/contentstore/views/tests/test_item.py @@ -1,53 +1,56 @@ """Tests for items views.""" import json from datetime import datetime, timedelta + import ddt - -from mock import patch, Mock, PropertyMock -from pytz import UTC -from pyquery import PyQuery -from webob import Response - +from contentstore.tests.utils import CourseTestCase +from contentstore.utils import reverse_course_url, reverse_usage_url +from contentstore.views.component import component_handler, get_component_templates +from contentstore.views.item import ( + ALWAYS, + VisibilityState, + _get_module_info, + _get_source_index, + _xblock_type_and_display_name, + add_container_page_publishing_info, + create_xblock_info +) from django.conf import settings +from django.core.urlresolvers import reverse from django.http import Http404 from django.test import TestCase from django.test.client import RequestFactory -from django.core.urlresolvers import reverse -from contentstore.utils import reverse_usage_url, reverse_course_url - +from mock import Mock, PropertyMock, patch from opaque_keys import InvalidKeyError +from opaque_keys.edx.keys import CourseKey, UsageKey +from opaque_keys.edx.locations import Location from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration -from contentstore.views.component import ( - component_handler, get_component_templates +from openedx.core.lib.partitions.partitions import ( + ENROLLMENT_TRACK_PARTITION_ID, + MINIMUM_STATIC_PARTITION_ID, + Group, + UserPartition ) - -from contentstore.views.item import ( - create_xblock_info, _get_source_index, _get_module_info, ALWAYS, VisibilityState, _xblock_type_and_display_name, - add_container_page_publishing_info -) -from contentstore.tests.utils import CourseTestCase +from openedx.core.lib.xblock_fields.inherited_fields import DEFAULT_START_DATE +from pyquery import PyQuery +from pytz import UTC from student.tests.factories import UserFactory +from webob import Response +from xblock.core import XBlockAside +from xblock.exceptions import NoSuchHandlerError +from xblock.fields import Scope, ScopeIds, String +from xblock.fragment import Fragment +from xblock.runtime import DictKeyValueStore, KvsFieldData +from xblock.test.tools import TestRuntime from xblock_django.models import XBlockConfiguration, XBlockStudioConfiguration, XBlockStudioConfigurationFlag +from xblock_django.user_service import DjangoXBlockUserService from xmodule.capa_module import CapaDescriptor from xmodule.modulestore import ModuleStoreEnum from xmodule.modulestore.django import modulestore from xmodule.modulestore.exceptions import ItemNotFoundError -from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase, TEST_DATA_SPLIT_MODULESTORE -from xmodule.modulestore.tests.factories import ItemFactory, LibraryFactory, check_mongo_calls, CourseFactory -from xmodule.x_module import STUDIO_VIEW, STUDENT_VIEW -from xmodule.course_module import DEFAULT_START_DATE -from xblock.core import XBlockAside -from xblock.fields import Scope, String, ScopeIds -from xblock.fragment import Fragment -from xblock.runtime import DictKeyValueStore, KvsFieldData -from xblock.test.tools import TestRuntime -from xblock.exceptions import NoSuchHandlerError -from xblock_django.user_service import DjangoXBlockUserService -from opaque_keys.edx.keys import UsageKey, CourseKey -from opaque_keys.edx.locations import Location -from xmodule.partitions.partitions import ( - Group, UserPartition, ENROLLMENT_TRACK_PARTITION_ID, MINIMUM_STATIC_PARTITION_ID -) +from xmodule.modulestore.tests.django_utils import TEST_DATA_SPLIT_MODULESTORE, ModuleStoreTestCase +from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory, LibraryFactory, check_mongo_calls +from xmodule.x_module import STUDENT_VIEW, STUDIO_VIEW class AsideTest(XBlockAside): diff --git a/cms/djangoapps/models/settings/encoder.py b/cms/djangoapps/models/settings/encoder.py index 36b6e1fb44..f048d3c15f 100644 --- a/cms/djangoapps/models/settings/encoder.py +++ b/cms/djangoapps/models/settings/encoder.py @@ -7,7 +7,7 @@ from json.encoder import JSONEncoder from opaque_keys.edx.locations import Location from openedx.core.djangoapps.models.course_details import CourseDetails -from xmodule.fields import Date +from openedx.core.lib.xblock_fields.fields import Date from .course_grading import CourseGradingModel diff --git a/cms/envs/common.py b/cms/envs/common.py index cef002da59..3593c00fc7 100644 --- a/cms/envs/common.py +++ b/cms/envs/common.py @@ -432,7 +432,7 @@ P3P_HEADER = 'CP="Open EdX does not have a P3P policy."' ############# XBlock Configuration ########## # Import after sys.path fixup -from xmodule.modulestore.inheritance import InheritanceMixin +from openedx.core.lib.xblock_fields.inherited_fields import InheritanceMixin from xmodule.modulestore import prefer_xmodules from xmodule.x_module import XModuleMixin diff --git a/cms/lib/xblock/test/test_authoring_mixin.py b/cms/lib/xblock/test/test_authoring_mixin.py index c45270c70a..a72eba4664 100644 --- a/cms/lib/xblock/test/test_authoring_mixin.py +++ b/cms/lib/xblock/test/test_authoring_mixin.py @@ -1,16 +1,17 @@ """ Tests for the Studio authoring XBlock mixin. """ +from course_modes.tests.factories import CourseModeFactory from django.conf import settings from django.test.utils import override_settings - -from course_modes.tests.factories import CourseModeFactory - +from openedx.core.lib.partitions.partitions import ( + ENROLLMENT_TRACK_PARTITION_ID, + MINIMUM_STATIC_PARTITION_ID, + Group, + UserPartition +) from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory -from xmodule.partitions.partitions import ( - Group, UserPartition, ENROLLMENT_TRACK_PARTITION_ID, MINIMUM_STATIC_PARTITION_ID -) class AuthoringMixinTestCase(ModuleStoreTestCase): diff --git a/common/lib/xmodule/xmodule/capa_base.py b/common/lib/xmodule/xmodule/capa_base.py index 847eed20fc..55f2d25dac 100644 --- a/common/lib/xmodule/xmodule/capa_base.py +++ b/common/lib/xmodule/xmodule/capa_base.py @@ -11,26 +11,27 @@ import struct import sys import traceback +from capa.capa_problem import LoncapaProblem, LoncapaSystem +from capa.inputtypes import Status +from capa.responsetypes import LoncapaProblemError, ResponseError, StudentInputError +from capa.util import convert_files_to_filenames, get_inner_html_from_xpath from django.conf import settings +from openedx.core.djangolib.markup import HTML, Text +from openedx.core.lib.xblock_fields.fields import Date, Timedelta +from pytz import utc +from xblock.fields import Boolean, Dict, Float, Integer, Scope, String, XMLString +from xblock.scorable import ScorableXBlockMixin, Score +from xmodule.capa_base_constants import RANDOMIZATION, SHOW_CORRECTNESS, SHOWANSWER +from xmodule.exceptions import NotFoundError + +from .progress import Progress + # We don't want to force a dependency on datadog, so make the import conditional try: import dogstats_wrapper as dog_stats_api except ImportError: dog_stats_api = None -from pytz import utc -from capa.capa_problem import LoncapaProblem, LoncapaSystem -from capa.inputtypes import Status -from capa.responsetypes import StudentInputError, ResponseError, LoncapaProblemError -from capa.util import convert_files_to_filenames, get_inner_html_from_xpath -from xblock.fields import Boolean, Dict, Float, Integer, Scope, String, XMLString -from xblock.scorable import ScorableXBlockMixin, Score -from xmodule.capa_base_constants import RANDOMIZATION, SHOWANSWER, SHOW_CORRECTNESS -from xmodule.exceptions import NotFoundError -from .fields import Date, Timedelta -from .progress import Progress - -from openedx.core.djangolib.markup import HTML, Text log = logging.getLogger("edx.courseware") diff --git a/common/lib/xmodule/xmodule/course_metadata_utils.py b/common/lib/xmodule/xmodule/course_metadata_utils.py index e0a2e996ed..cdf4d48bcd 100644 --- a/common/lib/xmodule/xmodule/course_metadata_utils.py +++ b/common/lib/xmodule/xmodule/course_metadata_utils.py @@ -12,7 +12,7 @@ from math import exp from pytz import utc -DEFAULT_START_DATE = datetime(2030, 1, 1, tzinfo=utc) +from openedx.core.lib.xblock_fields.inherited_fields import DEFAULT_START_DATE def clean_course_key(course_key, padding_char): diff --git a/common/lib/xmodule/xmodule/course_module.py b/common/lib/xmodule/xmodule/course_module.py index e32356062f..8ee3776a7d 100644 --- a/common/lib/xmodule/xmodule/course_module.py +++ b/common/lib/xmodule/xmodule/course_module.py @@ -9,17 +9,16 @@ from datetime import datetime import requests from lazy import lazy from lxml import etree +from openedx.core.lib.xblock_fields.fields import Date +from openedx.core.lib.xblock_fields.inherited_fields import DEFAULT_START_DATE from path import Path as path from pytz import utc -from xblock.fields import Scope, List, String, Dict, Boolean, Integer, Float - +from xblock.fields import Boolean, Dict, Float, Integer, List, Scope, String from xmodule import course_metadata_utils -from xmodule.course_metadata_utils import DEFAULT_START_DATE from xmodule.graders import grader_from_conf from xmodule.mixin import LicenseMixin from xmodule.seq_module import SequenceDescriptor, SequenceModule from xmodule.tabs import CourseTabList, InvalidTabsException -from .fields import Date log = logging.getLogger(__name__) diff --git a/common/lib/xmodule/xmodule/modulestore/inheritance.py b/common/lib/xmodule/xmodule/modulestore/inheritance.py index 91c2811b35..351e87c771 100644 --- a/common/lib/xmodule/xmodule/modulestore/inheritance.py +++ b/common/lib/xmodule/xmodule/modulestore/inheritance.py @@ -4,236 +4,9 @@ Support for inheritance of fields down an XBlock hierarchy. from __future__ import absolute_import from django.conf import settings - -from xmodule.partitions.partitions import UserPartition -from xblock.fields import Scope, Boolean, String, Float, XBlockMixin, Dict, Integer, List +from openedx.core.lib.xblock_fields.inherited_fields import InheritanceMixin +from xblock.fields import Scope from xblock.runtime import KeyValueStore, KvsFieldData -from xmodule.fields import Date, Timedelta -from ..course_metadata_utils import DEFAULT_START_DATE - - -# Make '_' a no-op so we can scrape strings -# Using lambda instead of `django.utils.translation.ugettext_noop` because Django cannot be imported in this file -_ = lambda text: text - - -class UserPartitionList(List): - """Special List class for listing UserPartitions""" - def from_json(self, values): - return [UserPartition.from_json(v) for v in values] - - def to_json(self, values): - return [user_partition.to_json() - for user_partition in values] - - -class InheritanceMixin(XBlockMixin): - """Field definitions for inheritable fields.""" - - graded = Boolean( - help="Whether this module contributes to the final course grade", - scope=Scope.settings, - default=False, - ) - start = Date( - help="Start time when this module is visible", - default=DEFAULT_START_DATE, - scope=Scope.settings - ) - due = Date( - display_name=_("Due Date"), - help=_("Enter the default date by which problems are due."), - scope=Scope.settings, - ) - visible_to_staff_only = Boolean( - help=_("If true, can be seen only by course staff, regardless of start date."), - default=False, - scope=Scope.settings, - ) - course_edit_method = String( - display_name=_("Course Editor"), - help=_("Enter the method by which this course is edited (\"XML\" or \"Studio\")."), - default="Studio", - scope=Scope.settings, - deprecated=True # Deprecated because user would not change away from Studio within Studio. - ) - giturl = String( - display_name=_("GIT URL"), - help=_("Enter the URL for the course data GIT repository."), - scope=Scope.settings - ) - xqa_key = String( - display_name=_("XQA Key"), - help=_("This setting is not currently supported."), scope=Scope.settings, - deprecated=True - ) - annotation_storage_url = String( - help=_("Enter the location of the annotation storage server. The textannotation, videoannotation, and imageannotation advanced modules require this setting."), - scope=Scope.settings, - default="http://your_annotation_storage.com", - display_name=_("URL for Annotation Storage") - ) - annotation_token_secret = String( - help=_("Enter the secret string for annotation storage. The textannotation, videoannotation, and imageannotation advanced modules require this string."), - scope=Scope.settings, - default="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - display_name=_("Secret Token String for Annotation") - ) - graceperiod = Timedelta( - help="Amount of time after the due date that submissions will be accepted", - scope=Scope.settings, - ) - group_access = Dict( - help=_("Enter the ids for the content groups this problem belongs to."), - scope=Scope.settings, - ) - - showanswer = String( - display_name=_("Show Answer"), - help=_( - # Translators: DO NOT translate the words in quotes here, they are - # specific words for the acceptable values. - 'Specify when the Show Answer button appears for each problem. ' - 'Valid values are "always", "answered", "attempted", "closed", ' - '"finished", "past_due", "correct_or_past_due", and "never".' - ), - scope=Scope.settings, - default="finished", - ) - - show_correctness = String( - display_name=_("Show Results"), - help=_( - # Translators: DO NOT translate the words in quotes here, they are - # specific words for the acceptable values. - 'Specify when to show answer correctness and score to learners. ' - 'Valid values are "always", "never", and "past_due".' - ), - scope=Scope.settings, - default="always", - ) - - rerandomize = String( - display_name=_("Randomization"), - help=_( - # Translators: DO NOT translate the words in quotes here, they are - # specific words for the acceptable values. - 'Specify the default for how often variable values in a problem are randomized. ' - 'This setting should be set to "never" unless you plan to provide a Python ' - 'script to identify and randomize values in most of the problems in your course. ' - 'Valid values are "always", "onreset", "never", and "per_student".' - ), - scope=Scope.settings, - default="never", - ) - days_early_for_beta = Float( - display_name=_("Days Early for Beta Users"), - help=_("Enter the number of days before the start date that beta users can access the course."), - scope=Scope.settings, - default=None, - ) - static_asset_path = String( - display_name=_("Static Asset Path"), - help=_("Enter the path to use for files on the Files & Uploads page. This value overrides the Studio default, c4x://."), - scope=Scope.settings, - default='', - ) - use_latex_compiler = Boolean( - display_name=_("Enable LaTeX Compiler"), - help=_("Enter true or false. If true, you can use the LaTeX templates for HTML components and advanced Problem components."), - default=False, - scope=Scope.settings - ) - max_attempts = Integer( - display_name=_("Maximum Attempts"), - help=_("Enter the maximum number of times a student can try to answer problems. By default, Maximum Attempts is set to null, meaning that students have an unlimited number of attempts for problems. You can override this course-wide setting for individual problems. However, if the course-wide setting is a specific number, you cannot set the Maximum Attempts for individual problems to unlimited."), - values={"min": 0}, scope=Scope.settings - ) - matlab_api_key = String( - display_name=_("Matlab API key"), - help=_("Enter the API key provided by MathWorks for accessing the MATLAB Hosted Service. " - "This key is granted for exclusive use in this course for the specified duration. " - "Do not share the API key with other courses. Notify MathWorks immediately " - "if you believe the key is exposed or compromised. To obtain a key for your course, " - "or to report an issue, please contact moocsupport@mathworks.com"), - scope=Scope.settings - ) - # This is should be scoped to content, but since it's defined in the policy - # file, it is currently scoped to settings. - user_partitions = UserPartitionList( - display_name=_("Group Configurations"), - help=_("Enter the configurations that govern how students are grouped together."), - default=[], - scope=Scope.settings - ) - video_speed_optimizations = Boolean( - display_name=_("Enable video caching system"), - help=_("Enter true or false. If true, video caching will be used for HTML5 videos."), - default=True, - scope=Scope.settings - ) - video_bumper = Dict( - display_name=_("Video Pre-Roll"), - help=_( - "Identify a video, 5-10 seconds in length, to play before course videos. Enter the video ID from " - "the Video Uploads page and one or more transcript files in the following format: {format}. " - "For example, an entry for a video with two transcripts looks like this: {example}" - ).format( - format='{"video_id": "ID", "transcripts": {"language": "/static/filename.srt"}}', - example=( - '{' - '"video_id": "77cef264-d6f5-4cf2-ad9d-0178ab8c77be", ' - '"transcripts": {"en": "/static/DemoX-D01_1.srt", "uk": "/static/DemoX-D01_1_uk.srt"}' - '}' - ), - ), - scope=Scope.settings - ) - - reset_key = "DEFAULT_SHOW_RESET_BUTTON" - default_reset_button = getattr(settings, reset_key) if hasattr(settings, reset_key) else False - show_reset_button = Boolean( - display_name=_("Show Reset Button for Problems"), - help=_( - "Enter true or false. If true, problems in the course default to always displaying a 'Reset' button. " - "You can override this in each problem's settings. All existing problems are affected when " - "this course-wide setting is changed." - ), - scope=Scope.settings, - default=default_reset_button - ) - edxnotes = Boolean( - display_name=_("Enable Student Notes"), - help=_("Enter true or false. If true, students can use the Student Notes feature."), - default=False, - scope=Scope.settings - ) - edxnotes_visibility = Boolean( - display_name="Student Notes Visibility", - help=_("Indicates whether Student Notes are visible in the course. " - "Students can also show or hide their notes in the courseware."), - default=True, - scope=Scope.user_info - ) - - in_entrance_exam = Boolean( - display_name=_("Tag this module as part of an Entrance Exam section"), - help=_("Enter true or false. If true, answer submissions for problem modules will be " - "considered in the Entrance Exam scoring/gating algorithm."), - scope=Scope.settings, - default=False - ) - - self_paced = Boolean( - display_name=_('Self Paced'), - help=_( - 'Set this to "true" to mark this course as self-paced. Self-paced courses do not have ' - 'due dates for assignments, and students can progress through the course at any rate before ' - 'the course ends.' - ), - default=False, - scope=Scope.settings - ) def compute_inherited_metadata(descriptor): diff --git a/common/lib/xmodule/xmodule/modulestore/mongo/base.py b/common/lib/xmodule/xmodule/modulestore/mongo/base.py index aad2b8c236..714d7d0998 100644 --- a/common/lib/xmodule/xmodule/modulestore/mongo/base.py +++ b/common/lib/xmodule/xmodule/modulestore/mongo/base.py @@ -13,46 +13,45 @@ structure: """ import copy -from datetime import datetime -from importlib import import_module import logging -import pymongo import re import sys +from datetime import datetime +from importlib import import_module from uuid import uuid4 +import pymongo from bson.son import SON from contracts import contract, new_contract from fs.osfs import OSFS from mongodb_proxy import autoretry_read -from opaque_keys.edx.keys import UsageKey, CourseKey, AssetKey -from opaque_keys.edx.locations import Location, BlockUsageLocator, SlashSeparatedCourseKey +from opaque_keys.edx.keys import AssetKey, CourseKey, UsageKey +from opaque_keys.edx.locations import BlockUsageLocator, Location, SlashSeparatedCourseKey from opaque_keys.edx.locator import CourseLocator, LibraryLocator +from openedx.core.lib.partitions.partitions_service import PartitionService +from openedx.core.lib.xblock_fields.inherited_fields import InheritanceMixin from path import Path as path from pytz import UTC from xblock.core import XBlock from xblock.exceptions import InvalidScopeError -from xblock.fields import Scope, ScopeIds, Reference, ReferenceList, ReferenceValueDict +from xblock.fields import Reference, ReferenceList, ReferenceValueDict, Scope, ScopeIds from xblock.runtime import KvsFieldData - from xmodule.assetstore import AssetMetadata, CourseAssetsFromStorage from xmodule.course_module import CourseSummary from xmodule.error_module import ErrorDescriptor -from xmodule.errortracker import null_error_tracker, exc_info_to_str +from xmodule.errortracker import exc_info_to_str, null_error_tracker from xmodule.exceptions import HeartbeatFailure from xmodule.mako_module import MakoDescriptorSystem -from xmodule.mongo_utils import connect_to_mongodb, create_collection_index -from xmodule.modulestore import ModuleStoreWriteBase, ModuleStoreEnum, BulkOperationsMixin, BulkOpsRecord -from xmodule.modulestore.draft_and_published import ModuleStoreDraftAndPublished, DIRECT_ONLY_CATEGORIES +from xmodule.modulestore import BulkOperationsMixin, BulkOpsRecord, ModuleStoreEnum, ModuleStoreWriteBase +from xmodule.modulestore.draft_and_published import DIRECT_ONLY_CATEGORIES, ModuleStoreDraftAndPublished from xmodule.modulestore.edit_info import EditInfoRuntimeMixin -from xmodule.modulestore.exceptions import ItemNotFoundError, DuplicateCourseError, ReferentialIntegrityError -from xmodule.modulestore.inheritance import InheritanceMixin, inherit_metadata, InheritanceKeyValueStore -from xmodule.partitions.partitions_service import PartitionService -from xmodule.modulestore.xml import CourseLocationManager +from xmodule.modulestore.exceptions import DuplicateCourseError, ItemNotFoundError, ReferentialIntegrityError +from xmodule.modulestore.inheritance import InheritanceKeyValueStore, inherit_metadata from xmodule.modulestore.store_utilities import DETACHED_XBLOCK_TYPES +from xmodule.modulestore.xml import CourseLocationManager +from xmodule.mongo_utils import connect_to_mongodb, create_collection_index from xmodule.services import SettingsService - log = logging.getLogger(__name__) new_contract('CourseKey', CourseKey) diff --git a/common/lib/xmodule/xmodule/modulestore/split_mongo/caching_descriptor_system.py b/common/lib/xmodule/xmodule/modulestore/split_mongo/caching_descriptor_system.py index 2e5d3f7cfe..938b02d655 100644 --- a/common/lib/xmodule/xmodule/modulestore/split_mongo/caching_descriptor_system.py +++ b/common/lib/xmodule/xmodule/modulestore/split_mongo/caching_descriptor_system.py @@ -1,25 +1,25 @@ -import sys import logging +import sys from contracts import contract, new_contract from fs.osfs import OSFS from lazy import lazy -from xblock.runtime import KvsFieldData, KeyValueStore -from xblock.fields import ScopeIds +from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator, DefinitionLocator, LibraryLocator, LocalId +from openedx.core.lib.xblock_fields.inherited_fields import InheritanceMixin from xblock.core import XBlock -from opaque_keys.edx.locator import BlockUsageLocator, LocalId, CourseLocator, LibraryLocator, DefinitionLocator - -from xmodule.library_tools import LibraryToolsService -from xmodule.mako_module import MakoDescriptorSystem +from xblock.fields import ScopeIds +from xblock.runtime import KeyValueStore, KvsFieldData from xmodule.error_module import ErrorDescriptor from xmodule.errortracker import exc_info_to_str +from xmodule.library_tools import LibraryToolsService +from xmodule.mako_module import MakoDescriptorSystem from xmodule.modulestore import BlockData from xmodule.modulestore.edit_info import EditInfoRuntimeMixin from xmodule.modulestore.exceptions import ItemNotFoundError -from xmodule.modulestore.inheritance import inheriting_field_data, InheritanceMixin +from xmodule.modulestore.inheritance import inheriting_field_data from xmodule.modulestore.split_mongo import BlockKey, CourseEnvelope -from xmodule.modulestore.split_mongo.id_manager import SplitMongoIdManager from xmodule.modulestore.split_mongo.definition_lazy_loader import DefinitionLazyLoader +from xmodule.modulestore.split_mongo.id_manager import SplitMongoIdManager from xmodule.modulestore.split_mongo.split_mongo_kvs import SplitMongoKVS from xmodule.x_module import XModuleMixin diff --git a/common/lib/xmodule/xmodule/modulestore/split_mongo/split.py b/common/lib/xmodule/xmodule/modulestore/split_mongo/split.py index 3e1a393f52..65931b7b2a 100644 --- a/common/lib/xmodule/xmodule/modulestore/split_mongo/split.py +++ b/common/lib/xmodule/xmodule/modulestore/split_mongo/split.py @@ -57,41 +57,56 @@ import copy import datetime import hashlib import logging -import six -from contracts import contract, new_contract +from collections import defaultdict from importlib import import_module -from mongodb_proxy import autoretry_read -from path import Path as path -from pytz import UTC -from bson.objectid import ObjectId +from types import NoneType -from xblock.core import XBlock -from xblock.fields import Scope, Reference, ReferenceList, ReferenceValueDict -from xmodule.course_module import CourseSummary -from xmodule.errortracker import null_error_tracker +import six + +from bson.objectid import ObjectId +from ccx_keys.locator import CCXBlockUsageLocator, CCXLocator +from contracts import contract, new_contract +from mongodb_proxy import autoretry_read from opaque_keys.edx.keys import CourseKey from opaque_keys.edx.locator import ( - BlockUsageLocator, DefinitionLocator, CourseLocator, LibraryLocator, VersionTree, LocalId, + BlockUsageLocator, + CourseLocator, + DefinitionLocator, + LibraryLocator, + LocalId, + VersionTree ) -from ccx_keys.locator import CCXLocator, CCXBlockUsageLocator -from xmodule.modulestore.exceptions import InsufficientSpecificationError, VersionConflictError, DuplicateItemError, \ - DuplicateCourseError, MultipleCourseBlocksFound +from openedx.core.lib.partitions.partitions_service import PartitionService +from openedx.core.lib.xblock_fields.inherited_fields import InheritanceMixin +from path import Path as path +from pytz import UTC +from xblock.core import XBlock +from xblock.fields import Reference, ReferenceList, ReferenceValueDict, Scope +from xmodule.assetstore import AssetMetadata +from xmodule.course_module import CourseSummary +from xmodule.error_module import ErrorDescriptor +from xmodule.errortracker import null_error_tracker from xmodule.modulestore import ( - inheritance, ModuleStoreWriteBase, ModuleStoreEnum, - BulkOpsRecord, BulkOperationsMixin, SortedAssetList, BlockData + BlockData, + BulkOperationsMixin, + BulkOpsRecord, + ModuleStoreEnum, + ModuleStoreWriteBase, + SortedAssetList ) +from xmodule.modulestore.exceptions import ( + DuplicateCourseError, + DuplicateItemError, + InsufficientSpecificationError, + MultipleCourseBlocksFound, + VersionConflictError +) +from xmodule.modulestore.split_mongo import BlockKey, CourseEnvelope +from xmodule.modulestore.split_mongo.mongo_connection import DuplicateKeyError, MongoConnection +from xmodule.modulestore.store_utilities import DETACHED_XBLOCK_TYPES from ..exceptions import ItemNotFoundError from .caching_descriptor_system import CachingDescriptorSystem -from xmodule.partitions.partitions_service import PartitionService -from xmodule.modulestore.split_mongo.mongo_connection import MongoConnection, DuplicateKeyError -from xmodule.modulestore.split_mongo import BlockKey, CourseEnvelope -from xmodule.modulestore.store_utilities import DETACHED_XBLOCK_TYPES -from xmodule.error_module import ErrorDescriptor -from collections import defaultdict -from types import NoneType -from xmodule.assetstore import AssetMetadata - log = logging.getLogger(__name__) @@ -2149,7 +2164,7 @@ class SplitMongoModuleStore(SplitBulkWriteMixin, ModuleStoreWriteBase): else: inherited_settings = parent_xblock.xblock_kvs.inherited_settings.copy() if fields is not None: - for field_name in inheritance.InheritanceMixin.fields: + for field_name in InheritanceMixin.fields: if field_name in fields: inherited_settings[field_name] = fields[field_name] @@ -2698,7 +2713,7 @@ class SplitMongoModuleStore(SplitBulkWriteMixin, ModuleStoreWriteBase): # update the inheriting w/ what should pass to children inheriting_settings = inherited_settings_map[block_key].copy() block_fields = block_data.fields - for field_name in inheritance.InheritanceMixin.fields: + for field_name in InheritanceMixin.fields: if field_name in block_fields: inheriting_settings[field_name] = block_fields[field_name] diff --git a/common/lib/xmodule/xmodule/modulestore/tests/test_cross_modulestore_import_export.py b/common/lib/xmodule/xmodule/modulestore/tests/test_cross_modulestore_import_export.py index 042198113f..ef40c9d7e6 100644 --- a/common/lib/xmodule/xmodule/modulestore/tests/test_cross_modulestore_import_export.py +++ b/common/lib/xmodule/xmodule/modulestore/tests/test_cross_modulestore_import_export.py @@ -14,23 +14,25 @@ and then for each combination of modulestores, performing the sequence: import itertools import os -from path import Path as path from shutil import rmtree from tempfile import mkdtemp import ddt -from nose.plugins.attrib import attr from mock import patch - -from xmodule.tests import CourseComparisonTest -from xmodule.modulestore.xml_importer import import_course_from_xml -from xmodule.modulestore.xml_exporter import export_course_to_xml -from xmodule.modulestore.tests.utils import mock_tab_from_json -from xmodule.partitions.tests.test_partitions import PartitionTestCase +from nose.plugins.attrib import attr +from openedx.core.lib.partitions.tests.test_partitions import PartitionTestCase +from path import Path as path from xmodule.modulestore.tests.utils import ( - MongoContentstoreBuilder, MODULESTORE_SETUPS, SPLIT_MODULESTORE_SETUP, - CONTENTSTORE_SETUPS, TEST_DATA_DIR + CONTENTSTORE_SETUPS, + MODULESTORE_SETUPS, + SPLIT_MODULESTORE_SETUP, + TEST_DATA_DIR, + MongoContentstoreBuilder, + mock_tab_from_json ) +from xmodule.modulestore.xml_exporter import export_course_to_xml +from xmodule.modulestore.xml_importer import import_course_from_xml +from xmodule.tests import CourseComparisonTest COURSE_DATA_NAMES = ( 'toy', diff --git a/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py b/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py index 59917387f5..0645e6afb6 100644 --- a/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py +++ b/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py @@ -1,59 +1,66 @@ """ Unit tests for the Mixed Modulestore, with DDT for the various stores (Split, Draft, XML) """ -from collections import namedtuple import datetime -import logging -import ddt import itertools +import logging import mimetypes -from uuid import uuid4 +from collections import namedtuple from contextlib import contextmanager -from mock import patch, Mock, call +from shutil import rmtree +from tempfile import mkdtemp +from uuid import uuid4 +import ddt +import pymongo # Mixed modulestore depends on django, so we'll manually configure some django settings # before importing the module # TODO remove this import and the configuration -- xmodule should not depend on django! from django.conf import settings +from mock import Mock, call, patch +from nose import SkipTest # This import breaks this test file when run separately. Needs to be fixed! (PLAT-449) from nose.plugins.attrib import attr -from nose import SkipTest -import pymongo +from opaque_keys.edx.locations import SlashSeparatedCourseKey +from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator, LibraryLocator +from openedx.core.lib.xblock_fields.inherited_fields import InheritanceMixin from pytz import UTC -from shutil import rmtree -from tempfile import mkdtemp - -from xmodule.x_module import XModuleMixin -from xmodule.modulestore.edit_info import EditInfoMixin -from xmodule.modulestore.inheritance import InheritanceMixin -from xmodule.modulestore.tests.utils import MongoContentstoreBuilder -from xmodule.contentstore.content import StaticContent -from xmodule.modulestore.xml_importer import import_course_from_xml -from xmodule.modulestore.xml_exporter import export_course_to_xml -from xmodule.modulestore.tests.test_asides import AsideTestType from xblock.core import XBlockAside -from xblock.fields import Scope, String, ScopeIds +from xblock.fields import Scope, ScopeIds, String from xblock.fragment import Fragment from xblock.runtime import DictKeyValueStore, KvsFieldData from xblock.test.tools import TestRuntime +from xmodule.contentstore.content import StaticContent +from xmodule.exceptions import InvalidVersionError +from xmodule.modulestore import ModuleStoreEnum +from xmodule.modulestore.draft_and_published import DIRECT_ONLY_CATEGORIES, UnsupportedRevisionError +from xmodule.modulestore.edit_info import EditInfoMixin +from xmodule.modulestore.exceptions import ( + DuplicateCourseError, + ItemNotFoundError, + NoPathToItem, + ReferentialIntegrityError +) +from xmodule.modulestore.mixed import MixedModuleStore +from xmodule.modulestore.search import navigation_index, path_to_location +from xmodule.modulestore.store_utilities import DETACHED_XBLOCK_TYPES +from xmodule.modulestore.tests.factories import check_exact_number_of_calls, check_mongo_calls, mongo_uses_error_check +from xmodule.modulestore.tests.mongo_connection import MONGO_HOST, MONGO_PORT_NUM +from xmodule.modulestore.tests.test_asides import AsideTestType +from xmodule.modulestore.tests.utils import ( + LocationMixin, + MongoContentstoreBuilder, + create_modulestore_instance, + mock_tab_from_json +) +from xmodule.modulestore.xml_exporter import export_course_to_xml +from xmodule.modulestore.xml_importer import import_course_from_xml +from xmodule.tests import DATA_DIR, CourseComparisonTest +from xmodule.x_module import XModuleMixin if not settings.configured: settings.configure() -from opaque_keys.edx.locations import SlashSeparatedCourseKey -from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator, LibraryLocator -from xmodule.exceptions import InvalidVersionError -from xmodule.modulestore import ModuleStoreEnum -from xmodule.modulestore.draft_and_published import UnsupportedRevisionError, DIRECT_ONLY_CATEGORIES -from xmodule.modulestore.exceptions import ItemNotFoundError, DuplicateCourseError, ReferentialIntegrityError, NoPathToItem -from xmodule.modulestore.mixed import MixedModuleStore -from xmodule.modulestore.search import path_to_location, navigation_index -from xmodule.modulestore.store_utilities import DETACHED_XBLOCK_TYPES -from xmodule.modulestore.tests.factories import check_mongo_calls, check_exact_number_of_calls, \ - mongo_uses_error_check -from xmodule.modulestore.tests.utils import create_modulestore_instance, LocationMixin, mock_tab_from_json -from xmodule.modulestore.tests.mongo_connection import MONGO_PORT_NUM, MONGO_HOST -from xmodule.tests import DATA_DIR, CourseComparisonTest log = logging.getLogger(__name__) diff --git a/common/lib/xmodule/xmodule/modulestore/tests/test_mongo.py b/common/lib/xmodule/xmodule/modulestore/tests/test_mongo.py index 90b6fd395b..ec17c0d63a 100644 --- a/common/lib/xmodule/xmodule/modulestore/tests/test_mongo.py +++ b/common/lib/xmodule/xmodule/modulestore/tests/test_mongo.py @@ -1,52 +1,54 @@ """ Unit tests for the Mongo modulestore """ -# pylint: disable=protected-access -# pylint: disable=no-name-in-module -# pylint: disable=bad-continuation -from nose.tools import assert_equals, assert_raises, \ - assert_not_equals, assert_false, assert_true, assert_greater, assert_is_instance, assert_is_none -# pylint: enable=E0611 -from path import Path as path -import pymongo + import logging import shutil +import unittest +from datetime import datetime from tempfile import mkdtemp from uuid import uuid4 -from datetime import datetime -from pytz import UTC -import unittest -from mock import patch -from xblock.core import XBlock -from xblock.fields import Scope, Reference, ReferenceList, ReferenceValueDict -from xblock.runtime import KeyValueStore -from xblock.exceptions import InvalidScopeError - -from xmodule.tests import DATA_DIR -from opaque_keys.edx.keys import CourseKey -from opaque_keys.edx.locations import Location -from xmodule.modulestore import ModuleStoreEnum -from xmodule.modulestore.mongo import MongoKeyValueStore -from xmodule.modulestore.draft import DraftModuleStore -from opaque_keys.edx.locations import SlashSeparatedCourseKey, AssetLocation -from opaque_keys.edx.locator import LibraryLocator, CourseLocator -from opaque_keys.edx.keys import UsageKey -from xmodule.modulestore.xml_exporter import export_course_to_xml -from xmodule.modulestore.xml_importer import import_course_from_xml, perform_xlint -from xmodule.contentstore.mongo import MongoContentStore - -from nose.tools import assert_in -from xmodule.exceptions import NotFoundError +import pymongo from git.test.lib.asserts import assert_not_none -from xmodule.x_module import XModuleMixin -from xmodule.modulestore.mongo.base import as_draft -from xmodule.modulestore.tests.mongo_connection import MONGO_PORT_NUM, MONGO_HOST -from xmodule.modulestore.tests.utils import LocationMixin, mock_tab_from_json +from mock import patch +# pylint: disable=no-name-in-module +# pylint: disable=bad-continuation +from nose.tools import ( + assert_equals, + assert_false, + assert_greater, + assert_in, + assert_is_instance, + assert_is_none, + assert_not_equals, + assert_raises, + assert_true +) +from opaque_keys.edx.keys import CourseKey, UsageKey +from opaque_keys.edx.locations import AssetLocation, Location, SlashSeparatedCourseKey +from opaque_keys.edx.locator import CourseLocator, LibraryLocator +from openedx.core.lib.xblock_fields.inherited_fields import InheritanceMixin +from path import Path as path +from pytz import UTC +from xblock.core import XBlock +from xblock.exceptions import InvalidScopeError +from xblock.fields import Reference, ReferenceList, ReferenceValueDict, Scope +from xblock.runtime import KeyValueStore +from xmodule.contentstore.mongo import MongoContentStore +from xmodule.exceptions import NotFoundError +from xmodule.modulestore import ModuleStoreEnum +from xmodule.modulestore.draft import DraftModuleStore from xmodule.modulestore.edit_info import EditInfoMixin from xmodule.modulestore.exceptions import ItemNotFoundError -from xmodule.modulestore.inheritance import InheritanceMixin - +from xmodule.modulestore.mongo import MongoKeyValueStore +from xmodule.modulestore.mongo.base import as_draft +from xmodule.modulestore.tests.mongo_connection import MONGO_HOST, MONGO_PORT_NUM +from xmodule.modulestore.tests.utils import LocationMixin, mock_tab_from_json +from xmodule.modulestore.xml_exporter import export_course_to_xml +from xmodule.modulestore.xml_importer import import_course_from_xml, perform_xlint +from xmodule.tests import DATA_DIR +from xmodule.x_module import XModuleMixin log = logging.getLogger(__name__) diff --git a/common/lib/xmodule/xmodule/modulestore/tests/test_split_modulestore.py b/common/lib/xmodule/xmodule/modulestore/tests/test_split_modulestore.py index 42835c4222..29025c440c 100644 --- a/common/lib/xmodule/xmodule/modulestore/tests/test_split_modulestore.py +++ b/common/lib/xmodule/xmodule/modulestore/tests/test_split_modulestore.py @@ -1,42 +1,42 @@ """ Test split modulestore w/o using any django stuff. """ -from mock import patch import datetime -from importlib import import_module -from path import Path as path import random import re import unittest import uuid +from importlib import import_module import ddt +from ccx_keys.locator import CCXBlockUsageLocator from contracts import contract +from django.core.cache import InvalidCacheBackendError, caches +from mock import patch from nose.plugins.attrib import attr -from django.core.cache import caches, InvalidCacheBackendError - +from opaque_keys.edx.locator import BlockUsageLocator, CourseKey, CourseLocator, LocalId, VersionTree from openedx.core.lib import tempdir +from openedx.core.lib.xblock_fields.fields import Date, Timedelta +from openedx.core.lib.xblock_fields.inherited_fields import InheritanceMixin +from path import Path as path from xblock.fields import Reference, ReferenceList, ReferenceValueDict from xmodule.course_module import CourseDescriptor from xmodule.modulestore import ModuleStoreEnum -from xmodule.modulestore.exceptions import ( - ItemNotFoundError, VersionConflictError, - DuplicateItemError, DuplicateCourseError, - InsufficientSpecificationError -) -from opaque_keys.edx.locator import CourseKey, CourseLocator, BlockUsageLocator, VersionTree, LocalId -from ccx_keys.locator import CCXBlockUsageLocator -from xmodule.modulestore.inheritance import InheritanceMixin -from xmodule.x_module import XModuleMixin -from xmodule.fields import Date, Timedelta -from xmodule.modulestore.split_mongo.split import SplitMongoModuleStore -from xmodule.modulestore.tests.test_modulestore import check_has_course_method -from xmodule.modulestore.split_mongo import BlockKey -from xmodule.modulestore.tests.factories import check_mongo_calls -from xmodule.modulestore.tests.mongo_connection import MONGO_PORT_NUM, MONGO_HOST -from xmodule.modulestore.tests.utils import mock_tab_from_json from xmodule.modulestore.edit_info import EditInfoMixin - +from xmodule.modulestore.exceptions import ( + DuplicateCourseError, + DuplicateItemError, + InsufficientSpecificationError, + ItemNotFoundError, + VersionConflictError +) +from xmodule.modulestore.split_mongo import BlockKey +from xmodule.modulestore.split_mongo.split import SplitMongoModuleStore +from xmodule.modulestore.tests.factories import check_mongo_calls +from xmodule.modulestore.tests.mongo_connection import MONGO_HOST, MONGO_PORT_NUM +from xmodule.modulestore.tests.test_modulestore import check_has_course_method +from xmodule.modulestore.tests.utils import mock_tab_from_json +from xmodule.x_module import XModuleMixin BRANCH_NAME_DRAFT = ModuleStoreEnum.BranchName.draft BRANCH_NAME_PUBLISHED = ModuleStoreEnum.BranchName.published diff --git a/common/lib/xmodule/xmodule/modulestore/tests/test_split_w_old_mongo.py b/common/lib/xmodule/xmodule/modulestore/tests/test_split_w_old_mongo.py index a9e92b1211..b45ea6d2da 100644 --- a/common/lib/xmodule/xmodule/modulestore/tests/test_split_w_old_mongo.py +++ b/common/lib/xmodule/xmodule/modulestore/tests/test_split_w_old_mongo.py @@ -3,17 +3,16 @@ import random import unittest import uuid -from nose.plugins.attrib import attr import mock - -from opaque_keys.edx.locator import CourseLocator, BlockUsageLocator +from nose.plugins.attrib import attr +from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator +from openedx.core.lib.xblock_fields.inherited_fields import InheritanceMixin from xmodule.modulestore import ModuleStoreEnum -from xmodule.x_module import XModuleMixin -from xmodule.modulestore.inheritance import InheritanceMixin from xmodule.modulestore.mongo import DraftMongoModuleStore from xmodule.modulestore.split_mongo.split import SplitMongoModuleStore -from xmodule.modulestore.tests.mongo_connection import MONGO_PORT_NUM, MONGO_HOST +from xmodule.modulestore.tests.mongo_connection import MONGO_HOST, MONGO_PORT_NUM from xmodule.modulestore.tests.utils import MemoryCache +from xmodule.x_module import XModuleMixin @attr('mongo') diff --git a/common/lib/xmodule/xmodule/modulestore/tests/test_xml_importer.py b/common/lib/xmodule/xmodule/modulestore/tests/test_xml_importer.py index 6cc5913374..93577346c0 100644 --- a/common/lib/xmodule/xmodule/modulestore/tests/test_xml_importer.py +++ b/common/lib/xmodule/xmodule/modulestore/tests/test_xml_importer.py @@ -1,21 +1,21 @@ """ Tests for XML importer. """ -import mock -from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator -from xblock.fields import String, Scope, ScopeIds, List -from xblock.runtime import Runtime, KvsFieldData, DictKeyValueStore -from xmodule.x_module import XModuleMixin -from opaque_keys.edx.locations import Location -from xmodule.modulestore import ModuleStoreEnum -from xmodule.modulestore.inheritance import InheritanceMixin -from xmodule.modulestore.xml_importer import _update_and_import_module, _update_module_location -from xmodule.modulestore.tests.mongo_connection import MONGO_PORT_NUM, MONGO_HOST -from opaque_keys.edx.locations import SlashSeparatedCourseKey -from xmodule.tests import DATA_DIR -from uuid import uuid4 -import unittest import importlib +import unittest +from uuid import uuid4 + +import mock +from opaque_keys.edx.locations import Location, SlashSeparatedCourseKey +from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator +from openedx.core.lib.xblock_fields.inherited_fields import InheritanceMixin +from xblock.fields import List, Scope, ScopeIds, String +from xblock.runtime import DictKeyValueStore, KvsFieldData, Runtime +from xmodule.modulestore import ModuleStoreEnum +from xmodule.modulestore.tests.mongo_connection import MONGO_HOST, MONGO_PORT_NUM +from xmodule.modulestore.xml_importer import _update_and_import_module, _update_module_location +from xmodule.tests import DATA_DIR +from xmodule.x_module import XModuleMixin class ModuleStoreNoSettings(unittest.TestCase): diff --git a/common/lib/xmodule/xmodule/modulestore/tests/utils.py b/common/lib/xmodule/xmodule/modulestore/tests/utils.py index e9666423c7..4c9f577e6b 100644 --- a/common/lib/xmodule/xmodule/modulestore/tests/utils.py +++ b/common/lib/xmodule/xmodule/modulestore/tests/utils.py @@ -2,30 +2,29 @@ Helper classes and methods for running modulestore tests without Django. """ import random - from contextlib import contextmanager, nested from importlib import import_module -from opaque_keys.edx.keys import UsageKey -from path import Path as path from shutil import rmtree from tempfile import mkdtemp from unittest import TestCase +from opaque_keys.edx.keys import UsageKey +from openedx.core.lib.xblock_fields.inherited_fields import InheritanceMixin +from path import Path as path from xblock.fields import XBlockMixin -from xmodule.x_module import XModuleMixin from xmodule.contentstore.mongo import MongoContentStore from xmodule.modulestore import ModuleStoreEnum from xmodule.modulestore.draft_and_published import ModuleStoreDraftAndPublished from xmodule.modulestore.edit_info import EditInfoMixin -from xmodule.modulestore.inheritance import InheritanceMixin from xmodule.modulestore.mixed import MixedModuleStore from xmodule.modulestore.mongo.base import ModuleStoreEnum from xmodule.modulestore.mongo.draft import DraftModuleStore from xmodule.modulestore.split_mongo.split_draft import DraftVersioningModuleStore from xmodule.modulestore.tests.factories import ItemFactory -from xmodule.modulestore.tests.mongo_connection import MONGO_PORT_NUM, MONGO_HOST +from xmodule.modulestore.tests.mongo_connection import MONGO_HOST, MONGO_PORT_NUM from xmodule.modulestore.xml import XMLModuleStore from xmodule.tests import DATA_DIR +from xmodule.x_module import XModuleMixin def load_function(path): diff --git a/common/lib/xmodule/xmodule/seq_module.py b/common/lib/xmodule/xmodule/seq_module.py index ecda5cc450..75e232ffd8 100644 --- a/common/lib/xmodule/xmodule/seq_module.py +++ b/common/lib/xmodule/xmodule/seq_module.py @@ -4,22 +4,23 @@ xModule implementation of a learning sequence # pylint: disable=abstract-method import collections -from datetime import datetime -from django.utils.timezone import UTC import json import logging +from datetime import datetime + from pkg_resources import resource_string +from django.utils.timezone import UTC from lxml import etree +from openedx.core.lib.xblock_fields.fields import Date from xblock.core import XBlock -from xblock.fields import Integer, Scope, Boolean, String +from xblock.fields import Boolean, Integer, Scope, String from xblock.fragment import Fragment from .exceptions import NotFoundError -from .fields import Date from .mako_module import MakoModuleDescriptor from .progress import Progress -from .x_module import XModule, STUDENT_VIEW +from .x_module import STUDENT_VIEW, XModule from .xml_module import XmlDescriptor log = logging.getLogger(__name__) diff --git a/common/lib/xmodule/xmodule/split_test_module.py b/common/lib/xmodule/xmodule/split_test_module.py index 58aebaa7f5..e9cb2a25f6 100644 --- a/common/lib/xmodule/xmodule/split_test_module.py +++ b/common/lib/xmodule/xmodule/split_test_module.py @@ -2,24 +2,22 @@ Module for running content split tests """ -import logging import json -from webob import Response -from uuid import uuid4 +import logging from operator import itemgetter - -from xmodule.progress import Progress -from xmodule.seq_module import SequenceDescriptor -from xmodule.studio_editable import StudioEditableModule, StudioEditableDescriptor -from xmodule.x_module import XModule, module_attr, STUDENT_VIEW -from xmodule.validation import StudioValidation, StudioValidationMessage -from xmodule.modulestore.inheritance import UserPartitionList +from uuid import uuid4 from lxml import etree - +from openedx.core.lib.xblock_fields.inherited_fields import UserPartitionList +from webob import Response from xblock.core import XBlock -from xblock.fields import Scope, Integer, String, ReferenceValueDict +from xblock.fields import Integer, ReferenceValueDict, Scope, String from xblock.fragment import Fragment +from xmodule.progress import Progress +from xmodule.seq_module import SequenceDescriptor +from xmodule.studio_editable import StudioEditableDescriptor, StudioEditableModule +from xmodule.validation import StudioValidation, StudioValidationMessage +from xmodule.x_module import STUDENT_VIEW, XModule, module_attr log = logging.getLogger('edx.' + __name__) diff --git a/common/lib/xmodule/xmodule/tests/__init__.py b/common/lib/xmodule/xmodule/tests/__init__.py index 498e145479..e34e270914 100644 --- a/common/lib/xmodule/xmodule/tests/__init__.py +++ b/common/lib/xmodule/xmodule/tests/__init__.py @@ -25,12 +25,13 @@ from path import Path as path from opaque_keys.edx.locations import SlashSeparatedCourseKey from xblock.field_data import DictFieldData from xblock.fields import ScopeIds, Scope, Reference, ReferenceList, ReferenceValueDict +from openedx.core.lib.xblock_fields.inherited_fields import InheritanceMixin from xmodule.assetstore import AssetMetadata from xmodule.error_module import ErrorDescriptor from xmodule.mako_module import MakoDescriptorSystem from xmodule.modulestore import ModuleStoreEnum from xmodule.modulestore.draft_and_published import DIRECT_ONLY_CATEGORIES, ModuleStoreDraftAndPublished -from xmodule.modulestore.inheritance import InheritanceMixin, own_metadata +from xmodule.modulestore.inheritance import own_metadata from xmodule.modulestore.mongo.draft import DraftModuleStore from xmodule.modulestore.xml import CourseLocationManager from xmodule.x_module import ModuleSystem, XModuleDescriptor, XModuleMixin diff --git a/common/lib/xmodule/xmodule/tests/test_course_metadata_utils.py b/common/lib/xmodule/xmodule/tests/test_course_metadata_utils.py index 06014a9bd7..3074fea4f2 100644 --- a/common/lib/xmodule/xmodule/tests/test_course_metadata_utils.py +++ b/common/lib/xmodule/xmodule/tests/test_course_metadata_utils.py @@ -6,6 +6,7 @@ from datetime import timedelta, datetime from unittest import TestCase from pytz import utc +from openedx.core.lib.xblock_fields.inherited_fields import DEFAULT_START_DATE from xmodule.block_metadata_utils import ( url_name_for_block, display_name_with_default, @@ -16,7 +17,6 @@ from xmodule.course_metadata_utils import ( number_for_course_location, has_course_started, has_course_ended, - DEFAULT_START_DATE, course_start_date_is_default, may_certify_for_course, ) diff --git a/common/lib/xmodule/xmodule/tests/test_fields.py b/common/lib/xmodule/xmodule/tests/test_fields.py index 4464470eab..5cd03c32f2 100644 --- a/common/lib/xmodule/xmodule/tests/test_fields.py +++ b/common/lib/xmodule/xmodule/tests/test_fields.py @@ -4,9 +4,7 @@ import datetime import unittest from django.utils.timezone import UTC - -from xmodule.fields import Date, Timedelta, RelativeTime -from xmodule.timeinfo import TimeInfo +from openedx.core.lib.xblock_fields.fields import Date, RelativeTime, Timedelta, TimeInfo class DateTest(unittest.TestCase): diff --git a/common/lib/xmodule/xmodule/tests/test_import.py b/common/lib/xmodule/xmodule/tests/test_import.py index f557d7959a..b2e373b3dc 100644 --- a/common/lib/xmodule/xmodule/tests/test_import.py +++ b/common/lib/xmodule/xmodule/tests/test_import.py @@ -1,30 +1,25 @@ # -*- coding: utf-8 -*- import datetime -import ddt import unittest +import ddt +from django.utils.timezone import UTC from fs.memoryfs import MemoryFS from lxml import etree from mock import Mock, patch - -from django.utils.timezone import UTC - -from xmodule.xml_module import is_pointer_tag -from opaque_keys.edx.locations import Location -from xmodule.modulestore import only_xmodules -from xmodule.modulestore.xml import ImportSystem, XMLModuleStore, LibraryXMLModuleStore -from xmodule.modulestore.inheritance import compute_inherited_metadata -from xmodule.x_module import XModuleMixin -from xmodule.fields import Date -from xmodule.tests import DATA_DIR -from xmodule.modulestore.inheritance import InheritanceMixin -from opaque_keys.edx.locations import SlashSeparatedCourseKey - +from opaque_keys.edx.locations import Location, SlashSeparatedCourseKey +from openedx.core.lib.xblock_fields.fields import Date +from openedx.core.lib.xblock_fields.inherited_fields import InheritanceMixin from xblock.core import XBlock -from xblock.fields import Scope, String, Integer -from xblock.runtime import KvsFieldData, DictKeyValueStore - +from xblock.fields import Integer, Scope, String +from xblock.runtime import DictKeyValueStore, KvsFieldData +from xmodule.modulestore import only_xmodules +from xmodule.modulestore.inheritance import compute_inherited_metadata +from xmodule.modulestore.xml import ImportSystem, LibraryXMLModuleStore, XMLModuleStore +from xmodule.tests import DATA_DIR +from xmodule.x_module import XModuleMixin +from xmodule.xml_module import is_pointer_tag ORG = 'test_org' COURSE = 'test_course' diff --git a/common/lib/xmodule/xmodule/tests/test_lti_unit.py b/common/lib/xmodule/xmodule/tests/test_lti_unit.py index ce83fed603..a3d05050c4 100644 --- a/common/lib/xmodule/xmodule/tests/test_lti_unit.py +++ b/common/lib/xmodule/xmodule/tests/test_lti_unit.py @@ -2,17 +2,17 @@ """Test for LTI Xmodule functional logic.""" import datetime -from django.utils.timezone import UTC -from mock import Mock, patch, PropertyMock import textwrap -from lxml import etree -from webob.request import Request -from copy import copy import urllib +from copy import copy -from xmodule.fields import Timedelta -from xmodule.lti_module import LTIDescriptor +from django.utils.timezone import UTC +from lxml import etree +from mock import Mock, PropertyMock, patch +from openedx.core.lib.xblock_fields.fields import Timedelta +from webob.request import Request from xmodule.lti_2_util import LTIError +from xmodule.lti_module import LTIDescriptor from . import LogicTest diff --git a/common/lib/xmodule/xmodule/tests/test_split_test_module.py b/common/lib/xmodule/xmodule/tests/test_split_test_module.py index ba23497d85..043edc1078 100644 --- a/common/lib/xmodule/xmodule/tests/test_split_test_module.py +++ b/common/lib/xmodule/xmodule/tests/test_split_test_module.py @@ -3,17 +3,20 @@ Tests for the Split Testing Module """ import ddt import lxml -from mock import Mock, patch from fs.memoryfs import MemoryFS - -from xmodule.partitions.tests.test_partitions import MockPartitionService, PartitionTestCase, MockUserPartitionScheme +from mock import Mock, patch +from openedx.core.lib.partitions.partitions import MINIMUM_STATIC_PARTITION_ID, Group, UserPartition +from openedx.core.lib.partitions.tests.test_partitions import ( + MockPartitionService, + MockUserPartitionScheme, + PartitionTestCase +) +from xmodule.split_test_module import SplitTestDescriptor, SplitTestFields, get_split_user_partitions +from xmodule.tests import get_test_system from xmodule.tests.xml import factories as xml from xmodule.tests.xml import XModuleXmlImportTest -from xmodule.tests import get_test_system -from xmodule.x_module import AUTHOR_VIEW, STUDENT_VIEW from xmodule.validation import StudioValidationMessage -from xmodule.split_test_module import SplitTestDescriptor, SplitTestFields, get_split_user_partitions -from xmodule.partitions.partitions import Group, UserPartition, MINIMUM_STATIC_PARTITION_ID +from xmodule.x_module import AUTHOR_VIEW, STUDENT_VIEW class SplitTestModuleFactory(xml.XmlImportFactory): diff --git a/common/lib/xmodule/xmodule/tests/test_xml_module.py b/common/lib/xmodule/xmodule/tests/test_xml_module.py index 290d5b1000..86dc651cf8 100644 --- a/common/lib/xmodule/xmodule/tests/test_xml_module.py +++ b/common/lib/xmodule/xmodule/tests/test_xml_module.py @@ -4,24 +4,29 @@ import unittest from mock import Mock -from nose.tools import assert_equals, assert_not_equals, assert_true, assert_false, assert_in, assert_not_in # pylint: disable=no-name-in-module +from nose.tools import ( # pylint: disable=no-name-in-module + assert_equals, + assert_false, + assert_in, + assert_not_equals, + assert_not_in, + assert_true +) from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator - +from openedx.core.lib.xblock_fields.fields import Date, RelativeTime, Timedelta +from openedx.core.lib.xblock_fields.inherited_fields import InheritanceMixin from xblock.field_data import DictFieldData -from xblock.fields import Scope, String, Dict, Boolean, Integer, Float, Any, List -from xblock.runtime import KvsFieldData, DictKeyValueStore - -from xmodule.fields import Date, Timedelta, RelativeTime -from xmodule.modulestore.inheritance import InheritanceKeyValueStore, InheritanceMixin, InheritingFieldData -from xmodule.modulestore.split_mongo.split_mongo_kvs import SplitMongoKVS -from xmodule.xml_module import XmlDescriptor, serialize_field, deserialize_field +from xblock.fields import Any, Boolean, Dict, Float, Integer, List, Scope, String +from xblock.runtime import DictKeyValueStore, KvsFieldData from xmodule.course_module import CourseDescriptor +from xmodule.modulestore.inheritance import InheritanceKeyValueStore, InheritingFieldData +from xmodule.modulestore.split_mongo.split_mongo_kvs import SplitMongoKVS from xmodule.seq_module import SequenceDescriptor -from xmodule.x_module import XModuleMixin - from xmodule.tests import get_test_descriptor_system from xmodule.tests.xml import XModuleXmlImportTest -from xmodule.tests.xml.factories import CourseFactory, SequenceFactory, ProblemFactory +from xmodule.tests.xml.factories import CourseFactory, ProblemFactory, SequenceFactory +from xmodule.x_module import XModuleMixin +from xmodule.xml_module import XmlDescriptor, deserialize_field, serialize_field class CrazyJsonString(String): diff --git a/common/lib/xmodule/xmodule/tests/xml/factories.py b/common/lib/xmodule/xmodule/tests/xml/factories.py index 903f2d925e..a906713472 100644 --- a/common/lib/xmodule/xmodule/tests/xml/factories.py +++ b/common/lib/xmodule/xmodule/tests/xml/factories.py @@ -4,14 +4,13 @@ Factories for generating edXML for testing XModule import import inspect +from factory import Factory, Sequence, lazy_attribute, post_generation from fs.memoryfs import MemoryFS -from factory import Factory, lazy_attribute, post_generation, Sequence from lxml import etree - +from openedx.core.lib.xblock_fields.inherited_fields import InheritanceMixin from xblock.mixins import HierarchyMixin -from xmodule.modulestore.inheritance import InheritanceMixin -from xmodule.x_module import XModuleMixin from xmodule.modulestore import only_xmodules +from xmodule.x_module import XModuleMixin class XmlImportData(object): diff --git a/common/lib/xmodule/xmodule/timeinfo.py b/common/lib/xmodule/xmodule/timeinfo.py deleted file mode 100644 index 17ac38de52..0000000000 --- a/common/lib/xmodule/xmodule/timeinfo.py +++ /dev/null @@ -1,38 +0,0 @@ -import logging -from xmodule.fields import Timedelta -log = logging.getLogger(__name__) - - -class TimeInfo(object): - """ - This is a simple object that calculates and stores datetime information for an XModule - based on the due date and the grace period string - - So far it parses out three different pieces of time information: - self.display_due_date - the 'official' due date that gets displayed to students - self.grace_period - the length of the grace period - self.close_date - the real due date - - """ - _delta_standin = Timedelta() - - def __init__(self, due_date, grace_period_string_or_timedelta): - if due_date is not None: - self.display_due_date = due_date - - else: - self.display_due_date = None - - if grace_period_string_or_timedelta is not None and self.display_due_date: - if isinstance(grace_period_string_or_timedelta, basestring): - try: - self.grace_period = TimeInfo._delta_standin.from_json(grace_period_string_or_timedelta) - except: - log.error("Error parsing the grace period {0}".format(grace_period_string_or_timedelta)) - raise - else: - self.grace_period = grace_period_string_or_timedelta - self.close_date = self.display_due_date + self.grace_period - else: - self.grace_period = None - self.close_date = self.display_due_date diff --git a/common/lib/xmodule/xmodule/video_module/video_handlers.py b/common/lib/xmodule/xmodule/video_module/video_handlers.py index be70ef0a75..a6809ec1c9 100644 --- a/common/lib/xmodule/xmodule/video_module/video_handlers.py +++ b/common/lib/xmodule/xmodule/video_module/video_handlers.py @@ -8,26 +8,24 @@ StudioViewHandlers are handlers for video descriptor instance. import json import logging from datetime import datetime -from webob import Response -from xblock.core import XBlock - -from xmodule.exceptions import NotFoundError -from xmodule.fields import RelativeTime from opaque_keys.edx.locator import CourseLocator +from openedx.core.lib.xblock_fields.fields import RelativeTime +from webob import Response +from xblock.core import XBlock +from xmodule.exceptions import NotFoundError from .transcripts_utils import ( - get_or_create_sjson, + Transcript, TranscriptException, TranscriptsGenerationException, generate_sjson_for_all_speeds, - youtube_speed_dict, - Transcript, + get_or_create_sjson, save_to_store, - subs_filename + subs_filename, + youtube_speed_dict ) - log = logging.getLogger(__name__) diff --git a/common/lib/xmodule/xmodule/video_module/video_xfields.py b/common/lib/xmodule/xmodule/video_module/video_xfields.py index cec0036391..bf358aaeb1 100644 --- a/common/lib/xmodule/xmodule/video_module/video_xfields.py +++ b/common/lib/xmodule/xmodule/video_module/video_xfields.py @@ -3,8 +3,8 @@ XFields for video module. """ import datetime -from xblock.fields import Scope, String, Float, Boolean, List, Dict, DateTime -from xmodule.fields import RelativeTime +from openedx.core.lib.xblock_fields.fields import RelativeTime +from xblock.fields import Boolean, DateTime, Dict, Float, List, Scope, String # Make '_' a no-op so we can scrape strings. Using lambda instead of # `django.utils.translation.ugettext_noop` because Django cannot be imported in this file diff --git a/common/lib/xmodule/xmodule/x_module.py b/common/lib/xmodule/xmodule/x_module.py index 7e707f4884..f8dc7fdd9a 100644 --- a/common/lib/xmodule/xmodule/x_module.py +++ b/common/lib/xmodule/xmodule/x_module.py @@ -2,40 +2,41 @@ import logging import os import sys import time -import yaml - -from contracts import contract, new_contract -from functools import partial -from lxml import etree from collections import namedtuple -from pkg_resources import ( - resource_exists, - resource_listdir, - resource_string, - resource_isdir, -) +from functools import partial + +from pkg_resources import resource_exists, resource_isdir, resource_listdir, resource_string + +import dogstats_wrapper as dog_stats_api +import yaml +from contracts import contract, new_contract +from lazy import lazy +from lxml import etree +from opaque_keys.edx.asides import AsideDefinitionKeyV2, AsideUsageKeyV2 +from opaque_keys.edx.keys import UsageKey +from openedx.core.lib.xblock_fields.fields import RelativeTime from webob import Response from webob.multidict import MultiDict -from lazy import lazy - from xblock.core import XBlock, XBlockAside from xblock.fields import ( - Scope, Integer, Float, List, - String, Dict, ScopeIds, Reference, ReferenceList, - ReferenceValueDict, UserScope + Dict, + Float, + Integer, + List, + Reference, + ReferenceList, + ReferenceValueDict, + Scope, + ScopeIds, + String, + UserScope ) - from xblock.fragment import Fragment -from xblock.runtime import Runtime, IdReader, IdGenerator +from xblock.runtime import IdGenerator, IdReader, Runtime from xmodule import block_metadata_utils -from xmodule.fields import RelativeTime from xmodule.errortracker import exc_info_to_str -from xmodule.modulestore.exceptions import ItemNotFoundError - -from opaque_keys.edx.keys import UsageKey -from opaque_keys.edx.asides import AsideUsageKeyV2, AsideDefinitionKeyV2 from xmodule.exceptions import UndefinedContext -import dogstats_wrapper as dog_stats_api +from xmodule.modulestore.exceptions import ItemNotFoundError log = logging.getLogger(__name__) diff --git a/common/test/acceptance/tests/discussion/test_cohort_management.py b/common/test/acceptance/tests/discussion/test_cohort_management.py index 5d0319ea90..0acb2d8c6b 100644 --- a/common/test/acceptance/tests/discussion/test_cohort_management.py +++ b/common/test/acceptance/tests/discussion/test_cohort_management.py @@ -3,22 +3,21 @@ End-to-end tests related to the cohort management on the LMS Instructor Dashboard """ +import os +import uuid from datetime import datetime -from pytz import UTC, utc +import unicodecsv from bok_choy.promise import EmptyPromise -from nose.plugins.attrib import attr -from common.test.acceptance.tests.discussion.helpers import CohortTestMixin -from common.test.acceptance.tests.helpers import UniqueCourseTest, EventsTestMixin, create_user_partition_json -from xmodule.partitions.partitions import Group from common.test.acceptance.fixtures.course import CourseFixture, XBlockFixtureDesc from common.test.acceptance.pages.lms.auto_auth import AutoAuthPage -from common.test.acceptance.pages.lms.instructor_dashboard import InstructorDashboardPage, DataDownloadPage +from common.test.acceptance.pages.lms.instructor_dashboard import DataDownloadPage, InstructorDashboardPage from common.test.acceptance.pages.studio.settings_group_configurations import GroupConfigurationsPage - -import os -import unicodecsv -import uuid +from common.test.acceptance.tests.discussion.helpers import CohortTestMixin +from common.test.acceptance.tests.helpers import EventsTestMixin, UniqueCourseTest, create_user_partition_json +from nose.plugins.attrib import attr +from openedx.core.lib.partitions.partitions import Group +from pytz import UTC, utc @attr(shard=8) diff --git a/common/test/acceptance/tests/helpers.py b/common/test/acceptance/tests/helpers.py index da988ec6a3..d026814c18 100644 --- a/common/test/acceptance/tests/helpers.py +++ b/common/test/acceptance/tests/helpers.py @@ -2,42 +2,39 @@ Test helper functions and base classes. """ +import functools import inspect import json -import unittest -import functools import operator -import pprint -import requests import os +import pprint +import unittest import urlparse from contextlib import contextmanager from datetime import datetime -from path import Path as path +from unittest import TestCase +import requests from bok_choy.javascript import js_defined -from bok_choy.web_app_test import WebAppTest -from bok_choy.promise import EmptyPromise, Promise from bok_choy.page_object import XSS_INJECTION +from bok_choy.promise import EmptyPromise, Promise +from bok_choy.web_app_test import WebAppTest from capa.tests.response_xml_factory import MultipleChoiceResponseXMLFactory -from common.test.acceptance.pages.studio.auto_auth import AutoAuthPage from common.test.acceptance.fixtures.course import XBlockFixtureDesc +from common.test.acceptance.pages.common import BASE_URL +from common.test.acceptance.pages.studio.auto_auth import AutoAuthPage from opaque_keys.edx.locator import CourseLocator -from pymongo import MongoClient, ASCENDING -from openedx.core.lib.tests.assertions.events import assert_event_matches, is_matching_event, EventMatchTolerates -from xmodule.partitions.partitions import UserPartition +from openedx.core.lib.partitions.partitions import UserPartition +from openedx.core.lib.tests.assertions.events import EventMatchTolerates, assert_event_matches, is_matching_event +from openedx.core.release import RELEASE_LINE, doc_version +from path import Path as path +from pymongo import ASCENDING, MongoClient from selenium.common.exceptions import StaleElementReferenceException from selenium.webdriver.common.desired_capabilities import DesiredCapabilities from selenium.webdriver.common.keys import Keys +from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.select import Select from selenium.webdriver.support.ui import WebDriverWait -from selenium.webdriver.support import expected_conditions as EC -from unittest import TestCase - -from openedx.core.release import doc_version, RELEASE_LINE - -from common.test.acceptance.pages.common import BASE_URL - MAX_EVENTS_IN_FAILURE_OUTPUT = 20 diff --git a/common/test/acceptance/tests/lms/test_lms_split_test_courseware_search.py b/common/test/acceptance/tests/lms/test_lms_split_test_courseware_search.py index 265f2874a0..28c0403fc2 100644 --- a/common/test/acceptance/tests/lms/test_lms_split_test_courseware_search.py +++ b/common/test/acceptance/tests/lms/test_lms_split_test_courseware_search.py @@ -4,20 +4,15 @@ Test courseware search import json -from common.test.acceptance.tests.helpers import remove_file -from common.test.acceptance.pages.common.logout import LogoutPage -from common.test.acceptance.pages.studio.overview import CourseOutlinePage as StudioCourseOutlinePage -from common.test.acceptance.pages.lms.courseware_search import CoursewareSearchPage from common.test.acceptance.fixtures.course import XBlockFixtureDesc -from common.test.acceptance.tests.helpers import create_user_partition_json - -from xmodule.partitions.partitions import Group - -from nose.plugins.attrib import attr - -from common.test.acceptance.tests.studio.base_studio_test import ContainerBase - +from common.test.acceptance.pages.common.logout import LogoutPage +from common.test.acceptance.pages.lms.courseware_search import CoursewareSearchPage from common.test.acceptance.pages.studio.auto_auth import AutoAuthPage as StudioAutoAuthPage +from common.test.acceptance.pages.studio.overview import CourseOutlinePage as StudioCourseOutlinePage +from common.test.acceptance.tests.helpers import create_user_partition_json, remove_file +from common.test.acceptance.tests.studio.base_studio_test import ContainerBase +from nose.plugins.attrib import attr +from openedx.core.lib.partitions.partitions import Group @attr(shard=1) diff --git a/common/test/acceptance/tests/lms/test_lms_user_preview.py b/common/test/acceptance/tests/lms/test_lms_user_preview.py index e7ad6484ee..2a0e4979e2 100644 --- a/common/test/acceptance/tests/lms/test_lms_user_preview.py +++ b/common/test/acceptance/tests/lms/test_lms_user_preview.py @@ -4,17 +4,17 @@ Tests the "preview" selector in the LMS that allows changing between Staff, Lear """ -from nose.plugins.attrib import attr +from textwrap import dedent -from common.test.acceptance.tests.helpers import UniqueCourseTest, create_user_partition_json -from common.test.acceptance.pages.studio.auto_auth import AutoAuthPage +from bok_choy.promise import EmptyPromise +from common.test.acceptance.fixtures.course import CourseFixture, XBlockFixtureDesc from common.test.acceptance.pages.lms.courseware import CoursewarePage from common.test.acceptance.pages.lms.instructor_dashboard import InstructorDashboardPage from common.test.acceptance.pages.lms.staff_view import StaffCoursewarePage -from common.test.acceptance.fixtures.course import CourseFixture, XBlockFixtureDesc -from bok_choy.promise import EmptyPromise -from xmodule.partitions.partitions import (Group, ENROLLMENT_TRACK_PARTITION_ID, MINIMUM_STATIC_PARTITION_ID) -from textwrap import dedent +from common.test.acceptance.pages.studio.auto_auth import AutoAuthPage +from common.test.acceptance.tests.helpers import UniqueCourseTest, create_user_partition_json +from nose.plugins.attrib import attr +from openedx.core.lib.partitions.partitions import ENROLLMENT_TRACK_PARTITION_ID, MINIMUM_STATIC_PARTITION_ID, Group @attr(shard=10) diff --git a/common/test/acceptance/tests/studio/test_studio_container.py b/common/test/acceptance/tests/studio/test_studio_container.py index 8ba505561e..4429c403a7 100644 --- a/common/test/acceptance/tests/studio/test_studio_container.py +++ b/common/test/acceptance/tests/studio/test_studio_container.py @@ -4,26 +4,22 @@ The container page is used both for displaying units, and for displaying containers within units. """ import datetime -import ddt -from nose.plugins.attrib import attr from unittest import skip +import ddt from base_studio_test import ContainerBase - from common.test.acceptance.fixtures.course import XBlockFixtureDesc +from common.test.acceptance.pages.lms.courseware import CoursewarePage from common.test.acceptance.pages.lms.create_mode import ModeCreationPage +from common.test.acceptance.pages.lms.staff_view import StaffCoursewarePage from common.test.acceptance.pages.studio.component_editor import ComponentEditorView, ComponentVisibilityEditorView from common.test.acceptance.pages.studio.container import ContainerPage from common.test.acceptance.pages.studio.html_component_editor import HtmlComponentEditorView from common.test.acceptance.pages.studio.move_xblock import MoveModalView from common.test.acceptance.pages.studio.utils import add_discussion, drag -from common.test.acceptance.pages.lms.courseware import CoursewarePage -from common.test.acceptance.pages.lms.staff_view import StaffCoursewarePage from common.test.acceptance.tests.helpers import create_user_partition_json - -from xmodule.partitions.partitions import ( - Group, ENROLLMENT_TRACK_PARTITION_ID, MINIMUM_STATIC_PARTITION_ID -) +from nose.plugins.attrib import attr +from openedx.core.lib.partitions.partitions import ENROLLMENT_TRACK_PARTITION_ID, MINIMUM_STATIC_PARTITION_ID, Group class NestedVerticalTest(ContainerBase): diff --git a/common/test/acceptance/tests/studio/test_studio_settings.py b/common/test/acceptance/tests/studio/test_studio_settings.py index e329c36e9c..f5347b24e4 100644 --- a/common/test/acceptance/tests/studio/test_studio_settings.py +++ b/common/test/acceptance/tests/studio/test_studio_settings.py @@ -3,25 +3,24 @@ Acceptance tests for Studio's Setting pages """ from __future__ import unicode_literals -import os -from mock import patch -from nose.plugins.attrib import attr +import os +from textwrap import dedent from base_studio_test import StudioCourseTest from bok_choy.promise import EmptyPromise from common.test.acceptance.fixtures.course import XBlockFixtureDesc -from common.test.acceptance.tests.helpers import create_user_partition_json, element_has_text +from common.test.acceptance.pages.common.utils import add_enrollment_course_modes +from common.test.acceptance.pages.lms.courseware import CoursewarePage from common.test.acceptance.pages.studio.overview import CourseOutlinePage from common.test.acceptance.pages.studio.settings import SettingsPage from common.test.acceptance.pages.studio.settings_advanced import AdvancedSettingsPage from common.test.acceptance.pages.studio.settings_group_configurations import GroupConfigurationsPage -from common.test.acceptance.pages.lms.courseware import CoursewarePage from common.test.acceptance.pages.studio.utils import get_input_value -from common.test.acceptance.pages.common.utils import add_enrollment_course_modes - -from textwrap import dedent -from xmodule.partitions.partitions import Group +from common.test.acceptance.tests.helpers import create_user_partition_json, element_has_text +from mock import patch +from nose.plugins.attrib import attr +from openedx.core.lib.partitions.partitions import Group @attr(shard=8) diff --git a/common/test/acceptance/tests/studio/test_studio_split_test.py b/common/test/acceptance/tests/studio/test_studio_split_test.py index 9bc0c4d90b..2b3dfeab89 100644 --- a/common/test/acceptance/tests/studio/test_studio_split_test.py +++ b/common/test/acceptance/tests/studio/test_studio_split_test.py @@ -4,24 +4,21 @@ Acceptance tests for Studio related to the split_test module. import math from unittest import skip -from nose.plugins.attrib import attr -from selenium.webdriver.support.ui import Select - -from xmodule.partitions.partitions import Group -from bok_choy.promise import Promise, EmptyPromise +from base_studio_test import StudioCourseTest +from bok_choy.promise import EmptyPromise, Promise from common.test.acceptance.fixtures.course import XBlockFixtureDesc +from common.test.acceptance.pages.lms.courseware import CoursewarePage from common.test.acceptance.pages.studio.component_editor import ComponentEditorView -from common.test.acceptance.pages.studio.overview import CourseOutlinePage, CourseOutlineUnit from common.test.acceptance.pages.studio.container import ContainerPage +from common.test.acceptance.pages.studio.overview import CourseOutlinePage, CourseOutlineUnit from common.test.acceptance.pages.studio.settings_group_configurations import GroupConfigurationsPage from common.test.acceptance.pages.studio.utils import add_advanced_component from common.test.acceptance.pages.xblock.utils import wait_for_xblock_initialization -from common.test.acceptance.pages.lms.courseware import CoursewarePage from common.test.acceptance.tests.helpers import create_user_partition_json - -from base_studio_test import StudioCourseTest - +from nose.plugins.attrib import attr +from openedx.core.lib.partitions.partitions import Group +from selenium.webdriver.support.ui import Select from test_studio_container import ContainerBase diff --git a/lms/djangoapps/course_api/tests/test_serializers.py b/lms/djangoapps/course_api/tests/test_serializers.py index b1d1e76bb6..b6e850a954 100644 --- a/lms/djangoapps/course_api/tests/test_serializers.py +++ b/lms/djangoapps/course_api/tests/test_serializers.py @@ -9,11 +9,11 @@ import ddt from nose.plugins.attrib import attr from openedx.core.djangoapps.models.course_details import CourseDetails from openedx.core.djangoapps.content.course_overviews.models import CourseOverview +from openedx.core.lib.xblock_fields.inherited_fields import DEFAULT_START_DATE from rest_framework.test import APIRequestFactory from rest_framework.request import Request from xblock.core import XBlock -from xmodule.course_module import DEFAULT_START_DATE from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.factories import check_mongo_calls diff --git a/lms/djangoapps/course_blocks/transformers/start_date.py b/lms/djangoapps/course_blocks/transformers/start_date.py index 561d3c3153..40e7cdd125 100644 --- a/lms/djangoapps/course_blocks/transformers/start_date.py +++ b/lms/djangoapps/course_blocks/transformers/start_date.py @@ -6,7 +6,7 @@ from openedx.core.djangoapps.content.block_structure.transformer import ( FilteringTransformerMixin, ) from lms.djangoapps.courseware.access_utils import check_start_date -from xmodule.course_metadata_utils import DEFAULT_START_DATE +from openedx.core.lib.xblock_fields.inherited_fields import DEFAULT_START_DATE from .utils import collect_merged_date_field diff --git a/lms/djangoapps/course_blocks/transformers/tests/test_split_test.py b/lms/djangoapps/course_blocks/transformers/tests/test_split_test.py index f5110868f5..74c56ef1eb 100644 --- a/lms/djangoapps/course_blocks/transformers/tests/test_split_test.py +++ b/lms/djangoapps/course_blocks/transformers/tests/test_split_test.py @@ -2,12 +2,11 @@ Tests for SplitTestTransformer. """ import ddt -from nose.plugins.attrib import attr - import openedx.core.djangoapps.user_api.course_tag.api as course_tag_api +from nose.plugins.attrib import attr from openedx.core.djangoapps.user_api.partition_schemes import RandomUserPartitionScheme +from openedx.core.lib.partitions.partitions import Group, UserPartition from student.tests.factories import CourseEnrollmentFactory -from xmodule.partitions.partitions import Group, UserPartition from xmodule.modulestore.tests.factories import check_mongo_calls from ...api import get_course_blocks diff --git a/lms/djangoapps/course_blocks/transformers/tests/test_user_partitions.py b/lms/djangoapps/course_blocks/transformers/tests/test_user_partitions.py index 2d51078a3b..3ec4924216 100644 --- a/lms/djangoapps/course_blocks/transformers/tests/test_user_partitions.py +++ b/lms/djangoapps/course_blocks/transformers/tests/test_user_partitions.py @@ -2,17 +2,17 @@ """ Tests for UserPartitionTransformer. """ +import string from collections import namedtuple + import ddt from nose.plugins.attrib import attr -import string - +from openedx.core.djangoapps.course_groups.cohorts import add_user_to_cohort from openedx.core.djangoapps.course_groups.partition_scheme import CohortPartitionScheme from openedx.core.djangoapps.course_groups.tests.helpers import CohortFactory, config_course_cohorts -from openedx.core.djangoapps.course_groups.cohorts import add_user_to_cohort from openedx.core.djangoapps.course_groups.views import link_cohort_to_partition_group +from openedx.core.lib.partitions.partitions import Group, UserPartition from student.tests.factories import CourseEnrollmentFactory -from xmodule.partitions.partitions import Group, UserPartition from xmodule.modulestore.tests.factories import CourseFactory from ...api import get_course_blocks diff --git a/lms/djangoapps/course_blocks/transformers/user_partitions.py b/lms/djangoapps/course_blocks/transformers/user_partitions.py index a01cdf3b54..488ae1ac5c 100644 --- a/lms/djangoapps/course_blocks/transformers/user_partitions.py +++ b/lms/djangoapps/course_blocks/transformers/user_partitions.py @@ -3,9 +3,9 @@ User Partitions Transformer """ from openedx.core.djangoapps.content.block_structure.transformer import ( BlockStructureTransformer, - FilteringTransformerMixin, + FilteringTransformerMixin ) -from xmodule.partitions.partitions_service import get_all_partitions_for_course +from openedx.core.lib.partitions.partitions_service import get_all_partitions_for_course from .split_test import SplitTestTransformer from .utils import get_field_on_block diff --git a/lms/djangoapps/courseware/access.py b/lms/djangoapps/courseware/access.py index c60368fe1d..1718bc8d90 100644 --- a/lms/djangoapps/courseware/access.py +++ b/lms/djangoapps/courseware/access.py @@ -10,33 +10,12 @@ Note: The access control logic in this file does NOT check for enrollment in If enrollment is to be checked, use get_course_with_access in courseware.courses. It is a wrapper around has_access that additionally checks for enrollment. """ -from datetime import datetime import logging +from datetime import datetime + import pytz - -from django.conf import settings -from django.contrib.auth.models import AnonymousUser -from django.utils.timezone import UTC - -from opaque_keys.edx.keys import CourseKey, UsageKey - -from util import milestones_helpers as milestones_helpers -from xblock.core import XBlock - -from xmodule.course_module import ( - CourseDescriptor, - CATALOG_VISIBILITY_CATALOG_AND_ABOUT, - CATALOG_VISIBILITY_ABOUT, -) -from xmodule.error_module import ErrorDescriptor -from xmodule.x_module import XModule -from xmodule.partitions.partitions import NoSuchUserPartitionError, NoSuchUserPartitionGroupError - -from courseware.access_response import ( - MilestoneError, - MobileAvailabilityError, - VisibilityError, -) +from ccx_keys.locator import CCXLocator +from courseware.access_response import MilestoneError, MobileAvailabilityError, VisibilityError from courseware.access_utils import ( ACCESS_DENIED, ACCESS_GRANTED, @@ -46,11 +25,16 @@ from courseware.access_utils import ( in_preview_mode ) from courseware.masquerade import get_masquerade_role, is_masquerading_as_student +from django.conf import settings +from django.contrib.auth.models import AnonymousUser +from django.utils.timezone import UTC from lms.djangoapps.ccx.custom_exception import CCXLocatorValidationException from lms.djangoapps.ccx.models import CustomCourseForEdX from mobile_api.models import IgnoreMobileAvailableFlagConfig +from opaque_keys.edx.keys import CourseKey, UsageKey from openedx.core.djangoapps.content.course_overviews.models import CourseOverview from openedx.core.djangoapps.external_auth.models import ExternalAuthMap +from openedx.core.lib.partitions.partitions import NoSuchUserPartitionError, NoSuchUserPartitionGroupError from student import auth from student.models import CourseEnrollmentAllowed from student.roles import ( @@ -59,16 +43,20 @@ from student.roles import ( CourseInstructorRole, CourseStaffRole, GlobalStaff, - SupportStaffRole, OrgInstructorRole, OrgStaffRole, + SupportStaffRole ) +from util import milestones_helpers as milestones_helpers from util.milestones_helpers import ( - get_pre_requisite_courses_not_completed, any_unfulfilled_milestones, - is_prerequisite_courses_enabled, + get_pre_requisite_courses_not_completed, + is_prerequisite_courses_enabled ) -from ccx_keys.locator import CCXLocator +from xblock.core import XBlock +from xmodule.course_module import CATALOG_VISIBILITY_ABOUT, CATALOG_VISIBILITY_CATALOG_AND_ABOUT, CourseDescriptor +from xmodule.error_module import ErrorDescriptor +from xmodule.x_module import XModule log = logging.getLogger(__name__) diff --git a/lms/djangoapps/courseware/access_response.py b/lms/djangoapps/courseware/access_response.py index 976571cf24..75c86547d1 100644 --- a/lms/djangoapps/courseware/access_response.py +++ b/lms/djangoapps/courseware/access_response.py @@ -3,7 +3,7 @@ This file contains all the classes used by has_access for error handling """ from django.utils.translation import ugettext as _ -from xmodule.course_metadata_utils import DEFAULT_START_DATE +from openedx.core.lib.xblock_fields.inherited_fields import DEFAULT_START_DATE class AccessResponse(object): diff --git a/lms/djangoapps/courseware/field_overrides.py b/lms/djangoapps/courseware/field_overrides.py index 02417d9515..2f9be430e1 100644 --- a/lms/djangoapps/courseware/field_overrides.py +++ b/lms/djangoapps/courseware/field_overrides.py @@ -14,16 +14,14 @@ package and is used to wrap the `authored_data` when constructing an `LmsFieldData`. This means overrides will be in effect for all scopes covered by `authored_data`, e.g. course content and settings stored in Mongo. """ +import threading from abc import ABCMeta, abstractmethod from contextlib import contextmanager -import threading from django.conf import settings -from xblock.field_data import FieldData - +from openedx.core.lib.xblock_fields.inherited_fields import InheritanceMixin from request_cache.middleware import RequestCache -from xmodule.modulestore.inheritance import InheritanceMixin - +from xblock.field_data import FieldData NOTSET = object() ENABLED_OVERRIDE_PROVIDERS_KEY = u'courseware.field_overrides.enabled_providers.{course_id}' diff --git a/lms/djangoapps/courseware/masquerade.py b/lms/djangoapps/courseware/masquerade.py index 5cfeac5c10..ce4eb59083 100644 --- a/lms/djangoapps/courseware/masquerade.py +++ b/lms/djangoapps/courseware/masquerade.py @@ -11,14 +11,12 @@ from django.contrib.auth.decorators import login_required from django.contrib.auth.models import User from django.utils.translation import ugettext as _ from django.views.decorators.http import require_POST -from student.models import CourseEnrollment -from util.json_request import expect_json, JsonResponse - from opaque_keys.edx.keys import CourseKey +from openedx.core.lib.partitions.partitions import NoSuchUserPartitionGroupError +from student.models import CourseEnrollment +from util.json_request import JsonResponse, expect_json from xblock.fragment import Fragment from xblock.runtime import KeyValueStore -from xmodule.partitions.partitions import NoSuchUserPartitionGroupError - log = logging.getLogger(__name__) diff --git a/lms/djangoapps/courseware/tests/test_access.py b/lms/djangoapps/courseware/tests/test_access.py index f509c9f6fe..ad32685be2 100644 --- a/lms/djangoapps/courseware/tests/test_access.py +++ b/lms/djangoapps/courseware/tests/test_access.py @@ -3,66 +3,60 @@ Test the access control framework """ import datetime -import ddt import itertools -import pytz -from django.contrib.auth.models import User -from ccx_keys.locator import CCXLocator -from django.test.client import RequestFactory -from django.core.urlresolvers import reverse -from django.test import TestCase -from mock import Mock, patch -from nose.plugins.attrib import attr -from opaque_keys.edx.locations import SlashSeparatedCourseKey - -from ccx.tests.factories import CcxFactory import courseware.access as access import courseware.access_response as access_response +import ddt +import pytz +from ccx.tests.factories import CcxFactory +from ccx_keys.locator import CCXLocator from courseware.masquerade import CourseMasquerade from courseware.tests.factories import ( BetaTesterFactory, GlobalStaffFactory, InstructorFactory, StaffFactory, - UserFactory, + UserFactory ) from courseware.tests.helpers import LoginEnrollmentTestCase, masquerade_as_group_member +from django.contrib.auth.models import User +from django.core.urlresolvers import reverse +from django.test import TestCase +from django.test.client import RequestFactory +from lms.djangoapps.ccx.models import CustomCourseForEdX +from milestones.tests.utils import MilestonesTestCaseMixin +from mock import Mock, patch +from nose.plugins.attrib import attr +from opaque_keys.edx.locations import SlashSeparatedCourseKey from openedx.core.djangoapps.content.course_overviews.models import CourseOverview +from openedx.core.lib.partitions.partitions import MINIMUM_STATIC_PARTITION_ID, Group, UserPartition from student.models import CourseEnrollment from student.roles import CourseCcxCoachRole, CourseStaffRole from student.tests.factories import ( AdminFactory, AnonymousUserFactory, CourseEnrollmentAllowedFactory, - CourseEnrollmentFactory, + CourseEnrollmentFactory ) - +from util.milestones_helpers import fulfill_course_milestone, set_prerequisite_courses from xmodule.course_module import ( - CATALOG_VISIBILITY_CATALOG_AND_ABOUT, CATALOG_VISIBILITY_ABOUT, - CATALOG_VISIBILITY_NONE, + CATALOG_VISIBILITY_CATALOG_AND_ABOUT, + CATALOG_VISIBILITY_NONE ) from xmodule.error_module import ErrorDescriptor -from xmodule.partitions.partitions import Group, UserPartition, MINIMUM_STATIC_PARTITION_ID from xmodule.modulestore import ModuleStoreEnum from xmodule.modulestore.django import modulestore -from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory from xmodule.modulestore.tests.django_utils import ( + TEST_DATA_SPLIT_MODULESTORE, ModuleStoreTestCase, - SharedModuleStoreTestCase, - TEST_DATA_SPLIT_MODULESTORE + SharedModuleStoreTestCase ) +from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory from xmodule.modulestore.xml import CourseLocationManager from xmodule.tests import get_test_system -from util.milestones_helpers import ( - set_prerequisite_courses, - fulfill_course_milestone, -) -from milestones.tests.utils import MilestonesTestCaseMixin - -from lms.djangoapps.ccx.models import CustomCourseForEdX # pylint: disable=protected-access diff --git a/lms/djangoapps/courseware/tests/test_group_access.py b/lms/djangoapps/courseware/tests/test_group_access.py index a762e4d88b..dd2eb83249 100644 --- a/lms/djangoapps/courseware/tests/test_group_access.py +++ b/lms/djangoapps/courseware/tests/test_group_access.py @@ -3,17 +3,15 @@ This module defines tests for courseware.access that are specific to group access control rules. """ +import courseware.access as access import ddt +from courseware.tests.factories import StaffFactory, UserFactory from nose.plugins.attrib import attr +from openedx.core.lib.partitions.partitions import USER_PARTITION_SCHEME_NAMESPACE, Group, UserPartition from stevedore.extension import Extension, ExtensionManager - +from xmodule.modulestore.django import modulestore from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory -from xmodule.partitions.partitions import Group, UserPartition, USER_PARTITION_SCHEME_NAMESPACE -from xmodule.modulestore.django import modulestore - -import courseware.access as access -from courseware.tests.factories import StaffFactory, UserFactory class MemoryUserPartitionScheme(object): diff --git a/lms/djangoapps/courseware/tests/test_masquerade.py b/lms/djangoapps/courseware/tests/test_masquerade.py index 64f175cf0d..16809614bb 100644 --- a/lms/djangoapps/courseware/tests/test_masquerade.py +++ b/lms/djangoapps/courseware/tests/test_masquerade.py @@ -3,32 +3,31 @@ Unit tests for masquerade. """ import json import pickle -from mock import patch -from nose.plugins.attrib import attr from datetime import datetime -from django.core.urlresolvers import reverse -from django.test import TestCase -from django.utils.timezone import UTC - from capa.tests.response_xml_factory import OptionResponseXMLFactory from courseware.masquerade import ( CourseMasquerade, MasqueradingKeyValueStore, + get_masquerading_user_group, handle_ajax, - setup_masquerade, - get_masquerading_user_group + setup_masquerade ) from courseware.tests.factories import StaffFactory from courseware.tests.helpers import LoginEnrollmentTestCase, masquerade_as_group_member from courseware.tests.test_submitting_problems import ProblemSubmissionTestMixin +from django.core.urlresolvers import reverse +from django.test import TestCase +from django.utils.timezone import UTC +from mock import patch +from nose.plugins.attrib import attr +from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration +from openedx.core.lib.partitions.partitions import Group, UserPartition from student.tests.factories import UserFactory from xblock.runtime import DictKeyValueStore from xmodule.modulestore.django import modulestore from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase -from xmodule.modulestore.tests.factories import ItemFactory, CourseFactory -from xmodule.partitions.partitions import Group, UserPartition -from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration +from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory class MasqueradeTestCase(SharedModuleStoreTestCase, LoginEnrollmentTestCase): diff --git a/lms/djangoapps/courseware/tests/test_split_module.py b/lms/djangoapps/courseware/tests/test_split_module.py index c7aa323170..4c6faea405 100644 --- a/lms/djangoapps/courseware/tests/test_split_module.py +++ b/lms/djangoapps/courseware/tests/test_split_module.py @@ -1,17 +1,16 @@ """ Test for split test XModule """ +from courseware.model_data import FieldDataCache +from courseware.module_render import get_module_for_descriptor from django.core.urlresolvers import reverse from mock import MagicMock from nose.plugins.attrib import attr - -from courseware.module_render import get_module_for_descriptor -from courseware.model_data import FieldDataCache -from student.tests.factories import UserFactory, CourseEnrollmentFactory -from xmodule.modulestore.tests.factories import ItemFactory, CourseFactory -from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase -from xmodule.partitions.partitions import Group, UserPartition from openedx.core.djangoapps.user_api.tests.factories import UserCourseTagFactory +from openedx.core.lib.partitions.partitions import Group, UserPartition +from student.tests.factories import CourseEnrollmentFactory, UserFactory +from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase +from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory @attr(shard=1) diff --git a/lms/djangoapps/courseware/tests/test_submitting_problems.py b/lms/djangoapps/courseware/tests/test_submitting_problems.py index 2532e67d55..0d389fedc2 100644 --- a/lms/djangoapps/courseware/tests/test_submitting_problems.py +++ b/lms/djangoapps/courseware/tests/test_submitting_problems.py @@ -10,34 +10,33 @@ import os from textwrap import dedent import ddt +from capa.tests.response_xml_factory import ( + CodeResponseXMLFactory, + CustomResponseXMLFactory, + OptionResponseXMLFactory, + SchematicResponseXMLFactory +) +from course_modes.models import CourseMode +from courseware.models import BaseStudentModuleHistory, StudentModule +from courseware.tests.helpers import LoginEnrollmentTestCase from django.conf import settings from django.contrib.auth.models import User from django.core.urlresolvers import reverse from django.test import TestCase from django.test.client import RequestFactory from django.utils.timezone import now +from lms.djangoapps.grades.new.course_grade_factory import CourseGradeFactory from mock import patch from nose.plugins.attrib import attr - -from capa.tests.response_xml_factory import ( - OptionResponseXMLFactory, CustomResponseXMLFactory, SchematicResponseXMLFactory, - CodeResponseXMLFactory, -) -from course_modes.models import CourseMode -from courseware.models import StudentModule, BaseStudentModuleHistory -from courseware.tests.helpers import LoginEnrollmentTestCase -from lms.djangoapps.grades.new.course_grade_factory import CourseGradeFactory -from openedx.core.djangoapps.credit.api import ( - set_credit_requirements, get_credit_requirement_status -) +from openedx.core.djangoapps.credit.api import get_credit_requirement_status, set_credit_requirements from openedx.core.djangoapps.credit.models import CreditCourse, CreditProvider from openedx.core.djangoapps.user_api.tests.factories import UserCourseTagFactory +from openedx.core.lib.partitions.partitions import Group, UserPartition from openedx.core.lib.url_utils import quote_slashes -from student.models import anonymous_id_for_user, CourseEnrollment +from student.models import CourseEnrollment, anonymous_id_for_user from submissions import api as submissions_api from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory -from xmodule.partitions.partitions import Group, UserPartition class ProblemSubmissionTestMixin(TestCase): diff --git a/lms/djangoapps/discussion_api/tests/test_api.py b/lms/djangoapps/discussion_api/tests/test_api.py index 32b818906d..f32c90cc42 100644 --- a/lms/djangoapps/discussion_api/tests/test_api.py +++ b/lms/djangoapps/discussion_api/tests/test_api.py @@ -1,24 +1,14 @@ """ Tests for Discussion API internal interface """ -from datetime import datetime, timedelta import itertools -from urlparse import parse_qs, urlparse, urlunparse +from datetime import datetime, timedelta from urllib import urlencode +from urlparse import parse_qs, urlparse, urlunparse import ddt import httpretty import mock -from nose.plugins.attrib import attr -from pytz import UTC - -from django.core.exceptions import ValidationError -from django.test.client import RequestFactory - -from rest_framework.exceptions import PermissionDenied - -from opaque_keys.edx.locator import CourseLocator - from common.test.utils import MockSignalHandlerMixin, disable_signal from courseware.tests.factories import BetaTesterFactory, StaffFactory from discussion_api import api @@ -30,35 +20,41 @@ from discussion_api.api import ( get_comment_list, get_course, get_course_topics, + get_thread, get_thread_list, update_comment, - update_thread, - get_thread, + update_thread ) -from discussion_api.exceptions import DiscussionDisabledError, ThreadNotFoundError, CommentNotFoundError +from discussion_api.exceptions import CommentNotFoundError, DiscussionDisabledError, ThreadNotFoundError from discussion_api.tests.utils import ( CommentsServiceMockMixin, make_minimal_cs_comment, make_minimal_cs_thread, - make_paginated_api_response, + make_paginated_api_response ) +from django.core.exceptions import ValidationError +from django.test.client import RequestFactory +from django_comment_client.tests.utils import ForumsEnableMixin from django_comment_common.models import ( FORUM_ROLE_ADMINISTRATOR, FORUM_ROLE_COMMUNITY_TA, FORUM_ROLE_MODERATOR, FORUM_ROLE_STUDENT, - Role, + Role ) -from django_comment_client.tests.utils import ForumsEnableMixin +from nose.plugins.attrib import attr +from opaque_keys.edx.locator import CourseLocator from openedx.core.djangoapps.course_groups.models import CourseUserGroupPartitionGroup from openedx.core.djangoapps.course_groups.tests.helpers import CohortFactory from openedx.core.lib.exceptions import CourseNotFoundError, PageNotFoundError +from openedx.core.lib.partitions.partitions import Group, UserPartition +from pytz import UTC +from rest_framework.exceptions import PermissionDenied from student.tests.factories import CourseEnrollmentFactory, UserFactory from util.testing import UrlResetMixin from xmodule.modulestore.django import modulestore from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase, SharedModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory -from xmodule.partitions.partitions import Group, UserPartition def _remove_discussion_tab(course, user_id): diff --git a/lms/djangoapps/instructor/tests/test_api.py b/lms/djangoapps/instructor/tests/test_api.py index b06a99bd7d..97a264052b 100644 --- a/lms/djangoapps/instructor/tests/test_api.py +++ b/lms/djangoapps/instructor/tests/test_api.py @@ -3,15 +3,30 @@ Unit tests for instructor.api methods. """ import datetime -import ddt import functools -import random -import pytz import io import json +import random import shutil import tempfile +import ddt +import lms.djangoapps.instructor.views.api +import lms.djangoapps.instructor_task.api +import pytz +from bulk_email.models import BulkEmailFlag, CourseEmail, CourseEmailTemplate +from certificates.models import CertificateStatuses +from certificates.tests.factories import GeneratedCertificateFactory +from course_modes.models import CourseMode +from courseware.models import StudentFieldOverride, StudentModule +from courseware.tests.factories import ( + BetaTesterFactory, + GlobalStaffFactory, + InstructorFactory, + StaffFactory, + UserProfileFactory +) +from courseware.tests.helpers import LoginEnrollmentTestCase from django.conf import settings from django.contrib.auth.models import User from django.core import mail @@ -22,55 +37,56 @@ from django.test import RequestFactory, TestCase from django.test.utils import override_settings from django.utils.timezone import utc from django.utils.translation import ugettext as _ - -from mock import Mock, patch -from nose.tools import raises -from nose.plugins.attrib import attr -from opaque_keys.edx.locations import SlashSeparatedCourseKey -from opaque_keys.edx.locator import UsageKey -from xmodule.modulestore import ModuleStoreEnum - -from bulk_email.models import BulkEmailFlag, CourseEmail, CourseEmailTemplate -from course_modes.models import CourseMode -from courseware.models import StudentModule -from courseware.tests.factories import ( - BetaTesterFactory, GlobalStaffFactory, InstructorFactory, StaffFactory, UserProfileFactory -) -from courseware.tests.helpers import LoginEnrollmentTestCase from django_comment_common.models import FORUM_ROLE_COMMUNITY_TA from django_comment_common.utils import seed_permissions_roles -from shoppingcart.models import ( - RegistrationCodeRedemption, Order, CouponRedemption, - PaidCourseRegistration, Coupon, Invoice, CourseRegistrationCode, CourseRegistrationCodeInvoiceItem, - InvoiceTransaction) -from shoppingcart.pdf import PDFInvoice -from student.models import ( - CourseEnrollment, CourseEnrollmentAllowed, NonExistentCourseError, - ManualEnrollmentAudit, UNENROLLED_TO_ENROLLED, ENROLLED_TO_UNENROLLED, - ALLOWEDTOENROLL_TO_UNENROLLED, ENROLLED_TO_ENROLLED, UNENROLLED_TO_ALLOWEDTOENROLL, - UNENROLLED_TO_UNENROLLED, ALLOWEDTOENROLL_TO_ENROLLED -) -from student.tests.factories import UserFactory, CourseModeFactory, AdminFactory -from student.roles import CourseBetaTesterRole, CourseSalesAdminRole, CourseFinanceAdminRole, CourseInstructorRole -from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase, ModuleStoreTestCase -from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory -from xmodule.fields import Date - -from courseware.models import StudentFieldOverride - -import lms.djangoapps.instructor_task.api -import lms.djangoapps.instructor.views.api -from lms.djangoapps.instructor.views.api import require_finance_admin from lms.djangoapps.instructor.tests.utils import FakeContentTask, FakeEmail, FakeEmailInfo -from lms.djangoapps.instructor.views.api import _split_input_list, common_exceptions_400, generate_unique_password +from lms.djangoapps.instructor.views.api import ( + _split_input_list, + common_exceptions_400, + generate_unique_password, + require_finance_admin +) from lms.djangoapps.instructor_task.api_helper import AlreadyRunningError -from certificates.tests.factories import GeneratedCertificateFactory -from certificates.models import CertificateStatuses - +from mock import Mock, patch +from nose.plugins.attrib import attr +from nose.tools import raises +from opaque_keys.edx.locations import SlashSeparatedCourseKey +from opaque_keys.edx.locator import UsageKey from openedx.core.djangoapps.course_groups.cohorts import set_course_cohort_settings -from openedx.core.lib.xblock_utils import grade_histogram from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers from openedx.core.djangoapps.site_configuration.tests.mixins import SiteMixin +from openedx.core.lib.xblock_fields.fields import Date +from openedx.core.lib.xblock_utils import grade_histogram +from shoppingcart.models import ( + Coupon, + CouponRedemption, + CourseRegistrationCode, + CourseRegistrationCodeInvoiceItem, + Invoice, + InvoiceTransaction, + Order, + PaidCourseRegistration, + RegistrationCodeRedemption +) +from shoppingcart.pdf import PDFInvoice +from student.models import ( + ALLOWEDTOENROLL_TO_ENROLLED, + ALLOWEDTOENROLL_TO_UNENROLLED, + ENROLLED_TO_ENROLLED, + ENROLLED_TO_UNENROLLED, + UNENROLLED_TO_ALLOWEDTOENROLL, + UNENROLLED_TO_ENROLLED, + UNENROLLED_TO_UNENROLLED, + CourseEnrollment, + CourseEnrollmentAllowed, + ManualEnrollmentAudit, + NonExistentCourseError +) +from student.roles import CourseBetaTesterRole, CourseFinanceAdminRole, CourseInstructorRole, CourseSalesAdminRole +from student.tests.factories import AdminFactory, CourseModeFactory, UserFactory +from xmodule.modulestore import ModuleStoreEnum +from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase, SharedModuleStoreTestCase +from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory from .test_tools import msk_from_problem_urlname diff --git a/lms/djangoapps/instructor/tests/test_tools.py b/lms/djangoapps/instructor/tests/test_tools.py index da8fe04d48..727312bb5a 100644 --- a/lms/djangoapps/instructor/tests/test_tools.py +++ b/lms/djangoapps/instructor/tests/test_tools.py @@ -3,21 +3,20 @@ Tests for views/tools.py. """ import datetime -import mock import json import unittest -from django.utils.timezone import utc -from django.test.utils import override_settings -from nose.plugins.attrib import attr - +import mock from courseware.field_overrides import OverrideFieldData +from django.test.utils import override_settings +from django.utils.timezone import utc from lms.djangoapps.ccx.tests.test_overrides import inject_field_overrides +from nose.plugins.attrib import attr +from opaque_keys.edx.keys import CourseKey +from openedx.core.lib.xblock_fields.fields import Date from student.tests.factories import UserFactory -from xmodule.fields import Date from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase, SharedModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory -from opaque_keys.edx.keys import CourseKey from ..views import tools diff --git a/lms/djangoapps/instructor/views/tools.py b/lms/djangoapps/instructor/views/tools.py index 9d6daa511d..aac26841ce 100644 --- a/lms/djangoapps/instructor/views/tools.py +++ b/lms/djangoapps/instructor/views/tools.py @@ -1,23 +1,18 @@ """ Tools for the instructor dashboard """ -import dateutil import json +import dateutil +from courseware.field_overrides import disable_overrides +from courseware.models import StudentFieldOverride +from courseware.student_field_overrides import clear_override_for_user, get_override_for_user, override_field_for_user from django.contrib.auth.models import User from django.http import HttpResponseBadRequest from django.utils.timezone import utc from django.utils.translation import ugettext as _ - -from courseware.models import StudentFieldOverride -from courseware.field_overrides import disable_overrides -from courseware.student_field_overrides import ( - clear_override_for_user, - get_override_for_user, - override_field_for_user, -) -from xmodule.fields import Date from opaque_keys.edx.keys import UsageKey +from openedx.core.lib.xblock_fields.fields import Date DATE_FIELD = Date() diff --git a/lms/djangoapps/instructor_task/tasks_helper/grades.py b/lms/djangoapps/instructor_task/tasks_helper/grades.py index b2cdcc6961..fe0d508464 100644 --- a/lms/djangoapps/instructor_task/tasks_helper/grades.py +++ b/lms/djangoapps/instructor_task/tasks_helper/grades.py @@ -1,37 +1,36 @@ """ Functionality for generating grade reports. """ +import logging +import re from collections import OrderedDict from datetime import datetime -from itertools import chain, izip_longest, izip -from lazy import lazy -import logging -from pytz import UTC -import re +from itertools import chain, izip, izip_longest from time import time +from certificates.models import CertificateWhitelist, GeneratedCertificate, certificate_info_for_user +from courseware.courses import get_course_by_id from instructor_analytics.basic import list_problem_responses from instructor_analytics.csvs import format_dictlist -from certificates.models import CertificateWhitelist, certificate_info_for_user, GeneratedCertificate -from courseware.courses import get_course_by_id -from lms.djangoapps.grades.context import grading_context_for_course, grading_context -from lms.djangoapps.grades.new.course_grade_factory import CourseGradeFactory +from lazy import lazy +from lms.djangoapps.grades.context import grading_context, grading_context_for_course from lms.djangoapps.grades.models import PersistentCourseGrade +from lms.djangoapps.grades.new.course_grade_factory import CourseGradeFactory from lms.djangoapps.teams.models import CourseTeamMembership from lms.djangoapps.verify_student.models import SoftwareSecurePhotoVerification from openedx.core.djangoapps.content.block_structure.api import get_course_in_cache -from openedx.core.djangoapps.course_groups.cohorts import get_cohort, is_course_cohorted, bulk_cache_cohorts +from openedx.core.djangoapps.course_groups.cohorts import bulk_cache_cohorts, get_cohort, is_course_cohorted from openedx.core.djangoapps.user_api.course_tag.api import BulkCourseTags +from openedx.core.lib.partitions.partitions_service import PartitionService +from pytz import UTC from student.models import CourseEnrollment from student.roles import BulkRoleCache from xmodule.modulestore.django import modulestore -from xmodule.partitions.partitions_service import PartitionService from xmodule.split_test_module import get_split_user_partitions from .runner import TaskProgress from .utils import upload_csv_to_report_store - TASK_LOG = logging.getLogger('edx.celery.task') diff --git a/lms/djangoapps/instructor_task/tests/test_tasks_helper.py b/lms/djangoapps/instructor_task/tests/test_tasks_helper.py index 2f4d5fde7c..52404b5784 100644 --- a/lms/djangoapps/instructor_task/tests/test_tasks_helper.py +++ b/lms/djangoapps/instructor_task/tests/test_tasks_helper.py @@ -10,79 +10,73 @@ Unit tests for LMS instructor-initiated background tasks helper functions. import os import shutil -from datetime import datetime +import tempfile import urllib +from datetime import datetime +import ddt +import openedx.core.djangoapps.user_api.course_tag.api as course_tag_api +import unicodecsv +from capa.tests.response_xml_factory import MultipleChoiceResponseXMLFactory +from certificates.models import CertificateStatuses, GeneratedCertificate +from certificates.tests.factories import CertificateWhitelistFactory, GeneratedCertificateFactory +from course_modes.models import CourseMode +from courseware.tests.factories import InstructorFactory from django.conf import settings from django.core.urlresolvers import reverse from django.test.utils import override_settings -import ddt from freezegun import freeze_time -from mock import Mock, patch, MagicMock -from nose.plugins.attrib import attr -from pytz import UTC -import tempfile -import unicodecsv - -from capa.tests.response_xml_factory import MultipleChoiceResponseXMLFactory -from certificates.models import CertificateStatuses, GeneratedCertificate -from certificates.tests.factories import GeneratedCertificateFactory, CertificateWhitelistFactory -from course_modes.models import CourseMode -from courseware.tests.factories import InstructorFactory from instructor_analytics.basic import UNAVAILABLE from lms.djangoapps.grades.models import PersistentCourseGrade from lms.djangoapps.grades.transformer import GradesTransformer -from lms.djangoapps.teams.tests.factories import CourseTeamFactory, CourseTeamMembershipFactory -from lms.djangoapps.verify_student.tests.factories import SoftwareSecurePhotoVerificationFactory -from openedx.core.djangoapps.course_groups.models import CourseUserGroupPartitionGroup, CohortMembership -from openedx.core.djangoapps.course_groups.tests.helpers import CohortFactory -from openedx.core.djangoapps.credit.tests.factories import CreditCourseFactory -import openedx.core.djangoapps.user_api.course_tag.api as course_tag_api -from openedx.core.djangoapps.user_api.partition_schemes import RandomUserPartitionScheme -from openedx.core.djangoapps.util.testing import ContentGroupTestCase, TestConditionalContent -from request_cache.middleware import RequestCache -from shoppingcart.models import ( - Order, PaidCourseRegistration, CourseRegistrationCode, Invoice, - CourseRegistrationCodeInvoiceItem, InvoiceTransaction, Coupon -) -from student.models import CourseEnrollment, CourseEnrollmentAllowed, ManualEnrollmentAudit, ALLOWEDTOENROLL_TO_ENROLLED -from student.tests.factories import CourseEnrollmentFactory, CourseModeFactory, UserFactory -from survey.models import SurveyForm, SurveyAnswer -from xmodule.modulestore import ModuleStoreEnum -from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase -from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory, check_mongo_calls -from xmodule.partitions.partitions import Group, UserPartition - -from ..models import ReportStore -from lms.djangoapps.instructor_task.tasks_helper.certs import ( - generate_students_certificates, -) +from lms.djangoapps.instructor_task.tasks_helper.certs import generate_students_certificates from lms.djangoapps.instructor_task.tasks_helper.enrollments import ( upload_enrollment_report, - upload_may_enroll_csv, upload_exec_summary_report, - upload_students_csv, -) -from lms.djangoapps.instructor_task.tasks_helper.grades import ( - CourseGradeReport, - ProblemGradeReport, - ProblemResponses, + upload_may_enroll_csv, + upload_students_csv ) +from lms.djangoapps.instructor_task.tasks_helper.grades import CourseGradeReport, ProblemGradeReport, ProblemResponses from lms.djangoapps.instructor_task.tasks_helper.misc import ( cohort_students_and_upload, upload_course_survey_report, - upload_ora2_data, + upload_ora2_data ) -from ..tasks_helper.utils import ( - UPDATE_STATUS_FAILED, - UPDATE_STATUS_SUCCEEDED, -) - from lms.djangoapps.instructor_task.tests.test_base import ( InstructorTaskCourseTestCase, - TestReportMixin, - InstructorTaskModuleTestCase + InstructorTaskModuleTestCase, + TestReportMixin ) +from lms.djangoapps.teams.tests.factories import CourseTeamFactory, CourseTeamMembershipFactory +from lms.djangoapps.verify_student.tests.factories import SoftwareSecurePhotoVerificationFactory +from mock import MagicMock, Mock, patch +from nose.plugins.attrib import attr +from openedx.core.djangoapps.course_groups.models import CohortMembership, CourseUserGroupPartitionGroup +from openedx.core.djangoapps.course_groups.tests.helpers import CohortFactory +from openedx.core.djangoapps.credit.tests.factories import CreditCourseFactory +from openedx.core.djangoapps.user_api.partition_schemes import RandomUserPartitionScheme +from openedx.core.djangoapps.util.testing import ContentGroupTestCase, TestConditionalContent +from openedx.core.lib.partitions.partitions import Group, UserPartition +from pytz import UTC +from request_cache.middleware import RequestCache +from shoppingcart.models import ( + Coupon, + CourseRegistrationCode, + CourseRegistrationCodeInvoiceItem, + Invoice, + InvoiceTransaction, + Order, + PaidCourseRegistration +) +from student.models import ALLOWEDTOENROLL_TO_ENROLLED, CourseEnrollment, CourseEnrollmentAllowed, ManualEnrollmentAudit +from student.tests.factories import CourseEnrollmentFactory, CourseModeFactory, UserFactory +from survey.models import SurveyAnswer, SurveyForm +from xmodule.modulestore import ModuleStoreEnum +from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase +from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory, check_mongo_calls + +from ..models import ReportStore +from ..tasks_helper.utils import UPDATE_STATUS_FAILED, UPDATE_STATUS_SUCCEEDED class InstructorGradeReportTestCase(TestReportMixin, InstructorTaskCourseTestCase): diff --git a/lms/djangoapps/lms_xblock/mixin.py b/lms/djangoapps/lms_xblock/mixin.py index 7bf2ed4f7a..dae6543e43 100644 --- a/lms/djangoapps/lms_xblock/mixin.py +++ b/lms/djangoapps/lms_xblock/mixin.py @@ -4,12 +4,11 @@ Namespace that defines fields common to all blocks used in the LMS #from django.utils.translation import ugettext_noop as _ from lazy import lazy - +from openedx.core.lib.partitions.partitions import NoSuchUserPartitionError, NoSuchUserPartitionGroupError +from openedx.core.lib.xblock_fields.inherited_fields import UserPartitionList from xblock.core import XBlock -from xblock.fields import Boolean, Scope, String, XBlockMixin, Dict +from xblock.fields import Boolean, Dict, Scope, String, XBlockMixin from xblock.validation import ValidationMessage -from xmodule.modulestore.inheritance import UserPartitionList -from xmodule.partitions.partitions import NoSuchUserPartitionError, NoSuchUserPartitionGroupError # Please do not remove, this is a workaround for Django 1.8. # more information can be found here: https://openedx.atlassian.net/browse/PLAT-902 diff --git a/lms/djangoapps/lms_xblock/runtime.py b/lms/djangoapps/lms_xblock/runtime.py index 58bf0f1f96..0a8434ea7b 100644 --- a/lms/djangoapps/lms_xblock/runtime.py +++ b/lms/djangoapps/lms_xblock/runtime.py @@ -1,24 +1,22 @@ """ Module implementing `xblock.runtime.Runtime` functionality for the LMS """ -from django.conf import settings -from django.core.urlresolvers import reverse - +import xblock.reference.plugins from badges.service import BadgingService from badges.utils import badges_enabled +from django.conf import settings +from django.core.urlresolvers import reverse +from lms.djangoapps.lms_xblock.models import XBlockAsidesConfig from openedx.core.djangoapps.user_api.course_tag import api as user_course_tag_api -from openedx.core.lib.xblock_utils import xblock_local_resource_url +from openedx.core.lib.partitions.partitions_service import PartitionService from openedx.core.lib.url_utils import quote_slashes +from openedx.core.lib.xblock_utils import xblock_local_resource_url from request_cache.middleware import RequestCache -import xblock.reference.plugins from xmodule.library_tools import LibraryToolsService -from xmodule.modulestore.django import modulestore, ModuleI18nService -from xmodule.partitions.partitions_service import PartitionService +from xmodule.modulestore.django import ModuleI18nService, modulestore from xmodule.services import SettingsService from xmodule.x_module import ModuleSystem -from lms.djangoapps.lms_xblock.models import XBlockAsidesConfig - def handler_url(block, handler_name, suffix='', query='', thirdparty=False): """ diff --git a/lms/djangoapps/mobile_api/users/tests.py b/lms/djangoapps/mobile_api/users/tests.py index 2cb0e64263..c57ea6ccd8 100644 --- a/lms/djangoapps/mobile_api/users/tests.py +++ b/lms/djangoapps/mobile_api/users/tests.py @@ -13,7 +13,6 @@ from django.utils import timezone from django.template import defaultfilters from django.test import RequestFactory, override_settings from milestones.tests.utils import MilestonesTestCaseMixin -from xmodule.course_module import DEFAULT_START_DATE from xmodule.modulestore.tests.factories import ItemFactory, CourseFactory from certificates.api import generate_user_certificates @@ -27,6 +26,7 @@ from courseware.access_response import ( from course_modes.models import CourseMode from lms.djangoapps.grades.tests.utils import mock_passing_grade from openedx.core.lib.courses import course_image_url +from openedx.core.lib.xblock_fields.inherited_fields import DEFAULT_START_DATE from student.models import CourseEnrollment from util.milestones_helpers import set_prerequisite_courses from util.testing import UrlResetMixin diff --git a/lms/djangoapps/mobile_api/video_outlines/tests.py b/lms/djangoapps/mobile_api/video_outlines/tests.py index 877bb87b7c..1f4ba04415 100644 --- a/lms/djangoapps/mobile_api/video_outlines/tests.py +++ b/lms/djangoapps/mobile_api/video_outlines/tests.py @@ -4,23 +4,22 @@ Tests for video outline API """ import itertools -from uuid import uuid4 from collections import namedtuple +from uuid import uuid4 import ddt -from nose.plugins.attrib import attr from edxval import api +from milestones.tests.utils import MilestonesTestCaseMixin +from mobile_api.models import MobileApiConfig +from mobile_api.testutils import MobileAPITestCase, MobileAuthTestMixin, MobileCourseAccessTestMixin +from nose.plugins.attrib import attr +from openedx.core.djangoapps.course_groups.cohorts import add_user_to_cohort, remove_user_from_cohort +from openedx.core.djangoapps.course_groups.models import CourseUserGroupPartitionGroup +from openedx.core.djangoapps.course_groups.tests.helpers import CohortFactory +from openedx.core.lib.partitions.partitions import Group, UserPartition +from xmodule.modulestore.django import modulestore from xmodule.modulestore.tests.factories import ItemFactory from xmodule.video_module import transcripts_utils -from xmodule.modulestore.django import modulestore -from xmodule.partitions.partitions import Group, UserPartition -from milestones.tests.utils import MilestonesTestCaseMixin - -from mobile_api.models import MobileApiConfig -from openedx.core.djangoapps.course_groups.tests.helpers import CohortFactory -from openedx.core.djangoapps.course_groups.models import CourseUserGroupPartitionGroup -from openedx.core.djangoapps.course_groups.cohorts import add_user_to_cohort, remove_user_from_cohort -from mobile_api.testutils import MobileAPITestCase, MobileAuthTestMixin, MobileCourseAccessTestMixin class TestVideoAPITestCase(MobileAPITestCase): diff --git a/lms/envs/common.py b/lms/envs/common.py index 65074ec198..543271b61b 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -730,7 +730,7 @@ VIRTUAL_UNIVERSITIES = [] ############# XBlock Configuration ########## # Import after sys.path fixup -from xmodule.modulestore.inheritance import InheritanceMixin +from openedx.core.lib.xblock_fields.inherited_fields import InheritanceMixin from xmodule.modulestore import prefer_xmodules from xmodule.x_module import XModuleMixin diff --git a/lms/lib/xblock/test/test_mixin.py b/lms/lib/xblock/test/test_mixin.py index f6cd9d68e9..60d0e8b5e1 100644 --- a/lms/lib/xblock/test/test_mixin.py +++ b/lms/lib/xblock/test/test_mixin.py @@ -2,14 +2,13 @@ Tests of the LMS XBlock Mixin """ import ddt +from lms_xblock.mixin import INVALID_USER_PARTITION_GROUP_VALIDATION, INVALID_USER_PARTITION_VALIDATION from nose.plugins.attrib import attr - -from lms_xblock.mixin import INVALID_USER_PARTITION_VALIDATION, INVALID_USER_PARTITION_GROUP_VALIDATION +from openedx.core.lib.partitions.partitions import Group, UserPartition from xblock.validation import ValidationMessage from xmodule.modulestore import ModuleStoreEnum -from xmodule.modulestore.tests.factories import CourseFactory, ToyCourseFactory, ItemFactory -from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase, TEST_DATA_MIXED_MODULESTORE -from xmodule.partitions.partitions import Group, UserPartition +from xmodule.modulestore.tests.django_utils import TEST_DATA_MIXED_MODULESTORE, ModuleStoreTestCase +from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory, ToyCourseFactory class LmsXBlockMixinTestCase(ModuleStoreTestCase): diff --git a/lms/templates/preview_menu.html b/lms/templates/preview_menu.html index d5de16c7b7..297de68630 100644 --- a/lms/templates/preview_menu.html +++ b/lms/templates/preview_menu.html @@ -7,7 +7,7 @@ from django.utils.translation import ugettext as _ from django.conf import settings from openedx.core.djangolib.js_utils import dump_js_escaped_json from openedx.core.djangolib.markup import HTML, Text -from xmodule.partitions.partitions_service import get_all_partitions_for_course +from openedx.core.lib.partitions.partitions_service import get_all_partitions_for_course %> <% diff --git a/openedx/core/djangoapps/content/course_overviews/models.py b/openedx/core/djangoapps/content/course_overviews/models.py index 20330043ac..f61d994f3b 100644 --- a/openedx/core/djangoapps/content/course_overviews/models.py +++ b/openedx/core/djangoapps/content/course_overviews/models.py @@ -20,10 +20,11 @@ from lms.djangoapps import django_comment_client from openedx.core.djangoapps.models.course_details import CourseDetails from static_replace.models import AssetBaseUrlConfig from xmodule import course_metadata_utils, block_metadata_utils -from xmodule.course_module import CourseDescriptor, DEFAULT_START_DATE +from xmodule.course_module import CourseDescriptor from xmodule.error_module import ErrorDescriptor from xmodule.modulestore.django import modulestore from openedx.core.djangoapps.xmodule_django.models import CourseKeyField, UsageKeyField +from openedx.core.lib.xblock_fields.inherited_fields import DEFAULT_START_DATE log = logging.getLogger(__name__) diff --git a/openedx/core/djangoapps/content/course_overviews/tests.py b/openedx/core/djangoapps/content/course_overviews/tests.py index 103db6d140..741951ad6d 100644 --- a/openedx/core/djangoapps/content/course_overviews/tests.py +++ b/openedx/core/djangoapps/content/course_overviews/tests.py @@ -19,11 +19,11 @@ from PIL import Image from lms.djangoapps.certificates.api import get_active_web_certificate from openedx.core.djangoapps.models.course_details import CourseDetails from openedx.core.lib.courses import course_image_url +from openedx.core.lib.xblock_fields.inherited_fields import DEFAULT_START_DATE from static_replace.models import AssetBaseUrlConfig from xmodule.assetstore.assetmgr import AssetManager from xmodule.contentstore.django import contentstore from xmodule.contentstore.content import StaticContent -from xmodule.course_metadata_utils import DEFAULT_START_DATE from xmodule.course_module import ( CATALOG_VISIBILITY_CATALOG_AND_ABOUT, CATALOG_VISIBILITY_ABOUT, diff --git a/openedx/core/djangoapps/course_groups/partition_scheme.py b/openedx/core/djangoapps/course_groups/partition_scheme.py index e47981a5f0..4a5b37bba1 100644 --- a/openedx/core/djangoapps/course_groups/partition_scheme.py +++ b/openedx/core/djangoapps/course_groups/partition_scheme.py @@ -8,11 +8,10 @@ from courseware.masquerade import ( # pylint: disable=import-error get_masquerading_user_group, is_masquerading_as_specific_student ) -from xmodule.partitions.partitions import NoSuchUserPartitionGroupError +from openedx.core.lib.partitions.partitions import NoSuchUserPartitionGroupError from .cohorts import get_cohort, get_group_info_for_cohort - log = logging.getLogger(__name__) diff --git a/openedx/core/djangoapps/course_groups/tests/test_partition_scheme.py b/openedx/core/djangoapps/course_groups/tests/test_partition_scheme.py index 1e28ad2afd..eb0b99932b 100644 --- a/openedx/core/djangoapps/course_groups/tests/test_partition_scheme.py +++ b/openedx/core/djangoapps/course_groups/tests/test_partition_scheme.py @@ -3,22 +3,21 @@ Test the partitions and partitions service """ import django.test +from courseware.tests.test_masquerade import StaffMasqueradeTestCase from mock import patch from nose.plugins.attrib import attr - -from courseware.tests.test_masquerade import StaffMasqueradeTestCase -from student.tests.factories import UserFactory -from xmodule.partitions.partitions import Group, UserPartition, UserPartitionError -from xmodule.modulestore.django import modulestore -from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase, TEST_DATA_MIXED_MODULESTORE -from xmodule.modulestore.tests.factories import ToyCourseFactory - from openedx.core.djangoapps.user_api.partition_schemes import RandomUserPartitionScheme from openedx.core.djangolib.testing.utils import skip_unless_lms -from ..partition_scheme import CohortPartitionScheme, get_cohorted_user_partition +from openedx.core.lib.partitions.partitions import Group, UserPartition, UserPartitionError +from student.tests.factories import UserFactory +from xmodule.modulestore.django import modulestore +from xmodule.modulestore.tests.django_utils import TEST_DATA_MIXED_MODULESTORE, ModuleStoreTestCase +from xmodule.modulestore.tests.factories import ToyCourseFactory + +from ..cohorts import add_user_to_cohort, get_course_cohorts, remove_user_from_cohort from ..models import CourseUserGroupPartitionGroup +from ..partition_scheme import CohortPartitionScheme, get_cohorted_user_partition from ..views import link_cohort_to_partition_group, unlink_cohort_partition_group -from ..cohorts import add_user_to_cohort, remove_user_from_cohort, get_course_cohorts from .helpers import CohortFactory, config_course_cohorts diff --git a/openedx/core/djangoapps/models/course_details.py b/openedx/core/djangoapps/models/course_details.py index 6f0a2de250..4fb3d7c917 100644 --- a/openedx/core/djangoapps/models/course_details.py +++ b/openedx/core/djangoapps/models/course_details.py @@ -1,17 +1,15 @@ """ CourseDetails """ -import re import logging +import re from django.conf import settings - -from xmodule.fields import Date -from xmodule.modulestore.exceptions import ItemNotFoundError from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration from openedx.core.lib.courses import course_image_url +from openedx.core.lib.xblock_fields.fields import Date from xmodule.modulestore.django import modulestore - +from xmodule.modulestore.exceptions import ItemNotFoundError # This list represents the attribute keys for a course's 'about' info. # Note: The 'video' attribute is intentionally excluded as it must be diff --git a/openedx/core/djangoapps/user_api/partition_schemes.py b/openedx/core/djangoapps/user_api/partition_schemes.py index 070acbd0cc..85ba29fa1c 100644 --- a/openedx/core/djangoapps/user_api/partition_schemes.py +++ b/openedx/core/djangoapps/user_api/partition_schemes.py @@ -3,9 +3,9 @@ Provides partition support to the user service. """ import logging import random -import course_tag.api as course_tag_api -from xmodule.partitions.partitions import UserPartitionError, NoSuchUserPartitionGroupError +import course_tag.api as course_tag_api +from openedx.core.lib.partitions.partitions import NoSuchUserPartitionGroupError, UserPartitionError log = logging.getLogger(__name__) diff --git a/openedx/core/djangoapps/user_api/tests/test_partition_schemes.py b/openedx/core/djangoapps/user_api/tests/test_partition_schemes.py index d12bc3f8c6..396fc7e605 100644 --- a/openedx/core/djangoapps/user_api/tests/test_partition_schemes.py +++ b/openedx/core/djangoapps/user_api/tests/test_partition_schemes.py @@ -2,13 +2,13 @@ Test the user api's partition extensions. """ from collections import defaultdict -from mock import patch from unittest import TestCase +from mock import patch from openedx.core.djangoapps.user_api.partition_schemes import RandomUserPartitionScheme, UserPartitionError +from openedx.core.lib.partitions.partitions import Group, UserPartition +from openedx.core.lib.partitions.tests.test_partitions import PartitionTestCase from student.tests.factories import UserFactory -from xmodule.partitions.partitions import Group, UserPartition -from xmodule.partitions.tests.test_partitions import PartitionTestCase class MemoryCourseTagAPI(object): diff --git a/openedx/core/djangoapps/util/testing.py b/openedx/core/djangoapps/util/testing.py index 380c8cdfcf..4cde8eccae 100644 --- a/openedx/core/djangoapps/util/testing.py +++ b/openedx/core/djangoapps/util/testing.py @@ -1,15 +1,15 @@ """ Mixins for setting up particular course structures (such as split tests or cohorted content) """ from datetime import datetime -from pytz import UTC from openedx.core.djangoapps.course_groups.models import CourseUserGroupPartitionGroup from openedx.core.djangoapps.course_groups.tests.helpers import CohortFactory from openedx.core.djangoapps.user_api.tests.factories import UserCourseTagFactory -from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory -from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase -from xmodule.partitions.partitions import UserPartition, Group +from openedx.core.lib.partitions.partitions import Group, UserPartition +from pytz import UTC from student.tests.factories import CourseEnrollmentFactory, UserFactory +from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase +from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory class ContentGroupTestCase(ModuleStoreTestCase): diff --git a/openedx/core/djangoapps/verified_track_content/partition_scheme.py b/openedx/core/djangoapps/verified_track_content/partition_scheme.py index 2260265b12..b11b22d12c 100644 --- a/openedx/core/djangoapps/verified_track_content/partition_scheme.py +++ b/openedx/core/djangoapps/verified_track_content/partition_scheme.py @@ -1,19 +1,17 @@ """ UserPartitionScheme for enrollment tracks. """ -from django.conf import settings - +from course_modes.models import CourseMode from courseware.masquerade import ( get_course_masquerade, get_masquerading_user_group, is_masquerading_as_specific_student ) -from course_modes.models import CourseMode -from student.models import CourseEnrollment +from django.conf import settings from opaque_keys.edx.keys import CourseKey from openedx.core.djangoapps.verified_track_content.models import VerifiedTrackCohortedCourse -from xmodule.partitions.partitions import NoSuchUserPartitionGroupError, Group, UserPartition - +from openedx.core.lib.partitions.partitions import Group, NoSuchUserPartitionGroupError, UserPartition +from student.models import CourseEnrollment # These IDs must be less than 100 so that they do not overlap with Groups in # CohortUserPartition or RandomUserPartitionScheme diff --git a/openedx/core/djangoapps/verified_track_content/tests/test_partition_scheme.py b/openedx/core/djangoapps/verified_track_content/tests/test_partition_scheme.py index 0e007e2697..66e47448c9 100644 --- a/openedx/core/djangoapps/verified_track_content/tests/test_partition_scheme.py +++ b/openedx/core/djangoapps/verified_track_content/tests/test_partition_scheme.py @@ -2,17 +2,17 @@ Tests for verified_track_content/partition_scheme.py. """ from datetime import datetime, timedelta + import pytz - -from ..partition_scheme import EnrollmentTrackPartitionScheme, EnrollmentTrackUserPartition, ENROLLMENT_GROUP_IDS -from ..models import VerifiedTrackCohortedCourse from course_modes.models import CourseMode - +from openedx.core.lib.partitions.partitions import MINIMUM_STATIC_PARTITION_ID, UserPartition from student.models import CourseEnrollment from student.tests.factories import UserFactory from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory -from xmodule.partitions.partitions import UserPartition, MINIMUM_STATIC_PARTITION_ID + +from ..models import VerifiedTrackCohortedCourse +from ..partition_scheme import ENROLLMENT_GROUP_IDS, EnrollmentTrackPartitionScheme, EnrollmentTrackUserPartition class EnrollmentTrackUserPartitionTest(SharedModuleStoreTestCase): diff --git a/common/lib/xmodule/xmodule/partitions/__init__.py b/openedx/core/lib/partitions/__init__.py similarity index 100% rename from common/lib/xmodule/xmodule/partitions/__init__.py rename to openedx/core/lib/partitions/__init__.py diff --git a/common/lib/xmodule/xmodule/partitions/partitions.py b/openedx/core/lib/partitions/partitions.py similarity index 100% rename from common/lib/xmodule/xmodule/partitions/partitions.py rename to openedx/core/lib/partitions/partitions.py diff --git a/common/lib/xmodule/xmodule/partitions/partitions_service.py b/openedx/core/lib/partitions/partitions_service.py similarity index 98% rename from common/lib/xmodule/xmodule/partitions/partitions_service.py rename to openedx/core/lib/partitions/partitions_service.py index 39c8dbe930..de5d5b7ab1 100644 --- a/common/lib/xmodule/xmodule/partitions/partitions_service.py +++ b/openedx/core/lib/partitions/partitions_service.py @@ -7,7 +7,7 @@ from django.conf import settings from django.utils.translation import ugettext_lazy as _ import logging -from xmodule.partitions.partitions import UserPartition, UserPartitionError, ENROLLMENT_TRACK_PARTITION_ID +from .partitions import UserPartition, UserPartitionError, ENROLLMENT_TRACK_PARTITION_ID from xmodule.modulestore.django import modulestore diff --git a/common/lib/xmodule/xmodule/partitions/tests/__init__.py b/openedx/core/lib/partitions/tests/__init__.py similarity index 100% rename from common/lib/xmodule/xmodule/partitions/tests/__init__.py rename to openedx/core/lib/partitions/tests/__init__.py diff --git a/common/lib/xmodule/xmodule/partitions/tests/test_partitions.py b/openedx/core/lib/partitions/tests/test_partitions.py similarity index 99% rename from common/lib/xmodule/xmodule/partitions/tests/test_partitions.py rename to openedx/core/lib/partitions/tests/test_partitions.py index 3b37bbb4d8..2d3aaf1ee1 100644 --- a/common/lib/xmodule/xmodule/partitions/tests/test_partitions.py +++ b/openedx/core/lib/partitions/tests/test_partitions.py @@ -8,11 +8,11 @@ from mock import Mock from opaque_keys.edx.locator import CourseLocator from stevedore.extension import Extension, ExtensionManager -from xmodule.partitions.partitions import ( +from openedx.core.lib.partitions.partitions import ( Group, UserPartition, UserPartitionError, NoSuchUserPartitionGroupError, USER_PARTITION_SCHEME_NAMESPACE, ENROLLMENT_TRACK_PARTITION_ID ) -from xmodule.partitions.partitions_service import ( +from openedx.core.lib.partitions.partitions_service import ( PartitionService, get_all_partitions_for_course, FEATURES ) diff --git a/openedx/core/lib/xblock_fields/__init__.py b/openedx/core/lib/xblock_fields/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/common/lib/xmodule/xmodule/fields.py b/openedx/core/lib/xblock_fields/fields.py similarity index 86% rename from common/lib/xmodule/xmodule/fields.py rename to openedx/core/lib/xblock_fields/fields.py index 2b73d5b63f..fe27225a16 100644 --- a/common/lib/xmodule/xmodule/fields.py +++ b/openedx/core/lib/xblock_fields/fields.py @@ -253,3 +253,38 @@ class RelativeTime(JSONField): return value return self.from_json(value) + + +class TimeInfo(object): + """ + This is a simple object that calculates and stores datetime information for an XModule + based on the due date and the grace period string + + So far it parses out three different pieces of time information: + self.display_due_date - the 'official' due date that gets displayed to students + self.grace_period - the length of the grace period + self.close_date - the real due date + + """ + _delta_standin = Timedelta() + + def __init__(self, due_date, grace_period_string_or_timedelta): + if due_date is not None: + self.display_due_date = due_date + + else: + self.display_due_date = None + + if grace_period_string_or_timedelta is not None and self.display_due_date: + if isinstance(grace_period_string_or_timedelta, basestring): + try: + self.grace_period = TimeInfo._delta_standin.from_json(grace_period_string_or_timedelta) + except: + log.error("Error parsing the grace period {0}".format(grace_period_string_or_timedelta)) + raise + else: + self.grace_period = grace_period_string_or_timedelta + self.close_date = self.display_due_date + self.grace_period + else: + self.grace_period = None + self.close_date = self.display_due_date diff --git a/openedx/core/lib/xblock_fields/inherited_fields.py b/openedx/core/lib/xblock_fields/inherited_fields.py new file mode 100644 index 0000000000..4bde53364b --- /dev/null +++ b/openedx/core/lib/xblock_fields/inherited_fields.py @@ -0,0 +1,239 @@ +""" +Inherited fields for all XBlocks. +""" +from __future__ import absolute_import + +from datetime import datetime + +from django.conf import settings +from openedx.core.lib.partitions.partitions import UserPartition +from pytz import utc +from xblock.fields import Boolean, Dict, Float, Integer, List, Scope, String, XBlockMixin + +from .fields import Date, Timedelta + +DEFAULT_START_DATE = datetime(2030, 1, 1, tzinfo=utc) + +# Make '_' a no-op so we can scrape strings +# Using lambda instead of `django.utils.translation.ugettext_noop` because Django cannot be imported in this file +_ = lambda text: text + + +class UserPartitionList(List): + """Special List class for listing UserPartitions""" + def from_json(self, values): + return [UserPartition.from_json(v) for v in values] + + def to_json(self, values): + return [user_partition.to_json() + for user_partition in values] + + +class InheritanceMixin(XBlockMixin): + """Field definitions for inheritable fields.""" + + graded = Boolean( + help="Whether this module contributes to the final course grade", + scope=Scope.settings, + default=False, + ) + start = Date( + help="Start time when this module is visible", + default=DEFAULT_START_DATE, + scope=Scope.settings + ) + due = Date( + display_name=_("Due Date"), + help=_("Enter the default date by which problems are due."), + scope=Scope.settings, + ) + visible_to_staff_only = Boolean( + help=_("If true, can be seen only by course staff, regardless of start date."), + default=False, + scope=Scope.settings, + ) + course_edit_method = String( + display_name=_("Course Editor"), + help=_("Enter the method by which this course is edited (\"XML\" or \"Studio\")."), + default="Studio", + scope=Scope.settings, + deprecated=True # Deprecated because user would not change away from Studio within Studio. + ) + giturl = String( + display_name=_("GIT URL"), + help=_("Enter the URL for the course data GIT repository."), + scope=Scope.settings + ) + xqa_key = String( + display_name=_("XQA Key"), + help=_("This setting is not currently supported."), scope=Scope.settings, + deprecated=True + ) + annotation_storage_url = String( + help=_("Enter the location of the annotation storage server. The textannotation, videoannotation, and imageannotation advanced modules require this setting."), + scope=Scope.settings, + default="http://your_annotation_storage.com", + display_name=_("URL for Annotation Storage") + ) + annotation_token_secret = String( + help=_("Enter the secret string for annotation storage. The textannotation, videoannotation, and imageannotation advanced modules require this string."), + scope=Scope.settings, + default="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + display_name=_("Secret Token String for Annotation") + ) + graceperiod = Timedelta( + help="Amount of time after the due date that submissions will be accepted", + scope=Scope.settings, + ) + group_access = Dict( + help=_("Enter the ids for the content groups this problem belongs to."), + scope=Scope.settings, + ) + + showanswer = String( + display_name=_("Show Answer"), + help=_( + # Translators: DO NOT translate the words in quotes here, they are + # specific words for the acceptable values. + 'Specify when the Show Answer button appears for each problem. ' + 'Valid values are "always", "answered", "attempted", "closed", ' + '"finished", "past_due", "correct_or_past_due", and "never".' + ), + scope=Scope.settings, + default="finished", + ) + + show_correctness = String( + display_name=_("Show Results"), + help=_( + # Translators: DO NOT translate the words in quotes here, they are + # specific words for the acceptable values. + 'Specify when to show answer correctness and score to learners. ' + 'Valid values are "always", "never", and "past_due".' + ), + scope=Scope.settings, + default="always", + ) + + rerandomize = String( + display_name=_("Randomization"), + help=_( + # Translators: DO NOT translate the words in quotes here, they are + # specific words for the acceptable values. + 'Specify the default for how often variable values in a problem are randomized. ' + 'This setting should be set to "never" unless you plan to provide a Python ' + 'script to identify and randomize values in most of the problems in your course. ' + 'Valid values are "always", "onreset", "never", and "per_student".' + ), + scope=Scope.settings, + default="never", + ) + days_early_for_beta = Float( + display_name=_("Days Early for Beta Users"), + help=_("Enter the number of days before the start date that beta users can access the course."), + scope=Scope.settings, + default=None, + ) + static_asset_path = String( + display_name=_("Static Asset Path"), + help=_("Enter the path to use for files on the Files & Uploads page. This value overrides the Studio default, c4x://."), + scope=Scope.settings, + default='', + ) + use_latex_compiler = Boolean( + display_name=_("Enable LaTeX Compiler"), + help=_("Enter true or false. If true, you can use the LaTeX templates for HTML components and advanced Problem components."), + default=False, + scope=Scope.settings + ) + max_attempts = Integer( + display_name=_("Maximum Attempts"), + help=_("Enter the maximum number of times a student can try to answer problems. By default, Maximum Attempts is set to null, meaning that students have an unlimited number of attempts for problems. You can override this course-wide setting for individual problems. However, if the course-wide setting is a specific number, you cannot set the Maximum Attempts for individual problems to unlimited."), + values={"min": 0}, scope=Scope.settings + ) + matlab_api_key = String( + display_name=_("Matlab API key"), + help=_("Enter the API key provided by MathWorks for accessing the MATLAB Hosted Service. " + "This key is granted for exclusive use in this course for the specified duration. " + "Do not share the API key with other courses. Notify MathWorks immediately " + "if you believe the key is exposed or compromised. To obtain a key for your course, " + "or to report an issue, please contact moocsupport@mathworks.com"), + scope=Scope.settings + ) + # This is should be scoped to content, but since it's defined in the policy + # file, it is currently scoped to settings. + user_partitions = UserPartitionList( + display_name=_("Group Configurations"), + help=_("Enter the configurations that govern how students are grouped together."), + default=[], + scope=Scope.settings + ) + video_speed_optimizations = Boolean( + display_name=_("Enable video caching system"), + help=_("Enter true or false. If true, video caching will be used for HTML5 videos."), + default=True, + scope=Scope.settings + ) + video_bumper = Dict( + display_name=_("Video Pre-Roll"), + help=_( + "Identify a video, 5-10 seconds in length, to play before course videos. Enter the video ID from " + "the Video Uploads page and one or more transcript files in the following format: {format}. " + "For example, an entry for a video with two transcripts looks like this: {example}" + ).format( + format='{"video_id": "ID", "transcripts": {"language": "/static/filename.srt"}}', + example=( + '{' + '"video_id": "77cef264-d6f5-4cf2-ad9d-0178ab8c77be", ' + '"transcripts": {"en": "/static/DemoX-D01_1.srt", "uk": "/static/DemoX-D01_1_uk.srt"}' + '}' + ), + ), + scope=Scope.settings + ) + + # TODO: Remove this Django dependency! It really doesn't belong here. + reset_key = "DEFAULT_SHOW_RESET_BUTTON" + default_reset_button = getattr(settings, reset_key) if hasattr(settings, reset_key) else False + show_reset_button = Boolean( + display_name=_("Show Reset Button for Problems"), + help=_( + "Enter true or false. If true, problems in the course default to always displaying a 'Reset' button. " + "You can override this in each problem's settings. All existing problems are affected when " + "this course-wide setting is changed." + ), + scope=Scope.settings, + default=default_reset_button + ) + edxnotes = Boolean( + display_name=_("Enable Student Notes"), + help=_("Enter true or false. If true, students can use the Student Notes feature."), + default=False, + scope=Scope.settings + ) + edxnotes_visibility = Boolean( + display_name="Student Notes Visibility", + help=_("Indicates whether Student Notes are visible in the course. " + "Students can also show or hide their notes in the courseware."), + default=True, + scope=Scope.user_info + ) + + in_entrance_exam = Boolean( + display_name=_("Tag this module as part of an Entrance Exam section"), + help=_("Enter true or false. If true, answer submissions for problem modules will be " + "considered in the Entrance Exam scoring/gating algorithm."), + scope=Scope.settings, + default=False + ) + + self_paced = Boolean( + display_name=_('Self Paced'), + help=_( + 'Set this to "true" to mark this course as self-paced. Self-paced courses do not have ' + 'due dates for assignments, and students can progress through the course at any rate before ' + 'the course ends.' + ), + default=False, + scope=Scope.settings + ) 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 8e518bb621..bd9a2c9528 100644 --- a/openedx/features/course_experience/tests/views/test_course_outline.py +++ b/openedx/features/course_experience/tests/views/test_course_outline.py @@ -16,7 +16,7 @@ from student.tests.factories import UserFactory from xmodule.modulestore import ModuleStoreEnum from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory -from xmodule.course_module import DEFAULT_START_DATE +from openedx.core.lib.xblock_fields.inherited_fields import DEFAULT_START_DATE from .test_course_home import course_home_url