Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add tests for django_simple_nav.permissions #27

Merged
merged 3 commits into from
Feb 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 15 additions & 11 deletions src/django_simple_nav/permissions.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class User(Protocol):
is_superuser: bool

def has_perm(self, perm: str) -> bool:
...
... # pragma: no cover


def check_item_permissions(item: NavGroup | NavItem, user: User) -> bool:
Expand All @@ -24,18 +24,18 @@ def check_item_permissions(item: NavGroup | NavItem, user: User) -> bool:
if not user_perm:
return False

if hasattr(item, "items"):
sub_items = [
sub_item
for sub_item in item.items
if check_item_permissions(sub_item, user)
]
if not sub_items:
return False

if not idx == len(item.permissions) - 1:
continue

if hasattr(item, "items"):
sub_items = [
sub_item
for sub_item in item.items
if check_item_permissions(sub_item, user)
]
if not sub_items and not item.url:
return False

return True


Expand All @@ -45,7 +45,11 @@ def user_has_perm(user: User, perm: str) -> bool:
has_perm = False

if perm in ["is_authenticated", "is_staff", "is_superuser"]:
has_perm = getattr(user, perm, False)
is_superuser = getattr(user, "is_superuser", False)
if is_superuser:
has_perm = True
else:
has_perm = getattr(user, perm, False)
elif user.has_perm(perm):
has_perm = True

Expand Down
2 changes: 1 addition & 1 deletion tests/test_nav.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def test_dotted_path_rendering(req):
[
("", 10), # regular authenticated user
("is_staff", 13),
("is_superuser", 16),
("is_superuser", 19),
("tests.dummy_perm", 13),
],
)
Expand Down
331 changes: 331 additions & 0 deletions tests/test_permissions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,331 @@
from __future__ import annotations

import pytest
from django.contrib.auth import get_user_model
from django.contrib.auth.models import AnonymousUser
from model_bakery import baker

from django_simple_nav.nav import NavGroup
from django_simple_nav.nav import NavItem
from django_simple_nav.permissions import check_item_permissions
from django_simple_nav.permissions import user_has_perm

pytestmark = pytest.mark.django_db


def test_check_anonymous_user_has_perm():
user = AnonymousUser()

assert not user_has_perm(user, "is_authenticated")


def test_check_authenticated_user_has_perm():
user = baker.make(get_user_model())

assert user_has_perm(user, "is_authenticated")


def test_check_staff_user_has_perm():
user = baker.make(get_user_model(), is_staff=True)

assert user_has_perm(user, "is_staff")


def test_check_superuser_user_has_perm():
user = baker.make(get_user_model(), is_superuser=True)

assert user_has_perm(user, "is_superuser")


def test_check_auth_permission_user_has_perm():
user = baker.make(get_user_model())

dummy_perm = baker.make(
"auth.Permission",
codename="dummy_perm",
name="Dummy Permission",
content_type=baker.make("contenttypes.ContentType", app_label="tests"),
)

user.user_permissions.add(dummy_perm)

assert user_has_perm(user, "tests.dummy_perm")


# anonymous user
@pytest.mark.parametrize(
"item,expected",
[
# nav item
(NavItem("Test", "/test"), True),
(NavItem("Test", "/test", permissions=["is_authenticated"]), False),
(NavItem("Test", "/test", permissions=["is_staff"]), False),
(NavItem("Test", "/test", permissions=["is_superuser"]), False),
(NavItem("Test", "/test", permissions=["tests.dummy_perm"]), False),
# nav group with url
(NavGroup("Test", [], "/test"), True),
(NavGroup("Test", [], "/test", permissions=["is_authenticated"]), False),
(NavGroup("Test", [], "/test", permissions=["is_staff"]), False),
(NavGroup("Test", [], "/test", permissions=["is_superuser"]), False),
(NavGroup("Test", [], "/test", permissions=["tests.dummy_perm"]), False),
# nav group with no url and items with perms
(NavGroup("Test", [NavItem("Test", "/test")]), True),
(
NavGroup(
"Test",
[NavItem("Test", "/test", permissions=["is_authenticated"])],
),
False,
),
(NavGroup("Test", [NavItem("Test", "/test", permissions=["is_staff"])]), False),
(
NavGroup("Test", [NavItem("Test", "/test", permissions=["is_superuser"])]),
False,
),
(
NavGroup(
"Test", [NavItem("Test", "/test", permissions=["tests.dummy_perm"])]
),
False,
),
# multiple perms
(NavItem("Test", "/test", permissions=["is_authenticated", "is_staff"]), False),
(
NavItem(
"Test",
"/test",
permissions=["is_authenticated", "is_staff", "is_superuser"],
),
False,
),
],
)
def test_check_item_permissions_anonymous(item, expected):
user = AnonymousUser()

assert check_item_permissions(item, user) == expected


# authenticated user
@pytest.mark.parametrize(
"item,expected",
[
# nav item
(NavItem("Test", "/test"), True),
(NavItem("Test", "/test", permissions=["is_authenticated"]), True),
(NavItem("Test", "/test", permissions=["is_staff"]), False),
(NavItem("Test", "/test", permissions=["is_superuser"]), False),
(NavItem("Test", "/test", permissions=["tests.dummy_perm"]), False),
# nav group with url
(NavGroup("Test", [], "/test"), True),
(NavGroup("Test", [], "/test", permissions=["is_authenticated"]), True),
(NavGroup("Test", [], "/test", permissions=["is_staff"]), False),
(NavGroup("Test", [], "/test", permissions=["is_superuser"]), False),
(NavGroup("Test", [], "/test", permissions=["tests.dummy_perm"]), False),
# nav group with no url and items with perms
(NavGroup("Test", [NavItem("Test", "/test")], "/test"), True),
(
NavGroup(
"Test",
[NavItem("Test", "/test", permissions=["is_authenticated"])],
),
True,
),
(NavGroup("Test", [NavItem("Test", "/test", permissions=["is_staff"])]), False),
(
NavGroup("Test", [NavItem("Test", "/test", permissions=["is_superuser"])]),
False,
),
(
NavGroup(
"Test", [NavItem("Test", "/test", permissions=["tests.dummy_perm"])]
),
False,
),
# multiple perms
(NavItem("Test", "/test", permissions=["is_authenticated", "is_staff"]), False),
(
NavItem(
"Test",
"/test",
permissions=["is_authenticated", "is_staff", "is_superuser"],
),
False,
),
],
)
def test_check_item_permissions_is_authenticated(item, expected):
user = baker.make(get_user_model())

assert check_item_permissions(item, user) == expected


# staff user
@pytest.mark.parametrize(
"item,expected",
[
# nav item
(NavItem("Test", "/test"), True),
(NavItem("Test", "/test", permissions=["is_authenticated"]), True),
(NavItem("Test", "/test", permissions=["is_staff"]), True),
(NavItem("Test", "/test", permissions=["is_superuser"]), False),
(NavItem("Test", "/test", permissions=["tests.dummy_perm"]), False),
# nav group with url
(NavGroup("Test", [], "/test"), True),
(NavGroup("Test", [], "/test", permissions=["is_authenticated"]), True),
(NavGroup("Test", [], "/test", permissions=["is_staff"]), True),
(NavGroup("Test", [], "/test", permissions=["is_superuser"]), False),
(NavGroup("Test", [], "/test", permissions=["tests.dummy_perm"]), False),
# nav group with no url and items with perms
(NavGroup("Test", [NavItem("Test", "/test")]), True),
(
NavGroup(
"Test",
[NavItem("Test", "/test", permissions=["is_authenticated"])],
),
True,
),
(NavGroup("Test", [NavItem("Test", "/test", permissions=["is_staff"])]), True),
(
NavGroup("Test", [NavItem("Test", "/test", permissions=["is_superuser"])]),
False,
),
(
NavGroup(
"Test", [NavItem("Test", "/test", permissions=["tests.dummy_perm"])]
),
False,
),
# multiple perms
(NavItem("Test", "/test", permissions=["is_authenticated", "is_staff"]), True),
(
NavItem(
"Test",
"/test",
permissions=["is_authenticated", "is_staff", "is_superuser"],
),
False,
),
],
)
def test_check_item_permissions_is_staff(item, expected):
user = baker.make(get_user_model(), is_staff=True)

assert check_item_permissions(item, user) == expected


# superuser
@pytest.mark.parametrize(
"item,expected",
[
# nav item
(NavItem("Test", "/test"), True),
(NavItem("Test", "/test", permissions=["is_authenticated"]), True),
(NavItem("Test", "/test", permissions=["is_staff"]), True),
(NavItem("Test", "/test", permissions=["is_superuser"]), True),
(NavItem("Test", "/test", permissions=["tests.dummy_perm"]), True),
# nav group with url
(NavGroup("Test", [], "/test"), True),
(NavGroup("Test", [], "/test", permissions=["is_authenticated"]), True),
(NavGroup("Test", [], "/test", permissions=["is_staff"]), True),
(NavGroup("Test", [], "/test", permissions=["is_superuser"]), True),
(NavGroup("Test", [], "/test", permissions=["tests.dummy_perm"]), True),
# nav group with no url and items with perms
(NavGroup("Test", [NavItem("Test", "/test")], "/test"), True),
(
NavGroup(
"Test",
[NavItem("Test", "/test", permissions=["is_authenticated"])],
),
True,
),
(NavGroup("Test", [NavItem("Test", "/test", permissions=["is_staff"])]), True),
(
NavGroup("Test", [NavItem("Test", "/test", permissions=["is_superuser"])]),
True,
),
(
NavGroup(
"Test", [NavItem("Test", "/test", permissions=["tests.dummy_perm"])]
),
True,
),
# multiple perms
(NavItem("Test", "/test", permissions=["is_authenticated", "is_staff"]), True),
(
NavItem(
"Test",
"/test",
permissions=["is_authenticated", "is_staff", "is_superuser"],
),
True,
),
],
)
def test_check_item_permissions_is_superuser(item, expected):
user = baker.make(get_user_model(), is_superuser=True)

assert check_item_permissions(item, user) == expected


# user with specific auth.Permission
@pytest.mark.parametrize(
"item,expected",
[
# nav item
(NavItem("Test", "/test"), True),
(NavItem("Test", "/test", permissions=["is_authenticated"]), True),
(NavItem("Test", "/test", permissions=["is_staff"]), False),
(NavItem("Test", "/test", permissions=["is_superuser"]), False),
(NavItem("Test", "/test", permissions=["tests.dummy_perm"]), True),
# nav group with url
(NavGroup("Test", [], "/test"), True),
(NavGroup("Test", [], "/test", permissions=["is_authenticated"]), True),
(NavGroup("Test", [], "/test", permissions=["is_staff"]), False),
(NavGroup("Test", [], "/test", permissions=["is_superuser"]), False),
(NavGroup("Test", [], "/test", permissions=["tests.dummy_perm"]), True),
# nav group with no url and items with perms
(NavGroup("Test", [NavItem("Test", "/test")], "/test"), True),
(
NavGroup(
"Test",
[NavItem("Test", "/test", permissions=["is_authenticated"])],
),
True,
),
(NavGroup("Test", [NavItem("Test", "/test", permissions=["is_staff"])]), False),
(
NavGroup("Test", [NavItem("Test", "/test", permissions=["is_superuser"])]),
False,
),
(
NavGroup(
"Test", [NavItem("Test", "/test", permissions=["tests.dummy_perm"])]
),
True,
),
# multiple perms
(NavItem("Test", "/test", permissions=["is_authenticated", "is_staff"]), False),
(
NavItem(
"Test",
"/test",
permissions=["is_authenticated", "is_staff", "is_superuser"],
),
False,
),
],
)
def test_check_item_permissions_auth_permission(item, expected):
user = baker.make(get_user_model())

dummy_perm = baker.make(
"auth.Permission",
codename="dummy_perm",
name="Dummy Permission",
content_type=baker.make("contenttypes.ContentType", app_label="tests"),
)

user.user_permissions.add(dummy_perm)

assert check_item_permissions(item, user) == expected
Loading