Coverage for bc/kwai-bc-identity/src/kwai_bc_identity/accept_user_invitation.py: 100%
33 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 that implements the use case for accepting 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.name import Name
8from kwai_core.domain.value_objects.password import Password
9from kwai_core.domain.value_objects.unique_id import UniqueId
11from kwai_bc_identity.user_invitations.user_invitation_repository import (
12 UserInvitationRepository,
13)
14from kwai_bc_identity.users.user import UserEntity
15from kwai_bc_identity.users.user_account import UserAccountEntity
16from kwai_bc_identity.users.user_account_repository import UserAccountRepository
19@dataclass(kw_only=True, frozen=True, slots=False)
20class AcceptUserInvitationCommand:
21 """Input for the AcceptUserInvitation use case.
23 See: [AcceptUserInvitation][kwai_bc_identity.accept_user_invitation.AcceptUserInvitation]
25 Attributes:
26 uuid: The unique id of the user invitation.
27 first_name: The first name of the new user.
28 last_name: The last name of the new user.
29 password: The password for the new user.
30 remark: A remark about the new user.
31 """
33 uuid: str
34 first_name: str
35 last_name: str
36 password: str
37 remark: str
40class AcceptUserInvitation:
41 """Use case for accepting a user invitation."""
43 def __init__(
44 self,
45 user_invitation_repo: UserInvitationRepository,
46 user_account_repo: UserAccountRepository,
47 presenter: Presenter[UserAccountEntity],
48 ):
49 """Create the use case.
51 Args:
52 user_invitation_repo: Repository for checking the user invitation.
53 user_account_repo: Repository that creates a new user account.
54 presenter: A presenter for a user account entity.
55 """
56 self._user_invitation_repo = user_invitation_repo
57 self._user_account_repo = user_account_repo
58 self._presenter = presenter
60 async def execute(self, command: AcceptUserInvitationCommand) -> None:
61 """Execute the use case.
63 Args:
64 command: The input for this use case.
66 Returns:
67 An entity for a user account.
69 Raises:
70 UserInvitationNotFoundExeption: when the user invitation does not
71 exist.
72 UnprocessableException: when the email address is already used by another
73 user.
74 When the user invitation is expired or was already accepted.
75 When the user invitation is revoked.
76 """
77 uuid = UniqueId.create_from_string(command.uuid)
78 user_invitation = await self._user_invitation_repo.get_invitation_by_uuid(uuid)
79 if user_invitation.revoked:
80 raise UnprocessableException(
81 f"The user invitation with id {uuid} is revoked."
82 )
83 if user_invitation.is_expired:
84 raise UnprocessableException(
85 f"The user invitation with id {uuid} is expired."
86 )
87 if user_invitation.confirmed:
88 raise UnprocessableException(
89 f"The user invitation with id {uuid} was already accepted."
90 )
92 if await self._user_account_repo.exists_with_email(user_invitation.email):
93 raise UnprocessableException(
94 f"A user with email {user_invitation.email} already exists."
95 )
97 user_account = UserAccountEntity(
98 user=UserEntity(
99 email=user_invitation.email,
100 remark=command.remark,
101 name=Name(first_name=command.first_name, last_name=command.last_name),
102 ),
103 password=Password.create_from_string(command.password),
104 )
106 user_invitation = user_invitation.confirm()
107 await self._user_invitation_repo.update(user_invitation)
109 user_account = await self._user_account_repo.create(user_account)
110 self._presenter.present(user_account)