feat(files): add safe connector space removal
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import unittest
|
||||
from types import SimpleNamespace
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
from govoplan_files.backend.storage.common import FileStorageError
|
||||
from govoplan_files.backend.storage.connector_spaces import soft_delete_connector_space
|
||||
|
||||
|
||||
class ConnectorSpaceDeletionTests(unittest.TestCase):
|
||||
def setUp(self) -> None:
|
||||
self.session = Mock()
|
||||
self.space = SimpleNamespace(
|
||||
tenant_id="tenant-1",
|
||||
owner_type="user",
|
||||
owner_user_id="owner-1",
|
||||
owner_group_id=None,
|
||||
deleted_at=None,
|
||||
is_active=True,
|
||||
)
|
||||
|
||||
@patch("govoplan_files.backend.storage.connector_spaces.utcnow")
|
||||
@patch("govoplan_files.backend.storage.connector_spaces.ensure_owner_access")
|
||||
def test_owner_can_soft_delete_local_space_definition(
|
||||
self, ensure_owner_access: Mock, utcnow: Mock
|
||||
) -> None:
|
||||
deleted_at = object()
|
||||
utcnow.return_value = deleted_at
|
||||
|
||||
result = soft_delete_connector_space(
|
||||
self.session, self.space, user_id="owner-1"
|
||||
)
|
||||
|
||||
self.assertIs(result, self.space)
|
||||
self.assertIs(deleted_at, self.space.deleted_at)
|
||||
self.assertFalse(self.space.is_active)
|
||||
ensure_owner_access.assert_called_once_with(
|
||||
self.session,
|
||||
tenant_id="tenant-1",
|
||||
owner_type="user",
|
||||
owner_id="owner-1",
|
||||
user_id="owner-1",
|
||||
is_admin=False,
|
||||
)
|
||||
self.session.add.assert_called_once_with(self.space)
|
||||
self.session.flush.assert_called_once_with()
|
||||
|
||||
@patch(
|
||||
"govoplan_files.backend.storage.connector_spaces.ensure_owner_access",
|
||||
side_effect=FileStorageError("File space access denied"),
|
||||
)
|
||||
def test_inaccessible_space_is_blocked_without_mutation(
|
||||
self, _ensure_owner_access: Mock
|
||||
) -> None:
|
||||
with self.assertRaisesRegex(FileStorageError, "access denied"):
|
||||
soft_delete_connector_space(
|
||||
self.session, self.space, user_id="other-user"
|
||||
)
|
||||
|
||||
self.assertIsNone(self.space.deleted_at)
|
||||
self.assertTrue(self.space.is_active)
|
||||
self.session.add.assert_not_called()
|
||||
self.session.flush.assert_not_called()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -85,6 +85,8 @@ class FilesRouterContractTests(unittest.TestCase):
|
||||
(("POST",), "/files/connectors/credentials"),
|
||||
(("GET",), "/files/connector-spaces"),
|
||||
(("POST",), "/files/connector-spaces"),
|
||||
(("PATCH",), "/files/connector-spaces/{space_id}"),
|
||||
(("DELETE",), "/files/connector-spaces/{space_id}"),
|
||||
}
|
||||
|
||||
self.assertTrue(expected.issubset(routes))
|
||||
|
||||
Reference in New Issue
Block a user