Пример #1
0
    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
            )
Пример #2
0
    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),
                         [])
Пример #3
0
    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)
Пример #4
0
 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')
Пример #5
0
    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)
Пример #6
0
    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)
Пример #7
0
    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)
Пример #8
0
    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)
Пример #9
0
    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)
Пример #10
0
    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'))
Пример #11
0
 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')
Пример #12
0
 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')
Пример #13
0
 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)
Пример #14
0
 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)
Пример #15
0
    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)
Пример #16
0
    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)
Пример #17
0
    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)
Пример #18
0
    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)
Пример #19
0
    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)
Пример #20
0
    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))
Пример #21
0
    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), [])
Пример #22
0
    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'])
Пример #23
0
    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
Пример #24
0
    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), [])
Пример #25
0
    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) == []
Пример #26
0
    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'])
Пример #27
0
    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)
Пример #28
0
 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)
Пример #29
0
    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)
Пример #30
0
    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