def test_is_gate_fulfilled(self, min_score, min_completion, learner_score, learner_completion, is_gate_fulfilled): """ Test if prereq section has any unfulfilled milestones """ student = UserFactory(is_staff=False) 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, min_completion ) milestone = milestones_api.add_milestone(self.generic_milestone) milestones_api.add_course_content_milestone(self.course.id, self.seq1.location, 'fulfills', milestone) self.assertFalse(gating_api.is_gate_fulfilled(self.course.id, self.seq1.location, student.id)) # complete the prerequisite to unlock the gated content # this call triggers reevaluation of prerequisites fulfilled by the gating block. with patch.object(gating_api, 'get_subsection_completion_percentage') as mock_grade: mock_grade.return_value = learner_completion lms_gating_api.evaluate_prerequisite( self.course, Mock(location=self.seq1.location, percent_graded=learner_score / 100.0), student, ) self.assertEqual( gating_api.is_gate_fulfilled(self.course.id, self.seq1.location, student.id), is_gate_fulfilled )
def test_get_gated_content(self): """ Verify staff bypasses gated content and student gets list of unfulfilled prerequisites. """ staff = UserFactory(is_staff=True) student = UserFactory(is_staff=False) self.assertEqual(gating_api.get_gated_content(self.course, staff), []) self.assertEqual(gating_api.get_gated_content(self.course, student), []) gating_api.add_prerequisite(self.course.id, self.seq1.location) gating_api.set_required_content(self.course.id, self.seq2.location, self.seq1.location, 100) milestone = milestones_api.get_course_content_milestones( self.course.id, self.seq2.location, 'requires')[0] self.assertEqual(gating_api.get_gated_content(self.course, staff), []) self.assertEqual(gating_api.get_gated_content(self.course, student), [unicode(self.seq2.location)]) milestones_api.add_user_milestone({'id': student.id}, milestone) # pylint: disable=no-member self.assertEqual(gating_api.get_gated_content(self.course, student), [])
def test_is_gate_fulfilled(self, min_score, min_completion, learner_score, learner_completion, is_gate_fulfilled): """ Test if prereq section has any unfulfilled milestones """ student = UserFactory(is_staff=False) 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, min_completion) milestone = milestones_api.add_milestone(self.generic_milestone) milestones_api.add_course_content_milestone(self.course.id, self.seq1.location, 'fulfills', milestone) self.assertFalse( gating_api.is_gate_fulfilled(self.course.id, self.seq1.location, student.id)) # complete the prerequisite to unlock the gated content # this call triggers reevaluation of prerequisites fulfilled by the gating block. with patch.object( gating_api, 'get_subsection_completion_percentage') as mock_grade: mock_grade.return_value = learner_completion lms_gating_api.evaluate_prerequisite( self.course, Mock(location=self.seq1.location, percent_graded=learner_score / 100.0), student, ) self.assertEqual( gating_api.is_gate_fulfilled(self.course.id, self.seq1.location, student.id), is_gate_fulfilled)
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')
def test_find_gating_milestones(self): """ Test test_find_gating_milestones """ gating_api.add_prerequisite(self.course.id, self.seq1.location) gating_api.set_required_content(self.course.id, self.seq2.location, self.seq1.location, 100) milestone = milestones_api.add_milestone(self.generic_milestone) milestones_api.add_course_content_milestone(self.course.id, self.seq1.location, 'fulfills', milestone) self.assertEqual( len( gating_api.find_gating_milestones(self.course.id, self.seq1.location, 'fulfills')), 1) self.assertEqual( len( gating_api.find_gating_milestones(self.course.id, self.seq1.location, 'requires')), 0) self.assertEqual( len( gating_api.find_gating_milestones(self.course.id, self.seq2.location, 'fulfills')), 0) self.assertEqual( len( gating_api.find_gating_milestones(self.course.id, self.seq2.location, 'requires')), 1)
def setUp(self): """ Initial data setup """ super(TestHandleItemDeleted, self).setUp() self.course = CourseFactory.create() self.course.enable_subsection_gating = True self.course.save() self.chapter = ItemFactory.create( parent=self.course, category="chapter", display_name="Chapter" ) self.open_seq = ItemFactory.create( parent=self.chapter, category='sequential', display_name="Open Sequential" ) self.gated_seq = ItemFactory.create( parent=self.chapter, category='sequential', display_name="Gated Sequential" ) gating_api.add_prerequisite(self.course.id, self.open_seq.location) gating_api.set_required_content(self.course.id, self.gated_seq.location, self.open_seq.location, 100)
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.location, self.user.id) self.assertFalse(mock_module_score.called)
def test_get_gating_milestone_is_none(self): """ Test test_get_gating_milestone_is_none """ gating_api.add_prerequisite(self.course.id, self.seq1.location) gating_api.set_required_content(self.course.id, self.seq2.location, self.seq1.location, 100) self.assertIsNone(gating_api.get_gating_milestone(self.course.id, self.seq1.location, 'requires')) self.assertIsNone(gating_api.get_gating_milestone(self.course.id, self.seq2.location, 'fulfills'))
def setup_gating_milestone(self, min_score): """ Setup a gating milestone for testing. Gating content: seq1 (must be fulfilled before access to seq2) Gated content: seq2 (requires completion of seq1 before access) """ gating_api.add_prerequisite(self.course.id, str(self.seq1.location)) gating_api.set_required_content(self.course.id, str(self.seq2.location), str(self.seq1.location), min_score) self.prereq_milestone = gating_api.get_gating_milestone(self.course.id, self.seq1.location, 'fulfills')
def setup_gated_section(self, gated_block, gating_block): """ Test helper to create a gating requirement. Args: gated_block: The block that should be inaccessible until gating_block is completed gating_block: The block that must be completed before access is granted """ gating_api.add_prerequisite(self.course.id, unicode(gating_block.location)) gating_api.set_required_content(self.course.id, gated_block.location, gating_block.location, 100)
def setup_gated_section(self, gated_block, gating_block): """ Test helper to create a gating requirement Args: gated_block: The block the that learner will not have access to until they complete the gating block gating_block: (The prerequisite) The block that must be completed to get access to the gated block """ gating_api.add_prerequisite(self.course.id, six.text_type(gating_block.location)) gating_api.set_required_content(self.course.id, gated_block.location, gating_block.location, 100)
def setup_gated_section(self, gated_block, gating_block): """ Test helper to create a gating requirement Args: gated_block: The block the that learner will not have access to until they complete the gating block gating_block: (The prerequisite) The block that must be completed to get access to the gated block """ gating_api.add_prerequisite(self.course.id, unicode(gating_block.location)) gating_api.set_required_content(self.course.id, gated_block.location, gating_block.location, 100)
def test_find_gating_milestones(self): """ Test test_find_gating_milestones """ gating_api.add_prerequisite(self.course.id, self.seq1.location) gating_api.set_required_content(self.course.id, self.seq2.location, self.seq1.location, 100) milestone = milestones_api.add_milestone(self.generic_milestone) milestones_api.add_course_content_milestone(self.course.id, self.seq1.location, 'fulfills', milestone) self.assertEqual(len(gating_api.find_gating_milestones(self.course.id, self.seq1.location, 'fulfills')), 1) self.assertEqual(len(gating_api.find_gating_milestones(self.course.id, self.seq1.location, 'requires')), 0) self.assertEqual(len(gating_api.find_gating_milestones(self.course.id, self.seq2.location, 'fulfills')), 0) self.assertEqual(len(gating_api.find_gating_milestones(self.course.id, self.seq2.location, 'requires')), 1)
def test_required_content(self): """ Test test_required_content """ gating_api.add_prerequisite(self.course.id, self.seq1.location) gating_api.set_required_content(self.course.id, self.seq2.location, self.seq1.location, 100) prereq_content_key, min_score = gating_api.get_required_content(self.course.id, self.seq2.location) self.assertEqual(prereq_content_key, unicode(self.seq1.location)) self.assertEqual(min_score, 100) gating_api.set_required_content(self.course.id, self.seq2.location, None, None) prereq_content_key, min_score = gating_api.get_required_content(self.course.id, self.seq2.location) self.assertIsNone(prereq_content_key) self.assertIsNone(min_score)
def test_prerequisites(self): """ Test test_prerequisites """ gating_api.add_prerequisite(self.course.id, self.seq1.location) prereqs = gating_api.get_prerequisites(self.course.id) assert len(prereqs) == 1 assert prereqs[0]['block_display_name'] == self.seq1.display_name assert prereqs[0]['block_usage_key'] == str(self.seq1.location) assert gating_api.is_prerequisite(self.course.id, self.seq1.location) gating_api.remove_prerequisite(self.seq1.location) assert len(gating_api.get_prerequisites(self.course.id)) == 0 assert not gating_api.is_prerequisite(self.course.id, self.seq1.location)
def test_prerequisites(self): """ Test test_prerequisites """ gating_api.add_prerequisite(self.course.id, self.seq1.location) prereqs = gating_api.get_prerequisites(self.course.id) self.assertEqual(len(prereqs), 1) self.assertEqual(prereqs[0]['block_display_name'], self.seq1.display_name) self.assertEqual(prereqs[0]['block_usage_key'], unicode(self.seq1.location)) self.assertTrue(gating_api.is_prerequisite(self.course.id, self.seq1.location)) gating_api.remove_prerequisite(self.seq1.location) self.assertEqual(len(gating_api.get_prerequisites(self.course.id)), 0) self.assertFalse(gating_api.is_prerequisite(self.course.id, self.seq1.location))
def test_get_gated_content(self): """ Test test_get_gated_content """ mock_user = MagicMock() mock_user.id.return_value = 1 self.assertEqual(gating_api.get_gated_content(self.course, mock_user), []) gating_api.add_prerequisite(self.course.id, self.seq1.location) gating_api.set_required_content(self.course.id, self.seq2.location, self.seq1.location, 100) milestone = milestones_api.get_course_content_milestones(self.course.id, self.seq2.location, 'requires')[0] self.assertEqual(gating_api.get_gated_content(self.course, mock_user), [unicode(self.seq2.location)]) milestones_api.add_user_milestone({'id': mock_user.id}, milestone) self.assertEqual(gating_api.get_gated_content(self.course, mock_user), [])
def test_compute_is_prereq_met(self): """ Test if prereq has been met and force recompute """ student = UserFactory(is_staff=False) gating_api.add_prerequisite(self.course.id, self.seq1.location) gating_api.set_required_content(self.course.id, self.seq2.location, self.seq1.location, 100, 0) # complete the prerequisite to unlock the gated content # this call triggers reevaluation of prerequisites fulfilled by the gating block. with patch.object(gating_api, 'get_subsection_grade_percentage') as mock_grade: mock_grade.return_value = 75 # don't force recompute prereq_met, prereq_meta_info = gating_api.compute_is_prereq_met( self.seq2.location, student.id, False) self.assertFalse(prereq_met) self.assertIsNone(prereq_meta_info['url']) self.assertIsNone(prereq_meta_info['display_name']) # force recompute prereq_met, prereq_meta_info = gating_api.compute_is_prereq_met( self.seq2.location, student.id, True) self.assertFalse(prereq_met) self.assertIsNotNone(prereq_meta_info['url']) self.assertIsNotNone(prereq_meta_info['display_name']) # change to passing grade mock_grade.return_value = 100 # don't force recompute prereq_met, prereq_meta_info = gating_api.compute_is_prereq_met( self.seq2.location, student.id, False) self.assertFalse(prereq_met) self.assertIsNone(prereq_meta_info['url']) self.assertIsNone(prereq_meta_info['display_name']) # force recompute prereq_met, prereq_meta_info = gating_api.compute_is_prereq_met( self.seq2.location, student.id, True) self.assertTrue(prereq_met) self.assertIsNotNone(prereq_meta_info['url']) self.assertIsNotNone(prereq_meta_info['display_name'])
def test_required_content(self): """ Test test_required_content """ gating_api.add_prerequisite(self.course.id, self.seq1.location) gating_api.set_required_content(self.course.id, self.seq2.location, self.seq1.location, 100, 100) prereq_content_key, min_score, min_completion = gating_api.get_required_content( self.course.id, self.seq2.location) assert prereq_content_key == str(self.seq1.location) assert min_score == 100 assert min_completion == 100 gating_api.set_required_content(self.course.id, self.seq2.location, None, None, None) prereq_content_key, min_score, min_completion = gating_api.get_required_content( self.course.id, self.seq2.location) assert prereq_content_key is None assert min_score is None assert min_completion is None
def test_get_gated_content(self): """ Verify staff bypasses gated content and student gets list of unfulfilled prerequisites. """ staff = UserFactory(is_staff=True) student = UserFactory(is_staff=False) self.assertEqual(gating_api.get_gated_content(self.course, staff), []) self.assertEqual(gating_api.get_gated_content(self.course, student), []) gating_api.add_prerequisite(self.course.id, self.seq1.location) gating_api.set_required_content(self.course.id, self.seq2.location, self.seq1.location, 100) milestone = milestones_api.get_course_content_milestones(self.course.id, self.seq2.location, 'requires')[0] self.assertEqual(gating_api.get_gated_content(self.course, staff), []) self.assertEqual(gating_api.get_gated_content(self.course, student), [unicode(self.seq2.location)]) milestones_api.add_user_milestone({'id': student.id}, milestone) # pylint: disable=no-member self.assertEqual(gating_api.get_gated_content(self.course, student), [])
def test_get_gated_content(self): """ Verify staff bypasses gated content and student gets list of unfulfilled prerequisites. """ staff = UserFactory(is_staff=True) student = UserFactory(is_staff=False) assert gating_api.get_gated_content(self.course, staff) == [] assert gating_api.get_gated_content(self.course, student) == [] gating_api.add_prerequisite(self.course.id, self.seq1.location) gating_api.set_required_content(self.course.id, self.seq2.location, self.seq1.location, 100) milestone = milestones_api.get_course_content_milestones(self.course.id, self.seq2.location, 'requires')[0] assert gating_api.get_gated_content(self.course, staff) == [] assert gating_api.get_gated_content(self.course, student) == [str(self.seq2.location)] milestones_api.add_user_milestone({'id': student.id}, milestone) assert gating_api.get_gated_content(self.course, student) == []
def test_compute_is_prereq_met(self): """ Test if prereq has been met and force recompute """ student = UserFactory(is_staff=False) gating_api.add_prerequisite(self.course.id, self.seq1.location) gating_api.set_required_content(self.course.id, self.seq2.location, self.seq1.location, 100, 0) # complete the prerequisite to unlock the gated content # this call triggers reevaluation of prerequisites fulfilled by the gating block. with patch.object(gating_api, 'get_subsection_grade_percentage') as mock_grade: mock_grade.return_value = 75 # don't force recompute prereq_met, prereq_meta_info = gating_api.compute_is_prereq_met(self.seq2.location, student.id, False) self.assertFalse(prereq_met) self.assertIsNone(prereq_meta_info['url']) self.assertIsNone(prereq_meta_info['display_name']) # force recompute prereq_met, prereq_meta_info = gating_api.compute_is_prereq_met(self.seq2.location, student.id, True) self.assertFalse(prereq_met) self.assertIsNotNone(prereq_meta_info['url']) self.assertIsNotNone(prereq_meta_info['display_name']) # change to passing grade mock_grade.return_value = 100 # don't force recompute prereq_met, prereq_meta_info = gating_api.compute_is_prereq_met(self.seq2.location, student.id, False) self.assertFalse(prereq_met) self.assertIsNone(prereq_meta_info['url']) self.assertIsNone(prereq_meta_info['display_name']) # force recompute prereq_met, prereq_meta_info = gating_api.compute_is_prereq_met(self.seq2.location, student.id, True) self.assertTrue(prereq_met) self.assertIsNotNone(prereq_meta_info['url']) self.assertIsNotNone(prereq_meta_info['display_name'])
def test_get_prerequisite_milestone_returns_milestone(self): """ Test test_get_prerequisite_milestone_returns_milestone """ gating_api.add_prerequisite(self.course.id, self.seq1.location) prereq = gating_api._get_prerequisite_milestone(self.seq1.location) # pylint: disable=protected-access self.assertIsNotNone(prereq)
def test_no_gated_content(self, mock_milestones): gating_api.add_prerequisite(self.course.id, self.seq1.location) answer_problem(self.course, self.request, self.gating_prob1, 1, 1) self.assertFalse(mock_milestones.called)
def test_no_gated_content(self, mock_score): gating_api.add_prerequisite(self.course.id, self.seq1.location) evaluate_prerequisite(self.course, self.subsection_grade, self.user) self.assertFalse(mock_score.called)
def test_no_gated_content(self, mock_score): gating_api.add_prerequisite(self.course.id, self.seq1.location) evaluate_prerequisite(self.course, self.subsection_grade, self.user) assert not mock_score.called