diff --git a/cms/djangoapps/contentstore/tests/test_course_settings.py b/cms/djangoapps/contentstore/tests/test_course_settings.py index b826afc652..a8d1dc765d 100644 --- a/cms/djangoapps/contentstore/tests/test_course_settings.py +++ b/cms/djangoapps/contentstore/tests/test_course_settings.py @@ -20,7 +20,6 @@ from models.settings.course_grading import CourseGradingModel, GRADING_POLICY_CH from models.settings.course_metadata import CourseMetadata from models.settings.encoder import CourseSettingsEncoder from openedx.core.djangoapps.models.course_details import CourseDetails -from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration from student.roles import CourseInstructorRole, CourseStaffRole from student.tests.factories import UserFactory from util import milestones_helpers @@ -113,7 +112,6 @@ class CourseDetailsViewTest(CourseTestCase, MilestonesTestCaseMixin): return Date().to_json(datetime_obj) def test_update_and_fetch(self): - SelfPacedConfiguration(enabled=True).save() details = CourseDetails.fetch(self.course.id) # resp s/b json from here on @@ -297,7 +295,9 @@ class CourseDetailsViewTest(CourseTestCase, MilestonesTestCaseMixin): 'short_description': 'empty', 'overview': '', 'effort': '', - 'intro_video': '' + 'intro_video': '', + 'start_date': '2012-01-01', + 'end_date': '2012-12-31', } response = self.client.post(settings_details_url, data=json.dumps(data), content_type='application/json', HTTP_ACCEPT='application/json') @@ -352,7 +352,9 @@ class CourseDetailsViewTest(CourseTestCase, MilestonesTestCaseMixin): 'short_description': 'empty', 'overview': '', 'effort': '', - 'intro_video': '' + 'intro_video': '', + 'start_date': '2012-01-01', + 'end_date': '2012-12-31', } response = self.client.post( settings_details_url, @@ -375,7 +377,9 @@ class CourseDetailsViewTest(CourseTestCase, MilestonesTestCaseMixin): 'short_description': 'empty', 'overview': '', 'effort': '', - 'intro_video': '' + 'intro_video': '', + 'start_date': '2012-01-01', + 'end_date': '2012-12-31', } response = self.client.post( diff --git a/cms/djangoapps/contentstore/utils.py b/cms/djangoapps/contentstore/utils.py index d13768929a..70451ff0b4 100644 --- a/cms/djangoapps/contentstore/utils.py +++ b/cms/djangoapps/contentstore/utils.py @@ -14,7 +14,6 @@ from six import text_type from django_comment_common.models import assign_default_role from django_comment_common.utils import seed_permissions_roles -from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration from openedx.core.djangoapps.site_configuration.models import SiteConfiguration from student import auth from student.models import CourseEnrollment @@ -509,4 +508,4 @@ def is_self_paced(course): """ Returns True if course is self-paced, False otherwise. """ - return course and course.self_paced and SelfPacedConfiguration.current().enabled + return course and course.self_paced diff --git a/cms/djangoapps/contentstore/views/course.py b/cms/djangoapps/contentstore/views/course.py index c960e7486a..d8a45c0fa9 100644 --- a/cms/djangoapps/contentstore/views/course.py +++ b/cms/djangoapps/contentstore/views/course.py @@ -60,7 +60,6 @@ from openedx.core.djangoapps.content.course_structures.api.v0 import api, errors from openedx.core.djangoapps.credit.api import get_credit_requirements, is_credit_course from openedx.core.djangoapps.credit.tasks import update_credit_course_requirements from openedx.core.djangoapps.models.course_details import CourseDetails -from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers from openedx.core.djangolib.js_utils import dump_js_escaped_json from openedx.core.lib.course_tabs import CourseTabPluginManager @@ -1045,7 +1044,7 @@ def settings_handler(request, course_key_string): 'EDITABLE_SHORT_DESCRIPTION', settings.FEATURES.get('EDITABLE_SHORT_DESCRIPTION', True) ) - self_paced_enabled = SelfPacedConfiguration.current().enabled + # self_paced_enabled = SelfPacedConfiguration.current().enabled settings_context = { 'context_course': course_module, @@ -1066,7 +1065,6 @@ def settings_handler(request, course_key_string): 'enrollment_end_editable': enrollment_end_editable, 'is_prerequisite_courses_enabled': is_prerequisite_courses_enabled(), 'is_entrance_exams_enabled': is_entrance_exams_enabled(), - 'self_paced_enabled': self_paced_enabled, 'enable_extended_course_details': enable_extended_course_details } if is_prerequisite_courses_enabled(): diff --git a/cms/djangoapps/contentstore/views/tests/test_item.py b/cms/djangoapps/contentstore/views/tests/test_item.py index da9f24aefd..8dde922dc0 100644 --- a/cms/djangoapps/contentstore/views/tests/test_item.py +++ b/cms/djangoapps/contentstore/views/tests/test_item.py @@ -37,7 +37,6 @@ from contentstore.views.item import ( highlights_setting, ) from lms_xblock.mixin import NONSENSICAL_ACCESS_RESTRICTION -from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration from student.tests.factories import UserFactory from xblock_django.models import XBlockConfiguration, XBlockStudioConfiguration, XBlockStudioConfigurationFlag from xblock_django.user_service import DjangoXBlockUserService @@ -3145,7 +3144,6 @@ class TestXBlockPublishingInfo(ItemTest): Test that when item was initially in `scheduled` state in instructor mode, change course pacing to self-paced, now in self-paced course, item should have `live` visibility state. """ - SelfPacedConfiguration(enabled=True).save() # Create course, chapter and setup future release date to make chapter in scheduled state course = CourseFactory.create(default_store=store_type) diff --git a/cms/static/sass/views/_settings.scss b/cms/static/sass/views/_settings.scss index 8798c6a58d..3a93ac2146 100644 --- a/cms/static/sass/views/_settings.scss +++ b/cms/static/sass/views/_settings.scss @@ -118,6 +118,10 @@ } } + legend { + width: 100%; + } + // basic layout/elements .title-2 { diff --git a/cms/templates/course_outline.html b/cms/templates/course_outline.html index 6bab750a87..9b5c3f3824 100644 --- a/cms/templates/course_outline.html +++ b/cms/templates/course_outline.html @@ -7,7 +7,6 @@ from util.date_utils import get_default_time_display from django.utils.translation import ugettext as _ from openedx.core.djangolib.js_utils import dump_js_escaped_json from contentstore.utils import reverse_usage_url -from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration from openedx.core.djangolib.markup import HTML, Text %> <%block name="title">${_("Course Outline")} @@ -166,17 +165,15 @@ from openedx.core.djangolib.markup import HTML, Text - % if SelfPacedConfiguration.current().enabled: -
-

${_("Course Pacing")}

-
- % if context_course.self_paced: -

${_("Self-Paced")}

- % else: -

${_("Instructor-Paced")}

- % endif -
- % endif +
+

${_("Course Pacing")}

+
+ % if context_course.self_paced: +

${_("Self-Paced")}

+ % else: +

${_("Instructor-Paced")}

+ % endif +
% endif - % if self_paced_enabled: +
-
- -
-
-

${_("Course Pacing")}

- ${_("Set the pacing for this course")} -
+
+
+ +
+

${_("Course Pacing")}

+ ${_("Set the pacing for this course")} +
+
    -
  1. - - - ${_("Instructor-paced courses progress at the pace that the course author sets. You can configure release dates for course content and due dates for assignments.")} -
  2. -
  3. - - - ${_("Self-paced courses do not have release dates for course content or due dates for assignments. Learners can complete course material at any time before the course end date.")} -
  4. +
  5. + + + ${_("Instructor-paced courses progress at the pace that the course author sets. You can configure release dates for course content and due dates for assignments.")} +
  6. +
  7. + + + ${_("Self-paced courses do not have release dates for course content or due dates for assignments. Learners can complete course material at any time before the course end date.")} +
-
- - % endif + +
% if settings.FEATURES.get("LICENSING", False):
diff --git a/common/lib/xmodule/xmodule/course_module.py b/common/lib/xmodule/xmodule/course_module.py index e5b0e05c10..c79007241b 100644 --- a/common/lib/xmodule/xmodule/course_module.py +++ b/common/lib/xmodule/xmodule/course_module.py @@ -1408,8 +1408,10 @@ class CourseDescriptor(CourseFields, SequenceDescriptor, LicenseMixin): Whether or not the course can be set to self-paced at this time. Returns: - bool: False if the course has already started, True otherwise. + bool: False if the course has already started or no start date set, True otherwise. """ + if not self.start: + return False return datetime.now(utc) <= self.start diff --git a/lms/djangoapps/certificates/tests/test_signals.py b/lms/djangoapps/certificates/tests/test_signals.py index 75bf216bc9..8212b04fbf 100644 --- a/lms/djangoapps/certificates/tests/test_signals.py +++ b/lms/djangoapps/certificates/tests/test_signals.py @@ -17,7 +17,6 @@ from lms.djangoapps.grades.course_grade_factory import CourseGradeFactory from lms.djangoapps.grades.tests.utils import mock_passing_grade from lms.djangoapps.verify_student.models import SoftwareSecurePhotoVerification from openedx.core.djangoapps.certificates.config import waffle -from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration from student.tests.factories import CourseEnrollmentFactory, UserFactory from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory @@ -31,7 +30,6 @@ class SelfGeneratedCertsSignalTest(ModuleStoreTestCase): def setUp(self): super(SelfGeneratedCertsSignalTest, self).setUp() - SelfPacedConfiguration(enabled=True).save() CertificateGenerationConfiguration.objects.create(enabled=True) def test_cert_generation_flag_on_pacing_toggle(self): diff --git a/lms/djangoapps/courseware/self_paced_overrides.py b/lms/djangoapps/courseware/self_paced_overrides.py index 2c8e7b4cac..25d3975055 100644 --- a/lms/djangoapps/courseware/self_paced_overrides.py +++ b/lms/djangoapps/courseware/self_paced_overrides.py @@ -3,8 +3,6 @@ Field overrides for self-paced courses. This allows overriding due dates for each block in the course. """ -from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration - from .field_overrides import FieldOverrideProvider @@ -27,4 +25,4 @@ class SelfPacedDateOverrideProvider(FieldOverrideProvider): @classmethod def enabled_for(cls, block): """This provider is enabled for self-paced courses only.""" - return block is not None and block.self_paced and SelfPacedConfiguration.current().enabled + return block is not None and block.self_paced diff --git a/lms/djangoapps/courseware/tests/test_course_info.py b/lms/djangoapps/courseware/tests/test_course_info.py index 58d338c296..0a2f471015 100644 --- a/lms/djangoapps/courseware/tests/test_course_info.py +++ b/lms/djangoapps/courseware/tests/test_course_info.py @@ -371,7 +371,6 @@ class SelfPacedCourseInfoTestCase(LoginEnrollmentTestCase, SharedModuleStoreTest cls.self_paced_course = CourseFactory.create(self_paced=True) def setUp(self): - SelfPacedConfiguration(enabled=True).save() super(SelfPacedCourseInfoTestCase, self).setUp() self.setup_user() diff --git a/lms/djangoapps/courseware/tests/test_self_paced_overrides.py b/lms/djangoapps/courseware/tests/test_self_paced_overrides.py index 47490b9c61..27bc610dbb 100644 --- a/lms/djangoapps/courseware/tests/test_self_paced_overrides.py +++ b/lms/djangoapps/courseware/tests/test_self_paced_overrides.py @@ -11,7 +11,6 @@ from courseware.tests.factories import BetaTesterFactory from lms.djangoapps.ccx.tests.test_overrides import inject_field_overrides from lms.djangoapps.courseware.field_overrides import OverrideFieldData, OverrideModulestoreFieldData from lms.djangoapps.django_comment_client.utils import get_accessible_discussion_xblocks -from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory @@ -29,8 +28,6 @@ class SelfPacedDateOverrideTest(ModuleStoreTestCase): self.reset_setting_cache_variables() super(SelfPacedDateOverrideTest, self).setUp() - SelfPacedConfiguration(enabled=True).save() - self.non_staff_user, __ = self.create_non_staff_user() self.now = datetime.datetime.now(pytz.UTC).replace(microsecond=0) self.future = self.now + datetime.timedelta(days=30) @@ -84,11 +81,6 @@ class SelfPacedDateOverrideTest(ModuleStoreTestCase): __, sp_section = self.setup_course(display_name="Self-Paced Course", self_paced=True) self.assertIsNone(sp_section.due) - def test_self_paced_disabled_due_date(self): - SelfPacedConfiguration(enabled=False).save() - __, sp_section = self.setup_course(display_name="Self-Paced Course", self_paced=True) - self.assertEqual(sp_section.due, self.now) - @patch.dict('courseware.access.settings.FEATURES', {'DISABLE_START_DATES': False}) def test_course_access_to_beta_users(self): """ diff --git a/lms/djangoapps/courseware/tests/test_views.py b/lms/djangoapps/courseware/tests/test_views.py index 538a78858f..aedd0aada0 100644 --- a/lms/djangoapps/courseware/tests/test_views.py +++ b/lms/djangoapps/courseware/tests/test_views.py @@ -57,7 +57,6 @@ from openedx.core.djangoapps.content.course_overviews.models import CourseOvervi from openedx.core.djangoapps.crawlers.models import CrawlersConfig from openedx.core.djangoapps.credit.api import set_credit_requirements from openedx.core.djangoapps.credit.models import CreditCourse, CreditProvider -from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration from openedx.core.djangoapps.waffle_utils import CourseWaffleFlag, WaffleFlagNamespace from openedx.core.djangoapps.waffle_utils.testutils import WAFFLE_TABLES, override_waffle_flag from openedx.core.djangolib.testing.utils import get_mock_request @@ -1425,13 +1424,9 @@ class ProgressPageTests(ProgressPageBaseTests): resp = self._get_progress_page() self.assertContains(resp, u"Download Your Certificate") - @ddt.data( - *itertools.product((True, False), (True, False)) - ) - @ddt.unpack - def test_progress_queries_paced_courses(self, self_paced, self_paced_enabled): + @ddt.data(True, False) + def test_progress_queries_paced_courses(self, self_paced): """Test that query counts remain the same for self-paced and instructor-paced courses.""" - SelfPacedConfiguration(enabled=self_paced_enabled).save() self.setup_course(self_paced=self_paced) with self.assertNumQueries(34 if self_paced else 33, table_blacklist=QUERY_COUNT_TABLE_BLACKLIST), check_mongo_calls(1): self._get_progress_page() @@ -2502,7 +2497,6 @@ class TestRenderXBlockSelfPaced(TestRenderXBlock): """ def setUp(self): super(TestRenderXBlockSelfPaced, self).setUp() - SelfPacedConfiguration(enabled=True).save() def course_options(self): options = super(TestRenderXBlockSelfPaced, self).course_options() diff --git a/openedx/core/djangoapps/models/course_details.py b/openedx/core/djangoapps/models/course_details.py index e24bac7565..a06a018395 100644 --- a/openedx/core/djangoapps/models/course_details.py +++ b/openedx/core/djangoapps/models/course_details.py @@ -8,7 +8,6 @@ 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 xmodule.modulestore.django import modulestore @@ -275,8 +274,7 @@ class CourseDetails(object): descriptor.language = jsondict['language'] dirty = True - if (SelfPacedConfiguration.current().enabled - and descriptor.can_toggle_course_pacing + if (descriptor.can_toggle_course_pacing and 'self_paced' in jsondict and jsondict['self_paced'] != descriptor.self_paced): descriptor.self_paced = jsondict['self_paced'] diff --git a/openedx/core/djangoapps/models/tests/test_course_details.py b/openedx/core/djangoapps/models/tests/test_course_details.py index ff0676997a..cd9cf17aca 100644 --- a/openedx/core/djangoapps/models/tests/test_course_details.py +++ b/openedx/core/djangoapps/models/tests/test_course_details.py @@ -11,7 +11,6 @@ from xmodule.modulestore import ModuleStoreEnum from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory -from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration from openedx.core.djangoapps.models.course_details import CourseDetails, ABOUT_ATTRIBUTES @@ -50,7 +49,6 @@ class CourseDetailsTestCase(ModuleStoreTestCase): self.assertFalse(details.self_paced) def test_update_and_fetch(self): - SelfPacedConfiguration(enabled=True).save() jsondetails = CourseDetails.fetch(self.course.id) jsondetails.syllabus = "bar" # encode - decode to convert date fields and other data which changes form @@ -143,7 +141,6 @@ class CourseDetailsTestCase(ModuleStoreTestCase): ) def test_toggle_pacing_during_course_run(self): - SelfPacedConfiguration(enabled=True).save() self.course.start = datetime.datetime.now() self.store.update_item(self.course, self.user.id)