forked from ScoDoc/DocScoDoc
pass unit test_sco_basic
This commit is contained in:
parent
642283c7d8
commit
068d2a659e
@ -187,6 +187,8 @@ def initialize_scodoc_database(erase=False):
|
||||
user_db_init()
|
||||
# - Insert some constant values (modalites, ...)
|
||||
sco_db_init()
|
||||
# - Flush cache
|
||||
clear_scodoc_cache()
|
||||
|
||||
|
||||
def truncate_database():
|
||||
@ -202,6 +204,18 @@ def truncate_database():
|
||||
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()
|
||||
# if admin_role:
|
||||
# admin = (
|
||||
|
@ -16,6 +16,8 @@ class Scolog(db.Model):
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
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
|
||||
authenticated_user = db.Column(db.Text) # login, sans contrainte
|
||||
# zope_remote_addr suppressed
|
||||
|
@ -1028,7 +1028,7 @@ def get_abs_count(etudid, sem):
|
||||
"""
|
||||
date_debut = sem["date_debut_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)
|
||||
if not r:
|
||||
nb_abs = count_abs( # was CountAbs XXX
|
||||
@ -1052,7 +1052,7 @@ def invalidate_abs_count(etudid, sem):
|
||||
"""Invalidate (clear) cached counts"""
|
||||
date_debut = sem["date_debut_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)
|
||||
|
||||
|
||||
|
@ -67,7 +67,7 @@ def index_html(context, REQUEST=None, showcodes=0, showsemtable=0):
|
||||
lockicon = scu.icontag("lock32_img", title="verrouillé", border="0")
|
||||
# Sélection sur l'etat du semestre
|
||||
for sem in sems:
|
||||
if sem["etat"] == "1" and sem["modalite"] != "EXT":
|
||||
if sem["etat"] and sem["modalite"] != "EXT":
|
||||
sem["lockimg"] = ""
|
||||
cursems.append(sem)
|
||||
else:
|
||||
|
@ -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>'
|
||||
% sem
|
||||
)
|
||||
if sem["etat"] != "1":
|
||||
if not sem["etat"]:
|
||||
H.append(" [verrouillé]")
|
||||
else:
|
||||
H.append(
|
||||
|
@ -991,7 +991,6 @@ def fill_etuds_info(etuds):
|
||||
)
|
||||
else:
|
||||
etud["telephonemobilestr"] = ""
|
||||
etud["debouche"] = etud["debouche"] or ""
|
||||
|
||||
|
||||
def descr_situation_etud(context, etudid, ne=""):
|
||||
|
@ -115,16 +115,16 @@ _evaluationEditor = ndb.EditableTable(
|
||||
sortkey="numero desc, jour desc, heure_debut desc", # plus recente d'abord
|
||||
output_formators={
|
||||
"jour": ndb.DateISOtoDMY,
|
||||
"visibulletin": str,
|
||||
"publish_incomplete": str,
|
||||
"visibulletin": bool,
|
||||
"publish_incomplete": bool,
|
||||
"numero": ndb.int_null_is_zero,
|
||||
},
|
||||
input_formators={
|
||||
"jour": ndb.DateDMYtoISO,
|
||||
"heure_debut": ndb.TimetoISO8601, # converti par do_evaluation_list
|
||||
"heure_fin": ndb.TimetoISO8601, # converti par do_evaluation_list
|
||||
"visibulletin": int,
|
||||
"publish_incomplete": int,
|
||||
"visibulletin": bool,
|
||||
"publish_incomplete": bool,
|
||||
},
|
||||
)
|
||||
|
||||
@ -602,7 +602,12 @@ def do_evaluation_list_in_sem(formsemestre_id, with_etat=True):
|
||||
'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()
|
||||
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
|
||||
cursor.execute(req, {"formsemestre_id": formsemestre_id})
|
||||
|
@ -69,18 +69,18 @@ _formsemestreEditor = ndb.EditableTable(
|
||||
output_formators={
|
||||
"date_debut": ndb.DateISOtoDMY,
|
||||
"date_fin": ndb.DateISOtoDMY,
|
||||
"gestion_compensation": str,
|
||||
"gestion_semestrielle": str,
|
||||
"gestion_compensation": bool,
|
||||
"gestion_semestrielle": bool,
|
||||
"etat": bool,
|
||||
"bul_hide_xml": str,
|
||||
"bul_hide_xml": bool,
|
||||
},
|
||||
input_formators={
|
||||
"date_debut": ndb.DateDMYtoISO,
|
||||
"date_fin": ndb.DateDMYtoISO,
|
||||
"gestion_compensation": int,
|
||||
"gestion_semestrielle": int,
|
||||
"gestion_compensation": bool,
|
||||
"gestion_semestrielle": bool,
|
||||
"etat": bool,
|
||||
"bul_hide_xml": int,
|
||||
"bul_hide_xml": bool,
|
||||
},
|
||||
)
|
||||
|
||||
@ -480,7 +480,7 @@ def scodoc_get_all_unlocked_sems(context):
|
||||
semdepts += [
|
||||
(sem, dept.Scolarite.Notes)
|
||||
for sem in do_formsemestre_list(dept.Scolarite.Notes)
|
||||
if sem["etat"] == "1"
|
||||
if sem["etat"]
|
||||
]
|
||||
return semdepts
|
||||
|
||||
|
@ -99,7 +99,7 @@ def formsemestre_editwithmodules(context, REQUEST, formsemestre_id):
|
||||
bodyOnLoad="init_tf_form('')",
|
||||
)
|
||||
]
|
||||
if sem["etat"] != "1":
|
||||
if not sem["etat"]:
|
||||
H.append(
|
||||
"""<p>%s<b>Ce semestre est verrouillé.</b></p>"""
|
||||
% scu.icontag("lock_img", border="0", title="Semestre verrouillé")
|
||||
@ -1483,7 +1483,7 @@ def formsemestre_change_lock(
|
||||
if not ok:
|
||||
return err
|
||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||
etat = 1 - int(sem["etat"])
|
||||
etat = not sem["etat"]
|
||||
|
||||
if REQUEST and not dialog_confirmed:
|
||||
if etat:
|
||||
@ -1500,11 +1500,9 @@ def formsemestre_change_lock(
|
||||
""",
|
||||
dest_url="",
|
||||
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}
|
||||
sco_formsemestre.do_formsemestre_edit(context, args)
|
||||
if REQUEST:
|
||||
|
@ -87,7 +87,7 @@ def do_formsemestre_inscription_create(context, args, REQUEST, method=None):
|
||||
raise ScoValueError("code de semestre invalide: %s" % args["formsemestre_id"])
|
||||
sem = sems[0]
|
||||
# check lock
|
||||
if sem["etat"] != "1":
|
||||
if not sem["etat"]:
|
||||
raise ScoValueError("inscription: semestre verrouille")
|
||||
#
|
||||
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)
|
||||
# -- check lock
|
||||
if sem["etat"] != "1":
|
||||
if not sem["etat"]:
|
||||
raise ScoValueError("desinscription impossible: semestre verrouille")
|
||||
|
||||
# -- 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):
|
||||
"""Dialogue pour (dés)inscription à des modules optionnels."""
|
||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||
if sem["etat"] != "1":
|
||||
if not sem["etat"]:
|
||||
raise ScoValueError("Modification impossible: semestre verrouille")
|
||||
|
||||
etud = sco_etud.get_etud_info(etudid=etudid, filled=1)[0]
|
||||
|
@ -163,7 +163,7 @@ def formsemestre_status_menubar(context, sem):
|
||||
and sem["resp_can_edit"]
|
||||
)
|
||||
)
|
||||
and (sem["etat"] == "1"),
|
||||
and (sem["etat"]),
|
||||
"helpmsg": "Modifie le contenu du semestre (modules)",
|
||||
},
|
||||
{
|
||||
@ -177,7 +177,7 @@ def formsemestre_status_menubar(context, sem):
|
||||
and sem["resp_can_edit"]
|
||||
)
|
||||
)
|
||||
and (sem["etat"] == "1"),
|
||||
and (sem["etat"]),
|
||||
"helpmsg": "Préférences du semestre",
|
||||
},
|
||||
{
|
||||
@ -229,7 +229,7 @@ def formsemestre_status_menubar(context, sem):
|
||||
"endpoint": "notes.formsemestre_associate_new_version",
|
||||
"args": {"formsemestre_id": formsemestre_id},
|
||||
"enabled": current_user.has_permission(Permission.ScoChangeFormation)
|
||||
and (sem["etat"] == "1"),
|
||||
and (sem["etat"]),
|
||||
"helpmsg": "",
|
||||
},
|
||||
{
|
||||
@ -264,7 +264,7 @@ def formsemestre_status_menubar(context, sem):
|
||||
"endpoint": "notes.formsemestre_inscr_passage",
|
||||
"args": {"formsemestre_id": formsemestre_id},
|
||||
"enabled": current_user.has_permission(Permission.ScoEtudInscrit)
|
||||
and (sem["etat"] == "1"),
|
||||
and (sem["etat"]),
|
||||
},
|
||||
{
|
||||
"title": "Synchroniser avec étape Apogée",
|
||||
@ -272,21 +272,21 @@ def formsemestre_status_menubar(context, sem):
|
||||
"args": {"formsemestre_id": formsemestre_id},
|
||||
"enabled": current_user.has_permission(Permission.ScoView)
|
||||
and sco_preferences.get_preference("portal_url")
|
||||
and (sem["etat"] == "1"),
|
||||
and (sem["etat"]),
|
||||
},
|
||||
{
|
||||
"title": "Inscrire un étudiant",
|
||||
"endpoint": "notes.formsemestre_inscription_with_modules_etud",
|
||||
"args": {"formsemestre_id": formsemestre_id},
|
||||
"enabled": current_user.has_permission(Permission.ScoEtudInscrit)
|
||||
and (sem["etat"] == "1"),
|
||||
and (sem["etat"]),
|
||||
},
|
||||
{
|
||||
"title": "Importer des étudiants dans ce semestre (table Excel)",
|
||||
"endpoint": "scolar.form_students_import_excel",
|
||||
"args": {"formsemestre_id": formsemestre_id},
|
||||
"enabled": current_user.has_permission(Permission.ScoEtudInscrit)
|
||||
and (sem["etat"] == "1"),
|
||||
and (sem["etat"]),
|
||||
},
|
||||
{
|
||||
"title": "Import/export des données admission",
|
||||
@ -539,7 +539,7 @@ def fill_formsemestre(sem):
|
||||
notes_url = scu.NotesURL()
|
||||
sem["notes_url"] = notes_url
|
||||
formsemestre_id = sem["formsemestre_id"]
|
||||
if sem["etat"] != "1":
|
||||
if not sem["etat"]:
|
||||
sem[
|
||||
"locklink"
|
||||
] = """<a href="%s/formsemestre_change_lock?formsemestre_id=%s">%s</a>""" % (
|
||||
|
@ -102,7 +102,7 @@ def formsemestre_validation_etud_form(
|
||||
|
||||
etud = sco_etud.get_etud_info(etudid=etudid, filled=True)[0]
|
||||
Se = sco_parcours_dut.SituationEtudParcours(context, etud, formsemestre_id)
|
||||
if Se.sem["etat"] != "1":
|
||||
if not Se.sem["etat"]:
|
||||
raise ScoValueError("validation: semestre verrouille")
|
||||
|
||||
H = [
|
||||
@ -599,7 +599,7 @@ def formsemestre_recap_parcours_table(
|
||||
default_sem_info = '<span class="fontred">[sem. précédent]</span>'
|
||||
else:
|
||||
default_sem_info = ""
|
||||
if sem["etat"] != "1": # locked
|
||||
if not sem["etat"]: # locked
|
||||
lockicon = scu.icontag("lock32_img", title="verrouillé", border="0")
|
||||
default_sem_info += lockicon
|
||||
if sem["formation_code"] != Se.formation["formation_code"]:
|
||||
|
@ -453,10 +453,10 @@ def etud_add_group_infos(context, etud, sem, sep=" "):
|
||||
def get_etud_groups_in_partition(context, partition_id):
|
||||
"""Returns { etudid : group }, with all students in this partition"""
|
||||
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
|
||||
WHERE gd.partition_id = %(partition_id)s
|
||||
AND gm.group_id = gd.group_id
|
||||
AND gm.group_id = gd.id
|
||||
""",
|
||||
{"partition_id": partition_id},
|
||||
)
|
||||
@ -670,7 +670,7 @@ def setGroups(
|
||||
log("groupsToCreate=%s" % groupsToCreate)
|
||||
log("groupsToDelete=%s" % groupsToDelete)
|
||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||
if sem["etat"] != "1":
|
||||
if not sem["etat"]:
|
||||
raise AccessDenied("Modification impossible: semestre verrouillé")
|
||||
|
||||
groupsToDelete = [g for g in groupsToDelete.split(";") if g]
|
||||
@ -1410,7 +1410,12 @@ def do_evaluation_listeetuds_groups(
|
||||
req = (
|
||||
"SELECT distinct Im.etudid FROM "
|
||||
+ ", ".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:
|
||||
req += " and Isem.etat='I'"
|
||||
@ -1418,8 +1423,6 @@ def do_evaluation_listeetuds_groups(
|
||||
cnx = ndb.GetDBConnexion()
|
||||
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
|
||||
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()
|
||||
return [x[0] for x in res]
|
||||
|
||||
|
@ -285,7 +285,7 @@ def formsemestre_inscr_passage(
|
||||
inscrit_groupes = int(inscrit_groupes)
|
||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||
# -- check lock
|
||||
if sem["etat"] != "1":
|
||||
if not sem["etat"]:
|
||||
raise ScoValueError("opération impossible: semestre verrouille")
|
||||
header = html_sco_header.sco_header(page_title="Passage des étudiants")
|
||||
footer = html_sco_header.sco_footer()
|
||||
|
@ -182,7 +182,14 @@ def do_moduleimpl_inscription_list(
|
||||
|
||||
def do_moduleimpl_listeetuds(context, moduleimpl_id):
|
||||
"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()
|
||||
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
|
||||
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)
|
||||
SELECT %(moduleimpl_id)s, I.etudid
|
||||
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}
|
||||
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]
|
||||
# -- check lock
|
||||
sem = sco_formsemestre.get_formsemestre(context, M["formsemestre_id"])
|
||||
if sem["etat"] != "1":
|
||||
if not sem["etat"]:
|
||||
raise ScoValueError("Modification impossible: semestre verrouille")
|
||||
# -- check access
|
||||
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]
|
||||
# -- check lock
|
||||
sem = sco_formsemestre.get_formsemestre(context, M["formsemestre_id"])
|
||||
if sem["etat"] != "1":
|
||||
if not sem["etat"]:
|
||||
if raise_exc:
|
||||
raise ScoValueError("Modification impossible: semestre verrouille")
|
||||
else:
|
||||
|
@ -69,7 +69,7 @@ def moduleimpl_inscriptions_edit(
|
||||
mod = sco_edit_module.do_module_list(context, args={"module_id": M["module_id"]})[0]
|
||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||
# -- check lock
|
||||
if sem["etat"] != "1":
|
||||
if not sem["etat"]:
|
||||
raise ScoValueError("opération impossible: semestre verrouille")
|
||||
header = html_sco_header.sco_header(
|
||||
page_title="Inscription au module",
|
||||
@ -261,9 +261,7 @@ def moduleimpl_inscriptions_stats(context, formsemestre_id, REQUEST=None):
|
||||
context, formsemestre_id
|
||||
)
|
||||
|
||||
can_change = (
|
||||
authuser.has_permission(Permission.ScoEtudInscrit) and sem["etat"] == "1"
|
||||
)
|
||||
can_change = authuser.has_permission(Permission.ScoEtudInscrit) and sem["etat"]
|
||||
|
||||
# Liste des modules
|
||||
Mlist = sco_moduleimpl.do_moduleimpl_withmodule_list(
|
||||
|
@ -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"])
|
||||
else:
|
||||
H.append("""</td><td>""")
|
||||
if sem["etat"] != "1":
|
||||
if not sem["etat"]:
|
||||
H.append(scu.icontag("lock32_img", title="verrouillé"))
|
||||
H.append(
|
||||
"""</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
|
||||
top_table_links = ""
|
||||
if sem["etat"] == "1": # non verrouillé
|
||||
if sem["etat"]: # non verrouillé
|
||||
top_table_links = (
|
||||
"""<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>
|
||||
@ -610,9 +610,9 @@ def moduleimpl_status(context, moduleimpl_id=None, partition_id=None, REQUEST=No
|
||||
H.append("""</td></tr>""")
|
||||
|
||||
#
|
||||
if caneditevals or sem["etat"] != "1":
|
||||
if caneditevals or not sem["etat"]:
|
||||
H.append("""<tr><td colspan="8">""")
|
||||
if sem["etat"] != "1":
|
||||
if not sem["etat"]:
|
||||
H.append("""%s semestre verrouillé""" % scu.icontag("lock32_img"))
|
||||
else:
|
||||
H.append(top_table_links)
|
||||
|
@ -58,7 +58,7 @@ def _menuScolarite(context, authuser, sem, etudid):
|
||||
"""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.
|
||||
"""
|
||||
locked = sem["etat"] != "1"
|
||||
locked = not sem["etat"]
|
||||
if locked:
|
||||
lockicon = scu.icontag("lock32_img", title="verrouillé", border="0")
|
||||
return lockicon # no menu
|
||||
|
@ -779,8 +779,8 @@ _scolar_formsemestre_validation_editor = ndb.EditableTable(
|
||||
"semestre_id",
|
||||
"is_external",
|
||||
),
|
||||
output_formators={"event_date": ndb.DateISOtoDMY, "assidu": str},
|
||||
input_formators={"event_date": ndb.DateDMYtoISO, "assidu": int_or_null},
|
||||
output_formators={"event_date": ndb.DateISOtoDMY, "assidu": bool},
|
||||
input_formators={"event_date": ndb.DateDMYtoISO, "assidu": bool},
|
||||
)
|
||||
|
||||
scolar_formsemestre_validation_create = _scolar_formsemestre_validation_editor.create
|
||||
@ -949,7 +949,7 @@ def do_formsemestre_validate_ue(
|
||||
moy_ue=None,
|
||||
date=None,
|
||||
semestre_id=None,
|
||||
is_external=0,
|
||||
is_external=False,
|
||||
):
|
||||
"""Ajoute ou change validation UE"""
|
||||
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"""
|
||||
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
|
||||
cursor.execute(
|
||||
"""select mi.* from notes_moduleimpl mi, notes_modules mo, notes_ue ue, notes_moduleimpl_inscription i
|
||||
where i.etudid = %(etudid)s and i.moduleimpl_id=mi.moduleimpl_id
|
||||
"""SELECT mi.*
|
||||
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.module_id = mo.module_id
|
||||
and mi.module_id = mo.id
|
||||
and mo.ue_id = %(ue_id)s
|
||||
""",
|
||||
{"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()
|
||||
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
|
||||
cursor.execute(
|
||||
"""select distinct SFV.*, ue.ue_code from notes_ue ue, notes_formations nf, notes_formations nf2,
|
||||
scolar_formsemestre_validation SFV, notes_formsemestre sem
|
||||
"""select distinct SFV.*, ue.ue_code from notes_ue ue, notes_formations nf,
|
||||
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 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.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.semestre_id = %(semestre_id)s )
|
||||
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)
|
||||
) )
|
||||
""",
|
||||
|
@ -28,7 +28,7 @@ def can_edit_notes(authuser, moduleimpl_id, allow_ens=True):
|
||||
uid = str(authuser)
|
||||
M = sco_moduleimpl.do_moduleimpl_list(context, moduleimpl_id=moduleimpl_id)[0]
|
||||
sem = sco_formsemestre.get_formsemestre(context, M["formsemestre_id"])
|
||||
if sem["etat"] != "1":
|
||||
if not sem["etat"]:
|
||||
return False # semestre verrouillé
|
||||
|
||||
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
|
||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||
if sem["etat"] != "1":
|
||||
if not sem["etat"]:
|
||||
return False # semestre verrouillé
|
||||
|
||||
return is_chef_or_diretud(sem)
|
||||
|
@ -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()
|
||||
|
||||
|
||||
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
|
||||
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)
|
||||
Return number of changed notes
|
||||
"""
|
||||
uid = str(uid)
|
||||
now = psycopg2.Timestamp(
|
||||
*time.localtime()[:6]
|
||||
) # 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,
|
||||
"value": value,
|
||||
"comment": comment,
|
||||
"uid": uid,
|
||||
"uid": user.id,
|
||||
"date": now,
|
||||
}
|
||||
ndb.quote_dict(aa)
|
||||
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,
|
||||
)
|
||||
changed = True
|
||||
@ -511,7 +514,7 @@ def _notes_add(context, uid, evaluation_id, notes, comment=None, do_it=True):
|
||||
"value": value,
|
||||
"date": now,
|
||||
"comment": comment,
|
||||
"uid": uid,
|
||||
"uid": user.id,
|
||||
}
|
||||
ndb.quote_dict(aa)
|
||||
if value != scu.NOTES_SUPPRESS:
|
||||
|
@ -98,7 +98,7 @@ def formsemestre_synchro_etuds(
|
||||
submitted = False
|
||||
dialog_confirmed = False
|
||||
# -- check lock
|
||||
if sem["etat"] != "1":
|
||||
if not sem["etat"]:
|
||||
raise ScoValueError("opération impossible: semestre verrouille")
|
||||
if not sem["etapes"]:
|
||||
raise ScoValueError(
|
||||
|
@ -244,11 +244,18 @@ def _user_list(user_name):
|
||||
|
||||
def user_info(user_name=None, user=None):
|
||||
"""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.
|
||||
"""
|
||||
if user_name:
|
||||
info = _user_list(user_name)
|
||||
if user_name is not None:
|
||||
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:
|
||||
info = user.to_dict()
|
||||
user_name = user.user_name
|
||||
|
@ -318,9 +318,12 @@ BULLETINS_VERSIONS = ("short", "selectedevals", "long")
|
||||
|
||||
# Support for ScoDoc7 compatibility
|
||||
def get_dept_id():
|
||||
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)
|
||||
return g.scodoc_dept # en scodoc 8.1 #sco8
|
||||
|
||||
|
||||
# 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):
|
||||
|
@ -40,7 +40,6 @@ def logdb(cnx=None, method=None, etudid=None, msg=None, commit=True):
|
||||
|
||||
args = {
|
||||
"authenticated_user": current_user.user_name,
|
||||
"remote_addr": request.remote_addr,
|
||||
}
|
||||
|
||||
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.execute(
|
||||
"""INSERT INTO scolog
|
||||
(authenticated_user,remote_addr,method,etudid,msg)
|
||||
(authenticated_user,method,etudid,msg)
|
||||
VALUES
|
||||
(%(authenticated_user)s,%(remote_addr)s,%(method)s,%(etudid)s,%(msg)s)""",
|
||||
(%(authenticated_user)s,%(method)s,%(etudid)s,%(msg)s)""",
|
||||
args,
|
||||
)
|
||||
if commit:
|
||||
|
@ -1245,7 +1245,7 @@ def formsemestre_desinscription(
|
||||
"""
|
||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||
# -- check lock
|
||||
if sem["etat"] != "1":
|
||||
if not sem["etat"]:
|
||||
raise ScoValueError("desinscription impossible: semestre verrouille")
|
||||
|
||||
# -- Si décisions de jury, désinscription interdite
|
||||
|
@ -185,7 +185,7 @@ def formsemestre_edit_preferences(context, formsemestre_id, REQUEST):
|
||||
ok = (
|
||||
authuser.has_permission(Permission.ScoImplement)
|
||||
or ((str(authuser) in sem["responsables"]) and sem["resp_can_edit"])
|
||||
) and (sem["etat"] == "1")
|
||||
) and (sem["etat"])
|
||||
if ok:
|
||||
return sco_preferences.SemPreferences(formsemestre_id=formsemestre_id).edit(
|
||||
REQUEST=REQUEST
|
||||
@ -842,7 +842,7 @@ def _formDem_of_Def(
|
||||
"Formulaire démission ou défaillance Etudiant"
|
||||
etud = sco_etud.get_etud_info(etudid=etudid, filled=1, REQUEST=REQUEST)[0]
|
||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||
if sem["etat"] != "1":
|
||||
if not sem["etat"]:
|
||||
raise ScoValueError("Modification impossible: semestre verrouille")
|
||||
|
||||
etud["formsemestre_id"] = formsemestre_id
|
||||
@ -927,7 +927,7 @@ def _do_dem_or_def_etud(
|
||||
cnx = ndb.GetDBConnexion()
|
||||
# check lock
|
||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||
if sem["etat"] != "1":
|
||||
if not sem["etat"]:
|
||||
raise ScoValueError("Modification impossible: semestre verrouille")
|
||||
#
|
||||
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"
|
||||
# check lock
|
||||
sem = sco_formsemestre.get_formsemestre(context, formsemestre_id)
|
||||
if sem["etat"] != "1":
|
||||
if not sem["etat"]:
|
||||
raise ScoValueError("Modification impossible: semestre verrouille")
|
||||
# verif
|
||||
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:
|
||||
sem = None
|
||||
dest_url = scu.ScoURL()
|
||||
if sem and sem["etat"] != "1":
|
||||
if sem and not sem["etat"]:
|
||||
raise ScoValueError("Modification impossible: semestre verrouille")
|
||||
H = [
|
||||
html_sco_header.sco_header(page_title="Import etudiants"),
|
||||
|
@ -62,3 +62,4 @@ class TestConfig(DevConfig):
|
||||
os.environ.get("SCODOC_TEST_DATABASE_URI") or "postgresql:///SCODOC_TEST"
|
||||
)
|
||||
SERVER_NAME = "test.gr"
|
||||
DEPT_TEST = "TEST_" # nom du département, ne pas l'utiliser pour un "vrai"
|
||||
|
@ -28,9 +28,11 @@ PASSWORD = "XXX"
|
||||
if not CHECK_CERTIFICATE:
|
||||
urllib3.disable_warnings()
|
||||
|
||||
|
||||
class ScoError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def GET(s, path, errmsg=None):
|
||||
"""Get and returns as JSON"""
|
||||
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)
|
||||
for sem in sems:
|
||||
if sem["etat"] == "1":
|
||||
if sem["etat"]:
|
||||
break
|
||||
|
||||
if sem["etat"] == "0":
|
||||
|
10
scodoc.py
10
scodoc.py
@ -16,7 +16,9 @@ import sys
|
||||
import click
|
||||
import flask
|
||||
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 import models
|
||||
@ -199,9 +201,5 @@ def clear_cache(): # clear-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()
|
||||
clear_scodoc_cache()
|
||||
click.echo("Redis caches flushed.")
|
||||
|
@ -4,7 +4,8 @@ from flask import g
|
||||
from flask_login import login_user, logout_user, current_user
|
||||
|
||||
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.auth.models import User, Role, UserRole, Permission
|
||||
from app.scodoc import sco_bulletins_standard
|
||||
@ -40,14 +41,15 @@ def test_client():
|
||||
u = User(user_name="bach")
|
||||
if not "Admin" in {r.name for r in u.roles}:
|
||||
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.commit()
|
||||
ndb.set_sco_dept("TEST") # set db connection
|
||||
ndb.set_sco_dept(TestConfig.DEPT_TEST) # set db connection
|
||||
yield client
|
||||
# ndb.close_dept_connection()
|
||||
# Teardown:
|
||||
db.session.remove()
|
||||
clear_scodoc_cache()
|
||||
# db.drop_all()
|
||||
# => laisse la base en état (l'efface au début)
|
||||
# utile pour les tests en cours de développement
|
||||
|
1
tests/scenarios/__init__.py
Normal file
1
tests/scenarios/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
#
|
@ -22,6 +22,10 @@ context = None # #context
|
||||
|
||||
def test_scenario1(test_client):
|
||||
"""Applique "scenario 1"""
|
||||
run_scenario1()
|
||||
|
||||
|
||||
def run_scenario1():
|
||||
G = sco_fake_gen.ScoFake(verbose=False)
|
||||
|
||||
# Lecture fichier XML local:
|
||||
@ -56,6 +60,5 @@ def test_scenario1(test_client):
|
||||
mi = G.create_moduleimpl(
|
||||
module_id=mod["module_id"],
|
||||
formsemestre_id=sems[mod["semestre_id"] - 1]["formsemestre_id"],
|
||||
responsable_id="bach",
|
||||
)
|
||||
mods_imp.append(mi)
|
||||
|
@ -307,11 +307,13 @@ class ScoFake(object):
|
||||
etud=None,
|
||||
note=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(
|
||||
context,
|
||||
uid,
|
||||
user,
|
||||
evaluation["evaluation_id"],
|
||||
[(etud["etudid"], note)],
|
||||
comment=comment,
|
||||
@ -367,7 +369,7 @@ class ScoFake(object):
|
||||
date_fin="30/06/2020",
|
||||
nb_evaluations_per_module=1,
|
||||
titre=None,
|
||||
responsables=["bach"],
|
||||
responsables=None, # list of users ids
|
||||
modalite=None,
|
||||
):
|
||||
"""Création semestre, avec modules et évaluations."""
|
||||
|
@ -16,17 +16,20 @@ from app.scodoc import sco_cache
|
||||
from app.scodoc import sco_evaluations
|
||||
from app.scodoc import sco_formsemestre
|
||||
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
|
||||
|
||||
|
||||
def test_notes_table(test_client):
|
||||
"""Test construction et cache de NotesTable.
|
||||
Attention: utilise une base (departement) existante.
|
||||
"""
|
||||
"""Test construction et cache de NotesTable."""
|
||||
ndb.set_sco_dept(DEPT)
|
||||
assert g.scodoc_dept == DEPT
|
||||
# prépare le département avec quelques semestres:
|
||||
run_scenario1()
|
||||
#
|
||||
sems = sco_formsemestre.do_formsemestre_list(context)
|
||||
assert len(sems)
|
||||
sem = sems[0]
|
||||
|
@ -15,9 +15,9 @@ import random
|
||||
|
||||
from flask import g
|
||||
|
||||
from config import TestConfig
|
||||
from tests.unit import sco_fake_gen
|
||||
|
||||
from app import decorators
|
||||
from app.scodoc import notesdb as ndb
|
||||
from app.scodoc import sco_abs
|
||||
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
|
||||
|
||||
context = None # #context
|
||||
DEPT = TestConfig.DEPT_TEST
|
||||
|
||||
|
||||
def test_sco_basic(test_client):
|
||||
@ -37,9 +38,15 @@ def test_sco_basic(test_client):
|
||||
Création 10 étudiants, formation, semestre, inscription etudiant,
|
||||
creation 1 evaluation, saisie 10 notes.
|
||||
"""
|
||||
ndb.set_sco_dept("TEST00") # ce département doit exister !
|
||||
G = sco_fake_gen.ScoFake(verbose=False)
|
||||
G.verbose = True
|
||||
ndb.set_sco_dept(DEPT)
|
||||
run_sco_basic()
|
||||
|
||||
|
||||
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
|
||||
etuds = [G.create_etud(code_nip=None) for _ in range(10)]
|
||||
@ -53,8 +60,8 @@ def test_sco_basic(test_client):
|
||||
code="TSM1",
|
||||
coefficient=1.0,
|
||||
titre="module test",
|
||||
ue_id=ue["ue_id"], # faiblesse de l'API
|
||||
formation_id=f["formation_id"], # faiblesse de l'API
|
||||
ue_id=ue["ue_id"],
|
||||
formation_id=f["formation_id"],
|
||||
)
|
||||
|
||||
# --- Mise place d'un semestre
|
||||
@ -68,7 +75,6 @@ def test_sco_basic(test_client):
|
||||
mi = G.create_moduleimpl(
|
||||
module_id=mod["module_id"],
|
||||
formsemestre_id=sem["formsemestre_id"],
|
||||
responsable_id="bach",
|
||||
)
|
||||
|
||||
# --- Inscription des étudiants
|
||||
|
Loading…
Reference in New Issue
Block a user