Skip to content

Commit

Permalink
test: add more unit tests (#98)
Browse files Browse the repository at this point in the history
  • Loading branch information
jnussbaum authored Apr 19, 2024
1 parent 7358037 commit 06c733f
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 6 deletions.
10 changes: 10 additions & 0 deletions dsp_permissions_scripts/models/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,13 @@ class SpecifiedPropsNotEmptyError(ValueError):
@dataclass
class OapRetrieveConfigEmptyError(ValueError):
message: str = "retrieve_resources cannot be False if retrieve_values is 'none'"


@dataclass
class EmptyScopeError(Exception):
message: str = "PermissionScope must not be empty"


@dataclass
class InvalidGroupError(Exception):
message: str
4 changes: 3 additions & 1 deletion dsp_permissions_scripts/models/group.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
from pydantic import ConfigDict
from pydantic import model_validator

from dsp_permissions_scripts.models.errors import InvalidGroupError


class Group(BaseModel):
model_config = ConfigDict(frozen=True)
Expand All @@ -16,7 +18,7 @@ class Group(BaseModel):
def _check_regex(self) -> Group:
common_part = re.escape("http://www.knora.org/ontology/knora-admin#")
if not re.search(f"{common_part}.+", self.val):
raise ValueError(f"{self.val} is not a valid group IRI")
raise InvalidGroupError(f"{self.val} is not a valid group IRI")
return self


Expand Down
7 changes: 7 additions & 0 deletions dsp_permissions_scripts/models/scope.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from pydantic import ConfigDict
from pydantic import model_validator

from dsp_permissions_scripts.models.errors import EmptyScopeError
from dsp_permissions_scripts.models.group import CREATOR
from dsp_permissions_scripts.models.group import KNOWN_USER
from dsp_permissions_scripts.models.group import PROJECT_ADMIN
Expand Down Expand Up @@ -73,6 +74,12 @@ def check_group_occurs_only_once(self) -> PermissionScope:
raise ValueError(f"Group {group} must not occur in more than one field")
return self

@model_validator(mode="after")
def check_scope_not_empty(self) -> PermissionScope:
if not any([len(self.get(field)) > 0 for field in self.model_fields]):
raise EmptyScopeError()
return self

def get(self, permission: str) -> frozenset[Group]:
"""Retrieve the groups that have the given permission."""
if permission not in self.model_fields:
Expand Down
24 changes: 24 additions & 0 deletions tests/test_group.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import pytest

from dsp_permissions_scripts.models import group
from dsp_permissions_scripts.models.errors import InvalidGroupError


def test_builtin_groups() -> None:
assert group.UNKNOWN_USER == group.Group(val="http://www.knora.org/ontology/knora-admin#UnknownUser")
assert group.KNOWN_USER == group.Group(val="http://www.knora.org/ontology/knora-admin#KnownUser")
assert group.PROJECT_MEMBER == group.Group(val="http://www.knora.org/ontology/knora-admin#ProjectMember")
assert group.PROJECT_ADMIN == group.Group(val="http://www.knora.org/ontology/knora-admin#ProjectAdmin")
assert group.CREATOR == group.Group(val="http://www.knora.org/ontology/knora-admin#Creator")
assert group.SYSTEM_ADMIN == group.Group(val="http://www.knora.org/ontology/knora-admin#SystemAdmin")


def test_custom_group() -> None:
group_iri = "http://www.knora.org/ontology/knora-admin#my-custom-group"
custom_group = group.Group(val=group_iri)
assert custom_group.val == group_iri


def test_invalid_group() -> None:
with pytest.raises(InvalidGroupError):
group.Group(val="http://www.knora.org/v2/resources/foo")
86 changes: 81 additions & 5 deletions tests/test_scope.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,67 @@
import pytest

from dsp_permissions_scripts.models import group
from dsp_permissions_scripts.models.errors import EmptyScopeError
from dsp_permissions_scripts.models.scope import PermissionScope


def test_scope_validation_on_creation() -> None:
with pytest.raises(ValueError, match=re.escape("must not occur in more than one field")):
PermissionScope.create(
CR={group.PROJECT_ADMIN},
class TestScopeCreation:
def test_valid_scope(self) -> None:
scope = PermissionScope(
CR=frozenset({group.SYSTEM_ADMIN}),
D=frozenset({group.PROJECT_ADMIN}),
M=frozenset({group.PROJECT_MEMBER, group.KNOWN_USER}),
V=frozenset({group.UNKNOWN_USER}),
)
assert scope.CR == frozenset({group.SYSTEM_ADMIN})
assert scope.D == frozenset({group.PROJECT_ADMIN})
assert scope.M == frozenset({group.PROJECT_MEMBER, group.KNOWN_USER})
assert scope.V == frozenset({group.UNKNOWN_USER})
assert scope.RV == frozenset()

def test_valid_scope_create(self) -> None:
scope = PermissionScope.create(
CR={group.SYSTEM_ADMIN},
D={group.PROJECT_ADMIN},
V={group.UNKNOWN_USER, group.KNOWN_USER},
M={group.PROJECT_MEMBER, group.KNOWN_USER},
V={group.UNKNOWN_USER},
)
assert scope.CR == frozenset({group.SYSTEM_ADMIN})
assert scope.D == frozenset({group.PROJECT_ADMIN})
assert scope.M == frozenset({group.PROJECT_MEMBER, group.KNOWN_USER})
assert scope.V == frozenset({group.UNKNOWN_USER})
assert scope.RV == frozenset()

def test_valid_scope_from_dict(self) -> None:
scope = PermissionScope.from_dict(
{
"CR": [group.SYSTEM_ADMIN.val],
"D": [group.PROJECT_ADMIN.val],
"M": [group.PROJECT_MEMBER.val, group.KNOWN_USER.val],
"V": [group.UNKNOWN_USER.val],
}
)
assert scope.CR == frozenset({group.SYSTEM_ADMIN})
assert scope.D == frozenset({group.PROJECT_ADMIN})
assert scope.M == frozenset({group.PROJECT_MEMBER, group.KNOWN_USER})
assert scope.V == frozenset({group.UNKNOWN_USER})
assert scope.RV == frozenset()

def test_create_empty_scope(self) -> None:
with pytest.raises(EmptyScopeError):
PermissionScope.create()
with pytest.raises(EmptyScopeError):
PermissionScope()
with pytest.raises(EmptyScopeError):
PermissionScope.from_dict({})

def test_same_group_in_multiple_fields(self) -> None:
with pytest.raises(ValueError, match=re.escape("must not occur in more than one field")):
PermissionScope.create(
CR={group.PROJECT_ADMIN},
D={group.PROJECT_ADMIN},
V={group.UNKNOWN_USER, group.KNOWN_USER},
)


class TestAdd:
Expand Down Expand Up @@ -78,6 +129,31 @@ def test_remove_from_empty_perm(self) -> None:
_ = scope.remove("CR", group.PROJECT_ADMIN)


class TestGet:
def test_get(self) -> None:
scope = PermissionScope.create(
CR={group.PROJECT_ADMIN},
D={group.SYSTEM_ADMIN},
M={group.PROJECT_MEMBER, group.KNOWN_USER},
V={group.UNKNOWN_USER},
)
assert scope.get("CR") == frozenset({group.PROJECT_ADMIN})
assert scope.get("D") == frozenset({group.SYSTEM_ADMIN})
assert scope.get("M") == frozenset({group.PROJECT_MEMBER, group.KNOWN_USER})
assert scope.get("V") == frozenset({group.UNKNOWN_USER})
assert scope.get("RV") == frozenset()

def test_get_inexisting_perm(self) -> None:
scope = PermissionScope.create(
CR={group.PROJECT_ADMIN},
D={group.SYSTEM_ADMIN},
M={group.PROJECT_MEMBER, group.KNOWN_USER},
V={group.UNKNOWN_USER},
)
with pytest.raises(ValueError, match=re.escape("Permission 'foo' not in")):
_ = scope.get("foo")


class TestRemoveDuplicatesFromKwargs:
def test_remove_duplicates_from_kwargs_CR(self) -> None:
original: dict[str, list[str]] = {
Expand Down

0 comments on commit 06c733f

Please sign in to comment.