mirror of
https://github.com/Hopiu/django-notifications.git
synced 2026-05-05 12:04:43 +00:00
Improve tests
This commit is contained in:
parent
ca635508e6
commit
21a0b95da8
5 changed files with 86 additions and 233 deletions
13
notifications/tests/test_admin.py
Normal file
13
notifications/tests/test_admin.py
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
from django.urls import reverse
|
||||
|
||||
from notifications.tests.factories.notifications import NotificationFullFactory
|
||||
|
||||
|
||||
def test_admin(admin_user, client):
|
||||
app_name = "notifications"
|
||||
NotificationFullFactory.create_batch(10)
|
||||
|
||||
client.force_login(admin_user)
|
||||
|
||||
response = client.get(reverse(f"admin:{app_name}_notification_changelist"))
|
||||
assert response.status_code == 200
|
||||
|
|
@ -111,9 +111,32 @@ def test_build_url():
|
|||
),
|
||||
)
|
||||
@pytest.mark.django_db
|
||||
def test_natural_day(increase, expected_result):
|
||||
def test_naturalday(increase, expected_result):
|
||||
initial_date = datetime(2023, 1, 1, 0, 0, 0)
|
||||
with freeze_time(initial_date):
|
||||
notification = NotificationShortFactory()
|
||||
with freeze_time(initial_date + timedelta(**increase)):
|
||||
assert notification.naturalday() == expected_result
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"increase,expected_result",
|
||||
(
|
||||
({"minutes": 10}, "10\xa0minutes ago"),
|
||||
({"days": 1}, "1\xa0day ago"),
|
||||
),
|
||||
)
|
||||
@pytest.mark.django_db
|
||||
def test_naturaltime(increase, expected_result):
|
||||
initial_date = datetime(2023, 1, 1, 0, 0, 0)
|
||||
with freeze_time(initial_date):
|
||||
notification = NotificationShortFactory()
|
||||
with freeze_time(initial_date + timedelta(**increase)):
|
||||
assert notification.naturaltime() == expected_result
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_extra_data():
|
||||
data = {"url": "/learn/ask-a-pro/q/test-question-9/299/", "other_content": "Hello my 'world'"}
|
||||
notification = NotificationFullFactory(data=data)
|
||||
assert notification.data == data
|
||||
|
|
|
|||
|
|
@ -1,45 +1,51 @@
|
|||
from unittest.mock import Mock, patch
|
||||
|
||||
import pytest
|
||||
from django.core.cache import cache
|
||||
from django.template import Context, Template
|
||||
from django.urls import reverse_lazy
|
||||
from freezegun import freeze_time
|
||||
from swapper import load_model
|
||||
|
||||
from notifications.templatetags.notifications_tags import (
|
||||
has_notification,
|
||||
live_notify_badge,
|
||||
live_notify_list,
|
||||
notifications_unread,
|
||||
register_notify_callbacks,
|
||||
user_context,
|
||||
)
|
||||
from notifications.templatetags.notifications_tags import user_context
|
||||
from notifications.tests.factories.notifications import NotificationFullFactory
|
||||
from notifications.tests.factories.users import RecipientFactory
|
||||
|
||||
Notification = load_model("notifications", "Notification")
|
||||
|
||||
|
||||
def render_tag(template, context):
|
||||
template = Template("{% load notifications_tags %}" + template)
|
||||
return template.render(Context(context))
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_notifications_unread():
|
||||
with patch("notifications.templatetags.notifications_tags.user_context") as user_context_mock:
|
||||
user_context_mock.return_value = None
|
||||
assert notifications_unread({}) == ""
|
||||
assert render_tag("{% notifications_unread %}", {}) == ""
|
||||
|
||||
notification = NotificationFullFactory()
|
||||
user_context_mock.return_value = notification.recipient
|
||||
assert notifications_unread({}) == 1
|
||||
assert (
|
||||
render_tag("{% notifications_unread %}", {"user": Mock(), "request": Mock(user=Mock(is_anonymous=True))}) == ""
|
||||
)
|
||||
|
||||
notification = NotificationFullFactory()
|
||||
assert (
|
||||
render_tag(
|
||||
"{% notifications_unread %}", {"user": notification.recipient, "request": Mock(user=notification.recipient)}
|
||||
)
|
||||
== "1"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_has_notification():
|
||||
user = RecipientFactory()
|
||||
assert has_notification(user) is False
|
||||
assert render_tag("{{ user|has_notification }}", {"user": user}) == "False"
|
||||
|
||||
notification = NotificationFullFactory(recipient=user)
|
||||
assert has_notification(user) is True
|
||||
assert render_tag("{{ user|has_notification }}", {"user": user}) == "True"
|
||||
|
||||
notification.mark_as_read()
|
||||
assert has_notification(user) is False
|
||||
assert render_tag("{{ user|has_notification }}", {"user": user}) == "False"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
|
|
@ -50,56 +56,53 @@ def test_has_notification():
|
|||
),
|
||||
)
|
||||
def test_register_notify_callbacks(_type, url):
|
||||
callback = register_notify_callbacks(
|
||||
badge_class="badge1",
|
||||
menu_class="menu2",
|
||||
refresh_period=10,
|
||||
callbacks="cb1,cb2",
|
||||
api_name=_type,
|
||||
fetch=50,
|
||||
nonce="123",
|
||||
mark_as_read=True,
|
||||
)
|
||||
tag = f"{{% register_notify_callbacks badge_class='badge1' menu_class='menu2' refresh_period=10 callbacks='cb1,cb2' api_name='{_type}' fetch=50 nonce='123' mark_as_read=True %}}" # pylint: disable=line-too-long
|
||||
|
||||
assert "notify_badge_class='badge1'" in callback
|
||||
assert "notify_menu_class='menu2'" in callback
|
||||
assert "notify_refresh_period=10" in callback
|
||||
assert "register_notifier(cb1);" in callback
|
||||
assert "register_notifier(cb2);" in callback
|
||||
assert "notify_fetch_count='50'" in callback
|
||||
assert 'nonce="123"' in callback
|
||||
assert "true" in callback
|
||||
assert str(url) in callback
|
||||
render = render_tag(tag, {})
|
||||
|
||||
assert "notify_badge_class='badge1'" in render
|
||||
assert "notify_menu_class='menu2'" in render
|
||||
assert "notify_refresh_period=10" in render
|
||||
assert "register_notifier(cb1);" in render
|
||||
assert "register_notifier(cb2);" in render
|
||||
assert "notify_fetch_count='50'" in render
|
||||
assert 'nonce="123"' in render
|
||||
assert "true" in render
|
||||
assert str(url) in render
|
||||
|
||||
|
||||
@patch("notifications.templatetags.notifications_tags.user_context")
|
||||
@patch("notifications.templatetags.notifications_tags.get_cached_notification_unread_count")
|
||||
@pytest.mark.django_db
|
||||
def test_live_notify_badge(cache_mock, user_context_mock):
|
||||
def test_live_notify_badge(user_context_mock):
|
||||
user = RecipientFactory()
|
||||
|
||||
# No user
|
||||
user_context_mock.return_value = None
|
||||
assert live_notify_badge({}) == ""
|
||||
assert render_tag("{% live_notify_badge %}", {}) == ""
|
||||
|
||||
# User without notifications
|
||||
user_context_mock.return_value = user
|
||||
badge = live_notify_badge({}, badge_class="blafoo")
|
||||
badge = render_tag("{% live_notify_badge badge_class='blafoo' %}", {})
|
||||
assert "blafoo" in badge
|
||||
assert "0" in badge
|
||||
|
||||
# Cached with 0 notifications
|
||||
with freeze_time("2024-01-01 00:00:00"):
|
||||
NotificationFullFactory(recipient=user)
|
||||
badge = live_notify_badge({}, badge_class="blafoo")
|
||||
badge = render_tag("{% live_notify_badge badge_class='blafoo' %}", {})
|
||||
assert "blafoo" in badge
|
||||
assert "0" in badge # Because of cache
|
||||
assert "0" in badge
|
||||
|
||||
cache_mock.side_effect = lambda user: user.notifications.unread().count()
|
||||
badge = live_notify_badge({}, badge_class="blafoo")
|
||||
# No cache with notification
|
||||
with freeze_time("2024-01-02 00:00:00"):
|
||||
cache.clear()
|
||||
badge = render_tag("{% live_notify_badge badge_class='blafoo' %}", {})
|
||||
assert "blafoo" in badge
|
||||
assert "1" in badge
|
||||
|
||||
|
||||
def test_live_notify_list():
|
||||
resp = live_notify_list("blafoo")
|
||||
resp = render_tag("{% live_notify_list list_class='blafoo' %}", {})
|
||||
assert "<ul" in resp
|
||||
assert "class='blafoo'" in resp
|
||||
|
||||
|
|
|
|||
|
|
@ -8,19 +8,14 @@ import json
|
|||
from datetime import datetime, timezone
|
||||
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.contrib.auth.models import Group
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.db import connection
|
||||
from django.shortcuts import render
|
||||
from django.template import Context, Template
|
||||
from django.test import override_settings # noqa
|
||||
from django.test import RequestFactory, TestCase
|
||||
from django.test.utils import CaptureQueriesContext
|
||||
from django.urls import reverse
|
||||
from django.utils.timezone import localtime
|
||||
from swapper import load_model
|
||||
|
||||
from notifications.signals import notify, notify_handler
|
||||
from notifications.signals import notify
|
||||
|
||||
Notification = load_model("notifications", "Notification")
|
||||
User = get_user_model()
|
||||
|
|
@ -60,127 +55,6 @@ class NotificationTest(TestCase):
|
|||
delta = datetime.now() - notification.timestamp
|
||||
self.assertTrue(delta.seconds < 60)
|
||||
|
||||
def test_humanize_naturalday_timestamp(self):
|
||||
from_user = User.objects.create(username="from2", password="pwd", email="example@example.com")
|
||||
to_user = User.objects.create(username="to2", password="pwd", email="example@example.com")
|
||||
notify.send(from_user, recipient=to_user, verb="commented", action_object=from_user)
|
||||
notification = Notification.objects.get(recipient=to_user)
|
||||
self.assertEqual(notification.naturalday(), "today")
|
||||
|
||||
def test_humanize_naturaltime_timestamp(self):
|
||||
from_user = User.objects.create(username="from2", password="pwd", email="example@example.com")
|
||||
to_user = User.objects.create(username="to2", password="pwd", email="example@example.com")
|
||||
notify.send(from_user, recipient=to_user, verb="commented", action_object=from_user)
|
||||
notification = Notification.objects.get(recipient=to_user)
|
||||
self.assertEqual(notification.naturaltime(), "now")
|
||||
|
||||
|
||||
class NotificationManagersTest(TestCase):
|
||||
"""Django notifications Manager automated tests"""
|
||||
|
||||
def setUp(self):
|
||||
self.message_count = 10
|
||||
self.other_user = User.objects.create(username="other1", password="pwd", email="example@example.com")
|
||||
|
||||
self.from_user = User.objects.create(username="from2", password="pwd", email="example@example.com")
|
||||
self.to_user = User.objects.create(username="to2", password="pwd", email="example@example.com")
|
||||
self.to_group = Group.objects.create(name="to2_g")
|
||||
self.to_user_list = User.objects.all()
|
||||
self.to_group.user_set.add(self.to_user)
|
||||
self.to_group.user_set.add(self.other_user)
|
||||
|
||||
for _ in range(self.message_count):
|
||||
notify.send(self.from_user, recipient=self.to_user, verb="commented", action_object=self.from_user)
|
||||
# Send notification to group
|
||||
notify.send(self.from_user, recipient=self.to_group, verb="commented", action_object=self.from_user)
|
||||
self.message_count += self.to_group.user_set.count()
|
||||
# Send notification to user list
|
||||
notify.send(self.from_user, recipient=self.to_user_list, verb="commented", action_object=self.from_user)
|
||||
self.message_count += len(self.to_user_list)
|
||||
|
||||
def test_notify_send_return_val(self):
|
||||
results = notify.send(self.from_user, recipient=self.to_user, verb="commented", action_object=self.from_user)
|
||||
for result in results:
|
||||
if result[0] is notify_handler:
|
||||
self.assertEqual(len(result[1]), 1)
|
||||
# only check types for now
|
||||
self.assertEqual(type(result[1][0]), Notification)
|
||||
|
||||
def test_notify_send_return_val_group(self):
|
||||
results = notify.send(self.from_user, recipient=self.to_group, verb="commented", action_object=self.from_user)
|
||||
for result in results:
|
||||
if result[0] is notify_handler:
|
||||
self.assertEqual(len(result[1]), self.to_group.user_set.count())
|
||||
for notification in result[1]:
|
||||
# only check types for now
|
||||
self.assertEqual(type(notification), Notification)
|
||||
|
||||
def test_unread_manager(self):
|
||||
self.assertEqual(Notification.objects.unread().count(), self.message_count)
|
||||
notification = Notification.objects.filter(recipient=self.to_user).first()
|
||||
notification.mark_as_read()
|
||||
self.assertEqual(Notification.objects.unread().count(), self.message_count - 1)
|
||||
for notification in Notification.objects.unread():
|
||||
self.assertTrue(notification.unread)
|
||||
|
||||
def test_read_manager(self):
|
||||
self.assertEqual(Notification.objects.unread().count(), self.message_count)
|
||||
notification = Notification.objects.filter(recipient=self.to_user).first()
|
||||
notification.mark_as_read()
|
||||
self.assertEqual(Notification.objects.read().count(), 1)
|
||||
for notification in Notification.objects.read():
|
||||
self.assertFalse(notification.unread)
|
||||
|
||||
def test_mark_all_as_read_manager(self):
|
||||
self.assertEqual(Notification.objects.unread().count(), self.message_count)
|
||||
Notification.objects.filter(recipient=self.to_user).mark_all_as_read()
|
||||
self.assertEqual(self.to_user.notifications.unread().count(), 0)
|
||||
|
||||
@override_settings(DJANGO_NOTIFICATIONS_CONFIG={"SOFT_DELETE": True})
|
||||
def test_mark_all_as_read_manager_with_soft_delete(self):
|
||||
# even soft-deleted notifications should be marked as read
|
||||
# refer: https://github.com/django-notifications/django-notifications/issues/126
|
||||
to_delete = Notification.objects.filter(recipient=self.to_user).order_by("id")[0]
|
||||
to_delete.deleted = True
|
||||
to_delete.save()
|
||||
self.assertTrue(Notification.objects.filter(recipient=self.to_user).order_by("id")[0].unread)
|
||||
Notification.objects.filter(recipient=self.to_user).mark_all_as_read()
|
||||
self.assertFalse(Notification.objects.filter(recipient=self.to_user).order_by("id")[0].unread)
|
||||
|
||||
def test_mark_all_as_unread_manager(self):
|
||||
self.assertEqual(Notification.objects.unread().count(), self.message_count)
|
||||
Notification.objects.filter(recipient=self.to_user).mark_all_as_read()
|
||||
self.assertEqual(self.to_user.notifications.unread().count(), 0)
|
||||
Notification.objects.filter(recipient=self.to_user).mark_all_as_unread()
|
||||
self.assertEqual(Notification.objects.unread().count(), self.message_count)
|
||||
|
||||
def test_mark_all_deleted_manager_without_soft_delete(self):
|
||||
self.assertRaises(ImproperlyConfigured, Notification.objects.active)
|
||||
self.assertRaises(ImproperlyConfigured, Notification.objects.active)
|
||||
self.assertRaises(ImproperlyConfigured, Notification.objects.mark_all_as_deleted)
|
||||
self.assertRaises(ImproperlyConfigured, Notification.objects.mark_all_as_active)
|
||||
|
||||
@override_settings(DJANGO_NOTIFICATIONS_CONFIG={"SOFT_DELETE": True})
|
||||
def test_mark_all_deleted_manager(self):
|
||||
notification = Notification.objects.filter(recipient=self.to_user).first()
|
||||
notification.mark_as_read()
|
||||
self.assertEqual(Notification.objects.read().count(), 1)
|
||||
self.assertEqual(Notification.objects.unread().count(), self.message_count - 1)
|
||||
self.assertEqual(Notification.objects.active().count(), self.message_count)
|
||||
self.assertEqual(Notification.objects.deleted().count(), 0)
|
||||
|
||||
Notification.objects.mark_all_as_deleted()
|
||||
self.assertEqual(Notification.objects.read().count(), 0)
|
||||
self.assertEqual(Notification.objects.unread().count(), 0)
|
||||
self.assertEqual(Notification.objects.active().count(), 0)
|
||||
self.assertEqual(Notification.objects.deleted().count(), self.message_count)
|
||||
|
||||
Notification.objects.mark_all_as_active()
|
||||
self.assertEqual(Notification.objects.read().count(), 1)
|
||||
self.assertEqual(Notification.objects.unread().count(), self.message_count - 1)
|
||||
self.assertEqual(Notification.objects.active().count(), self.message_count)
|
||||
self.assertEqual(Notification.objects.deleted().count(), 0)
|
||||
|
||||
|
||||
class NotificationTestPages(TestCase):
|
||||
"""Django notifications automated page tests"""
|
||||
|
|
@ -512,62 +386,3 @@ class NotificationTestExtraData(TestCase):
|
|||
data = json.loads(response.content.decode("utf-8"))
|
||||
self.assertEqual(data["unread_list"][0]["data"]["url"], "/learn/ask-a-pro/q/test-question-9/299/")
|
||||
self.assertEqual(data["unread_list"][0]["data"]["other_content"], "Hello my 'world'")
|
||||
|
||||
|
||||
class TagTest(TestCase):
|
||||
"""Django notifications automated tags tests"""
|
||||
|
||||
def setUp(self):
|
||||
self.message_count = 1
|
||||
self.from_user = User.objects.create_user(username="from", password="pwd", email="example@example.com")
|
||||
self.to_user = User.objects.create_user(username="to", password="pwd", email="example@example.com")
|
||||
self.to_user.is_staff = True
|
||||
self.to_user.save()
|
||||
for _ in range(self.message_count):
|
||||
notify.send(
|
||||
self.from_user,
|
||||
recipient=self.to_user,
|
||||
verb="commented",
|
||||
action_object=self.from_user,
|
||||
url="/learn/ask-a-pro/q/test-question-9/299/",
|
||||
other_content="Hello my 'world'",
|
||||
)
|
||||
|
||||
def tag_test(self, template, context, output):
|
||||
template = Template("{% load notifications_tags %}" + template)
|
||||
context = Context(context)
|
||||
self.assertEqual(template.render(context), output)
|
||||
|
||||
def test_has_notification(self):
|
||||
template = "{{ user|has_notification }}"
|
||||
context = {"user": self.to_user}
|
||||
output = "True"
|
||||
self.tag_test(template, context, output)
|
||||
|
||||
|
||||
class AdminTest(TestCase):
|
||||
app_name = "notifications"
|
||||
|
||||
def setUp(self):
|
||||
self.message_count = 10
|
||||
self.from_user = User.objects.create_user(username="from", password="pwd", email="example@example.com")
|
||||
self.to_user = User.objects.create_user(username="to", password="pwd", email="example@example.com")
|
||||
self.to_user.is_staff = True
|
||||
self.to_user.is_superuser = True
|
||||
self.to_user.save()
|
||||
for _ in range(self.message_count):
|
||||
notify.send(
|
||||
self.from_user,
|
||||
recipient=self.to_user,
|
||||
verb="commented",
|
||||
action_object=self.from_user,
|
||||
)
|
||||
|
||||
def test_list(self):
|
||||
self.client.login(username="to", password="pwd")
|
||||
|
||||
with CaptureQueriesContext(connection=connection) as context:
|
||||
response = self.client.get(reverse(f"admin:{self.app_name}_notification_changelist"))
|
||||
self.assertLessEqual(len(context), 6)
|
||||
|
||||
self.assertEqual(response.status_code, 200, response.content)
|
||||
|
|
|
|||
|
|
@ -214,7 +214,6 @@ testpaths = [
|
|||
]
|
||||
DJANGO_SETTINGS_MODULE = "notifications.tests.settings_for_tests"
|
||||
django_debug_mode = "keep"
|
||||
show_locals=true
|
||||
|
||||
[tool.coverage.run]
|
||||
relative_files = true
|
||||
|
|
|
|||
Loading…
Reference in a new issue