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

1"""Module for implementing the use case of recreating a user invitation.""" 

2 

3from dataclasses import dataclass 

4 

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 

9 

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) 

22 

23 

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

25class RecreateUserInvitationCommand: 

26 """Input for the use case 'Recreate User Invitation'. 

27 

28 [RecreateUserInvitation][kwai_bc_identity.invite_user.RecreateUserInvitation] 

29 

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 """ 

35 

36 uuid: str 

37 expiration_in_days: int = 7 

38 remark: str = "" 

39 

40 

41class RecreateUserInvitation: 

42 """Use case for recreating a user invitation.""" 

43 

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 

56 

57 async def execute( 

58 self, command: RecreateUserInvitationCommand 

59 ) -> UserInvitationEntity: 

60 """Execute the use case. 

61 

62 Args: 

63 command: The input for this use case. 

64 

65 Returns: 

66 A user invitation. 

67 

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) 

77 

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 

85 

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 ) 

96 

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 ) 

107 

108 await self._publisher.publish( 

109 UserInvitationCreatedEvent(uuid=str(invitation.uuid)) 

110 ) 

111 

112 return invitation