Skip to content
test_flow.py 124 KiB
Newer Older
Dong Zhuang's avatar
Dong Zhuang committed
            permissions=[constants.flow_permission.cannot_see_flow_result]
        )

        access_rule_for_session2 = self.get_hacked_session_access_rule(
            permissions=[
                constants.flow_permission.view,
                constants.flow_permission.submit_answer,
                constants.flow_permission.end_session,
                constants.flow_permission.see_answer_after_submission]
        )

        grading_rule_for_session1 = self.get_hacked_session_grading_rule(
            due=None, max_points=10
        )
        grading_rule_for_session2 = self.get_hacked_session_grading_rule(
            due=now() - timedelta(days=1), max_points=9
        )

        new_session_grading_rule = self.get_hacked_session_grading_rule(
            due=now() + timedelta(hours=2), max_points=8
        )

        self.mock_get_session_start_rule.return_value = session_start_rule

        self.mock_get_session_access_rule.side_effect = [
            access_rule_for_session1, access_rule_for_session2
        ]

        self.mock_get_session_grading_rule.side_effect = [
            grading_rule_for_session1, grading_rule_for_session2,
            new_session_grading_rule
        ]

        with self.temporarily_switch_to_user(self.student_participation.user):
            resp = self.c.get(self.get_view_start_flow_url(self.flow_id))
            self.assertResponseContextEqual(resp, "may_start", True)
            self.assertResponseContextEqual(
                resp, "start_may_decrease_grade", True)
            past_sessions_and_properties = resp.context[
                "past_sessions_and_properties"]
            self.assertEqual(len(past_sessions_and_properties), 2)

            psap_session1, psap_property1 = past_sessions_and_properties[0]
            self.assertEqual(psap_session1, fs1)
            self.assertEqual(psap_property1.may_view, False)
            self.assertEqual(psap_property1.may_modify, False)
            self.assertEqual(psap_property1.due, None)
            self.assertEqual(psap_property1.grade_shown, False)

            psap_session2, psap_property2 = past_sessions_and_properties[1]
            self.assertEqual(psap_session2, fs2)
            self.assertEqual(psap_property2.may_view, True)
            self.assertEqual(psap_property2.may_modify, True)
            self.assertIsNotNone(psap_property2.due)
            self.assertEqual(psap_property2.grade_shown, True)

    def test_get_not_may_list_existing_sessions(self):
        session_start_rule = self.get_hacked_session_start_rule(
            may_start_new_session=False,
            may_list_existing_sessions=False,
        )

        # create 2 session with different access_rule and grading_rule
        self.get_test_flow_session(in_progress=False,
                                   start_time=now() - timedelta(days=3))
        self.get_test_flow_session(in_progress=True,
                                   start_time=now() - timedelta(days=2),
                                   completion_time=None)

        self.mock_get_session_start_rule.return_value = session_start_rule

        self.mock_get_session_grading_rule.return_value = (
            self.get_hacked_session_grading_rule(
                due=now() + timedelta(hours=2), max_points=8))

        with self.temporarily_switch_to_user(self.student_participation.user):
            resp = self.c.get(self.get_view_start_flow_url(self.flow_id))
            self.assertResponseContextEqual(resp, "may_start", False)
            self.assertResponseContextEqual(
                resp, "start_may_decrease_grade", False)

            past_sessions_and_properties = resp.context[
                "past_sessions_and_properties"]

            self.assertEqual(len(past_sessions_and_properties), 0)

        self.assertEqual(self.mock_get_session_grading_rule.call_count, 0)
        self.assertEqual(self.mock_get_session_access_rule.call_count, 0)


class PostStartFlowTest(SingleCourseTestMixin, TestCase):
    # test flow.post_start_flow

    flow_id = QUIZ_FLOW_ID

    def setUp(self):
        super(PostStartFlowTest, self).setUp()

        fake_get_login_exam_ticket = mock.patch("course.flow.get_login_exam_ticket")
        self.mock_get_login_exam_ticket = fake_get_login_exam_ticket.start()
        self.addCleanup(fake_get_login_exam_ticket.stop)

        fake_flow_context = mock.patch("course.flow.FlowContext")
        self.mock_flow_context = fake_flow_context.start()
        self.fctx = mock.MagicMock()
        self.fctx.flow_id = self.flow_id
        self.fctx.flow_desc = dict_to_struct(
            {"title": "test page title", "description_html": "foo bar"})
        self.mock_flow_context.return_value = self.fctx
        self.addCleanup(fake_flow_context.stop)

        fake_get_session_start_rule = mock.patch(
            "course.flow.get_session_start_rule")
        self.mock_get_session_start_rule = fake_get_session_start_rule.start()
        self.addCleanup(fake_get_session_start_rule.stop)

        fake_get_session_access_rule = mock.patch(
            "course.flow.get_session_access_rule")
        self.mock_get_session_access_rule = fake_get_session_access_rule.start()
        self.addCleanup(fake_get_session_access_rule.stop)

        fake_lock_down_if_needed = mock.patch(
            "course.flow.lock_down_if_needed")
        self.mock_lock_down_if_needed = fake_lock_down_if_needed.start()
        self.addCleanup(fake_lock_down_if_needed.stop)

        fake_start_flow = mock.patch("course.flow.start_flow")
        self.mock_start_flow = fake_start_flow.start()
        self.addCleanup(fake_start_flow.stop)

    def get_hacked_session_access_rule(self, **kwargs):
        from course.utils import FlowSessionAccessRule
        defaults = {
            "permissions": [],
        }
        defaults.update(kwargs)
        return FlowSessionAccessRule(**defaults)

    def get_hacked_session_start_rule(self, **kwargs):
        from course.utils import FlowSessionStartRule
        defaults = {
            "tag_session": None,
            "may_start_new_session": True,
            "may_list_existing_sessions": True,
            "default_expiration_mode": None,
        }
        defaults.update(kwargs)
        return FlowSessionStartRule(**defaults)

    def test_cooldown_seconds_worked(self):
        with self.temporarily_switch_to_user(self.student_participation.user):
            self.mock_get_session_start_rule.return_value = \
                self.get_hacked_session_start_rule()

            mock_session = mock.MagicMock()
            mock_session.id = 0
            mock_session.pk = 0
            self.mock_start_flow.return_value = mock_session

            # create an exising session started recently
            factories.FlowSessionFactory(participation=self.student_participation)

            self.start_flow(self.flow_id, ignore_cool_down=False,
                            assume_success=False)
            self.assertEqual(self.mock_start_flow.call_count, 0)
            self.assertEqual(self.mock_get_session_access_rule.call_count, 0)
            self.assertEqual(self.mock_get_login_exam_ticket.call_count, 1)
            self.assertEqual(self.mock_lock_down_if_needed.call_count, 0)

    def test_cooldown_seconds_dued(self):
        with self.temporarily_switch_to_user(self.student_participation.user):
            self.mock_get_session_start_rule.return_value = (
                self.get_hacked_session_start_rule())

            mock_session = mock.MagicMock()
            mock_session.id = 0
            mock_session.pk = 0
            self.mock_start_flow.return_value = mock_session

            # create an exising session started recently
            factories.FlowSessionFactory(
                participation=self.student_participation,
                start_time=now() - timedelta(seconds=11))

            self.start_flow(self.flow_id, ignore_cool_down=False,
                            assume_success=False)
            self.assertEqual(self.mock_start_flow.call_count, 1)
            self.assertEqual(self.mock_get_session_access_rule.call_count, 1)
            self.assertEqual(self.mock_get_login_exam_ticket.call_count, 1)
            self.assertEqual(self.mock_lock_down_if_needed.call_count, 1)

    def test_not_may_start(self):
        with self.temporarily_switch_to_user(self.student_participation.user):
            self.mock_get_session_start_rule.return_value = \
                self.get_hacked_session_start_rule(
                    may_start_new_session=False,
                )
            resp = self.start_flow(self.flow_id, ignore_cool_down=True,
                                   assume_success=False)
            self.assertEqual(resp.status_code, 403)

            self.assertEqual(self.mock_start_flow.call_count, 0)
            self.assertEqual(self.mock_get_session_access_rule.call_count, 0)
            self.assertEqual(self.mock_get_login_exam_ticket.call_count, 1)
            self.assertEqual(self.mock_lock_down_if_needed.call_count, 0)

    def test_start_session_for_anonymous(self):
        self.c.logout()
        self.mock_get_session_start_rule.return_value = \
            self.get_hacked_session_start_rule(
                may_start_new_session=True,
            )

        mock_session = mock.MagicMock()
        mock_session.id = 0
        mock_session.pk = 0
        self.mock_start_flow.return_value = mock_session

        resp = self.start_flow(self.flow_id, ignore_cool_down=True,
                               assume_success=False)
        self.assertEqual(resp.status_code, 302)

        self.assertEqual(self.mock_start_flow.call_count, 1)
        self.assertEqual(self.mock_get_session_access_rule.call_count, 1)
        self.assertEqual(self.mock_get_login_exam_ticket.call_count, 1)
        self.assertEqual(self.mock_lock_down_if_needed.call_count, 1)


Dong Zhuang's avatar
Dong Zhuang committed
# vim: foldmethod=marker