diff --git a/gestioncof/petits_cours_views.py b/gestioncof/petits_cours_views.py index d640981a..737365ac 100644 --- a/gestioncof/petits_cours_views.py +++ b/gestioncof/petits_cours_views.py @@ -316,6 +316,7 @@ def _traitement_post(request, demande): with transaction.atomic(): for matiere in proposals: for rank, user in enumerate(proposals[matiere]): + # TODO(AD): Prefer PetitCoursAttributionCounter.get_uptodate() counter = PetitCoursAttributionCounter.objects.get( user=user, matiere=matiere ) diff --git a/gestioncof/tests/test_views.py b/gestioncof/tests/test_views.py index 5fdac4e1..fae54fb3 100644 --- a/gestioncof/tests/test_views.py +++ b/gestioncof/tests/test_views.py @@ -1,4 +1,5 @@ import csv +import json import os import uuid from datetime import timedelta @@ -19,7 +20,15 @@ from gestioncof.autocomplete import Clipper from gestioncof.models import CalendarSubscription, Club, Event, Survey, SurveyAnswer from gestioncof.tests.testcases import ViewTestCaseMixin -from .utils import create_member, create_petitcours_demande, create_root, create_user +from .utils import ( + PetitCoursTestHelpers, + create_member, + create_petitcours_ability, + create_petitcours_demande, + create_petitcours_subject, + create_root, + create_user, +) User = get_user_model() @@ -1295,3 +1304,204 @@ class PetitCoursDemandeDetailListViewTestCase(ViewTestCaseMixin, TestCase): def test_get(self): resp = self.client.get(self.url) self.assertEqual(resp.status_code, 200) + + +class PetitCoursInscriptionViewTestCase(ViewTestCaseMixin, TestCase): + url_name = "petits-cours-inscription" + url_expected = "/petitcours/inscription" + + http_methods = ["GET", "POST"] + + auth_user = "member" + # Also forbidden for "user". Test below. + auth_forbidden = [None] + + def setUp(self): + super().setUp() + self.user = self.users["member"] + self.cofprofile = self.user.profile + + self.subject1 = create_petitcours_subject(name="Matière 1") + self.subject2 = create_petitcours_subject(name="Matière 2") + + def test_get_forbidden_user_not_cof(self): + self.client.force_login(self.users["user"]) + resp = self.client.get(self.url) + self.assertRedirects(resp, reverse("cof-denied")) + + def test_get(self): + resp = self.client.get(self.url) + self.assertEqual(resp.status_code, 200) + + def get_base_post_data(self): + return { + "petitcoursability_set-TOTAL_FORMS": "3", + "petitcoursability_set-INITIAL_FORMS": "0", + "petitcoursability_set-MIN_NUM_FORMS": "0", + "petitcoursability_set-MAX_NUM_FORMS": "1000", + "remarques": "", + } + + base_post_data = property(get_base_post_data) + + def test_post(self): + data = dict( + self.base_post_data, + **{ + "petitcoursability_set-TOTAL_FORMS": "2", + "petitcoursability_set-0-id": "", + "petitcoursability_set-0-user": "", + "petitcoursability_set-0-matiere": str(self.subject1.pk), + "petitcoursability_set-0-niveau": "college", + "petitcoursability_set-0-agrege": "1", + # "petitcoursability_set-0-DELETE": "1", + "petitcoursability_set-1-id": "", + "petitcoursability_set-1-user": "", + "petitcoursability_set-1-matiere": str(self.subject2.pk), + "petitcoursability_set-1-niveau": "lycee", + # "petitcoursability_set-1-agrege": "1", + # "petitcoursability_set-1-DELETE": "1", + # "receive_proposals": "1", + "remarques": "Une remarque", + }, + ) + resp = self.client.post(self.url, data) + + self.assertEqual(resp.status_code, 200) + self.cofprofile.refresh_from_db() + self.assertEqual(self.cofprofile.petits_cours_accept, False) + self.assertEqual(self.cofprofile.petits_cours_remarques, "Une remarque") + self.assertEqual(self.user.petitcoursability_set.count(), 2) + ability1 = self.user.petitcoursability_set.get(matiere=self.subject1) + self.assertEqual(ability1.niveau, "college") + self.assertTrue(ability1.agrege) + ability2 = self.user.petitcoursability_set.get(matiere=self.subject2) + self.assertEqual(ability2.niveau, "lycee") + self.assertFalse(ability2.agrege) + + def test_post_delete(self): + ability1 = create_petitcours_ability(user=self.user) + ability2 = create_petitcours_ability(user=self.user) + + data = dict( + self.base_post_data, + **{ + "petitcoursability_set-INITIAL_FORMS": "2", + "petitcoursability_set-TOTAL_FORMS": "2", + "petitcoursability_set-0-id": str(ability1.pk), + "petitcoursability_set-0-user": "", + "petitcoursability_set-0-matiere": str(self.subject1.pk), + "petitcoursability_set-0-niveau": "college", + "petitcoursability_set-0-agrege": "1", + "petitcoursability_set-0-DELETE": "1", + "petitcoursability_set-1-id": str(ability2.pk), + "petitcoursability_set-1-user": str(self.user.pk), + "petitcoursability_set-1-matiere": str(self.subject2.pk), + "petitcoursability_set-1-niveau": "lycee", + # "petitcoursability_set-1-agrege": "1", + "petitcoursability_set-1-DELETE": "1", + }, + ) + resp = self.client.post(self.url, data) + + self.assertEqual(resp.status_code, 200) + self.assertFalse(self.user.petitcoursability_set.all()) + + +class PetitCoursTraitementViewTestCase( + ViewTestCaseMixin, PetitCoursTestHelpers, TestCase +): + url_name = "petits-cours-demande-traitement" + + http_methods = ["GET", "POST"] + + auth_user = "staff" + auth_forbidden = [None, "user", "member"] + + @property + def url_kwargs(self): + return {"demande_id": self.demande.pk} + + @property + def url_expected(self): + return "/petitcours/demandes/{}/traitement".format(self.demande.pk) + + def setUp(self): + super().setUp() + self.user = self.users["member"] + self.user.profile.petits_cours_accept = True + self.user.profile.save() + self.subject = create_petitcours_subject() + self.demande = create_petitcours_demande(niveau="college") + self.demande.matieres.add(self.subject) + + def test_get(self): + self.require_custommails() + + resp = self.client.get(self.url) + self.assertEqual(resp.status_code, 200) + + def test_get_with_match(self): + self.require_custommails() + + create_petitcours_ability( + user=self.user, matiere=self.subject, niveau="college" + ) + + resp = self.client.get(self.url) + + self.assertEqual(resp.status_code, 200) + self.assertListEqual( + list(resp.context["proposals"]), [(self.subject, [self.user])] + ) + self.assertEqual( + resp.context["attribdata"], json.dumps([(self.subject.id, [self.user.id])]) + ) + + def test_post_with_match(self): + self.require_custommails() + + create_petitcours_ability( + user=self.user, matiere=self.subject, niveau="college" + ) + + data = { + "attribdata": json.dumps([(self.subject.pk, [self.user.pk])]), + "extra": "", + } + resp = self.client.post(self.url, data) + + self.assertEqual(resp.status_code, 200) + self.demande.refresh_from_db() + self.assertTrue(self.demande.traitee) + self.assertEqual(self.demande.traitee_par, self.users["staff"]) + self.assertIsNotNone(self.demande.processed) + + +class PetitCoursRetraitementViewTestCase( + ViewTestCaseMixin, PetitCoursTestHelpers, TestCase +): + url_name = "petits-cours-demande-retraitement" + + http_methods = ["GET", "POST"] + + auth_user = "staff" + auth_forbidden = [None, "user", "member"] + + @property + def url_kwargs(self): + return {"demande_id": self.demande.pk} + + @property + def url_expected(self): + return "/petitcours/demandes/{}/retraitement".format(self.demande.pk) + + def setUp(self): + super().setUp() + self.demande = create_petitcours_demande() + + def test_get(self): + self.require_custommails() + + resp = self.client.get(self.url) + self.assertEqual(resp.status_code, 200) diff --git a/gestioncof/tests/utils.py b/gestioncof/tests/utils.py index f2d95c16..d35cb87f 100644 --- a/gestioncof/tests/utils.py +++ b/gestioncof/tests/utils.py @@ -1,4 +1,8 @@ +import os + +from django.conf import settings from django.contrib.auth import get_user_model +from django.core.management import call_command from gestioncof.petits_cours_models import ( PetitCoursAbility, @@ -93,3 +97,11 @@ def create_petitcours_demande(**kwargs): def create_petitcours_subject(**kwargs): return PetitCoursSubject.objects.create(**kwargs) + + +class PetitCoursTestHelpers: + def require_custommails(self): + data_file = os.path.join( + settings.BASE_DIR, "gestioncof", "management", "data", "custommail.json" + ) + call_command("syncmails", data_file, verbosity=0)