Coverage for bc/kwai-bc-identity/src/kwai_bc_identity/recreate_user_invitation.py: 95%
38 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.presenter import Presenter
7from kwai_core.domain.value_objects.timestamp import Timestamp
8from kwai_core.domain.value_objects.unique_id import UniqueId
9from kwai_core.events.publisher import Publisher
11from kwai_bc_identity.user_invitations.user_invitation import UserInvitationEntity
12from kwai_bc_identity.user_invitations.user_invitation_events import (
13 UserInvitationCreatedEvent,
14)
15from kwai_bc_identity.user_invitations.user_invitation_repository import (
16 UserInvitationRepository,
17)
18from kwai_bc_identity.users.user import UserEntity
19from kwai_bc_identity.users.user_repository import (
20 UserNotFoundException,
21 UserRepository,
22)
25@dataclass(kw_only=True, slots=True, frozen=True)
26class RecreateUserInvitationCommand:
27 """Input for the use case 'Recreate User Invitation'.
29 [RecreateUserInvitation][kwai_bc_identity.invite_user.RecreateUserInvitation]
31 Attributes:
32 uuid: The unique id of the original invitation.
33 expiration_in_days: When does the invitation expires (in days)
34 remark: A remark for this user invitation
35 """
37 uuid: str
38 expiration_in_days: int = 7
39 remark: str = ""
42class RecreateUserInvitation:
43 """Use case for recreating a user invitation."""
45 def __init__(
46 self,
47 user: UserEntity,
48 user_repo: UserRepository,
49 user_invitation_repo: UserInvitationRepository,
50 presenter: Presenter[UserInvitationEntity],
51 publisher: Publisher,
52 ):
53 """Initialize the use case."""
54 self._user = user
55 self._user_repo = user_repo
56 self._user_invitation_repo = user_invitation_repo
57 self._presenter = presenter
58 self._publisher = publisher
60 async def execute(self, command: RecreateUserInvitationCommand):
61 """Execute the use case.
63 Args:
64 command: The input for this use case.
66 Raises:
67 UnprocessableException: raised when the email address is already in use.
68 """
69 uuid = UniqueId.create_from_string(command.uuid)
70 original_invitation = await self._user_invitation_repo.get_invitation_by_uuid(
71 uuid
72 )
73 original_invitation = original_invitation.revoke()
74 await self._user_invitation_repo.update(original_invitation)
76 try:
77 await self._user_repo.get_user_by_email(original_invitation.email)
78 raise UnprocessableException(
79 f"{original_invitation.email} is already in use"
80 )
81 except UserNotFoundException:
82 pass
84 query = (
85 self._user_invitation_repo.create_query()
86 .filter_by_email(original_invitation.email)
87 .filter_active()
88 .filter_not_expired(Timestamp.create_now())
89 )
90 if await query.count() > 0:
91 raise UnprocessableException(
92 f"There are still pending invitations for {original_invitation.email}"
93 )
95 invitation = await self._user_invitation_repo.create(
96 UserInvitationEntity(
97 email=original_invitation.email,
98 name=original_invitation.name,
99 uuid=UniqueId.generate(),
100 expired_at=Timestamp.create_with_delta(days=command.expiration_in_days),
101 remark=command.remark,
102 user=self._user,
103 )
104 )
106 await self._publisher.publish(
107 UserInvitationCreatedEvent(uuid=str(invitation.uuid))
108 )
110 self._presenter.present(invitation)