From 4bf983dbe4731c6aed9c8a8d4cd4867374f99def Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Wed, 3 Nov 2021 16:15:39 +0100 Subject: [PATCH] Add unit test: test_notes_modules_att_dem (scenario "lyonnais") --- app/scodoc/sco_formsemestre_inscriptions.py | 38 ++++++- app/views/scolar.py | 37 ++----- tests/unit/test_notes_modules.py | 107 +++++++++++++++++++- 3 files changed, 152 insertions(+), 30 deletions(-) diff --git a/app/scodoc/sco_formsemestre_inscriptions.py b/app/scodoc/sco_formsemestre_inscriptions.py index bbfb81b953..20ffa7a907 100644 --- a/app/scodoc/sco_formsemestre_inscriptions.py +++ b/app/scodoc/sco_formsemestre_inscriptions.py @@ -35,7 +35,7 @@ from flask import url_for, g, request import app.scodoc.sco_utils as scu from app import log from app.scodoc.scolog import logdb -from app.scodoc.sco_exceptions import ScoValueError +from app.scodoc.sco_exceptions import ScoException, ScoValueError from app.scodoc.sco_permissions import Permission from app.scodoc.sco_codes_parcours import UE_STANDARD, UE_SPORT, UE_TYPE_NAME import app.scodoc.notesdb as ndb @@ -127,6 +127,42 @@ def do_formsemestre_inscription_delete(oid, formsemestre_id=None): ) # > desinscription du semestre +def do_formsemestre_demission( + etudid, + formsemestre_id, + event_date=None, + etat_new="D", # 'D' or DEF + operation_method="demEtudiant", + event_type="DEMISSION", +): + "Démission ou défaillance d'un étudiant" + # marque 'D' ou DEF dans l'inscription au semestre et ajoute + # un "evenement" scolarite + cnx = ndb.GetDBConnexion() + # check lock + sem = sco_formsemestre.get_formsemestre(formsemestre_id) + if not sem["etat"]: + raise ScoValueError("Modification impossible: semestre verrouille") + # + ins = do_formsemestre_inscription_list( + {"etudid": etudid, "formsemestre_id": formsemestre_id} + )[0] + if not ins: + raise ScoException("etudiant non inscrit ?!") + ins["etat"] = etat_new + do_formsemestre_inscription_edit(args=ins, formsemestre_id=formsemestre_id) + logdb(cnx, method=operation_method, etudid=etudid) + sco_etud.scolar_events_create( + cnx, + args={ + "etudid": etudid, + "event_date": event_date, + "formsemestre_id": formsemestre_id, + "event_type": event_type, + }, + ) + + def do_formsemestre_inscription_edit(args=None, formsemestre_id=None): "edit a formsemestre_inscription" cnx = ndb.GetDBConnexion() diff --git a/app/views/scolar.py b/app/views/scolar.py index 79e9d1986c..ee6b69693d 100644 --- a/app/views/scolar.py +++ b/app/views/scolar.py @@ -34,7 +34,7 @@ import os import time import flask -from flask import jsonify, url_for, flash, redirect, render_template, make_response +from flask import jsonify, url_for, flash, render_template, make_response from flask import current_app, g, request from flask_login import current_user from flask_wtf import FlaskForm @@ -215,7 +215,7 @@ def config_logos(scodoc_dept): ) app.clear_scodoc_cache() flash(f"Logos enregistrés") - return redirect(url_for("scolar.index_html", scodoc_dept=scodoc_dept)) + return flask.redirect(url_for("scolar.index_html", scodoc_dept=scodoc_dept)) return render_template( "configuration.html", @@ -1017,32 +1017,13 @@ def _do_dem_or_def_etud( redirect=True, ): "Démission ou défaillance d'un étudiant" - # marque 'D' ou DEF dans l'inscription au semestre et ajoute - # un "evenement" scolarite - cnx = ndb.GetDBConnexion() - # check lock - sem = sco_formsemestre.get_formsemestre(formsemestre_id) - if not sem["etat"]: - raise ScoValueError("Modification impossible: semestre verrouille") - # - ins = sco_formsemestre_inscriptions.do_formsemestre_inscription_list( - {"etudid": etudid, "formsemestre_id": formsemestre_id} - )[0] - if not ins: - raise ScoException("etudiant non inscrit ?!") - ins["etat"] = etat_new - sco_formsemestre_inscriptions.do_formsemestre_inscription_edit( - args=ins, formsemestre_id=formsemestre_id - ) - logdb(cnx, method=operation_method, etudid=etudid) - sco_etud.scolar_events_create( - cnx, - args={ - "etudid": etudid, - "event_date": event_date, - "formsemestre_id": formsemestre_id, - "event_type": event_type, - }, + sco_formsemestre_inscriptions.do_formsemestre_demission( + etudid, + formsemestre_id, + event_date=event_date, + etat_new=etat_new, # 'D' or DEF + operation_method=operation_method, + event_type=event_type, ) if redirect: return flask.redirect( diff --git a/tests/unit/test_notes_modules.py b/tests/unit/test_notes_modules.py index c997cfd15d..fbd7bdeeac 100644 --- a/tests/unit/test_notes_modules.py +++ b/tests/unit/test_notes_modules.py @@ -3,6 +3,7 @@ et aussi moyennes modules et UE internes (via nt) """ +from re import X from config import TestConfig from tests.unit import sco_fake_gen @@ -11,8 +12,10 @@ from flask import g import app from app.scodoc import sco_bulletins from app.scodoc import sco_cache +from app.scodoc import sco_formsemestre_inscriptions from app.scodoc import sco_moduleimpl from app.scodoc import sco_utils as scu +from app.views import scolar DEPT = TestConfig.DEPT_TEST @@ -40,6 +43,7 @@ def check_nt( if expected_sum_coefs_ue is not False: ue_status = nt.get_etud_ue_status(etudid, ue_id) assert expected_sum_coefs_ue == ue_status["sum_coefs"] + return nt def test_notes_modules(test_client): @@ -149,7 +153,7 @@ def test_notes_modules(test_client): moduleimpl_id, expected_mod_moy=0.0, expected_moy_ue=0.0, - expected_sum_coefs_ue=0.0, + expected_sum_coefs_ue=coef_mod_1, # absences, donc zéros et on garde le coef ) # Note excusée EXC <-> scu.NOTES_NEUTRALISE @@ -241,6 +245,7 @@ def test_notes_modules(test_client): expected_sum_coefs_ue=0.0, ) # --- Maintenant avec 2 modules dans l'UE + coef_mod_2 = 2.1 mod2 = G.create_module( matiere_id=mat["matiere_id"], code="TSM2", @@ -305,3 +310,103 @@ def test_notes_modules(test_client): ) assert b2["ues"][0]["ue_status"]["cur_moy_ue"] == 11.0 assert b2["ues"][0]["ue_status"]["moy"] == 11 + + +def test_notes_modules_att_dem(test_client): + """Scénario dit "lyonnais": + Des étudiants, des notes, plusieurs étudiants avec notes ATT (ici notes éval en "attente"), + démission d'un étudiant qui avait ATT. Passage des autres ATT en EXC ou ABS. + On va tester avec un module, une éval, deux étudiants + """ + app.set_sco_dept(DEPT) + + G = sco_fake_gen.ScoFake(verbose=False) + etuds = [G.create_etud(code_nip=None) for i in range(2)] # 2 étudiants + + f = G.create_formation(acronyme="") + ue = G.create_ue(formation_id=f["formation_id"], acronyme="TST1", titre="ue test") + ue_id = ue["ue_id"] + mat = G.create_matiere(ue_id=ue_id, titre="matière test") + coef_mod_1 = 1.5 + mod = G.create_module( + matiere_id=mat["matiere_id"], + code="TSM1", + coefficient=coef_mod_1, + titre="module test", + ue_id=ue["ue_id"], + formation_id=f["formation_id"], + ) + # + # -------------------------------- + # + sem = G.create_formsemestre( + formation_id=f["formation_id"], + semestre_id=1, + date_debut="01/01/2020", + date_fin="30/06/2020", + ) + formsemestre_id = sem["formsemestre_id"] + mi = G.create_moduleimpl( + module_id=mod["module_id"], + formsemestre_id=formsemestre_id, + ) + moduleimpl_id = mi["moduleimpl_id"] + # --- Inscription des étudiants + for etud in etuds: + G.inscrit_etudiant(sem, etud) + # --- Creation évaluation: e1 + coef_1 = 1.0 + e1 = G.create_evaluation( + moduleimpl_id=moduleimpl_id, + jour="01/01/2020", + description="evaluation 1", + coefficient=coef_1, + ) + # Attente (ATT) sur les 2 evals + _, _, _ = G.create_note(evaluation=e1, etud=etuds[0], note=scu.NOTES_ATTENTE) # ATT + _, _, _ = G.create_note(evaluation=e1, etud=etuds[1], note=scu.NOTES_ATTENTE) # ATT + # Démission du premier étudiant + sco_formsemestre_inscriptions.do_formsemestre_demission( + etuds[0]["etudid"], + sem["formsemestre_id"], + event_date="02/01/2020", + ) + b = sco_bulletins.formsemestre_bulletinetud_dict( + sem["formsemestre_id"], etuds[0]["etudid"] + ) + assert b["etud_etat"] == "D" + assert b["nb_demissions"] == 1 + assert b["ues"] == [] # inscrit à aucune UE ! + # bulletin de l'étudiant non demissionnaire: + b = sco_bulletins.formsemestre_bulletinetud_dict( + sem["formsemestre_id"], etuds[1]["etudid"] + ) + assert b["etud_etat"] == "I" + assert b["nb_demissions"] == 1 + assert len(b["ues"]) == 1 + nt = check_nt( + etuds[1]["etudid"], + sem["formsemestre_id"], + ue_id, + moduleimpl_id, + expected_mod_moy="NA0", + expected_moy_ue=0.0, + expected_sum_coefs_ue=0.0, + ) + note_e1 = nt.get_etud_eval_note(etuds[1]["etudid"], e1["evaluation_id"]) + assert note_e1["value"] == scu.NOTES_ATTENTE + note_e1 = nt.get_etud_eval_note(etuds[0]["etudid"], e1["evaluation_id"]) + assert note_e1["value"] == scu.NOTES_ATTENTE # XXXX un peu contestable + # Saisie note ABS pour le deuxième etud + _, _, _ = G.create_note(evaluation=e1, etud=etuds[1], note=None) # ABS + nt = check_nt( + etuds[1]["etudid"], + sem["formsemestre_id"], + ue_id, + moduleimpl_id, + expected_mod_moy=0.0, + expected_moy_ue=0.0, + expected_sum_coefs_ue=coef_mod_1, + ) + note_e1 = nt.get_etud_eval_note(etuds[1]["etudid"], e1["evaluation_id"]) + assert note_e1["value"] is None