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
d58f2ac2
Commit
d58f2ac2
authored
Jul 17, 2017
by
Andy Armstrong
Committed by
GitHub
Jul 17, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #15580 from edx/andya/course-home-messaging
Show page banner for anonymous and unenrolled users
parents
4370142a
3e786ec6
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
90 additions
and
26 deletions
+90
-26
lms/djangoapps/courseware/views/views.py
+55
-14
lms/static/sass/elements/_banners.scss
+7
-0
lms/templates/page_banner.html
+6
-2
openedx/features/course_experience/tests/views/test_course_home.py
+22
-10
No files found.
lms/djangoapps/courseware/views/views.py
View file @
d58f2ac2
...
...
@@ -17,12 +17,10 @@ from certificates.models import CertificateStatuses
from
commerce.utils
import
EcommerceService
from
course_modes.models
import
CourseMode
from
courseware.access
import
has_access
,
has_ccx_coach_role
from
courseware.access_response
import
StartDateError
from
courseware.access_utils
import
in_preview_mode
,
check_course_open_for_learner
from
courseware.access_utils
import
check_course_open_for_learner
from
courseware.courses
import
(
can_self_enroll_in_course
,
get_course
,
get_course_by_id
,
get_course_overview_with_access
,
get_course_with_access
,
get_courses
,
...
...
@@ -49,6 +47,7 @@ from django.db.models import Q
from
django.http
import
Http404
,
HttpResponse
,
HttpResponseBadRequest
,
HttpResponseForbidden
,
QueryDict
from
django.shortcuts
import
redirect
from
django.utils.decorators
import
method_decorator
from
django.utils.http
import
urlquote_plus
from
django.utils.text
import
slugify
from
django.utils.timezone
import
UTC
from
django.utils.translation
import
ugettext
as
_
...
...
@@ -83,17 +82,17 @@ from openedx.core.djangoapps.plugin_api.views import EdxFragmentView
from
openedx.core.djangoapps.programs.utils
import
ProgramMarketingDataExtender
from
openedx.core.djangoapps.self_paced.models
import
SelfPacedConfiguration
from
openedx.core.djangoapps.site_configuration
import
helpers
as
configuration_helpers
from
openedx.core.djangoapps.util.user_messages
import
register_warning_message
from
openedx.core.djangolib.markup
import
HTML
,
Text
from
openedx.features.course_experience
import
UNIFIED_COURSE_TAB_FLAG
,
course_home_url_name
from
openedx.features.course_experience.course_tools
import
CourseToolsPluginManager
from
openedx.features.course_experience.views.course_dates
import
CourseDatesFragmentView
from
openedx.features.enterprise_support.api
import
data_sharing_consent_required
from
pytz
import
utc
from
rest_framework
import
status
from
shoppingcart.utils
import
is_shopping_cart_enabled
from
student.models
import
CourseEnrollment
,
UserTestGroup
from
survey.utils
import
must_answer_survey
from
util.cache
import
cache
,
cache_if_anonymous
from
util.date_utils
import
strftime_localized
from
util.db
import
outer_atomic
from
util.milestones_helpers
import
get_prerequisite_courses_display
from
util.views
import
_record_feedback_in_zendesk
,
ensure_valid_course_key
,
ensure_valid_usage_key
...
...
@@ -269,7 +268,7 @@ def course_info(request, course_id):
masquerade
,
user
=
setup_masquerade
(
request
,
course_key
,
staff_access
,
reset_masquerade_data
=
True
)
# LEARNER-612: CCX redirect handled by new Course Home (DONE)
#
TODO: LEARNER-1697: Transition banner messages to new Course Home.
#
LEARNER-1697: Transition banner messages to new Course Home (DONE)
# if user is not enrolled in a course then app will show enroll/get register link inside course info page.
user_is_enrolled
=
CourseEnrollment
.
is_enrolled
(
user
,
course
.
id
)
show_enroll_banner
=
request
.
user
.
is_authenticated
()
and
not
user_is_enrolled
...
...
@@ -296,13 +295,6 @@ def course_info(request, course_id):
if
course
.
bypass_home
and
is_from_dashboard
:
return
redirect
(
reverse
(
'courseware'
,
args
=
[
course_id
]))
# TODO: LEARNER-1697: Transition handling of enroll links in new Course Home.
# link to where the student should go to enroll in the course:
# about page if there is not marketing site, SITE_NAME if there is
url_to_enroll
=
reverse
(
course_about
,
args
=
[
course_id
])
if
settings
.
FEATURES
.
get
(
'ENABLE_MKTG_SITE'
):
url_to_enroll
=
marketing_link
(
'COURSES'
)
# Construct the dates fragment
dates_fragment
=
None
...
...
@@ -334,7 +326,7 @@ def course_info(request, course_id):
'show_enroll_banner'
:
show_enroll_banner
,
'user_is_enrolled'
:
user_is_enrolled
,
'dates_fragment'
:
dates_fragment
,
'url_to_enroll'
:
url_to_enroll
,
'url_to_enroll'
:
CourseTabView
.
url_to_enroll
(
course_key
)
,
'course_tools'
:
course_tools
,
# TODO: (Experimental Code). See https://openedx.atlassian.net/wiki/display/RET/2.+In-course+Verification+Prompts
...
...
@@ -391,6 +383,10 @@ class StaticCourseTabView(EdxFragmentView):
tab
=
CourseTabList
.
get_tab_by_slug
(
course
.
tabs
,
tab_slug
)
if
tab
is
None
:
raise
Http404
# Show warnings if the user has limited access
CourseTabView
.
register_user_access_warning_messages
(
request
,
course_key
)
return
super
(
StaticCourseTabView
,
self
)
.
get
(
request
,
course
=
course
,
tab
=
tab
,
**
kwargs
)
def
render_to_fragment
(
self
,
request
,
course
=
None
,
tab
=
None
,
**
kwargs
):
...
...
@@ -431,6 +427,9 @@ class CourseTabView(EdxFragmentView):
# Verify that the user has access to the course
check_access_to_course
(
request
,
course
)
# Show warnings if the user has limited access
self
.
register_user_access_warning_messages
(
request
,
course_key
)
# Render the page
tab
=
CourseTabList
.
get_tab_by_type
(
course
.
tabs
,
tab_type
)
page_context
=
self
.
create_page_context
(
request
,
course
=
course
,
tab
=
tab
,
**
kwargs
)
...
...
@@ -440,6 +439,48 @@ class CourseTabView(EdxFragmentView):
return
CourseTabView
.
handle_exceptions
(
request
,
course
,
exception
)
@staticmethod
def
url_to_enroll
(
course_key
):
"""
Returns the URL to use to enroll in the specified course.
"""
url_to_enroll
=
reverse
(
'about_course'
,
args
=
[
unicode
(
course_key
)])
if
settings
.
FEATURES
.
get
(
'ENABLE_MKTG_SITE'
):
url_to_enroll
=
marketing_link
(
'COURSES'
)
return
url_to_enroll
@staticmethod
def
register_user_access_warning_messages
(
request
,
course_key
):
"""
Register messages to be shown to the user if they have limited access.
"""
is_enrolled
=
CourseEnrollment
.
is_enrolled
(
request
.
user
,
course_key
)
is_staff
=
has_access
(
request
.
user
,
'staff'
,
course_key
)
if
request
.
user
.
is_anonymous
():
register_warning_message
(
request
,
Text
(
_
(
"To see course content, {sign_in_link} or {register_link}."
))
.
format
(
sign_in_link
=
HTML
(
'<a href="/login?next={current_url}">{sign_in_label}</a>'
)
.
format
(
sign_in_label
=
_
(
"sign in"
),
current_url
=
urlquote_plus
(
request
.
path
),
),
register_link
=
HTML
(
'<a href="/register?next={current_url}">{register_label}</a>'
)
.
format
(
register_label
=
_
(
"register"
),
current_url
=
urlquote_plus
(
request
.
path
),
),
)
)
elif
not
is_enrolled
and
not
is_staff
:
register_warning_message
(
request
,
Text
(
_
(
'You must be enrolled in the course to see course content. {enroll_link}.'
))
.
format
(
enroll_link
=
HTML
(
'<a href="{url_to_enroll}">{enroll_link_label}</a>'
)
.
format
(
url_to_enroll
=
CourseTabView
.
url_to_enroll
(
course_key
),
enroll_link_label
=
_
(
"Enroll now"
),
)
)
)
@staticmethod
def
handle_exceptions
(
request
,
course
,
exception
):
"""
Handle exceptions raised when rendering a view.
...
...
lms/static/sass/elements/_banners.scss
View file @
d58f2ac2
...
...
@@ -51,6 +51,13 @@ $full-width-banner-margin: 20px;
.user-messages
{
padding-top
:
$baseline
;
// Hack: force override the global important rule
// that courseware links don't have an underline.
a
:hover
{
color
:
$link-color
;
text-decoration
:
underline
!
important
;
}
}
.alert
{
...
...
lms/templates/page_banner.html
View file @
d58f2ac2
...
...
@@ -10,10 +10,14 @@ from openedx.core.djangolib.markup import HTML
from
openedx
.
core
.
djangoapps
.
util
.
user_messages
import
user_messages
%
>
% if user_messages:
<
%
banner_messages =
list(user_messages(request))
%
>
% if banner_messages:
<div
class=
"page-banner"
>
<div
class=
"user-messages"
>
% for message in
user_messages(request)
:
% for message in
banner_messages
:
<div
class=
"alert ${message.css_class}"
role=
"alert"
>
<span
class=
"icon icon-alert fa ${message.icon_class}"
aria-hidden=
"true"
></span>
${HTML(message.message_html)}
...
...
openedx/features/course_experience/tests/views/test_course_home.py
View file @
d58f2ac2
...
...
@@ -186,12 +186,13 @@ class TestCourseHomePageAccess(CourseHomePageTestCase):
@override_waffle_flag
(
UNIFIED_COURSE_TAB_FLAG
,
active
=
True
)
@override_waffle_flag
(
SHOW_REVIEWS_TOOL_FLAG
,
active
=
True
)
@ddt.data
(
CourseUserType
.
ANONYMOUS
,
CourseUserType
.
ENROLLED
,
CourseUserType
.
UNENROLLED
,
CourseUserType
.
UNENROLLED_STAFF
,
[
CourseUserType
.
ANONYMOUS
,
'To see course content'
]
,
[
CourseUserType
.
ENROLLED
,
None
]
,
[
CourseUserType
.
UNENROLLED
,
'You must be enrolled in the course to see course content.'
]
,
[
CourseUserType
.
UNENROLLED_STAFF
,
None
]
,
)
def
test_home_page
(
self
,
user_type
):
@ddt.unpack
def
test_home_page
(
self
,
user_type
,
expected_message
):
self
.
user
=
self
.
create_user_for_course
(
self
.
course
,
user_type
)
# Render the course home page
...
...
@@ -212,15 +213,21 @@ class TestCourseHomePageAccess(CourseHomePageTestCase):
self
.
assertContains
(
response
,
'Learn About Verified Certificate'
,
count
=
expected_count
)
self
.
assertContains
(
response
,
TEST_WELCOME_MESSAGE
,
count
=
expected_count
)
# Verify that the expected message is shown to the user
self
.
assertContains
(
response
,
'<div class="user-messages">'
,
count
=
1
if
expected_message
else
0
)
if
expected_message
:
self
.
assertContains
(
response
,
expected_message
)
@override_waffle_flag
(
UNIFIED_COURSE_TAB_FLAG
,
active
=
False
)
@override_waffle_flag
(
SHOW_REVIEWS_TOOL_FLAG
,
active
=
True
)
@ddt.data
(
CourseUserType
.
ANONYMOUS
,
CourseUserType
.
ENROLLED
,
CourseUserType
.
UNENROLLED
,
CourseUserType
.
UNENROLLED_STAFF
,
[
CourseUserType
.
ANONYMOUS
,
'To see course content'
]
,
[
CourseUserType
.
ENROLLED
,
None
]
,
[
CourseUserType
.
UNENROLLED
,
'You must be enrolled in the course to see course content.'
]
,
[
CourseUserType
.
UNENROLLED_STAFF
,
None
]
,
)
def
test_home_page_not_unified
(
self
,
user_type
):
@ddt.unpack
def
test_home_page_not_unified
(
self
,
user_type
,
expected_message
):
"""
Verifies the course home tab when not unified.
"""
...
...
@@ -246,6 +253,11 @@ class TestCourseHomePageAccess(CourseHomePageTestCase):
self
.
assertContains
(
response
,
'Start Course'
,
count
=
expected_count
)
self
.
assertContains
(
response
,
'Learn About Verified Certificate'
,
count
=
expected_count
)
# Verify that the expected message is shown to the user
self
.
assertContains
(
response
,
'<div class="user-messages">'
,
count
=
1
if
expected_message
else
0
)
if
expected_message
:
self
.
assertContains
(
response
,
expected_message
)
def
test_sign_in_button
(
self
):
"""
Verify that the sign in button will return to this page.
...
...
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