Files
xiaoxia-saas/tests/unit/test_invite_member_use_case.py
T
API文档维护Agent e3fb518ab2
CI/CD Pipeline / Validate Code Quality And Tests (pull_request) Has been cancelled
CI/CD Pipeline / Frontend Lint (pull_request) Has been cancelled
refactor: remove all workspace_id references from codebase
- Remove workspace_id from Pydantic models in project_management routes
- Remove workspace_id from SQLAlchemy and SQLite project management repos
- Remove workspace_id from worker tasks (storage keys, entity creation)
- Remove workspace_id from video dedup and title usage modules
- Remove workspace_id from generation and ingest worker tasks
- Clean workspace_id from all test files and scripts
- Remove workspace-specific test files (list_workspaces, workspace repos)

Task: #14 workspace_id 残留清理
2026-06-27 22:52:09 +08:00

286 lines
8.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
邀请成员 Use Case 测试
"""
from datetime import datetime, timezone
from unittest.mock import Mock
import pytest
from packages.application.workspace.invite_member_use_case import (
InviteMemberRequest,
InviteMemberUseCase,
)
from packages.domain.entities import (
User,
Workspace,
WorkspaceMember,
WorkspaceMemberRole,
)
class TestInviteMemberUseCase:
"""邀请成员测试"""
@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)
return repo
@pytest.fixture
def mock_invitation_repo(self):
repo = Mock()
repo.find_pending_by_workspace_and_email = Mock(return_value=None)
repo.save = Mock()
return repo
@pytest.fixture
def mock_user_repo(self):
repo = Mock()
repo.find_by_email = Mock(return_value=None)
repo.find_by_id = Mock(return_value=None)
return repo
@pytest.fixture
def use_case(
self,
mock_workspace_repo,
mock_member_repo,
mock_invitation_repo,
mock_user_repo,
):
email_service = Mock()
email_service.send_workspace_invitation_email.return_value = (True, None)
return InviteMemberUseCase(
workspace_repository=mock_workspace_repo,
workspace_member_repository=mock_member_repo,
workspace_invitation_repository=mock_invitation_repo,
user_repository=mock_user_repo,
base_url="https://test.com",
invitation_expire_days=7,
email_service=email_service,
)
@pytest.fixture
def test_workspace(self):
return Workspace(
id="workspace-123",
name="Test Workspace",
owner_user_id="owner-id",
)
@pytest.fixture
def test_inviter(self):
return User(
id="inviter-id",
email="inviter@test.com",
username="inviter",
display_name="Inviter User",
)
@pytest.fixture
def owner_member(self):
return WorkspaceMember(
id="member-1",
user_id="inviter-id",
role=WorkspaceMemberRole.OWNER,
)
@pytest.fixture
def admin_member(self):
return WorkspaceMember(
id="member-2",
user_id="inviter-id",
role=WorkspaceMemberRole.ADMIN,
)
def test_invite_member_success_by_owner(
self,
use_case,
mock_workspace_repo,
mock_member_repo,
mock_invitation_repo,
mock_user_repo,
test_workspace,
test_inviter,
owner_member,
):
"""测试 Owner 邀请成员成功"""
mock_workspace_repo.find_by_id.return_value = test_workspace
mock_member_repo.find_by_workspace_and_user.return_value = owner_member
mock_user_repo.find_by_id.return_value = test_inviter
request = InviteMemberRequest(
inviter_user_id="inviter-id",
invitee_email="newuser@test.com",
role="member",
)
response, error = use_case.execute(request)
assert error is None
assert response is not None
assert response.invitee_email == "newuser@test.com"
assert response.role == "member"
assert response.expires_at is not None
# 验证保存了邀请
mock_invitation_repo.save.assert_called_once()
invitation = mock_invitation_repo.save.call_args[0][0]
assert invitation.invitee_email == "newuser@test.com"
assert invitation.status == "pending"
# 验证发送了邮件
use_case.email_service.send_workspace_invitation_email.assert_called_once()
def test_invite_member_success_by_admin(
self,
use_case,
mock_workspace_repo,
mock_member_repo,
mock_invitation_repo,
mock_user_repo,
test_workspace,
test_inviter,
admin_member,
):
"""测试 Admin 邀请成员成功"""
mock_workspace_repo.find_by_id.return_value = test_workspace
mock_member_repo.find_by_workspace_and_user.return_value = admin_member
mock_user_repo.find_by_id.return_value = test_inviter
request = InviteMemberRequest(
inviter_user_id="inviter-id",
invitee_email="newuser@test.com",
role="viewer",
)
response, error = use_case.execute(request)
assert error is None
assert response is not None
def test_invite_member_workspace_not_found(self, use_case, mock_workspace_repo):
"""测试 Workspace 不存在"""
mock_workspace_repo.find_by_id.return_value = None
request = InviteMemberRequest(
inviter_user_id="inviter-id",
invitee_email="newuser@test.com",
role="member",
)
response, error = use_case.execute(request)
assert response is None
assert error == "Workspace not found"
def test_invite_member_inviter_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 = InviteMemberRequest(
inviter_user_id="nonmember-id",
invitee_email="newuser@test.com",
role="member",
)
response, error = use_case.execute(request)
assert response is None
assert error == "You are not a member of this workspace"
def test_invite_member_inviter_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-3",
user_id="inviter-id",
role=WorkspaceMemberRole.MEMBER,
)
mock_member_repo.find_by_workspace_and_user.return_value = regular_member
request = InviteMemberRequest(
inviter_user_id="inviter-id",
invitee_email="newuser@test.com",
role="member",
)
response, error = use_case.execute(request)
assert response is None
assert error == "Only owners and admins can invite members"
def test_invite_member_already_member(
self,
use_case,
mock_workspace_repo,
mock_member_repo,
mock_user_repo,
test_workspace,
owner_member,
):
"""测试被邀请人已经是成员"""
mock_workspace_repo.find_by_id.return_value = test_workspace
mock_member_repo.find_by_workspace_and_user.side_effect = [
owner_member, # 第一次调用:inviter 是 owner
WorkspaceMember( # 第二次调用:invitee 已经是成员
id="member-4",
user_id="existing-user-id",
role=WorkspaceMemberRole.MEMBER,
),
]
existing_user = User(
id="existing-user-id",
email="existing@test.com",
username="existing",
display_name="Existing User",
)
mock_user_repo.find_by_email.return_value = existing_user
request = InviteMemberRequest(
inviter_user_id="inviter-id",
invitee_email="existing@test.com",
role="member",
)
response, error = use_case.execute(request)
assert response is None
assert error == "User is already a member of this workspace"
def test_invite_member_invalid_role(self, use_case):
"""测试无效角色(不能邀请为 owner"""
request = InviteMemberRequest(
inviter_user_id="inviter-id",
invitee_email="newuser@test.com",
role="owner",
)
response, error = use_case.execute(request)
assert response is None
assert "Invalid role" in error