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