Skip to content

Commit

Permalink
Merge pull request #3565 from webkom/ivarnakken/aba-855-add-filter-fo…
Browse files Browse the repository at this point in the history
…r-users-in-a-specific-pool-to-announcements

Extend announcement to support more filtering event
  • Loading branch information
ivarnakken authored Mar 8, 2024
2 parents 79ad51b + e414577 commit be1c3ee
Show file tree
Hide file tree
Showing 11 changed files with 195 additions and 15 deletions.
15 changes: 12 additions & 3 deletions lego/apps/events/fixtures/test_events.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@
created_by: 1
require_auth: False
responsible_group: 25

- model: events.Pool
pk: 1
fields:
Expand Down Expand Up @@ -287,9 +287,9 @@
pk: 9
fields:
name: Abakusmember
capacity: 1
capacity: 1
event: 13
counter: 1
counter: 1
activation_date: "2019-09-01T13:20:30+03:00"
permission_groups:
- - Abakus
Expand Down Expand Up @@ -361,3 +361,12 @@
pool: 9
registration_date: "2011-09-01T13:20:30+03:00"
status: "SUCCESS_REGISTER"

- model: events.Registration
pk: 8
fields:
user: 10
event: 1
pool: null
registration_date: "2011-09-01T13:20:30+03:00"
status: "SUCCESS_REGISTER"
6 changes: 5 additions & 1 deletion lego/apps/events/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -776,10 +776,14 @@ def restricted_lookup(self) -> tuple[list[User], list]:
)
return [registration.user for registration in registrations], []

def announcement_lookup(self) -> list[User]:
def announcement_lookup(self, exclude_waiting_list: bool) -> list[User]:
registrations: QuerySet[Registration] = self.registrations.filter(
status=constants.SUCCESS_REGISTER
)

if exclude_waiting_list:
registrations = registrations.exclude(pool=None)

return [registration.user for registration in registrations]

def add_legacy_registration(self) -> None:
Expand Down
6 changes: 3 additions & 3 deletions lego/apps/events/tests/test_registrations.py
Original file line number Diff line number Diff line change
Expand Up @@ -413,13 +413,13 @@ def test_register_to_waiting_list_after_unregister(self):

registration = Registration.objects.get_or_create(event=event, user=user)[0]
event.register(registration)
self.assertEqual(event.waiting_registrations.count(), 1)
self.assertEqual(event.waiting_registrations.count(), 2)

event.unregister(registration)
self.assertEqual(event.waiting_registrations.count(), 0)
self.assertEqual(event.waiting_registrations.count(), 1)

event.register(registration)
self.assertEqual(event.waiting_registrations.count(), 1)
self.assertEqual(event.waiting_registrations.count(), 2)

def test_unregistering_non_existing_user(self):
"""Test that non existing user trying to unregister raises error"""
Expand Down
23 changes: 23 additions & 0 deletions lego/apps/meetings/fixtures/test_meetings.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,26 @@
end_time: "2011-02-01T23:59:00+00:00"
report: "tomp"
report_author: 3

- model: meetings.Meeting
pk: 4
fields:
title: Enda et tomt møte
location: "null"
start_time: "2024-02-01T17:15:00+00:00"
end_time: "2024-02-01T23:59:00+00:00"
report: "hei"
report_author: 3

- model: meetings.MeetingInvitation
pk: 1
fields:
user: 8
meeting: 4
status: "ATTENDING"

- model: meetings.MeetingInvitation
pk: 2
fields:
user: 9
meeting: 4
13 changes: 11 additions & 2 deletions lego/apps/meetings/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,17 @@ def restricted_lookup(self):
"""
return self.invited_users, []

def announcement_lookup(self):
return self.invited_users
def announcement_lookup(self, meeting_invitation_status) -> list[User]:
meeting_invitations = self.invitations

if meeting_invitation_status:
meeting_invitations = meeting_invitations.filter(
status=meeting_invitation_status
)

return User.objects.filter(
id__in=meeting_invitations.values_list("user", flat=True)
)

@property
def content_target(self):
Expand Down
39 changes: 35 additions & 4 deletions lego/apps/notifications/fixtures/test_announcements.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
pk: 1
fields:
message: abakom
sent: '2019-02-10T14:38:49.164657Z'
sent: "2019-02-10T14:38:49.164657Z"
groups: [3]
created_by: 4

Expand All @@ -11,15 +11,15 @@
fields:
message: event_from_arrkom
from_group: 4
sent: '2019-02-10T14:38:49.164657Z'
sent: "2019-02-10T14:38:49.164657Z"
events: [1]
created_by: 4

- model: notifications.Announcement
pk: 3
fields:
message: event_abakom
sent: '2019-02-10T14:38:49.164657Z'
sent: "2019-02-10T14:38:49.164657Z"
groups: [3]
events: [1]
created_by: 4
Expand All @@ -29,7 +29,7 @@
fields:
message: user_from_webkom
from_group: 12
users: [1, 2,3]
users: [1, 2, 3]
created_by: 4

- model: notifications.Announcement
Expand All @@ -46,3 +46,34 @@
message: test_from_user_webkom
groups: [1]
created_by: 3

- model: notifications.Announcement
pk: 7
fields:
message: another_event_from_arrkom
events: [1]
exclude_waiting_list: false
created_by: 9

- model: notifications.Announcement
pk: 8
fields:
message: yet_another_event_from_arrkom
events: [1]
exclude_waiting_list: true
created_by: 9

- model: notifications.Announcement
pk: 9
fields:
message: meeting
meetings: [4]
created_by: 1

- model: notifications.Announcement
pk: 10
fields:
message: meeting
meetings: [4]
meeting_invitation_status: "ATTENDING"
created_by: 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Generated by Django 4.0.10 on 2024-03-07 14:51

from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("notifications", "0014_alter_notificationsetting_notification_type"),
]

operations = [
migrations.AddField(
model_name="announcement",
name="exclude_waiting_list",
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name="announcement",
name="meeting_invitation_status",
field=models.CharField(
blank=True,
choices=[
("NO_ANSWER", "NO_ANSWER"),
("ATTENDING", "ATTENDING"),
("NOT_ATTENDING", "NOT_ATTENDING"),
],
max_length=50,
),
),
]
13 changes: 12 additions & 1 deletion lego/apps/notifications/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from django.utils import timezone

from lego.apps.action_handlers.events import handle_event
from lego.apps.meetings import constants
from lego.utils.models import BasisModel

from .constants import (
Expand Down Expand Up @@ -76,12 +77,16 @@ class Announcement(BasisModel):
message = models.TextField()
sent = models.DateTimeField(null=True, default=None)

MANY_TO_MANY_RELATIONS = ["users", "groups", "events", "meetings"]
MANY_TO_MANY_RELATIONS = ["users", "groups"]

users = models.ManyToManyField("users.User", blank=True)
groups = models.ManyToManyField("users.AbakusGroup", blank=True)
events = models.ManyToManyField("events.Event", blank=True)
exclude_waiting_list = models.BooleanField(default=False)
meetings = models.ManyToManyField("meetings.Meeting", blank=True)
meeting_invitation_status = models.CharField(
max_length=50, choices=constants.INVITATION_STATUS_TYPES, blank=True
)
from_group = models.ForeignKey(
"users.AbakusGroup",
on_delete=models.PROTECT,
Expand All @@ -104,6 +109,12 @@ def lookup_recipients(self):
users = announcement_lookup()
all_users += list(users)

for event in self.events.all():
all_users += event.announcement_lookup(self.exclude_waiting_list)

for meeting in self.meetings.all():
all_users += meeting.announcement_lookup(self.meeting_invitation_status)

return list(set(all_users))

def send(self):
Expand Down
4 changes: 4 additions & 0 deletions lego/apps/notifications/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ class Meta:
"users",
"groups",
"events",
"exclude_waiting_list",
"meetings",
"meeting_invitation_status",
)
read_only_fields = ("sent",)

Expand All @@ -59,6 +61,8 @@ class Meta(AnnouncementListSerializer.Meta):
"users",
"groups",
"events",
"exclude_waiting_list",
"meetings",
"meeting_invitation_status",
)
read_only_fields = ("sent",)
57 changes: 57 additions & 0 deletions lego/apps/notifications/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ class AnnouncementViewSetTestCase(BaseAPITestCase):
"test_events.yaml",
"test_companies.yaml",
"test_announcements.yaml",
"test_meetings.yaml",
]

def setUp(self):
Expand Down Expand Up @@ -238,3 +239,59 @@ def test_send_announcement_unauthorized(self):
self.client.force_authenticate(self.unauthorized_user)
response = self.client.post(f"{self.url}{self.unsent_announcement.id}/send/")
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)

def test_send_announcement_twice(self):
"""
An announcement can not be sent twice
"""

self.client.force_authenticate(self.authorized_user)
response = self.client.post(f"{self.url}{self.unsent_announcement.id}/send/")
self.assertEqual(response.status_code, status.HTTP_202_ACCEPTED)
response = self.client.post(f"{self.url}{self.unsent_announcement.id}/send/")
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

def test_recipients_lookup_to_users(self):
"""
An announcement should be sent to the specified users
"""

announcement = Announcement.objects.get(pk=4)
recipients = announcement.lookup_recipients()
self.assertEqual(len(recipients), 3)

def test_recipients_lookup_for_event(self):
"""
Everyone registered to an event should receive the announcement
"""
announcement = Announcement.objects.get(pk=7)
recipients = announcement.lookup_recipients()
self.assertEqual(len(recipients), 3)

def test_recipients_lookup_for_event_exclude_waiting_list(self):
"""
Everyone registered to an event, except those on waiting list,
should receive the announcement
"""

announcement = Announcement.objects.get(pk=8)
recipients = announcement.lookup_recipients()
self.assertEqual(len(recipients), 2)

def test_recipients_lookup_for_meeting(self):
"""
Everyone invited to a meeting should receive the announcement
"""

announcement = Announcement.objects.get(pk=9)
recipients = announcement.lookup_recipients()
self.assertEqual(len(recipients), 2)

def test_recipients_lookup_for_only_meeting_attendees(self):
"""
Only those invited to a meeting and accepted should receive the announcement
"""

announcement = Announcement.objects.get(pk=10)
recipients = announcement.lookup_recipients()
self.assertEqual(len(recipients), 1)
4 changes: 3 additions & 1 deletion lego/apps/restricted/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ def test_lookup_recipients(self):
restricted_mail = RestrictedMail.objects.get(id=1)
recipients = restricted_mail.lookup_recipients()

self.assertCountEqual(recipients, ["[email protected]", "[email protected]"])
self.assertCountEqual(
recipients, ["[email protected]", "[email protected]", "[email protected]"]
)

def test_mark_used(self):
"""The used field is not None when the item is marked as used"""
Expand Down

0 comments on commit be1c3ee

Please sign in to comment.