From 30a75ee6da0f56badb95c1b8fcd86e8648fec81b Mon Sep 17 00:00:00 2001
From: Maximilian Moser <maximilian.moser@tuwien.ac.at>
Date: Wed, 19 Mar 2025 22:33:08 +0100
Subject: [PATCH] Update the request reminder email tasks to make them simpler
 to test

* return the request/record IDs for which reminders will be sent out, to
  enable simpler asserts in the tests
* handle the case that request topic's PID cannot be resolved - this is
  likely when the topic has not been published yet
* include "today" in the "accepted review" reminder, as too new requests
  will be filtered out anyway and are not expected to add significant
  load
---
 invenio_config_tuw/curations/tasks.py | 37 +++++++++++++++++++--------
 1 file changed, 26 insertions(+), 11 deletions(-)

diff --git a/invenio_config_tuw/curations/tasks.py b/invenio_config_tuw/curations/tasks.py
index 2fef1b5..7956786 100644
--- a/invenio_config_tuw/curations/tasks.py
+++ b/invenio_config_tuw/curations/tasks.py
@@ -15,6 +15,7 @@ from celery.schedules import crontab
 from flask import current_app, url_for
 from invenio_access.permissions import system_identity
 from invenio_notifications.tasks import broadcast_notification
+from invenio_pidstore.models import PIDDoesNotExistError
 from invenio_rdm_records.proxies import current_rdm_records_service as records_service
 from invenio_requests.customizations.event_types import CommentEventType
 from invenio_requests.proxies import current_events_service as events_service
@@ -145,7 +146,7 @@ def send_open_requests_reminder_to_reviewers(request_ids: List[str]):
 @shared_task(ignore_result=True)
 def remind_uploaders_about_accepted_reviews(
     remind_after_days: Optional[List[int]] = None,
-):
+) -> List[str]:
     """Find curation reviews that were accepted a while ago and remind the uploaders.
 
     ``remind_after_days`` specifies after how many days of inactivity reminders
@@ -156,7 +157,6 @@ def remind_uploaders_about_accepted_reviews(
         remind_after_days = [1, 3, 5, 7, 10, 14, 30]
 
     # first, we get a list of all requests that have been updated in the last year
-    # but excluding today (with the brackets "[ ... }")
     #
     # note: the date query is intended to set a soft limit on the number of results
     #       to avoid unbounded degradation over time
@@ -173,10 +173,11 @@ def remind_uploaders_about_accepted_reviews(
         q=(
             "type:rdm-curation AND "
             "status:accepted AND "
-            f"updated:[{start_date} TO {today}}}"
+            f"updated:[{start_date} TO {today}]"
         ),
     )
 
+    records_reminded = []
     now = datetime.now(tz=UTC)
     for request in accepted_curation_requests:
         if isinstance(request, dict):
@@ -184,18 +185,27 @@ def remind_uploaders_about_accepted_reviews(
             # BEWARE: other than for resolving the topic, this is useless!
             request = requests_service.record_cls(request)
 
-        record = request.topic.resolve()
-        if record.is_published:
-            continue
+        try:
+            # quick sanity check: don't notify about weird zombie requests
+            record = request.topic.resolve()
+            if record.is_published:
+                continue
+        except PIDDoesNotExistError:
+            pass
 
         # check if we're hitting one of the reminder dates
         timestamp = _get_last_request_action_timestamp(request)
         if abs((now - timestamp).days) in remind_after_days:
             send_acceptance_reminder_to_uploader.delay(record.pid.pid_value)
+            records_reminded.append(record.pid.pid_value)
+
+    return records_reminded
 
 
 @shared_task(ignore_result=True)
-def remind_reviewers_about_open_reviews(remind_after_days: Optional[List[int]] = None):
+def remind_reviewers_about_open_reviews(
+    remind_after_days: Optional[List[int]] = None,
+) -> List[str]:
     """Remind a user about having an accepted review for an unpublished record.
 
     ``remind_after_days`` specifies after how many days of inactivity reminders
@@ -220,10 +230,13 @@ def remind_reviewers_about_open_reviews(remind_after_days: Optional[List[int]] =
             # BEWARE: other than for resolving the topic, this is useless!
             request = requests_service.record_cls(request)
 
-        # quick sanity check: don't notify about weird zombie requests
-        record = request.topic.resolve()
-        if record.is_published:
-            continue
+        try:
+            # quick sanity check: don't notify about weird zombie requests
+            record = request.topic.resolve()
+            if record and record.is_published:
+                continue
+        except PIDDoesNotExistError:
+            pass
 
         # check if we're hitting one of the reminder dates
         timestamp = _get_last_request_action_timestamp(request)
@@ -233,6 +246,8 @@ def remind_reviewers_about_open_reviews(remind_after_days: Optional[List[int]] =
     if stale_request_ids:
         send_open_requests_reminder_to_reviewers.delay(stale_request_ids)
 
+    return stale_request_ids
+
 
 @shared_task(ignore_result=True)
 def auto_review_curation_request(request_id: str):
-- 
GitLab