cvat/tests/python/rest_api/test_organizations.py

272 lines
7.7 KiB
Python
Raw Normal View History

2025-09-16 01:19:40 +00:00
# Copyright (C) 2021-2022 Intel Corporation
# Copyright (C) CVAT.ai Corporation
#
# SPDX-License-Identifier: MIT
import json
from copy import deepcopy
from http import HTTPStatus
from typing import Optional
import pytest
from cvat_sdk.api_client.api_client import ApiClient, Endpoint
from deepdiff import DeepDiff
from shared.utils.config import (
delete_method,
get_method,
make_api_client,
options_method,
patch_method,
)
from .utils import CollectionSimpleFilterTestBase
class TestMetadataOrganizations:
_ORG = 2
@pytest.mark.parametrize(
"privilege, role, is_member",
[
("admin", None, None),
("user", None, False),
("worker", None, False),
(None, "owner", True),
(None, "maintainer", True),
(None, "worker", True),
(None, "supervisor", True),
],
)
def test_can_send_options_request(
self,
privilege: Optional[str],
role: Optional[str],
is_member: Optional[bool],
find_users,
organizations,
):
exclude_org = None if is_member else self._ORG
org = self._ORG if is_member else None
filters = {}
for key, value in {
"privilege": privilege,
"role": role,
"org": org,
"exclude_org": exclude_org,
}.items():
if value is not None:
filters[key] = value
user = find_users(**filters)[0]["username"]
response = options_method(user, f"organizations")
assert response.status_code == HTTPStatus.OK
response = options_method(user, f"organizations/{self._ORG}")
assert response.status_code == HTTPStatus.OK
@pytest.mark.usefixtures("restore_db_per_class")
class TestGetOrganizations:
_ORG = 2
@pytest.mark.parametrize(
"privilege, role, is_member, is_allow",
[
("admin", None, None, True),
("user", None, False, False),
("worker", None, False, False),
(None, "owner", True, True),
(None, "maintainer", True, True),
(None, "worker", True, True),
(None, "supervisor", True, True),
],
)
def test_can_see_specific_organization(
self,
privilege: Optional[str],
role: Optional[str],
is_member: Optional[bool],
is_allow: bool,
find_users,
organizations,
):
exclude_org = None if is_member else self._ORG
org = self._ORG if is_member else None
filters = {}
for key, value in {
"privilege": privilege,
"role": role,
"org": org,
"exclude_org": exclude_org,
}.items():
if value is not None:
filters[key] = value
user = find_users(**filters)[0]["username"]
response = get_method(user, f"organizations/{self._ORG}")
if is_allow:
assert response.status_code == HTTPStatus.OK
assert DeepDiff(organizations[self._ORG], response.json()) == {}
else:
assert response.status_code == HTTPStatus.NOT_FOUND
def test_can_remove_owner_and_fetch_with_sdk(self, admin_user, organizations):
# test for API schema regressions
source_org = next(
org
for org in organizations
if org.get("owner") and org["owner"]["username"] != admin_user
).copy()
with make_api_client(admin_user) as api_client:
api_client.users_api.destroy(source_org["owner"]["id"])
(_, response) = api_client.organizations_api.retrieve(source_org["id"])
fetched_org = json.loads(response.data)
source_org["owner"] = None
assert DeepDiff(source_org, fetched_org, ignore_order=True) == {}
class TestOrganizationsListFilters(CollectionSimpleFilterTestBase):
field_lookups = {
"owner": ["owner", "username"],
}
@pytest.fixture(autouse=True)
def setup(self, restore_db_per_class, admin_user, organizations):
self.user = admin_user
self.samples = organizations
def _get_endpoint(self, api_client: ApiClient) -> Endpoint:
return api_client.organizations_api.list_endpoint
@pytest.mark.parametrize(
"field",
("name", "owner", "slug"),
)
def test_can_use_simple_filter_for_object_list(self, field):
return super()._test_can_use_simple_filter_for_object_list(field)
@pytest.mark.usefixtures("restore_db_per_function")
class TestPatchOrganizations:
_ORG = 2
@pytest.fixture(scope="class")
def request_data(self):
return {
"slug": "new",
"name": "new",
"description": "new",
"contact": {"email": "new@cvat.org"},
}
@pytest.fixture(scope="class")
def expected_data(self, organizations, request_data):
data = deepcopy(organizations[self._ORG])
data.update(request_data)
return data
@pytest.mark.parametrize(
"privilege, role, is_member, is_allow",
[
("admin", None, None, True),
("user", None, False, False),
("worker", None, False, False),
(None, "owner", True, True),
(None, "maintainer", True, True),
(None, "worker", True, False),
(None, "supervisor", True, False),
],
)
def test_can_update_specific_organization(
self,
privilege: Optional[str],
role: Optional[str],
is_member: Optional[bool],
is_allow: bool,
find_users,
request_data,
expected_data,
):
exclude_org = None if is_member else self._ORG
org = self._ORG if is_member else None
filters = {}
for key, value in {
"privilege": privilege,
"role": role,
"org": org,
"exclude_org": exclude_org,
}.items():
if value is not None:
filters[key] = value
user = find_users(**filters)[0]["username"]
response = patch_method(user, f"organizations/{self._ORG}", request_data)
if is_allow:
assert response.status_code == HTTPStatus.OK
assert (
DeepDiff(expected_data, response.json(), exclude_paths="root['updated_date']") == {}
)
else:
assert response.status_code != HTTPStatus.OK
@pytest.mark.usefixtures("restore_db_per_function")
class TestDeleteOrganizations:
_ORG = 2
@pytest.mark.parametrize(
"privilege, role, is_member, is_allow",
[
("admin", None, None, True),
(None, "owner", True, True),
(None, "maintainer", True, False),
(None, "worker", True, False),
(None, "supervisor", True, False),
("user", None, False, False),
("worker", None, False, False),
],
)
def test_can_delete(
self,
privilege: Optional[str],
role: Optional[str],
is_member: Optional[bool],
is_allow: bool,
find_users,
):
exclude_org = None if is_member else self._ORG
org = self._ORG if is_member else None
filters = {}
for key, value in {
"privilege": privilege,
"role": role,
"org": org,
"exclude_org": exclude_org,
}.items():
if value is not None:
filters[key] = value
user = find_users(**filters)[0]["username"]
response = delete_method(user, f"organizations/{self._ORG}")
if is_allow:
assert response.status_code == HTTPStatus.NO_CONTENT
else:
assert response.status_code != HTTPStatus.OK