Coverage for functions \ flipdare \ mailer \ admin \ admin_flag_review_email.py: 74%

72 statements  

« prev     ^ index     » next       coverage.py v7.13.0, created at 2026-05-08 12:22 +1000

1#!/usr/bin/env python 

2# Copyright (c) 2026 Flipdare Pty Ltd. All rights reserved. 

3# 

4# This file is part of Flipdare's proprietary software and contains 

5# confidential and copyrighted material. Unauthorised copying, 

6# modification, distribution, or use of this file is strictly 

7# prohibited without prior written permission from Flipdare Pty Ltd. 

8# 

9# This software includes third-party components licensed under MIT, 

10# BSD, and Apache 2.0 licences. See THIRD_PARTY_NOTICES for details. 

11# 

12 

13 

14from typing import override 

15from flipdare.mailer._jinja_email_template import JinjaEmailTemplate 

16from flipdare.mailer.app_email_params import AppEmailParams 

17from flipdare.mailer.app_email_type import AppEmailType 

18from flipdare.generated import RestrictionModel 

19from flipdare.generated.schema.email.body.admin.flag_review_email_schema import ( 

20 FlagReviewEmailSchema, 

21) 

22from flipdare.generated.schema.email.subject.admin.flag_subject_schema import FlagSubjectSchema 

23from flipdare.wrapper import FlagWrapper, UserWrapper 

24 

25 

26class AdminFlagReviewEmail(JinjaEmailTemplate[FlagReviewEmailSchema]): 

27 

28 SCHEMA_CLASS = FlagReviewEmailSchema 

29 

30 def __init__( 

31 self, 

32 reported_by: UserWrapper, 

33 flagged_user: UserWrapper, 

34 flag: FlagWrapper, 

35 restriction: RestrictionModel | None = None, 

36 ) -> None: 

37 data = self._build_data( 

38 reported_by=reported_by, 

39 flagged_user=flagged_user, 

40 flag=flag, 

41 restriction=restriction, 

42 ) 

43 

44 super().__init__( 

45 data=data, 

46 params=AppEmailParams( 

47 email_type=AppEmailType.ADM_FLAG_REVIEW, 

48 schema=FlagSubjectSchema( 

49 label=flag.flag_type.label, 

50 obj_type=flag.obj_type.label, 

51 obj_id=flag.obj_id, 

52 ), 

53 ), 

54 ) 

55 

56 def _build_data( 

57 self, 

58 reported_by: UserWrapper, 

59 flagged_user: UserWrapper, 

60 flag: FlagWrapper, 

61 restriction: RestrictionModel | None = None, 

62 ) -> FlagReviewEmailSchema: 

63 flag_id = flag.doc_id 

64 

65 flag_type = flag.flag_type 

66 obj_id = flag.obj_id 

67 obj_type = flag.obj_type 

68 flag_detail = f"{flag_type.label} - {obj_type.label} ({obj_id})" 

69 

70 reported_by_str = f"{reported_by.name} ({reported_by.email})" 

71 flagged_str = f"{flagged_user.name} ({flagged_user.email})" 

72 severity = f"SEVERE ({flag_type.value})" if flag_type.is_severe else f"{flag_type.value}" 

73 reason = flag_type.label 

74 description = flag.description 

75 

76 if restriction is not None: 

77 restriction_detail = f"Auto Restriction:\n\tID: {restriction.id}\n" 

78 f"\tType: {restriction.category.value}\n" 

79 f"\tReason: {restriction.reason}\n" 

80 if restriction.stopwatch is not None: 

81 restriction_detail += f"\tStarted At: {restriction.stopwatch.started_at}\n" 

82 restriction_detail += f"\tEnds At: {restriction.stopwatch.expires_at}\n" 

83 else: 

84 restriction_detail += "\tNo stopwatch information.\n" 

85 else: 

86 restriction_detail = "No restriction applied." 

87 

88 return FlagReviewEmailSchema( 

89 reported_by=reported_by_str, 

90 flagged=flagged_str, 

91 reason=reason, 

92 description=description, 

93 flag_detail=flag_detail, 

94 severity=severity, 

95 restriction_detail=restriction_detail, 

96 flag_id=flag_id, 

97 flag_type=flag_type.label, 

98 obj_type=obj_type.label, 

99 obj_id=obj_id, 

100 ) 

101 

102 @override 

103 def newline_fields(self) -> list[str]: 

104 return ["description", "flag_detail"] 

105 

106 @property 

107 @override 

108 def data(self) -> FlagReviewEmailSchema: 

109 assert isinstance(self._data, dict) # narrowing, we known we have a dict.. 

110 return self._data 

111 

112 @property 

113 def reported_by(self) -> str: 

114 return self.data["reported_by"] 

115 

116 @property 

117 def flagged(self) -> str: 

118 return self.data["flagged"] 

119 

120 @property 

121 def severity(self) -> str: 

122 return self.data["severity"] 

123 

124 @property 

125 def reason(self) -> str: 

126 return self.data["reason"] 

127 

128 @property 

129 def description(self) -> str: 

130 return self.data["description"] 

131 

132 @property 

133 def restriction_detail(self) -> str: 

134 return self.data["restriction_detail"] 

135 

136 @property 

137 def flag_id(self) -> str: 

138 return self.data["flag_id"] 

139 

140 @property 

141 def flag_type(self) -> str: 

142 return self.data["flag_type"] 

143 

144 @property 

145 def obj_type(self) -> str: 

146 return self.data["obj_type"] 

147 

148 @property 

149 def obj_id(self) -> str: 

150 return self.data["obj_id"]