Coverage for src/kwai/modules/identity/recreate_user_invitation.py: 95%
37 statements
« prev ^ index » next coverage.py v7.7.1, created at 2024-01-01 00:00 +0000
« prev ^ index » next coverage.py v7.7.1, created at 2024-01-01 00:00 +0000
1"""Module for implementing the use case of recreating a user invitation."""
3from dataclasses import dataclass
5from kwai.core.domain.exceptions import UnprocessableException
6from kwai.core.domain.value_objects.timestamp import Timestamp
7from kwai.core.domain.value_objects.unique_id import UniqueId
8from kwai.core.events.publisher import Publisher
9from kwai.modules.identity.user_invitations.user_invitation import UserInvitationEntity
10from kwai.modules.identity.user_invitations.user_invitation_events import (
11 UserInvitationCreatedEvent,
12)
13from kwai.modules.identity.user_invitations.user_invitation_repository import (
14 UserInvitationRepository,
15)
16from kwai.modules.identity.users.user import UserEntity
17from kwai.modules.identity.users.user_repository import (
18 UserNotFoundException,
19 UserRepository,
20)
23@dataclass(kw_only=True, slots=True, frozen=True)
24class RecreateUserInvitationCommand:
25 """Input for the use case 'Recreate User Invitation'.
27 [RecreateUserInvitation][kwai.modules.identity.invite_user.RecreateUserInvitation]
29 Attributes:
30 uuid: The unique id of the original invitation.
31 expiration_in_days: When does the invitation expires (in days)
32 remark: A remark for this user invitation
33 """
35 uuid: str
36 expiration_in_days: int = 7
37 remark: str = ""
40class RecreateUserInvitation:
41 """Use case for recreating a user invitation."""
43 def __init__(
44 self,
45 user: UserEntity,
46 user_repo: UserRepository,
47 user_invitation_repo: UserInvitationRepository,
48 publisher: Publisher,
49 ):
50 """Initialize the use case."""
51 self._user = user
52 self._user_repo = user_repo
53 self._user_invitation_repo = user_invitation_repo
54 self._publisher = publisher
56 async def execute(
57 self, command: RecreateUserInvitationCommand
58 ) -> UserInvitationEntity:
59 """Execute the use case.
61 Args:
62 command: The input for this use case.
64 Returns:
65 A user invitation.
67 Raises:
68 UnprocessableException: raised when the email address is already in use.
69 """
70 uuid = UniqueId.create_from_string(command.uuid)
71 original_invitation = await self._user_invitation_repo.get_invitation_by_uuid(
72 uuid
73 )
74 original_invitation = original_invitation.revoke()
75 await self._user_invitation_repo.update(original_invitation)
77 try:
78 await self._user_repo.get_user_by_email(original_invitation.email)
79 raise UnprocessableException(
80 f"{original_invitation.email} is already in use"
81 )
82 except UserNotFoundException:
83 pass
85 query = (
86 self._user_invitation_repo.create_query()
87 .filter_by_email(original_invitation.email)
88 .filter_active()
89 .filter_not_expired(Timestamp.create_now())
90 )
91 if await query.count() > 0:
92 raise UnprocessableException(
93 f"There are still pending invitations for {original_invitation.email}"
94 )
96 invitation = await self._user_invitation_repo.create(
97 UserInvitationEntity(
98 email=original_invitation.email,
99 name=original_invitation.name,
100 uuid=UniqueId.generate(),
101 expired_at=Timestamp.create_with_delta(days=command.expiration_in_days),
102 remark=command.remark,
103 user=self._user,
104 )
105 )
107 await self._publisher.publish(
108 UserInvitationCreatedEvent(uuid=str(invitation.uuid))
109 )
111 return invitation