Skip to content

Commit 6cd19d9

Browse files
committed
Fix removing suspended badge when absolving earlier warning
1 parent c07cedf commit 6cd19d9

File tree

3 files changed

+124
-21
lines changed

3 files changed

+124
-21
lines changed

collectives/models/user/badge.py

+42-19
Original file line numberDiff line numberDiff line change
@@ -194,23 +194,25 @@ def increment_warning_badges(self, registration: Registration):
194194
level=num_suspended_badges + 1,
195195
registration=registration,
196196
)
197-
else:
198-
badge_id = BadgeIds.UnjustifiedAbsenceWarning
199-
expiration_date = date(
200-
(
201-
date.today().year
202-
if date.today().month < Configuration.LICENSE_EXPIRY_MONTH
203-
else date.today().year + 1
204-
),
205-
Configuration.LICENSE_EXPIRY_MONTH,
206-
1,
207-
) - timedelta(days=1)
208-
self.assign_badge(
209-
badge_id,
210-
expiration_date=expiration_date,
211-
level=num_warning_badges + 1,
212-
registration=registration,
213-
)
197+
198+
# always add a warning badge as well
199+
# this simplifies logic when removing badge due to status change
200+
badge_id = BadgeIds.UnjustifiedAbsenceWarning
201+
expiration_date = date(
202+
(
203+
date.today().year
204+
if date.today().month < Configuration.LICENSE_EXPIRY_MONTH
205+
else date.today().year + 1
206+
),
207+
Configuration.LICENSE_EXPIRY_MONTH,
208+
1,
209+
) - timedelta(days=1)
210+
self.assign_badge(
211+
badge_id,
212+
expiration_date=expiration_date,
213+
level=num_warning_badges + 1,
214+
registration=registration,
215+
)
214216
except ValueError:
215217
# Badges update should not break unregistration logic
216218
pass
@@ -220,11 +222,32 @@ def remove_warning_badges(self, registration: Registration):
220222
Removes warning badges associated to this registration
221223
"""
222224

223-
badges = [
225+
registration_badges = [
224226
badge
225227
for badge in registration.badges
226228
if badge.badge_id
227229
in (BadgeIds.Suspended, BadgeIds.UnjustifiedAbsenceWarning)
228230
]
229-
for badge in badges:
231+
232+
if not any(
233+
badge
234+
for badge in registration_badges
235+
if badge.badge_id == BadgeIds.Suspended
236+
):
237+
# If this badge was counted towards a later suspension,
238+
# Remove the first suspended badge from a later registration
239+
max_id = max(badge.id for badge in registration_badges)
240+
241+
later_suspended_badges = [
242+
badge
243+
for badge in self.matching_badges([BadgeIds.Suspended], valid_only=True)
244+
if badge.id > max_id
245+
]
246+
if later_suspended_badges:
247+
first_suspended_badge = min(
248+
later_suspended_badges, key=lambda badge: badge.id
249+
)
250+
db.session.delete(first_suspended_badge)
251+
252+
for badge in registration_badges:
230253
db.session.delete(badge)

tests/events/test_registrations.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ def test_unregister_lately_valid_second_warning(
357357

358358
assert event.is_late_unregistered(user)
359359
assert user.has_a_valid_badge([BadgeIds.UnjustifiedAbsenceWarning])
360-
assert user.number_of_valid_warning_badges() == 2
360+
assert user.number_of_valid_warning_badges() == 3
361361
assert user.has_a_valid_badge([BadgeIds.Suspended])
362362

363363

tests/unit/test_badges.py

+81-1
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,14 @@
33
from datetime import date, timedelta
44
from collectives.models.activity_type import ActivityType
55
from collectives.models.badge import Badge, BadgeIds
6-
from collectives.models import db
76
from collectives.models.user import User
7+
from collectives.models import (
8+
db,
9+
Event,
10+
Registration,
11+
RegistrationLevels,
12+
RegistrationStatus,
13+
)
814

915

1016
def test_add_a_valid_badge(user1):
@@ -143,3 +149,77 @@ def test_increment_warning_badges_no_updates(
143149
assert len(session_monkeypatch["add"]) == 2 # No badge should be added
144150
assert session_monkeypatch["commit"] == 2 # No commit should occur
145151
assert session_monkeypatch["rollback"] == 0 # No rollback should occur
152+
153+
154+
def test_remove_sanction_badge(user1: User, event: Event):
155+
"""Test that removing a warning badge removes suspension
156+
if that warning was counted towards suspension"""
157+
158+
db.session.add(event)
159+
db.session.commit()
160+
161+
expiration_date = date.today() + timedelta(days=1)
162+
163+
reg1 = Registration(
164+
user_id=user1.id,
165+
status=RegistrationStatus.UnJustifiedAbsentee,
166+
level=RegistrationLevels.Normal,
167+
is_self=True,
168+
)
169+
reg2 = Registration(
170+
user_id=user1.id,
171+
status=RegistrationStatus.UnJustifiedAbsentee,
172+
level=RegistrationLevels.Normal,
173+
is_self=True,
174+
)
175+
reg3 = Registration(
176+
user_id=user1.id,
177+
status=RegistrationStatus.UnJustifiedAbsentee,
178+
level=RegistrationLevels.Normal,
179+
is_self=True,
180+
)
181+
event.registrations.append(reg1)
182+
event.registrations.append(reg2)
183+
event.registrations.append(reg3)
184+
185+
user1.assign_badge(
186+
BadgeIds.UnjustifiedAbsenceWarning,
187+
expiration_date=expiration_date,
188+
registration=reg1,
189+
)
190+
user1.assign_badge(
191+
BadgeIds.UnjustifiedAbsenceWarning,
192+
expiration_date=expiration_date,
193+
registration=reg2,
194+
)
195+
user1.assign_badge(
196+
BadgeIds.Suspended,
197+
expiration_date=expiration_date,
198+
registration=reg2,
199+
)
200+
user1.assign_badge(
201+
BadgeIds.UnjustifiedAbsenceWarning,
202+
expiration_date=expiration_date,
203+
registration=reg3,
204+
)
205+
user1.assign_badge(
206+
BadgeIds.Suspended,
207+
expiration_date=expiration_date,
208+
registration=reg3,
209+
)
210+
db.session.commit()
211+
212+
assert user1.has_a_valid_suspended_badge()
213+
assert user1.number_of_valid_warning_badges() == 3
214+
215+
user1.remove_warning_badges(reg1)
216+
db.session.commit()
217+
218+
assert user1.has_a_valid_suspended_badge()
219+
assert user1.number_of_valid_warning_badges() == 2
220+
221+
user1.remove_warning_badges(reg2)
222+
db.session.commit()
223+
224+
assert not user1.has_a_valid_suspended_badge()
225+
assert user1.number_of_valid_warning_badges() == 1

0 commit comments

Comments
 (0)