Coverage for src/ptf_tools/signals.py: 83%

71 statements  

« prev     ^ index     » next       coverage.py v7.7.0, created at 2025-04-09 14:54 +0000

1from itertools import chain 

2 

3from allauth.account.signals import user_signed_up 

4from django.contrib.auth.models import Group, User 

5from django.dispatch import receiver 

6from django.http import HttpRequest 

7from django.urls import reverse_lazy 

8from ptf.models import Collection 

9from ptf.utils import send_email_from_template 

10 

11from comments_moderation.models import CommentModerator 

12from comments_moderation.rights import ModeratorUserRights 

13from comments_moderation.utils import update_moderation_right 

14 

15from .models import Invitation, InvitationExtraData 

16 

17 

18@receiver(user_signed_up) 

19def update_user_from_invite( 

20 sender, request: HttpRequest | None = None, user: User | None = None, **kwargs 

21): 

22 """ 

23 Update extra information on the user signing up from the attached invitation. 

24 The extra information is either basic data (first name, last name) 

25 or app specific extra information (eg. for comment moderation). 

26 """ 

27 

28 if not isinstance(user, User): 28 ↛ 29line 28 didn't jump to line 29 because the condition on line 28 was never true

29 return 

30 

31 try: 

32 invite: Invitation | None = Invitation.objects.get(email__iexact=user.email) 

33 # TODO: Log if no invitation attached to the user 

34 # This should not happened since signup is closed outside of invitation system 

35 except Invitation.DoesNotExist: 

36 invite = None 

37 

38 if invite is None: 38 ↛ 39line 38 didn't jump to line 39 because the condition on line 38 was never true

39 return 

40 

41 if invite.first_name: 41 ↛ 43line 41 didn't jump to line 43 because the condition on line 41 was always true

42 user.first_name = invite.first_name 

43 if invite.last_name: 43 ↛ 46line 43 didn't jump to line 46 because the condition on line 43 was always true

44 user.last_name = invite.last_name 

45 

46 extra_data = InvitationExtraData(**invite.extra_data) 

47 

48 # Handle comment moderation related data 

49 if extra_data.moderator: 49 ↛ 116line 49 didn't jump to line 116 because the condition on line 49 was always true

50 # The list of users that "invited" the signing up user as a comment moderator. 

51 # We will send an e-mail to notify them of the account creation. 

52 users_to_mail = [] 

53 # Mark the user as a comment moderator 

54 try: 

55 comment_moderator = CommentModerator.objects.get(user=user) 

56 except CommentModerator.DoesNotExist: 

57 comment_moderator = CommentModerator(user=user) 

58 

59 comment_moderator.is_moderator = True 

60 comment_moderator.save() 

61 

62 # Staff moderators - Fill the selected collections 

63 if extra_data.moderator.collections: 

64 pids = chain.from_iterable(c.pid for c in extra_data.moderator.collections) 

65 collections_id = Collection.objects.filter(pid__in=set(pids)).values_list( 

66 "pk", flat=True 

67 ) 

68 comment_moderator.collections.add(*collections_id) 

69 

70 users_to_mail.extend(c.user_id for c in extra_data.moderator.collections) 

71 

72 # Base moderatos - Create a moderaton right entry associated to 

73 # the selected comments 

74 if extra_data.moderator.comments: 

75 processed_comments = [] 

76 for comment in extra_data.moderator.comments: 

77 try: 

78 users_to_mail.append(comment.user_id) 

79 if comment.id in processed_comments: 79 ↛ 80line 79 didn't jump to line 80 because the condition on line 79 was never true

80 continue 

81 right_creator = User.objects.get(pk=comment.user_id) 

82 rights = ModeratorUserRights(right_creator) 

83 error, _ = update_moderation_right(comment.id, user.pk, rights) 

84 # TODO: Log if the the POST request is unsuccessful ? 

85 processed_comments.append(comment.id) 

86 # Catch any exception and continue the workflow. 

87 # We don't want this additional processing to result in the sign up 

88 # failing. 

89 except Exception: 

90 continue 

91 # Send notification e-mail 

92 if users_to_mail: 

93 recipient_list = User.objects.filter(pk__in=set(users_to_mail)).values( 

94 "first_name", "last_name", "email" 

95 ) 

96 if recipient_list: 96 ↛ 116line 96 didn't jump to line 116 because the condition on line 96 was always true

97 for r in recipient_list: 

98 context_data = { 

99 "full_name": f"{r['first_name']} {r['last_name']}", 

100 "sign_up_name": f"{user.first_name} {user.last_name}", 

101 "sign_up_email": user.email, 

102 "comment_moderator_url": request.build_absolute_uri( 

103 reverse_lazy("comment_moderators") 

104 ), 

105 "invitation_date": invite.created, 

106 "email_signature": "The editorial team", 

107 } 

108 send_email_from_template( 

109 "mail/comment_moderator_account_created.html", 

110 context_data, 

111 "[TRAMMEL] Comment moderator sign up", 

112 to=[r["email"]], 

113 ) 

114 

115 # Add the newly created user to the given user groups. 

116 if extra_data.user_groups: 

117 group_pks = [] 

118 for group_pk in extra_data.user_groups: 

119 try: 

120 group_pks.append(int(group_pk)) 

121 except ValueError: 

122 pass 

123 if group_pks: 123 ↛ 128line 123 didn't jump to line 128 because the condition on line 123 was always true

124 user_groups = Group.objects.filter(pk__in=group_pks) 

125 if user_groups: 125 ↛ 128line 125 didn't jump to line 128 because the condition on line 125 was always true

126 user.groups.add(*user_groups) 

127 

128 user.save()