# # Copyright 2023 © AE UTBM # ae@utbm.fr / ae.info@utbm.fr # # This file is part of the website of the UTBM Student Association (AE UTBM), # https://ae.utbm.fr. # # You can find the source code of the website at https://github.com/ae-utbm/sith # # LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3) # SEE : https://raw.githubusercontent.com/ae-utbm/sith/master/LICENSE # OR WITHIN THE LOCAL FILE "LICENSE" # # from typing import Callable import pytest from bs4 import BeautifulSoup from django.conf import settings from django.core.cache import cache from django.test import Client, TestCase from django.urls import reverse from django.utils import timezone from model_bakery import baker from pytest_django.asserts import assertHTMLEqual, assertInHTML, assertRedirects from core.baker_recipes import old_subscriber_user, subscriber_user from core.models import Group, User from sas.baker_recipes import picture_recipe from sas.forms import AlbumEditForm from sas.models import Album, Picture # Create your tests here. @pytest.mark.django_db @pytest.mark.parametrize( "user_factory", [ subscriber_user.make, old_subscriber_user.make, lambda: baker.make(User, is_superuser=True), lambda: baker.make( User, groups=[Group.objects.get(pk=settings.SITH_GROUP_SAS_ADMIN_ID)] ), lambda: baker.make(User), lambda: None, ], ) def test_load_main_page(client: Client, user_factory: Callable[[], User]): """Just check that the SAS doesn't crash.""" user = user_factory() if user is not None: client.force_login(user) res = client.get(reverse("sas:main")) assert res.status_code == 200 @pytest.mark.django_db def test_main_page_no_form_for_regular_users(client: Client): """Test that subscribed users see no form on the sas main page""" client.force_login(subscriber_user.make()) res = client.get(reverse("sas:main")) soup = BeautifulSoup(res.text, "lxml") forms = soup.find("main").find_all("form") assert len(forms) == 0 @pytest.mark.django_db def test_main_page_content_anonymous(client: Client): """Test that public users see only an incentive to login""" res = client.get(reverse("sas:main")) soup = BeautifulSoup(res.text, "lxml") expected = "
Vous devez être connecté pour voir les photos.
" assertHTMLEqual(soup.find("main").decode_contents(), expected) @pytest.mark.django_db def test_album_access_non_subscriber(client: Client): """Test that non-subscribers can only access albums where they are identified.""" album = baker.make(Album, parent_id=settings.SITH_SAS_ROOT_DIR_ID) user = baker.make(User) client.force_login(user) res = client.get(reverse("sas:album", kwargs={"album_id": album.id})) assert res.status_code == 403 picture = picture_recipe.make(parent=album) picture.people.create(user=user) cache.clear() res = client.get(reverse("sas:album", kwargs={"album_id": album.id})) assert res.status_code == 200 @pytest.mark.django_db class TestAlbumUpload: @staticmethod def assert_album_created(response, name, parent): assert response.headers.get("HX-Redirect", "") == parent.get_absolute_url() children = list(Album.objects.filter(parent=parent)) assert len(children) == 1 assert children[0].name == name def test_sas_admin(self, client: Client): user = baker.make( User, groups=[Group.objects.get(id=settings.SITH_GROUP_SAS_ADMIN_ID)] ) album = baker.make(Album, parent_id=settings.SITH_SAS_ROOT_DIR_ID) client.force_login(user) response = client.post( reverse("sas:album_create"), {"name": "new", "parent": album.id} ) self.assert_album_created(response, "new", album) def test_non_admin_user_with_edit_rights_on_parent(self, client: Client): group = baker.make(Group) user = subscriber_user.make(groups=[group]) album = baker.make( Album, parent_id=settings.SITH_SAS_ROOT_DIR_ID, edit_groups=[group] ) client.force_login(user) response = client.post( reverse("sas:album_create"), {"name": "new", "parent": album.id} ) self.assert_album_created(response, "new", album) def test_permission_denied(self, client: Client): album = baker.make(Album, parent_id=settings.SITH_SAS_ROOT_DIR_ID) client.force_login(subscriber_user.make()) response = client.post( reverse("sas:album_create"), {"name": "new", "parent": album.id} ) errors = BeautifulSoup(response.text, "lxml").find_all(class_="errorlist") assert len(errors) == 1 assert errors[0].text == "Vous n'avez pas la permission de faire cela" assert not album.children.exists() @pytest.mark.django_db class TestAlbumEdit: @pytest.fixture def sas_root(self) -> Album: return Album.objects.get(id=settings.SITH_SAS_ROOT_DIR_ID) @pytest.fixture def album(self) -> Album: return baker.make( Album, parent_id=settings.SITH_SAS_ROOT_DIR_ID, is_moderated=True ) @pytest.mark.parametrize( "user", [ None, subscriber_user.make, ], ) def test_permission_denied( self, client: Client, album: Album, request: pytest.FixtureRequest, user: Callable[[], User] | None, ): if user: client.force_login(user()) response = client.get(reverse("sas:album_edit", kwargs={"album_id": album.pk})) assert response.status_code == 403 response = client.post(reverse("sas:album_edit", kwargs={"album_id": album.pk})) assert response.status_code == 403 def test_sas_root_read_only(self, client: Client, sas_root: Album): moderator = baker.make( User, groups=[Group.objects.get(pk=settings.SITH_GROUP_SAS_ADMIN_ID)] ) client.force_login(moderator) response = client.get( reverse("sas:album_edit", kwargs={"album_id": sas_root.pk}) ) assert response.status_code == 404 response = client.post( reverse("sas:album_edit", kwargs={"album_id": sas_root.pk}) ) assert response.status_code == 404 @pytest.mark.parametrize( ("excluded", "is_valid"), [ ("name", False), ("date", False), ("file", True), ("parent", False), ("edit_groups", True), ("recursive", True), ], ) def test_form_required(self, album: Album, excluded: str, is_valid: bool): # noqa: FBT001 data = { "name": album.name[: Album.NAME_MAX_LENGTH], "parent": baker.make(Album, parent=album.parent, is_moderated=True).pk, "date": timezone.now().strftime("%Y-%m-%d"), "file": "/random/path", "edit_groups": [settings.SITH_GROUP_SAS_ADMIN_ID], "recursive": False, } del data[excluded] assert AlbumEditForm(data=data).is_valid() == is_valid def test_form_album_name(self, album: Album): data = { "name": album.name[: Album.NAME_MAX_LENGTH], "parent": album.pk, "date": timezone.now().strftime("%Y-%m-%d"), } assert AlbumEditForm(data=data).is_valid() data["name"] = album.name[: Album.NAME_MAX_LENGTH + 1] assert not AlbumEditForm(data=data).is_valid() def test_update_recursive_parent(self, client: Client, album: Album): client.force_login(User.objects.get(username="root")) payload = { "name": album.name[: Album.NAME_MAX_LENGTH], "parent": album.pk, "date": timezone.now().strftime("%Y-%m-%d"), } response = client.post( reverse( "sas:album_edit", kwargs={"album_id": album.pk}, ), payload, ) assertInHTML( "