import mock
from django.test import TestCase
from django.conf import settings
from django.core.exceptions import PermissionDenied


from mapentity import app_settings
from mapentity.decorators import view_permission_required


class ViewPermissionRequiredTestCase(TestCase):
    def setUp(self):
        # Fake request and its positional and keywords arguments.
        self.request = mock.MagicMock()
        self.request.user.is_anonymous = mock.MagicMock(return_value=False)
        self.request_args = ['fake_arg']
        self.request_kwargs = {'fake': 'kwarg'}
        self.mocked_view = mock.MagicMock()

    def run_decorated_view(self, raise_exception=True):
        """Setup, decorate and call view, then return response."""
        decorator = view_permission_required(raise_exception=raise_exception)
        decorated_view = decorator(self.mocked_view)
        # Return response.
        return decorated_view(self.mocked_view,
                              self.request,
                              *self.request_args,
                              **self.request_kwargs)

    def test_anonymous_are_redirected_to_login(self):
        self.request.user.is_anonymous.return_value = True
        self.request.user.has_perm.return_value = False
        response = self.run_decorated_view()
        self.assertEqual(response.status_code, 302)
        self.assertTrue(response['Location'].startswith(settings.LOGIN_URL))

    def test_unauthorized_is_rendered_if_missing_perm(self):
        self.request.user.is_anonymous.return_value = False
        self.request.user.has_perm.return_value = False
        self.assertRaises(PermissionDenied, self.run_decorated_view)

    def test_permission_is_taken_from_view(self):
        self.request.user.is_anonymous.return_value = False
        self.mocked_view.get_view_perm.return_value = 'view-perm'
        self.run_decorated_view()
        self.request.user.has_perm.assert_called_once_with('view-perm')

    def test_anonymous_may_be_authorized_from_settings(self):
        self.request.user.is_authenticated.return_value = False
        self.mocked_view.get_view_perm.return_value = 'view-perm'
        app_settings['ANONYMOUS_VIEWS_PERMS'] = ('view-perm',)
        response = self.run_decorated_view()
        self.assertNotEqual(response.status_code, 200)

    def test_a_message_is_show_when_user_is_redirected(self):
        self.request.user.has_perm.return_value = False
        with mock.patch('django.contrib.messages.warning') as patched:
            self.run_decorated_view(raise_exception=False)
            patched.assert_called_once_with(self.request,
                                            u'Access to the requested resource is restricted. You have been redirected.')
@@ -123,16 +123,60 @@
 nDenied%0A
+from django.core.urlresolvers import reverse
 %0A%0Afrom m
@@ -702,16 +702,32 @@
 ion=True
+, login_url=None
 ):%0A     
@@ -864,16 +864,82 @@
 xception
+,%0A                                             login_url=login_url
 )%0A      
@@ -2865,8 +2865,437 @@
 ected.')
+%0A%0A    def test_it_redirects_to_the_specified_view(self):%0A        self.request.user.has_perm.return_value = False%0A        response = self.run_decorated_view(raise_exception=False,%0A                                           login_url='tests:dummymodel_list')%0A        self.assertEqual(response.status_code, 302)%0A        dummylist_url = reverse('tests:dummymodel_list')%0A        self.assertTrue(dummylist_url in response%5B'Location'%5D)%0A

Check redirections work with decorator