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()
# - 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 = (

View File

@ -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

View File

@ -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)

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")
# 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:

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>'
% sem
)
if sem["etat"] != "1":
if not sem["etat"]:
H.append(" [verrouillé]")
else:
H.append(

View File

@ -991,7 +991,6 @@ def fill_etuds_info(etuds):
)
else:
etud["telephonemobilestr"] = ""
etud["debouche"] = etud["debouche"] or ""
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
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})

View File

@ -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

View File

@ -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:

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"])
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]

View File

@ -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>""" % (

View File

@ -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"]:

View File

@ -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]

View File

@ -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()

View File

@ -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:

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]
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(

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"])
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)

View File

@ -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

View File

@ -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)
) )
""",

View File

@ -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)

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()
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:

View File

@ -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(

View File

@ -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

View File

@ -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):

View File

@ -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:

View File

@ -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

View File

@ -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"),

View File

@ -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"

View File

@ -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":

View File

@ -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.")

View File

@ -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

View File

@ -0,0 +1 @@
#

View File

@ -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)

View File

@ -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."""

View File

@ -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]

View File

@ -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