Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
2167584e
Commit
2167584e
authored
Apr 27, 2017
by
Andy Armstrong
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Unify the home and course tabs
LEARNER-609
parent
b10c71d8
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
120 additions
and
64 deletions
+120
-64
common/djangoapps/student/views.py
+4
-3
common/test/acceptance/tests/lms/test_lms_course_home.py
+1
-1
lms/djangoapps/ccx/tests/test_field_override_performance.py
+27
-27
lms/djangoapps/courseware/tabs.py
+7
-13
lms/djangoapps/courseware/tests/test_course_info.py
+2
-2
lms/djangoapps/courseware/tests/test_tabs.py
+23
-0
lms/djangoapps/courseware/tests/test_views.py
+5
-5
lms/djangoapps/courseware/views/views.py
+13
-5
lms/templates/dashboard/_dashboard_course_listing.html
+2
-1
lms/templates/shoppingcart/registration_code_receipt.html
+3
-1
lms/tests.py
+2
-1
openedx/features/course_bookmarks/views/course_bookmarks.py
+2
-2
openedx/features/course_experience/__init__.py
+27
-1
openedx/features/course_experience/views/course_updates.py
+2
-2
No files found.
common/djangoapps/student/views.py
View file @
2167584e
...
@@ -116,6 +116,7 @@ from student.models import anonymous_id_for_user, UserAttribute, EnrollStatusCha
...
@@ -116,6 +116,7 @@ from student.models import anonymous_id_for_user, UserAttribute, EnrollStatusCha
from
shoppingcart.models
import
DonationConfiguration
,
CourseRegistrationCode
from
shoppingcart.models
import
DonationConfiguration
,
CourseRegistrationCode
from
openedx.core.djangoapps.embargo
import
api
as
embargo_api
from
openedx.core.djangoapps.embargo
import
api
as
embargo_api
from
openedx.features.course_experience
import
course_home_url_name
from
openedx.features.enterprise_support.api
import
get_dashboard_consent_notification
from
openedx.features.enterprise_support.api
import
get_dashboard_consent_notification
import
analytics
import
analytics
...
@@ -2194,12 +2195,12 @@ def auto_auth(request):
...
@@ -2194,12 +2195,12 @@ def auto_auth(request):
# Redirect to specific page if specified
# Redirect to specific page if specified
if
redirect_to
:
if
redirect_to
:
redirect_url
=
redirect_to
redirect_url
=
redirect_to
# Redirect to course
info
page if course_id is known
# Redirect to course
home
page if course_id is known
elif
course_id
:
elif
course_id
:
try
:
try
:
# redirect to course
info
page in LMS
# redirect to course
home
page in LMS
redirect_url
=
reverse
(
redirect_url
=
reverse
(
'info'
,
course_home_url_name
(
request
)
,
kwargs
=
{
'course_id'
:
course_id
}
kwargs
=
{
'course_id'
:
course_id
}
)
)
except
NoReverseMatch
:
except
NoReverseMatch
:
...
...
common/test/acceptance/tests/lms/test_lms_course_home.py
View file @
2167584e
...
@@ -64,7 +64,7 @@ class CourseHomeTest(CourseHomeBaseTest):
...
@@ -64,7 +64,7 @@ class CourseHomeTest(CourseHomeBaseTest):
def
test_course_home
(
self
):
def
test_course_home
(
self
):
"""
"""
Smoke test of course outline, breadcrumbs to and from cours outline, and bookmarks.
Smoke test of course outline, breadcrumbs to and from cours
e
outline, and bookmarks.
"""
"""
self
.
course_home_page
.
visit
()
self
.
course_home_page
.
visit
()
...
...
lms/djangoapps/ccx/tests/test_field_override_performance.py
View file @
2167584e
...
@@ -231,18 +231,18 @@ class TestFieldOverrideMongoPerformance(FieldOverridePerformanceTestCase):
...
@@ -231,18 +231,18 @@ class TestFieldOverrideMongoPerformance(FieldOverridePerformanceTestCase):
# # of sql queries to default,
# # of sql queries to default,
# # of mongo queries,
# # of mongo queries,
# )
# )
(
'no_overrides'
,
1
,
True
,
False
):
(
2
3
,
1
),
(
'no_overrides'
,
1
,
True
,
False
):
(
2
4
,
1
),
(
'no_overrides'
,
2
,
True
,
False
):
(
2
3
,
1
),
(
'no_overrides'
,
2
,
True
,
False
):
(
2
4
,
1
),
(
'no_overrides'
,
3
,
True
,
False
):
(
2
3
,
1
),
(
'no_overrides'
,
3
,
True
,
False
):
(
2
4
,
1
),
(
'ccx'
,
1
,
True
,
False
):
(
2
3
,
1
),
(
'ccx'
,
1
,
True
,
False
):
(
2
4
,
1
),
(
'ccx'
,
2
,
True
,
False
):
(
2
3
,
1
),
(
'ccx'
,
2
,
True
,
False
):
(
2
4
,
1
),
(
'ccx'
,
3
,
True
,
False
):
(
2
3
,
1
),
(
'ccx'
,
3
,
True
,
False
):
(
2
4
,
1
),
(
'no_overrides'
,
1
,
False
,
False
):
(
2
3
,
1
),
(
'no_overrides'
,
1
,
False
,
False
):
(
2
4
,
1
),
(
'no_overrides'
,
2
,
False
,
False
):
(
2
3
,
1
),
(
'no_overrides'
,
2
,
False
,
False
):
(
2
4
,
1
),
(
'no_overrides'
,
3
,
False
,
False
):
(
2
3
,
1
),
(
'no_overrides'
,
3
,
False
,
False
):
(
2
4
,
1
),
(
'ccx'
,
1
,
False
,
False
):
(
2
3
,
1
),
(
'ccx'
,
1
,
False
,
False
):
(
2
4
,
1
),
(
'ccx'
,
2
,
False
,
False
):
(
2
3
,
1
),
(
'ccx'
,
2
,
False
,
False
):
(
2
4
,
1
),
(
'ccx'
,
3
,
False
,
False
):
(
2
3
,
1
),
(
'ccx'
,
3
,
False
,
False
):
(
2
4
,
1
),
}
}
...
@@ -254,19 +254,19 @@ class TestFieldOverrideSplitPerformance(FieldOverridePerformanceTestCase):
...
@@ -254,19 +254,19 @@ class TestFieldOverrideSplitPerformance(FieldOverridePerformanceTestCase):
__test__
=
True
__test__
=
True
TEST_DATA
=
{
TEST_DATA
=
{
(
'no_overrides'
,
1
,
True
,
False
):
(
2
3
,
3
),
(
'no_overrides'
,
1
,
True
,
False
):
(
2
4
,
3
),
(
'no_overrides'
,
2
,
True
,
False
):
(
2
3
,
3
),
(
'no_overrides'
,
2
,
True
,
False
):
(
2
4
,
3
),
(
'no_overrides'
,
3
,
True
,
False
):
(
2
3
,
3
),
(
'no_overrides'
,
3
,
True
,
False
):
(
2
4
,
3
),
(
'ccx'
,
1
,
True
,
False
):
(
2
3
,
3
),
(
'ccx'
,
1
,
True
,
False
):
(
2
4
,
3
),
(
'ccx'
,
2
,
True
,
False
):
(
2
3
,
3
),
(
'ccx'
,
2
,
True
,
False
):
(
2
4
,
3
),
(
'ccx'
,
3
,
True
,
False
):
(
2
3
,
3
),
(
'ccx'
,
3
,
True
,
False
):
(
2
4
,
3
),
(
'ccx'
,
1
,
True
,
True
):
(
2
4
,
3
),
(
'ccx'
,
1
,
True
,
True
):
(
2
5
,
3
),
(
'ccx'
,
2
,
True
,
True
):
(
2
4
,
3
),
(
'ccx'
,
2
,
True
,
True
):
(
2
5
,
3
),
(
'ccx'
,
3
,
True
,
True
):
(
2
4
,
3
),
(
'ccx'
,
3
,
True
,
True
):
(
2
5
,
3
),
(
'no_overrides'
,
1
,
False
,
False
):
(
2
3
,
3
),
(
'no_overrides'
,
1
,
False
,
False
):
(
2
4
,
3
),
(
'no_overrides'
,
2
,
False
,
False
):
(
2
3
,
3
),
(
'no_overrides'
,
2
,
False
,
False
):
(
2
4
,
3
),
(
'no_overrides'
,
3
,
False
,
False
):
(
2
3
,
3
),
(
'no_overrides'
,
3
,
False
,
False
):
(
2
4
,
3
),
(
'ccx'
,
1
,
False
,
False
):
(
2
3
,
3
),
(
'ccx'
,
1
,
False
,
False
):
(
2
4
,
3
),
(
'ccx'
,
2
,
False
,
False
):
(
2
3
,
3
),
(
'ccx'
,
2
,
False
,
False
):
(
2
4
,
3
),
(
'ccx'
,
3
,
False
,
False
):
(
2
3
,
3
),
(
'ccx'
,
3
,
False
,
False
):
(
2
4
,
3
),
}
}
lms/djangoapps/courseware/tabs.py
View file @
2167584e
...
@@ -10,7 +10,7 @@ from django.utils.translation import ugettext as _, ugettext_noop
...
@@ -10,7 +10,7 @@ from django.utils.translation import ugettext as _, ugettext_noop
from
courseware.access
import
has_access
from
courseware.access
import
has_access
from
courseware.entrance_exams
import
user_can_skip_entrance_exam
from
courseware.entrance_exams
import
user_can_skip_entrance_exam
from
openedx.core.lib.course_tabs
import
CourseTabPluginManager
from
openedx.core.lib.course_tabs
import
CourseTabPluginManager
from
openedx.features.course_experience
import
UNIFIED_COURSE_VIEW
_FLAG
from
openedx.features.course_experience
import
defaut_course_url_name
,
UNIFIED_COURSE_EXPERIENCE
_FLAG
from
request_cache.middleware
import
RequestCache
from
request_cache.middleware
import
RequestCache
from
student.models
import
CourseEnrollment
from
student.models
import
CourseEnrollment
from
xmodule.tabs
import
CourseTab
,
CourseTabList
,
key_checker
,
link_reverse_func
from
xmodule.tabs
import
CourseTab
,
CourseTabList
,
key_checker
,
link_reverse_func
...
@@ -39,23 +39,13 @@ class CoursewareTab(EnrolledTab):
...
@@ -39,23 +39,13 @@ class CoursewareTab(EnrolledTab):
is_default
=
False
is_default
=
False
supports_preview_menu
=
True
supports_preview_menu
=
True
@staticmethod
def
main_course_url_name
(
request
):
"""
Returns the main course URL for the current user.
"""
if
waffle
.
flag_is_active
(
request
,
UNIFIED_COURSE_VIEW_FLAG
):
return
'openedx.course_experience.course_home'
else
:
return
'courseware'
@property
@property
def
link_func
(
self
):
def
link_func
(
self
):
"""
"""
Returns a function that computes the URL for this tab.
Returns a function that computes the URL for this tab.
"""
"""
request
=
RequestCache
.
get_current_request
()
request
=
RequestCache
.
get_current_request
()
url_name
=
self
.
main
_course_url_name
(
request
)
url_name
=
defaut
_course_url_name
(
request
)
return
link_reverse_func
(
url_name
)
return
link_reverse_func
(
url_name
)
...
@@ -73,7 +63,11 @@ class CourseInfoTab(CourseTab):
...
@@ -73,7 +63,11 @@ class CourseInfoTab(CourseTab):
@classmethod
@classmethod
def
is_enabled
(
cls
,
course
,
user
=
None
):
def
is_enabled
(
cls
,
course
,
user
=
None
):
return
True
"""
The "Home" tab is not shown for the new unified course experience.
"""
request
=
RequestCache
.
get_current_request
()
return
not
waffle
.
flag_is_active
(
request
,
UNIFIED_COURSE_EXPERIENCE_FLAG
)
class
SyllabusTab
(
EnrolledTab
):
class
SyllabusTab
(
EnrolledTab
):
...
...
lms/djangoapps/courseware/tests/test_course_info.py
View file @
2167584e
...
@@ -367,7 +367,7 @@ class SelfPacedCourseInfoTestCase(LoginEnrollmentTestCase, SharedModuleStoreTest
...
@@ -367,7 +367,7 @@ class SelfPacedCourseInfoTestCase(LoginEnrollmentTestCase, SharedModuleStoreTest
self
.
assertEqual
(
resp
.
status_code
,
200
)
self
.
assertEqual
(
resp
.
status_code
,
200
)
def
test_num_queries_instructor_paced
(
self
):
def
test_num_queries_instructor_paced
(
self
):
self
.
fetch_course_info_with_queries
(
self
.
instructor_paced_course
,
18
,
4
)
self
.
fetch_course_info_with_queries
(
self
.
instructor_paced_course
,
20
,
4
)
def
test_num_queries_self_paced
(
self
):
def
test_num_queries_self_paced
(
self
):
self
.
fetch_course_info_with_queries
(
self
.
self_paced_course
,
18
,
4
)
self
.
fetch_course_info_with_queries
(
self
.
self_paced_course
,
20
,
4
)
lms/djangoapps/courseware/tests/test_tabs.py
View file @
2167584e
...
@@ -2,6 +2,8 @@
...
@@ -2,6 +2,8 @@
Test cases for tabs.
Test cases for tabs.
"""
"""
import
waffle
from
django.core.urlresolvers
import
reverse
from
django.core.urlresolvers
import
reverse
from
django.http
import
Http404
from
django.http
import
Http404
from
mock
import
MagicMock
,
Mock
,
patch
from
mock
import
MagicMock
,
Mock
,
patch
...
@@ -16,6 +18,7 @@ from courseware.tests.helpers import LoginEnrollmentTestCase
...
@@ -16,6 +18,7 @@ from courseware.tests.helpers import LoginEnrollmentTestCase
from
courseware.tests.factories
import
InstructorFactory
,
StaffFactory
from
courseware.tests.factories
import
InstructorFactory
,
StaffFactory
from
courseware.views.views
import
get_static_tab_fragment
,
StaticCourseTabView
from
courseware.views.views
import
get_static_tab_fragment
,
StaticCourseTabView
from
openedx.core.djangolib.testing.utils
import
get_mock_request
from
openedx.core.djangolib.testing.utils
import
get_mock_request
from
openedx.features.course_experience
import
UNIFIED_COURSE_EXPERIENCE_FLAG
from
student.models
import
CourseEnrollment
from
student.models
import
CourseEnrollment
from
student.tests.factories
import
UserFactory
from
student.tests.factories
import
UserFactory
from
util.milestones_helpers
import
(
from
util.milestones_helpers
import
(
...
@@ -767,6 +770,26 @@ class StaticTabTestCase(TabTestCase):
...
@@ -767,6 +770,26 @@ class StaticTabTestCase(TabTestCase):
@attr
(
shard
=
1
)
@attr
(
shard
=
1
)
class
CourseInfoTabTestCase
(
TabTestCase
):
"""Test cases for the course info tab."""
def
setUp
(
self
):
self
.
user
=
self
.
create_mock_user
()
self
.
request
=
get_mock_request
(
self
.
user
)
def
test_default_tab
(
self
):
# Verify that the course info tab is the first tab
tabs
=
get_course_tab_list
(
self
.
request
,
self
.
course
)
self
.
assertEqual
(
tabs
[
0
]
.
type
,
'course_info'
)
@patch
(
'waffle.flag_is_active'
)
def
test_default_tab_for_new_course_experience
(
self
,
patched_flag_is_active
):
# Verify that the unified course experience hides the course info tab
patched_flag_is_active
.
return_value
=
True
tabs
=
get_course_tab_list
(
self
.
request
,
self
.
course
)
self
.
assertEqual
(
tabs
[
0
]
.
type
,
'courseware'
)
@attr
(
shard
=
1
)
class
DiscussionLinkTestCase
(
TabTestCase
):
class
DiscussionLinkTestCase
(
TabTestCase
):
"""Test cases for discussion link tab."""
"""Test cases for discussion link tab."""
...
...
lms/djangoapps/courseware/tests/test_views.py
View file @
2167584e
...
@@ -206,8 +206,8 @@ class IndexQueryTestCase(ModuleStoreTestCase):
...
@@ -206,8 +206,8 @@ class IndexQueryTestCase(ModuleStoreTestCase):
NUM_PROBLEMS
=
20
NUM_PROBLEMS
=
20
@ddt.data
(
@ddt.data
(
(
ModuleStoreEnum
.
Type
.
mongo
,
10
,
14
1
),
(
ModuleStoreEnum
.
Type
.
mongo
,
10
,
14
2
),
(
ModuleStoreEnum
.
Type
.
split
,
4
,
14
1
),
(
ModuleStoreEnum
.
Type
.
split
,
4
,
14
2
),
)
)
@ddt.unpack
@ddt.unpack
def
test_index_query_counts
(
self
,
store_type
,
expected_mongo_query_count
,
expected_mysql_query_count
):
def
test_index_query_counts
(
self
,
store_type
,
expected_mongo_query_count
,
expected_mysql_query_count
):
...
@@ -1408,12 +1408,12 @@ class ProgressPageTests(ModuleStoreTestCase):
...
@@ -1408,12 +1408,12 @@ class ProgressPageTests(ModuleStoreTestCase):
"""Test that query counts remain the same for self-paced and instructor-paced courses."""
"""Test that query counts remain the same for self-paced and instructor-paced courses."""
SelfPacedConfiguration
(
enabled
=
self_paced_enabled
)
.
save
()
SelfPacedConfiguration
(
enabled
=
self_paced_enabled
)
.
save
()
self
.
setup_course
(
self_paced
=
self_paced
)
self
.
setup_course
(
self_paced
=
self_paced
)
with
self
.
assertNumQueries
(
39
),
check_mongo_calls
(
1
):
with
self
.
assertNumQueries
(
40
),
check_mongo_calls
(
1
):
self
.
_get_progress_page
()
self
.
_get_progress_page
()
@ddt.data
(
@ddt.data
(
(
False
,
39
,
25
),
(
False
,
40
,
26
),
(
True
,
3
2
,
21
)
(
True
,
3
3
,
22
)
)
)
@ddt.unpack
@ddt.unpack
def
test_progress_queries
(
self
,
enable_waffle
,
initial
,
subsequent
):
def
test_progress_queries
(
self
,
enable_waffle
,
initial
,
subsequent
):
...
...
lms/djangoapps/courseware/views/views.py
View file @
2167584e
...
@@ -91,11 +91,15 @@ from openedx.core.djangoapps.programs.utils import ProgramMarketingDataExtender
...
@@ -91,11 +91,15 @@ from openedx.core.djangoapps.programs.utils import ProgramMarketingDataExtender
from
openedx.core.djangoapps.site_configuration
import
helpers
as
configuration_helpers
from
openedx.core.djangoapps.site_configuration
import
helpers
as
configuration_helpers
from
openedx.core.djangoapps.self_paced.models
import
SelfPacedConfiguration
from
openedx.core.djangoapps.self_paced.models
import
SelfPacedConfiguration
from
openedx.core.djangoapps.monitoring_utils
import
set_custom_metrics_for_course_key
from
openedx.core.djangoapps.monitoring_utils
import
set_custom_metrics_for_course_key
from
openedx.features.course_experience
import
(
course_home_url_name
,
UNIFIED_COURSE_EXPERIENCE_FLAG
,
UNIFIED_COURSE_VIEW_FLAG
,
)
from
openedx.features.enterprise_support.api
import
data_sharing_consent_required
from
openedx.features.enterprise_support.api
import
data_sharing_consent_required
from
shoppingcart.models
import
CourseRegistrationCode
from
shoppingcart.models
import
CourseRegistrationCode
from
shoppingcart.utils
import
is_shopping_cart_enabled
from
shoppingcart.utils
import
is_shopping_cart_enabled
from
student.models
import
UserTestGroup
,
CourseEnrollment
from
student.models
import
UserTestGroup
,
CourseEnrollment
from
student.roles
import
GlobalStaff
from
survey.utils
import
must_answer_survey
from
survey.utils
import
must_answer_survey
from
util.cache
import
cache
,
cache_if_anonymous
from
util.cache
import
cache
,
cache_if_anonymous
from
util.date_utils
import
strftime_localized
from
util.date_utils
import
strftime_localized
...
@@ -226,7 +230,7 @@ def jump_to(request, course_id, location):
...
@@ -226,7 +230,7 @@ def jump_to(request, course_id, location):
except
InvalidKeyError
:
except
InvalidKeyError
:
raise
Http404
(
u"Invalid course_key or usage_key"
)
raise
Http404
(
u"Invalid course_key or usage_key"
)
try
:
try
:
unified_course_view
=
waffle
.
flag_is_active
(
request
,
'unified_course_view'
)
unified_course_view
=
waffle
.
flag_is_active
(
request
,
UNIFIED_COURSE_VIEW_FLAG
)
redirect_url
=
get_redirect_url
(
course_key
,
usage_key
,
unified_course_view
=
unified_course_view
)
redirect_url
=
get_redirect_url
(
course_key
,
usage_key
,
unified_course_view
=
unified_course_view
)
except
ItemNotFoundError
:
except
ItemNotFoundError
:
raise
Http404
(
u"No data at this location: {0}"
.
format
(
usage_key
))
raise
Http404
(
u"No data at this location: {0}"
.
format
(
usage_key
))
...
@@ -245,6 +249,10 @@ def course_info(request, course_id):
...
@@ -245,6 +249,10 @@ def course_info(request, course_id):
Assumes the course_id is in a valid format.
Assumes the course_id is in a valid format.
"""
"""
# If the unified course experience is enabled, redirect to the "Course" tab
if
waffle
.
flag_is_active
(
request
,
UNIFIED_COURSE_EXPERIENCE_FLAG
):
return
redirect
(
reverse
(
course_home_url_name
(
request
),
args
=
[
course_id
]))
course_key
=
CourseKey
.
from_string
(
course_id
)
course_key
=
CourseKey
.
from_string
(
course_id
)
with
modulestore
()
.
bulk_operations
(
course_key
):
with
modulestore
()
.
bulk_operations
(
course_key
):
course
=
get_course_by_id
(
course_key
,
depth
=
2
)
course
=
get_course_by_id
(
course_key
,
depth
=
2
)
...
@@ -636,7 +644,7 @@ def course_about(request, course_id):
...
@@ -636,7 +644,7 @@ def course_about(request, course_id):
modes
=
CourseMode
.
modes_for_course_dict
(
course_key
)
modes
=
CourseMode
.
modes_for_course_dict
(
course_key
)
if
configuration_helpers
.
get_value
(
'ENABLE_MKTG_SITE'
,
settings
.
FEATURES
.
get
(
'ENABLE_MKTG_SITE'
,
False
)):
if
configuration_helpers
.
get_value
(
'ENABLE_MKTG_SITE'
,
settings
.
FEATURES
.
get
(
'ENABLE_MKTG_SITE'
,
False
)):
return
redirect
(
reverse
(
'info'
,
args
=
[
course
.
id
.
to_deprecated_string
(
)]))
return
redirect
(
reverse
(
course_home_url_name
(
request
),
args
=
[
unicode
(
course
.
id
)]))
registered
=
registered_for_course
(
course
,
request
.
user
)
registered
=
registered_for_course
(
course
,
request
.
user
)
...
@@ -644,7 +652,7 @@ def course_about(request, course_id):
...
@@ -644,7 +652,7 @@ def course_about(request, course_id):
studio_url
=
get_studio_url
(
course
,
'settings/details'
)
studio_url
=
get_studio_url
(
course
,
'settings/details'
)
if
has_access
(
request
.
user
,
'load'
,
course
):
if
has_access
(
request
.
user
,
'load'
,
course
):
course_target
=
reverse
(
'info'
,
args
=
[
course
.
id
.
to_deprecated_string
()])
course_target
=
reverse
(
course_home_url_name
(
request
)
,
args
=
[
course
.
id
.
to_deprecated_string
()])
else
:
else
:
course_target
=
reverse
(
'about_course'
,
args
=
[
course
.
id
.
to_deprecated_string
()])
course_target
=
reverse
(
'about_course'
,
args
=
[
course
.
id
.
to_deprecated_string
()])
...
@@ -1208,7 +1216,7 @@ def course_survey(request, course_id):
...
@@ -1208,7 +1216,7 @@ def course_survey(request, course_id):
course_key
=
CourseKey
.
from_string
(
course_id
)
course_key
=
CourseKey
.
from_string
(
course_id
)
course
=
get_course_with_access
(
request
.
user
,
'load'
,
course_key
)
course
=
get_course_with_access
(
request
.
user
,
'load'
,
course_key
)
redirect_url
=
reverse
(
'info'
,
args
=
[
course_id
])
redirect_url
=
reverse
(
course_home_url_name
(
request
)
,
args
=
[
course_id
])
# if there is no Survey associated with this course,
# if there is no Survey associated with this course,
# then redirect to the course instead
# then redirect to the course instead
...
...
lms/templates/dashboard/_dashboard_course_listing.html
View file @
2167584e
...
@@ -10,6 +10,7 @@ from course_modes.models import CourseMode
...
@@ -10,6 +10,7 @@ from course_modes.models import CourseMode
from
course_modes
.
helpers
import
enrollment_mode_display
from
course_modes
.
helpers
import
enrollment_mode_display
from
openedx
.
core
.
djangolib
.
js_utils
import
dump_js_escaped_json
,
js_escaped_string
from
openedx
.
core
.
djangolib
.
js_utils
import
dump_js_escaped_json
,
js_escaped_string
from
openedx
.
core
.
djangolib
.
markup
import
HTML
,
Text
from
openedx
.
core
.
djangolib
.
markup
import
HTML
,
Text
from
openedx
.
features
.
course_experience
import
course_home_url_name
from
student
.
helpers
import
(
from
student
.
helpers
import
(
VERIFY_STATUS_NEED_TO_VERIFY
,
VERIFY_STATUS_NEED_TO_VERIFY
,
VERIFY_STATUS_SUBMITTED
,
VERIFY_STATUS_SUBMITTED
,
...
@@ -55,7 +56,7 @@ from util.course import get_link_for_about_page, get_encoded_course_sharing_utm_
...
@@ -55,7 +56,7 @@ from util.course import get_link_for_about_page, get_encoded_course_sharing_utm_
% endif
% endif
<div
class=
"course-container"
>
<div
class=
"course-container"
>
<article
class=
"course${mode_class}"
>
<article
class=
"course${mode_class}"
>
<
%
course_target =
reverse(
'info'
,
args=
[unicode(course_overview.id)])
%
>
<
%
course_target =
reverse(
course_home_url_name()
,
args=
[unicode(course_overview.id)])
%
>
<section
class=
"details"
aria-labelledby=
"details-heading-${course_overview.number}"
>
<section
class=
"details"
aria-labelledby=
"details-heading-${course_overview.number}"
>
<h2
class=
"hd hd-2 sr"
id=
"details-heading-${course_overview.number}"
>
${_('Course details')}
</h2>
<h2
class=
"hd hd-2 sr"
id=
"details-heading-${course_overview.number}"
>
${_('Course details')}
</h2>
<div
class=
"wrapper-course-image"
aria-hidden=
"true"
>
<div
class=
"wrapper-course-image"
aria-hidden=
"true"
>
...
...
lms/templates/shoppingcart/registration_code_receipt.html
View file @
2167584e
...
@@ -2,7 +2,9 @@
...
@@ -2,7 +2,9 @@
from
django
.
utils
.
translation
import
ugettext
as
_
from
django
.
utils
.
translation
import
ugettext
as
_
from
django
.
core
.
urlresolvers
import
reverse
from
django
.
core
.
urlresolvers
import
reverse
from
openedx
.
core
.
lib
.
courses
import
course_image_url
from
openedx
.
core
.
lib
.
courses
import
course_image_url
from
openedx
.
features
.
course_experience
import
course_home_url_name
%
>
%
>
<
%
inherit
file=
"../main.html"
/>
<
%
inherit
file=
"../main.html"
/>
<
%
namespace
name=
'static'
file=
'/static_content.html'
/>
<
%
namespace
name=
'static'
file=
'/static_content.html'
/>
<
%
block
name=
"pagetitle"
>
${_("Confirm Enrollment")}
</
%
block>
<
%
block
name=
"pagetitle"
>
${_("Confirm Enrollment")}
</
%
block>
...
@@ -73,7 +75,7 @@ from openedx.core.lib.courses import course_image_url
...
@@ -73,7 +75,7 @@ from openedx.core.lib.courses import course_image_url
</div>
</div>
% if not reg_code_already_redeemed:
% if not reg_code_already_redeemed:
%if redemption_success:
%if redemption_success:
<
%
course_url =
reverse(
'info'
,
args=
[course.id.to_deprecated_string()])
%
>
<
%
course_url =
reverse(
course_home_url_name()
,
args=
[course.id.to_deprecated_string()])
%
>
<a
href=
"${course_url}"
class=
"link-button course-link-bg-color"
>
${_("View Course")}
<span
class=
"icon fa fa-caret-right"
aria-hidden=
"true"
></span></a>
<a
href=
"${course_url}"
class=
"link-button course-link-bg-color"
>
${_("View Course")}
<span
class=
"icon fa fa-caret-right"
aria-hidden=
"true"
></span></a>
%elif not registered_for_course:
%elif not registered_for_course:
<form
method=
"post"
>
<form
method=
"post"
>
...
...
lms/tests.py
View file @
2167584e
...
@@ -8,6 +8,7 @@ from django.core.urlresolvers import reverse
...
@@ -8,6 +8,7 @@ from django.core.urlresolvers import reverse
from
edxmako
import
add_lookup
,
LOOKUP
from
edxmako
import
add_lookup
,
LOOKUP
from
lms
import
startup
from
lms
import
startup
from
openedx.features.course_experience
import
course_home_url_name
from
xmodule.modulestore.tests.factories
import
CourseFactory
from
xmodule.modulestore.tests.factories
import
CourseFactory
from
xmodule.modulestore.tests.django_utils
import
ModuleStoreTestCase
from
xmodule.modulestore.tests.django_utils
import
ModuleStoreTestCase
...
@@ -54,6 +55,6 @@ class HelpModalTests(ModuleStoreTestCase):
...
@@ -54,6 +55,6 @@ class HelpModalTests(ModuleStoreTestCase):
Simple test to make sure that you don't get a 500 error when the modal
Simple test to make sure that you don't get a 500 error when the modal
is enabled.
is enabled.
"""
"""
url
=
reverse
(
'info'
,
args
=
[
self
.
course
.
id
.
to_deprecated_string
()])
url
=
reverse
(
course_home_url_name
()
,
args
=
[
self
.
course
.
id
.
to_deprecated_string
()])
resp
=
self
.
client
.
get
(
url
)
resp
=
self
.
client
.
get
(
url
)
self
.
assertEqual
(
resp
.
status_code
,
200
)
self
.
assertEqual
(
resp
.
status_code
,
200
)
openedx/features/course_bookmarks/views/course_bookmarks.py
View file @
2167584e
...
@@ -13,9 +13,9 @@ from django.views.decorators.csrf import ensure_csrf_cookie
...
@@ -13,9 +13,9 @@ from django.views.decorators.csrf import ensure_csrf_cookie
from
django.views.generic
import
View
from
django.views.generic
import
View
from
courseware.courses
import
get_course_with_access
from
courseware.courses
import
get_course_with_access
from
lms.djangoapps.courseware.tabs
import
CoursewareTab
from
opaque_keys.edx.keys
import
CourseKey
from
opaque_keys.edx.keys
import
CourseKey
from
openedx.core.djangoapps.plugin_api.views
import
EdxFragmentView
from
openedx.core.djangoapps.plugin_api.views
import
EdxFragmentView
from
openedx.features.course_experience
import
defaut_course_url_name
from
util.views
import
ensure_valid_course_key
from
util.views
import
ensure_valid_course_key
from
web_fragments.fragment
import
Fragment
from
web_fragments.fragment
import
Fragment
...
@@ -38,7 +38,7 @@ class CourseBookmarksView(View):
...
@@ -38,7 +38,7 @@ class CourseBookmarksView(View):
"""
"""
course_key
=
CourseKey
.
from_string
(
course_id
)
course_key
=
CourseKey
.
from_string
(
course_id
)
course
=
get_course_with_access
(
request
.
user
,
'load'
,
course_key
,
check_if_enrolled
=
True
)
course
=
get_course_with_access
(
request
.
user
,
'load'
,
course_key
,
check_if_enrolled
=
True
)
course_url_name
=
CoursewareTab
.
main
_course_url_name
(
request
)
course_url_name
=
defaut
_course_url_name
(
request
)
course_url
=
reverse
(
course_url_name
,
kwargs
=
{
'course_id'
:
unicode
(
course
.
id
)})
course_url
=
reverse
(
course_url_name
,
kwargs
=
{
'course_id'
:
unicode
(
course
.
id
)})
# Render the bookmarks list as a fragment
# Render the bookmarks list as a fragment
...
...
openedx/features/course_experience/__init__.py
View file @
2167584e
# Unified course experience settings.
"""
Unified course experience settings and helper methods.
"""
import
waffle
from
request_cache.middleware
import
RequestCache
# Waffle flag to enable a single unified "Course" tab.
# Waffle flag to enable a single unified "Course" tab.
UNIFIED_COURSE_EXPERIENCE_FLAG
=
'unified_course_experience'
UNIFIED_COURSE_EXPERIENCE_FLAG
=
'unified_course_experience'
...
@@ -6,3 +12,23 @@ UNIFIED_COURSE_EXPERIENCE_FLAG = 'unified_course_experience'
...
@@ -6,3 +12,23 @@ UNIFIED_COURSE_EXPERIENCE_FLAG = 'unified_course_experience'
# Waffle flag to enable the full screen course content view
# Waffle flag to enable the full screen course content view
# along with a unified course home page.
# along with a unified course home page.
UNIFIED_COURSE_VIEW_FLAG
=
'unified_course_view'
UNIFIED_COURSE_VIEW_FLAG
=
'unified_course_view'
def
defaut_course_url_name
(
request
=
None
):
"""
Returns the default course URL name for the current user.
"""
if
waffle
.
flag_is_active
(
request
or
RequestCache
.
get_current_request
(),
UNIFIED_COURSE_VIEW_FLAG
):
return
'openedx.course_experience.course_home'
else
:
return
'courseware'
def
course_home_url_name
(
request
=
None
):
"""
Returns the course home page's URL name for the current user.
"""
if
waffle
.
flag_is_active
(
request
or
RequestCache
.
get_current_request
(),
UNIFIED_COURSE_EXPERIENCE_FLAG
):
return
'openedx.course_experience.course_home'
else
:
return
'info'
openedx/features/course_experience/views/course_updates.py
View file @
2167584e
...
@@ -10,10 +10,10 @@ from django.utils.decorators import method_decorator
...
@@ -10,10 +10,10 @@ from django.utils.decorators import method_decorator
from
django.views.decorators.cache
import
cache_control
from
django.views.decorators.cache
import
cache_control
from
courseware.courses
import
get_course_info_section
,
get_course_with_access
from
courseware.courses
import
get_course_info_section
,
get_course_with_access
from
lms.djangoapps.courseware.tabs
import
CoursewareTab
from
lms.djangoapps.courseware.views.views
import
CourseTabView
from
lms.djangoapps.courseware.views.views
import
CourseTabView
from
opaque_keys.edx.keys
import
CourseKey
from
opaque_keys.edx.keys
import
CourseKey
from
openedx.core.djangoapps.plugin_api.views
import
EdxFragmentView
from
openedx.core.djangoapps.plugin_api.views
import
EdxFragmentView
from
openedx.features.course_experience
import
defaut_course_url_name
from
web_fragments.fragment
import
Fragment
from
web_fragments.fragment
import
Fragment
...
@@ -45,7 +45,7 @@ class CourseUpdatesFragmentView(EdxFragmentView):
...
@@ -45,7 +45,7 @@ class CourseUpdatesFragmentView(EdxFragmentView):
"""
"""
course_key
=
CourseKey
.
from_string
(
course_id
)
course_key
=
CourseKey
.
from_string
(
course_id
)
course
=
get_course_with_access
(
request
.
user
,
'load'
,
course_key
,
check_if_enrolled
=
True
)
course
=
get_course_with_access
(
request
.
user
,
'load'
,
course_key
,
check_if_enrolled
=
True
)
course_url_name
=
CoursewareTab
.
main
_course_url_name
(
request
)
course_url_name
=
defaut
_course_url_name
(
request
)
course_url
=
reverse
(
course_url_name
,
kwargs
=
{
'course_id'
:
unicode
(
course
.
id
)})
course_url
=
reverse
(
course_url_name
,
kwargs
=
{
'course_id'
:
unicode
(
course
.
id
)})
# Fetch the updates as HTML
# Fetch the updates as HTML
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment