1
0
forked from ScoDoc/ScoDoc

pass unit test_sco_basic

This commit is contained in:
Emmanuel Viennet 2021-08-10 12:57:38 +02:00
parent 642283c7d8
commit 068d2a659e
36 changed files with 177 additions and 118 deletions

View File

@ -187,6 +187,8 @@ def initialize_scodoc_database(erase=False):
user_db_init() user_db_init()
# - Insert some constant values (modalites, ...) # - Insert some constant values (modalites, ...)
sco_db_init() sco_db_init()
# - Flush cache
clear_scodoc_cache()
def truncate_database(): def truncate_database():
@ -202,6 +204,18 @@ def truncate_database():
raise raise
def clear_scodoc_cache():
"""Clear ScoDoc cache
This cache (currently Redis) is persistent between invocation
and it may be necessary to clear it during developement or tests.
"""
# attaque directement redis, court-circuite ScoDoc:
import redis
r = redis.Redis()
r.flushall()
# admin_role = Role.query.filter_by(name="SuperAdmin").first() # admin_role = Role.query.filter_by(name="SuperAdmin").first()
# if admin_role: # if admin_role:
# admin = ( # admin = (

View File

@ -16,6 +16,8 @@ class Scolog(db.Model):
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)
date = db.Column(db.DateTime(timezone=True), server_default=db.func.now()) date = db.Column(db.DateTime(timezone=True), server_default=db.func.now())
method = db.Column(db.Text)
msg = db.Column(db.Text)
etudid = db.Column(db.Integer) # sans contrainte pour garder logs après suppression etudid = db.Column(db.Integer) # sans contrainte pour garder logs après suppression
authenticated_user = db.Column(db.Text) # login, sans contrainte authenticated_user = db.Column(db.Text) # login, sans contrainte
# zope_remote_addr suppressed # zope_remote_addr suppressed

View File

@ -1028,7 +1028,7 @@ def get_abs_count(etudid, sem):
""" """
date_debut = sem["date_debut_iso"] date_debut = sem["date_debut_iso"]
date_fin = sem["date_fin_iso"] date_fin = sem["date_fin_iso"]
key = etudid + "_" + date_debut + "_" + date_fin key = str(etudid) + "_" + date_debut + "_" + date_fin
r = sco_cache.AbsSemEtudCache.get(key) r = sco_cache.AbsSemEtudCache.get(key)
if not r: if not r:
nb_abs = count_abs( # was CountAbs XXX nb_abs = count_abs( # was CountAbs XXX
@ -1052,7 +1052,7 @@ def invalidate_abs_count(etudid, sem):
"""Invalidate (clear) cached counts""" """Invalidate (clear) cached counts"""
date_debut = sem["date_debut_iso"] date_debut = sem["date_debut_iso"]
date_fin = sem["date_fin_iso"] date_fin = sem["date_fin_iso"]
key = etudid + "_" + date_debut + "_" + date_fin key = str(etudid) + "_" + date_debut + "_" + date_fin
sco_cache.AbsSemEtudCache.delete(key) sco_cache.AbsSemEtudCache.delete(key)

View File

@ -67,7 +67,7 @@ def index_html(context, REQUEST=None, showcodes=0, showsemtable=0):
lockicon = scu.icontag("lock32_img", title="verrouillé", border="0") lockicon = scu.icontag("lock32_img", title="verrouillé", border="0")
# Sélection sur l'etat du semestre # Sélection sur l'etat du semestre
for sem in sems: for sem in sems:
if sem["etat"] == "1" and sem["modalite"] != "EXT": if sem["etat"] and sem["modalite"] != "EXT":
sem["lockimg"] = "" sem["lockimg"] = ""
cursems.append(sem) cursems.append(sem)
else: else:

View File

@ -805,7 +805,7 @@ Si vous souhaitez modifier cette formation (par exemple pour y ajouter un module
'<li><a class="stdlink" href="formsemestre_status?formsemestre_id=%(formsemestre_id)s">%(titremois)s</a>' '<li><a class="stdlink" href="formsemestre_status?formsemestre_id=%(formsemestre_id)s">%(titremois)s</a>'
% sem % sem
) )
if sem["etat"] != "1": if not sem["etat"]:
H.append(" [verrouillé]") H.append(" [verrouillé]")
else: else:
H.append( H.append(

View File

@ -991,7 +991,6 @@ def fill_etuds_info(etuds):
) )
else: else:
etud["telephonemobilestr"] = "" etud["telephonemobilestr"] = ""
etud["debouche"] = etud["debouche"] or ""
def descr_situation_etud(context, etudid, ne=""): def descr_situation_etud(context, etudid, ne=""):

View File

@ -115,16 +115,16 @@ _evaluationEditor = ndb.EditableTable(
sortkey="numero desc, jour desc, heure_debut desc", # plus recente d'abord sortkey="numero desc, jour desc, heure_debut desc", # plus recente d'abord
output_formators={ output_formators={
"jour": ndb.DateISOtoDMY, "jour": ndb.DateISOtoDMY,
"visibulletin": str, "visibulletin": bool,
"publish_incomplete": str, "publish_incomplete": bool,
"numero": ndb.int_null_is_zero, "numero": ndb.int_null_is_zero,
}, },
input_formators={ input_formators={
"jour": ndb.DateDMYtoISO, "jour": ndb.DateDMYtoISO,
"heure_debut": ndb.TimetoISO8601, # converti par do_evaluation_list "heure_debut": ndb.TimetoISO8601, # converti par do_evaluation_list
"heure_fin": ndb.TimetoISO8601, # converti par do_evaluation_list "heure_fin": ndb.TimetoISO8601, # converti par do_evaluation_list
"visibulletin": int, "visibulletin": bool,
"publish_incomplete": int, "publish_incomplete": bool,
}, },
) )
@ -602,7 +602,12 @@ def do_evaluation_list_in_sem(formsemestre_id, with_etat=True):
'visibulletin': 1} ] 'visibulletin': 1} ]
""" """
req = "select E.* from notes_evaluation E, notes_moduleimpl MI where MI.formsemestre_id = %(formsemestre_id)s and MI.moduleimpl_id = E.moduleimpl_id order by moduleimpl_id, numero desc, jour desc, heure_debut desc" req = """SELECT E.id AS evaluation_id, E.*
FROM notes_evaluation E, notes_moduleimpl MI
WHERE MI.formsemestre_id = %(formsemestre_id)s
and MI.id = E.moduleimpl_id
ORDER BY MI.id, numero desc, jour desc, heure_debut DESC
"""
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor) cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
cursor.execute(req, {"formsemestre_id": formsemestre_id}) cursor.execute(req, {"formsemestre_id": formsemestre_id})

View File

@ -69,18 +69,18 @@ _formsemestreEditor = ndb.EditableTable(
output_formators={ output_formators={
"date_debut": ndb.DateISOtoDMY, "date_debut": ndb.DateISOtoDMY,
"date_fin": ndb.DateISOtoDMY, "date_fin": ndb.DateISOtoDMY,
"gestion_compensation": str, "gestion_compensation": bool,
"gestion_semestrielle": str, "gestion_semestrielle": bool,
"etat": bool, "etat": bool,
"bul_hide_xml": str, "bul_hide_xml": bool,
}, },
input_formators={ input_formators={
"date_debut": ndb.DateDMYtoISO, "date_debut": ndb.DateDMYtoISO,
"date_fin": ndb.DateDMYtoISO, "date_fin": ndb.DateDMYtoISO,
"gestion_compensation": int, "gestion_compensation": bool,
"gestion_semestrielle": int, "gestion_semestrielle": bool,
"etat": bool, "etat": bool,
"bul_hide_xml": int, "bul_hide_xml": bool,
}, },
) )
@ -480,7 +480,7 @@ def scodoc_get_all_unlocked_sems(context):
semdepts += [ semdepts += [
(sem, dept.Scolarite.Notes) (sem, dept.Scolarite.Notes)
for sem in do_formsemestre_list(dept.Scolarite.Notes) for sem in do_formsemestre_list(dept.Scolarite.Notes)
if sem["etat"] == "1" if sem["etat"]
] ]
return semdepts return semdepts

View File

@ -99,7 +99,7 @@ def formsemestre_editwithmodules(context, REQUEST, formsemestre_id):
bodyOnLoad="init_tf_form('')", bodyOnLoad="init_tf_form('')",
) )
] ]
if sem["etat"] != "1": if not sem["etat"]:
H.append( H.append(
"""<p>%s<b>Ce semestre est verrouillé.</b></p>""" """<p>%s<b>Ce semestre est verrouillé.</b></p>"""
% scu.icontag("lock_img", border="0", title="Semestre verrouillé") % scu.icontag("lock_img", border="0", title="Semestre verrouillé")
@ -1483,7 +1483,7 @@ def formsemestre_change_lock(
if not ok: if not ok:
return err return err
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
etat = 1 - int(sem["etat"]) etat = not sem["etat"]
if REQUEST and not dialog_confirmed: if REQUEST and not dialog_confirmed:
if etat: if etat:
@ -1500,11 +1500,9 @@ def formsemestre_change_lock(
""", """,
dest_url="", dest_url="",
cancel_url="formsemestre_status?formsemestre_id=%s" % formsemestre_id, cancel_url="formsemestre_status?formsemestre_id=%s" % formsemestre_id,
parameters={"etat": etat, "formsemestre_id": formsemestre_id}, parameters={"formsemestre_id": formsemestre_id},
) )
if etat not in (0, 1):
raise ScoValueError("formsemestre_lock: invalid value for etat (%s)" % etat)
args = {"formsemestre_id": formsemestre_id, "etat": etat} args = {"formsemestre_id": formsemestre_id, "etat": etat}
sco_formsemestre.do_formsemestre_edit(context, args) sco_formsemestre.do_formsemestre_edit(context, args)
if REQUEST: if REQUEST:

View File

@ -87,7 +87,7 @@ def do_formsemestre_inscription_create(context, args, REQUEST, method=None):
raise ScoValueError("code de semestre invalide: %s" % args["formsemestre_id"]) raise ScoValueError("code de semestre invalide: %s" % args["formsemestre_id"])
sem = sems[0] sem = sems[0]
# check lock # check lock
if sem["etat"] != "1": if not sem["etat"]:
raise ScoValueError("inscription: semestre verrouille") raise ScoValueError("inscription: semestre verrouille")
# #
r = _formsemestre_inscriptionEditor.create(cnx, args) r = _formsemestre_inscriptionEditor.create(cnx, args)
@ -143,7 +143,7 @@ def do_formsemestre_desinscription(context, etudid, formsemestre_id, REQUEST=Non
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
# -- check lock # -- check lock
if sem["etat"] != "1": if not sem["etat"]:
raise ScoValueError("desinscription impossible: semestre verrouille") raise ScoValueError("desinscription impossible: semestre verrouille")
# -- Si decisions de jury, desinscription interdite # -- Si decisions de jury, desinscription interdite
@ -444,7 +444,7 @@ def formsemestre_inscription_with_modules(
def formsemestre_inscription_option(context, etudid, formsemestre_id, REQUEST=None): def formsemestre_inscription_option(context, etudid, formsemestre_id, REQUEST=None):
"""Dialogue pour (dés)inscription à des modules optionnels.""" """Dialogue pour (dés)inscription à des modules optionnels."""
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
if sem["etat"] != "1": if not sem["etat"]:
raise ScoValueError("Modification impossible: semestre verrouille") raise ScoValueError("Modification impossible: semestre verrouille")
etud = sco_etud.get_etud_info(etudid=etudid, filled=1)[0] etud = sco_etud.get_etud_info(etudid=etudid, filled=1)[0]

View File

@ -163,7 +163,7 @@ def formsemestre_status_menubar(context, sem):
and sem["resp_can_edit"] and sem["resp_can_edit"]
) )
) )
and (sem["etat"] == "1"), and (sem["etat"]),
"helpmsg": "Modifie le contenu du semestre (modules)", "helpmsg": "Modifie le contenu du semestre (modules)",
}, },
{ {
@ -177,7 +177,7 @@ def formsemestre_status_menubar(context, sem):
and sem["resp_can_edit"] and sem["resp_can_edit"]
) )
) )
and (sem["etat"] == "1"), and (sem["etat"]),
"helpmsg": "Préférences du semestre", "helpmsg": "Préférences du semestre",
}, },
{ {
@ -229,7 +229,7 @@ def formsemestre_status_menubar(context, sem):
"endpoint": "notes.formsemestre_associate_new_version", "endpoint": "notes.formsemestre_associate_new_version",
"args": {"formsemestre_id": formsemestre_id}, "args": {"formsemestre_id": formsemestre_id},
"enabled": current_user.has_permission(Permission.ScoChangeFormation) "enabled": current_user.has_permission(Permission.ScoChangeFormation)
and (sem["etat"] == "1"), and (sem["etat"]),
"helpmsg": "", "helpmsg": "",
}, },
{ {
@ -264,7 +264,7 @@ def formsemestre_status_menubar(context, sem):
"endpoint": "notes.formsemestre_inscr_passage", "endpoint": "notes.formsemestre_inscr_passage",
"args": {"formsemestre_id": formsemestre_id}, "args": {"formsemestre_id": formsemestre_id},
"enabled": current_user.has_permission(Permission.ScoEtudInscrit) "enabled": current_user.has_permission(Permission.ScoEtudInscrit)
and (sem["etat"] == "1"), and (sem["etat"]),
}, },
{ {
"title": "Synchroniser avec étape Apogée", "title": "Synchroniser avec étape Apogée",
@ -272,21 +272,21 @@ def formsemestre_status_menubar(context, sem):
"args": {"formsemestre_id": formsemestre_id}, "args": {"formsemestre_id": formsemestre_id},
"enabled": current_user.has_permission(Permission.ScoView) "enabled": current_user.has_permission(Permission.ScoView)
and sco_preferences.get_preference("portal_url") and sco_preferences.get_preference("portal_url")
and (sem["etat"] == "1"), and (sem["etat"]),
}, },
{ {
"title": "Inscrire un étudiant", "title": "Inscrire un étudiant",
"endpoint": "notes.formsemestre_inscription_with_modules_etud", "endpoint": "notes.formsemestre_inscription_with_modules_etud",
"args": {"formsemestre_id": formsemestre_id}, "args": {"formsemestre_id": formsemestre_id},
"enabled": current_user.has_permission(Permission.ScoEtudInscrit) "enabled": current_user.has_permission(Permission.ScoEtudInscrit)
and (sem["etat"] == "1"), and (sem["etat"]),
}, },
{ {
"title": "Importer des étudiants dans ce semestre (table Excel)", "title": "Importer des étudiants dans ce semestre (table Excel)",
"endpoint": "scolar.form_students_import_excel", "endpoint": "scolar.form_students_import_excel",
"args": {"formsemestre_id": formsemestre_id}, "args": {"formsemestre_id": formsemestre_id},
"enabled": current_user.has_permission(Permission.ScoEtudInscrit) "enabled": current_user.has_permission(Permission.ScoEtudInscrit)
and (sem["etat"] == "1"), and (sem["etat"]),
}, },
{ {
"title": "Import/export des données admission", "title": "Import/export des données admission",
@ -539,7 +539,7 @@ def fill_formsemestre(sem):
notes_url = scu.NotesURL() notes_url = scu.NotesURL()
sem["notes_url"] = notes_url sem["notes_url"] = notes_url
formsemestre_id = sem["formsemestre_id"] formsemestre_id = sem["formsemestre_id"]
if sem["etat"] != "1": if not sem["etat"]:
sem[ sem[
"locklink" "locklink"
] = """<a href="%s/formsemestre_change_lock?formsemestre_id=%s">%s</a>""" % ( ] = """<a href="%s/formsemestre_change_lock?formsemestre_id=%s">%s</a>""" % (

View File

@ -102,7 +102,7 @@ def formsemestre_validation_etud_form(
etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0] etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
Se = sco_parcours_dut.SituationEtudParcours(context, etud, formsemestre_id) Se = sco_parcours_dut.SituationEtudParcours(context, etud, formsemestre_id)
if Se.sem["etat"] != "1": if not Se.sem["etat"]:
raise ScoValueError("validation: semestre verrouille") raise ScoValueError("validation: semestre verrouille")
H = [ H = [
@ -599,7 +599,7 @@ def formsemestre_recap_parcours_table(
default_sem_info = '<span class="fontred">[sem. précédent]</span>' default_sem_info = '<span class="fontred">[sem. précédent]</span>'
else: else:
default_sem_info = "" default_sem_info = ""
if sem["etat"] != "1": # locked if not sem["etat"]: # locked
lockicon = scu.icontag("lock32_img", title="verrouillé", border="0") lockicon = scu.icontag("lock32_img", title="verrouillé", border="0")
default_sem_info += lockicon default_sem_info += lockicon
if sem["formation_code"] != Se.formation["formation_code"]: if sem["formation_code"] != Se.formation["formation_code"]:

View File

@ -453,10 +453,10 @@ def etud_add_group_infos(context, etud, sem, sep=" "):
def get_etud_groups_in_partition(context, partition_id): def get_etud_groups_in_partition(context, partition_id):
"""Returns { etudid : group }, with all students in this partition""" """Returns { etudid : group }, with all students in this partition"""
infos = ndb.SimpleDictFetch( infos = ndb.SimpleDictFetch(
"""SELECT gd.id as group_id, gd.*, etudid """SELECT gd.id AS group_id, gd.*, etudid
FROM group_descr gd, group_membership gm FROM group_descr gd, group_membership gm
WHERE gd.partition_id = %(partition_id)s WHERE gd.partition_id = %(partition_id)s
AND gm.group_id = gd.group_id AND gm.group_id = gd.id
""", """,
{"partition_id": partition_id}, {"partition_id": partition_id},
) )
@ -670,7 +670,7 @@ def setGroups(
log("groupsToCreate=%s" % groupsToCreate) log("groupsToCreate=%s" % groupsToCreate)
log("groupsToDelete=%s" % groupsToDelete) log("groupsToDelete=%s" % groupsToDelete)
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
if sem["etat"] != "1": if not sem["etat"]:
raise AccessDenied("Modification impossible: semestre verrouillé") raise AccessDenied("Modification impossible: semestre verrouillé")
groupsToDelete = [g for g in groupsToDelete.split(";") if g] groupsToDelete = [g for g in groupsToDelete.split(";") if g]
@ -1410,7 +1410,12 @@ def do_evaluation_listeetuds_groups(
req = ( req = (
"SELECT distinct Im.etudid FROM " "SELECT distinct Im.etudid FROM "
+ ", ".join(fromtables) + ", ".join(fromtables)
+ " WHERE Isem.etudid=Im.etudid and Im.moduleimpl_id=M.moduleimpl_id and Isem.formsemestre_id=M.formsemestre_id and E.moduleimpl_id=M.moduleimpl_id and E.evaluation_id = %(evaluation_id)s" + """ WHERE Isem.etudid = Im.etudid
and Im.moduleimpl_id = M.id
and Isem.formsemestre_id = M.formsemestre_id
and E.moduleimpl_id = M.id
and E.id = %(evaluation_id)s
"""
) )
if not include_dems: if not include_dems:
req += " and Isem.etat='I'" req += " and Isem.etat='I'"
@ -1418,8 +1423,6 @@ def do_evaluation_listeetuds_groups(
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor) cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
cursor.execute(req, {"evaluation_id": evaluation_id}) cursor.execute(req, {"evaluation_id": evaluation_id})
# log('listeetuds_groups: getallstudents=%s groups=%s' % (getallstudents,groups))
# log('req=%s' % (req % { 'evaluation_id' : "'"+evaluation_id+"'" }))
res = cursor.fetchall() res = cursor.fetchall()
return [x[0] for x in res] return [x[0] for x in res]

View File

@ -285,7 +285,7 @@ def formsemestre_inscr_passage(
inscrit_groupes = int(inscrit_groupes) inscrit_groupes = int(inscrit_groupes)
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
# -- check lock # -- check lock
if sem["etat"] != "1": if not sem["etat"]:
raise ScoValueError("opération impossible: semestre verrouille") raise ScoValueError("opération impossible: semestre verrouille")
header = html_sco_header.sco_header(page_title="Passage des étudiants") header = html_sco_header.sco_header(page_title="Passage des étudiants")
footer = html_sco_header.sco_footer() footer = html_sco_header.sco_footer()

View File

@ -182,7 +182,14 @@ def do_moduleimpl_inscription_list(
def do_moduleimpl_listeetuds(context, moduleimpl_id): def do_moduleimpl_listeetuds(context, moduleimpl_id):
"retourne liste des etudids inscrits a ce module" "retourne liste des etudids inscrits a ce module"
req = "select distinct Im.etudid from notes_moduleimpl_inscription Im, notes_formsemestre_inscription Isem, notes_moduleimpl M where Isem.etudid=Im.etudid and Im.moduleimpl_id=M.moduleimpl_id and M.moduleimpl_id = %(moduleimpl_id)s" req = """SELECT DISTINCT Im.etudid
FROM notes_moduleimpl_inscription Im,
notes_formsemestre_inscription Isem,
notes_moduleimpl M
WHERE Isem.etudid = Im.etudid
and Im.moduleimpl_id = M.id
and M.id = %(moduleimpl_id)s
"""
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor) cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
cursor.execute(req, {"moduleimpl_id": moduleimpl_id}) cursor.execute(req, {"moduleimpl_id": moduleimpl_id})
@ -199,7 +206,8 @@ def do_moduleimpl_inscrit_tout_semestre(context, moduleimpl_id, formsemestre_id)
(moduleimpl_id, etudid) (moduleimpl_id, etudid)
SELECT %(moduleimpl_id)s, I.etudid SELECT %(moduleimpl_id)s, I.etudid
FROM notes_formsemestre_inscription I FROM notes_formsemestre_inscription I
WHERE I.formsemestre_id=%(formsemestre_id)s""" WHERE I.formsemestre_id=%(formsemestre_id)s
"""
args = {"moduleimpl_id": moduleimpl_id, "formsemestre_id": formsemestre_id} args = {"moduleimpl_id": moduleimpl_id, "formsemestre_id": formsemestre_id}
cursor.execute(req, args) cursor.execute(req, args)
@ -322,7 +330,7 @@ def can_change_module_resp(context, REQUEST, moduleimpl_id):
M = do_moduleimpl_withmodule_list(context, moduleimpl_id=moduleimpl_id)[0] M = do_moduleimpl_withmodule_list(context, moduleimpl_id=moduleimpl_id)[0]
# -- check lock # -- check lock
sem = sco_formsemestre.get_formsemestre(context, M["formsemestre_id"]) sem = sco_formsemestre.get_formsemestre(context, M["formsemestre_id"])
if sem["etat"] != "1": if not sem["etat"]:
raise ScoValueError("Modification impossible: semestre verrouille") raise ScoValueError("Modification impossible: semestre verrouille")
# -- check access # -- check access
authuser = REQUEST.AUTHENTICATED_USER authuser = REQUEST.AUTHENTICATED_USER
@ -340,7 +348,7 @@ def can_change_ens(context, REQUEST, moduleimpl_id, raise_exc=True):
M = do_moduleimpl_withmodule_list(context, moduleimpl_id=moduleimpl_id)[0] M = do_moduleimpl_withmodule_list(context, moduleimpl_id=moduleimpl_id)[0]
# -- check lock # -- check lock
sem = sco_formsemestre.get_formsemestre(context, M["formsemestre_id"]) sem = sco_formsemestre.get_formsemestre(context, M["formsemestre_id"])
if sem["etat"] != "1": if not sem["etat"]:
if raise_exc: if raise_exc:
raise ScoValueError("Modification impossible: semestre verrouille") raise ScoValueError("Modification impossible: semestre verrouille")
else: else:

View File

@ -69,7 +69,7 @@ def moduleimpl_inscriptions_edit(
mod = sco_edit_module.do_module_list(context, args={"module_id": M["module_id"]})[0] mod = sco_edit_module.do_module_list(context, args={"module_id": M["module_id"]})[0]
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
# -- check lock # -- check lock
if sem["etat"] != "1": if not sem["etat"]:
raise ScoValueError("opération impossible: semestre verrouille") raise ScoValueError("opération impossible: semestre verrouille")
header = html_sco_header.sco_header( header = html_sco_header.sco_header(
page_title="Inscription au module", page_title="Inscription au module",
@ -261,9 +261,7 @@ def moduleimpl_inscriptions_stats(context, formsemestre_id, REQUEST=None):
context, formsemestre_id context, formsemestre_id
) )
can_change = ( can_change = authuser.has_permission(Permission.ScoEtudInscrit) and sem["etat"]
authuser.has_permission(Permission.ScoEtudInscrit) and sem["etat"] == "1"
)
# Liste des modules # Liste des modules
Mlist = sco_moduleimpl.do_moduleimpl_withmodule_list( Mlist = sco_moduleimpl.do_moduleimpl_withmodule_list(

View File

@ -223,7 +223,7 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
H.append("""Semestre: </td><td>%s""" % sem["semestre_id"]) H.append("""Semestre: </td><td>%s""" % sem["semestre_id"])
else: else:
H.append("""</td><td>""") H.append("""</td><td>""")
if sem["etat"] != "1": if not sem["etat"]:
H.append(scu.icontag("lock32_img", title="verrouillé")) H.append(scu.icontag("lock32_img", title="verrouillé"))
H.append( H.append(
"""</td><td class="fichetitre2">Coef dans le semestre: %(coefficient)s</td><td></td></tr>""" """</td><td class="fichetitre2">Coef dans le semestre: %(coefficient)s</td><td></td></tr>"""
@ -345,7 +345,7 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
# -------- Tableau des evaluations # -------- Tableau des evaluations
top_table_links = "" top_table_links = ""
if sem["etat"] == "1": # non verrouillé if sem["etat"]: # non verrouillé
top_table_links = ( top_table_links = (
"""<a class="stdlink" href="evaluation_create?moduleimpl_id=%(moduleimpl_id)s">Créer nouvelle évaluation</a> """<a class="stdlink" href="evaluation_create?moduleimpl_id=%(moduleimpl_id)s">Créer nouvelle évaluation</a>
<a class="stdlink" style="margin-left:2em;" href="module_evaluation_renumber?moduleimpl_id=%(moduleimpl_id)s&redirect=1">Trier par date</a> <a class="stdlink" style="margin-left:2em;" href="module_evaluation_renumber?moduleimpl_id=%(moduleimpl_id)s&redirect=1">Trier par date</a>
@ -610,9 +610,9 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
H.append("""</td></tr>""") H.append("""</td></tr>""")
# #
if caneditevals or sem["etat"] != "1": if caneditevals or not sem["etat"]:
H.append("""<tr><td colspan="8">""") H.append("""<tr><td colspan="8">""")
if sem["etat"] != "1": if not sem["etat"]:
H.append("""%s semestre verrouillé""" % scu.icontag("lock32_img")) H.append("""%s semestre verrouillé""" % scu.icontag("lock32_img"))
else: else:
H.append(top_table_links) H.append(top_table_links)

View File

@ -58,7 +58,7 @@ def _menuScolarite(context, authuser, sem, etudid):
"""HTML pour menu "scolarite" pour un etudiant dans un semestre. """HTML pour menu "scolarite" pour un etudiant dans un semestre.
Le contenu du menu depend des droits de l'utilisateur et de l'état de l'étudiant. Le contenu du menu depend des droits de l'utilisateur et de l'état de l'étudiant.
""" """
locked = sem["etat"] != "1" locked = not sem["etat"]
if locked: if locked:
lockicon = scu.icontag("lock32_img", title="verrouillé", border="0") lockicon = scu.icontag("lock32_img", title="verrouillé", border="0")
return lockicon # no menu return lockicon # no menu

View File

@ -779,8 +779,8 @@ _scolar_formsemestre_validation_editor = ndb.EditableTable(
"semestre_id", "semestre_id",
"is_external", "is_external",
), ),
output_formators={"event_date": ndb.DateISOtoDMY, "assidu": str}, output_formators={"event_date": ndb.DateISOtoDMY, "assidu": bool},
input_formators={"event_date": ndb.DateDMYtoISO, "assidu": int_or_null}, input_formators={"event_date": ndb.DateDMYtoISO, "assidu": bool},
) )
scolar_formsemestre_validation_create = _scolar_formsemestre_validation_editor.create scolar_formsemestre_validation_create = _scolar_formsemestre_validation_editor.create
@ -949,7 +949,7 @@ def do_formsemestre_validate_ue(
moy_ue=None, moy_ue=None,
date=None, date=None,
semestre_id=None, semestre_id=None,
is_external=0, is_external=False,
): ):
"""Ajoute ou change validation UE""" """Ajoute ou change validation UE"""
args = { args = {
@ -1003,10 +1003,12 @@ def etud_est_inscrit_ue(cnx, etudid, formsemestre_id, ue_id):
"""Vrai si l'étudiant est inscrit a au moins un module de cette UE dans ce semestre""" """Vrai si l'étudiant est inscrit a au moins un module de cette UE dans ce semestre"""
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor) cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
cursor.execute( cursor.execute(
"""select mi.* from notes_moduleimpl mi, notes_modules mo, notes_ue ue, notes_moduleimpl_inscription i """SELECT mi.*
where i.etudid = %(etudid)s and i.moduleimpl_id=mi.moduleimpl_id FROM notes_moduleimpl mi, notes_modules mo, notes_ue ue, notes_moduleimpl_inscription i
WHERE i.etudid = %(etudid)s
and i.moduleimpl_id=mi.id
and mi.formsemestre_id = %(formsemestre_id)s and mi.formsemestre_id = %(formsemestre_id)s
and mi.module_id = mo.module_id and mi.module_id = mo.id
and mo.ue_id = %(ue_id)s and mo.ue_id = %(ue_id)s
""", """,
{"etudid": etudid, "formsemestre_id": formsemestre_id, "ue_id": ue_id}, {"etudid": etudid, "formsemestre_id": formsemestre_id, "ue_id": ue_id},
@ -1053,22 +1055,22 @@ def formsemestre_get_etud_capitalisation(context, sem, etudid):
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor) cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
cursor.execute( cursor.execute(
"""select distinct SFV.*, ue.ue_code from notes_ue ue, notes_formations nf, notes_formations nf2, """select distinct SFV.*, ue.ue_code from notes_ue ue, notes_formations nf,
scolar_formsemestre_validation SFV, notes_formsemestre sem notes_formations nf2, scolar_formsemestre_validation SFV, notes_formsemestre sem
where ue.formation_id = nf.formation_id WHERE ue.formation_id = nf.id
and nf.formation_code = nf2.formation_code and nf.formation_code = nf2.formation_code
and nf2.formation_id=%(formation_id)s and nf2.id=%(formation_id)s
and SFV.ue_id = ue.ue_id and SFV.ue_id = ue.id
and SFV.code = 'ADM' and SFV.code = 'ADM'
and SFV.etudid = %(etudid)s and SFV.etudid = %(etudid)s
and ( (sem.formsemestre_id = SFV.formsemestre_id and ( (sem.id = SFV.formsemestre_id
and sem.date_debut < %(date_debut)s and sem.date_debut < %(date_debut)s
and sem.semestre_id = %(semestre_id)s ) and sem.semestre_id = %(semestre_id)s )
or ( or (
((SFV.formsemestre_id is NULL) OR (SFV.is_external = 1)) -- les UE externes ou "anterieures" ((SFV.formsemestre_id is NULL) OR (SFV.is_external)) -- les UE externes ou "anterieures"
AND (SFV.semestre_id is NULL OR SFV.semestre_id=%(semestre_id)s) AND (SFV.semestre_id is NULL OR SFV.semestre_id=%(semestre_id)s)
) ) ) )
""", """,

View File

@ -28,7 +28,7 @@ def can_edit_notes(authuser, moduleimpl_id, allow_ens=True):
uid = str(authuser) uid = str(authuser)
M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=moduleimpl_id)[0] M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=moduleimpl_id)[0]
sem = sco_formsemestre.get_formsemestre(context, M["formsemestre_id"]) sem = sco_formsemestre.get_formsemestre(context, M["formsemestre_id"])
if sem["etat"] != "1": if not sem["etat"]:
return False # semestre verrouillé return False # semestre verrouillé
if sco_parcours_dut.formsemestre_has_decisions(context, sem["formsemestre_id"]): if sco_parcours_dut.formsemestre_has_decisions(context, sem["formsemestre_id"]):
@ -111,7 +111,7 @@ def can_validate_sem(formsemestre_id):
context = None # XXX #context context = None # XXX #context
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
if sem["etat"] != "1": if not sem["etat"]:
return False # semestre verrouillé return False # semestre verrouillé
return is_chef_or_diretud(sem) return is_chef_or_diretud(sem)

View File

@ -429,7 +429,9 @@ def evaluation_suppress_alln(evaluation_id, dialog_confirmed=False):
return html_sco_header.sco_header() + "\n".join(H) + html_sco_header.sco_footer() return html_sco_header.sco_header() + "\n".join(H) + html_sco_header.sco_footer()
def _notes_add(context, uid, evaluation_id, notes, comment=None, do_it=True): def _notes_add(
context, user, evaluation_id: int, notes: list, comment=None, do_it=True
):
""" """
Insert or update notes Insert or update notes
notes is a list of tuples (etudid,value) notes is a list of tuples (etudid,value)
@ -439,7 +441,6 @@ def _notes_add(context, uid, evaluation_id, notes, comment=None, do_it=True):
- si la note existe deja avec valeur distincte, ajoute une entree au log (notes_notes_log) - si la note existe deja avec valeur distincte, ajoute une entree au log (notes_notes_log)
Return number of changed notes Return number of changed notes
""" """
uid = str(uid)
now = psycopg2.Timestamp( now = psycopg2.Timestamp(
*time.localtime()[:6] *time.localtime()[:6]
) # datetime.datetime.now().isoformat() ) # datetime.datetime.now().isoformat()
@ -478,12 +479,14 @@ def _notes_add(context, uid, evaluation_id, notes, comment=None, do_it=True):
"evaluation_id": evaluation_id, "evaluation_id": evaluation_id,
"value": value, "value": value,
"comment": comment, "comment": comment,
"uid": uid, "uid": user.id,
"date": now, "date": now,
} }
ndb.quote_dict(aa) ndb.quote_dict(aa)
cursor.execute( cursor.execute(
"insert into notes_notes (etudid,evaluation_id,value,comment,date,uid) values (%(etudid)s,%(evaluation_id)s,%(value)s,%(comment)s,%(date)s,%(uid)s)", """INSERT INTO notes_notes
(etudid,evaluation_id,value,comment,date,uid)
VALUES (%(etudid)s,%(evaluation_id)s,%(value)s,%(comment)s,%(date)s,%(uid)s)""",
aa, aa,
) )
changed = True changed = True
@ -511,7 +514,7 @@ def _notes_add(context, uid, evaluation_id, notes, comment=None, do_it=True):
"value": value, "value": value,
"date": now, "date": now,
"comment": comment, "comment": comment,
"uid": uid, "uid": user.id,
} }
ndb.quote_dict(aa) ndb.quote_dict(aa)
if value != scu.NOTES_SUPPRESS: if value != scu.NOTES_SUPPRESS:

View File

@ -98,7 +98,7 @@ def formsemestre_synchro_etuds(
submitted = False submitted = False
dialog_confirmed = False dialog_confirmed = False
# -- check lock # -- check lock
if sem["etat"] != "1": if not sem["etat"]:
raise ScoValueError("opération impossible: semestre verrouille") raise ScoValueError("opération impossible: semestre verrouille")
if not sem["etapes"]: if not sem["etapes"]:
raise ScoValueError( raise ScoValueError(

View File

@ -244,11 +244,18 @@ def _user_list(user_name):
def user_info(user_name=None, user=None): def user_info(user_name=None, user=None):
"""Dict avec infos sur l'utilisateur (qui peut ne pas etre dans notre base). """Dict avec infos sur l'utilisateur (qui peut ne pas etre dans notre base).
Si user_name est specifie, interroge la BD. Sinon, user doit etre une instance Si user_name est specifie (string ou id), interroge la BD. Sinon, user doit etre une instance
de User. de User.
""" """
if user_name: if user_name is not None:
info = _user_list(user_name) if isinstance(user_name, int):
u = User.query.filter_by(id=user_name).first()
else:
u = User.query.filter_by(user_name=user_name).first()
if u:
info = u.to_dict()
else:
info = None
else: else:
info = user.to_dict() info = user.to_dict()
user_name = user.user_name user_name = user.user_name

View File

@ -318,9 +318,12 @@ BULLETINS_VERSIONS = ("short", "selectedevals", "long")
# Support for ScoDoc7 compatibility # Support for ScoDoc7 compatibility
def get_dept_id(): def get_dept_id():
if g.scodoc_dept in sco_mgr.get_dept_ids(): return g.scodoc_dept # en scodoc 8.1 #sco8
return g.scodoc_dept
raise sco_exceptions.ScoInvalidDept("département invalide: %s" % g.scodoc_dept)
# if g.scodoc_dept in sco_mgr.get_dept_ids():
# return g.scodoc_dept
# raise sco_exceptions.ScoInvalidDept("département invalide: %s" % g.scodoc_dept)
def get_db_cnx_string(scodoc_dept=None): def get_db_cnx_string(scodoc_dept=None):

View File

@ -40,7 +40,6 @@ def logdb(cnx=None, method=None, etudid=None, msg=None, commit=True):
args = { args = {
"authenticated_user": current_user.user_name, "authenticated_user": current_user.user_name,
"remote_addr": request.remote_addr,
} }
args.update({"method": method, "etudid": etudid, "msg": msg}) args.update({"method": method, "etudid": etudid, "msg": msg})
@ -48,9 +47,9 @@ def logdb(cnx=None, method=None, etudid=None, msg=None, commit=True):
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor) cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
cursor.execute( cursor.execute(
"""INSERT INTO scolog """INSERT INTO scolog
(authenticated_user,remote_addr,method,etudid,msg) (authenticated_user,method,etudid,msg)
VALUES VALUES
(%(authenticated_user)s,%(remote_addr)s,%(method)s,%(etudid)s,%(msg)s)""", (%(authenticated_user)s,%(method)s,%(etudid)s,%(msg)s)""",
args, args,
) )
if commit: if commit:

View File

@ -1245,7 +1245,7 @@ def formsemestre_desinscription(
""" """
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
# -- check lock # -- check lock
if sem["etat"] != "1": if not sem["etat"]:
raise ScoValueError("desinscription impossible: semestre verrouille") raise ScoValueError("desinscription impossible: semestre verrouille")
# -- Si décisions de jury, désinscription interdite # -- Si décisions de jury, désinscription interdite

View File

@ -185,7 +185,7 @@ def formsemestre_edit_preferences(context, formsemestre_id, REQUEST):
ok = ( ok = (
authuser.has_permission(Permission.ScoImplement) authuser.has_permission(Permission.ScoImplement)
or ((str(authuser) in sem["responsables"]) and sem["resp_can_edit"]) or ((str(authuser) in sem["responsables"]) and sem["resp_can_edit"])
) and (sem["etat"] == "1") ) and (sem["etat"])
if ok: if ok:
return sco_preferences.SemPreferences(formsemestre_id=formsemestre_id).edit( return sco_preferences.SemPreferences(formsemestre_id=formsemestre_id).edit(
REQUEST=REQUEST REQUEST=REQUEST
@ -842,7 +842,7 @@ def _formDem_of_Def(
"Formulaire démission ou défaillance Etudiant" "Formulaire démission ou défaillance Etudiant"
etud = sco_etud.get_etud_info(etudid=etudid, filled=1, REQUEST=REQUEST)[0] etud = sco_etud.get_etud_info(etudid=etudid, filled=1, REQUEST=REQUEST)[0]
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
if sem["etat"] != "1": if not sem["etat"]:
raise ScoValueError("Modification impossible: semestre verrouille") raise ScoValueError("Modification impossible: semestre verrouille")
etud["formsemestre_id"] = formsemestre_id etud["formsemestre_id"] = formsemestre_id
@ -927,7 +927,7 @@ def _do_dem_or_def_etud(
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
# check lock # check lock
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
if sem["etat"] != "1": if not sem["etat"]:
raise ScoValueError("Modification impossible: semestre verrouille") raise ScoValueError("Modification impossible: semestre verrouille")
# #
ins = sco_formsemestre_inscriptions.do_formsemestre_inscription_list( ins = sco_formsemestre_inscriptions.do_formsemestre_inscription_list(
@ -1015,7 +1015,7 @@ def _do_cancel_dem_or_def(
"Annule une demission ou une défaillance" "Annule une demission ou une défaillance"
# check lock # check lock
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id) sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
if sem["etat"] != "1": if not sem["etat"]:
raise ScoValueError("Modification impossible: semestre verrouille") raise ScoValueError("Modification impossible: semestre verrouille")
# verif # verif
info = sco_etud.get_etud_info(etudid, filled=True)[0] info = sco_etud.get_etud_info(etudid, filled=True)[0]
@ -1712,7 +1712,7 @@ def form_students_import_excel(context, REQUEST, formsemestre_id=None):
else: else:
sem = None sem = None
dest_url = scu.ScoURL() dest_url = scu.ScoURL()
if sem and sem["etat"] != "1": if sem and not sem["etat"]:
raise ScoValueError("Modification impossible: semestre verrouille") raise ScoValueError("Modification impossible: semestre verrouille")
H = [ H = [
html_sco_header.sco_header(page_title="Import etudiants"), html_sco_header.sco_header(page_title="Import etudiants"),

View File

@ -62,3 +62,4 @@ class TestConfig(DevConfig):
os.environ.get("SCODOC_TEST_DATABASE_URI") or "postgresql:///SCODOC_TEST" os.environ.get("SCODOC_TEST_DATABASE_URI") or "postgresql:///SCODOC_TEST"
) )
SERVER_NAME = "test.gr" SERVER_NAME = "test.gr"
DEPT_TEST = "TEST_" # nom du département, ne pas l'utiliser pour un "vrai"

View File

@ -28,9 +28,11 @@ PASSWORD = "XXX"
if not CHECK_CERTIFICATE: if not CHECK_CERTIFICATE:
urllib3.disable_warnings() urllib3.disable_warnings()
class ScoError(Exception): class ScoError(Exception):
pass pass
def GET(s, path, errmsg=None): def GET(s, path, errmsg=None):
"""Get and returns as JSON""" """Get and returns as JSON"""
r = s.get(BASEURL + "/" + path) r = s.get(BASEURL + "/" + path)
@ -58,7 +60,7 @@ sems = GET(s, "Notes/formsemestre_list?format=json", "Aucun semestre !")
# sems est une liste de semestres (dictionnaires) # sems est une liste de semestres (dictionnaires)
for sem in sems: for sem in sems:
if sem["etat"] == "1": if sem["etat"]:
break break
if sem["etat"] == "0": if sem["etat"] == "0":

View File

@ -16,7 +16,9 @@ import sys
import click import click
import flask import flask
from flask.cli import with_appcontext from flask.cli import with_appcontext
from app import create_app, cli, db, initialize_scodoc_database from app import create_app, cli, db
from app import initialize_scodoc_database
from app import clear_scodoc_cache
from app.auth.models import User, Role, UserRole from app.auth.models import User, Role, UserRole
from app import models from app import models
@ -199,9 +201,5 @@ def clear_cache(): # clear-cache
This cache (currently Redis) is persistent between invocation This cache (currently Redis) is persistent between invocation
and it may be necessary to clear it during developement or tests. and it may be necessary to clear it during developement or tests.
""" """
# attaque directement redis, court-circuite ScoDoc: clear_scodoc_cache()
import redis
r = redis.Redis()
r.flushall()
click.echo("Redis caches flushed.") click.echo("Redis caches flushed.")

View File

@ -4,7 +4,8 @@ from flask import g
from flask_login import login_user, logout_user, current_user from flask_login import login_user, logout_user, current_user
from config import TestConfig from config import TestConfig
from app import db, create_app, initialize_scodoc_database from app import db, create_app
from app import initialize_scodoc_database, clear_scodoc_cache
from app import models from app import models
from app.auth.models import User, Role, UserRole, Permission from app.auth.models import User, Role, UserRole, Permission
from app.scodoc import sco_bulletins_standard from app.scodoc import sco_bulletins_standard
@ -40,14 +41,15 @@ def test_client():
u = User(user_name="bach") u = User(user_name="bach")
if not "Admin" in {r.name for r in u.roles}: if not "Admin" in {r.name for r in u.roles}:
admin_role = Role.query.filter_by(name="Admin").first() admin_role = Role.query.filter_by(name="Admin").first()
u.add_role(admin_role, "TEST00") u.add_role(admin_role, TestConfig.DEPT_TEST)
db.session.add(u) db.session.add(u)
db.session.commit() db.session.commit()
ndb.set_sco_dept("TEST") # set db connection ndb.set_sco_dept(TestConfig.DEPT_TEST) # set db connection
yield client yield client
# ndb.close_dept_connection() # ndb.close_dept_connection()
# Teardown: # Teardown:
db.session.remove() db.session.remove()
clear_scodoc_cache()
# db.drop_all() # db.drop_all()
# => laisse la base en état (l'efface au début) # => laisse la base en état (l'efface au début)
# utile pour les tests en cours de développement # utile pour les tests en cours de développement

View File

@ -0,0 +1 @@
#

View File

@ -22,6 +22,10 @@ context = None # #context
def test_scenario1(test_client): def test_scenario1(test_client):
"""Applique "scenario 1""" """Applique "scenario 1"""
run_scenario1()
def run_scenario1():
G = sco_fake_gen.ScoFake(verbose=False) G = sco_fake_gen.ScoFake(verbose=False)
# Lecture fichier XML local: # Lecture fichier XML local:
@ -56,6 +60,5 @@ def test_scenario1(test_client):
mi = G.create_moduleimpl( mi = G.create_moduleimpl(
module_id=mod["module_id"], module_id=mod["module_id"],
formsemestre_id=sems[mod["semestre_id"] - 1]["formsemestre_id"], formsemestre_id=sems[mod["semestre_id"] - 1]["formsemestre_id"],
responsable_id="bach",
) )
mods_imp.append(mi) mods_imp.append(mi)

View File

@ -307,11 +307,13 @@ class ScoFake(object):
etud=None, etud=None,
note=None, note=None,
comment=None, comment=None,
uid: typing.Optional[int] = None, user=None, # User instance
): ):
if user is None:
user = self.default_user
return sco_saisie_notes._notes_add( return sco_saisie_notes._notes_add(
context, context,
uid, user,
evaluation["evaluation_id"], evaluation["evaluation_id"],
[(etud["etudid"], note)], [(etud["etudid"], note)],
comment=comment, comment=comment,
@ -367,7 +369,7 @@ class ScoFake(object):
date_fin="30/06/2020", date_fin="30/06/2020",
nb_evaluations_per_module=1, nb_evaluations_per_module=1,
titre=None, titre=None,
responsables=["bach"], responsables=None, # list of users ids
modalite=None, modalite=None,
): ):
"""Création semestre, avec modules et évaluations.""" """Création semestre, avec modules et évaluations."""

View File

@ -16,17 +16,20 @@ from app.scodoc import sco_cache
from app.scodoc import sco_evaluations from app.scodoc import sco_evaluations
from app.scodoc import sco_formsemestre from app.scodoc import sco_formsemestre
from app.scodoc import notesdb as ndb from app.scodoc import notesdb as ndb
from config import TestConfig
DEPT = "RT" # ce département (BD) doit exister
DEPT = TestConfig.DEPT_TEST
context = None # #context context = None # #context
def test_notes_table(test_client): def test_notes_table(test_client):
"""Test construction et cache de NotesTable. """Test construction et cache de NotesTable."""
Attention: utilise une base (departement) existante.
"""
ndb.set_sco_dept(DEPT) ndb.set_sco_dept(DEPT)
assert g.scodoc_dept == DEPT assert g.scodoc_dept == DEPT
# prépare le département avec quelques semestres:
run_scenario1()
#
sems = sco_formsemestre.do_formsemestre_list(context) sems = sco_formsemestre.do_formsemestre_list(context)
assert len(sems) assert len(sems)
sem = sems[0] sem = sems[0]

View File

@ -15,9 +15,9 @@ import random
from flask import g from flask import g
from config import TestConfig
from tests.unit import sco_fake_gen from tests.unit import sco_fake_gen
from app import decorators
from app.scodoc import notesdb as ndb from app.scodoc import notesdb as ndb
from app.scodoc import sco_abs from app.scodoc import sco_abs
from app.scodoc import sco_abs_views from app.scodoc import sco_abs_views
@ -30,6 +30,7 @@ from app.scodoc import sco_saisie_notes
from app.scodoc import sco_utils as scu from app.scodoc import sco_utils as scu
context = None # #context context = None # #context
DEPT = TestConfig.DEPT_TEST
def test_sco_basic(test_client): def test_sco_basic(test_client):
@ -37,9 +38,15 @@ def test_sco_basic(test_client):
Création 10 étudiants, formation, semestre, inscription etudiant, Création 10 étudiants, formation, semestre, inscription etudiant,
creation 1 evaluation, saisie 10 notes. creation 1 evaluation, saisie 10 notes.
""" """
ndb.set_sco_dept("TEST00") # ce département doit exister ! ndb.set_sco_dept(DEPT)
G = sco_fake_gen.ScoFake(verbose=False) run_sco_basic()
G.verbose = True
def run_sco_basic(verbose=False):
"""Scénario de base: création formation, semestre, étudiants, notes,
décisions jury
"""
G = sco_fake_gen.ScoFake(verbose=verbose)
# --- Création d'étudiants # --- Création d'étudiants
etuds = [G.create_etud(code_nip=None) for _ in range(10)] etuds = [G.create_etud(code_nip=None) for _ in range(10)]
@ -53,8 +60,8 @@ def test_sco_basic(test_client):
code="TSM1", code="TSM1",
coefficient=1.0, coefficient=1.0,
titre="module test", titre="module test",
ue_id=ue["ue_id"], # faiblesse de l'API ue_id=ue["ue_id"],
formation_id=f["formation_id"], # faiblesse de l'API formation_id=f["formation_id"],
) )
# --- Mise place d'un semestre # --- Mise place d'un semestre
@ -68,7 +75,6 @@ def test_sco_basic(test_client):
mi = G.create_moduleimpl( mi = G.create_moduleimpl(
module_id=mod["module_id"], module_id=mod["module_id"],
formsemestre_id=sem["formsemestre_id"], formsemestre_id=sem["formsemestre_id"],
responsable_id="bach",
) )
# --- Inscription des étudiants # --- Inscription des étudiants