test_context_processors.py 6.61 KB
Newer Older
1 2
import datetime

3
from django.contrib.auth import authenticate
4 5
from django.contrib.auth.context_processors import PermLookupDict, PermWrapper
from django.contrib.auth.models import Permission, User
6
from django.contrib.contenttypes.models import ContentType
7
from django.db.models import Q
8
from django.test import SimpleTestCase, TestCase, override_settings
9 10

from .settings import AUTH_MIDDLEWARE_CLASSES, AUTH_TEMPLATES
11

12

13
class MockUser(object):
14 15
    def has_module_perms(self, perm):
        if perm == 'mockapp':
16 17 18 19
            return True
        return False

    def has_perm(self, perm):
20
        if perm == 'mockapp.someperm':
21 22 23 24
            return True
        return False


25
class PermWrapperTests(SimpleTestCase):
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
    """
    Test some details of the PermWrapper implementation.
    """
    class EQLimiterObject(object):
        """
        This object makes sure __eq__ will not be called endlessly.
        """
        def __init__(self):
            self.eq_calls = 0

        def __eq__(self, other):
            if self.eq_calls > 0:
                return True
            self.eq_calls += 1
            return False

    def test_permwrapper_in(self):
        """
44
        Test that 'something' in PermWrapper works as expected.
45 46
        """
        perms = PermWrapper(MockUser())
47
        # Works for modules and full permissions.
48 49 50 51
        self.assertIn('mockapp', perms)
        self.assertNotIn('nonexisting', perms)
        self.assertIn('mockapp.someperm', perms)
        self.assertNotIn('mockapp.nonexisting', perms)
52 53

    def test_permlookupdict_in(self):
54 55 56
        """
        No endless loops if accessed with 'in' - refs #18979.
        """
57 58 59 60 61
        pldict = PermLookupDict(MockUser(), 'mockapp')
        with self.assertRaises(TypeError):
            self.EQLimiterObject() in pldict


62
@override_settings(
63
    PASSWORD_HASHERS=['django.contrib.auth.hashers.SHA1PasswordHasher'],
64
    ROOT_URLCONF='auth_tests.urls',
65
    TEMPLATES=AUTH_TEMPLATES,
66 67
    USE_TZ=False,                           # required for loading the fixture
)
68 69 70 71
class AuthContextProcessorTests(TestCase):
    """
    Tests for the ``django.contrib.auth.context_processors.auth`` processor
    """
72 73 74 75 76 77 78 79 80 81

    @classmethod
    def setUpTestData(cls):
        # password = "secret"
        cls.u1 = User.objects.create(
            id=100, password='sha1$995a3$6011485ea3834267d719b4c801409b8b1ddd0158',
            last_login=datetime.datetime(2007, 5, 30, 13, 20, 10), is_superuser=True, username='super',
            first_name='Super', last_name='User', email='super@example.com',
            is_staff=True, is_active=True, date_joined=datetime.datetime(2007, 5, 30, 13, 20, 10)
        )
82

83
    @override_settings(MIDDLEWARE_CLASSES=AUTH_MIDDLEWARE_CLASSES)
84 85 86 87 88 89 90 91
    def test_session_not_accessed(self):
        """
        Tests that the session is not accessed simply by including
        the auth context processor
        """
        response = self.client.get('/auth_processor_no_attr_access/')
        self.assertContains(response, "Session not accessed")

92
    @override_settings(MIDDLEWARE_CLASSES=AUTH_MIDDLEWARE_CLASSES)
93 94 95 96 97 98 99 100 101
    def test_session_is_accessed(self):
        """
        Tests that the session is accessed if the auth context processor
        is used and relevant attributes accessed.
        """
        response = self.client.get('/auth_processor_attr_access/')
        self.assertContains(response, "Session accessed")

    def test_perms_attrs(self):
102 103 104 105 106 107
        u = User.objects.create_user(username='normal', password='secret')
        u.user_permissions.add(
            Permission.objects.get(
                content_type=ContentType.objects.get_for_model(Permission),
                codename='add_permission'))
        self.client.login(username='normal', password='secret')
108 109
        response = self.client.get('/auth_processor_perms/')
        self.assertContains(response, "Has auth permissions")
110 111
        self.assertContains(response, "Has auth.add_permission permissions")
        self.assertNotContains(response, "nonexisting")
Tim Graham's avatar
Tim Graham committed
112

113 114 115 116 117 118 119 120 121 122 123
    def test_perm_in_perms_attrs(self):
        u = User.objects.create_user(username='normal', password='secret')
        u.user_permissions.add(
            Permission.objects.get(
                content_type=ContentType.objects.get_for_model(Permission),
                codename='add_permission'))
        self.client.login(username='normal', password='secret')
        response = self.client.get('/auth_processor_perm_in_perms/')
        self.assertContains(response, "Has auth permissions")
        self.assertContains(response, "Has auth.add_permission permissions")
        self.assertNotContains(response, "nonexisting")
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160

    def test_message_attrs(self):
        self.client.login(username='super', password='secret')
        response = self.client.get('/auth_processor_messages/')
        self.assertContains(response, "Message 1")

    def test_user_attrs(self):
        """
        Test that the lazy objects returned behave just like the wrapped objects.
        """
        # These are 'functional' level tests for common use cases.  Direct
        # testing of the implementation (SimpleLazyObject) is in the 'utils'
        # tests.
        self.client.login(username='super', password='secret')
        user = authenticate(username='super', password='secret')
        response = self.client.get('/auth_processor_user/')
        self.assertContains(response, "unicode: super")
        self.assertContains(response, "id: 100")
        self.assertContains(response, "username: super")
        # bug #12037 is tested by the {% url %} in the template:
        self.assertContains(response, "url: /userpage/super/")

        # See if this object can be used for queries where a Q() comparing
        # a user can be used with another Q() (in an AND or OR fashion).
        # This simulates what a template tag might do with the user from the
        # context. Note that we don't need to execute a query, just build it.
        #
        # The failure case (bug #12049) on Python 2.4 with a LazyObject-wrapped
        # User is a fatal TypeError: "function() takes at least 2 arguments
        # (0 given)" deep inside deepcopy().
        #
        # Python 2.5 and 2.6 succeeded, but logged internally caught exception
        # spew:
        #
        #    Exception RuntimeError: 'maximum recursion depth exceeded while
        #    calling a Python object' in <type 'exceptions.AttributeError'>
        #    ignored"
161
        Q(user=response.context['user']) & Q(someflag=True)
162 163 164 165 166

        # Tests for user equality.  This is hard because User defines
        # equality in a non-duck-typing way
        # See bug #12060
        self.assertEqual(response.context['user'], user)
167
        self.assertEqual(user, response.context['user'])