Skip to content

Commit

Permalink
resolvers: add UserResultItemResolver
Browse files Browse the repository at this point in the history
notifications: update UserPreferencesFilter to work with dict
tests: add test for UserPreferencesFilter
  • Loading branch information
rekt-hard committed Apr 19, 2023
1 parent a777aff commit f4c0d44
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 54 deletions.
15 changes: 15 additions & 0 deletions invenio_users_resources/entity_resolvers.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from invenio_records_resources.references.entity_resolvers import (
EntityProxy,
EntityResolver,
ResultItemResolver,
)

from .proxies import current_users_service
Expand Down Expand Up @@ -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,
)
40 changes: 22 additions & 18 deletions invenio_users_resources/notifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,48 +9,52 @@
"""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


class UserRecipient:
"""User recipient generator for a notification."""

def __init__(self, key):
"""Ctor."""
self.key = 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):
"""User related email backend generator for a notification."""

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(
# {
Expand Down
66 changes: 30 additions & 36 deletions tests/test_notifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"]]

0 comments on commit f4c0d44

Please sign in to comment.