diff --git a/app/api/assiduites.py b/app/api/assiduites.py index e2853dae7..d5208ac29 100644 --- a/app/api/assiduites.py +++ b/app/api/assiduites.py @@ -19,21 +19,22 @@ from app.scodoc.sco_permissions import Permission from flask_login import login_required -from app.models import Identite, Assiduite, FormSemestreInscription, FormSemestre +from app.models import Identite, Assiduite, FormSemestre, ModuleImpl +from app.scodoc.sco_exceptions import ScoValueError import app.scodoc.sco_utils as scu import app.scodoc.sco_assiduites as scass -@bp.route("/assiduite/") -@api_web_bp.route("/assiduite/") +@bp.route("/assiduite/") +@api_web_bp.route("/assiduite/") @scodoc @permission_required(Permission.ScoView) -def assiduite(assiduiteid: int = None): +def assiduite(assiduite_id: int = None): """Retourne un objet assiduité à partir de son id Exemple de résultat: { - "assiduiteid": 1, + "assiduite_id": 1, "etudid": 2, "moduleimpl_id": 3, "date_debut": "2022-10-31T08:00+01:00", @@ -42,9 +43,11 @@ def assiduite(assiduiteid: int = None): } """ - assiduite = Assiduite.query.get(assiduiteid) - if assiduite is None: - return json_error(404, message="assiduité inexistante") + query = Assiduite.query.filter_by(id=assiduite_id) + # if g.scodoc_dept: + # query = query.join(Identite).filter_by(dept_id=g.scodoc_dept_id) + + assiduite = query.first_or_404() data = assiduite.to_dict() @@ -346,13 +349,12 @@ def create_singular( # cas 4 : moduleimpl_id - moduleimpl_id = data.get("moduleimpl_id", None) - if moduleimpl_id is not None: - try: - moduleimpl_id: int = int(moduleimpl_id) - if moduleimpl_id < 0: - raise Exception - except: + moduleimpl_id = data.get("moduleimpl_id", False) + moduleimpl: ModuleImpl = None + + if moduleimpl_id is not False: + moduleimpl = ModuleImpl.query.filter_by(id=int(moduleimpl_id)).first() + if moduleimpl is None: errors.append("param 'moduleimpl_id': invalide") if errors != []: @@ -360,26 +362,24 @@ def create_singular( return (404, err) # TOUT EST OK - nouv_assiduite: Assiduite or int = Assiduite.create_assiduite( - date_debut=deb, - date_fin=fin, - etat=etat, - etud=etud, - module=moduleimpl_id, - ) - if type(nouv_assiduite) is Assiduite: + try: + nouv_assiduite: Assiduite = Assiduite.create_assiduite( + date_debut=deb, + date_fin=fin, + etat=etat, + etud=etud, + moduleimpl=moduleimpl, + ) + db.session.add(nouv_assiduite) db.session.commit() - return (200, {"assiduiteid": nouv_assiduite.assiduiteid}) - - return ( - 404, - { - 1: "La période sélectionnée est déjà couverte par une autre assiduite", - 2: "L'étudiant ne participe pas au moduleimpl sélectionné", - }.get(nouv_assiduite), - ) + return (200, {"assiduite_id": nouv_assiduite.assiduite_id}) + except ScoValueError as excp: + return ( + 404, + excp.args[0], + ) @bp.route("/assiduite/delete", methods=["POST"], defaults={"batch": False}) @@ -417,7 +417,7 @@ def delete(batch: bool = False): else: code, msg = delete_singular( - request.get_json(force=True).get("assiduiteid", -1), db + request.get_json(force=True).get("assiduite_id", -1), db ) if code == 404: return json_error(code, msg) @@ -434,13 +434,13 @@ def delete_singular(assiduite_id: int, db): return (200, "OK") -@bp.route("/assiduite//edit", methods=["POST"]) -@api_web_bp.route("/assiduite//edit", methods=["POST"]) +@bp.route("/assiduite//edit", methods=["POST"]) +@api_web_bp.route("/assiduite//edit", methods=["POST"]) @login_required @scodoc @permission_required(Permission.ScoView) # @permission_required(Permission.ScoAssiduiteChange) -def edit(assiduiteid: int): +def edit(assiduite_id: int): """ Edition d'une assiduité à partir de son id La requête doit avoir un content type "application/json": @@ -449,7 +449,7 @@ def edit(assiduiteid: int): "moduleimpl_id": int } """ - assiduite: Assiduite = Assiduite.query.filter_by(id=assiduiteid).first_or_404() + assiduite: Assiduite = Assiduite.query.filter_by(id=assiduite_id).first_or_404() errors: List[str] = [] data = request.get_json(force=True) @@ -465,18 +465,20 @@ def edit(assiduiteid: int): # Cas 2 : Moduleimpl_id moduleimpl_id = data.get("moduleimpl_id", False) - if moduleimpl_id is not False: - try: - if moduleimpl_id is not None: - moduleimpl_id: int = int(moduleimpl_id) - if moduleimpl_id < 0 or not Assiduite.verif_moduleimpl( - moduleimpl_id, assiduite.etudid - ): - errors.append("param 'moduleimpl_id': etud non inscrit") + moduleimpl: ModuleImpl = None - assiduite.moduleimpl_id = moduleimpl_id - except: + if moduleimpl_id is not False: + if moduleimpl_id is not None: + moduleimpl = ModuleImpl.query.filter_by(id=int(moduleimpl_id)).first() + if moduleimpl is None: errors.append("param 'moduleimpl_id': invalide") + else: + if not moduleimpl.est_inscrit( + Identite.query.filter_by(id=assiduite.etudid).first() + ): + errors.append("param 'moduleimpl_id': etud non inscrit") + else: + assiduite.moduleimpl_id = moduleimpl_id if errors != []: err: str = ", ".join(errors) diff --git a/app/models/assiduites.py b/app/models/assiduites.py index cd930e608..caaa83749 100644 --- a/app/models/assiduites.py +++ b/app/models/assiduites.py @@ -4,8 +4,8 @@ from app import db from app.models import ModuleImpl, ModuleImplInscription from app.models.etudiants import Identite -from app.scodoc.sco_utils import EtatAssiduite, localize_datetime, verif_interval - +from app.scodoc.sco_utils import EtatAssiduite, localize_datetime, is_period_overlapping +from app.scodoc.sco_exceptions import ScoValueError from datetime import datetime @@ -19,7 +19,7 @@ class Assiduite(db.Model): __tablename__ = "assiduites" id = db.Column(db.Integer, primary_key=True) - assiduiteid = db.synonym("id") + assiduite_id = db.synonym("id") date_debut = db.Column( db.DateTime(timezone=True), server_default=db.func.now(), nullable=False @@ -42,7 +42,7 @@ class Assiduite(db.Model): def to_dict(self) -> dict: data = { - "assiduiteid": self.assiduiteid, + "assiduite_id": self.assiduite_id, "etudid": self.etudid, "moduleimpl_id": self.moduleimpl_id, "date_debut": self.date_debut, @@ -58,13 +58,9 @@ class Assiduite(db.Model): date_debut: datetime, date_fin: datetime, etat: EtatAssiduite, - module: int or None = None, + moduleimpl: ModuleImpl = None, ) -> object or int: - """Créer une nouvelle assiduité pour l'étudiant - Documentation des codes d'erreurs renvoyés: - 1: Duplication des assiduités (la période rentrée rentre en conflit avec une assiduité enregistrée) - 2: l'ID du module_impl n'existe pas. - """ + """Créer une nouvelle assiduité pour l'étudiant""" # Vérification de non duplication des périodes assiduites: list[Assiduite] = etud.assiduites.all() @@ -73,26 +69,28 @@ class Assiduite(db.Model): assiduites = [ ass for ass in assiduites - if verif_interval( + if is_period_overlapping( (date_debut, date_fin), (ass.date_debut, ass.date_fin), ) ] if len(assiduites) != 0: - return 1 + raise ScoValueError( + "Duplication des assiduités (la période rentrée rentre en conflit avec une assiduité enregistrée)" + ) - if module is not None: - # Vérification de l'existance du module pour l'étudiant - if cls.verif_moduleimpl(module, etud): + if moduleimpl is not None: + # Vérification de l'existence du module pour l'étudiant + if moduleimpl.est_inscrit(etud): nouv_assiduite = Assiduite( date_debut=date_debut, date_fin=date_fin, etat=etat, etudiant=etud, - moduleimpl_id=module, + moduleimpl_id=moduleimpl.id, ) else: - return 2 + raise ScoValueError("L'étudiant n'est pas inscrit au moduleimpl") else: nouv_assiduite = Assiduite( date_debut=date_debut, @@ -103,30 +101,6 @@ class Assiduite(db.Model): return nouv_assiduite - @staticmethod - def verif_moduleimpl(moduleimpl_id: int, etud: Identite or int) -> bool: - """ - Vérifie si l'étudiant est bien inscrit au moduleimpl - - Retourne Vrai si c'est le cas, faux sinon - """ - output = True - module: ModuleImpl = ModuleImpl.query.filter_by( - moduleimpl_id=moduleimpl_id - ).first() - if module is None: - output = False - - if output: - search_etudid: int = etud.id if type(etud) == Identite else etud - is_module: int = ModuleImplInscription.query.filter_by( - etudid=search_etudid, moduleimpl_id=moduleimpl_id - ).count() - - output = is_module > 0 - - return output - class Justificatif(db.Model): """ @@ -138,7 +112,7 @@ class Justificatif(db.Model): __tablename__ = "justificatifs" - justifid = db.Column(db.Integer, primary_key=True) + justif_id = db.Column(db.Integer, primary_key=True) date_debut = db.Column( db.DateTime(timezone=True), server_default=db.func.now(), nullable=False @@ -158,11 +132,18 @@ class Justificatif(db.Model): ) raison = db.Column(db.Text()) - fichier = db.Column(db.Integer()) + + """ + Les documents liés à l'étudiant sont dans + /docetuds/// + + d'après sco_archives.py + """ + fichier = db.Column(db.Date()) def to_dict(self) -> dict: data = { - "justifid": self.assiduiteid, + "justif_id": self.assiduite_id, "etudid": self.etudid, "date_debut": self.date_debut, "date_fin": self.date_fin, diff --git a/app/models/moduleimpls.py b/app/models/moduleimpls.py index 5b81fa1b4..6bae755b3 100644 --- a/app/models/moduleimpls.py +++ b/app/models/moduleimpls.py @@ -101,6 +101,22 @@ class ModuleImpl(db.Model): d.pop("module", None) return d + def est_inscrit(self, etud: Identite) -> bool: + """ + Vérifie si l'étudiant est bien inscrit au moduleimpl + + Retourne Vrai si c'est le cas, faux sinon + """ + + is_module: int = ( + ModuleImplInscription.query.filter_by( + etudid=etud.id, moduleimpl_id=self.id + ).count() + > 0 + ) + + return is_module + # Enseignants (chargés de TD ou TP) d'un moduleimpl notes_modules_enseignants = db.Table( diff --git a/app/scodoc/sco_utils.py b/app/scodoc/sco_utils.py index ea8d3288b..020ba9c68 100644 --- a/app/scodoc/sco_utils.py +++ b/app/scodoc/sco_utils.py @@ -150,11 +150,11 @@ def is_iso_formated(date: str, convert=False) -> bool or datetime.datetime or No def localize_datetime(date: datetime.datetime or str) -> datetime.datetime: - if type(date) == str: + if isinstance(date, str): date = is_iso_formated(date, convert=True) new_date: datetime.datetime = date - if date.tzinfo == None: + if date.tzinfo is None: from app.models.assiduites import Assiduite first_assiduite = Assiduite.query.first() @@ -167,27 +167,30 @@ def localize_datetime(date: datetime.datetime or str) -> datetime.datetime: return new_date -def verif_interval( - periode: tuple[datetime.datetime], interval: tuple[datetime.datetime] +def is_period_overlapping( + periode: tuple[datetime.datetime, datetime.datetime], + interval: tuple[datetime.datetime, datetime.datetime], ) -> bool: """ - Vérifie si une période est comprise dans un interval, chevauche l'interval ou comprend l'interval + Vérifie si la période et l'interval s'intersectent Retourne Vrai si c'est le cas, faux sinon """ p_deb, p_fin = periode i_deb, i_fin = interval - i = intervalmap() - p = intervalmap() - i[:] = 0 - p[:] = 0 - i[i_deb:i_fin] = 1 - p[p_deb:p_fin] = 1 + # i = intervalmap() + # p = intervalmap() + # i[:] = 0 + # p[:] = 0 + # i[i_deb:i_fin] = 1 + # p[p_deb:p_fin] = 1 - res: int = sum((i[p_deb], i[p_fin], p[i_deb], p[i_fin])) + # # TOTALK: Vérification des bornes de la période dans l'interval et inversement + # res: int = sum((i[p_deb], i[p_fin], p[i_deb], p[i_fin])) - return res > 0 + # return res > 0 + return p_deb <= i_fin and p_fin >= i_deb # Types de modules diff --git a/tests/api/test_api_assiduites.py b/tests/api/test_api_assiduites.py index 33a7767d7..6af3a2656 100644 --- a/tests/api/test_api_assiduites.py +++ b/tests/api/test_api_assiduites.py @@ -15,7 +15,7 @@ MODULE = 1 ASSIDUITES_FIELDS = { - "assiduiteid": int, + "assiduite_id": int, "etudid": int, "moduleimpl_id": int, "date_debut": str, @@ -23,7 +23,7 @@ ASSIDUITES_FIELDS = { "etat": str, } -CREATE_FIELD = {"assiduiteid": int} +CREATE_FIELD = {"assiduite_id": int} BATCH_FIELD = {"errors": dict, "success": dict} COUNT_FIELDS = {"compte": int, "journee": int, "demi": int, "heure": float} @@ -86,7 +86,6 @@ def test_route_assiduite(api_headers): check_failure_get( f"/assiduite/{FAUX}", api_headers, - "assiduité inexistante", ) @@ -195,12 +194,12 @@ def test_route_create(api_headers): res = POST_JSON(f"/assiduite/{ETUDID}/create", data, api_headers) check_fields(res, CREATE_FIELD) - TO_REMOVE.append(res["assiduiteid"]) + TO_REMOVE.append(res["assiduite_id"]) data2 = create_data("absent", "02", MODULE) res = POST_JSON(f"/assiduite/{ETUDID}/create", data2, api_headers) check_fields(res, CREATE_FIELD) - TO_REMOVE.append(res["assiduiteid"]) + TO_REMOVE.append(res["assiduite_id"]) # Mauvais fonctionnement check_failure_post(f"/assiduite/{FAUX}/create", api_headers, data) @@ -208,13 +207,13 @@ def test_route_create(api_headers): f"/assiduite/{ETUDID}/create", api_headers, data, - err="La période sélectionnée est déjà couverte par une autre assiduite", + err="Duplication des assiduités (la période rentrée rentre en conflit avec une assiduité enregistrée)", ) check_failure_post( f"/assiduite/{ETUDID}/create", api_headers, create_data("absent", "03", FAUX), - err="L'étudiant ne participe pas au moduleimpl sélectionné", + err="param 'moduleimpl_id': invalide", ) # -== Avec batch ==- @@ -233,7 +232,7 @@ def test_route_create(api_headers): check_fields(res, BATCH_FIELD) for dat in res["success"]: check_fields(res["success"][dat], CREATE_FIELD) - TO_REMOVE.append(res["success"][dat]["assiduiteid"]) + TO_REMOVE.append(res["success"][dat]["assiduite_id"]) # Mauvais Fonctionnement @@ -252,9 +251,9 @@ def test_route_create(api_headers): assert ( res["errors"]["0"] - == "La période sélectionnée est déjà couverte par une autre assiduite" + == "Duplication des assiduités (la période rentrée rentre en conflit avec une assiduité enregistrée)" ) - assert res["errors"]["1"] == "L'étudiant ne participe pas au moduleimpl sélectionné" + assert res["errors"]["1"] == "param 'moduleimpl_id': invalide" assert res["errors"]["2"] == "param 'etat': invalide" assert ( res["errors"]["3"] @@ -290,7 +289,7 @@ def test_route_delete(api_headers): # -== Sans batch ==- # Bon fonctionnement - data = {"assiduiteid": TO_REMOVE[0]} + data = {"assiduite_id": TO_REMOVE[0]} res = POST_JSON(f"/assiduite/delete", data, api_headers) assert res == {"OK": True} @@ -299,7 +298,7 @@ def test_route_delete(api_headers): check_failure_post( f"/assiduite/delete", api_headers, - {"assiduiteid": FAUX}, + {"assiduite_id": FAUX}, err="Assiduite non existante", ) # -== Avec batch ==- diff --git a/tests/ressources/samples.csv b/tests/ressources/samples.csv index 819d39c28..a8d92875f 100644 --- a/tests/ressources/samples.csv +++ b/tests/ressources/samples.csv @@ -1,4 +1,24 @@ "entry_name";"url";"permission";"method";"content" +"assiduite";"/assiduite/1";"ScoView";"GET"; +"assiduites";"/assiduites/1";"ScoView";"GET"; +"assiduites";"/assiduites/1/query?etat=retard";"ScoView";"GET"; +"assiduites";"/assiduites/1/query?moduleimpl_id=1";"ScoView";"GET"; +"assiduites_count";"/assiduites/1/count";"ScoView";"GET"; +"assiduites_count";"/assiduites/1/count/query?etat=retard";"ScoView";"GET"; +"assiduites_count";"/assiduites/1/count/query?etat=present,retard&metric=compte,heure";"ScoView";"GET"; +"assiduites_formsemestre";"/assiduites/formsemestre/1";"ScoView";"GET"; +"assiduites_formsemestre";"/assiduites/formsemestre/1/query?etat=retard";"ScoView";"GET"; +"assiduites_formsemestre";"/assiduites/formsemestre/1/query?moduleimpl_id=1";"ScoView";"GET"; +"assiduites_formsemestre_count";"/assiduites/formsemestre/1/count";"ScoView";"GET"; +"assiduites_formsemestre_count";"/assiduites/formsemestre/1/count/query?etat=retard";"ScoView";"GET"; +"assiduites_formsemestre_count";"/assiduites/formsemestre/1/count/query?etat=present,retard&metric=compte,heure";"ScoView";"GET"; +"assiduite_create";"/assiduite/1/create";"ScoView";"POST";"{""date_debut"": ""2022-10-27T08:00"",""date_fin"": ""2022-10-27T10:00"",""etat"": ""absent""}" +"assiduite_create";"/assiduite/1/create/batch";"ScoView";"POST";"{""batch"":[{""date_debut"": ""2022-10-27T08:00"",""date_fin"": ""2022-10-27T10:00"",""etat"": ""absent""},{""date_debut"": ""2022-10-27T08:00"",""date_fin"": ""2022-10-27T10:00"",""etat"": ""retard""},{""date_debut"": ""2022-10-27T11:00"",""date_fin"": ""2022-10-27T13:00"",""etat"": ""present""}]}" +"assiduite_edit";"/assiduite/1/edit";"ScoView";"POST";"{""etat"":""absent""}" +"assiduite_edit";"/assiduite/1/edit";"ScoView";"POST";"{""moduleimpl_id"":2}" +"assiduite_edit";"/assiduite/1/edit";"ScoView";"POST";"{""etat"": ""retard"",""moduleimpl_id"":3}" +"assiduite_delete";"/assiduite/delete";"ScoView";"POST";"{""assiduite_id"": 1}" +"assiduite_delete";"/assiduite/delete/batch";"ScoView";"POST";"{""batch"":[2,2,3]}" "departements";"/departements";"ScoView";"GET"; "departements-ids";"/departements_ids";"ScoView";"GET"; "departement";"/departement/TAPI";"ScoView";"GET"; diff --git a/tests/unit/test_assiduites.py b/tests/unit/test_assiduites.py index 1bb5b6641..0eb3ae884 100644 --- a/tests/unit/test_assiduites.py +++ b/tests/unit/test_assiduites.py @@ -14,7 +14,8 @@ from app import db from app.scodoc import sco_formsemestre import app.scodoc.sco_assiduites as scass -from app.models import Assiduite, Identite, FormSemestre +from app.models import Assiduite, Identite, FormSemestre, ModuleImpl +from app.scodoc.sco_exceptions import ScoValueError import app.scodoc.sco_utils as scu @@ -62,29 +63,33 @@ def test_general(test_client): # Création des modulesimpls (4, 2 par semestre) - moduleimpl_id_1_1 = G.create_moduleimpl( + moduleimpl_1_1 = G.create_moduleimpl( module_id=module_id_1, formsemestre_id=formsemestre_id_1, ) - moduleimpl_id_1_2 = G.create_moduleimpl( + moduleimpl_1_2 = G.create_moduleimpl( module_id=module_id_2, formsemestre_id=formsemestre_id_1, ) - moduleimpl_id_2_1 = G.create_moduleimpl( + moduleimpl_2_1 = G.create_moduleimpl( module_id=module_id_1, formsemestre_id=formsemestre_id_2, ) - moduleimpl_id_2_2 = G.create_moduleimpl( + moduleimpl_2_2 = G.create_moduleimpl( module_id=module_id_2, formsemestre_id=formsemestre_id_2, ) moduleimpls = [ - moduleimpl_id_1_1, - moduleimpl_id_1_2, - moduleimpl_id_2_1, - moduleimpl_id_2_2, + moduleimpl_1_1, + moduleimpl_1_2, + moduleimpl_2_1, + moduleimpl_2_2, + ] + + moduleimpls = [ + ModuleImpl.query.filter_by(id=mi_id).first() for mi_id in moduleimpls ] # Création des étudiants (3) @@ -100,7 +105,12 @@ def test_general(test_client): assert None not in etuds, "Problème avec la conversion en Identite" - ajouter_assiduites(etuds, moduleimpls=moduleimpls) + # Etudiant faux + + etud_faux_dict = G.create_etud(code_nip=None, prenom="etudfaux") + etud_faux = Identite.query.filter_by(id=etud_faux_dict["id"]).first() + + ajouter_assiduites(etuds, moduleimpls, etud_faux) verifier_comptage_et_filtrage( etuds, moduleimpls, (formsemestre_1, formsemestre_2, formsemestre_3) ) @@ -124,7 +134,7 @@ def editer_supprimer_assiduiter(etuds: list[Identite], moduleimpls: list[int]): ass1.etat = scu.EtatAssiduite.RETARD db.session.add(ass1) # Modification du moduleimpl - ass2.moduleimpl_id = moduleimpls[0] + ass2.moduleimpl_id = moduleimpls[0].id db.session.add(ass2) db.session.commit() @@ -133,7 +143,7 @@ def editer_supprimer_assiduiter(etuds: list[Identite], moduleimpls: list[int]): scass.filter_by_etat(etuds[0].assiduites, "retard").count() == 3 ), "Edition d'assiduité mauvais" assert ( - scass.filter_by_module_impl(etuds[1].assiduites, moduleimpls[0]).count() == 2 + scass.filter_by_module_impl(etuds[1].assiduites, moduleimpls[0].id).count() == 2 ), "Edition d'assiduité mauvais" # Supression d'une assiduité @@ -144,7 +154,9 @@ def editer_supprimer_assiduiter(etuds: list[Identite], moduleimpls: list[int]): assert etuds[2].assiduites.count() == 5, "Supression d'assiduité mauvais" -def ajouter_assiduites(etuds: list[Identite], moduleimpls: list[int]): +def ajouter_assiduites( + etuds: list[Identite], moduleimpls: list[ModuleImpl], etud_faux: Identite +): """ Première partie: - Ajoute 6 assiduités à chaque étudiant @@ -160,43 +172,43 @@ def ajouter_assiduites(etuds: list[Identite], moduleimpls: list[int]): "etat": scu.EtatAssiduite.PRESENT, "deb": "2022-09-03T08:00+01:00", "fin": "2022-09-03T10:00+01:00", - "moduleimpl_id": None, + "moduleimpl": None, }, { "etat": scu.EtatAssiduite.PRESENT, "deb": "2023-01-03T08:00+01:00", "fin": "2023-01-03T10:00+01:00", - "moduleimpl_id": moduleimpls[2], + "moduleimpl": moduleimpls[2], }, { "etat": scu.EtatAssiduite.ABSENT, "deb": "2022-09-03T10:00:01+01:00", "fin": "2022-09-03T11:00+01:00", - "moduleimpl_id": moduleimpls[0], + "moduleimpl": moduleimpls[0], }, { "etat": scu.EtatAssiduite.ABSENT, "deb": "2022-09-03T14:00:00+01:00", "fin": "2022-09-03T15:00+01:00", - "moduleimpl_id": moduleimpls[1], + "moduleimpl": moduleimpls[1], }, { "etat": scu.EtatAssiduite.RETARD, "deb": "2023-01-03T11:00:01+01:00", "fin": "2023-01-03T12:00+01:00", - "moduleimpl_id": moduleimpls[3], + "moduleimpl": moduleimpls[3], }, { "etat": scu.EtatAssiduite.RETARD, "deb": "2023-01-04T11:00:01+01:00", "fin": "2023-01-04T12:00+01:00", - "moduleimpl_id": moduleimpls[3], + "moduleimpl": moduleimpls[3], }, ] assiduites = [ Assiduite.create_assiduite( - etud, ass["deb"], ass["fin"], ass["etat"], ass["moduleimpl_id"] + etud, ass["deb"], ass["fin"], ass["etat"], ass["moduleimpl"] ) for ass in obj_assiduites ] @@ -208,32 +220,36 @@ def ajouter_assiduites(etuds: list[Identite], moduleimpls: list[int]): # Vérification de la gestion des erreurs - test_assiduites = [ - { - "etat": scu.EtatAssiduite.RETARD, - "deb": "2023-01-04T11:00:01+01:00", - "fin": "2023-01-04T12:00+01:00", - "moduleimpl_id": moduleimpls[3], - }, - { - "etat": scu.EtatAssiduite.RETARD, - "deb": "2023-01-05T11:00:01+01:00", - "fin": "2023-01-05T12:00+01:00", - "moduleimpl_id": 1000, - }, - ] + test_assiduite = { + "etat": scu.EtatAssiduite.RETARD, + "deb": "2023-01-04T11:00:01+01:00", + "fin": "2023-01-04T12:00+01:00", + "moduleimpl": moduleimpls[3], + } - assiduites_crees = [ + try: Assiduite.create_assiduite( - etuds[0], ass["deb"], ass["fin"], ass["etat"], ass["moduleimpl_id"] + etuds[0], + test_assiduite["deb"], + test_assiduite["fin"], + test_assiduite["etat"], + test_assiduite["moduleimpl"], ) - for ass in test_assiduites - ] - - assert [ass for ass in assiduites_crees if type(ass) != Assiduite] == [ - 1, - 2, - ], "La vérification des erreurs ne fonctionne pas" + except ScoValueError as excp: + assert ( + excp.args[0] + == "Duplication des assiduités (la période rentrée rentre en conflit avec une assiduité enregistrée)" + ) + try: + Assiduite.create_assiduite( + etud_faux, + test_assiduite["deb"], + test_assiduite["fin"], + test_assiduite["etat"], + test_assiduite["moduleimpl"], + ) + except ScoValueError as excp: + assert excp.args[0] == "L'étudiant n'est pas inscrit au moduleimpl" def verifier_comptage_et_filtrage( @@ -282,16 +298,16 @@ def verifier_comptage_et_filtrage( # Module assert ( - scass.filter_by_module_impl(etu3.assiduites, mod11).count() == 1 + scass.filter_by_module_impl(etu3.assiduites, mod11.id).count() == 1 ), "Filtrage par 'Moduleimpl' mauvais" assert ( - scass.filter_by_module_impl(etu3.assiduites, mod12).count() == 1 + scass.filter_by_module_impl(etu3.assiduites, mod12.id).count() == 1 ), "Filtrage par 'Moduleimpl' mauvais" assert ( - scass.filter_by_module_impl(etu3.assiduites, mod21).count() == 1 + scass.filter_by_module_impl(etu3.assiduites, mod21.id).count() == 1 ), "Filtrage par 'Moduleimpl' mauvais" assert ( - scass.filter_by_module_impl(etu3.assiduites, mod22).count() == 2 + scass.filter_by_module_impl(etu3.assiduites, mod22.id).count() == 2 ), "Filtrage par 'Moduleimpl' mauvais" assert ( scass.filter_by_module_impl(etu3.assiduites, None).count() == 1 diff --git a/tools/fakedatabase/create_test_api_database.py b/tools/fakedatabase/create_test_api_database.py index 74e07a23f..f884b82de 100644 --- a/tools/fakedatabase/create_test_api_database.py +++ b/tools/fakedatabase/create_test_api_database.py @@ -383,7 +383,7 @@ def ajouter_assiduites(formsemestre: FormSemestre): """ Ajoute des assiduités semi-aléatoires à chaque étudiant du semestre """ - MODS = [moduleimpl.id for moduleimpl in formsemestre.modimpls] + MODS = [moduleimpl for moduleimpl in formsemestre.modimpls] MODS.append(None) from app.scodoc.sco_utils import localize_datetime @@ -394,11 +394,13 @@ def ajouter_assiduites(formsemestre: FormSemestre): for i in range(random.randint(1, 5)): etat = random.randint(0, 2) - module = random.choice(MODS) + moduleimpl = random.choice(MODS) deb_date = base_date + datetime.timedelta(days=i) fin_date = deb_date + datetime.timedelta(hours=i) - code = Assiduite.create_assiduite(etud, deb_date, fin_date, etat, module) + code = Assiduite.create_assiduite( + etud, deb_date, fin_date, etat, moduleimpl + ) assert isinstance( code, Assiduite