Coverage for src/kwai/modules/identity/mail_user_invitation.py: 93%

30 statements  

« prev     ^ index     » next       coverage.py v7.6.10, created at 2024-01-01 00:00 +0000

1"""Module that defines the use case for sending a user invitation email.""" 

2 

3from dataclasses import dataclass 

4 

5from kwai.core.domain.exceptions import UnprocessableException 

6from kwai.core.domain.value_objects.unique_id import UniqueId 

7from kwai.core.mail.mailer import Mailer 

8from kwai.core.mail.recipient import Recipients 

9from kwai.core.template.mail_template import MailTemplate 

10from kwai.modules.identity.user_invitations.user_invitation import UserInvitationEntity 

11from kwai.modules.identity.user_invitations.user_invitation_mailer import ( 

12 UserInvitationMailer, 

13) 

14from kwai.modules.identity.user_invitations.user_invitation_repository import ( 

15 UserInvitationRepository, 

16) 

17 

18 

19@dataclass(frozen=True, kw_only=True, slots=True) 

20class MailUserInvitationCommand: 

21 """Command for the use case MailUserInvitation. 

22 

23 Attributes: 

24 uuid: The unique id of the user invitation. 

25 """ 

26 

27 uuid: str 

28 

29 

30class MailUserInvitation: 

31 """Use case for sending a user invitation email.""" 

32 

33 def __init__( 

34 self, 

35 user_invitation_repo: UserInvitationRepository, 

36 mailer: Mailer, 

37 recipients: Recipients, 

38 mail_template: MailTemplate, 

39 ): 

40 self._user_invitation_repo = user_invitation_repo 

41 self._mailer = mailer 

42 self._recipients = recipients 

43 self._mail_template = mail_template 

44 

45 async def execute(self, command: MailUserInvitationCommand) -> UserInvitationEntity: 

46 """Execute the use case. 

47 

48 Args: 

49 command: the input for this use case. 

50 

51 Raises: 

52 UserInvitationNotFoundException: Raised when 

53 the user invitation cannot be found. 

54 UnprocessableException: Raised when the mail was already sent. 

55 Raised when the user recovery was already confirmed. 

56 """ 

57 user_invitation = await self._user_invitation_repo.get_invitation_by_uuid( 

58 UniqueId.create_from_string(command.uuid) 

59 ) 

60 if user_invitation.mailed: 

61 raise UnprocessableException( 

62 f"Mail already send for user invitation {command.uuid}" 

63 ) 

64 

65 if user_invitation.is_expired: 

66 raise UnprocessableException( 

67 f"User invitation {command.uuid} already expired" 

68 ) 

69 

70 if user_invitation.confirmed: 

71 raise UnprocessableException( 

72 f"User invitation {command.uuid} already confirmed" 

73 ) 

74 

75 UserInvitationMailer( 

76 self._mailer, 

77 self._recipients, 

78 self._mail_template, 

79 user_invitation, 

80 ).send() 

81 

82 user_invitation.mail_sent() 

83 await self._user_invitation_repo.update(user_invitation) 

84 

85 return user_invitation