Skip to content

Commit d694281

Browse files
Add scheduled field to Notification model and update digest email tasks
1 parent d00a752 commit d694281

4 files changed

Lines changed: 70 additions & 0 deletions

File tree

api_tests/notifications/test_notification_digest.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import pytest
2+
from django.utils import timezone
23
from django.contrib.contenttypes.models import ContentType
34

45
from osf.models import Notification, NotificationType, NotificationTypeEnum, EmailTask, Email
@@ -186,6 +187,26 @@ def test_get_users_emails(self):
186187
assert user_info['user_id'] == user._id
187188
assert any(msg['notification_id'] == notification1.id for msg in user_info['info'])
188189

190+
def test_get_users_emails_ignore_scheduled(self):
191+
user = AuthUserFactory()
192+
notification_type = NotificationType.objects.get(name=NotificationTypeEnum.USER_FILE_UPDATED)
193+
notification1 = Notification.objects.create(
194+
subscription=add_notification_subscription(user, notification_type, 'daily'),
195+
event_context={},
196+
sent=None
197+
)
198+
Notification.objects.create(
199+
subscription=add_notification_subscription(user, notification_type, 'daily'),
200+
event_context={},
201+
sent=None,
202+
scheduled=timezone.now()
203+
)
204+
res = list(get_users_emails('daily'))
205+
assert len(res) == 1
206+
user_info = res[0]
207+
assert user_info['user_id'] == user._id
208+
assert any(msg['notification_id'] == notification1.id for msg in user_info['info'])
209+
189210
def test_get_moderators_emails(self):
190211
user = AuthUserFactory()
191212
provider = RegistrationProviderFactory()
@@ -204,6 +225,30 @@ def test_get_moderators_emails(self):
204225
]
205226
assert entry, 'Expected moderator digest group'
206227

228+
def test_get_moderators_emails_ignore_scheduled(self):
229+
user = AuthUserFactory()
230+
provider = RegistrationProviderFactory()
231+
reg = RegistrationFactory(provider=provider)
232+
notification_type = NotificationType.objects.get(name=NotificationTypeEnum.PROVIDER_NEW_PENDING_SUBMISSIONS)
233+
subscription = add_notification_subscription(user, notification_type, 'daily', subscribed_object=reg)
234+
Notification.objects.create(
235+
subscription=subscription,
236+
event_context={},
237+
sent=None
238+
)
239+
Notification.objects.create(
240+
subscription=subscription,
241+
event_context={},
242+
sent=None,
243+
scheduled=timezone.now()
244+
)
245+
res = list(get_moderators_emails('daily'))
246+
assert len(res) >= 1
247+
entry = [
248+
x for x in res if x['user_id'] == user._id and subscription.subscribed_object.id == reg.id
249+
]
250+
assert entry, 'Expected moderator digest group'
251+
207252
def test_send_users_digest_email_end_to_end(self):
208253
user = AuthUserFactory()
209254
notification_type = NotificationType.objects.get(name=NotificationTypeEnum.USER_FILE_UPDATED)

notifications/tasks.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,8 @@ def send_users_digest_email(dry_run=False):
314314
user_id = group['user_id']
315315
notification_ids = [msg['notification_id'] for msg in group['info']]
316316
if not dry_run:
317+
notifications_qs = Notification.objects.filter(id__in=notification_ids)
318+
notifications_qs.update(scheduled=timezone.now())
317319
send_user_email_task.delay(user_id, notification_ids)
318320

319321
@celery_app.task(name='notifications.tasks.send_moderators_digest_email')
@@ -334,6 +336,8 @@ def send_moderators_digest_email(dry_run=False):
334336
provider_content_type_id = group['provider_content_type_id']
335337
notification_ids = [msg['notification_id'] for msg in group['info']]
336338
if not dry_run:
339+
notifications_qs = Notification.objects.filter(id__in=notification_ids)
340+
notifications_qs.update(scheduled=timezone.now())
337341
send_moderator_email_task.delay(user_id, notification_ids, provider_content_type_id, provider_id)
338342

339343
def get_moderators_emails(message_freq: str):
@@ -358,6 +362,7 @@ def get_moderators_emails(message_freq: str):
358362
INNER JOIN osf_notificationtype AS nt ON ns.notification_type_id = nt.id
359363
LEFT JOIN osf_guid ON ns.user_id = osf_guid.object_id
360364
WHERE n.sent IS NULL
365+
AND n.scheduled IS NULL
361366
AND ns.message_frequency = %s
362367
AND nt.name IN (%s, %s)
363368
AND nt.name NOT IN (%s, %s, %s)
@@ -401,6 +406,7 @@ def get_users_emails(message_freq):
401406
INNER JOIN osf_notificationtype AS nt ON ns.notification_type_id = nt.id
402407
LEFT JOIN osf_guid ON ns.user_id = osf_guid.object_id
403408
WHERE n.sent IS NULL
409+
AND n.scheduled IS NULL
404410
AND ns.message_frequency = %s
405411
AND nt.name NOT IN (%s, %s, %s, %s, %s)
406412
AND osf_guid.content_type_id = (
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Generated by Django 4.2.26 on 2026-06-04 13:39
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('osf', '0039_merge_20260427_1359'),
10+
]
11+
12+
operations = [
13+
migrations.AddField(
14+
model_name='notification',
15+
name='scheduled',
16+
field=models.DateTimeField(blank=True, null=True),
17+
),
18+
]

osf/models/notification.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class Notification(models.Model):
1818
sent = models.DateTimeField(null=True, blank=True)
1919
created = models.DateTimeField(auto_now_add=True)
2020
fake_sent = models.BooleanField(default=False)
21+
scheduled = models.DateTimeField(null=True, blank=True)
2122

2223
def send(
2324
self,

0 commit comments

Comments
 (0)