Improve coverage

This commit is contained in:
Alvaro Leonel 2024-05-03 12:08:49 -03:00
parent 836a4c01de
commit c4cf1c5e17
5 changed files with 114 additions and 4 deletions

View file

@ -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()

View file

@ -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:

View file

@ -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

View 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

View file

@ -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"