Files
edx-platform/lms/djangoapps/gating/tests/test_api.py
2016-11-01 15:02:04 -04:00

177 lines
5.8 KiB
Python

"""
Unit tests for gating.signals module
"""
from mock import patch
from nose.plugins.attrib import attr
from ddt import ddt, data, unpack
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from courseware.tests.helpers import LoginEnrollmentTestCase
from milestones import api as milestones_api
from milestones.tests.utils import MilestonesTestCaseMixin
from openedx.core.lib.gating import api as gating_api
from gating.api import _get_xblock_parent, evaluate_prerequisite
class GatingTestCase(LoginEnrollmentTestCase, ModuleStoreTestCase):
"""
Base TestCase class for setting up a basic course structure
and testing the gating feature
"""
def setUp(self):
"""
Initial data setup
"""
super(GatingTestCase, self).setUp()
# create course
self.course = CourseFactory.create(
org='edX',
number='EDX101',
run='EDX101_RUN1',
display_name='edX 101'
)
self.course.enable_subsection_gating = True
self.course.save()
self.store.update_item(self.course, 0)
# create chapter
self.chapter1 = ItemFactory.create(
parent_location=self.course.location,
category='chapter',
display_name='untitled chapter 1'
)
# create sequentials
self.seq1 = ItemFactory.create(
parent_location=self.chapter1.location,
category='sequential',
display_name='untitled sequential 1'
)
self.seq2 = ItemFactory.create(
parent_location=self.chapter1.location,
category='sequential',
display_name='untitled sequential 2'
)
# create vertical
self.vert1 = ItemFactory.create(
parent_location=self.seq1.location,
category='vertical',
display_name='untitled vertical 1'
)
# create problem
self.prob1 = ItemFactory.create(
parent_location=self.vert1.location,
category='problem',
display_name='untitled problem 1'
)
# create orphan
self.prob2 = ItemFactory.create(
parent_location=self.course.location,
category='problem',
display_name='untitled problem 2'
)
class TestGetXBlockParent(GatingTestCase):
"""
Tests for the get_xblock_parent function
"""
def test_get_direct_parent(self):
""" Test test_get_direct_parent """
result = _get_xblock_parent(self.vert1)
self.assertEqual(result.location, self.seq1.location)
def test_get_parent_with_category(self):
""" Test test_get_parent_of_category """
result = _get_xblock_parent(self.vert1, 'sequential')
self.assertEqual(result.location, self.seq1.location)
result = _get_xblock_parent(self.vert1, 'chapter')
self.assertEqual(result.location, self.chapter1.location)
def test_get_parent_none(self):
""" Test test_get_parent_none """
result = _get_xblock_parent(self.vert1, 'unit')
self.assertIsNone(result)
@attr(shard=3)
@ddt
class TestEvaluatePrerequisite(GatingTestCase, MilestonesTestCaseMixin):
"""
Tests for the evaluate_prerequisite function
"""
def setUp(self):
super(TestEvaluatePrerequisite, self).setUp()
self.user_dict = {'id': self.user.id}
self.prereq_milestone = None
def _setup_gating_milestone(self, min_score):
"""
Setup a gating milestone for testing
"""
gating_api.add_prerequisite(self.course.id, self.seq1.location)
gating_api.set_required_content(self.course.id, self.seq2.location, self.seq1.location, min_score)
self.prereq_milestone = gating_api.get_gating_milestone(self.course.id, self.seq1.location, 'fulfills')
@patch('gating.api.get_module_score')
@data((.5, True), (1, True), (0, False))
@unpack
def test_min_score_achieved(self, module_score, result, mock_module_score):
""" Test test_min_score_achieved """
self._setup_gating_milestone(50)
mock_module_score.return_value = module_score
evaluate_prerequisite(self.course, self.prob1, self.user.id)
self.assertEqual(milestones_api.user_has_milestone(self.user_dict, self.prereq_milestone), result)
@patch('gating.api.log.warning')
@patch('gating.api.get_module_score')
@data((.5, False), (1, True))
@unpack
def test_invalid_min_score(self, module_score, result, mock_module_score, mock_log):
""" Test test_invalid_min_score """
self._setup_gating_milestone(None)
mock_module_score.return_value = module_score
evaluate_prerequisite(self.course, self.prob1, self.user.id)
self.assertEqual(milestones_api.user_has_milestone(self.user_dict, self.prereq_milestone), result)
self.assertTrue(mock_log.called)
@patch('gating.api.get_module_score')
def test_orphaned_xblock(self, mock_module_score):
""" Test test_orphaned_xblock """
evaluate_prerequisite(self.course, self.prob2, self.user.id)
self.assertFalse(mock_module_score.called)
@patch('gating.api.get_module_score')
def test_no_prerequisites(self, mock_module_score):
""" Test test_no_prerequisites """
evaluate_prerequisite(self.course, self.prob1, self.user.id)
self.assertFalse(mock_module_score.called)
@patch('gating.api.get_module_score')
def test_no_gated_content(self, mock_module_score):
""" Test test_no_gated_content """
# Setup gating milestones data
gating_api.add_prerequisite(self.course.id, self.seq1.location)
evaluate_prerequisite(self.course, self.prob1, self.user.id)
self.assertFalse(mock_module_score.called)