mirror of
https://github.com/Hopiu/django-notifications.git
synced 2026-05-01 18:34:43 +00:00
Improve coverage
This commit is contained in:
parent
836a4c01de
commit
c4cf1c5e17
5 changed files with 114 additions and 4 deletions
|
|
@ -29,8 +29,8 @@ class NotificationAdmin(admin.ModelAdmin):
|
|||
|
||||
@admin.action(description=gettext_lazy("Mark selected notifications as unread"))
|
||||
def mark_unread(self, request: HttpRequest, queryset: NotificationQuerySet): # pylint: disable=unused-argument
|
||||
queryset.update(unread=True)
|
||||
queryset.mark_as_unread()
|
||||
|
||||
@admin.action(description=gettext_lazy("Mark selected notifications as read"))
|
||||
def mark_read(self, request: HttpRequest, queryset: NotificationQuerySet): # pylint: disable=unused-argument
|
||||
queryset.update(unread=False)
|
||||
queryset.mark_as_read()
|
||||
|
|
|
|||
|
|
@ -189,10 +189,10 @@ class AbstractNotification(models.Model):
|
|||
def actor_object_url(self) -> str:
|
||||
return self._build_url("actor")
|
||||
|
||||
def action_object_url(self) -> Union[str, None]:
|
||||
def action_object_url(self) -> Union[str, int]:
|
||||
return self._build_url("action_object")
|
||||
|
||||
def target_object_url(self) -> Union[str, None]:
|
||||
def target_object_url(self) -> Union[str, int]:
|
||||
return self._build_url("target")
|
||||
|
||||
def timesince(self, now: Union[None, datetime.datetime] = None) -> str:
|
||||
|
|
|
|||
|
|
@ -112,3 +112,57 @@ def test_mark_all_active_deleted(method, initial_status):
|
|||
assert func() == 2
|
||||
|
||||
assert Notification.objects.filter(deleted=not initial_status).count() == 4
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"method,field,initial_status,final_status",
|
||||
(
|
||||
("mark_as_sent", "emailed", False, True),
|
||||
("mark_as_sent", "emailed", True, True),
|
||||
("mark_as_unsent", "emailed", True, False),
|
||||
("mark_as_unsent", "emailed", False, False),
|
||||
("mark_as_public", "public", True, True),
|
||||
("mark_as_public", "public", False, True),
|
||||
("mark_as_private", "public", False, False),
|
||||
("mark_as_private", "public", True, False),
|
||||
("mark_as_read", "unread", False, False),
|
||||
("mark_as_read", "unread", True, False),
|
||||
("mark_as_unread", "unread", False, True),
|
||||
("mark_as_unread", "unread", True, True),
|
||||
),
|
||||
)
|
||||
@pytest.mark.django_db
|
||||
def test_mark_as(method, field, initial_status, final_status):
|
||||
recipient = RecipientFactory()
|
||||
NotificationFullFactory.create_batch(2, **{field: initial_status})
|
||||
NotificationFullFactory.create_batch(2, recipient=recipient, **{field: initial_status})
|
||||
func = getattr(Notification.objects, method)
|
||||
|
||||
assert func(recipient=recipient) == 2
|
||||
assert func() == 4
|
||||
|
||||
assert Notification.objects.filter(**{field: final_status}).count() == 4
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"method,initial_status",
|
||||
(
|
||||
("mark_as_active", True),
|
||||
("mark_as_deleted", False),
|
||||
),
|
||||
)
|
||||
@pytest.mark.django_db
|
||||
def test_mark_as_active_deleted(method, initial_status):
|
||||
recipient = RecipientFactory()
|
||||
NotificationFullFactory.create_batch(2, recipient=recipient, deleted=initial_status)
|
||||
NotificationFullFactory.create_batch(2, deleted=initial_status)
|
||||
|
||||
func = getattr(Notification.objects, method)
|
||||
with pytest.raises(ImproperlyConfigured):
|
||||
func()
|
||||
|
||||
with override_settings(DJANGO_NOTIFICATIONS_CONFIG={"SOFT_DELETE": True}):
|
||||
assert func(recipient=recipient) == 2
|
||||
assert func() == 4
|
||||
|
||||
assert Notification.objects.filter(deleted=not initial_status).count() == 4
|
||||
|
|
|
|||
50
notifications/tests/test_views/test_mixins.py
Normal file
50
notifications/tests/test_views/test_mixins.py
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
import pytest
|
||||
from django.test import override_settings
|
||||
from django.urls import reverse
|
||||
|
||||
MALICIOUS_NEXT_URLS = (
|
||||
"http://bla.com",
|
||||
"http://www.bla.com",
|
||||
"https://bla.com",
|
||||
"https://www.bla.com",
|
||||
"ftp://www.bla.com/file.exe",
|
||||
)
|
||||
|
||||
|
||||
@override_settings(ALLOWED_HOSTS=["www.notifications_notification_related.com"])
|
||||
@pytest.mark.django_db
|
||||
def test_next_url(client, staff_user):
|
||||
client.force_login(staff_user)
|
||||
query_parameters = "?var1=hello&var2=world"
|
||||
|
||||
response = client.get(
|
||||
reverse("notifications:mark_all_as", args=("read",)),
|
||||
data={
|
||||
"next": reverse("notifications:list", args=("read",)) + query_parameters,
|
||||
},
|
||||
follow=True,
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert len(response.redirect_chain) == 1
|
||||
assert response.redirect_chain[0][0] == reverse("notifications:list", args=("read",)) + query_parameters
|
||||
assert response.redirect_chain[0][1] == 302
|
||||
|
||||
|
||||
@override_settings(ALLOWED_HOSTS=["www.notifications_notification_related.com"])
|
||||
@pytest.mark.django_db
|
||||
def test_malicious_next_pages(client, staff_user):
|
||||
client.force_login(staff_user)
|
||||
query_parameters = "?var1=hello&var2=world"
|
||||
|
||||
for next_url in MALICIOUS_NEXT_URLS:
|
||||
response = client.get(
|
||||
reverse("notifications:mark_all_as", args=("read",)),
|
||||
data={
|
||||
"next": next_url + query_parameters,
|
||||
},
|
||||
follow=True,
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert len(response.redirect_chain) == 1
|
||||
assert response.redirect_chain[0][0] == reverse("notifications:list", args=("unread",))
|
||||
assert response.redirect_chain[0][1] == 302
|
||||
|
|
@ -219,6 +219,12 @@ django_debug_mode = "keep"
|
|||
relative_files = true
|
||||
parallel = true
|
||||
branch = true
|
||||
omit = [
|
||||
"__init__.py",
|
||||
"manage.py",
|
||||
"settings.py",
|
||||
"notifications/tests/**/*",
|
||||
]
|
||||
|
||||
[tool.mypy]
|
||||
files = "**/*.py"
|
||||
|
|
|
|||
Loading…
Reference in a new issue