from datetime import date, timedelta from unittest import mock from authens.models import CASAccount, OldCASAccount from authens.tests.cas_utils import FakeCASClient from django.conf import settings from django.test import TestCase from django.urls import reverse from django.utils import timezone from .models import AvisLieu, Lieu, Normalien, Stage, StageMatiere, User class ExperiENSTestCase(TestCase): # Dummy database def setUp(self): self.u_conscrit = User.objects.create_user( "conscrit", "conscrit@ens.fr", "conscrit" ) self.p_conscrit = self.u_conscrit.profil self.p_conscrit.nom = "Petit conscrit" self.p_conscrit.promotion = "Serpentard 2020" self.p_conscrit.bio = "Je suis un petit conscrit" self.p_conscrit.save() self.sa_conscrit = CASAccount( user=self.u_conscrit, cas_login="conscrit", entrance_year=2020, ) self.sa_conscrit.save() self.u_archi = User.objects.create_user( "archicube", "archicube@ens.fr", "archicube" ) self.p_archi = self.u_archi.profil self.p_archi.nom = "Vieil archicube" self.p_archi.promotion = "Gryffondor 2014" self.p_archi.bio = "Je suis un vieil archicube" self.lieu1 = Lieu( nom="Beaux-Bâtons", type_lieu="universite", ville="Brocéliande", pays="FR", coord="POINT(-1.63971 48.116382)", ) self.lieu1.save() self.lieu2 = Lieu( nom="Durmstrang", type_lieu="universite", ville="Edimbourg", pays="GB", coord="POINT(56.32153 -1.259715)", ) self.lieu2.save() self.matiere1 = StageMatiere(nom="Arithmancie", slug="arithmancie") self.matiere1.save() self.matiere2 = StageMatiere(nom="Sortilège", slug="sortilege") self.matiere2.save() self.cstage1 = Stage( auteur=self.p_conscrit, sujet="Wingardium Leviosa", date_debut=date(2020, 5, 10), date_fin=date(2020, 8, 26), type_stage="recherche", niveau_scol="M1", public=True, ) self.cstage1.save() self.cstage1.matieres.add(self.matiere1) alieu1 = AvisLieu(stage=self.cstage1, lieu=self.lieu1, chapo="Trop bien") alieu1.save() self.cstage2 = Stage( auteur=self.p_conscrit, sujet="Avada Kedavra", date_debut=date(2021, 5, 10), date_fin=date(2021, 8, 26), type_stage="sejour_dri", niveau_scol="M2", public=False, ) self.cstage2.save() self.cstage2.matieres.add(self.matiere2) alieu2 = AvisLieu(stage=self.cstage2, lieu=self.lieu2, chapo="Trop nul") alieu2.save() self.astage1 = Stage( auteur=self.p_archi, sujet="Alohomora", date_debut=date(2014, 5, 10), date_fin=date(2014, 8, 26), type_stage="recherche", niveau_scol="M2", public=True, ) self.astage1.save() self.astage1.matieres.add(self.matiere2) alieu3 = AvisLieu(stage=self.astage1, lieu=self.lieu1, chapo="Trop moyen") alieu3.save() def assertRedirectToLogin(self, testurl): r = self.client.get(testurl) return self.assertRedirects(r, settings.LOGIN_URL + "?next=" + testurl) def assertPageNotFound(self, testurl): r = self.client.get(testurl) self.assertEqual(r.status_code, 404) """ ACCÈS PUBLIC """ class PublicViewsTest(ExperiENSTestCase): """ Vérifie que les fiches de stages ne sont pas visibles hors connexion """ def test_stage_visibility_public(self): self.assertRedirectToLogin( reverse("avisstage:stage", kwargs={"pk": self.cstage1.id}) ) self.assertRedirectToLogin( reverse("avisstage:stage", kwargs={"pk": self.cstage2.id}) ) self.assertRedirectToLogin( reverse("avisstage:stage", kwargs={"pk": self.astage1.id}) ) """ Vérifie que les profils de normaliens ne sont pas visibles hors connexion """ def test_profil_visibility_public(self): self.assertRedirectToLogin( reverse("avisstage:profil", kwargs={"username": self.u_conscrit.username}) ) self.assertRedirectToLogin( reverse("avisstage:profil", kwargs={"username": self.u_archi.username}) ) """ Vérifie que la recherche n'est pas accessible hors connexion """ def test_pages_visibility_public(self): self.assertRedirectToLogin(reverse("avisstage:recherche")) self.assertRedirectToLogin(reverse("avisstage:recherche_resultats")) self.assertRedirectToLogin(reverse("avisstage:stage_items")) self.assertRedirectToLogin(reverse("avisstage:feedback")) self.assertRedirectToLogin(reverse("avisstage:moderation")) """ Vérifie que l'API n'est pas accessible hors connexion """ def test_api_visibility_public(self): testurl = reverse( "avisstage:api_dispatch_list", kwargs={"resource_name": "lieu", "api_name": "v1"}, ) r = self.client.get(testurl) self.assertEqual(r.status_code, 401) testurl = reverse( "avisstage:api_dispatch_list", kwargs={"resource_name": "stage", "api_name": "v1"}, ) r = self.client.get(testurl) self.assertEqual(r.status_code, 401) testurl = reverse( "avisstage:api_dispatch_list", kwargs={"resource_name": "profil", "api_name": "v1"}, ) r = self.client.get(testurl) self.assertEqual(r.status_code, 401) """ Vérifie que les pages d'édition ne sont pas accessible hors connexion """ def test_edit_visibility_public(self): self.assertRedirectToLogin( reverse("avisstage:stage_edit", kwargs={"pk": self.cstage1.id}) ) self.assertRedirectToLogin( reverse("avisstage:stage_edit", kwargs={"pk": self.astage1.id}) ) self.assertRedirectToLogin( reverse("avisstage:stage_publication", kwargs={"pk": self.cstage1.id}) ) self.assertRedirectToLogin( reverse("avisstage:stage_publication", kwargs={"pk": self.astage1.id}) ) self.assertRedirectToLogin(reverse("avisstage:stage_ajout")) self.assertRedirectToLogin(reverse("avisstage:profil_edit")) """ ACCÈS ARCHICUBE """ class ArchicubeViewsTest(ExperiENSTestCase): def setUp(self): super().setUp() # Connexion with password self.client.login(username="archicube", password="archicube") def assert403Archicubes(self, testurl): r = self.client.get(testurl) return self.assertRedirects(r, reverse("avisstage:403-archicubes")) """ Vérifie que les seules fiches de stages visibles sont les siennes """ def test_stage_visibility_archi(self): self.assertPageNotFound( reverse("avisstage:stage", kwargs={"pk": self.cstage1.id}) ) self.assertPageNotFound( reverse("avisstage:stage", kwargs={"pk": self.cstage2.id}) ) testurl = reverse("avisstage:stage", kwargs={"pk": self.astage1.id}) r = self.client.get(testurl) self.assertEqual(r.status_code, 200) """ Vérifie que le seul profil visible est le sien """ def test_profil_visibility_archi(self): self.assertPageNotFound( reverse("avisstage:profil", kwargs={"username": self.u_conscrit.username}) ) testurl = reverse( "avisstage:profil", kwargs={"username": self.u_archi.username} ) r = self.client.get(testurl) self.assertEqual(r.status_code, 200) """ Vérifie que la recherche n'est pas accessible """ def test_pages_visibility_archi(self): self.assert403Archicubes(reverse("avisstage:recherche")) self.assert403Archicubes(reverse("avisstage:recherche_resultats")) self.assert403Archicubes(reverse("avisstage:stage_items")) testurl = reverse("avisstage:feedback") r = self.client.post( testurl, {"objet": "Contact", "message": "Ceci est un texte"} ) self.assertRedirects(r, reverse("avisstage:index")) testurl = reverse("avisstage:moderation") r = self.client.get(testurl) self.assertRedirects(r, reverse("admin:login") + "?next=" + testurl) """ Vérifie que la seule API accessible est celle des lieux """ def test_api_visibility_archi(self): testurl = reverse( "avisstage:api_dispatch_list", kwargs={"resource_name": "lieu", "api_name": "v1"}, ) r = self.client.get(testurl) self.assertEqual(r.status_code, 200) testurl = reverse( "avisstage:api_dispatch_list", kwargs={"resource_name": "stage", "api_name": "v1"}, ) r = self.client.get(testurl) self.assertEqual(r.status_code, 401) testurl = reverse( "avisstage:api_dispatch_list", kwargs={"resource_name": "profil", "api_name": "v1"}, ) r = self.client.get(testurl) self.assertEqual(r.status_code, 401) """ Vérifie que le seul stage modifiable est le sien """ def test_edit_visibility_archi(self): testurl = reverse("avisstage:stage_edit", kwargs={"pk": self.cstage1.id}) r = self.client.get(testurl) self.assertEqual(r.status_code, 403) testurl = reverse("avisstage:stage_edit", kwargs={"pk": self.astage1.id}) r = self.client.get(testurl) self.assertEqual(r.status_code, 200) testurl = reverse("avisstage:stage_publication", kwargs={"pk": self.cstage1.id}) r = self.client.post(testurl, {"publier": True}) self.assertEqual(r.status_code, 403) testurl = reverse("avisstage:stage_publication", kwargs={"pk": self.astage1.id}) r = self.client.post(testurl, {"publier": True}) self.assertRedirects( r, reverse("avisstage:stage", kwargs={"pk": self.astage1.id}) ) testurl = reverse("avisstage:stage_ajout") r = self.client.get(testurl) self.assertEqual(r.status_code, 200) testurl = reverse("avisstage:profil_edit") r = self.client.get(testurl) self.assertEqual(r.status_code, 200) # TODO : test post() class DeprecatedArchicubeViewsTest(ArchicubeViewsTest): @mock.patch("authens.backends.get_cas_client") def setUp(self, mock_cas_client): super().setUp() fake_cas_client = FakeCASClient(cas_login="archicube", entrance_year=2012) mock_cas_client.return_value = fake_cas_client self.sa_archi = OldCASAccount( user=self.u_archi, cas_login="archicube", entrance_year=2012, ) self.sa_archi.save() # First connexion through CAS self.client.login(ticket="dummy") self.client.logout() # Time flies self.p_archi.last_cas_login = (timezone.now() - timedelta(days=365)).date() self.p_archi.save() # New connexion with password self.client.login(username="archicube", password="archicube") """ ACCÈS EN SCOLARITE """ class ScolariteViewsTest(ExperiENSTestCase): @mock.patch("authens.backends.get_cas_client") def setUp(self, mock_cas_client): super().setUp() fake_cas_client = FakeCASClient(cas_login="vieuxcon", entrance_year=2017) mock_cas_client.return_value = fake_cas_client self.u_vieuxcon = User.objects.create_user( "vieuxcon", "vieuxcon@ens.fr", "vieuxcon" ) self.p_vieuxcon = self.u_vieuxcon.profil self.p_vieuxcon.nom = "Vieux con" self.p_vieuxcon.promotion = "Poufsouffle 2017" self.p_vieuxcon.bio = "Je suis un vieux con encore en scolarité" self.p_vieuxcon.save() self.sa_vieuxcon = CASAccount( user=self.u_vieuxcon, cas_login="vieuxcon", entrance_year=2017, ) self.sa_vieuxcon.save() self.vstage1 = Stage( auteur=self.p_vieuxcon, sujet="Oubliettes", date_debut=date(2018, 5, 10), date_fin=date(2018, 8, 26), type_stage="recherche", niveau_scol="M1", public=False, ) self.vstage1.save() self.vstage1.matieres.add(self.matiere2) alieu1 = AvisLieu(stage=self.vstage1, lieu=self.lieu2, chapo="Pas si mal") alieu1.save() # Connexion through CAS self.client.login(ticket="dummy") """ Vérifie que les seules fiches de stages visibles sont les siennes ou celles publiques """ def test_stage_visibility_scolarite(self): testurl = reverse("avisstage:stage", kwargs={"pk": self.cstage1.id}) r = self.client.get(testurl) self.assertEqual(r.status_code, 200) self.assertPageNotFound( reverse("avisstage:stage", kwargs={"pk": self.cstage2.id}) ) testurl = reverse("avisstage:stage", kwargs={"pk": self.vstage1.id}) r = self.client.get(testurl) self.assertEqual(r.status_code, 200) """ Vérifie que tous les profils sont visibles """ def test_profil_visibility_scolarite(self): testurl = reverse( "avisstage:profil", kwargs={"username": self.u_conscrit.username} ) r = self.client.get(testurl) self.assertEqual(r.status_code, 200) self.assertContains(r, "Wingardium Leviosa") # Public self.assertNotContains(r, "Avada Kedavra") # Brouillon testurl = reverse( "avisstage:profil", kwargs={"username": self.u_archi.username} ) r = self.client.get(testurl) self.assertEqual(r.status_code, 200) testurl = reverse( "avisstage:profil", kwargs={"username": self.u_vieuxcon.username} ) r = self.client.get(testurl) self.assertEqual(r.status_code, 200) """ Vérifie que la recherche et les autres pages sont accessibles """ def test_pages_visibility_scolarite(self): testurl = reverse("avisstage:recherche") r = self.client.get(testurl) self.assertEqual(r.status_code, 200) testurl = reverse("avisstage:recherche_resultats") r = self.client.get(testurl) self.assertEqual(r.status_code, 200) self.assertContains(r, "Wingardium Leviosa") # Public self.assertNotContains(r, "Avada Kedavra") # Brouillon testurl = ( reverse("avisstage:stage_items") + "?ids=" + ";".join( ("%d" % k.id) for k in [self.cstage1, self.cstage2, self.astage1] ) ) r = self.client.get(testurl) self.assertEqual(r.status_code, 200) self.assertContains(r, "Wingardium Leviosa") # Public self.assertNotContains(r, "Avada Kedavra") # Brouillon testurl = reverse("avisstage:feedback") r = self.client.post( testurl, {"objet": "Contact", "message": "Ceci est un texte"} ) self.assertRedirects(r, reverse("avisstage:index")) testurl = reverse("avisstage:moderation") r = self.client.get(testurl) self.assertRedirects(r, reverse("admin:login") + "?next=" + testurl) """ Vérifie que toutes les API sont accessibles et qu'elles ne montrent que les stages publics """ def test_api_visibility_scolarite(self): testurl = reverse( "avisstage:api_dispatch_list", kwargs={"resource_name": "lieu", "api_name": "v1"}, ) r = self.client.get(testurl) self.assertEqual(r.status_code, 200) testurl = reverse( "avisstage:api_dispatch_list", kwargs={"resource_name": "stage", "api_name": "v1"}, ) r = self.client.get(testurl) self.assertEqual(r.status_code, 200) self.assertContains(r, "Wingardium Leviosa") # Public self.assertNotContains(r, "Avada Kedavra") # Brouillon testurl = reverse( "avisstage:api_dispatch_list", kwargs={"resource_name": "profil", "api_name": "v1"}, ) r = self.client.get(testurl) self.assertEqual(r.status_code, 200) """ Vérifie que le seul stage modifiable est le sien """ def test_edit_visibility_scolarite(self): testurl = reverse("avisstage:stage_edit", kwargs={"pk": self.cstage1.id}) r = self.client.get(testurl) self.assertEqual(r.status_code, 403) testurl = reverse("avisstage:stage_edit", kwargs={"pk": self.astage1.id}) r = self.client.get(testurl) self.assertEqual(r.status_code, 403) testurl = reverse("avisstage:stage_edit", kwargs={"pk": self.vstage1.id}) r = self.client.get(testurl) self.assertEqual(r.status_code, 200) testurl = reverse("avisstage:stage_publication", kwargs={"pk": self.cstage1.id}) r = self.client.post(testurl, {"publier": True}) self.assertEqual(r.status_code, 403) testurl = reverse("avisstage:stage_publication", kwargs={"pk": self.vstage1.id}) r = self.client.post(testurl, {"publier": True}) self.assertRedirects( r, reverse("avisstage:stage", kwargs={"pk": self.vstage1.id}) ) testurl = reverse("avisstage:stage_ajout") r = self.client.get(testurl) self.assertEqual(r.status_code, 200) testurl = reverse("avisstage:profil_edit") r = self.client.get(testurl) self.assertEqual(r.status_code, 200) # TODO : test post()