""" 移除成员 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"