Add tests to verify access denied message deduplication works

This commit is contained in:
Matt Tuchfarber
2018-12-03 11:39:28 -05:00
parent 7fb51dfa16
commit 5a60fc1db6

View File

@@ -14,7 +14,6 @@ from course_modes.tests.factories import CourseModeFactory
from lms.djangoapps.courseware.module_render import load_single_xblock
from openedx.core.djangoapps.user_api.tests.factories import UserCourseTagFactory
from openedx.core.djangoapps.util.testing import TestConditionalContent
from openedx.core.djangoapps.waffle_utils.testutils import override_waffle_flag
from openedx.core.lib.url_utils import quote_slashes
from openedx.features.content_type_gating.partitions import CONTENT_GATING_PARTITION_ID
from openedx.features.content_type_gating.models import ContentTypeGatingConfig
@@ -26,20 +25,18 @@ from student.tests.factories import (
UserFactory,
TEST_PASSWORD
)
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase, SharedModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
@patch("crum.get_current_request")
def _assert_block_is_gated(mock_get_current_request, block, is_gated, user_id, course, request_factory):
def _get_fragment_from_block(block, user_id, course, request_factory, mock_get_current_request):
"""
Asserts that a block in a specific course is gated for a specific user
Returns the rendered fragment of a block
Arguments:
block: some sort of xblock descriptor, must implement .scope_ids.usage_id
is_gated (bool): if True, this user is expected to be gated from this block
user_id (int): id of user
course_id (CourseLocator): id of course
view_name (str): type of view for the block, if not set will default to 'student_view'
"""
fake_request = request_factory.get('')
mock_get_current_request.return_value = fake_request
@@ -59,12 +56,38 @@ def _assert_block_is_gated(mock_get_current_request, block, is_gated, user_id, c
# Attempt to render the block, this should return different fragments if the content is gated or not.
frag = runtime.render(problem_block, 'student_view')
return frag
def _assert_block_is_gated(block, is_gated, user_id, course, request_factory):
"""
Asserts that a block in a specific course is gated for a specific user
Arguments:
block: some sort of xblock descriptor, must implement .scope_ids.usage_id
is_gated (bool): if True, this user is expected to be gated from this block
user_id (int): id of user
course_id (CourseLocator): id of course
"""
frag = _get_fragment_from_block(block, user_id, course, request_factory)
if is_gated:
assert 'content-paywall' in frag.content
else:
assert 'content-paywall' not in frag.content
def _assert_block_is_empty(block, user_id, course, request_factory):
"""
Asserts that a block in a specific course is empty for a specific user
Arguments:
block: some sort of xblock descriptor, must implement .scope_ids.usage_id
is_gated (bool): if True, this user is expected to be gated from this block
user_id (int): id of user
course_id (CourseLocator): id of course
"""
frag = _get_fragment_from_block(block, user_id, course, request_factory)
assert frag.content == u''
@ddt.ddt
@override_settings(FIELD_OVERRIDE_PROVIDERS=(
'openedx.features.content_type_gating.field_override.ContentTypeGatingFieldOverride',
@@ -505,3 +528,219 @@ class TestConditionalContentAccess(TestConditionalContent):
is_gated=False,
request_factory=self.factory,
)
@override_settings(FIELD_OVERRIDE_PROVIDERS=(
'openedx.features.content_type_gating.field_override.ContentTypeGatingFieldOverride',
))
class TestMessageDeduplication(ModuleStoreTestCase):
"""
Tests to verify that access denied messages isn't shown if multiple items in a row are denied.
Expected results:
- 0 items denied => No access denied messages
- 1+ items in a row denied => 1 access denied message
- If page has accessible content between access denied blocks, show both blocks.
NOTE: This uses `_assert_block_is_gated` to verify that the message is being shown (as that's
how it's currently tested). If that method changes to use something other than the template
message, this method's checks will need to be updated.
"""
def setUp(self):
super(TestMessageDeduplication, self).setUp()
self.user = UserFactory.create()
self.request_factory = RequestFactory()
ContentTypeGatingConfig.objects.create(enabled=True, enabled_as_of=date(2018, 1, 1))
def _create_course(self):
course = CourseFactory.create(run='test', display_name='test')
CourseModeFactory.create(course_id=course.id, mode_slug='audit')
CourseModeFactory.create(course_id=course.id, mode_slug='verified')
blocks_dict = {}
with self.store.bulk_operations(course.id):
blocks_dict['chapter'] = ItemFactory.create(
parent=course,
category='chapter',
display_name='Week 1'
)
blocks_dict['sequential'] = ItemFactory.create(
parent=blocks_dict['chapter'],
category='sequential',
display_name='Lesson 1'
)
blocks_dict['vertical'] = ItemFactory.create(
parent=blocks_dict['sequential'],
category='vertical',
display_name='Lesson 1 Vertical - Unit 1'
)
return {
'course': course,
'blocks': blocks_dict,
}
def test_single_denied(self):
''' Single graded problem should show error '''
course = self._create_course()
blocks_dict = course['blocks']
CourseEnrollmentFactory.create(
user=self.user,
course_id=course['course'].id,
mode='audit'
)
blocks_dict['graded_1'] = ItemFactory.create(
parent=blocks_dict['vertical'],
category='problem',
display_name='graded_problem',
graded=True,
)
_assert_block_is_gated(
block=blocks_dict['graded_1'],
user_id=self.user.id,
course=course['course'],
is_gated=True,
request_factory=self.request_factory,
)
def test_double_denied(self):
''' First graded problem should show message, second shouldn't '''
course = self._create_course()
blocks_dict = course['blocks']
blocks_dict['graded_1'] = ItemFactory.create(
parent=blocks_dict['vertical'],
category='problem',
display_name='graded_problem',
graded=True,
)
blocks_dict['graded_2'] = ItemFactory.create(
parent=blocks_dict['vertical'],
category='problem',
display_name='graded_problem',
graded=True,
)
CourseEnrollmentFactory.create(
user=self.user,
course_id=course['course'].id,
mode='audit'
)
_assert_block_is_gated(
block=blocks_dict['graded_1'],
user_id=self.user.id,
course=course['course'],
is_gated=True,
request_factory=self.request_factory,
)
_assert_block_is_empty(
block=blocks_dict['graded_2'],
user_id=self.user.id,
course=course['course'],
request_factory=self.request_factory,
)
def test_many_denied(self):
''' First graded problem should show message, all that follow shouldn't '''
course = self._create_course()
blocks_dict = course['blocks']
blocks_dict['graded_1'] = ItemFactory.create(
parent=blocks_dict['vertical'],
category='problem',
display_name='graded_problem',
graded=True,
)
blocks_dict['graded_2'] = ItemFactory.create(
parent=blocks_dict['vertical'],
category='problem',
display_name='graded_problem',
graded=True,
)
blocks_dict['graded_3'] = ItemFactory.create(
parent=blocks_dict['vertical'],
category='problem',
display_name='graded_problem',
graded=True,
)
blocks_dict['graded_4'] = ItemFactory.create(
parent=blocks_dict['vertical'],
category='problem',
display_name='graded_problem',
graded=True,
)
CourseEnrollmentFactory.create(
user=self.user,
course_id=course['course'].id,
mode='audit'
)
_assert_block_is_gated(
block=blocks_dict['graded_1'],
user_id=self.user.id,
course=course['course'],
is_gated=True,
request_factory=self.request_factory,
)
_assert_block_is_empty(
block=blocks_dict['graded_2'],
user_id=self.user.id,
course=course['course'],
request_factory=self.request_factory,
)
_assert_block_is_empty(
block=blocks_dict['graded_3'],
user_id=self.user.id,
course=course['course'],
request_factory=self.request_factory,
)
_assert_block_is_empty(
block=blocks_dict['graded_4'],
user_id=self.user.id,
course=course['course'],
request_factory=self.request_factory,
)
def test_alternate_denied(self):
''' Multiple graded content with ungraded between it should show message on either end '''
course = self._create_course()
blocks_dict = course['blocks']
blocks_dict['graded_1'] = ItemFactory.create(
parent=blocks_dict['vertical'],
category='problem',
display_name='graded_problem',
graded=True,
)
blocks_dict['ungraded_2'] = ItemFactory.create(
parent=blocks_dict['vertical'],
category='problem',
display_name='ungraded_problem',
graded=False,
)
blocks_dict['graded_3'] = ItemFactory.create(
parent=blocks_dict['vertical'],
category='problem',
display_name='graded_problem',
graded=True,
)
CourseEnrollmentFactory.create(
user=self.user,
course_id=course['course'].id,
mode='audit'
)
_assert_block_is_gated(
block=blocks_dict['graded_1'],
user_id=self.user.id,
course=course['course'],
is_gated=True,
request_factory=self.request_factory,
)
_assert_block_is_gated(
block=blocks_dict['ungraded_2'],
user_id=self.user.id,
course=course['course'],
is_gated=False,
request_factory=self.request_factory,
)
_assert_block_is_gated(
block=blocks_dict['graded_3'],
user_id=self.user.id,
course=course['course'],
is_gated=True,
request_factory=self.request_factory,
)