Skip to content

Commit

Permalink
Merge pull request #51 from farridav/farridav/add_missing_tests
Browse files Browse the repository at this point in the history
Adds missing tests
  • Loading branch information
farridav authored Jun 11, 2020
2 parents a89c989 + c5812ca commit 44b2dc0
Show file tree
Hide file tree
Showing 11 changed files with 278 additions and 97 deletions.
1 change: 1 addition & 0 deletions dev-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ ipdb # ipython breakpoints
django-extensions # Django Sugar for development
faker # less fake fake data
coveralls # Publish code coverage to coveralls
beautifulsoup4 # Structure HTML documents into navigable things for test assertions
4 changes: 2 additions & 2 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ JAZZMIN_SETTINGS = {
'name': 'Make Messages',
'url': 'make_messages',
'icon': 'fa-comments',
'permissions': ['polls.view_polls']
'permissions': ['polls.view_poll']
}]
},

Expand Down Expand Up @@ -115,7 +115,7 @@ Example:
'icon': 'fa-comments',
# a list of permissions the user must have to see this link (optional)
'permissions': ['polls.view_polls']
'permissions': ['polls.view_poll']
}]
},

Expand Down
2 changes: 1 addition & 1 deletion jazzmin/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
version = '2.0.1'
version = '2.1.1'
default_app_config = 'jazzmin.apps.JazzminConfig'
8 changes: 7 additions & 1 deletion jazzmin/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,13 +141,19 @@ def get_settings():
if 'url' in link:
link['url'] = get_custom_url(link['url'])
elif 'model' in link:
link['name'] = get_model_meta(link['model']).verbose_name_plural.title()
model_meta = get_model_meta(link['model'])
link['name'] = model_meta.verbose_name_plural.title() if model_meta else link['model']
link['url'] = get_admin_url(link['model'])
elif 'app' in link:
link['name'] = link['app'].title()
link['app_children'] = get_app_admin_urls(link['app'])

if type(jazzmin_settings['hide_apps']) == str:
jazzmin_settings['hide_apps'] = [jazzmin_settings['hide_apps']]
jazzmin_settings['hide_apps'] = [x.lower() for x in jazzmin_settings['hide_apps']]

if type(jazzmin_settings['hide_models']) == str:
jazzmin_settings['hide_models'] = [jazzmin_settings['hide_models']]
jazzmin_settings['hide_models'] = [x.lower() for x in jazzmin_settings['hide_models']]

return jazzmin_settings
Expand Down
40 changes: 18 additions & 22 deletions jazzmin/templatetags/jazzmin.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,45 +13,45 @@

from .. import version
from ..settings import get_settings, get_ui_tweaks
from ..utils import order_with_respect_to, get_filter_id, get_custom_url, get_admin_url, get_model_permissions
from ..utils import order_with_respect_to, get_filter_id, get_custom_url, get_admin_url, get_view_permissions

User = get_user_model()
register = Library()
logger = logging.getLogger(__name__)
OPTIONS = get_settings()
UI_TWEAKS = get_ui_tweaks()


@register.simple_tag(takes_context=True)
def get_side_menu(context):
"""
Get the list of apps and models to render out in the side menu and on the dashboard page
"""

user = context.get('user')
if not user:
return []

model_permissions = get_model_permissions(user)
model_permissions = get_view_permissions(user)
options = get_settings()

menu = []
available_apps = copy.deepcopy(context.get('available_apps', []))
for app in available_apps:
app_label = app['app_label'].lower()
if app_label in OPTIONS['hide_apps']:
if app_label in options['hide_apps']:
continue

allowed_models = []
for model in app.get('models', []):
model_str = '{app_label}.{model}'.format(app_label=app_label, model=model["object_name"]).lower()
if model_str not in model_permissions:
continue
if model_str in OPTIONS.get('hide_models', []):
if model_str in options.get('hide_models', []):
continue

model['icon'] = OPTIONS.get('icons', {}).get(model_str)
model['icon'] = options.get('icons', {}).get(model_str)
allowed_models.append(model)

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

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

if OPTIONS.get('order_with_respect_to'):
menu = order_with_respect_to(menu, OPTIONS['order_with_respect_to'])
if options.get('order_with_respect_to'):
menu = order_with_respect_to(menu, options['order_with_respect_to'])

return menu

Expand All @@ -82,10 +82,11 @@ def get_top_menu(user):
if not user:
return []

model_permissions = get_model_permissions(user)
model_permissions = get_view_permissions(user)
options = get_settings()

menu = []
for item in get_settings().get('topmenu_links', []):
for item in options.get('topmenu_links', []):

perm_matches = []
for perm in item.get('permissions', []):
Expand All @@ -112,21 +113,15 @@ def get_jazzmin_settings():
"""
Return Jazzmin settings
"""
return OPTIONS
return get_settings()


@register.simple_tag
def get_jazzmin_ui_tweaks():
"""
Return Jazzmin ui tweaks
Find all the places references in ui-builder.js
and get template variables in there
ensure we have sane defaults
"""
return UI_TWEAKS
return get_ui_tweaks()


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

if not OPTIONS.get('user_avatar'):
if not options.get('user_avatar'):
return no_avatar

avatar_field = getattr(user, OPTIONS['user_avatar'], None)
avatar_field = getattr(user, options['user_avatar'], None)
if avatar_field:
return avatar_field.url

Expand Down
27 changes: 11 additions & 16 deletions jazzmin/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def order_with_respect_to(first, reference):

def get_admin_url(instance, **kwargs):
"""
Return the admin URL for the given instance, model class or <app>/<model> string
Return the admin URL for the given instance, model class or <app>.<model> string
"""
url = '#'

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

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

if kwargs:
Expand Down Expand Up @@ -88,9 +88,12 @@ def get_model_meta(model_str):
"""
Get the plural name
"""
app, model = model_str.split('.')
Model = apps.get_registered_model(app, model)
return Model._meta
try:
app, model = model_str.split('.')
Model = apps.get_registered_model(app, model)
return Model._meta
except (ValueError, LookupError):
return None


def get_app_admin_urls(app):
Expand Down Expand Up @@ -118,16 +121,8 @@ def get_app_admin_urls(app):
return models


def get_model_permissions(user):
def get_view_permissions(user):
"""
Create model permissions from the users permissions,
e.g having any of auth.view_user, auth.change_user, auth.delete_user will grant you auth.user
Get model names based on a users view permissions
"""
permissions = set()
for permission in user.get_all_permissions():
app_label, model = permission.split('.')
model = model.split('_')[1]
permissions.add('{app_label}.{model}'.format(app_label=app_label, model=model))

return permissions
return {x.replace('view_', '') for x in user.get_all_permissions() if 'view' in x}
59 changes: 41 additions & 18 deletions tests/test_admin_permissions.py
Original file line number Diff line number Diff line change
@@ -1,41 +1,64 @@
import pytest
from django.urls import reverse

from tests.test_app.polls.models import Poll
from tests.utils import user_with_permissions, parse_sidemenu

@pytest.mark.skip
def test_no_delete_permission():

@pytest.mark.django_db
def test_no_delete_permission(client):
"""
When our user has no delete permission, they dont see things they are not supposed to
"""
pass
user = user_with_permissions('polls.view_poll')
poll = Poll.objects.create(owner=user, text='question')

url = reverse('admin:polls_poll_change', args=(poll.pk,))
delete_url = reverse('admin:polls_poll_delete', args=(poll.pk,))
client.force_login(user)

response = client.get(url)
assert delete_url not in response.content.decode()


@pytest.mark.skip
def test_no_add_permission():
@pytest.mark.django_db
def test_no_add_permission(client):
"""
When our user has no add permission, they dont see things they are not supposed to
"""
pass
user = user_with_permissions('polls.view_poll')
url = reverse('admin:polls_poll_changelist')
add_url = reverse('admin:polls_poll_add')

client.force_login(user)
response = client.get(url)

@pytest.mark.skip
def test_no_change_permission():
"""
When our user has no change permission, they dont see things they are not supposed to
"""
pass
assert add_url not in response.content.decode()


@pytest.mark.skip
def test_no_view_permission():
@pytest.mark.django_db
def test_no_view_permission(client):
"""
When our user has no view permission, they dont see things they are not supposed to
"""
pass
user = user_with_permissions('polls.change_poll')

url = reverse('admin:index')
client.force_login(user)

@pytest.mark.skip
def test_no_permission():
response = client.get(url)
assert parse_sidemenu(response) == {'Global': ['/admin/']}


@pytest.mark.django_db
def test_no_permission(client):
"""
When our user has no permissions at all, they see no menu or dashboard
"""
pass
user = user_with_permissions()

url = reverse('admin:index')
client.force_login(user)

response = client.get(url)
assert parse_sidemenu(response) == {'Global': ['/admin/']}
2 changes: 1 addition & 1 deletion tests/test_app/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@
'custom_links': {
'polls': [{
'name': 'Make Messages', 'url': 'make_messages', 'icon': 'fa-comments',
'permissions': ['polls.view_polls']
'permissions': ['polls.view_poll']
}]
},

Expand Down
Loading

0 comments on commit 44b2dc0

Please sign in to comment.