Merge pull request #19258 from edx/revert/paulo/anonymous-views
Revert "Merge pull request #18720 from open-craft/paulo/anonymous-views"
This commit is contained in:
@@ -43,10 +43,6 @@ LATEST_UPDATE_FLAG = CourseWaffleFlag(WAFFLE_FLAG_NAMESPACE, 'latest_update')
|
||||
# Waffle flag to enable the use of Bootstrap for course experience pages
|
||||
USE_BOOTSTRAP_FLAG = CourseWaffleFlag(WAFFLE_FLAG_NAMESPACE, 'use_bootstrap', flag_undefined_default=True)
|
||||
|
||||
# Waffle flag to enable anonymous access to a course
|
||||
SEO_WAFFLE_FLAG_NAMESPACE = WaffleFlagNamespace(name='seo')
|
||||
COURSE_ENABLE_UNENROLLED_ACCESS_FLAG = CourseWaffleFlag(SEO_WAFFLE_FLAG_NAMESPACE, 'enable_anonymous_courseware_access')
|
||||
|
||||
|
||||
def course_home_page_title(course): # pylint: disable=unused-argument
|
||||
"""
|
||||
|
||||
@@ -51,7 +51,7 @@ course_sections = blocks.get('children')
|
||||
completed_prereqs = gated_content[subsection['id']]['completed_prereqs'] if gated_subsection else False
|
||||
subsection_is_auto_opened = subsection.get('resume_block') is True
|
||||
%>
|
||||
<li class="subsection accordion ${ 'current' if subsection.get('resume_block') else '' }">
|
||||
<li class="subsection accordion ${ 'current' if subsection['resume_block'] else '' }">
|
||||
% if gated_subsection and not completed_prereqs:
|
||||
<a href="${ subsection['lms_web_url'] }">
|
||||
<button class="subsection-text prerequisite-button"
|
||||
@@ -153,11 +153,7 @@ course_sections = blocks.get('children')
|
||||
% for vertical in subsection.get('children', []):
|
||||
<li class="vertical outline-item focusable">
|
||||
<a class="outline-item focusable"
|
||||
% if enable_links:
|
||||
href="${ vertical['lms_web_url'] }"
|
||||
% else:
|
||||
aria-disabled="true"
|
||||
% endif
|
||||
href="${ vertical['lms_web_url'] }"
|
||||
id="${ vertical['id'] }">
|
||||
<div class="vertical-details">
|
||||
<div class="vertical-title">
|
||||
|
||||
@@ -28,13 +28,11 @@ from openedx.features.course_duration_limits.config import CONTENT_TYPE_GATING_F
|
||||
from openedx.features.course_experience import (
|
||||
SHOW_REVIEWS_TOOL_FLAG,
|
||||
SHOW_UPGRADE_MSG_ON_COURSE_HOME,
|
||||
UNIFIED_COURSE_TAB_FLAG,
|
||||
COURSE_ENABLE_UNENROLLED_ACCESS_FLAG,
|
||||
UNIFIED_COURSE_TAB_FLAG
|
||||
)
|
||||
from student.models import CourseEnrollment
|
||||
from student.tests.factories import UserFactory
|
||||
from util.date_utils import strftime_localized
|
||||
from xmodule.course_module import COURSE_VISIBILITY_PRIVATE, COURSE_VISIBILITY_PUBLIC_OUTLINE, COURSE_VISIBILITY_PUBLIC
|
||||
from xmodule.modulestore import ModuleStoreEnum
|
||||
from xmodule.modulestore.tests.django_utils import CourseUserType, ModuleStoreTestCase, SharedModuleStoreTestCase
|
||||
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory, check_mongo_calls
|
||||
@@ -225,56 +223,37 @@ class TestCourseHomePageAccess(CourseHomePageTestCase):
|
||||
|
||||
@override_waffle_flag(SHOW_REVIEWS_TOOL_FLAG, active=True)
|
||||
@ddt.data(
|
||||
[False, COURSE_VISIBILITY_PRIVATE, CourseUserType.ANONYMOUS, True],
|
||||
[False, COURSE_VISIBILITY_PUBLIC_OUTLINE, CourseUserType.ANONYMOUS, True],
|
||||
[False, COURSE_VISIBILITY_PUBLIC, CourseUserType.ANONYMOUS, True],
|
||||
[False, COURSE_VISIBILITY_PRIVATE, CourseUserType.ENROLLED, False],
|
||||
[False, COURSE_VISIBILITY_PRIVATE, CourseUserType.UNENROLLED, True],
|
||||
[False, COURSE_VISIBILITY_PRIVATE, CourseUserType.UNENROLLED_STAFF, True],
|
||||
[True, COURSE_VISIBILITY_PRIVATE, CourseUserType.ANONYMOUS, True],
|
||||
[True, COURSE_VISIBILITY_PUBLIC_OUTLINE, CourseUserType.ANONYMOUS, True],
|
||||
[True, COURSE_VISIBILITY_PUBLIC, CourseUserType.ANONYMOUS, True],
|
||||
[True, COURSE_VISIBILITY_PRIVATE, CourseUserType.UNENROLLED, True],
|
||||
[True, COURSE_VISIBILITY_PUBLIC_OUTLINE, CourseUserType.UNENROLLED, True],
|
||||
[True, COURSE_VISIBILITY_PUBLIC, CourseUserType.UNENROLLED, True],
|
||||
[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, 'You must be enrolled in the course to see course content.'],
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_home_page(self, enable_unenrolled_access, course_visibility, user_type, expected_message):
|
||||
def test_home_page(self, user_type, expected_message):
|
||||
self.create_user_for_course(self.course, user_type)
|
||||
|
||||
# Render the course home page
|
||||
with mock.patch('xmodule.course_module.CourseDescriptor.course_visibility', course_visibility):
|
||||
# Test access with anonymous flag and course visibility
|
||||
with override_waffle_flag(COURSE_ENABLE_UNENROLLED_ACCESS_FLAG, enable_unenrolled_access):
|
||||
url = course_home_url(self.course)
|
||||
response = self.client.get(url)
|
||||
url = course_home_url(self.course)
|
||||
response = self.client.get(url)
|
||||
|
||||
# Verify that the course tools and dates are always shown
|
||||
self.assertContains(response, 'Course Tools')
|
||||
self.assertContains(response, 'Today is')
|
||||
|
||||
# Verify that start button, course sock, and welcome message
|
||||
# Verify that the outline, start button, course sock, and welcome message
|
||||
# are only shown to enrolled users.
|
||||
is_enrolled = user_type is CourseUserType.ENROLLED
|
||||
is_unenrolled_staff = user_type is CourseUserType.UNENROLLED_STAFF
|
||||
expected_welcome = 1 if (is_enrolled or is_unenrolled_staff) else 0
|
||||
self.assertContains(response, 'Start Course', count=expected_welcome)
|
||||
expected_count = 1 if (is_enrolled or is_unenrolled_staff) else 0
|
||||
self.assertContains(response, TEST_CHAPTER_NAME, count=expected_count)
|
||||
self.assertContains(response, 'Start Course', count=expected_count)
|
||||
self.assertContains(response, 'Learn About Verified Certificate', count=(1 if is_enrolled else 0))
|
||||
self.assertContains(response, TEST_WELCOME_MESSAGE, count=expected_welcome)
|
||||
|
||||
# Verify the outline is shown to enrolled users, unenrolled_staff and anonymous users if allowed
|
||||
is_public = course_visibility == COURSE_VISIBILITY_PUBLIC and enable_unenrolled_access
|
||||
is_public_outline = course_visibility == COURSE_VISIBILITY_PUBLIC_OUTLINE and enable_unenrolled_access
|
||||
expected_chapter = 1 if (is_public or is_public_outline) else expected_welcome
|
||||
self.assertContains(response, TEST_CHAPTER_NAME, count=expected_chapter)
|
||||
self.assertContains(response, TEST_WELCOME_MESSAGE, count=expected_count)
|
||||
|
||||
# Verify that the expected message is shown to the user
|
||||
self.assertContains(
|
||||
response, 'To see course content', count=1 if user_type is CourseUserType.ANONYMOUS else 0
|
||||
)
|
||||
self.assertContains(response, '<div class="user-messages">', count=1 if expected_message else 0)
|
||||
if expected_message:
|
||||
self.assertContains(response, 'You must be enrolled in the course to see course content.')
|
||||
self.assertContains(response, expected_message)
|
||||
|
||||
@override_waffle_flag(UNIFIED_COURSE_TAB_FLAG, active=False)
|
||||
@override_waffle_flag(SHOW_REVIEWS_TOOL_FLAG, active=True)
|
||||
|
||||
@@ -11,13 +11,11 @@ from xmodule.modulestore.django import modulestore
|
||||
|
||||
|
||||
@request_cached()
|
||||
def get_course_outline_block_tree(request, course_id, user=None):
|
||||
def get_course_outline_block_tree(request, course_id):
|
||||
"""
|
||||
Returns the root block of the course outline, with children as blocks.
|
||||
"""
|
||||
|
||||
assert user is None or user.is_authenticated
|
||||
|
||||
def populate_children(block, all_blocks):
|
||||
"""
|
||||
Replace each child id with the full block for the child.
|
||||
@@ -158,13 +156,13 @@ def get_course_outline_block_tree(request, course_id, user=None):
|
||||
course_outline_root_block = all_blocks['blocks'].get(all_blocks['root'], None)
|
||||
if course_outline_root_block:
|
||||
populate_children(course_outline_root_block, all_blocks['blocks'])
|
||||
if user:
|
||||
set_last_accessed_default(course_outline_root_block)
|
||||
mark_blocks_completed(
|
||||
block=course_outline_root_block,
|
||||
user=request.user,
|
||||
course_key=course_key
|
||||
)
|
||||
set_last_accessed_default(course_outline_root_block)
|
||||
|
||||
mark_blocks_completed(
|
||||
block=course_outline_root_block,
|
||||
user=request.user,
|
||||
course_key=course_key
|
||||
)
|
||||
return course_outline_root_block
|
||||
|
||||
|
||||
|
||||
@@ -28,11 +28,8 @@ from openedx.core.djangoapps.util.maintenance_banner import add_maintenance_bann
|
||||
from openedx.features.course_experience.course_tools import CourseToolsPluginManager
|
||||
from student.models import CourseEnrollment
|
||||
from util.views import ensure_valid_course_key
|
||||
from xmodule.course_module import COURSE_VISIBILITY_PUBLIC_OUTLINE, COURSE_VISIBILITY_PUBLIC
|
||||
|
||||
from .. import (
|
||||
LATEST_UPDATE_FLAG, SHOW_UPGRADE_MSG_ON_COURSE_HOME, USE_BOOTSTRAP_FLAG, COURSE_ENABLE_UNENROLLED_ACCESS_FLAG
|
||||
)
|
||||
from .. import LATEST_UPDATE_FLAG, SHOW_UPGRADE_MSG_ON_COURSE_HOME, USE_BOOTSTRAP_FLAG
|
||||
from ..utils import get_course_outline_block_tree, get_resume_block
|
||||
from .course_dates import CourseDatesFragmentView
|
||||
from .course_home_messages import CourseHomeMessageFragmentView
|
||||
@@ -86,7 +83,7 @@ class CourseHomeFragmentView(EdxFragmentView):
|
||||
otherwise the URL of the course root.
|
||||
|
||||
"""
|
||||
course_outline_root_block = get_course_outline_block_tree(request, course_id, request.user)
|
||||
course_outline_root_block = get_course_outline_block_tree(request, course_id)
|
||||
resume_block = get_resume_block(course_outline_root_block) if course_outline_root_block else None
|
||||
has_visited_course = bool(resume_block)
|
||||
if resume_block:
|
||||
@@ -120,26 +117,11 @@ class CourseHomeFragmentView(EdxFragmentView):
|
||||
enrollment = CourseEnrollment.get_enrollment(request.user, course_key)
|
||||
user_access = {
|
||||
'is_anonymous': request.user.is_anonymous,
|
||||
'is_enrolled': enrollment and enrollment.is_active,
|
||||
'is_enrolled': enrollment is not None,
|
||||
'is_staff': has_access(request.user, 'staff', course_key),
|
||||
}
|
||||
|
||||
allow_anonymous = COURSE_ENABLE_UNENROLLED_ACCESS_FLAG.is_enabled(course_key)
|
||||
allow_public = allow_anonymous and course.course_visibility == COURSE_VISIBILITY_PUBLIC
|
||||
allow_public_outline = allow_anonymous and course.course_visibility == COURSE_VISIBILITY_PUBLIC_OUTLINE
|
||||
|
||||
# Set all the fragments
|
||||
outline_fragment = None
|
||||
update_message_fragment = None
|
||||
course_sock_fragment = None
|
||||
has_visited_course = None
|
||||
resume_course_url = None
|
||||
handouts_html = None
|
||||
|
||||
if user_access['is_enrolled'] or user_access['is_staff']:
|
||||
outline_fragment = CourseOutlineFragmentView().render_to_fragment(
|
||||
request, course_id=course_id, **kwargs
|
||||
)
|
||||
outline_fragment = CourseOutlineFragmentView().render_to_fragment(request, course_id=course_id, **kwargs)
|
||||
if LATEST_UPDATE_FLAG.is_enabled(course_key):
|
||||
update_message_fragment = LatestUpdateFragmentView().render_to_fragment(
|
||||
request, course_id=course_id, **kwargs
|
||||
@@ -150,18 +132,22 @@ class CourseHomeFragmentView(EdxFragmentView):
|
||||
)
|
||||
course_sock_fragment = CourseSockFragmentView().render_to_fragment(request, course=course, **kwargs)
|
||||
has_visited_course, resume_course_url = self._get_resume_course_info(request, course_id)
|
||||
handouts_html = self._get_course_handouts(request, course)
|
||||
elif allow_public_outline or allow_public:
|
||||
outline_fragment = CourseOutlineFragmentView().render_to_fragment(
|
||||
request, course_id=course_id, user_is_enrolled=False, **kwargs
|
||||
)
|
||||
course_sock_fragment = CourseSockFragmentView().render_to_fragment(request, course=course, **kwargs)
|
||||
else:
|
||||
# Redirect the user to the dashboard if they are not enrolled and
|
||||
# this is a course that does not support direct enrollment.
|
||||
if not can_self_enroll_in_course(course_key):
|
||||
raise CourseAccessRedirect(reverse('dashboard'))
|
||||
|
||||
# Set all the fragments
|
||||
outline_fragment = None
|
||||
update_message_fragment = None
|
||||
course_sock_fragment = None
|
||||
has_visited_course = None
|
||||
resume_course_url = None
|
||||
|
||||
# Get the handouts
|
||||
handouts_html = self._get_course_handouts(request, course)
|
||||
|
||||
# Get the course tools enabled for this user and course
|
||||
course_tools = CourseToolsPluginManager.get_enabled_course_tools(request, course_key)
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@ from openedx.core.djangoapps.plugin_api.views import EdxFragmentView
|
||||
from student.models import CourseEnrollment
|
||||
|
||||
from util.milestones_helpers import get_course_content_milestones
|
||||
from xmodule.course_module import COURSE_VISIBILITY_PUBLIC
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from ..utils import get_course_outline_block_tree, get_resume_block
|
||||
|
||||
@@ -31,19 +30,15 @@ class CourseOutlineFragmentView(EdxFragmentView):
|
||||
Course outline fragment to be shown in the unified course view.
|
||||
"""
|
||||
|
||||
def render_to_fragment(self, request, course_id, user_is_enrolled=True, **kwargs): # pylint: disable=arguments-differ
|
||||
def render_to_fragment(self, request, course_id=None, **kwargs): # pylint: disable=arguments-differ
|
||||
"""
|
||||
Renders the course outline as a fragment.
|
||||
"""
|
||||
course_key = CourseKey.from_string(course_id)
|
||||
course_overview = get_course_overview_with_access(
|
||||
request.user, 'load', course_key, check_if_enrolled=user_is_enrolled
|
||||
)
|
||||
course_overview = get_course_overview_with_access(request.user, 'load', course_key, check_if_enrolled=True)
|
||||
course = modulestore().get_course(course_key)
|
||||
|
||||
course_block_tree = get_course_outline_block_tree(
|
||||
request, course_id, request.user if user_is_enrolled else None
|
||||
)
|
||||
course_block_tree = get_course_outline_block_tree(request, course_id)
|
||||
if not course_block_tree:
|
||||
return None
|
||||
|
||||
@@ -51,12 +46,10 @@ class CourseOutlineFragmentView(EdxFragmentView):
|
||||
'csrf': csrf(request)['csrf_token'],
|
||||
'course': course_overview,
|
||||
'due_date_display_format': course.due_date_display_format,
|
||||
'blocks': course_block_tree,
|
||||
'enable_links': user_is_enrolled or course.course_visibility == COURSE_VISIBILITY_PUBLIC,
|
||||
'blocks': course_block_tree
|
||||
}
|
||||
|
||||
resume_block = get_resume_block(course_block_tree) if user_is_enrolled else None
|
||||
|
||||
resume_block = get_resume_block(course_block_tree)
|
||||
if not resume_block:
|
||||
self.mark_first_unit_to_resume(course_block_tree)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user