Exemple #1
0
    def _set_user_denied(self):
        """
        Sets course creator status to denied in admin table.
        """
        self.table_entry = CourseCreator(user=self.user)
        self.table_entry.save()

        self.deny_request = HttpRequest()
        self.deny_request.user = self.admin

        self.creator_admin = CourseCreatorAdmin(self.table_entry, AdminSite())

        self.table_entry.state = CourseCreator.DENIED
        self.creator_admin.save_model(self.deny_request, self.table_entry, None, True)
Exemple #2
0
    def setUp(self):
        """ Test case setup """
        self.user = User.objects.create_user('test_user', '*****@*****.**', 'foo')
        self.table_entry = CourseCreator(user=self.user)
        self.table_entry.save()

        self.admin = User.objects.create_user('Mark', '*****@*****.**', 'foo')
        self.admin.is_staff = True

        self.request = HttpRequest()
        self.request.user = self.admin

        self.creator_admin = CourseCreatorAdmin(self.table_entry, AdminSite())

        self.studio_request_email = '*****@*****.**'
        self.enable_creator_group_patch = {
            "ENABLE_CREATOR_GROUP": True,
            "STUDIO_REQUEST_EMAIL": self.studio_request_email
        }
    def setUp(self):
        """ Test case setup """
        self.user = User.objects.create_user('test_user', '*****@*****.**', 'foo')
        self.table_entry = CourseCreator(user=self.user)
        self.table_entry.save()

        self.admin = User.objects.create_user('Mark', '*****@*****.**', 'foo')
        self.admin.is_staff = True

        self.request = HttpRequest()
        self.request.user = self.admin

        self.creator_admin = CourseCreatorAdmin(self.table_entry, AdminSite())
Exemple #4
0
    def setUp(self):
        """ Test case setup """
        self.user = User.objects.create_user('test_user', '*****@*****.**', 'foo')
        self.table_entry = CourseCreator(user=self.user)
        self.table_entry.save()

        self.admin = User.objects.create_user('Mark', '*****@*****.**', 'foo')
        self.admin.is_staff = True

        self.request = HttpRequest()
        self.request.user = self.admin

        self.creator_admin = CourseCreatorAdmin(self.table_entry, AdminSite())

        self.studio_request_email = '*****@*****.**'
        self.enable_creator_group_patch = {
            "ENABLE_CREATOR_GROUP": True,
            "STUDIO_REQUEST_EMAIL": self.studio_request_email
        }
Exemple #5
0
class CourseCreatorAdminTest(TestCase):
    """
    Tests for course creator admin.
    """
    def setUp(self):
        """ Test case setup """
        super(CourseCreatorAdminTest, self).setUp()
        self.user = User.objects.create_user('test_user',
                                             '*****@*****.**',
                                             'foo')
        self.table_entry = CourseCreator(user=self.user)
        self.table_entry.save()

        self.admin = User.objects.create_user('Mark', '*****@*****.**',
                                              'foo')
        self.admin.is_staff = True

        self.request = HttpRequest()
        self.request.user = self.admin

        self.creator_admin = CourseCreatorAdmin(self.table_entry, AdminSite())

        self.studio_request_email = '*****@*****.**'
        self.enable_creator_group_patch = {
            "ENABLE_CREATOR_GROUP": True,
            "STUDIO_REQUEST_EMAIL": self.studio_request_email
        }

    @mock.patch('course_creators.admin.render_to_string',
                mock.Mock(side_effect=mock_render_to_string, autospec=True))
    @mock.patch('django.contrib.auth.models.User.email_user')
    def test_change_status(self, email_user):
        """
        Tests that updates to state impact the creator group maintained in authz.py and that e-mails are sent.
        """
        def change_state_and_verify_email(state, is_creator):
            """ Changes user state, verifies creator status, and verifies e-mail is sent based on transition """
            self._change_state(state)
            self.assertEqual(
                is_creator, auth.user_has_role(self.user, CourseCreatorRole()))

            context = {'studio_request_email': self.studio_request_email}
            if state == CourseCreator.GRANTED:
                template = 'emails/course_creator_granted.txt'
            elif state == CourseCreator.DENIED:
                template = 'emails/course_creator_denied.txt'
            else:
                template = 'emails/course_creator_revoked.txt'
            email_user.assert_called_with(
                mock_render_to_string('emails/course_creator_subject.txt',
                                      context),
                mock_render_to_string(template, context),
                self.studio_request_email)

        with mock.patch.dict('django.conf.settings.FEATURES',
                             self.enable_creator_group_patch):

            # User is initially unrequested.
            self.assertFalse(auth.user_has_role(self.user,
                                                CourseCreatorRole()))

            change_state_and_verify_email(CourseCreator.GRANTED, True)

            change_state_and_verify_email(CourseCreator.DENIED, False)

            change_state_and_verify_email(CourseCreator.GRANTED, True)

            change_state_and_verify_email(CourseCreator.PENDING, False)

            change_state_and_verify_email(CourseCreator.GRANTED, True)

            change_state_and_verify_email(CourseCreator.UNREQUESTED, False)

            change_state_and_verify_email(CourseCreator.DENIED, False)

    @mock.patch('course_creators.admin.render_to_string',
                mock.Mock(side_effect=mock_render_to_string, autospec=True))
    def test_mail_admin_on_pending(self):
        """
        Tests that the admin account is notified when a user is in the 'pending' state.
        """
        def check_admin_message_state(state, expect_sent_to_admin,
                                      expect_sent_to_user):
            """ Changes user state and verifies e-mail sent to admin address only when pending. """
            mail.outbox = []
            self._change_state(state)

            # If a message is sent to the user about course creator status change, it will be the first
            # message sent. Admin message will follow.
            base_num_emails = 1 if expect_sent_to_user else 0
            if expect_sent_to_admin:
                context = {
                    'user_name': "test_user",
                    'user_email': u'*****@*****.**'
                }
                self.assertEquals(base_num_emails + 1, len(mail.outbox),
                                  'Expected admin message to be sent')
                sent_mail = mail.outbox[base_num_emails]
                self.assertEquals(
                    mock_render_to_string(
                        'emails/course_creator_admin_subject.txt', context),
                    sent_mail.subject)
                self.assertEquals(
                    mock_render_to_string(
                        'emails/course_creator_admin_user_pending.txt',
                        context), sent_mail.body)
                self.assertEquals(self.studio_request_email,
                                  sent_mail.from_email)
                self.assertEqual([self.studio_request_email], sent_mail.to)
            else:
                self.assertEquals(base_num_emails, len(mail.outbox))

        with mock.patch.dict('django.conf.settings.FEATURES',
                             self.enable_creator_group_patch):
            # E-mail message should be sent to admin only when new state is PENDING, regardless of what
            # previous state was (unless previous state was already PENDING).
            # E-mail message sent to user only on transition into and out of GRANTED state.
            check_admin_message_state(CourseCreator.UNREQUESTED,
                                      expect_sent_to_admin=False,
                                      expect_sent_to_user=False)
            check_admin_message_state(CourseCreator.PENDING,
                                      expect_sent_to_admin=True,
                                      expect_sent_to_user=False)
            check_admin_message_state(CourseCreator.GRANTED,
                                      expect_sent_to_admin=False,
                                      expect_sent_to_user=True)
            check_admin_message_state(CourseCreator.DENIED,
                                      expect_sent_to_admin=False,
                                      expect_sent_to_user=True)
            check_admin_message_state(CourseCreator.GRANTED,
                                      expect_sent_to_admin=False,
                                      expect_sent_to_user=True)
            check_admin_message_state(CourseCreator.PENDING,
                                      expect_sent_to_admin=True,
                                      expect_sent_to_user=True)
            check_admin_message_state(CourseCreator.PENDING,
                                      expect_sent_to_admin=False,
                                      expect_sent_to_user=False)
            check_admin_message_state(CourseCreator.DENIED,
                                      expect_sent_to_admin=False,
                                      expect_sent_to_user=True)

    def _change_state(self, state):
        """ Helper method for changing state """
        self.table_entry.state = state
        self.creator_admin.save_model(self.request, self.table_entry, None,
                                      True)

    def test_add_permission(self):
        """
        Tests that staff cannot add entries
        """
        self.assertFalse(self.creator_admin.has_add_permission(self.request))

    def test_delete_permission(self):
        """
        Tests that staff cannot delete entries
        """
        self.assertFalse(self.creator_admin.has_delete_permission(
            self.request))

    def test_change_permission(self):
        """
        Tests that only staff can change entries
        """
        self.assertTrue(self.creator_admin.has_change_permission(self.request))

        self.request.user = self.user
        self.assertFalse(self.creator_admin.has_change_permission(
            self.request))

    def test_rate_limit_login(self):
        with mock.patch.dict('django.conf.settings.FEATURES',
                             {'ENABLE_CREATOR_GROUP': True}):
            post_params = {
                'username': self.user.username,
                'password': '******'
            }
            # try logging in 30 times, the default limit in the number of failed
            # login attempts in one 5 minute period before the rate gets limited
            for _ in xrange(30):
                response = self.client.post('/admin/login/', post_params)
                self.assertEquals(response.status_code, 200)

            response = self.client.post('/admin/login/', post_params)
            # Since we are using the default rate limit behavior, we are
            # expecting this to return a 403 error to indicate that there have
            # been too many attempts
            self.assertEquals(response.status_code, 403)
Exemple #6
0
class CourseCreatorAdminTest(TestCase):
    """
    Tests for course creator admin.
    """

    def setUp(self):
        """ Test case setup """
        self.user = User.objects.create_user('test_user', '*****@*****.**', 'foo')
        self.table_entry = CourseCreator(user=self.user)
        self.table_entry.save()

        self.admin = User.objects.create_user('Mark', '*****@*****.**', 'foo')
        self.admin.is_staff = True

        self.request = HttpRequest()
        self.request.user = self.admin

        self.creator_admin = CourseCreatorAdmin(self.table_entry, AdminSite())

        self.studio_request_email = '*****@*****.**'
        self.enable_creator_group_patch = {
            "ENABLE_CREATOR_GROUP": True,
            "STUDIO_REQUEST_EMAIL": self.studio_request_email
        }

    @mock.patch('course_creators.admin.render_to_string', mock.Mock(side_effect=mock_render_to_string, autospec=True))
    @mock.patch('django.contrib.auth.models.User.email_user')
    def test_change_status(self, email_user):
        """
        Tests that updates to state impact the creator group maintained in authz.py and that e-mails are sent.
        """

        def change_state_and_verify_email(state, is_creator):
            """ Changes user state, verifies creator status, and verifies e-mail is sent based on transition """
            self._change_state(state)
            self.assertEqual(is_creator, auth.has_access(self.user, CourseCreatorRole()))

            context = {'studio_request_email': self.studio_request_email}
            if state == CourseCreator.GRANTED:
                template = 'emails/course_creator_granted.txt'
            elif state == CourseCreator.DENIED:
                template = 'emails/course_creator_denied.txt'
            else:
                template = 'emails/course_creator_revoked.txt'
            email_user.assert_called_with(
                mock_render_to_string('emails/course_creator_subject.txt', context),
                mock_render_to_string(template, context),
                self.studio_request_email
            )

        with mock.patch.dict('django.conf.settings.FEATURES', self.enable_creator_group_patch):

            # User is initially unrequested.
            self.assertFalse(auth.has_access(self.user, CourseCreatorRole()))

            change_state_and_verify_email(CourseCreator.GRANTED, True)

            change_state_and_verify_email(CourseCreator.DENIED, False)

            change_state_and_verify_email(CourseCreator.GRANTED, True)

            change_state_and_verify_email(CourseCreator.PENDING, False)

            change_state_and_verify_email(CourseCreator.GRANTED, True)

            change_state_and_verify_email(CourseCreator.UNREQUESTED, False)

            change_state_and_verify_email(CourseCreator.DENIED, False)

    @mock.patch('course_creators.admin.render_to_string', mock.Mock(side_effect=mock_render_to_string, autospec=True))
    def test_mail_admin_on_pending(self):
        """
        Tests that the admin account is notified when a user is in the 'pending' state.
        """

        def check_admin_message_state(state, expect_sent_to_admin, expect_sent_to_user):
            """ Changes user state and verifies e-mail sent to admin address only when pending. """
            mail.outbox = []
            self._change_state(state)

            # If a message is sent to the user about course creator status change, it will be the first
            # message sent. Admin message will follow.
            base_num_emails = 1 if expect_sent_to_user else 0
            if expect_sent_to_admin:
                context = {'user_name': "test_user", 'user_email': '*****@*****.**'}
                self.assertEquals(base_num_emails + 1, len(mail.outbox), 'Expected admin message to be sent')
                sent_mail = mail.outbox[base_num_emails]
                self.assertEquals(
                    mock_render_to_string('emails/course_creator_admin_subject.txt', context),
                    sent_mail.subject
                )
                self.assertEquals(
                    mock_render_to_string('emails/course_creator_admin_user_pending.txt', context),
                    sent_mail.body
                )
                self.assertEquals(self.studio_request_email, sent_mail.from_email)
                self.assertEqual([self.studio_request_email], sent_mail.to)
            else:
                self.assertEquals(base_num_emails, len(mail.outbox))

        with mock.patch.dict('django.conf.settings.FEATURES', self.enable_creator_group_patch):
            # E-mail message should be sent to admin only when new state is PENDING, regardless of what
            # previous state was (unless previous state was already PENDING).
            # E-mail message sent to user only on transition into and out of GRANTED state.
            check_admin_message_state(CourseCreator.UNREQUESTED, expect_sent_to_admin=False, expect_sent_to_user=False)
            check_admin_message_state(CourseCreator.PENDING, expect_sent_to_admin=True, expect_sent_to_user=False)
            check_admin_message_state(CourseCreator.GRANTED, expect_sent_to_admin=False, expect_sent_to_user=True)
            check_admin_message_state(CourseCreator.DENIED, expect_sent_to_admin=False, expect_sent_to_user=True)
            check_admin_message_state(CourseCreator.GRANTED, expect_sent_to_admin=False, expect_sent_to_user=True)
            check_admin_message_state(CourseCreator.PENDING, expect_sent_to_admin=True, expect_sent_to_user=True)
            check_admin_message_state(CourseCreator.PENDING, expect_sent_to_admin=False, expect_sent_to_user=False)
            check_admin_message_state(CourseCreator.DENIED, expect_sent_to_admin=False, expect_sent_to_user=True)

    def _change_state(self, state):
        """ Helper method for changing state """
        self.table_entry.state = state
        self.creator_admin.save_model(self.request, self.table_entry, None, True)

    def test_add_permission(self):
        """
        Tests that staff cannot add entries
        """
        self.assertFalse(self.creator_admin.has_add_permission(self.request))

    def test_delete_permission(self):
        """
        Tests that staff cannot delete entries
        """
        self.assertFalse(self.creator_admin.has_delete_permission(self.request))

    def test_change_permission(self):
        """
        Tests that only staff can change entries
        """
        self.assertTrue(self.creator_admin.has_change_permission(self.request))

        self.request.user = self.user
        self.assertFalse(self.creator_admin.has_change_permission(self.request))

    def test_rate_limit_login(self):
        with mock.patch.dict('django.conf.settings.FEATURES', {'ENABLE_CREATOR_GROUP': True}):
            post_params = {'username': self.user.username, 'password': '******'}
            # try logging in 30 times, the default limit in the number of failed
            # login attempts in one 5 minute period before the rate gets limited
            for _ in xrange(30):
                response = self.client.post('/admin/', post_params)
                self.assertEquals(response.status_code, 200)

            response = self.client.post('/admin/', post_params)
            # Since we are using the default rate limit behavior, we are
            # expecting this to return a 403 error to indicate that there have
            # been too many attempts
            self.assertEquals(response.status_code, 403)
Exemple #7
0
class IndexCourseCreatorTests(CourseTestCase):
    """
    Tests the various permutations of course creator status.
    """
    def setUp(self):
        super(IndexCourseCreatorTests, self).setUp()

        self.index_url = reverse("index")
        self.request_access_url = reverse("request_course_creator")

        # Disable course creation takes precedence over enable creator group. I have enabled the
        # latter to make this clear.
        self.disable_course_creation = {
            "DISABLE_COURSE_CREATION": True,
            "ENABLE_CREATOR_GROUP": True,
            'STAFF_EMAIL': '*****@*****.**',
        }

        self.enable_creator_group = {"ENABLE_CREATOR_GROUP": True}

        self.admin = User.objects.create_user('Mark', '*****@*****.**', 'foo')
        self.admin.is_staff = True

    def test_get_course_creator_status_disable_creation(self):
        # DISABLE_COURSE_CREATION is True (this is the case on edx, where we have a marketing site).
        # Only edx staff can create courses.
        with mock.patch.dict('django.conf.settings.MITX_FEATURES', self.disable_course_creation):
            self.assertTrue(self.user.is_staff)
            self.assertEquals('granted', _get_course_creator_status(self.user))
            self._set_user_non_staff()
            self.assertFalse(self.user.is_staff)
            self.assertEquals('disallowed_for_this_site', _get_course_creator_status(self.user))

    def test_get_course_creator_status_default_cause(self):
        # Neither ENABLE_CREATOR_GROUP nor DISABLE_COURSE_CREATION are enabled. Anyone can create a course.
        self.assertEquals('granted', _get_course_creator_status(self.user))
        self._set_user_non_staff()
        self.assertEquals('granted', _get_course_creator_status(self.user))

    def test_get_course_creator_status_creator_group(self):
        # ENABLE_CREATOR_GROUP is True. This is the case on edge.
        # Only staff members and users who have been granted access can create courses.
        with mock.patch.dict('django.conf.settings.MITX_FEATURES', self.enable_creator_group):
            # Staff members can always create courses.
            self.assertEquals('granted', _get_course_creator_status(self.user))
            # Non-staff must request access.
            self._set_user_non_staff()
            self.assertEquals('unrequested', _get_course_creator_status(self.user))
            # Staff user requests access.
            self.client.post(self.request_access_url)
            self.assertEquals('pending', _get_course_creator_status(self.user))

    def test_get_course_creator_status_creator_group_granted(self):
        # ENABLE_CREATOR_GROUP is True. This is the case on edge.
        # Check return value for a non-staff user who has been granted access.
        with mock.patch.dict('django.conf.settings.MITX_FEATURES', self.enable_creator_group):
            self._set_user_non_staff()
            add_user_with_status_granted(self.admin, self.user)
            self.assertEquals('granted', _get_course_creator_status(self.user))

    def test_get_course_creator_status_creator_group_denied(self):
        # ENABLE_CREATOR_GROUP is True. This is the case on edge.
        # Check return value for a non-staff user who has been denied access.
        with mock.patch.dict('django.conf.settings.MITX_FEATURES', self.enable_creator_group):
            self._set_user_non_staff()
            self._set_user_denied()
            self.assertEquals('denied', _get_course_creator_status(self.user))

    def test_disable_course_creation_enabled_non_staff(self):
        # Test index page content when DISABLE_COURSE_CREATION is True, non-staff member.
        with mock.patch.dict('django.conf.settings.MITX_FEATURES', self.disable_course_creation):
            self._set_user_non_staff()
            self._assert_cannot_create()

    def test_disable_course_creation_enabled_staff(self):
        # Test index page content when DISABLE_COURSE_CREATION is True, staff member.
        with mock.patch.dict('django.conf.settings.MITX_FEATURES', self.disable_course_creation):
            resp = self._assert_can_create()
            self.assertFalse('Email staff to create course' in resp.content)

    def test_can_create_by_default(self):
        # Test index page content with neither ENABLE_CREATOR_GROUP nor DISABLE_COURSE_CREATION enabled.
        # Anyone can create a course.
        self._assert_can_create()
        self._set_user_non_staff()
        self._assert_can_create()

    def test_course_creator_group_enabled(self):
        # Test index page content with ENABLE_CREATOR_GROUP True.
        # Staff can always create a course, others must request access.
        with mock.patch.dict('django.conf.settings.MITX_FEATURES', self.enable_creator_group):
            # Staff members can always create courses.
            self._assert_can_create()

            # Non-staff case.
            self._set_user_non_staff()
            resp = self._assert_cannot_create()
            self.assertTrue(self.request_access_url in resp.content)

            # Now request access.
            self.client.post(self.request_access_url)

            # Still cannot create a course, but the "request access button" is no longer there.
            resp = self._assert_cannot_create()
            self.assertFalse(self.request_access_url in resp.content)
            self.assertTrue('has-status is-pending' in resp.content)

    def test_course_creator_group_granted(self):
        # Test index page content with ENABLE_CREATOR_GROUP True, non-staff member with access granted.
        with mock.patch.dict('django.conf.settings.MITX_FEATURES', self.enable_creator_group):
            self._set_user_non_staff()
            add_user_with_status_granted(self.admin, self.user)
            self._assert_can_create()

    def test_course_creator_group_denied(self):
        # Test index page content with ENABLE_CREATOR_GROUP True, non-staff member with access denied.
        with mock.patch.dict('django.conf.settings.MITX_FEATURES', self.enable_creator_group):
            self._set_user_non_staff()
            self._set_user_denied()
            resp = self._assert_cannot_create()
            self.assertFalse(self.request_access_url in resp.content)
            self.assertTrue('has-status is-denied' in resp.content)

    def _assert_can_create(self):
        """
        Helper method that posts to the index page and checks that the user can create a course.

        Returns the response from the post.
        """
        resp = self.client.post(self.index_url)
        self.assertTrue('new-course-button' in resp.content)
        self.assertFalse(self.request_access_url in resp.content)
        self.assertFalse('Email staff to create course' in resp.content)
        return resp

    def _assert_cannot_create(self):
        """
        Helper method that posts to the index page and checks that the user cannot create a course.

        Returns the response from the post.
        """
        resp = self.client.post(self.index_url)
        self.assertFalse('new-course-button' in resp.content)
        return resp

    def _set_user_non_staff(self):
        """
        Sets user as non-staff.
        """
        self.user.is_staff = False
        self.user.save()

    def _set_user_denied(self):
        """
        Sets course creator status to denied in admin table.
        """
        self.table_entry = CourseCreator(user=self.user)
        self.table_entry.save()

        self.deny_request = HttpRequest()
        self.deny_request.user = self.admin

        self.creator_admin = CourseCreatorAdmin(self.table_entry, AdminSite())

        self.table_entry.state = CourseCreator.DENIED
        self.creator_admin.save_model(self.deny_request, self.table_entry, None, True)
class CourseCreatorAdminTest(TestCase):
    """
    Tests for course creator admin.
    """

    def setUp(self):
        """ Test case setup """
        self.user = User.objects.create_user('test_user', '*****@*****.**', 'foo')
        self.table_entry = CourseCreator(user=self.user)
        self.table_entry.save()

        self.admin = User.objects.create_user('Mark', '*****@*****.**', 'foo')
        self.admin.is_staff = True

        self.request = HttpRequest()
        self.request.user = self.admin

        self.creator_admin = CourseCreatorAdmin(self.table_entry, AdminSite())

    @mock.patch('course_creators.admin.render_to_string', mock.Mock(side_effect=mock_render_to_string, autospec=True))
    @mock.patch('django.contrib.auth.models.User.email_user')
    def test_change_status(self, email_user):
        """
        Tests that updates to state impact the creator group maintained in authz.py and that e-mails are sent.
        """
        STUDIO_REQUEST_EMAIL = '*****@*****.**' 
        
        def change_state(state, is_creator):
            """ Helper method for changing state """
            self.table_entry.state = state
            self.creator_admin.save_model(self.request, self.table_entry, None, True)
            self.assertEqual(is_creator, is_user_in_creator_group(self.user))
            
            context = {'studio_request_email': STUDIO_REQUEST_EMAIL}
            if state == CourseCreator.GRANTED:
                template = 'emails/course_creator_granted.txt'
            elif state == CourseCreator.DENIED:
                template = 'emails/course_creator_denied.txt'
            else:
                template = 'emails/course_creator_revoked.txt'
            email_user.assert_called_with(
                mock_render_to_string('emails/course_creator_subject.txt', context),
                mock_render_to_string(template, context),
                STUDIO_REQUEST_EMAIL
            )

        with mock.patch.dict(
            'django.conf.settings.MITX_FEATURES',
            {
                "ENABLE_CREATOR_GROUP": True,
                "STUDIO_REQUEST_EMAIL": STUDIO_REQUEST_EMAIL
            }):

            # User is initially unrequested.
            self.assertFalse(is_user_in_creator_group(self.user))

            change_state(CourseCreator.GRANTED, True)

            change_state(CourseCreator.DENIED, False)

            change_state(CourseCreator.GRANTED, True)

            change_state(CourseCreator.PENDING, False)

            change_state(CourseCreator.GRANTED, True)

            change_state(CourseCreator.UNREQUESTED, False)

    def test_add_permission(self):
        """
        Tests that staff cannot add entries
        """
        self.assertFalse(self.creator_admin.has_add_permission(self.request))

    def test_delete_permission(self):
        """
        Tests that staff cannot delete entries
        """
        self.assertFalse(self.creator_admin.has_delete_permission(self.request))

    def test_change_permission(self):
        """
        Tests that only staff can change entries
        """
        self.assertTrue(self.creator_admin.has_change_permission(self.request))

        self.request.user = self.user
        self.assertFalse(self.creator_admin.has_change_permission(self.request))
class CourseCreatorAdminTest(TestCase):
    """
    Tests for course creator admin.
    """

    def setUp(self):
        """ Test case setup """
        self.user = User.objects.create_user('test_user', '*****@*****.**', 'foo')
        self.table_entry = CourseCreator(user=self.user)
        self.table_entry.save()

        self.admin = User.objects.create_user('Mark', '*****@*****.**', 'foo')
        self.admin.is_staff = True

        self.request = HttpRequest()
        self.request.user = self.admin

        self.creator_admin = CourseCreatorAdmin(self.table_entry, AdminSite())

    @mock.patch('course_creators.admin.render_to_string', mock.Mock(side_effect=mock_render_to_string, autospec=True))
    @mock.patch('django.contrib.auth.models.User.email_user')
    def test_change_status(self, email_user):
        """
        Tests that updates to state impact the creator group maintained in authz.py and that e-mails are sent.
        """
        STUDIO_REQUEST_EMAIL = '*****@*****.**'

        def change_state(state, is_creator):
            """ Helper method for changing state """
            self.table_entry.state = state
            self.creator_admin.save_model(self.request, self.table_entry, None, True)
            self.assertEqual(is_creator, is_user_in_creator_group(self.user))

            context = {'studio_request_email': STUDIO_REQUEST_EMAIL}
            if state == CourseCreator.GRANTED:
                template = 'emails/course_creator_granted.txt'
            elif state == CourseCreator.DENIED:
                template = 'emails/course_creator_denied.txt'
            else:
                template = 'emails/course_creator_revoked.txt'
            email_user.assert_called_with(
                mock_render_to_string('emails/course_creator_subject.txt', context),
                mock_render_to_string(template, context),
                STUDIO_REQUEST_EMAIL
            )

        with mock.patch.dict(
            'django.conf.settings.MITX_FEATURES',
            {
                "ENABLE_CREATOR_GROUP": True,
                "STUDIO_REQUEST_EMAIL": STUDIO_REQUEST_EMAIL
            }
        ):

            # User is initially unrequested.
            self.assertFalse(is_user_in_creator_group(self.user))

            change_state(CourseCreator.GRANTED, True)

            change_state(CourseCreator.DENIED, False)

            change_state(CourseCreator.GRANTED, True)

            change_state(CourseCreator.PENDING, False)

            change_state(CourseCreator.GRANTED, True)

            change_state(CourseCreator.UNREQUESTED, False)

    def test_add_permission(self):
        """
        Tests that staff cannot add entries
        """
        self.assertFalse(self.creator_admin.has_add_permission(self.request))

    def test_delete_permission(self):
        """
        Tests that staff cannot delete entries
        """
        self.assertFalse(self.creator_admin.has_delete_permission(self.request))

    def test_change_permission(self):
        """
        Tests that only staff can change entries
        """
        self.assertTrue(self.creator_admin.has_change_permission(self.request))

        self.request.user = self.user
        self.assertFalse(self.creator_admin.has_change_permission(self.request))

    def test_rate_limit_login(self):
        with mock.patch.dict('django.conf.settings.MITX_FEATURES', {'ENABLE_CREATOR_GROUP': True}):
            post_params = {'username': self.user.username, 'password': '******'}
            # try logging in 30 times, the default limit in the number of failed
            # login attempts in one 5 minute period before the rate gets limited
            for _ in xrange(30):
                response = self.client.post('/admin/', post_params)
                self.assertEquals(response.status_code, 200)

            response = self.client.post('/admin/', post_params)
            # Since we are using the default rate limit behavior, we are
            # expecting this to return a 403 error to indicate that there have
            # been too many attempts
            self.assertEquals(response.status_code, 403)
Exemple #10
0
class CourseCreatorAdminTest(TestCase):
    """
    Tests for course creator admin.
    """

    def setUp(self):
        """ Test case setup """
        self.user = User.objects.create_user('test_user', '*****@*****.**', 'foo')
        self.table_entry = CourseCreator(user=self.user)
        self.table_entry.save()

        self.admin = User.objects.create_user('Mark', '*****@*****.**', 'foo')
        self.admin.is_staff = True

        self.request = HttpRequest()
        self.request.user = self.admin

        self.creator_admin = CourseCreatorAdmin(self.table_entry, AdminSite())

    def test_change_status(self):
        """
        Tests that updates to state impact the creator group maintained in authz.py.
        """
        def change_state(state, is_creator):
            """ Helper method for changing state """
            self.table_entry.state = state
            self.creator_admin.save_model(self.request, self.table_entry, None, True)
            self.assertEqual(is_creator, is_user_in_creator_group(self.user))

        with mock.patch.dict('django.conf.settings.MITX_FEATURES', {"ENABLE_CREATOR_GROUP": True}):
            # User is initially unrequested.
            self.assertFalse(is_user_in_creator_group(self.user))

            change_state(CourseCreator.GRANTED, True)

            change_state(CourseCreator.DENIED, False)

            change_state(CourseCreator.GRANTED, True)

            change_state(CourseCreator.PENDING, False)

            change_state(CourseCreator.GRANTED, True)

            change_state(CourseCreator.UNREQUESTED, False)

    def test_add_permission(self):
        """
        Tests that staff cannot add entries
        """
        self.assertFalse(self.creator_admin.has_add_permission(self.request))

    def test_delete_permission(self):
        """
        Tests that staff cannot delete entries
        """
        self.assertFalse(self.creator_admin.has_delete_permission(self.request))

    def test_change_permission(self):
        """
        Tests that only staff can change entries
        """
        self.assertTrue(self.creator_admin.has_change_permission(self.request))

        self.request.user = self.user
        self.assertFalse(self.creator_admin.has_change_permission(self.request))