Fix - test unitaires OK - bug saisie notes persistant

This commit is contained in:
Emmanuel Viennet 2021-08-21 12:23:00 +02:00
parent 3254093b95
commit 29b44ad5a4
7 changed files with 64 additions and 35 deletions

View File

@ -26,6 +26,8 @@ from app.scodoc.sco_roles_default import SCO_ROLES_DEFAULTS
import app.scodoc.sco_utils as scu
from app.scodoc import sco_etud # a deplacer dans scu
VALID_LOGIN_EXP = re.compile(r"^[a-zA-Z0-9@\\\-_\\\.]+$")
class User(UserMixin, db.Model):
"""ScoDoc users, handled by Flask / SQLAlchemy"""
@ -55,6 +57,9 @@ class User(UserMixin, db.Model):
def __init__(self, **kwargs):
self.roles = []
self.user_roles = []
# check login:
if kwargs.get("user_name") and not VALID_LOGIN_EXP.match(kwargs["user_name"]):
raise ValueError(f"invalid user_name: {kwargs['user_name']}")
super(User, self).__init__(**kwargs)
# Ajoute roles:
if (
@ -167,6 +172,8 @@ class User(UserMixin, db.Model):
self.user_name = data["user_name"]
if "password" in data:
self.set_password(data["password"])
if not VALID_LOGIN_EXP.match(self.user_name):
raise ValueError(f"invalid user_name: {self.user_name}")
# Roles: roles_string is "Ens_RT, Secr_RT, ..."
if "roles_string" in data:
self.user_roles = []

View File

@ -35,6 +35,7 @@ import datetime
import psycopg2
import flask
from flask import g, url_for
from flask_login import current_user
import app.scodoc.sco_utils as scu
@ -251,7 +252,11 @@ def do_evaluation_upload_xls(REQUEST):
M = sco_moduleimpl.do_moduleimpl_list(moduleimpl_id=E["moduleimpl_id"])[0]
mod = sco_edit_module.do_module_list(args={"module_id": M["module_id"]})[0]
mod["moduleimpl_id"] = M["moduleimpl_id"]
mod["url"] = "Notes/moduleimpl_status?moduleimpl_id=%(moduleimpl_id)s" % mod
mod["url"] = url_for(
"notes.moduleimpl_status",
scodoc_dept=g.scodoc_dept,
moduleimpl_id=mod["moduleimpl_id"],
)
sco_news.add(
typ=sco_news.NEWS_NOTE,
object=M["moduleimpl_id"],
@ -335,7 +340,11 @@ def do_evaluation_set_missing(evaluation_id, value, dialog_confirmed=False):
M = sco_moduleimpl.do_moduleimpl_list(moduleimpl_id=E["moduleimpl_id"])[0]
mod = sco_edit_module.do_module_list(args={"module_id": M["module_id"]})[0]
mod["moduleimpl_id"] = M["moduleimpl_id"]
mod["url"] = "Notes/moduleimpl_status?moduleimpl_id=%(moduleimpl_id)s" % mod
mod["url"] = url_for(
"notes.moduleimpl_status",
scodoc_dept=g.scodoc_dept,
moduleimpl_id=mod["moduleimpl_id"],
)
sco_news.add(
typ=sco_news.NEWS_NOTE,
object=M["moduleimpl_id"],
@ -344,15 +353,23 @@ def do_evaluation_set_missing(evaluation_id, value, dialog_confirmed=False):
)
return (
html_sco_header.sco_header()
+ """<h2>%d notes changées</h2>
<ul>
<li><a class="stdlink" href="saisie_notes?evaluation_id=%s">
Revenir au formulaire de saisie des notes</a></li>
<li><a class="stdlink" href="moduleimpl_status?moduleimpl_id=%s">
Tableau de bord du module</a></li>
</ul>
"""
% (nb_changed, evaluation_id, M["moduleimpl_id"])
+ f"""
<h2>{nb_changed} notes changées</h2>
<ul>
<li><a class="stdlink" href="{url_for("notes.saisie_notes",
scodoc_dept=g.scodoc_dept, evaluation_id=evaluation_id)
}">
Revenir au formulaire de saisie des notes</a>
</li>
<li><a class="stdlink" href="{
url_for(
"notes.moduleimpl_status",
scodoc_dept=g.scodoc_dept,
moduleimpl_id=M["moduleimpl_id"],
)}">Tableau de bord du module</a>
</li>
</ul>
"""
+ html_sco_header.sco_footer()
)
@ -930,14 +947,18 @@ def saisie_notes(evaluation_id, group_ids=[], REQUEST=None):
H.append("""</td></tr></table></div>""")
# Le formulaire de saisie des notes:
destination = "%s/Notes/moduleimpl_status?moduleimpl_id=%s" % (
scu.ScoURL(),
E["moduleimpl_id"],
destination = url_for(
"notes.moduleimpl_status",
scodoc_dept=g.scodoc_dept,
moduleimpl_id=E["moduleimpl_id"],
)
form = _form_saisie_notes(
E, M, groups_infos.group_ids, destination=destination, REQUEST=REQUEST
)
if form is None:
log(f"redirecting to {destination}")
stop
return flask.redirect(destination)
H.append(form)
#
@ -1044,9 +1065,8 @@ def _form_saisie_notes(E, M, group_ids, destination="", REQUEST=None):
# Decisions de jury existantes ?
decisions_jury = {etudid: has_existing_decision(M, E, etudid) for etudid in etudids}
nb_decisions = sum(
decisions_jury.values()
) # Nb de decisions de jury (pour les inscrits à l'évaluation)
# Nb de decisions de jury (pour les inscrits à l'évaluation):
nb_decisions = sum(decisions_jury.values())
etuds = _get_sorted_etuds(E, etudids, formsemestre_id)
@ -1155,6 +1175,7 @@ def _form_saisie_notes(E, M, group_ids, destination="", REQUEST=None):
)
)
#
breakpoint()
H = []
if nb_decisions > 0:
H.append(
@ -1212,7 +1233,11 @@ def save_note(etudid=None, evaluation_id=None, value=None, comment="", REQUEST=N
E = sco_evaluations.do_evaluation_list({"evaluation_id": evaluation_id})[0]
M = sco_moduleimpl.do_moduleimpl_list(moduleimpl_id=E["moduleimpl_id"])[0]
Mod = sco_edit_module.do_module_list(args={"module_id": M["module_id"]})[0]
Mod["url"] = "Notes/moduleimpl_status?moduleimpl_id=%(moduleimpl_id)s" % M
Mod["url"] = url_for(
"notes.moduleimpl_status",
scodoc_dept=g.scodoc_dept,
moduleimpl_id=M["moduleimpl_id"],
)
result = {"nbchanged": 0} # JSON
# Check access: admin, respformation, or responsable_id
if not sco_permissions_check.can_edit_notes(authuser, E["moduleimpl_id"]):

View File

@ -116,7 +116,7 @@ def create_user_form(REQUEST, user_name=None, edit=0):
is_super_admin = True
# Les rôles standards créés à l'initialisation de ScoDoc:
standard_roles = [Role.get_named_role(r) for r in (u"Ens", u"Secr", u"Admin")]
standard_roles = [Role.get_named_role(r) for r in ("Ens", "Secr", "Admin")]
# Rôles pouvant etre attribués aux utilisateurs via ce dialogue:
# si SuperAdmin, tous les rôles standards dans tous les départements
# sinon, les départements dans lesquels l'utilisateur a le droit

View File

@ -34,7 +34,6 @@ from app.scodoc import sco_moduleimpl
from app.scodoc import sco_saisie_notes
from app.scodoc import sco_synchro_etuds
from app.scodoc import sco_utils as scu
from app.scodoc.debug import REQUEST
from app.scodoc.notes_log import log
from app.scodoc.sco_exceptions import ScoValueError
@ -94,6 +93,7 @@ class ScoFake(object):
@logging_meth
def create_etud(
self,
cnx=None,
code_nip="",
nom="",
@ -128,7 +128,7 @@ class ScoFake(object):
nom = r_nom
if not prenom:
prenom = r_prenom
etud = sco_etud.create_etud(cnx, args=locals(), REQUEST=REQUEST)
etud = sco_etud.create_etud(cnx, args=locals())
inscription = "2020" # pylint: disable=possibly-unused-variable
sco_synchro_etuds.do_import_etud_admission(cnx, etud["etudid"], locals())
return etud
@ -262,7 +262,6 @@ class ScoFake(object):
etud["etudid"],
etat="I",
etape=etud.get("etape", None),
REQUEST=REQUEST,
method="test_inscrit_etudiant",
)
@ -280,7 +279,6 @@ class ScoFake(object):
publish_incomplete=None,
evaluation_type=None,
numero=None,
REQUEST=REQUEST,
):
args = locals()
del args["self"]
@ -423,5 +421,4 @@ class ScoFake(object):
code_etat=code_etat,
devenir=devenir,
assidu=assidu,
REQUEST=REQUEST,
)

View File

@ -309,7 +309,7 @@ def test_abs_basic(test_client):
# --- Création de billets
b1 = absences.AddBilletAbsence(
s begin="2021-01-22 00:00",
begin="2021-01-22 00:00",
end="2021-01-22 23:59",
etudid=etudid,
description="abs du 22",
@ -327,7 +327,7 @@ s begin="2021-01-22 00:00",
code_ine=etuds[0]["code_ine"],
)
li_bi = absences.listeBilletsEtud( etudid=etudid, format="json")
li_bi = absences.listeBilletsEtud(etudid=etudid, format="json")
assert isinstance(li_bi, str)
load_li_bi = json.loads(li_bi)

View File

@ -59,7 +59,7 @@ def test_preferences(test_client):
.value
)
# Compare valeurs
sco_val = prefs.get("abs_notification_mail_tmpl")
sco_val = prefs.get(None, "abs_notification_mail_tmpl")
assert orm_val.strip() == sco_val.strip()
# nb: I don't understand why SQLAlchemy strips the string ?!
@ -71,9 +71,9 @@ def test_preferences(test_client):
app.set_sco_dept("D2")
prefs2 = sco_preferences.get_base_preferences()
assert len(prefs2) == len(prefs)
prefs2.set("abs_notification_mail_tmpl", "toto")
assert prefs2.get("abs_notification_mail_tmpl") == "toto"
assert prefs.get("abs_notification_mail_tmpl") != "toto"
prefs2.set(None, "abs_notification_mail_tmpl", "toto")
assert prefs2.get(None, "abs_notification_mail_tmpl") == "toto"
assert prefs.get(None, "abs_notification_mail_tmpl") != "toto"
orm_val = (
ScoPreference.query.filter_by(dept_id=d.id, name="abs_notification_mail_tmpl")
.first()
@ -81,7 +81,7 @@ def test_preferences(test_client):
)
assert orm_val == "toto"
# --- Preferences d'un semestre
# rejoure ce test pour avoir un semestre créé
# rejoue ce test pour avoir un semestre créé
test_sco_basic.run_sco_basic()
sem = sco_formsemestre.do_formsemestre_list()[0]
formsemestre_id = sem["formsemestre_id"]

View File

@ -65,7 +65,7 @@ def test_users_roles(test_client):
dept = "XX"
perm = Permission.ScoAbsChange
perm2 = Permission.ScoView
u = User(user_name="un enseignant")
u = User(user_name="un_enseignant")
db.session.add(u)
assert not u.has_permission(perm, dept)
r = Role.get_named_role("Ens")
@ -73,7 +73,7 @@ def test_users_roles(test_client):
r = Role(name="Ens", permissions=perm)
u.add_role(r, dept)
assert u.has_permission(perm, dept)
u = User(user_name="un autre")
u = User(user_name="un_autre")
u.add_role(r, dept)
db.session.add(u)
db.session.commit()
@ -83,7 +83,7 @@ def test_users_roles(test_client):
r2 = Role(name="Secr", dept=dept, permissions=perm2)
u.add_roles([r, r2], dept)
assert len(u.roles) == 2
u = User(user_name="encore un")
u = User(user_name="encore_un")
db.session.add(u)
db.session.commit()
u.set_roles([r, r2], dept)
@ -99,7 +99,7 @@ def test_users_roles(test_client):
def test_user_admin(test_client):
dept = "XX"
perm = 0x1234 # a random perm
u = User(user_name="un admin", email=current_app.config["SCODOC_ADMIN_MAIL"])
u = User(user_name="un_admin", email=current_app.config["SCODOC_ADMIN_MAIL"])
db.session.add(u)
assert len(u.roles) == 1
assert u.has_permission(perm, dept)