From 2fd1b039f4a8c3c1a6349e7dc192f24bdd091ee0 Mon Sep 17 00:00:00 2001 From: iziram Date: Fri, 3 Feb 2023 10:40:51 +0100 Subject: [PATCH] justificatif: test model + api --- app/api/justificatif.py | 6 +- app/models/assiduites.py | 4 +- app/scodoc/sco_assiduites.py | 14 +- tests/api/test_api_justificatifs.py | 37 +++++- tests/unit/test_assiduites.py | 199 +++++++++++++++++++++++++--- 5 files changed, 228 insertions(+), 32 deletions(-) diff --git a/app/api/justificatif.py b/app/api/justificatif.py index 59bdad30a..374f2cb9f 100644 --- a/app/api/justificatif.py +++ b/app/api/justificatif.py @@ -397,7 +397,7 @@ def justif_import(justif_id: int = None): return jsonify({"response": "imported"}) except ScoValueError as err: - return json_error(404, err.args[1]) + return json_error(404, err.args[0]) @bp.route("/justificatif/export//", methods=["GET"]) @@ -428,7 +428,7 @@ def justif_export(justif_id: int = None, filename: str = None): archive_name, justificatif_unique.etudid, filename ) except ScoValueError as err: - return json_error(404, err.args[1]) + return json_error(404, err.args[0]) @bp.route("/justificatif/remove/", methods=["POST"]) @@ -490,7 +490,7 @@ def justif_remove(justif_id: int = None): db.session.commit() except ScoValueError as err: - return json_error(404, err.args[1]) + return json_error(404, err.args[0]) return jsonify({"response": "removed"}) diff --git a/app/models/assiduites.py b/app/models/assiduites.py index 6dd3928d0..ea59c967e 100644 --- a/app/models/assiduites.py +++ b/app/models/assiduites.py @@ -83,7 +83,7 @@ class Assiduite(db.Model): assiduites: list[Assiduite] = etud.assiduites.all() assiduites: list[Justificatif] = etud.assiduites.all() - if is_period_conflicting(date_debut, date_fin, assiduites) != 0: + if is_period_conflicting(date_debut, date_fin, assiduites): raise ScoValueError( "Duplication des assiduités (la période rentrée rentre en conflit avec une assiduité enregistrée)" ) @@ -183,7 +183,7 @@ class Justificatif(db.Model): """Créer un nouveau justificatif pour l'étudiant""" # Vérification de non duplication des périodes justificatifs: list[Justificatif] = etud.justificatifs.all() - if is_period_conflicting(date_debut, date_fin, justificatifs) != 0: + if is_period_conflicting(date_debut, date_fin, justificatifs): raise ScoValueError( "Duplication des justificatifs (la période rentrée rentre en conflit avec un justificatif enregistré)" ) diff --git a/app/scodoc/sco_assiduites.py b/app/scodoc/sco_assiduites.py index ce457b3d3..edba0f103 100644 --- a/app/scodoc/sco_assiduites.py +++ b/app/scodoc/sco_assiduites.py @@ -186,11 +186,15 @@ def justifies(justi: Justificatif) -> list[int]: if justi.etat != scu.EtatJustificatif.VALIDE: return justified - assiduites_query: Assiduite = ( - Assiduite.query.join(Justificatif) - .filter_by(etudid=justi.etudid) - .filter(justi.date_debut >= Assiduite.date_debut) - .filter(justi.date_fin <= Assiduite.date_fin) + assiduites_query: Assiduite = Assiduite.query.join( + Justificatif, Assiduite.etudid == Justificatif.etudid + ).filter(Assiduite.etat != scu.EtatAssiduite.PRESENT) + + assiduites_query = filter_assiduites_by_date( + assiduites_query, justi.date_debut, True + ) + assiduites_query = filter_assiduites_by_date( + assiduites_query, justi.date_fin, False ) justified = [assi.id for assi in assiduites_query.all()] diff --git a/tests/api/test_api_justificatifs.py b/tests/api/test_api_justificatifs.py index 01562c6ea..8c5f4e2b5 100644 --- a/tests/api/test_api_justificatifs.py +++ b/tests/api/test_api_justificatifs.py @@ -209,6 +209,8 @@ def test_route_edit(api_headers): res = POST_JSON(f"/justificatif/{TO_REMOVE[1]}/edit", data, api_headers) assert res == {"OK": True} + # TODO: Modification date deb / fin + # Mauvais fonctionnement check_failure_post(f"/justificatif/{FAUX}/edit", api_headers, data) @@ -288,7 +290,7 @@ def send_file(justif_id: int, filename: str, headers): def check_failure_send( justif_id: int, headers, - filename: str = "/opt/scodoc/tests/api/test_api_justificatif.txt", + filename: str = "tests/api/test_api_justificatif.txt", err: str = None, ): try: @@ -306,6 +308,7 @@ def test_import_justificatif(api_headers): # Bon fonctionnement filename: str = "tests/api/test_api_justificatif.txt" + resp: dict = send_file(1, filename, api_headers) assert "response" in resp assert resp["response"] == "imported" @@ -339,13 +342,30 @@ def test_list_justificatifs(api_headers): check_failure_get(f"/justificatif/list/{FAUX}", api_headers) +def get_export(id: int, fname: str, api_headers): + url: str = API_URL + f"/justificatif/export/{id}/{fname}" + res = requests.get(url, headers=api_headers) + return res + + +def test_export(api_headers): + # Bon fonctionnement + + assert get_export(1, "test_api_justificatif.txt", api_headers).status_code == 200 + + # Mauvais fonctionnement + assert get_export(FAUX, "test_api_justificatif.txt", api_headers).status_code == 404 + assert get_export(1, "blabla.txt", api_headers).status_code == 404 + assert get_export(2, "blabla.txt", api_headers).status_code == 404 + + def test_remove_justificatif(api_headers): # Bon fonctionnement - filename: str = "/opt/scodoc/tests/api/test_api_justificatif.txt" + filename: str = "tests/api/test_api_justificatif.txt" send_file(2, filename, api_headers) - filename: str = "/opt/scodoc/tests/api/test_api_justificatif2.txt" + filename: str = "tests/api/test_api_justificatif2.txt" send_file(2, filename, api_headers) res: dict = POST_JSON("/justificatif/remove/1", {"remove": "all"}, api_headers) @@ -373,3 +393,14 @@ def test_remove_justificatif(api_headers): check_failure_post("/justificatif/remove/2", api_headers, {}) check_failure_post(f"/justificatif/remove/{FAUX}", api_headers, {"remove": "all"}) check_failure_post("/justificatif/remove/1", api_headers, {"remove": "all"}) + + +def test_justified(api_headers): + # Bon fonctionnement + + res: list = GET("/justificatif/justified/1", api_headers) + assert isinstance(res, list) + + # Mauvais fonctionnement + + check_failure_get(f"/justificatif/justified/{FAUX}", api_headers) diff --git a/tests/unit/test_assiduites.py b/tests/unit/test_assiduites.py index 80760a2b7..50f7097a7 100644 --- a/tests/unit/test_assiduites.py +++ b/tests/unit/test_assiduites.py @@ -115,20 +115,23 @@ def test_general(test_client): etud_faux = Identite.query.filter_by(id=etud_faux_dict["id"]).first() ajouter_assiduites(etuds, moduleimpls, etud_faux) - verifier_comptage_et_filtrage( + justificatifs: list[Justificatif] = ajouter_justificatifs(etuds[0]) + verifier_comptage_et_filtrage_assiduites( etuds, moduleimpls, (formsemestre_1, formsemestre_2, formsemestre_3) ) + verifier_filtrage_justificatifs(etuds[0], justificatifs) - editer_supprimer_assiduiter(etuds, moduleimpls) + editer_supprimer_assiduites(etuds, moduleimpls) + editer_supprimer_justificatif(etuds[0]) -def ajouter_justificatifs(etud, etud_faux): +def ajouter_justificatifs(etud): obj_justificatifs = [ { "etat": scu.EtatJustificatif.ATTENTE, "deb": "2022-09-03T08:00+01:00", - "fin": "2022-09-03T10:00+01:00", + "fin": "2022-09-03T09:59:59+01:00", "raison": None, }, { @@ -139,7 +142,7 @@ def ajouter_justificatifs(etud, etud_faux): }, { "etat": scu.EtatJustificatif.VALIDE, - "deb": "2022-09-03T09:00:01+01:00", + "deb": "2022-09-03T10:00:00+01:00", "fin": "2022-09-03T12:00+01:00", "raison": None, }, @@ -151,7 +154,7 @@ def ajouter_justificatifs(etud, etud_faux): }, { "etat": scu.EtatJustificatif.MODIFIE, - "deb": "2023-01-03T11:00:01+01:00", + "deb": "2023-01-03T11:30+01:00", "fin": "2023-01-03T12:00+01:00", "raison": None, }, @@ -160,20 +163,178 @@ def ajouter_justificatifs(etud, etud_faux): justificatifs = [ Justificatif.create_justificatif( etud, - ass["deb"], - ass["fin"], - ass["etat"], - ass["raison"], + scu.is_iso_formated(just["deb"], True), + scu.is_iso_formated(just["fin"], True), + just["etat"], + just["raison"], ) - for ass in obj_justificatifs + for just in obj_justificatifs ] # Vérification de la création des justificatifs assert [ justi for justi in justificatifs if not isinstance(justi, Justificatif) ] == [], "La création des justificatifs de base n'est pas OK" + # Vérification de la gestion des erreurs -def editer_supprimer_assiduiter(etuds: list[Identite], moduleimpls: list[int]): + test_assiduite = { + "etat": scu.EtatJustificatif.ATTENTE, + "deb": "2023-01-03T11:00:01+01:00", + "fin": "2023-01-03T12:00+01:00", + "raison": "Description", + } + + try: + Justificatif.create_justificatif( + etud, + scu.is_iso_formated(test_assiduite["deb"], True), + scu.is_iso_formated(test_assiduite["fin"], True), + test_assiduite["etat"], + test_assiduite["raison"], + ) + except ScoValueError as excp: + assert ( + excp.args[0] + == "Duplication des justificatifs (la période rentrée rentre en conflit avec un justificatif enregistré)" + ) + return justificatifs + + +def verifier_filtrage_justificatifs(etud: Identite, justificatifs: list[Justificatif]): + """ + - vérifier le filtrage des justificatifs (etat, debut, fin) + """ + + # Vérification du filtrage classique + + # Etat + assert ( + scass.filter_justificatifs_by_etat(etud.justificatifs, "valide").count() == 2 + ), "Filtrage de l'état 'valide' mauvais" + assert ( + scass.filter_justificatifs_by_etat(etud.justificatifs, "attente").count() == 1 + ), f"Filtrage de l'état 'attente' mauvais" + assert ( + scass.filter_justificatifs_by_etat(etud.justificatifs, "modifie").count() == 1 + ), "Filtrage de l'état 'modifie' mauvais" + assert ( + scass.filter_justificatifs_by_etat(etud.justificatifs, "non_valide").count() + == 1 + ), "Filtrage de l'état 'non_valide' mauvais" + assert ( + scass.filter_justificatifs_by_etat(etud.justificatifs, "valide,modifie").count() + == 3 + ), "Filtrage de l'état 'valide,modifie' mauvais" + assert ( + scass.filter_justificatifs_by_etat( + etud.justificatifs, "valide,modifie,attente" + ).count() + == 4 + ), "Filtrage de l'état 'valide,modifie,attente' mauvais" + assert ( + scass.filter_justificatifs_by_etat( + etud.justificatifs, "valide,modifie,attente,non_valide" + ).count() + == 5 + ), "Filtrage de l'état 'valide,modifie,attente,_non_valide' mauvais" + + assert ( + scass.filter_justificatifs_by_etat(etud.justificatifs, "autre").count() == 0 + ), "Filtrage de l'état 'autre' mauvais" + + # Date début + date = scu.localize_datetime("2022-09-01T10:00+01:00") + assert ( + scass.filter_justificatifs_by_date(etud.justificatifs, date, sup=True).count() + == 5 + ), "Filtrage 'Date début' mauvais 1" + date = scu.localize_datetime("2022-09-03T08:00:00+01:00") + assert ( + scass.filter_justificatifs_by_date(etud.justificatifs, date, sup=True).count() + == 5 + ), "Filtrage 'Date début' mauvais 2" + date = scu.localize_datetime("2022-09-03T09:00:00+01:00") + assert ( + scass.filter_justificatifs_by_date(etud.justificatifs, date, sup=True).count() + == 4 + ), "Filtrage 'Date début' mauvais 3" + date = scu.localize_datetime("2022-09-03T09:00:02+01:00") + assert ( + scass.filter_justificatifs_by_date(etud.justificatifs, date, sup=True).count() + == 4 + ), "Filtrage 'Date début' mauvais 4" + + # Date fin + date = scu.localize_datetime("2022-09-01T10:00+01:00") + assert ( + scass.filter_justificatifs_by_date(etud.justificatifs, date, sup=False).count() + == 0 + ), "Filtrage 'Date fin' mauvais 1" + date = scu.localize_datetime("2022-09-03T10:00:00+01:00") + assert ( + scass.filter_justificatifs_by_date(etud.justificatifs, date, sup=False).count() + == 1 + ), "Filtrage 'Date fin' mauvais 2" + date = scu.localize_datetime("2022-09-03T10:00:01+01:00") + assert ( + scass.filter_justificatifs_by_date(etud.justificatifs, date, sup=False).count() + == 1 + ), "Filtrage 'Date fin' mauvais 3" + date = scu.localize_datetime("2023-01-04T13:00:01+01:00") + assert ( + scass.filter_justificatifs_by_date(etud.justificatifs, date, sup=False).count() + == 5 + ), "Filtrage 'Date fin' mauvais 4" + date = scu.localize_datetime("2023-01-03T11:00:01+01:00") + assert ( + scass.filter_justificatifs_by_date(etud.justificatifs, date, sup=False).count() + == 4 + ), "Filtrage 'Date fin' mauvais 5" + + # Justifications des assiduites + + assert len(scass.justifies(justificatifs[2])) == 1, "Justifications mauvais" + assert len(scass.justifies(justificatifs[0])) == 0, f"Justifications mauvais" + + +def editer_supprimer_justificatif(etud: Identite): + """ + Troisième Partie: + - Vérification de l'édition des justificatifs + - Vérification de la suppression des justificatifs + """ + + justi: Justificatif = etud.justificatifs.first() + + # Modification de l'état + justi.etat = scu.EtatJustificatif.MODIFIE + db.session.add(justi) + # Modification du moduleimpl + justi.date_debut = scu.localize_datetime("2023-02-03T11:00:01+01:00") + justi.fin = scu.localize_datetime("2023-02-03T12:00:01+01:00") + db.session.add(justi) + db.session.commit() + + # Vérification du changement + assert ( + scass.filter_justificatifs_by_etat(etud.justificatifs, "modifie").count() == 2 + ), "Edition de justificatif mauvais" + assert ( + scass.filter_justificatifs_by_date( + etud.justificatifs, scu.localize_datetime("2023-02-03T11:00:00+01:00") + ).count() + == 1 + ), "Edition de justificatif mauvais" + + # Supression d'une assiduité + + db.session.delete(justi) + db.session.commit() + + assert etud.justificatifs.count() == 4, "Supression de justificatif mauvais" + + +def editer_supprimer_assiduites(etuds: list[Identite], moduleimpls: list[int]): """ Troisième Partie: - Vérification de l'édition des assiduitées @@ -269,8 +430,8 @@ def ajouter_assiduites( assiduites = [ Assiduite.create_assiduite( etud, - ass["deb"], - ass["fin"], + scu.is_iso_formated(ass["deb"], True), + scu.is_iso_formated(ass["fin"], True), ass["etat"], ass["moduleimpl"], ass["desc"], @@ -296,8 +457,8 @@ def ajouter_assiduites( try: Assiduite.create_assiduite( etuds[0], - test_assiduite["deb"], - test_assiduite["fin"], + scu.is_iso_formated(test_assiduite["deb"], True), + scu.is_iso_formated(test_assiduite["fin"], True), test_assiduite["etat"], test_assiduite["moduleimpl"], test_assiduite["desc"], @@ -310,8 +471,8 @@ def ajouter_assiduites( try: Assiduite.create_assiduite( etud_faux, - test_assiduite["deb"], - test_assiduite["fin"], + scu.is_iso_formated(test_assiduite["deb"], True), + scu.is_iso_formated(test_assiduite["fin"], True), test_assiduite["etat"], test_assiduite["moduleimpl"], test_assiduite["desc"], @@ -320,7 +481,7 @@ def ajouter_assiduites( assert excp.args[0] == "L'étudiant n'est pas inscrit au moduleimpl" -def verifier_comptage_et_filtrage( +def verifier_comptage_et_filtrage_assiduites( etuds: list[Identite], moduleimpls: list[int], formsemestres: tuple[int] ): """