Files
xiaoxia-saas/tests/unit/test_remove_member_use_case.py
T
2026-06-21 06:52:19 +08:00

379 lines
10 KiB
Python

"""
移除成员 Use Case 测试
"""
from unittest.mock import Mock
import pytest
from packages.application.workspace.remove_member_use_case import (
LeaveWorkspaceRequest,
LeaveWorkspaceUseCase,
RemoveMemberRequest,
RemoveMemberUseCase,
)
from packages.domain.entities import Workspace, WorkspaceMember, WorkspaceMemberRole
class TestRemoveMemberUseCase:
"""移除成员测试"""
@pytest.fixture
def mock_workspace_repo(self):
repo = Mock()
repo.find_by_id = Mock(return_value=None)
return repo
@pytest.fixture
def mock_member_repo(self):
repo = Mock()
repo.find_by_workspace_and_user = Mock(return_value=None)
repo.delete = Mock(return_value=True)
return repo
@pytest.fixture
def use_case(self, mock_workspace_repo, mock_member_repo):
return RemoveMemberUseCase(
workspace_repository=mock_workspace_repo,
workspace_member_repository=mock_member_repo,
)
@pytest.fixture
def test_workspace(self):
return Workspace(
id="workspace-123",
name="Test Workspace",
owner_user_id="owner-id",
)
def test_remove_member_success_by_owner(
self,
use_case,
mock_workspace_repo,
mock_member_repo,
test_workspace,
):
"""测试 Owner 移除成员成功"""
mock_workspace_repo.find_by_id.return_value = test_workspace
owner_member = WorkspaceMember(
id="member-1",
workspace_id="workspace-123",
user_id="owner-id",
role=WorkspaceMemberRole.OWNER,
)
target_member = WorkspaceMember(
id="member-2",
workspace_id="workspace-123",
user_id="target-id",
role=WorkspaceMemberRole.MEMBER,
)
mock_member_repo.find_by_workspace_and_user.side_effect = [
owner_member,
target_member,
]
request = RemoveMemberRequest(
workspace_id="workspace-123",
requester_user_id="owner-id",
target_user_id="target-id",
)
success, error = use_case.execute(request)
assert success is True
assert error is None
mock_member_repo.delete.assert_called_once_with("member-2")
def test_remove_member_success_by_admin(
self,
use_case,
mock_workspace_repo,
mock_member_repo,
test_workspace,
):
"""测试 Admin 移除普通成员成功"""
mock_workspace_repo.find_by_id.return_value = test_workspace
admin_member = WorkspaceMember(
id="member-1",
workspace_id="workspace-123",
user_id="admin-id",
role=WorkspaceMemberRole.ADMIN,
)
target_member = WorkspaceMember(
id="member-2",
workspace_id="workspace-123",
user_id="target-id",
role=WorkspaceMemberRole.VIEWER,
)
mock_member_repo.find_by_workspace_and_user.side_effect = [
admin_member,
target_member,
]
request = RemoveMemberRequest(
workspace_id="workspace-123",
requester_user_id="admin-id",
target_user_id="target-id",
)
success, error = use_case.execute(request)
assert success is True
assert error is None
def test_remove_member_cannot_remove_owner(
self,
use_case,
mock_workspace_repo,
mock_member_repo,
test_workspace,
):
"""测试不能移除 Owner"""
mock_workspace_repo.find_by_id.return_value = test_workspace
admin_member = WorkspaceMember(
id="member-1",
workspace_id="workspace-123",
user_id="admin-id",
role=WorkspaceMemberRole.ADMIN,
)
owner_member = WorkspaceMember(
id="member-2",
workspace_id="workspace-123",
user_id="owner-id",
role=WorkspaceMemberRole.OWNER,
)
mock_member_repo.find_by_workspace_and_user.side_effect = [
admin_member,
owner_member,
]
request = RemoveMemberRequest(
workspace_id="workspace-123",
requester_user_id="admin-id",
target_user_id="owner-id",
)
success, error = use_case.execute(request)
assert success is False
assert error == "Cannot remove the workspace owner"
def test_remove_member_admin_cannot_remove_admin(
self,
use_case,
mock_workspace_repo,
mock_member_repo,
test_workspace,
):
"""测试 Admin 不能移除另一个 Admin"""
mock_workspace_repo.find_by_id.return_value = test_workspace
admin_member1 = WorkspaceMember(
id="member-1",
workspace_id="workspace-123",
user_id="admin-id-1",
role=WorkspaceMemberRole.ADMIN,
)
admin_member2 = WorkspaceMember(
id="member-2",
workspace_id="workspace-123",
user_id="admin-id-2",
role=WorkspaceMemberRole.ADMIN,
)
mock_member_repo.find_by_workspace_and_user.side_effect = [
admin_member1,
admin_member2,
]
request = RemoveMemberRequest(
workspace_id="workspace-123",
requester_user_id="admin-id-1",
target_user_id="admin-id-2",
)
success, error = use_case.execute(request)
assert success is False
assert error == "Admins cannot remove other admins"
def test_remove_member_cannot_remove_self(
self,
use_case,
mock_workspace_repo,
mock_member_repo,
test_workspace,
):
"""测试不能移除自己"""
mock_workspace_repo.find_by_id.return_value = test_workspace
admin_member = WorkspaceMember(
id="member-1",
workspace_id="workspace-123",
user_id="admin-id",
role=WorkspaceMemberRole.ADMIN,
)
mock_member_repo.find_by_workspace_and_user.return_value = admin_member
request = RemoveMemberRequest(
workspace_id="workspace-123",
requester_user_id="admin-id",
target_user_id="admin-id",
)
success, error = use_case.execute(request)
assert success is False
assert "Cannot remove yourself" in error
def test_remove_member_no_permission(
self,
use_case,
mock_workspace_repo,
mock_member_repo,
test_workspace,
):
"""测试普通成员没有权限移除"""
mock_workspace_repo.find_by_id.return_value = test_workspace
regular_member = WorkspaceMember(
id="member-1",
workspace_id="workspace-123",
user_id="user-id",
role=WorkspaceMemberRole.MEMBER,
)
mock_member_repo.find_by_workspace_and_user.return_value = regular_member
request = RemoveMemberRequest(
workspace_id="workspace-123",
requester_user_id="user-id",
target_user_id="target-id",
)
success, error = use_case.execute(request)
assert success is False
assert error == "Only owners and admins can remove members"
class TestLeaveWorkspaceUseCase:
"""离开 Workspace 测试"""
@pytest.fixture
def mock_workspace_repo(self):
repo = Mock()
repo.find_by_id = Mock(return_value=None)
return repo
@pytest.fixture
def mock_member_repo(self):
repo = Mock()
repo.find_by_workspace_and_user = Mock(return_value=None)
repo.delete = Mock(return_value=True)
return repo
@pytest.fixture
def use_case(self, mock_workspace_repo, mock_member_repo):
return LeaveWorkspaceUseCase(
workspace_repository=mock_workspace_repo,
workspace_member_repository=mock_member_repo,
)
@pytest.fixture
def test_workspace(self):
return Workspace(
id="workspace-123",
name="Test Workspace",
owner_user_id="owner-id",
)
def test_leave_workspace_success(
self,
use_case,
mock_workspace_repo,
mock_member_repo,
test_workspace,
):
"""测试离开工作空间成功"""
mock_workspace_repo.find_by_id.return_value = test_workspace
member = WorkspaceMember(
id="member-1",
workspace_id="workspace-123",
user_id="user-id",
role=WorkspaceMemberRole.MEMBER,
)
mock_member_repo.find_by_workspace_and_user.return_value = member
request = LeaveWorkspaceRequest(
workspace_id="workspace-123",
user_id="user-id",
)
success, error = use_case.execute(request)
assert success is True
assert error is None
mock_member_repo.delete.assert_called_once_with("member-1")
def test_leave_workspace_owner_cannot_leave(
self,
use_case,
mock_workspace_repo,
mock_member_repo,
test_workspace,
):
"""测试 Owner 不能离开"""
mock_workspace_repo.find_by_id.return_value = test_workspace
owner_member = WorkspaceMember(
id="member-1",
workspace_id="workspace-123",
user_id="owner-id",
role=WorkspaceMemberRole.OWNER,
)
mock_member_repo.find_by_workspace_and_user.return_value = owner_member
request = LeaveWorkspaceRequest(
workspace_id="workspace-123",
user_id="owner-id",
)
success, error = use_case.execute(request)
assert success is False
assert "Owner cannot leave workspace" in error
def test_leave_workspace_not_member(
self,
use_case,
mock_workspace_repo,
mock_member_repo,
test_workspace,
):
"""测试不是成员"""
mock_workspace_repo.find_by_id.return_value = test_workspace
mock_member_repo.find_by_workspace_and_user.return_value = None
request = LeaveWorkspaceRequest(
workspace_id="workspace-123",
user_id="user-id",
)
success, error = use_case.execute(request)
assert success is False
assert error == "You are not a member of this workspace"