From 02ec55ca1853897a3b482dd563048ef23c5c3e2b Mon Sep 17 00:00:00 2001 From: iziram Date: Mon, 30 Jan 2023 15:12:31 +0100 Subject: [PATCH] - Modifi comportement Batch - Ajout description assiduite --- app/api/assiduites.py | 110 ++++++---------- app/models/assiduites.py | 15 ++- ..._ajout_modeles_assiduites_justificatifs.py | 82 ------------ ..._ajout_modeles_assiduites_justificatifs.py | 82 ------------ ...b22e_modèle_assiduites_et_justificatifs.py | 55 ++++++++ tests/api/test_api_assiduites.py | 124 +++++++++--------- tests/unit/test_assiduites.py | 18 ++- 7 files changed, 184 insertions(+), 302 deletions(-) delete mode 100644 migrations/versions/530594458193_ajout_modeles_assiduites_justificatifs.py delete mode 100644 migrations/versions/685fe5c55439_ajout_modeles_assiduites_justificatifs.py create mode 100644 migrations/versions/943eb2deb22e_modèle_assiduites_et_justificatifs.py diff --git a/app/api/assiduites.py b/app/api/assiduites.py index d5208ac29..b479ab695 100644 --- a/app/api/assiduites.py +++ b/app/api/assiduites.py @@ -39,7 +39,8 @@ def assiduite(assiduite_id: int = None): "moduleimpl_id": 3, "date_debut": "2022-10-31T08:00+01:00", "date_fin": "2022-10-31T10:00+01:00", - "etat": "retard" + "etat": "retard", + "desc": "une description", } """ @@ -258,21 +259,13 @@ def count_assiduites_formsemestre( return jsonify(scass.get_assiduites_stats(assiduites, metric, filter)) -@bp.route("/assiduite//create", methods=["POST"], defaults={"batch": False}) -@api_web_bp.route( - "/assiduite//create", methods=["POST"], defaults={"batch": False} -) -@bp.route( - "/assiduite//create/batch", methods=["POST"], defaults={"batch": True} -) -@api_web_bp.route( - "/assiduite//create/batch", methods=["POST"], defaults={"batch": True} -) +@bp.route("/assiduite//create", methods=["POST"]) +@api_web_bp.route("/assiduite//create", methods=["POST"]) @scodoc @login_required @permission_required(Permission.ScoView) # @permission_required(Permission.ScoAssiduiteChange) -def create(etudid: int = None, batch: bool = False): +def create(etudid: int = None): """ Création d'une assiduité pour l'étudiant (etudid) La requête doit avoir un content type "application/json": @@ -292,26 +285,17 @@ def create(etudid: int = None, batch: bool = False): """ etud: Identite = Identite.query.filter_by(id=etudid).first_or_404() - if batch: - errors: dict[int, str] = {} - success: dict[ - int, - ] = {} - for i, data in enumerate(request.get_json(force=True).get("batch")): - code, obj = create_singular(data, etud) - if code == 404: - errors[i] = obj - else: - success[i] = obj - return jsonify({"errors": errors, "success": success}) - - else: - code, obj = create_singular(request.get_json(force=True), etud) + errors: dict[int, str] = {} + success: dict[int, object] = {} + for i, data in enumerate(request.get_json(force=True)): + code, obj = create_singular(data, etud) if code == 404: - return json_error(code, obj) + errors[i] = obj else: - return jsonify(obj) + success[i] = obj + + return jsonify({"errors": errors, "success": success}) def create_singular( @@ -357,6 +341,10 @@ def create_singular( if moduleimpl is None: errors.append("param 'moduleimpl_id': invalide") + # cas 5 : desc + + desc:str = data.get("desc", None) + if errors != []: err: str = ", ".join(errors) return (404, err) @@ -382,48 +370,27 @@ def create_singular( ) -@bp.route("/assiduite/delete", methods=["POST"], defaults={"batch": False}) -@api_web_bp.route("/assiduite/delete", methods=["POST"], defaults={"batch": False}) -@bp.route( - "/assiduite/delete/batch", - methods=["POST"], - defaults={"batch": True}, -) -@api_web_bp.route( - "/assiduite/delete/batch", - methods=["POST"], - defaults={"batch": True}, -) +@bp.route("/assiduite/delete", methods=["POST"]) +@api_web_bp.route("/assiduite/delete", methods=["POST"]) @login_required @scodoc @permission_required(Permission.ScoView) # @permission_required(Permission.ScoAssiduiteChange) -def delete(batch: bool = False): +def delete(): """ Suppression d'une assiduité à partir de son id """ - if batch: - assiduites: list[int] = request.get_json(force=True).get("batch", []) - output = {"errors": {}, "success": {}} + assiduites: list[int] = request.get_json(force=True) + output = {"errors": {}, "success": {}} - for i, ass in enumerate(assiduites): - code, msg = delete_singular(ass, db) - if code == 404: - output["errors"][f"{i}"] = msg - else: - output["success"][f"{i}"] = {"OK": True} - db.session.commit() - return jsonify(output) - - else: - code, msg = delete_singular( - request.get_json(force=True).get("assiduite_id", -1), db - ) + for i, ass in enumerate(assiduites): + code, msg = delete_singular(ass, db) if code == 404: - return json_error(code, msg) - if code == 200: - db.session.commit() - return jsonify({"OK": True}) + output["errors"][f"{i}"] = msg + else: + output["success"][f"{i}"] = {"OK": True} + db.session.commit() + return jsonify(output) def delete_singular(assiduite_id: int, db): @@ -470,16 +437,17 @@ def edit(assiduite_id: int): 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") + if moduleimpl is None: + errors.append("param 'moduleimpl_id': invalide") else: - assiduite.moduleimpl_id = moduleimpl_id - + 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 + else: + assiduite.moduleimpl_id = moduleimpl_id if errors != []: err: str = ", ".join(errors) return json_error(404, err) diff --git a/app/models/assiduites.py b/app/models/assiduites.py index caaa83749..53e127d87 100644 --- a/app/models/assiduites.py +++ b/app/models/assiduites.py @@ -14,6 +14,7 @@ class Assiduite(db.Model): Représente une assiduité: - une plage horaire lié à un état et un étudiant - un module si spécifiée + - une description si spécifiée """ __tablename__ = "assiduites" @@ -40,6 +41,8 @@ class Assiduite(db.Model): ) etat = db.Column(db.Integer, nullable=False) + desc = db.Column(db.Text) + def to_dict(self) -> dict: data = { "assiduite_id": self.assiduite_id, @@ -48,6 +51,7 @@ class Assiduite(db.Model): "date_debut": self.date_debut, "date_fin": self.date_fin, "etat": self.etat, + "desc": self.desc, } return data @@ -59,6 +63,7 @@ class Assiduite(db.Model): date_fin: datetime, etat: EtatAssiduite, moduleimpl: ModuleImpl = None, + description: str = None, ) -> object or int: """Créer une nouvelle assiduité pour l'étudiant""" # Vérification de non duplication des périodes @@ -88,6 +93,7 @@ class Assiduite(db.Model): etat=etat, etudiant=etud, moduleimpl_id=moduleimpl.id, + desc=description, ) else: raise ScoValueError("L'étudiant n'est pas inscrit au moduleimpl") @@ -97,6 +103,7 @@ class Assiduite(db.Model): date_fin=date_fin, etat=etat, etudiant=etud, + desc=description, ) return nouv_assiduite @@ -134,12 +141,12 @@ class Justificatif(db.Model): raison = db.Column(db.Text()) """ - Les documents liés à l'étudiant sont dans - /docetuds/// + Les justificatifs sont enregistrés dans + /justificatifs/// - d'après sco_archives.py + d'après sco_archives.py#JustificatifArchiver """ - fichier = db.Column(db.Date()) + fichier = db.Column(db.Text()) def to_dict(self) -> dict: data = { diff --git a/migrations/versions/530594458193_ajout_modeles_assiduites_justificatifs.py b/migrations/versions/530594458193_ajout_modeles_assiduites_justificatifs.py deleted file mode 100644 index fb36c80cb..000000000 --- a/migrations/versions/530594458193_ajout_modeles_assiduites_justificatifs.py +++ /dev/null @@ -1,82 +0,0 @@ -"""Ajout Modeles Assiduites Justificatifs - -Revision ID: 530594458193 -Revises: 3c12f5850cff -Create Date: 2022-12-19 13:56:28.597632 - -""" -from alembic import op -import sqlalchemy as sa - - -# revision identifiers, used by Alembic. -revision = "530594458193" -down_revision = "3c12f5850cff" -branch_labels = None -depends_on = None - - -def upgrade(): - # ### commands auto generated by Alembic - please adjust! ### - op.create_table( - "justificatifs", - sa.Column("justifid", sa.Integer(), nullable=False), - sa.Column( - "date_debut", - sa.DateTime(timezone=True), - server_default=sa.text("now()"), - nullable=False, - ), - sa.Column( - "date_fin", - sa.DateTime(timezone=True), - server_default=sa.text("now()"), - nullable=False, - ), - sa.Column("etudid", sa.Integer(), nullable=False), - sa.Column("etat", sa.Integer(), nullable=True), - sa.Column("raison", sa.Text(), nullable=True), - sa.Column("fichier", sa.Integer(), nullable=True), - sa.ForeignKeyConstraint(["etudid"], ["identite.id"], ondelete="CASCADE"), - sa.PrimaryKeyConstraint("justifid"), - ) - op.create_index( - op.f("ix_justificatifs_etudid"), "justificatifs", ["etudid"], unique=False - ) - op.create_table( - "assiduites", - sa.Column("id", sa.Integer(), nullable=False), - sa.Column( - "date_debut", - sa.DateTime(timezone=True), - server_default=sa.text("now()"), - nullable=False, - ), - sa.Column( - "date_fin", - sa.DateTime(timezone=True), - server_default=sa.text("now()"), - nullable=False, - ), - sa.Column("moduleimpl_id", sa.Integer(), nullable=True), - sa.Column("etudid", sa.Integer(), nullable=False), - sa.Column("etat", sa.Integer(), nullable=False), - sa.ForeignKeyConstraint(["etudid"], ["identite.id"], ondelete="CASCADE"), - sa.ForeignKeyConstraint( - ["moduleimpl_id"], ["notes_moduleimpl.id"], ondelete="SET NULL" - ), - sa.PrimaryKeyConstraint("id"), - ) - op.create_index( - op.f("ix_assiduites_etudid"), "assiduites", ["etudid"], unique=False - ) - # ### end Alembic commands ### - - -def downgrade(): - # ### commands auto generated by Alembic - please adjust! ### - op.drop_index(op.f("ix_assiduites_etudid"), table_name="assiduites") - op.drop_table("assiduites") - op.drop_index(op.f("ix_justificatifs_etudid"), table_name="justificatifs") - op.drop_table("justificatifs") - # ### end Alembic commands ### diff --git a/migrations/versions/685fe5c55439_ajout_modeles_assiduites_justificatifs.py b/migrations/versions/685fe5c55439_ajout_modeles_assiduites_justificatifs.py deleted file mode 100644 index 02ae24488..000000000 --- a/migrations/versions/685fe5c55439_ajout_modeles_assiduites_justificatifs.py +++ /dev/null @@ -1,82 +0,0 @@ -"""Ajout Modeles Assiduites Justificatifs - -Revision ID: 685fe5c55439 -Revises: 3c12f5850cff -Create Date: 2022-12-26 09:00:54.750859 - -""" -from alembic import op -import sqlalchemy as sa - - -# revision identifiers, used by Alembic. -revision = "685fe5c55439" -down_revision = "3c12f5850cff" -branch_labels = None -depends_on = None - - -def upgrade(): - # ### commands auto generated by Alembic - please adjust! ### - op.create_table( - "justificatifs", - sa.Column("justifid", sa.Integer(), nullable=False), - sa.Column( - "date_debut", - sa.DateTime(timezone=True), - server_default=sa.text("now()"), - nullable=False, - ), - sa.Column( - "date_fin", - sa.DateTime(timezone=True), - server_default=sa.text("now()"), - nullable=False, - ), - sa.Column("etudid", sa.Integer(), nullable=False), - sa.Column("etat", sa.Integer(), nullable=True), - sa.Column("raison", sa.Text(), nullable=True), - sa.Column("fichier", sa.Date(), nullable=True), - sa.ForeignKeyConstraint(["etudid"], ["identite.id"], ondelete="CASCADE"), - sa.PrimaryKeyConstraint("justifid"), - ) - op.create_index( - op.f("ix_justificatifs_etudid"), "justificatifs", ["etudid"], unique=False - ) - op.create_table( - "assiduites", - sa.Column("id", sa.Integer(), nullable=False), - sa.Column( - "date_debut", - sa.DateTime(timezone=True), - server_default=sa.text("now()"), - nullable=False, - ), - sa.Column( - "date_fin", - sa.DateTime(timezone=True), - server_default=sa.text("now()"), - nullable=False, - ), - sa.Column("moduleimpl_id", sa.Integer(), nullable=True), - sa.Column("etudid", sa.Integer(), nullable=False), - sa.Column("etat", sa.Integer(), nullable=False), - sa.ForeignKeyConstraint(["etudid"], ["identite.id"], ondelete="CASCADE"), - sa.ForeignKeyConstraint( - ["moduleimpl_id"], ["notes_moduleimpl.id"], ondelete="SET NULL" - ), - sa.PrimaryKeyConstraint("id"), - ) - op.create_index( - op.f("ix_assiduites_etudid"), "assiduites", ["etudid"], unique=False - ) - # ### end Alembic commands ### - - -def downgrade(): - # ### commands auto generated by Alembic - please adjust! ### - op.drop_index(op.f("ix_assiduites_etudid"), table_name="assiduites") - op.drop_table("assiduites") - op.drop_index(op.f("ix_justificatifs_etudid"), table_name="justificatifs") - op.drop_table("justificatifs") - # ### end Alembic commands ### diff --git a/migrations/versions/943eb2deb22e_modèle_assiduites_et_justificatifs.py b/migrations/versions/943eb2deb22e_modèle_assiduites_et_justificatifs.py new file mode 100644 index 000000000..f15db40b4 --- /dev/null +++ b/migrations/versions/943eb2deb22e_modèle_assiduites_et_justificatifs.py @@ -0,0 +1,55 @@ +"""Modèle Assiduites et Justificatifs + +Revision ID: 943eb2deb22e +Revises: 25e3ca6cc063 +Create Date: 2023-01-30 14:08:47.214916 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = '943eb2deb22e' +down_revision = '25e3ca6cc063' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('justificatifs', + sa.Column('justif_id', sa.Integer(), nullable=False), + sa.Column('date_debut', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False), + sa.Column('date_fin', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False), + sa.Column('etudid', sa.Integer(), nullable=False), + sa.Column('etat', sa.Integer(), nullable=True), + sa.Column('raison', sa.Text(), nullable=True), + sa.Column('fichier', sa.Text(), nullable=True), + sa.ForeignKeyConstraint(['etudid'], ['identite.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('justif_id') + ) + op.create_index(op.f('ix_justificatifs_etudid'), 'justificatifs', ['etudid'], unique=False) + op.create_table('assiduites', + sa.Column('id', sa.Integer(), nullable=False), + sa.Column('date_debut', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False), + sa.Column('date_fin', sa.DateTime(timezone=True), server_default=sa.text('now()'), nullable=False), + sa.Column('moduleimpl_id', sa.Integer(), nullable=True), + sa.Column('etudid', sa.Integer(), nullable=False), + sa.Column('etat', sa.Integer(), nullable=False), + sa.Column('desc', sa.Text(), nullable=True), + sa.ForeignKeyConstraint(['etudid'], ['identite.id'], ondelete='CASCADE'), + sa.ForeignKeyConstraint(['moduleimpl_id'], ['notes_moduleimpl.id'], ondelete='SET NULL'), + sa.PrimaryKeyConstraint('id') + ) + op.create_index(op.f('ix_assiduites_etudid'), 'assiduites', ['etudid'], unique=False) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_index(op.f('ix_assiduites_etudid'), table_name='assiduites') + op.drop_table('assiduites') + op.drop_index(op.f('ix_justificatifs_etudid'), table_name='justificatifs') + op.drop_table('justificatifs') + # ### end Alembic commands ### diff --git a/tests/api/test_api_assiduites.py b/tests/api/test_api_assiduites.py index 6af3a2656..05a8b45e2 100644 --- a/tests/api/test_api_assiduites.py +++ b/tests/api/test_api_assiduites.py @@ -21,6 +21,7 @@ ASSIDUITES_FIELDS = { "date_debut": str, "date_fin": str, "etat": str, + "desc": str, } CREATE_FIELD = {"assiduite_id": int} @@ -34,7 +35,7 @@ TO_REMOVE = [] def check_fields(data, fields=ASSIDUITES_FIELDS): assert set(data.keys()) == set(fields.keys()) for key in data: - if key == "moduleimpl_id": + if key in ("moduleimpl_id", "desc"): assert isinstance(data[key], fields[key]) or data[key] is None else: assert isinstance(data[key], fields[key]) @@ -62,7 +63,7 @@ def check_failure_post(path, headers, data, err=None): raise APIError("Le GET n'aurait pas du fonctionner") -def create_data(etat: str, day: str, module=None): +def create_data(etat: str, day: str, module: int = None, desc: str = None): data = { "date_debut": f"2022-01-{day}T08:00", "date_fin": f"2022-01-{day}T10:00", @@ -71,6 +72,8 @@ def create_data(etat: str, day: str, module=None): if module is not None: data["moduleimpl_id"] = module + if desc is not None: + data["desc"] = desc return data @@ -187,48 +190,53 @@ def test_route_count_formsemestre_assiduites(api_headers): def test_route_create(api_headers): - # -== Sans batch ==- + # -== Unique ==- # Bon fonctionnement data = create_data("present", "01") - res = POST_JSON(f"/assiduite/{ETUDID}/create", data, api_headers) - check_fields(res, CREATE_FIELD) - TO_REMOVE.append(res["assiduite_id"]) + res = POST_JSON(f"/assiduite/{ETUDID}/create", [data], api_headers) + check_fields(res, BATCH_FIELD) + assert len(res["success"]) == 1 - 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["assiduite_id"]) + TO_REMOVE.append(res["success"]["0"]["assiduite_id"]) + + data2 = create_data("absent", "02", MODULE, "desc") + res = POST_JSON(f"/assiduite/{ETUDID}/create", [data2], api_headers) + check_fields(res, BATCH_FIELD) + assert len(res["success"]) == 1 + + TO_REMOVE.append(res["success"]["0"]["assiduite_id"]) # Mauvais fonctionnement - check_failure_post(f"/assiduite/{FAUX}/create", api_headers, data) - check_failure_post( - f"/assiduite/{ETUDID}/create", - api_headers, - data, - 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="param 'moduleimpl_id': invalide", + check_failure_post(f"/assiduite/{FAUX}/create", api_headers, [data]) + + res = POST_JSON(f"/assiduite/{ETUDID}/create", [data], api_headers) + check_fields(res, BATCH_FIELD) + assert len(res["errors"]) == 1 + assert ( + res["errors"]["0"] + == "Duplication des assiduités (la période rentrée rentre en conflit avec une assiduité enregistrée)" ) - # -== Avec batch ==- + res = POST_JSON( + f"/assiduite/{ETUDID}/create", [create_data("absent", "03", FAUX)], api_headers + ) + check_fields(res, BATCH_FIELD) + assert len(res["errors"]) == 1 + assert res["errors"]["0"] == "param 'moduleimpl_id': invalide" + + # -== Multiple ==- # Bon Fonctionnement etats = ["present", "absent", "retard"] - data = { - "batch": [ - create_data(etats[d % 3], 10 + d, MODULE if d % 2 else None) - for d in range(randint(3, 5)) - ] - } + data = [ + create_data(etats[d % 3], 10 + d, MODULE if d % 2 else None) + for d in range(randint(3, 5)) + ] - res = POST_JSON(f"/assiduite/{ETUDID}/create/batch", data, api_headers) + res = POST_JSON(f"/assiduite/{ETUDID}/create", data, api_headers) check_fields(res, BATCH_FIELD) for dat in res["success"]: check_fields(res["success"][dat], CREATE_FIELD) @@ -236,16 +244,14 @@ def test_route_create(api_headers): # Mauvais Fonctionnement - data2 = { - "batch": [ - create_data("present", "01"), - create_data("present", "25", FAUX), - create_data("blabla", 26), - create_data("absent", 32), - ] - } + data2 = [ + create_data("present", "01"), + create_data("present", "25", FAUX), + create_data("blabla", 26), + create_data("absent", 32), + ] - res = POST_JSON(f"/assiduite/{ETUDID}/create/batch", data2, api_headers) + res = POST_JSON(f"/assiduite/{ETUDID}/create", data2, api_headers) check_fields(res, BATCH_FIELD) assert len(res["errors"]) == 4 @@ -286,43 +292,41 @@ def test_route_edit(api_headers): def test_route_delete(api_headers): - # -== Sans batch ==- + # -== Unique ==- # Bon fonctionnement - data = {"assiduite_id": TO_REMOVE[0]} + data = TO_REMOVE[0] - res = POST_JSON(f"/assiduite/delete", data, api_headers) - assert res == {"OK": True} + res = POST_JSON(f"/assiduite/delete", [data], api_headers) + check_fields(res, BATCH_FIELD) + for dat in res["success"]: + assert res["success"][dat] == {"OK": True} # Mauvais fonctionnement - check_failure_post( - f"/assiduite/delete", - api_headers, - {"assiduite_id": FAUX}, - err="Assiduite non existante", - ) - # -== Avec batch ==- + res = POST_JSON(f"/assiduite/delete", [data], api_headers) + check_fields(res, BATCH_FIELD) + assert len(res["errors"]) == 1 + + # -== Multiple ==- # Bon Fonctionnement - data = {"batch": TO_REMOVE[1:]} + data = TO_REMOVE[1:] - res = POST_JSON(f"/assiduite/delete/batch", data, api_headers) + res = POST_JSON(f"/assiduite/delete", data, api_headers) check_fields(res, BATCH_FIELD) for dat in res["success"]: assert res["success"][dat] == {"OK": True} # Mauvais Fonctionnement - data2 = { - "batch": [ - FAUX, - FAUX + 1, - FAUX + 2, - ] - } + data2 = [ + FAUX, + FAUX + 1, + FAUX + 2, + ] - res = POST_JSON(f"/assiduite/delete/batch", data2, api_headers) + res = POST_JSON(f"/assiduite/delete", data2, api_headers) check_fields(res, BATCH_FIELD) assert len(res["errors"]) == 3 diff --git a/tests/unit/test_assiduites.py b/tests/unit/test_assiduites.py index 0eb3ae884..c553a6a29 100644 --- a/tests/unit/test_assiduites.py +++ b/tests/unit/test_assiduites.py @@ -124,8 +124,6 @@ def editer_supprimer_assiduiter(etuds: list[Identite], moduleimpls: list[int]): - Vérification de la suppression des assiduitées """ - from sqlalchemy.exc import IntegrityError - ass1: Assiduite = etuds[0].assiduites.first() ass2: Assiduite = etuds[1].assiduites.first() ass3: Assiduite = etuds[2].assiduites.first() @@ -173,42 +171,53 @@ def ajouter_assiduites( "deb": "2022-09-03T08:00+01:00", "fin": "2022-09-03T10:00+01:00", "moduleimpl": None, + "desc": None, }, { "etat": scu.EtatAssiduite.PRESENT, "deb": "2023-01-03T08:00+01:00", "fin": "2023-01-03T10:00+01:00", "moduleimpl": moduleimpls[2], + "desc": None, }, { "etat": scu.EtatAssiduite.ABSENT, "deb": "2022-09-03T10:00:01+01:00", "fin": "2022-09-03T11:00+01:00", "moduleimpl": moduleimpls[0], + "desc": None, }, { "etat": scu.EtatAssiduite.ABSENT, "deb": "2022-09-03T14:00:00+01:00", "fin": "2022-09-03T15:00+01:00", "moduleimpl": moduleimpls[1], + "desc": "Description", }, { "etat": scu.EtatAssiduite.RETARD, "deb": "2023-01-03T11:00:01+01:00", "fin": "2023-01-03T12:00+01:00", "moduleimpl": moduleimpls[3], + "desc": None, }, { "etat": scu.EtatAssiduite.RETARD, "deb": "2023-01-04T11:00:01+01:00", "fin": "2023-01-04T12:00+01:00", "moduleimpl": moduleimpls[3], + "desc": "Description", }, ] assiduites = [ Assiduite.create_assiduite( - etud, ass["deb"], ass["fin"], ass["etat"], ass["moduleimpl"] + etud, + ass["deb"], + ass["fin"], + ass["etat"], + ass["moduleimpl"], + ass["desc"], ) for ass in obj_assiduites ] @@ -225,6 +234,7 @@ def ajouter_assiduites( "deb": "2023-01-04T11:00:01+01:00", "fin": "2023-01-04T12:00+01:00", "moduleimpl": moduleimpls[3], + "desc": "Description", } try: @@ -234,6 +244,7 @@ def ajouter_assiduites( test_assiduite["fin"], test_assiduite["etat"], test_assiduite["moduleimpl"], + test_assiduite["desc"], ) except ScoValueError as excp: assert ( @@ -247,6 +258,7 @@ def ajouter_assiduites( test_assiduite["fin"], test_assiduite["etat"], test_assiduite["moduleimpl"], + test_assiduite["desc"], ) except ScoValueError as excp: assert excp.args[0] == "L'étudiant n'est pas inscrit au moduleimpl"