From c28f97c15ed249ed59f9a81ac3eba0e37dca80db Mon Sep 17 00:00:00 2001 From: Jonathan Piacenti Date: Tue, 25 Nov 2014 16:13:14 +0000 Subject: [PATCH 1/9] Made empty course url the 'home' url instead. --- cms/djangoapps/contentstore/views/course.py | 6 +++-- cms/templates/index.html | 30 ++------------------- cms/urls.py | 1 + 3 files changed, 7 insertions(+), 30 deletions(-) diff --git a/cms/djangoapps/contentstore/views/course.py b/cms/djangoapps/contentstore/views/course.py index d6b2b67aad97..23be040253bd 100644 --- a/cms/djangoapps/contentstore/views/course.py +++ b/cms/djangoapps/contentstore/views/course.py @@ -1,6 +1,7 @@ """ Views related to operations on course objects """ +from django.shortcuts import redirect import json import random import string # pylint: disable=deprecated-module @@ -71,7 +72,8 @@ from xmodule.course_module import CourseFields -__all__ = ['course_info_handler', 'course_handler', 'course_info_update_handler', +__all__ = ['course_info_handler', 'course_handler', 'course_listing', + 'course_info_update_handler', 'course_rerun_handler', 'settings_handler', 'grading_handler', @@ -230,7 +232,7 @@ def course_handler(request, course_key_string=None): return HttpResponseBadRequest() elif request.method == 'GET': # assume html if course_key_string is None: - return course_listing(request) + return redirect(reverse("home")) else: return course_index(request, CourseKey.from_string(course_key_string)) else: diff --git a/cms/templates/index.html b/cms/templates/index.html index 85d008a13640..178eec6f4370 100644 --- a/cms/templates/index.html +++ b/cms/templates/index.html @@ -14,7 +14,7 @@ <%block name="content">
-

${_("My Courses")}

+

${_("Studio Home")}

% if user.is_active:
From 798d595f0c944eb6260b4aaf92463b12ac138144 Mon Sep 17 00:00:00 2001 From: Matjaz Gregoric Date: Fri, 14 Nov 2014 09:08:14 +0100 Subject: [PATCH 4/9] Update text on new content library form. --- cms/templates/index.html | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/cms/templates/index.html b/cms/templates/index.html index 178eec6f4370..b3adca264e24 100644 --- a/cms/templates/index.html +++ b/cms/templates/index.html @@ -129,15 +129,14 @@

${_("Create a New Library")}

  • - ${_("The name of the organization sponsoring the library.")} ${_("Note: This is part of your library URL, so no spaces or special characters are allowed.")} ${_("This cannot be changed.")} + ${_("The public organization name for your library.")} ${_("This cannot be changed.")}
  • - - ## Translators: This is an example for the "number" used to identify a library, seen when filling out the form to create a new library. This example is short for "Computer Science Problems". The example number may contain letters but must not contain spaces. - - ${_("The unique code that identifies this library.")} ${_("Note: This is part of your library URL, so no spaces or special characters are allowed.")} ${_("This cannot be changed.")} + + + ${_("The {em_start}major version number{em_end} of your library. Minor revisions are tracked as edits happen within a library.").format(em_start='', em_end='')}
  • From 460d1cde55aa996c912a98649c68660c521c8e00 Mon Sep 17 00:00:00 2001 From: Matjaz Gregoric Date: Fri, 14 Nov 2014 08:55:21 +0100 Subject: [PATCH 5/9] Libraries UI: remove underline on hover. This changes the style of the inactive libraries/courses tab when hovering. Only the active tab on the dashboard page gets the blue underline. When hovering over an inactive tab, the color of the text changes, but the underline does not appear. --- cms/static/sass/views/_dashboard.scss | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/cms/static/sass/views/_dashboard.scss b/cms/static/sass/views/_dashboard.scss index 1a1430f0127e..3ae4bd3ba228 100644 --- a/cms/static/sass/views/_dashboard.scss +++ b/cms/static/sass/views/_dashboard.scss @@ -299,19 +299,21 @@ line-height: $baseline*2; margin: 0 10px; - &.active, &:hover { + &.active { border-bottom: 4px solid $blue; } + &.active, &:hover { + a { + color: $gray-d2; + } + } + a { color: $blue; cursor: pointer; display: inline-block; } - - &.active a { - color: $gray-d2; - } } } From f39b2c7969882f80a696f1a25d7b38c0030b20e7 Mon Sep 17 00:00:00 2001 From: Jonathan Piacenti Date: Fri, 28 Nov 2014 16:52:00 +0000 Subject: [PATCH 6/9] Added test for /home/ redirect. --- .../test/acceptance/tests/studio/test_studio_general.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/common/test/acceptance/tests/studio/test_studio_general.py b/common/test/acceptance/tests/studio/test_studio_general.py index 88dc31467389..c0b409b66bb5 100644 --- a/common/test/acceptance/tests/studio/test_studio_general.py +++ b/common/test/acceptance/tests/studio/test_studio_general.py @@ -88,6 +88,15 @@ def setUp(self): ] ] + def test_page_redirect(self): + """ + /course/ is the base URL for all courses, but by itself, it should + redirect to /home/. + """ + self.dashboard_page = DashboardPage(self.browser) + self.dashboard_page.visit() + self.assertEqual(self.browser.current_url.strip('/').rsplit('/')[-1], 'home') + @skip('Intermittently failing with Page not found error for Assets. TE-418') def test_page_existence(self): """ From be488704a8da0c3e3f89f2b073d9d0197d22a206 Mon Sep 17 00:00:00 2001 From: Jonathan Piacenti Date: Fri, 28 Nov 2014 17:23:45 +0000 Subject: [PATCH 7/9] Quality check and test fixes. --- .../contentstore/tests/test_contentstore.py | 8 ++--- .../contentstore/tests/test_i18n.py | 10 +++--- cms/djangoapps/contentstore/tests/tests.py | 10 +++--- cms/djangoapps/contentstore/views/public.py | 2 +- .../views/tests/test_course_index.py | 4 +-- cms/templates/index.html | 2 +- common/djangoapps/student/tests/test_login.py | 2 +- .../pages/lms/login_and_register.py | 2 ++ common/test/acceptance/tests/lms/test_lms.py | 5 ++- docs/shared/conf.py | 1 - pavelib/paver_tests/test_prereqs.py | 31 +++++++++++++++++-- pavelib/prereqs.py | 2 +- 12 files changed, 55 insertions(+), 24 deletions(-) diff --git a/cms/djangoapps/contentstore/tests/test_contentstore.py b/cms/djangoapps/contentstore/tests/test_contentstore.py index 27714230dc62..e0122f4cd92d 100644 --- a/cms/djangoapps/contentstore/tests/test_contentstore.py +++ b/cms/djangoapps/contentstore/tests/test_contentstore.py @@ -1167,7 +1167,7 @@ def assert_course_permission_denied(self): def test_course_index_view_with_no_courses(self): """Test viewing the index page with no courses""" # Create a course so there is something to view - resp = self.client.get_html('/course/') + resp = self.client.get_html('/home/') self.assertContains( resp, '

    My Courses

    ', @@ -1189,7 +1189,7 @@ def test_item_factory(self): def test_course_index_view_with_course(self): """Test viewing the index page with an existing course""" CourseFactory.create(display_name='Robot Super Educational Course') - resp = self.client.get_html('/course/') + resp = self.client.get_html('/home/') self.assertContains( resp, '

    Robot Super Educational Course

    ', @@ -1604,7 +1604,7 @@ def assertInCourseListing(self, course_key): Asserts that the given course key is in the accessible course listing section of the html and NOT in the unsucceeded course action section of the html. """ - course_listing = lxml.html.fromstring(self.client.get_html('/course/').content) + course_listing = lxml.html.fromstring(self.client.get_html('/home/').content) self.assertEqual(len(self.get_course_listing_elements(course_listing, course_key)), 1) self.assertEqual(len(self.get_unsucceeded_course_action_elements(course_listing, course_key)), 0) @@ -1613,7 +1613,7 @@ def assertInUnsucceededCourseActions(self, course_key): Asserts that the given course key is in the unsucceeded course action section of the html and NOT in the accessible course listing section of the html. """ - course_listing = lxml.html.fromstring(self.client.get_html('/course/').content) + course_listing = lxml.html.fromstring(self.client.get_html('/home/').content) self.assertEqual(len(self.get_course_listing_elements(course_listing, course_key)), 0) self.assertEqual(len(self.get_unsucceeded_course_action_elements(course_listing, course_key)), 1) diff --git a/cms/djangoapps/contentstore/tests/test_i18n.py b/cms/djangoapps/contentstore/tests/test_i18n.py index e9e17394883f..da7911722035 100644 --- a/cms/djangoapps/contentstore/tests/test_i18n.py +++ b/cms/djangoapps/contentstore/tests/test_i18n.py @@ -44,9 +44,9 @@ def test_course_plain_english(self): self.client = AjaxEnabledTestClient() self.client.login(username=self.uname, password=self.password) - resp = self.client.get_html('/course/') + resp = self.client.get_html('/home/') self.assertContains(resp, - '

    My Courses

    ', + '

    Studio Home

    ', status_code=200, html=True) @@ -56,13 +56,13 @@ def test_course_explicit_english(self): self.client.login(username=self.uname, password=self.password) resp = self.client.get_html( - '/course/', + '/home/', {}, HTTP_ACCEPT_LANGUAGE='en', ) self.assertContains(resp, - '

    My Courses

    ', + '

    Studio Home

    ', status_code=200, html=True) @@ -81,7 +81,7 @@ def test_course_with_accents(self): self.client.login(username=self.uname, password=self.password) resp = self.client.get_html( - '/course/', + '/home/', {}, HTTP_ACCEPT_LANGUAGE='eo' ) diff --git a/cms/djangoapps/contentstore/tests/tests.py b/cms/djangoapps/contentstore/tests/tests.py index 9975764345e1..76429befa6cf 100644 --- a/cms/djangoapps/contentstore/tests/tests.py +++ b/cms/djangoapps/contentstore/tests/tests.py @@ -234,13 +234,13 @@ def test_login_link_on_activation_age(self): def test_private_pages_auth(self): """Make sure pages that do require login work.""" auth_pages = ( - '/course/', + '/home/', ) # These are pages that should just load when the user is logged in # (no data needed) simple_auth_pages = ( - '/course/', + '/home/', ) # need an activated user @@ -266,7 +266,7 @@ def test_private_pages_auth(self): def test_index_auth(self): # not logged in. Should return a redirect. - resp = self.client.get_html('/course/') + resp = self.client.get_html('/home/') self.assertEqual(resp.status_code, 302) # Logged in should work. @@ -283,7 +283,7 @@ def test_inactive_session_timeout(self): self.login(self.email, self.pw) # make sure we can access courseware immediately - course_url = '/course/' + course_url = '/home/' resp = self.client.get_html(course_url) self.assertEquals(resp.status_code, 200) @@ -293,7 +293,7 @@ def test_inactive_session_timeout(self): resp = self.client.get_html(course_url) # re-request, and we should get a redirect to login page - self.assertRedirects(resp, settings.LOGIN_REDIRECT_URL + '?next=/course/') + self.assertRedirects(resp, settings.LOGIN_REDIRECT_URL + '?next=/home/') class ForumTestCase(CourseTestCase): diff --git a/cms/djangoapps/contentstore/views/public.py b/cms/djangoapps/contentstore/views/public.py index 597bb5e18781..7bc6545868c9 100644 --- a/cms/djangoapps/contentstore/views/public.py +++ b/cms/djangoapps/contentstore/views/public.py @@ -66,6 +66,6 @@ def login_page(request): def howitworks(request): "Proxy view" if request.user.is_authenticated(): - return redirect('/course/') + return redirect('/home/') else: return render_to_response('howitworks.html', {}) diff --git a/cms/djangoapps/contentstore/views/tests/test_course_index.py b/cms/djangoapps/contentstore/views/tests/test_course_index.py index 965879e15428..32b5ccbf2cf2 100644 --- a/cms/djangoapps/contentstore/views/tests/test_course_index.py +++ b/cms/djangoapps/contentstore/views/tests/test_course_index.py @@ -42,7 +42,7 @@ def check_index_and_outline(self, authed_client): """ Test getting the list of courses and then pulling up their outlines """ - index_url = '/course/' + index_url = '/home/' index_response = authed_client.get(index_url, {}, HTTP_ACCEPT='text/html') parsed_html = lxml.html.fromstring(index_response.content) course_link_eles = parsed_html.find_class('course-link') @@ -68,7 +68,7 @@ def test_libraries_on_course_index(self): # Add a library: lib1 = LibraryFactory.create() - index_url = '/course/' + index_url = '/home/' index_response = self.client.get(index_url, {}, HTTP_ACCEPT='text/html') parsed_html = lxml.html.fromstring(index_response.content) library_link_elements = parsed_html.find_class('library-link') diff --git a/cms/templates/index.html b/cms/templates/index.html index b3adca264e24..e9d57f7c1ba8 100644 --- a/cms/templates/index.html +++ b/cms/templates/index.html @@ -2,7 +2,7 @@ <%inherit file="base.html" /> <%def name="online_help_token()"><% return "home" %> -<%block name="title">${_("My Courses")} +<%block name="title">${_("Studio Home")} <%block name="bodyclass">is-signedin index view-dashboard <%block name="requirejs"> diff --git a/common/djangoapps/student/tests/test_login.py b/common/djangoapps/student/tests/test_login.py index 828e951cbbf6..8cf07e3a80b7 100644 --- a/common/djangoapps/student/tests/test_login.py +++ b/common/djangoapps/student/tests/test_login.py @@ -482,7 +482,7 @@ def test_success(self): self._setup_user_response(success=True) response = self.client.post(self.url, {"access_token": "dummy"}) self.assertEqual(response.status_code, 204) - self.assertEqual(self.client.session['_auth_user_id'], self.user.id) + self.assertEqual(self.client.session['_auth_user_id'], self.user.id) # pylint: disable=no-member def test_invalid_token(self): self._setup_user_response(success=False) diff --git a/common/test/acceptance/pages/lms/login_and_register.py b/common/test/acceptance/pages/lms/login_and_register.py index 1bda4fa2d817..f775066fb65c 100644 --- a/common/test/acceptance/pages/lms/login_and_register.py +++ b/common/test/acceptance/pages/lms/login_and_register.py @@ -244,6 +244,7 @@ def errors(self): def wait_for_errors(self): """Wait for errors to be visible, then return them. """ def _check_func(): + """Return success status and any errors that occurred.""" errors = self.errors return (bool(errors), errors) return Promise(_check_func, "Errors are visible").fulfill() @@ -257,6 +258,7 @@ def success(self): def wait_for_success(self): """Wait for a success message to be visible, then return it.""" def _check_func(): + """Return success status and any errors that occurred.""" success = self.success return (bool(success), success) return Promise(_check_func, "Success message is visible").fulfill() diff --git a/common/test/acceptance/tests/lms/test_lms.py b/common/test/acceptance/tests/lms/test_lms.py index 09853250bfcf..d15b0d77582f 100644 --- a/common/test/acceptance/tests/lms/test_lms.py +++ b/common/test/acceptance/tests/lms/test_lms.py @@ -119,7 +119,7 @@ def test_toggle_to_register_form(self): def test_password_reset_success(self): # Create a user account - email, password = self._create_unique_user() + email, password = self._create_unique_user() # pylint: disable=unused-variable # Navigate to the password reset form and try to submit it self.login_page.visit().password_reset(email=email) @@ -141,6 +141,9 @@ def test_password_reset_failure(self): ) def _create_unique_user(self): + """ + Create a new user with a unique name and email. + """ username = "test_{uuid}".format(uuid=self.unique_id[0:6]) email = "{user}@example.com".format(user=username) password = "password" diff --git a/docs/shared/conf.py b/docs/shared/conf.py index dfedf01ca81b..992f0e54f38c 100644 --- a/docs/shared/conf.py +++ b/docs/shared/conf.py @@ -22,7 +22,6 @@ # ----------------------------------------------------------------------------- import os -import sys BASEDIR = os.path.dirname(os.path.abspath(__file__)) diff --git a/pavelib/paver_tests/test_prereqs.py b/pavelib/paver_tests/test_prereqs.py index e4586d18434d..47437ee90768 100644 --- a/pavelib/paver_tests/test_prereqs.py +++ b/pavelib/paver_tests/test_prereqs.py @@ -1,12 +1,21 @@ - import os import unittest from pavelib.prereqs import no_prereq_install class TestPaverPrereqInstall(unittest.TestCase): - + """ + Test the status of the NO_PREREQ_INSTALL variable, its presence and how + paver handles it. + """ def check_val(self, set_val, expected_val): + """ + Verify that setting the variable to a certain value returns + the expected boolean for it. + + As environment variables are only stored as strings, we have to cast + whatever it's set at to a boolean that does not violate expectations. + """ _orig_environ = dict(os.environ) os.environ['NO_PREREQ_INSTALL'] = set_val self.assertEqual( @@ -21,19 +30,37 @@ def check_val(self, set_val, expected_val): os.environ.update(_orig_environ) def test_no_prereq_install_true(self): + """ + Ensure that 'true' will be True. + """ self.check_val('true', True) def test_no_prereq_install_false(self): + """ + Ensure that 'false' will be False. + """ self.check_val('false', False) def test_no_prereq_install_True(self): + """ + Ensure that 'True' will be True. + """ self.check_val('True', True) def test_no_prereq_install_False(self): + """ + Ensure that 'False' will be False. + """ self.check_val('False', False) def test_no_prereq_install_0(self): + """ + Ensure that '0' will be False. + """ self.check_val('0', False) def test_no_prereq_install_1(self): + """ + Ensure that '1' will be True. + """ self.check_val('1', True) diff --git a/pavelib/prereqs.py b/pavelib/prereqs.py index 0a334a815204..220a5387c4ec 100644 --- a/pavelib/prereqs.py +++ b/pavelib/prereqs.py @@ -41,7 +41,7 @@ def no_prereq_install(): try: return vals[val] - except: + except KeyError: return False From ad1e83f913d95f38aa66ef7afd8c1fa272facbc0 Mon Sep 17 00:00:00 2001 From: Matjaz Gregoric Date: Wed, 17 Dec 2014 12:28:34 +0100 Subject: [PATCH 8/9] Update tests. Most of the updates are related to the My Courses -> Studio Home change. --- cms/djangoapps/contentstore/features/common.py | 2 +- cms/djangoapps/contentstore/features/courses.py | 8 ++++---- .../contentstore/features/help.feature | 2 +- .../contentstore/features/signup.feature | 2 +- cms/djangoapps/contentstore/features/signup.py | 2 +- .../contentstore/tests/test_contentstore.py | 3 +-- .../js/mock/mock-index-page.underscore | 17 +++++------------ cms/templates/widgets/header.html | 2 +- common/djangoapps/terrain/ui_helpers.py | 2 +- common/test/acceptance/pages/studio/index.py | 11 ++--------- .../acceptance/tests/studio/test_studio_home.py | 10 ---------- 11 files changed, 18 insertions(+), 43 deletions(-) diff --git a/cms/djangoapps/contentstore/features/common.py b/cms/djangoapps/contentstore/features/common.py index b0681433b09d..deefb84ff199 100644 --- a/cms/djangoapps/contentstore/features/common.py +++ b/cms/djangoapps/contentstore/features/common.py @@ -171,7 +171,7 @@ def log_into_studio( world.log_in(username=uname, password=password, email=email, name=name) # Navigate to the studio dashboard world.visit('/') - assert_in(uname, world.css_text('h2.title', timeout=10)) + assert_in(uname, world.css_text('span.account-username', timeout=10)) def add_course_author(user, course): diff --git a/cms/djangoapps/contentstore/features/courses.py b/cms/djangoapps/contentstore/features/courses.py index 7b3ccbcbd2af..075d8525b56e 100644 --- a/cms/djangoapps/contentstore/features/courses.py +++ b/cms/djangoapps/contentstore/features/courses.py @@ -33,8 +33,8 @@ def i_create_a_course(step): create_a_course() -@step('I click the course link in My Courses$') -def i_click_the_course_link_in_my_courses(step): +@step('I click the course link in Studio Home$') +def i_click_the_course_link_in_studio_home(step): course_css = 'a.course-link' world.css_click(course_css) @@ -52,8 +52,8 @@ def courseware_page_has_loaded_in_studio(step): assert world.is_css_present(course_title_css) -@step('I see the course listed in My Courses$') -def i_see_the_course_in_my_courses(step): +@step('I see the course listed in Studio Home$') +def i_see_the_course_in_studio_home(step): course_css = 'h3.class-title' assert world.css_has_text(course_css, world.scenario_dict['COURSE'].display_name) diff --git a/cms/djangoapps/contentstore/features/help.feature b/cms/djangoapps/contentstore/features/help.feature index eb0f872247b3..567a2f252664 100644 --- a/cms/djangoapps/contentstore/features/help.feature +++ b/cms/djangoapps/contentstore/features/help.feature @@ -11,7 +11,7 @@ Feature: CMS.Help Scenario: Users can access online help within a course Given I have opened a new course in Studio - And I click the course link in My Courses + And I click the course link in Studio Home Then I should see online help for "outline" And I go to the course updates page diff --git a/cms/djangoapps/contentstore/features/signup.feature b/cms/djangoapps/contentstore/features/signup.feature index 92ff0d393d7d..3f29c4fda68c 100644 --- a/cms/djangoapps/contentstore/features/signup.feature +++ b/cms/djangoapps/contentstore/features/signup.feature @@ -26,4 +26,4 @@ Feature: CMS.Sign in And I visit the url "/signin?next=http://www.google.com/" When I fill in and submit the signin form And I wait for "2" seconds - Then I should see that the path is "/course/" + Then I should see that the path is "/home/" diff --git a/cms/djangoapps/contentstore/features/signup.py b/cms/djangoapps/contentstore/features/signup.py index 26374fe963f7..a661b2473c2e 100644 --- a/cms/djangoapps/contentstore/features/signup.py +++ b/cms/djangoapps/contentstore/features/signup.py @@ -24,7 +24,7 @@ def i_press_the_button_on_the_registration_form(step): @step('I should see an email verification prompt') def i_should_see_an_email_verification_prompt(step): - world.css_has_text('h1.page-header', u'My Courses') + world.css_has_text('h1.page-header', u'Studio Home') world.css_has_text('div.msg h3.title', u'We need to verify your email address') diff --git a/cms/djangoapps/contentstore/tests/test_contentstore.py b/cms/djangoapps/contentstore/tests/test_contentstore.py index e0122f4cd92d..a107d654494b 100644 --- a/cms/djangoapps/contentstore/tests/test_contentstore.py +++ b/cms/djangoapps/contentstore/tests/test_contentstore.py @@ -1166,11 +1166,10 @@ def assert_course_permission_denied(self): def test_course_index_view_with_no_courses(self): """Test viewing the index page with no courses""" - # Create a course so there is something to view resp = self.client.get_html('/home/') self.assertContains( resp, - '

    My Courses

    ', + '

    Studio Home

    ', status_code=200, html=True ) diff --git a/cms/templates/js/mock/mock-index-page.underscore b/cms/templates/js/mock/mock-index-page.underscore index 83f1bc509e26..8a149ece9d23 100644 --- a/cms/templates/js/mock/mock-index-page.underscore +++ b/cms/templates/js/mock/mock-index-page.underscore @@ -1,6 +1,6 @@
    -

    My Courses

    +

    Studio Home