from authens.tests.cas_utils import FakeCASClient from authens.models import CASAccount, OldCASAccount from datetime import date, timedelta from django.test import TestCase from django.urls import reverse from django.conf import settings from django.utils import timezone from unittest import mock from .models import User, Normalien, Lieu, Stage, StageMatiere, AvisLieu 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()