feat: display moderation requests to moderators

This commit is contained in:
imperosol
2024-10-14 00:45:31 +02:00
parent 5348a451e9
commit 19cd51043a
10 changed files with 362 additions and 187 deletions

View File

@ -3,35 +3,45 @@ from django.db import transaction
from django.test import TestCase
from django.urls import reverse
from model_bakery import baker
from model_bakery.recipe import Recipe
from pytest_django.asserts import assertNumQueries
from core.baker_recipes import old_subscriber_user, subscriber_user
from core.models import RealGroup, User
from core.models import RealGroup, SithFile, User
from sas.baker_recipes import picture_recipe
from sas.models import Album, PeoplePictureRelation, Picture
from sas.models import Album, PeoplePictureRelation, Picture, PictureModerationRequest
class TestSas(TestCase):
@classmethod
def setUpTestData(cls):
Picture.objects.all().delete()
sas = SithFile.objects.get(pk=settings.SITH_SAS_ROOT_DIR_ID)
Picture.objects.exclude(id=sas.id).delete()
owner = User.objects.get(username="root")
cls.user_a = old_subscriber_user.make()
cls.user_b, cls.user_c = subscriber_user.make(_quantity=2)
picture = picture_recipe.extend(owner=owner)
cls.album_a = baker.make(Album, is_in_sas=True)
cls.album_b = baker.make(Album, is_in_sas=True)
cls.album_a = baker.make(Album, is_in_sas=True, parent=sas)
cls.album_b = baker.make(Album, is_in_sas=True, parent=sas)
relation_recipe = Recipe(PeoplePictureRelation)
relations = []
for album in cls.album_a, cls.album_b:
pictures = picture.make(parent=album, _quantity=5, _bulk_create=True)
baker.make(PeoplePictureRelation, picture=pictures[1], user=cls.user_a)
baker.make(PeoplePictureRelation, picture=pictures[2], user=cls.user_a)
baker.make(PeoplePictureRelation, picture=pictures[2], user=cls.user_b)
baker.make(PeoplePictureRelation, picture=pictures[3], user=cls.user_b)
baker.make(PeoplePictureRelation, picture=pictures[4], user=cls.user_a)
baker.make(PeoplePictureRelation, picture=pictures[4], user=cls.user_b)
baker.make(PeoplePictureRelation, picture=pictures[4], user=cls.user_c)
relations.extend(
[
relation_recipe.prepare(picture=pictures[1], user=cls.user_a),
relation_recipe.prepare(picture=pictures[2], user=cls.user_a),
relation_recipe.prepare(picture=pictures[2], user=cls.user_b),
relation_recipe.prepare(picture=pictures[3], user=cls.user_b),
relation_recipe.prepare(picture=pictures[4], user=cls.user_a),
relation_recipe.prepare(picture=pictures[4], user=cls.user_b),
relation_recipe.prepare(picture=pictures[4], user=cls.user_c),
]
)
PeoplePictureRelation.objects.bulk_create(relations)
class TestPictureSearch(TestSas):
@ -170,3 +180,49 @@ class TestPictureRelation(TestSas):
res = self.client.delete(f"/api/sas/relation/{relation.id}")
assert res.status_code == 404
assert PeoplePictureRelation.objects.count() == relation_count
class TestPictureModeration(TestSas):
@classmethod
def setUpTestData(cls):
super().setUpTestData()
cls.sas_admin = baker.make(
User, groups=[RealGroup.objects.get(pk=settings.SITH_GROUP_SAS_ADMIN_ID)]
)
cls.picture = Picture.objects.filter(parent=cls.album_a)[0]
cls.picture.is_moderated = False
cls.picture.asked_for_removal = True
cls.picture.save()
cls.url = reverse("api:picture_moderate", kwargs={"picture_id": cls.picture.id})
baker.make(PictureModerationRequest, picture=cls.picture, author=cls.user_a)
def test_moderation_route_forbidden(self):
"""Test that basic users (even if owner) cannot moderate a picture."""
self.picture.owner = self.user_b
for user in baker.make(User), subscriber_user.make(), self.user_b:
self.client.force_login(user)
res = self.client.patch(self.url)
assert res.status_code == 403
def test_moderation_route_authorized(self):
"""Test that sas admins can moderate a picture."""
self.client.force_login(self.sas_admin)
res = self.client.patch(self.url)
assert res.status_code == 200
self.picture.refresh_from_db()
assert self.picture.is_moderated
assert not self.picture.asked_for_removal
assert not self.picture.moderation_requests.exists()
def test_get_moderation_requests(self):
"""Test that fetching moderation requests work."""
url = reverse(
"api:picture_moderation_requests", kwargs={"picture_id": self.picture.id}
)
self.client.force_login(self.sas_admin)
res = self.client.get(url)
assert res.status_code == 200
assert len(res.json()) == 1
assert res.json()[0]["author"]["id"] == self.user_a.id

View File

@ -20,7 +20,7 @@ from django.core.cache import cache
from django.test import Client, TestCase
from django.urls import reverse
from model_bakery import baker
from pytest_django.asserts import assertRedirects
from pytest_django.asserts import assertInHTML, assertRedirects
from core.baker_recipes import old_subscriber_user, subscriber_user
from core.models import RealGroup, User
@ -70,7 +70,9 @@ def test_album_access_non_subscriber(client: Client):
class TestSasModeration(TestCase):
@classmethod
def setUpTestData(cls):
album = baker.make(Album, parent_id=settings.SITH_SAS_ROOT_DIR_ID)
album = baker.make(
Album, parent_id=settings.SITH_SAS_ROOT_DIR_ID, is_moderated=True
)
cls.pictures = picture_recipe.make(
parent=album, _quantity=10, _bulk_create=True
)
@ -82,6 +84,9 @@ class TestSasModeration(TestCase):
)
cls.simple_user = subscriber_user.make()
def setUp(self):
cache.clear()
def test_moderation_page_sas_admin(self):
"""Test that a moderator can see the pictures needing moderation."""
self.client.force_login(self.moderator)
@ -132,3 +137,37 @@ class TestSasModeration(TestCase):
)
assert res.status_code == 403
assert Picture.objects.filter(pk=self.to_moderate.id).exists()
def test_request_moderation_form_access(self):
"""Test that regular can access the form to ask for moderation."""
self.client.force_login(self.simple_user)
res = self.client.get(
reverse(
"sas:picture_ask_removal", kwargs={"picture_id": self.pictures[1].id}
),
)
assert res.status_code == 200
def test_request_moderation_form_submit(self):
"""Test that moderation requests are created."""
self.client.force_login(self.simple_user)
message = "J'aime pas cette photo (ni la Cocarde)."
url = reverse(
"sas:picture_ask_removal", kwargs={"picture_id": self.pictures[1].id}
)
res = self.client.post(url, data={"reason": message})
assertRedirects(
res, reverse("sas:album", kwargs={"album_id": self.pictures[1].parent_id})
)
assert self.pictures[1].moderation_requests.count() == 1
assert self.pictures[1].moderation_requests.first().reason == message
# test that the user cannot ask for moderation twice
res = self.client.post(url, data={"reason": message})
assert res.status_code == 200
assert self.pictures[1].moderation_requests.count() == 1
assertInHTML(
'<ul class="errorlist nonfield"><li>'
"Vous avez déjà déposé une demande de retrait pour cette photo.</li></ul>",
res.content.decode(),
)