From a68ad6b8a564f29029352760898b76040c084cf1 Mon Sep 17 00:00:00 2001 From: Tobias Kunze Date: Fri, 5 Dec 2025 16:39:11 +0100 Subject: [PATCH] Increase test coverage --- .../frontend/templatetags/version_tags.py | 2 +- src/tests/conftest.py | 29 +++- src/tests/test_rules.py | 151 ++++++++++++++++++ 3 files changed, 178 insertions(+), 4 deletions(-) create mode 100644 src/tests/test_rules.py diff --git a/src/servala/frontend/templatetags/version_tags.py b/src/servala/frontend/templatetags/version_tags.py index 6019738..2a94030 100644 --- a/src/servala/frontend/templatetags/version_tags.py +++ b/src/servala/frontend/templatetags/version_tags.py @@ -13,4 +13,4 @@ def get_version_or_env(): env = os.environ.get("SERVALA_ENVIRONMENT", "development") if env == "production": return __version__ - return env + return env # pragma: no cover diff --git a/src/tests/conftest.py b/src/tests/conftest.py index 859b4ca..d80aed8 100644 --- a/src/tests/conftest.py +++ b/src/tests/conftest.py @@ -42,13 +42,36 @@ def other_organization(origin): return Organization.objects.create(name="Test Org Alternate", origin=origin) +@pytest.fixture +def user(): + return User.objects.create(email="testuser@example.org", password="test") + + @pytest.fixture def org_owner(organization): - user = User.objects.create(email="user@example.org", password="example") + owner = User.objects.create(email="owner@example.org", password="example") OrganizationMembership.objects.create( - organization=organization, user=user, role="owner" + organization=organization, user=owner, role="owner" ) - return user + return owner + + +@pytest.fixture +def org_admin(organization): + admin = User.objects.create(email="admin@example.org", password="example") + OrganizationMembership.objects.create( + organization=organization, user=admin, role="admin" + ) + return admin + + +@pytest.fixture +def org_member(organization): + member = User.objects.create(email="member@example.org", password="example") + OrganizationMembership.objects.create( + organization=organization, user=member, role="member" + ) + return member @pytest.fixture diff --git a/src/tests/test_rules.py b/src/tests/test_rules.py new file mode 100644 index 0000000..9a83163 --- /dev/null +++ b/src/tests/test_rules.py @@ -0,0 +1,151 @@ +import pytest +from django_scopes import scope + +from servala.core.models.organization import OrganizationRole +from servala.core.rules import ( + has_organization_role, + is_organization_admin, + is_organization_member, + is_organization_owner, +) + +pytestmark = pytest.mark.django_db + + +def test_has_organization_role_returns_false_for_non_organization_object(user): + assert has_organization_role(user, "not an organization", None) is False + + +def test_has_organization_role_returns_false_for_non_member(user, organization): + with scope(organization=organization): + assert has_organization_role(user, organization, None) is False + + +@pytest.mark.parametrize("user_fixture", ["org_owner", "org_admin", "org_member"]) +def test_has_organization_role_returns_true_for_any_member( + user_fixture, organization, request +): + user = request.getfixturevalue(user_fixture) + with scope(organization=organization): + assert has_organization_role(user, organization, None) is True + + +@pytest.mark.parametrize( + "user_fixture,roles,expected", + [ + ("org_owner", [OrganizationRole.OWNER], True), + ("org_owner", [OrganizationRole.ADMIN], False), + ("org_owner", [OrganizationRole.MEMBER], False), + ("org_owner", [OrganizationRole.OWNER, OrganizationRole.ADMIN], True), + ("org_admin", [OrganizationRole.ADMIN], True), + ("org_admin", [OrganizationRole.OWNER], False), + ("org_admin", [OrganizationRole.OWNER, OrganizationRole.ADMIN], True), + ("org_member", [OrganizationRole.MEMBER], True), + ("org_member", [OrganizationRole.OWNER], False), + ("org_member", [OrganizationRole.ADMIN], False), + ], +) +def test_has_organization_role_filters_by_roles( + user_fixture, roles, expected, organization, request +): + user = request.getfixturevalue(user_fixture) + with scope(organization=organization): + assert has_organization_role(user, organization, roles) is expected + + +@pytest.mark.parametrize( + "user_fixture,expected", + [ + ("org_owner", True), + ("org_admin", False), + ("org_member", False), + ], +) +def test_is_organization_owner(user_fixture, expected, organization, request): + user = request.getfixturevalue(user_fixture) + with scope(organization=organization): + assert is_organization_owner(user, organization) is expected + + +@pytest.mark.parametrize( + "user_fixture,expected", + [ + ("org_owner", True), + ("org_admin", False), + ("org_member", False), + ], +) +def test_is_organization_owner_with_related_object( + user_fixture, expected, organization, mocker, request +): + user = request.getfixturevalue(user_fixture) + obj = mocker.MagicMock() + obj.organization = organization + with scope(organization=organization): + assert is_organization_owner(user, obj) is expected + + +@pytest.mark.parametrize( + "user_fixture,expected", + [ + ("org_owner", True), + ("org_admin", True), + ("org_member", False), + ], +) +def test_is_organization_admin(user_fixture, expected, organization, request): + user = request.getfixturevalue(user_fixture) + with scope(organization=organization): + assert is_organization_admin(user, organization) is expected + + +@pytest.mark.parametrize( + "user_fixture,expected", + [ + ("org_owner", True), + ("org_admin", True), + ("org_member", False), + ], +) +def test_is_organization_admin_with_related_object( + user_fixture, expected, organization, mocker, request +): + user = request.getfixturevalue(user_fixture) + obj = mocker.MagicMock() + obj.organization = organization + with scope(organization=organization): + assert is_organization_admin(user, obj) is expected + + +@pytest.mark.parametrize("user_fixture", ["org_owner", "org_admin", "org_member"]) +def test_is_organization_member_returns_true_for_members( + user_fixture, organization, request +): + user = request.getfixturevalue(user_fixture) + with scope(organization=organization): + assert is_organization_member(user, organization) is True + + +def test_is_organization_member_returns_false_for_non_member(user, organization): + with scope(organization=organization): + assert is_organization_member(user, organization) is False + + +@pytest.mark.parametrize("user_fixture", ["org_owner", "org_admin", "org_member"]) +def test_is_organization_member_with_related_object( + user_fixture, organization, mocker, request +): + user = request.getfixturevalue(user_fixture) + obj = mocker.MagicMock() + obj.organization = organization + with scope(organization=organization): + assert is_organization_member(user, obj) is True + + +def test_is_organization_member_with_related_object_returns_false_for_non_member( + user, organization, mocker +): + obj = mocker.MagicMock() + obj.organization = organization + with scope(organization=organization): + assert is_organization_member(user, obj) is False