Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Notifications: Correction de l'envoi de certaines notifications #5343

Merged
merged 2 commits into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions itou/communications/dispatch/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ def is_manageable_by_user(self):
return self.can_be_disabled and self.is_applicable()

def should_send(self):
if not self.user.is_active:
return False
if not self.is_applicable():
return False
if self.is_manageable_by_user():
Expand Down
16 changes: 8 additions & 8 deletions itou/job_applications/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1085,9 +1085,9 @@ def notifications_new_for_employer(self, employer):

@property
def notifications_new_for_proxy(self):
return job_application_notifications.JobApplicationNewForPrescriberNotification(
return job_application_notifications.JobApplicationNewForProxyNotification(
self.sender,
self.sender_prescriber_organization,
self.sender_prescriber_organization or self.sender_company,
job_application=self,
)

Expand All @@ -1108,17 +1108,17 @@ def notifications_accept_for_job_seeker(self):

@property
def notifications_accept_for_proxy(self):
return job_application_notifications.JobApplicationAcceptedForPrescriberNotification(
return job_application_notifications.JobApplicationAcceptedForProxyNotification(
self.sender,
self.sender_prescriber_organization,
self.sender_prescriber_organization or self.sender_company,
job_application=self,
)

@property
def notifications_postpone_for_proxy(self):
return job_application_notifications.JobApplicationPostponedForProxyNotification(
self.sender,
self.sender_prescriber_organization,
self.sender_prescriber_organization or self.sender_company,
job_application=self,
)

Expand All @@ -1131,9 +1131,9 @@ def notifications_postpone_for_job_seeker(self):

@property
def notifications_refuse_for_proxy(self):
return job_application_notifications.JobApplicationRefusedForPrescriberNotification(
return job_application_notifications.JobApplicationRefusedForProxyNotification(
self.sender,
self.sender_prescriber_organization,
self.sender_prescriber_organization or self.sender_company,
job_application=self,
)

Expand All @@ -1155,7 +1155,7 @@ def notifications_cancel_for_employer(self, canceled_by):
def notifications_cancel_for_proxy(self):
return job_application_notifications.JobApplicationCanceledNotification(
self.sender,
self.sender_prescriber_organization,
self.sender_prescriber_organization or self.sender_company,
job_application=self,
)

Expand Down
12 changes: 6 additions & 6 deletions itou/job_applications/notifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ class JobApplicationNewForJobSeekerNotification(JobSeekerNotification, EmailNoti


@notifications_registry.register
class JobApplicationNewForPrescriberNotification(PrescriberNotification, EmailNotification):
"""Notification sent to prescriber when created"""
class JobApplicationNewForProxyNotification(PrescriberOrEmployerNotification, EmailNotification):
"""Notification sent to proxy (prescriber or employer/orienter) when created"""

name = "Confirmation d’envoi de candidature"
category = NotificationCategory.JOB_APPLICATION
Expand Down Expand Up @@ -71,8 +71,8 @@ class JobApplicationAcceptedForJobSeekerNotification(JobSeekerNotification, Emai


@notifications_registry.register
class JobApplicationAcceptedForPrescriberNotification(PrescriberNotification, EmailNotification):
"""Notification sent to prescriber when accepted"""
class JobApplicationAcceptedForProxyNotification(PrescriberOrEmployerNotification, EmailNotification):
"""Notification sent to proxy (prescriber or employer/orienter) when accepted"""

name = "Confirmation d’acceptation de candidature"
category = NotificationCategory.JOB_APPLICATION
Expand Down Expand Up @@ -101,8 +101,8 @@ class JobApplicationRefusedForJobSeekerNotification(JobSeekerNotification, Email


@notifications_registry.register
class JobApplicationRefusedForPrescriberNotification(PrescriberNotification, EmailNotification):
"""Notification sent to prescriber when refused"""
class JobApplicationRefusedForProxyNotification(PrescriberOrEmployerNotification, EmailNotification):
"""Notification sent to proxy (prescriber or employer/orienter) when refused"""

name = "Refus de candidature"
category = NotificationCategory.JOB_APPLICATION
Expand Down
2 changes: 1 addition & 1 deletion itou/www/apply/views/submit_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -676,7 +676,7 @@ def form_valid(self):
for employer in company_recipients:
job_application.notifications_new_for_employer(employer).send()
job_application.notifications_new_for_job_seeker.send()
if self.request.user.is_prescriber:
if self.request.user.kind in [UserKind.PRESCRIBER, UserKind.EMPLOYER]:
job_application.notifications_new_for_proxy.send()
finally:
# We are done, send to the (mostly) stateless final page as we now have no session.
Expand Down
19 changes: 19 additions & 0 deletions tests/communications/test_dispatch.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,25 @@ def test_method_send_for_employer_that_left_his_company(
" ne fait plus partie de votre structure." in mailoutbox[1].body
)

def test_method_send_for_inactive_user(self, email_notification, django_capture_on_commit_callbacks, mailoutbox):
self.user.is_active = False
self.user.save()
with django_capture_on_commit_callbacks(execute=True):
email_notification(self.user, self.organization).send()
assert len(mailoutbox) == 0

# But we still forward it if the user left his organozation
admin = PrescriberMembershipFactory(
user=PrescriberFactory(),
organization=self.organization,
is_admin=True,
).user

with django_capture_on_commit_callbacks(execute=True):
email_notification(self.user, self.organization).send()
assert len(mailoutbox) == 1
assert mailoutbox[0].to == [admin.email]


class TestProfiledNotification:
def setup_method(self):
Expand Down
15 changes: 15 additions & 0 deletions tests/job_applications/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -960,6 +960,21 @@ def test_cancel_sent_by_prescriber(self, django_capture_on_commit_callbacks, mai
assert job_application.job_seeker.get_full_name() in mailoutbox[0].body
assert mailoutbox[0].body == mailoutbox[1].body

def test_for_proxy_notification(self, subtests):
employer_job_app = JobApplicationFactory(sent_by_another_employer=True)
prescriber_job_app = JobApplicationFactory(sent_by_authorized_prescriber_organisation=True)

for transition in ["cancel", "postpone", "refuse", "new", "accept"]:
with subtests.test(transition):
assert (
getattr(employer_job_app, f"notifications_{transition}_for_proxy").structure
== employer_job_app.sender_company
)
assert (
getattr(prescriber_job_app, f"notifications_{transition}_for_proxy").structure
== prescriber_job_app.sender_prescriber_organization
)

def test_cancel_sent_by_job_seeker(self, django_capture_on_commit_callbacks, mailoutbox):
# When sent by jobseeker.
job_application = JobApplicationSentByJobSeekerFactory(state=JobApplicationState.ACCEPTED)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@
# ---
# name: test_employer_create_update_notification_settings[view queries - disable all notifications]
dict({
'num_queries': 19,
'num_queries': 22,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ça me chagrine un peu toutes ces requêtes mais ça sera pour une autre fois 🙈

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

J'ai eu la même reaction. Mais vu que c'est pas une page très utilisée, je me suis dit que c'était pas super grave

'queries': list([
dict({
'origin': list([
Expand Down Expand Up @@ -606,6 +606,60 @@
LIMIT 21
''',
}),
dict({
'origin': list([
'EditUserNotificationForm.save[www/dashboard/forms.py]',
'edit_user_notifications[www/dashboard/views.py]',
]),
'sql': '''
SELECT "communications_notificationrecord"."id",
"communications_notificationrecord"."notification_class",
"communications_notificationrecord"."name",
"communications_notificationrecord"."category",
"communications_notificationrecord"."can_be_disabled",
"communications_notificationrecord"."is_obsolete"
FROM "communications_notificationrecord"
WHERE (NOT ("communications_notificationrecord"."is_obsolete")
AND "communications_notificationrecord"."notification_class" = %s)
LIMIT 21
''',
}),
dict({
'origin': list([
'EditUserNotificationForm.save[www/dashboard/forms.py]',
'edit_user_notifications[www/dashboard/views.py]',
]),
'sql': '''
SELECT "communications_notificationrecord"."id",
"communications_notificationrecord"."notification_class",
"communications_notificationrecord"."name",
"communications_notificationrecord"."category",
"communications_notificationrecord"."can_be_disabled",
"communications_notificationrecord"."is_obsolete"
FROM "communications_notificationrecord"
WHERE (NOT ("communications_notificationrecord"."is_obsolete")
AND "communications_notificationrecord"."notification_class" = %s)
LIMIT 21
''',
}),
dict({
'origin': list([
'EditUserNotificationForm.save[www/dashboard/forms.py]',
'edit_user_notifications[www/dashboard/views.py]',
]),
'sql': '''
SELECT "communications_notificationrecord"."id",
"communications_notificationrecord"."notification_class",
"communications_notificationrecord"."name",
"communications_notificationrecord"."category",
"communications_notificationrecord"."can_be_disabled",
"communications_notificationrecord"."is_obsolete"
FROM "communications_notificationrecord"
WHERE (NOT ("communications_notificationrecord"."is_obsolete")
AND "communications_notificationrecord"."notification_class" = %s)
LIMIT 21
''',
}),
dict({
'origin': list([
'EditUserNotificationForm.save[www/dashboard/forms.py]',
Expand Down Expand Up @@ -635,6 +689,9 @@
%s,
%s,
%s,
%s,
%s,
%s,
%s)
AND "communications_disablednotification"."settings_id" = %s)
ORDER BY RANDOM() ASC
Expand All @@ -655,6 +712,9 @@
(%s, %s, %s),
(%s, %s, %s),
(%s, %s, %s),
(%s, %s, %s),
(%s, %s, %s),
(%s, %s, %s),
(%s, %s, %s) RETURNING "communications_disablednotification"."id"
''',
}),
Expand Down
Loading