diff --git a/src/backoffice/templates/backoffice/teams/list.html b/src/backoffice/templates/backoffice/teams/list.html index d904f6c70d077e24d9ede674122109043c30231f..3152d99ee3cd8abdee656e4bb2be9ffb35290d61 100644 --- a/src/backoffice/templates/backoffice/teams/list.html +++ b/src/backoffice/templates/backoffice/teams/list.html @@ -47,7 +47,7 @@ <a href="{% url 'backoffice:team' uuid=team.uuid %}">{{ team.name }}</a> </td> <td>{{ team.get_visibility_display }}</td> - {% if user.is_staff %}<td>{{ team.members_count }}</td>{% endif %} + {% if conferencemember.is_staff %}<td>{{ team.members_count }}</td>{% endif %} <td> {% if team.is_member %} {{ team.is_manager|yesno }} diff --git a/src/backoffice/tests/teams/members.py b/src/backoffice/tests/teams/members.py index 56d9744885a9ffe75079da3e8b0ca5b873c0c769..a2fbe91c5d9ab5e2c42e5f0f54fca8981389261f 100644 --- a/src/backoffice/tests/teams/members.py +++ b/src/backoffice/tests/teams/members.py @@ -88,6 +88,7 @@ class TeamMemberDeleteViewTestCase(BackOfficeTestCase): self.client.force_login(self.admin) activity_log_count = ActivityLogEntry.objects.count() + # Remove the first manager response = self.client.post( reverse('backoffice:team-member-delete', kwargs={'pk': self.team_member_staff_2.pk, 'team': self.team.uuid}), {'confirmation': 'true'}, @@ -96,20 +97,30 @@ class TeamMemberDeleteViewTestCase(BackOfficeTestCase): self.assertFalse(TeamMember.objects.filter(user=self.staff_2).exists()) self.assertEqual(ActivityLogEntry.objects.count(), activity_log_count + 1) + # Remove a normal user + response = self.client.post( + reverse('backoffice:team-member-delete', kwargs={'pk': self.team_member_user.pk, 'team': self.team.uuid}), + {'confirmation': 'true'}, + ) + self.assertRedirects(response, reverse('backoffice:team', kwargs={'uuid': self.team.uuid})) + self.assertFalse(TeamMember.objects.filter(user=self.user).exists()) + self.assertEqual(ActivityLogEntry.objects.count(), activity_log_count + 2) + + # Try to remove the last manager response = self.client.post( reverse('backoffice:team-member-delete', kwargs={'pk': self.team_member_staff.pk, 'team': self.team.uuid}), {'confirmation': 'true'}, ) self.assertTemplateUsed(response, 'backoffice/components/confirmation_modal.html') self.assertTrue(TeamMember.objects.filter(user=self.staff).exists()) - self.assertEqual(ActivityLogEntry.objects.count(), activity_log_count + 1) + self.assertEqual(ActivityLogEntry.objects.count(), activity_log_count + 2) self.assertContains(response, _('TeamMember__delete__cannot_delete_last_manager')) def test_cannot_leave_last_manager(self): activate('en') - self.client.force_login(self.staff) activity_log_count = ActivityLogEntry.objects.count() + self.client.force_login(self.staff_2) response = self.client.post( reverse('backoffice:team-member-delete', kwargs={'pk': self.team_member_staff_2.pk, 'team': self.team.uuid}), {'confirmation': 'true'}, @@ -118,13 +129,23 @@ class TeamMemberDeleteViewTestCase(BackOfficeTestCase): self.assertFalse(TeamMember.objects.filter(user=self.staff_2).exists()) self.assertEqual(ActivityLogEntry.objects.count(), activity_log_count + 1) + self.client.force_login(self.user) + response = self.client.post( + reverse('backoffice:team-member-delete', kwargs={'pk': self.team_member_user.pk, 'team': self.team.uuid}), + {'confirmation': 'true'}, + ) + self.assertRedirects(response, reverse('backoffice:team', kwargs={'uuid': self.team.uuid})) + self.assertFalse(TeamMember.objects.filter(user=self.user).exists()) + self.assertEqual(ActivityLogEntry.objects.count(), activity_log_count + 2) + + self.client.force_login(self.staff) response = self.client.post( reverse('backoffice:team-member-delete', kwargs={'pk': self.team_member_staff.pk, 'team': self.team.uuid}), {'confirmation': 'true'}, ) self.assertTemplateUsed(response, 'backoffice/components/confirmation_modal.html') self.assertTrue(TeamMember.objects.filter(user=self.staff).exists()) - self.assertEqual(ActivityLogEntry.objects.count(), activity_log_count + 1) + self.assertEqual(ActivityLogEntry.objects.count(), activity_log_count + 2) self.assertContains(response, _('TeamMember__delete__cannot_delete_last_manager')) diff --git a/src/core/models/teams/team_member.py b/src/core/models/teams/team_member.py index 5523f45c72873bbebfaba0d7436e686875c5ee8c..0fb4ce95bef0d881924c0425c6ef4e14eba820b3 100644 --- a/src/core/models/teams/team_member.py +++ b/src/core/models/teams/team_member.py @@ -63,11 +63,13 @@ class TeamMember(RulesModel): return isinstance(obj, cls) def clean(self) -> None: - if not self.can_manage and self.team.members.filter(can_manage=True).count() == 1: + # Here we clan the new values of the object. So we have to check if it can_manage is False (e.g. remove) + if not self.can_manage and not self.team.members.exclude(user=self.user).filter(can_manage=True).exists(): raise LastManagerError(_('TeamMember__clean__cannot_remove_last_manager')) return super().clean() def delete(self, using: Any = None, keep_parents: bool = False) -> tuple[int, dict[str, int]]: - if self.can_manage and self.team.members.filter(can_manage=True).count() == 1: + # Here we check for the current value of the object. So we have to check if it can_manage is True + if self.can_manage and not self.team.members.exclude(user=self.user).filter(can_manage=True).exists(): raise LastManagerError(_('TeamMember__delete__cannot_delete_last_manager')) return super().delete(using, keep_parents)