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

added new apis to get user notifications and bulk update status #855

Merged
merged 5 commits into from
Sep 13, 2024
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
49 changes: 44 additions & 5 deletions ddpui/api/notifications_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from ddpui.schemas.notifications_api_schemas import (
CreateNotificationPayloadSchema,
UpdateReadStatusSchema,
UpdateReadStatusSchemav1,
)
from ddpui.models.org_user import OrgUser

Expand Down Expand Up @@ -73,12 +74,16 @@


@notificationsapi.get("/history")
def get_notification_history(request, page: int = 1, limit: int = 10):
def get_notification_history(
request, page: int = 1, limit: int = 10, read_status: int = None
):
"""
Returns all the notifications including the
past and the future scheduled notifications
"""
error, result = notifications_service.get_notification_history(page, limit)
error, result = notifications_service.get_notification_history(
page, limit, read_status=None
)
if error is not None:
raise HttpError(400, error)

Expand All @@ -97,22 +102,41 @@
return result


@notificationsapi.get("/", auth=auth.CustomAuthMiddleware())
@notificationsapi.get("/", auth=auth.CustomAuthMiddleware(), deprecated=True)
def get_user_notifications(request, page: int = 1, limit: int = 10):
"""
Returns all the notifications for a particular user.
It returns only the past notifications,i.e,notifications
which are already sent
"""
orguser = request.orguser
error, result = notifications_service.get_user_notifications(orguser, page, limit)
error, result = notifications_service.fetch_user_notifications(orguser, page, limit)
if error is not None:
raise HttpError(400, error)

Check warning on line 115 in ddpui/api/notifications_api.py

View check run for this annotation

Codecov / codecov/patch

ddpui/api/notifications_api.py#L115

Added line #L115 was not covered by tests

return result


@notificationsapi.get("/v1", auth=auth.CustomAuthMiddleware())
def get_user_notifications_v1(
request, page: int = 1, limit: int = 10, read_status: int = None
):
"""
Returns all the notifications for a particular user.
It returns only the past notifications,i.e,notifications
which are already sent
"""
orguser = request.orguser
error, result = notifications_service.fetch_user_notifications_v1(

Check warning on line 130 in ddpui/api/notifications_api.py

View check run for this annotation

Codecov / codecov/patch

ddpui/api/notifications_api.py#L129-L130

Added lines #L129 - L130 were not covered by tests
orguser, page, limit, read_status
)
if error is not None:
raise HttpError(400, error)

return result


@notificationsapi.put("/", auth=auth.CustomAuthMiddleware())
@notificationsapi.put("/", auth=auth.CustomAuthMiddleware(), deprecated=True)
def mark_as_read(request, payload: UpdateReadStatusSchema):
"""
Handles the task of updating the read_status
Expand All @@ -128,6 +152,21 @@
return result


@notificationsapi.put("/v1", auth=auth.CustomAuthMiddleware())
def mark_as_read_v1(request, payload: UpdateReadStatusSchemav1):
"""
Bulk update of read status of notifications
"""
orguser: OrgUser = request.orguser
error, result = notifications_service.mark_notifications_as_read_or_unread(

Check warning on line 161 in ddpui/api/notifications_api.py

View check run for this annotation

Codecov / codecov/patch

ddpui/api/notifications_api.py#L160-L161

Added lines #L160 - L161 were not covered by tests
orguser.id, payload.notification_ids, payload.read_status
)
if error is not None:
raise HttpError(400, error)

Check warning on line 165 in ddpui/api/notifications_api.py

View check run for this annotation

Codecov / codecov/patch

ddpui/api/notifications_api.py#L164-L165

Added lines #L164 - L165 were not covered by tests

return result

Check warning on line 167 in ddpui/api/notifications_api.py

View check run for this annotation

Codecov / codecov/patch

ddpui/api/notifications_api.py#L167

Added line #L167 was not covered by tests


@notificationsapi.delete("/")
def delete_notification(request, notification_id: int):
"""
Expand Down
71 changes: 67 additions & 4 deletions ddpui/core/notifications_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,13 +157,18 @@

# get notification history
def get_notification_history(
page: int, limit: int
page: int, limit: int, read_status: Optional[int] = None
) -> Tuple[Optional[None], Dict[str, Any]]:
"""returns history of sent notifications"""
notifications = Notification.objects.all().order_by("-timestamp")
notifications = Notification.objects

if read_status:
notifications = notifications.filter(read_status=(read_status == 1))

Check warning on line 166 in ddpui/core/notifications_service.py

View check run for this annotation

Codecov / codecov/patch

ddpui/core/notifications_service.py#L166

Added line #L166 was not covered by tests

notifications = notifications.all().order_by("-timestamp")

paginator = Paginator(notifications, limit)
paginated_notifications: Notification = paginator.get_page(page)
paginated_notifications: list[Notification] = paginator.get_page(page)

notification_history = [
{
Expand Down Expand Up @@ -214,7 +219,7 @@


# get notification data
def get_user_notifications(
def fetch_user_notifications(
orguser: OrgUser, page: int, limit: int
) -> Tuple[Optional[None], Dict[str, Any]]:
"""returns all notifications for a specific user"""
Expand Down Expand Up @@ -256,6 +261,50 @@
}


def fetch_user_notifications_v1(
orguser: OrgUser, page: int, limit: int, read_status: int = None
) -> Tuple[Optional[None], Dict[str, Any]]:
"""returns all notifications for a specific user"""

notifications = (

Check warning on line 269 in ddpui/core/notifications_service.py

View check run for this annotation

Codecov / codecov/patch

ddpui/core/notifications_service.py#L269

Added line #L269 was not covered by tests
NotificationRecipient.objects.filter(
recipient=orguser,
notification__sent_time__isnull=False,
**({"read_status": read_status == 1} if read_status is not None else {}),
)
.select_related("notification")
.order_by("-notification__timestamp")
)

paginator = Paginator(notifications, limit)
paginated_notifications = paginator.get_page(page)

Check warning on line 280 in ddpui/core/notifications_service.py

View check run for this annotation

Codecov / codecov/patch

ddpui/core/notifications_service.py#L279-L280

Added lines #L279 - L280 were not covered by tests

user_notifications = []

Check warning on line 282 in ddpui/core/notifications_service.py

View check run for this annotation

Codecov / codecov/patch

ddpui/core/notifications_service.py#L282

Added line #L282 was not covered by tests

for recipient in paginated_notifications:
notification = recipient.notification
user_notifications.append(

Check warning on line 286 in ddpui/core/notifications_service.py

View check run for this annotation

Codecov / codecov/patch

ddpui/core/notifications_service.py#L284-L286

Added lines #L284 - L286 were not covered by tests
{
"id": notification.id,
"author": notification.author,
"message": notification.message,
"timestamp": notification.timestamp,
"urgent": notification.urgent,
"scheduled_time": notification.scheduled_time,
"sent_time": notification.sent_time,
"read_status": recipient.read_status,
}
)

return None, {

Check warning on line 299 in ddpui/core/notifications_service.py

View check run for this annotation

Codecov / codecov/patch

ddpui/core/notifications_service.py#L299

Added line #L299 was not covered by tests
"success": True,
"res": user_notifications,
"page": paginated_notifications.number,
"total_pages": paginated_notifications.paginator.num_pages,
"total_notifications": paginated_notifications.paginator.count,
}


# mark notificaiton as read
def mark_notification_as_read_or_unread(
orguser_id: int, notification_id: int, read_status: bool
Expand All @@ -272,6 +321,20 @@
return "Notification not found for the given user", None


def mark_notifications_as_read_or_unread(
orguser_id: int, notification_ids: int, read_status: bool
) -> Tuple[Optional[str], Optional[Dict[str, Any]]]:
"""bulk update of the read status of a recipient for notifications"""
try:
NotificationRecipient.objects.filter(

Check warning on line 329 in ddpui/core/notifications_service.py

View check run for this annotation

Codecov / codecov/patch

ddpui/core/notifications_service.py#L328-L329

Added lines #L328 - L329 were not covered by tests
recipient__id=orguser_id,
notification__id__in=notification_ids,
).update(read_status=read_status)
return None, {"success": True, "message": "Notifications updated successfully"}
except NotificationRecipient.DoesNotExist:
return "Something went wrong updating the notifications", None

Check warning on line 335 in ddpui/core/notifications_service.py

View check run for this annotation

Codecov / codecov/patch

ddpui/core/notifications_service.py#L333-L335

Added lines #L333 - L335 were not covered by tests


# delete notification
def delete_scheduled_notification(
notification_id: int,
Expand Down
7 changes: 7 additions & 0 deletions ddpui/schemas/notifications_api_schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,10 @@ class UpdateReadStatusSchema(Schema):

notification_id: int
read_status: bool


class UpdateReadStatusSchemav1(Schema):
"""Schema for updating the read status of a notification."""

notification_ids: list[int]
read_status: bool
13 changes: 6 additions & 7 deletions ddpui/tests/api_tests/test_notifications_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
get_user_notifications,
delete_notification,
mark_as_read,
get_unread_notifications_count
get_unread_notifications_count,
)
from ddpui.schemas.notifications_api_schemas import (
CreateNotificationPayloadSchema,
Expand Down Expand Up @@ -253,7 +253,7 @@ def test_get_notification_history_success():
assert response["success"] is True
assert isinstance(response["res"], list)
assert all(isinstance(notification, dict) for notification in response["res"])
mock_get_notification_history.assert_called_once_with(1, 10)
mock_get_notification_history.assert_called_once_with(1, 10, read_status=None)


def test_get_notification_recipients_success():
Expand All @@ -277,7 +277,7 @@ def test_get_user_notifications_success(orguser):
request = MagicMock()
request.orguser = orguser
with patch(
"ddpui.core.notifications_service.get_user_notifications"
"ddpui.core.notifications_service.fetch_user_notifications"
) as mock_get_user_notifications:
mock_get_user_notifications.return_value = (None, {"success": True, "res": []})
response = get_user_notifications(request, 1, 10)
Expand Down Expand Up @@ -383,6 +383,7 @@ def test_delete_already_sent_notification():
)
mock_delete_notification.assert_called_once_with(1)


def test_get_unread_notifications_count_success(orguser):
"""tests the success of api endpoint for fetching unread notification count"""
request = MagicMock()
Expand All @@ -399,7 +400,5 @@ def test_get_unread_notifications_count_success(orguser):
)
response = get_unread_notifications_count(request)
assert response["success"] is True
assert (
response["res"] == 0
)
mock_get_unread_notifications_count.assert_called_once_with(orguser)
assert response["res"] == 0
mock_get_unread_notifications_count.assert_called_once_with(orguser)
8 changes: 4 additions & 4 deletions ddpui/tests/core/test_notifications_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@
create_notification,
get_notification_history,
get_notification_recipients,
get_user_notifications,
fetch_user_notifications,
mark_notification_as_read_or_unread,
delete_scheduled_notification,
get_unread_notifications_count
get_unread_notifications_count,
)
from ddpui.schemas.notifications_api_schemas import SentToEnum
from ddpui.tests.api_tests.test_user_org_api import mock_request, seed_db
Expand Down Expand Up @@ -248,7 +248,7 @@ def test_get_notification_recipients_not_exist():


def test_get_user_notifications(orguser):
error, result = get_user_notifications(orguser, 1, 10)
error, result = fetch_user_notifications(orguser, 1, 10)
assert error is None
assert result["success"] is True
assert len(result["res"]) >= 0
Expand Down Expand Up @@ -290,4 +290,4 @@ def test_count_unread_notifications_success(orguser):
error, result = get_unread_notifications_count(orguser)
assert error is None
assert result["success"] is True
assert result["res"] >= 0
assert result["res"] >= 0
Loading