Skip to content

Commit 44b2dc0

Browse files
authored
Merge pull request #51 from farridav/farridav/add_missing_tests
Adds missing tests
2 parents a89c989 + c5812ca commit 44b2dc0

File tree

11 files changed

+278
-97
lines changed

11 files changed

+278
-97
lines changed

dev-requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ ipdb # ipython breakpoints
1717
django-extensions # Django Sugar for development
1818
faker # less fake fake data
1919
coveralls # Publish code coverage to coveralls
20+
beautifulsoup4 # Structure HTML documents into navigable things for test assertions

docs/configuration.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ JAZZMIN_SETTINGS = {
6464
'name': 'Make Messages',
6565
'url': 'make_messages',
6666
'icon': 'fa-comments',
67-
'permissions': ['polls.view_polls']
67+
'permissions': ['polls.view_poll']
6868
}]
6969
},
7070

@@ -115,7 +115,7 @@ Example:
115115
'icon': 'fa-comments',
116116
117117
# a list of permissions the user must have to see this link (optional)
118-
'permissions': ['polls.view_polls']
118+
'permissions': ['polls.view_poll']
119119
}]
120120
},
121121

jazzmin/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
version = '2.0.1'
1+
version = '2.1.1'
22
default_app_config = 'jazzmin.apps.JazzminConfig'

jazzmin/settings.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,13 +141,19 @@ def get_settings():
141141
if 'url' in link:
142142
link['url'] = get_custom_url(link['url'])
143143
elif 'model' in link:
144-
link['name'] = get_model_meta(link['model']).verbose_name_plural.title()
144+
model_meta = get_model_meta(link['model'])
145+
link['name'] = model_meta.verbose_name_plural.title() if model_meta else link['model']
145146
link['url'] = get_admin_url(link['model'])
146147
elif 'app' in link:
147148
link['name'] = link['app'].title()
148149
link['app_children'] = get_app_admin_urls(link['app'])
149150

151+
if type(jazzmin_settings['hide_apps']) == str:
152+
jazzmin_settings['hide_apps'] = [jazzmin_settings['hide_apps']]
150153
jazzmin_settings['hide_apps'] = [x.lower() for x in jazzmin_settings['hide_apps']]
154+
155+
if type(jazzmin_settings['hide_models']) == str:
156+
jazzmin_settings['hide_models'] = [jazzmin_settings['hide_models']]
151157
jazzmin_settings['hide_models'] = [x.lower() for x in jazzmin_settings['hide_models']]
152158

153159
return jazzmin_settings

jazzmin/templatetags/jazzmin.py

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,45 +13,45 @@
1313

1414
from .. import version
1515
from ..settings import get_settings, get_ui_tweaks
16-
from ..utils import order_with_respect_to, get_filter_id, get_custom_url, get_admin_url, get_model_permissions
16+
from ..utils import order_with_respect_to, get_filter_id, get_custom_url, get_admin_url, get_view_permissions
1717

1818
User = get_user_model()
1919
register = Library()
2020
logger = logging.getLogger(__name__)
21-
OPTIONS = get_settings()
22-
UI_TWEAKS = get_ui_tweaks()
2321

2422

2523
@register.simple_tag(takes_context=True)
2624
def get_side_menu(context):
2725
"""
2826
Get the list of apps and models to render out in the side menu and on the dashboard page
2927
"""
28+
3029
user = context.get('user')
3130
if not user:
3231
return []
3332

34-
model_permissions = get_model_permissions(user)
33+
model_permissions = get_view_permissions(user)
34+
options = get_settings()
3535

3636
menu = []
3737
available_apps = copy.deepcopy(context.get('available_apps', []))
3838
for app in available_apps:
3939
app_label = app['app_label'].lower()
40-
if app_label in OPTIONS['hide_apps']:
40+
if app_label in options['hide_apps']:
4141
continue
4242

4343
allowed_models = []
4444
for model in app.get('models', []):
4545
model_str = '{app_label}.{model}'.format(app_label=app_label, model=model["object_name"]).lower()
4646
if model_str not in model_permissions:
4747
continue
48-
if model_str in OPTIONS.get('hide_models', []):
48+
if model_str in options.get('hide_models', []):
4949
continue
5050

51-
model['icon'] = OPTIONS.get('icons', {}).get(model_str)
51+
model['icon'] = options.get('icons', {}).get(model_str)
5252
allowed_models.append(model)
5353

54-
for custom_link in OPTIONS.get('custom_links', {}).get(app_label, []):
54+
for custom_link in options.get('custom_links', {}).get(app_label, []):
5555

5656
perm_matches = []
5757
for perm in custom_link.get('permissions', []):
@@ -71,8 +71,8 @@ def get_side_menu(context):
7171
app['models'] = allowed_models
7272
menu.append(app)
7373

74-
if OPTIONS.get('order_with_respect_to'):
75-
menu = order_with_respect_to(menu, OPTIONS['order_with_respect_to'])
74+
if options.get('order_with_respect_to'):
75+
menu = order_with_respect_to(menu, options['order_with_respect_to'])
7676

7777
return menu
7878

@@ -82,10 +82,11 @@ def get_top_menu(user):
8282
if not user:
8383
return []
8484

85-
model_permissions = get_model_permissions(user)
85+
model_permissions = get_view_permissions(user)
86+
options = get_settings()
8687

8788
menu = []
88-
for item in get_settings().get('topmenu_links', []):
89+
for item in options.get('topmenu_links', []):
8990

9091
perm_matches = []
9192
for perm in item.get('permissions', []):
@@ -112,21 +113,15 @@ def get_jazzmin_settings():
112113
"""
113114
Return Jazzmin settings
114115
"""
115-
return OPTIONS
116+
return get_settings()
116117

117118

118119
@register.simple_tag
119120
def get_jazzmin_ui_tweaks():
120121
"""
121122
Return Jazzmin ui tweaks
122-
123-
Find all the places references in ui-builder.js
124-
125-
and get template variables in there
126-
127-
ensure we have sane defaults
128123
"""
129-
return UI_TWEAKS
124+
return get_ui_tweaks()
130125

131126

132127
@register.simple_tag
@@ -143,11 +138,12 @@ def get_user_avatar(user):
143138
For the given user, try to get the avatar image
144139
"""
145140
no_avatar = static("adminlte/img/user2-160x160.jpg")
141+
options = get_settings()
146142

147-
if not OPTIONS.get('user_avatar'):
143+
if not options.get('user_avatar'):
148144
return no_avatar
149145

150-
avatar_field = getattr(user, OPTIONS['user_avatar'], None)
146+
avatar_field = getattr(user, options['user_avatar'], None)
151147
if avatar_field:
152148
return avatar_field.url
153149

jazzmin/utils.py

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def order_with_respect_to(first, reference):
2626

2727
def get_admin_url(instance, **kwargs):
2828
"""
29-
Return the admin URL for the given instance, model class or <app>/<model> string
29+
Return the admin URL for the given instance, model class or <app>.<model> string
3030
"""
3131
url = '#'
3232

@@ -52,7 +52,7 @@ def get_admin_url(instance, **kwargs):
5252
app_label=app_label, model_name=model_name
5353
), args=(instance.pk,))
5454

55-
except NoReverseMatch:
55+
except (NoReverseMatch, ValueError):
5656
logger.error('Couldnt reverse url from {instance}'.format(instance=instance))
5757

5858
if kwargs:
@@ -88,9 +88,12 @@ def get_model_meta(model_str):
8888
"""
8989
Get the plural name
9090
"""
91-
app, model = model_str.split('.')
92-
Model = apps.get_registered_model(app, model)
93-
return Model._meta
91+
try:
92+
app, model = model_str.split('.')
93+
Model = apps.get_registered_model(app, model)
94+
return Model._meta
95+
except (ValueError, LookupError):
96+
return None
9497

9598

9699
def get_app_admin_urls(app):
@@ -118,16 +121,8 @@ def get_app_admin_urls(app):
118121
return models
119122

120123

121-
def get_model_permissions(user):
124+
def get_view_permissions(user):
122125
"""
123-
Create model permissions from the users permissions,
124-
125-
e.g having any of auth.view_user, auth.change_user, auth.delete_user will grant you auth.user
126+
Get model names based on a users view permissions
126127
"""
127-
permissions = set()
128-
for permission in user.get_all_permissions():
129-
app_label, model = permission.split('.')
130-
model = model.split('_')[1]
131-
permissions.add('{app_label}.{model}'.format(app_label=app_label, model=model))
132-
133-
return permissions
128+
return {x.replace('view_', '') for x in user.get_all_permissions() if 'view' in x}

tests/test_admin_permissions.py

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,64 @@
11
import pytest
2+
from django.urls import reverse
23

4+
from tests.test_app.polls.models import Poll
5+
from tests.utils import user_with_permissions, parse_sidemenu
36

4-
@pytest.mark.skip
5-
def test_no_delete_permission():
7+
8+
@pytest.mark.django_db
9+
def test_no_delete_permission(client):
610
"""
711
When our user has no delete permission, they dont see things they are not supposed to
812
"""
9-
pass
13+
user = user_with_permissions('polls.view_poll')
14+
poll = Poll.objects.create(owner=user, text='question')
15+
16+
url = reverse('admin:polls_poll_change', args=(poll.pk,))
17+
delete_url = reverse('admin:polls_poll_delete', args=(poll.pk,))
18+
client.force_login(user)
19+
20+
response = client.get(url)
21+
assert delete_url not in response.content.decode()
1022

1123

12-
@pytest.mark.skip
13-
def test_no_add_permission():
24+
@pytest.mark.django_db
25+
def test_no_add_permission(client):
1426
"""
1527
When our user has no add permission, they dont see things they are not supposed to
1628
"""
17-
pass
29+
user = user_with_permissions('polls.view_poll')
30+
url = reverse('admin:polls_poll_changelist')
31+
add_url = reverse('admin:polls_poll_add')
1832

33+
client.force_login(user)
34+
response = client.get(url)
1935

20-
@pytest.mark.skip
21-
def test_no_change_permission():
22-
"""
23-
When our user has no change permission, they dont see things they are not supposed to
24-
"""
25-
pass
36+
assert add_url not in response.content.decode()
2637

2738

28-
@pytest.mark.skip
29-
def test_no_view_permission():
39+
@pytest.mark.django_db
40+
def test_no_view_permission(client):
3041
"""
3142
When our user has no view permission, they dont see things they are not supposed to
3243
"""
33-
pass
44+
user = user_with_permissions('polls.change_poll')
3445

46+
url = reverse('admin:index')
47+
client.force_login(user)
3548

36-
@pytest.mark.skip
37-
def test_no_permission():
49+
response = client.get(url)
50+
assert parse_sidemenu(response) == {'Global': ['/admin/']}
51+
52+
53+
@pytest.mark.django_db
54+
def test_no_permission(client):
3855
"""
3956
When our user has no permissions at all, they see no menu or dashboard
4057
"""
41-
pass
58+
user = user_with_permissions()
59+
60+
url = reverse('admin:index')
61+
client.force_login(user)
62+
63+
response = client.get(url)
64+
assert parse_sidemenu(response) == {'Global': ['/admin/']}

tests/test_app/settings.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@
112112
'custom_links': {
113113
'polls': [{
114114
'name': 'Make Messages', 'url': 'make_messages', 'icon': 'fa-comments',
115-
'permissions': ['polls.view_polls']
115+
'permissions': ['polls.view_poll']
116116
}]
117117
},
118118

0 commit comments

Comments
 (0)