Skip to content

Commit 87b00d4

Browse files
authored
Merge pull request #867 from City-of-Helsinki/feature/LINK-1926_invitation-sending
LINK-1926 | send invitation is is_substitute_user is changed
2 parents 3f36baa + 3319ee1 commit 87b00d4

File tree

6 files changed

+94
-74
lines changed

6 files changed

+94
-74
lines changed

events/api.py

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1503,21 +1503,14 @@ def are_only_admin_visible_fields_allowed(self, obj):
15031503
def _create_or_update_registration_user_accesses(
15041504
registration, registration_user_accesses
15051505
):
1506-
users_to_send_invitations = []
1507-
15081506
for data in registration_user_accesses:
15091507
if current_obj := data.pop("id", None):
15101508
current_id = current_obj.id
1511-
current_email = current_obj.email
15121509
else:
15131510
current_id = None
1514-
current_email = None
15151511

15161512
try:
1517-
(
1518-
user_instance,
1519-
created,
1520-
) = RegistrationUserAccess.objects.update_or_create(
1513+
RegistrationUserAccess.objects.update_or_create(
15211514
id=current_id,
15221515
registration=registration,
15231516
defaults=data,
@@ -1541,16 +1534,6 @@ def _create_or_update_registration_user_accesses(
15411534
else:
15421535
raise
15431536

1544-
# Send invitation to new registration users or if the email is updated to an
1545-
# existing registration user
1546-
if created or (current_email != user_instance.email):
1547-
users_to_send_invitations.append(user_instance)
1548-
1549-
# Send invitations to registration users after updating all registration users to
1550-
# make sure that all instances are created or updated successfully
1551-
for user_instance in users_to_send_invitations:
1552-
user_instance.send_invitation()
1553-
15541537
@staticmethod
15551538
def _create_or_update_registration_price_groups(
15561539
registration, registration_price_groups

registrations/admin.py

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -89,25 +89,6 @@ def get_formsets_with_inlines(self, request, obj=None):
8989
):
9090
yield inline.get_formset(request, obj), inline
9191

92-
def save_related(self, request, form, formsets, change):
93-
for formset in formsets:
94-
if formset.model == RegistrationUserAccess:
95-
formset.save(commit=False)
96-
97-
for added_registration_user_accesses in formset.new_objects:
98-
# Send invitation email if new registration user accesses is added
99-
added_registration_user_accesses.send_invitation()
100-
101-
for [
102-
changed_registration_user_access,
103-
changed_fields,
104-
] in formset.changed_objects:
105-
# Send invitation email if email address is changed
106-
if "email" in changed_fields:
107-
changed_registration_user_access.send_invitation()
108-
109-
super(RegistrationAdmin, self).save_related(request, form, formsets, change)
110-
11192
def get_readonly_fields(self, request, obj=None):
11293
if obj:
11394
return ["id", "event"]

registrations/models.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,22 @@ def send_invitation(self):
864864
html_message=rendered_body,
865865
)
866866

867+
@transaction.atomic
868+
def save(self, *args, **kwargs):
869+
if self.pk:
870+
old_instance = RegistrationUserAccess.objects.filter(pk=self.pk).first()
871+
else:
872+
old_instance = None
873+
874+
super().save(*args, **kwargs)
875+
876+
if (
877+
not old_instance
878+
or old_instance.email != self.email
879+
or old_instance.is_substitute_user != self.is_substitute_user
880+
):
881+
self.send_invitation()
882+
867883
class Meta:
868884
unique_together = ("email", "registration")
869885

registrations/tests/test_admin.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from django.contrib import admin
44
from django.contrib.admin.sites import AdminSite
55
from django.contrib.auth import get_user_model
6+
from django.core import mail
67
from django.test import RequestFactory, TestCase
78
from django.utils import translation
89
from rest_framework import status
@@ -262,6 +263,7 @@ def test_send_invitation_email_when_registration_user_access_is_updated(self):
262263
registration_user_access = RegistrationUserAccess.objects.create(
263264
registration=self.registration, email=EMAIL
264265
)
266+
mail.outbox.clear()
265267
self.registration.event.name = EVENT_NAME
266268
self.registration.event.save()
267269

registrations/tests/test_registration_put.py

Lines changed: 53 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@ def test_send_email_to_new_registration_user_access(
325325
RegistrationUserAccessFactory(registration=registration, email="delete1@email.com")
326326
RegistrationUserAccessFactory(registration=registration, email="delete2@email.com")
327327
assert len(registration.registration_user_accesses.all()) == 2
328+
mail.outbox.clear()
328329

329330
registration_data = {
330331
"event": {"@id": get_event_url(registration.event.id)},
@@ -366,6 +367,7 @@ def test_email_is_not_sent_if_registration_user_access_email_is_not_updated(
366367
email=user_email,
367368
is_substitute_user=is_substitute_user,
368369
)
370+
mail.outbox.clear()
369371

370372
registration_data = {
371373
"event": {"@id": get_event_url(registration.event.id)},
@@ -397,29 +399,68 @@ def test_email_is_sent_if_registration_user_access_email_is_updated(
397399
email=user_email,
398400
is_substitute_user=is_substitute_user,
399401
)
402+
mail.outbox.clear()
400403

401-
registration_data = {
402-
"event": {"@id": get_event_url(registration.event.id)},
403-
"registration_user_accesses": [
404-
{
405-
"id": registration_user_access.id,
406-
"email": edited_user_email,
407-
"is_substitute_user": is_substitute_user,
408-
}
409-
],
410-
}
404+
with translation.override("fi"):
405+
registration.event.type_id = Event.TypeId.GENERAL
406+
registration.event.name = event_name
407+
registration.event.save()
408+
409+
registration_data = {
410+
"event": {"@id": get_event_url(registration.event.id)},
411+
"registration_user_accesses": [
412+
{
413+
"id": registration_user_access.id,
414+
"email": edited_user_email,
415+
"is_substitute_user": is_substitute_user,
416+
}
417+
],
418+
}
419+
420+
assert_update_registration(user_api_client, registration.id, registration_data)
421+
# assert that the email after update was sent
422+
registration_user_access.refresh_from_db()
423+
assert_invitation_email_is_sent(
424+
edited_user_email, event_name, registration_user_access
425+
)
426+
427+
428+
@pytest.mark.parametrize("is_substitute_user", [False, True])
429+
@pytest.mark.django_db
430+
def test_email_is_sent_if_is_substitute_value_of_registration_user_access_is_updated(
431+
registration, user_api_client, is_substitute_user
432+
):
433+
user_email = hel_email
434+
435+
registration_user_access = RegistrationUserAccessFactory(
436+
registration=registration,
437+
email=user_email,
438+
is_substitute_user=is_substitute_user,
439+
)
440+
mail.outbox.clear()
411441

412442
with translation.override("fi"):
413443
registration.event.type_id = Event.TypeId.GENERAL
414444
registration.event.name = event_name
415445
registration.event.save()
416446

447+
registration_data = {
448+
"event": {"@id": get_event_url(registration.event.id)},
449+
"registration_user_accesses": [
450+
{
451+
"id": registration_user_access.id,
452+
"email": hel_email,
453+
"is_substitute_user": False if is_substitute_user else True,
454+
}
455+
],
456+
}
457+
417458
assert_update_registration(user_api_client, registration.id, registration_data)
418459

419-
# assert that the email was sent
460+
# assert that the email after update was sent
420461
registration_user_access.refresh_from_db()
421462
assert_invitation_email_is_sent(
422-
edited_user_email, event_name, registration_user_access
463+
user_email, event_name, registration_user_access
423464
)
424465

425466

registrations/tests/utils.py

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -39,36 +39,33 @@ def assert_invitation_email_is_sent(
3939
expected_subject: Optional[str] = None,
4040
expected_body: Optional[str] = None,
4141
) -> None:
42-
assert mail.outbox[0].to[0] == email
42+
first_email = mail.outbox[0]
43+
assert first_email.to[0] == email
4344

4445
ui_locale = ui_locale or "fi"
45-
email_body_string = str(mail.outbox[0].alternatives[0])
46+
email_body_string = str(first_email.alternatives[0])
4647

4748
if registration_user_access.is_substitute_user:
4849
expected_subject = expected_subject or "Oikeudet myönnetty ilmoittautumiseen"
49-
assert mail.outbox[0].subject.startswith(expected_subject)
50-
5150
expected_body = expected_body or (
5251
f"Sähköpostiosoitteelle <strong>{email}</strong> on myönnetty sijaisen käyttöoikeudet "
5352
f"tapahtuman <strong>{event_name}</strong> ilmoittautumiselle."
5453
)
55-
assert expected_body in email_body_string
5654

5755
service_base_url = settings.LINKED_EVENTS_UI_URL
5856
registration_term = "registrations"
5957
else:
6058
expected_subject = expected_subject or "Oikeudet myönnetty osallistujalistaan"
61-
assert mail.outbox[0].subject.startswith(expected_subject)
62-
6359
expected_body = expected_body or (
6460
f"Sähköpostiosoitteelle <strong>{email}</strong> on myönnetty oikeudet lukea "
6561
f"tapahtuman <strong>{event_name}</strong> osallistujalista."
6662
)
67-
assert expected_body in email_body_string
68-
6963
service_base_url = settings.LINKED_REGISTRATIONS_UI_URL
7064
registration_term = "registration"
7165

66+
assert first_email.subject.startswith(expected_subject)
67+
assert expected_body in email_body_string
68+
7269
participant_list_url = (
7370
f"{service_base_url}/{ui_locale}/{registration_term}/"
7471
f"{registration_user_access.registration_id}/attendance-list/"
@@ -128,22 +125,22 @@ def create_user_by_role(
128125

129126
user_role_mapping = {
130127
"superuser": lambda usr: None,
131-
"admin": lambda usr: usr.admin_organizations.add(organization)
132-
if organization
133-
else None,
134-
"registration_admin": lambda usr: usr.registration_admin_organizations.add(
135-
organization
136-
)
137-
if organization
138-
else None,
139-
"financial_admin": lambda usr: usr.financial_admin_organizations.add(
140-
organization
141-
)
142-
if organization
143-
else None,
144-
"regular_user": lambda usr: usr.organization_memberships.add(organization)
145-
if organization
146-
else None,
128+
"admin": lambda usr: (
129+
usr.admin_organizations.add(organization) if organization else None
130+
),
131+
"registration_admin": lambda usr: (
132+
usr.registration_admin_organizations.add(organization)
133+
if organization
134+
else None
135+
),
136+
"financial_admin": lambda usr: (
137+
usr.financial_admin_organizations.add(organization)
138+
if organization
139+
else None
140+
),
141+
"regular_user": lambda usr: (
142+
usr.organization_memberships.add(organization) if organization else None
143+
),
147144
}
148145
if isinstance(additional_roles, dict):
149146
user_role_mapping.update(additional_roles)

0 commit comments

Comments
 (0)