From f854d4d18064693ee646a531f39c6e6aeafe2d93 Mon Sep 17 00:00:00 2001 From: David Eckhard Date: Wed, 19 Apr 2023 13:53:10 +0200 Subject: [PATCH] resolvers: add UserResultItemResolver notifications: update UserPreferencesFilter to work with dict tests: add test for UserPreferencesFilter --- invenio_users_resources/entity_resolvers.py | 15 +++++ invenio_users_resources/notifications.py | 36 +++++------ tests/test_notifications.py | 66 ++++++++++----------- 3 files changed, 63 insertions(+), 54 deletions(-) diff --git a/invenio_users_resources/entity_resolvers.py b/invenio_users_resources/entity_resolvers.py index b2f22e5..d0449ca 100644 --- a/invenio_users_resources/entity_resolvers.py +++ b/invenio_users_resources/entity_resolvers.py @@ -16,6 +16,7 @@ from invenio_records_resources.references.entity_resolvers import ( EntityProxy, EntityResolver, + ResultItemResolver, ) from .proxies import current_users_service @@ -83,3 +84,17 @@ def matches_entity(self, entity): def _get_entity_proxy(self, ref_dict): """Return a UserProxy for the given reference dict.""" return UserProxy(self, ref_dict) + + +class UserResultItemResolver(ResultItemResolver): + """Resolver for user result items.""" + + type_id = "user" + + def __init__(self): + """Ctor.""" + super().__init__( + UsersServiceConfig.result_item_cls, + UsersServiceConfig.service_id, + type_key=self.type_id, + ) diff --git a/invenio_users_resources/notifications.py b/invenio_users_resources/notifications.py index d14054c..d8b1f6a 100644 --- a/invenio_users_resources/notifications.py +++ b/invenio_users_resources/notifications.py @@ -9,25 +9,26 @@ """User specific resources for notifications.""" -from invenio_accounts.models import User from invenio_notifications.models import Recipient +from invenio_notifications.services.builders import RecipientBackendGenerator from invenio_notifications.services.filters import RecipientFilter +from invenio_records.dictutils import dict_lookup class UserPreferencesRecipientFilter(RecipientFilter): """Recipient filter for notifications being enabled at all.""" - @classmethod - def __call___(cls, notification, recipients): + def __call__(self, notification, recipients): """Filter recipients.""" - recipients = [ - r - for r in recipients - if r.get("data", {}) - .get("preferences", {}) - .get("notifications", {}) - .get("enabled", False) - ] + for key in list(recipients.keys()): + r = recipients[key] + if not ( + r.data.get("preferences", {}) + .get("notifications", {}) + .get("enabled", False) + ): + del recipients[key] + return recipients @@ -38,19 +39,18 @@ def __init__(self, key): def __call__(self, notification, recipients): """Update required recipient information and add backend id.""" - user = notification[self.key] - if isinstance(user, User): - if user.preferences["notifications"]["enabled"]: - recipients[user.id] = Recipient(data=user.dump()) - else: + user = dict_lookup(notification.context, self.key) + if user.get("preferences", {}).get("notifications", {}).get("enabled", True): recipients[user.get("id")] = Recipient(data=user) return recipients -class UserEmailBackend: - def __call__(self, notification, recipient): +class UserEmailBackend(RecipientBackendGenerator): + def __call__(self, notification, recipient, backends): """Update required recipient information and add backend id.""" + backends.append("email") return "email" + # NOTE: Not sure about the backend payload yet. Is it needed? # user = recipient.data # rec.backends.append( # { diff --git a/tests/test_notifications.py b/tests/test_notifications.py index 5a06789..21a11a4 100644 --- a/tests/test_notifications.py +++ b/tests/test_notifications.py @@ -8,42 +8,36 @@ """Notification related tests.""" -from invenio_users_resources.notifications import ( - UserPreferencesRecipientFilter, -) +from copy import deepcopy + +from invenio_notifications.models import Notification, Recipient + +from invenio_users_resources.notifications import UserPreferencesRecipientFilter from invenio_users_resources.records.api import UserAggregate -# def test_user_recipient_filter(user_pub): -# """Test user recipient filter for notifications.""" -# preferences_filter = UserPreferencesRecipientFilter - -# u = UserAggregate.from_user(user_pub.user).dumps() - -# user_notifications_enabled = u.copy() -# user_notifications_enabled["preferences"]["notifications"] = { -# "enabled": True -# } -# user_notifications_disabled = u.copy() -# user_notifications_disabled["preferences"]["notifications"] = { -# "enabled": False -# } - -# recipient_enabled = { -# "user": user_notifications_enabled, -# "backends": [], -# } -# recipient_disabled = { -# "user": user_notifications_disabled, -# "backends": [], -# } - -# filtered_users = preferences_filter.run( -# [ -# recipient_disabled, -# recipient_enabled, -# ] -# ) - -# assert 1 == len(filtered_users) -# assert recipient_enabled == filtered_users[0]["user"] +def test_user_recipient_filter(user_pub): + """Test user recipient filter for notifications.""" + preferences_filter = UserPreferencesRecipientFilter() + + u = UserAggregate.from_user(user_pub.user).dumps() + + user_notifications_enabled = deepcopy(u) + user_notifications_enabled["preferences"]["notifications"] = {"enabled": True} + user_notifications_disabled = deepcopy(u) + user_notifications_disabled["preferences"]["notifications"] = {"enabled": False} + + n = Notification(type="", context={}) + recipient_enabled = Recipient(data=user_notifications_enabled) + recipient_disabled = Recipient(data=user_notifications_disabled) + + filtered_recipients = preferences_filter( + notification=n, + recipients={ + user_notifications_disabled["id"]: recipient_disabled, + user_notifications_enabled["id"]: recipient_enabled, + }, + ) + + assert 1 == len(filtered_recipients) + assert recipient_enabled == filtered_recipients[user_notifications_enabled["id"]]