from unittest import mock from backend.models import Administre, Decision, DecisionChoices, Poste from backend.models import StatutPamChoices as StatutPam from backend.utils.decisions import (KEY_CREATE, KEY_UPDATE, get_available_decisions) from backend.utils.permissions import (KEY_READ, KEY_WRITE, Profiles, get_profiles_by_adm) from backend.views import DecisionView from django.contrib.auth import get_user_model from rest_framework import status from rest_framework.test import APITestCase from .constants import PASSWORD, USERNAME from .test_utils import TestUtilsMixin, disable_gestionnaire_permission PK_SV_1 = 'SV1' VIEW_TYPE = DecisionView class DecisionViewTest(APITestCase, TestUtilsMixin): basename = 'Decision' @classmethod def setUpTestData(cls): user = get_user_model().objects.create(id=1, username=USERNAME, is_superuser=True) user.set_password(PASSWORD) user.save() def setUp(self): """ vérifie qu'il n'existe aucun administré ou poste avant le test """ self.assertEqual(Administre.objects.exists(), False, "pas d'administré avant un test") self.assertEqual(Poste.objects.exists(), False, "pas de poste avant un test") logged_in = self.client.login(username=USERNAME, password=PASSWORD) self.assertTrue(logged_in, "l'utilisateur devrait être connecté") def tearDown(self): """ supprime tous les administrés, les postes, les décisions en fin de test """ self.client.logout() Decision.objects.all().delete() Poste.objects.all().delete() Administre.objects.all().delete() def test_list_anonymous(self): """ vérifie que l'accès anonyme est interdit """ self.client.logout() url = self._api_url() response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) @disable_gestionnaire_permission(VIEW_TYPE) def test_list_authenticated(self): """ vérifie que l'utilisateur authentifié peut récupérer des décisions """ url = self._api_url() response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_200_OK) @disable_gestionnaire_permission(VIEW_TYPE) def test_crud(self): """ test de création, MAJ, suppression """ try: statut_pam = next(x for x in StatutPam if x.dec_enabled) self.assertIsNotNone(statut_pam, 'il devrait exister un statut permettant les décisions') self.user = get_user_model().objects.first() self.adm = Administre.objects.create(pk=1, a_statut_pam=statut_pam) @mock.patch( f'{get_available_decisions.__module__}.{get_profiles_by_adm.__name__}', return_value={self.adm.pk: {KEY_READ: (), KEY_WRITE: (Profiles.FILIERE, Profiles.PCP)}} ) def do_with_mock_profiles(mock): user = self.user adm = self.adm decisions = get_available_decisions((adm,), user=user).get(adm.pk) self.assertTrue(decisions.get(KEY_CREATE), 'il devrait exister des décisions possibles (création)') def create(poste_id, de_decision, adm_id=adm.pk, delete_former=None): return self.client.post( self._api_url(), {'administre_id': adm_id, 'poste_id': poste_id, 'de_decision': de_decision, **({'delete_former': delete_former} if isinstance(delete_former, bool) else {})} ) postes = (Poste.objects.create(pk='11'), Poste.objects.create(pk='13')) poste_1 = postes[0].pk poste_2 = postes[1].pk dec_status_1 = decisions.get(KEY_CREATE)[0] # création initiale response = create(poste_1, dec_status_1) qs_decision1 = Decision.objects.filter(pk=adm.pk, poste_id=poste_1, de_decision=dec_status_1) self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(1, Decision.objects.count(), "il doit exister une seule décision") self.assertTrue(qs_decision1.exists(), "la décision n'a pas les bonnes données") # création bis, pas possible sans forcer response = create(poste_2, dec_status_1) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(1, Decision.objects.count(), "il doit exister une seule décision") self.assertTrue(qs_decision1.exists(), "la première décision doit encore exister") # création bis en forçant notes = 'notes' qs_decision1.update(de_notes_gestionnaire='notes') self.assertEqual(notes, qs_decision1.first().de_notes_gestionnaire, "les notes doivent être sauvegardées pour le prochain test") response = create(poste_2, dec_status_1, delete_former=True) qs_decision2 = Decision.objects.filter(pk=adm.pk, poste_id=poste_2, de_decision=dec_status_1) self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(1, Decision.objects.count(), "il doit exister une seule décision") self.assertFalse(qs_decision1.exists(), "la première décision ne doit plus exister") self.assertTrue(qs_decision2.exists(), "la deuxième décision n'a pas les bonnes données") self.assertIsNone(qs_decision2.first().de_notes_gestionnaire, "il ne doit plus exister de notes dans la deuxième décision") # MAJ adm = Administre.objects.filter(pk=adm.pk).first() decisions = get_available_decisions((adm,), user=user).get(adm.pk) self.assertTrue(decisions.get(KEY_UPDATE), 'il devrait exister des décisions possibles (MAJ) pour le prochain test') dec_status_2 = decisions.get(KEY_UPDATE)[0] response = self.client.patch(self._api_url(adm.pk), data={'de_decision': dec_status_2}) qs_decision3 = Decision.objects.filter(pk=adm.pk, poste_id=poste_2, de_decision=dec_status_2) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(1, Decision.objects.count(), "il doit exister une seule décision") self.assertTrue(qs_decision3.exists(), "la deuxième décision doit changer de statut") # suppression response = self.client.delete(self._api_url(adm.pk)) self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) self.assertEqual(0, Decision.objects.count(), "il ne doit plus exister de décision") do_with_mock_profiles() finally: self.user = None self.adm = None