tests basiques pour ScoDoc8

This commit is contained in:
Emmanuel Viennet 2021-06-24 10:59:03 +02:00
parent 7c1263060e
commit 70f97c8501
5 changed files with 130 additions and 66 deletions

View File

@ -29,7 +29,7 @@ class ZUser(object):
def __str__(self): def __str__(self):
return self.username return self.username
def has_permission(self, perm, context): def has_permission(self, perm, dept=None):
"""check if this user as the permission `perm` """check if this user as the permission `perm`
in departement given by `g.scodoc_dept`. in departement given by `g.scodoc_dept`.
""" """
@ -42,7 +42,7 @@ class ZRequest(object):
def __init__(self): def __init__(self):
self.URL = request.base_url.encode( self.URL = request.base_url.encode(
"utf-8" "utf-8"
) # necessaire pour ScoDoc 8 en Python 2 ) # necessaire pour ScoDoc 8 en Python 2 #sco8
self.URL0 = self.URL self.URL0 = self.URL
self.BASE0 = request.url_root.encode("utf-8") self.BASE0 = request.url_root.encode("utf-8")
self.QUERY_STRING = request.query_string.encode("utf-8") self.QUERY_STRING = request.query_string.encode("utf-8")

View File

@ -98,7 +98,7 @@ class FakeUser:
def __str__(self): def __str__(self):
return self.name return self.name
def has_permission(self, op, dept): def has_permission(self, op, dept=None):
return True return True
def has_role(self, role): def has_role(self, role):

View File

@ -9,13 +9,15 @@
from __future__ import print_function from __future__ import print_function
import os
from pprint import pprint as pp from pprint import pprint as pp
import sys import sys
import click import click
import flask import flask
from flask.cli import with_appcontext
from app import create_app, cli, db from app import create_app, cli, db
from app.auth.models import User, Role, UserRole from app.auth.models import User, Role, UserRole
from app.views import notes, scolar, absences from app.views import notes, scolar, absences
@ -120,3 +122,47 @@ def user_password(username, password=None):
db.session.add(u) db.session.add(u)
db.session.commit() db.session.commit()
click.echo("changed password for user {}".format(u)) click.echo("changed password for user {}".format(u))
@app.cli.command()
@click.argument("dept")
def sco_delete_dept(dept):
"Delete existing departement"
if os.getuid() != 0:
sys.stderr.write("sco_delete_dept: must be run by root\n")
return 1
if os.system('cd config; ./delete_dept.sh -n "{}"'.format(dept)):
sys.stderr.write("error deleting dept " + dept)
return 1
return 0
@app.cli.command()
@click.argument("dept")
def sco_create_dept(dept):
"Create new departement"
if os.getuid() != 0:
sys.stderr.write("sco_create_dept: must be run by root\n")
return 1
if os.system('cd config; ./create_dept.sh -n "{}"'.format(dept)):
sys.stderr.write("error deleting dept " + dept)
return 1
return 0
@app.cli.command()
@click.argument("filename")
@with_appcontext
def test_interactive(filename=None):
"Run interactive test"
import flask_login
from app import decorators
click.echo("Executing {}".format(filename))
with app.test_request_context(""):
u = User.query.first()
flask_login.login_user(u)
REQUEST = decorators.ZRequest()
exec(open(filename).read())
click.echo("Done.")

View File

@ -16,29 +16,36 @@ import collections
import pprint import pprint
import random import random
import scodoc_manager
from app.scodoc import notesdb as ndb
from app.scodoc import sco_codes_parcours
from app.scodoc import sco_edit_formation
from app.scodoc import sco_edit_matiere
from app.scodoc import sco_edit_module
from app.scodoc import sco_edit_ue
from app.scodoc import sco_etud
from app.scodoc import sco_evaluations
from app.scodoc import sco_formations
from app.scodoc import sco_formsemestre
from app.scodoc import sco_formsemestre_inscriptions
from app.scodoc import sco_formsemestre_validation
from app.scodoc import sco_moduleimpl
from app.scodoc import sco_saisie_notes
from app.scodoc import sco_synchro_etuds
from app.scodoc import sco_utils as scu
from app.scodoc.debug import REQUEST
from app.scodoc.notes_log import log
from app.scodoc.sco_exceptions import ScoValueError
random.seed(12345) # tests reproductibles random.seed(12345) # tests reproductibles
from debug import REQUEST
import sco_utils DEMO_DIR = scu.SCO_SRC_DIR + "/scotests/demo/"
import notesdb as ndb
from notes_log import log
from sco_exceptions import ScoValueError
import scolars
import sco_formsemestre
import sco_formsemestre_inscriptions
import sco_formsemestre_validation
import sco_moduleimpl
import sco_synchro_etuds
import sco_edit_formation
import sco_edit_ue
import sco_codes_parcours
import sco_saisie_notes
DEMO_DIR = sco_utils.SCO_SRC_DIR + "/scotests/demo/"
NOMS = [x.strip() for x in open(DEMO_DIR + "/noms.txt").readlines()] NOMS = [x.strip() for x in open(DEMO_DIR + "/noms.txt").readlines()]
PRENOMS_H = [x.strip() for x in open(DEMO_DIR + "/prenoms-h.txt").readlines()] PRENOMS_H = [x.strip() for x in open(DEMO_DIR + "/prenoms-h.txt").readlines()]
PRENOMS_F = [x.strip() for x in open(DEMO_DIR + "/prenoms-f.txt").readlines()] PRENOMS_F = [x.strip() for x in open(DEMO_DIR + "/prenoms-f.txt").readlines()]
PRENOMS_X = [x.strip() for x in open(DEMO_DIR + "/prenoms-x.txt").readlines()]
# nb: en python2, les chaines ci-dessus sont en utf8 # nb: en python2, les chaines ci-dessus sont en utf8
@ -119,7 +126,7 @@ class ScoFake:
nom = r_nom nom = r_nom
if not prenom: if not prenom:
prenom = r_prenom prenom = r_prenom
etud = scolars.create_etud(self.context, cnx, args=locals(), REQUEST=REQUEST) etud = sco_etud.create_etud(self.context, cnx, args=locals(), REQUEST=REQUEST)
inscription = "2020" # pylint: disable=unused-variable inscription = "2020" # pylint: disable=unused-variable
sco_synchro_etuds.do_import_etud_admission( sco_synchro_etuds.do_import_etud_admission(
self.context, cnx, etud["etudid"], locals() self.context, cnx, etud["etudid"], locals()
@ -139,8 +146,10 @@ class ScoFake:
"""Crée une formation""" """Crée une formation"""
if not acronyme: if not acronyme:
acronyme = "TEST" + str(random.randint(100000, 999999)) acronyme = "TEST" + str(random.randint(100000, 999999))
oid = self.context.do_formation_create(locals(), REQUEST=REQUEST) oid = sco_edit_formation.do_formation_create(
oids = self.context.formation_list(args={"formation_id": oid}) self.context, locals(), REQUEST=REQUEST
)
oids = sco_formations.formation_list(self.context, formation_id=oid)
if not oids: if not oids:
raise ScoValueError("formation not created !") raise ScoValueError("formation not created !")
return oids[0] return oids[0]
@ -162,16 +171,16 @@ class ScoFake:
"""Crée une UE""" """Crée une UE"""
if numero is None: if numero is None:
numero = sco_edit_ue.next_ue_numero(self.context, formation_id, 0) numero = sco_edit_ue.next_ue_numero(self.context, formation_id, 0)
oid = self.context.do_ue_create(locals(), REQUEST) oid = sco_edit_ue.do_ue_create(self.context, locals(), REQUEST)
oids = self.context.do_ue_list(args={"ue_id": oid}) oids = sco_edit_ue.do_ue_list(self.context, args={"ue_id": oid})
if not oids: if not oids:
raise ScoValueError("ue not created !") raise ScoValueError("ue not created !")
return oids[0] return oids[0]
@logging_meth @logging_meth
def create_matiere(self, ue_id=None, titre=None, numero=None): def create_matiere(self, ue_id=None, titre=None, numero=None):
oid = self.context.do_matiere_create(locals(), REQUEST) oid = sco_edit_matiere.do_matiere_create(self.context, locals(), REQUEST)
oids = self.context.do_matiere_list(args={"matiere_id": oid}) oids = sco_edit_matiere.do_matiere_list(self.context, args={"matiere_id": oid})
if not oids: if not oids:
raise ScoValueError("matiere not created !") raise ScoValueError("matiere not created !")
return oids[0] return oids[0]
@ -195,8 +204,8 @@ class ScoFake:
code_apogee=None, code_apogee=None,
module_type=None, module_type=None,
): ):
oid = self.context.do_module_create(locals(), REQUEST) oid = sco_edit_module.do_module_create(self.context, locals(), REQUEST)
oids = self.context.do_module_list(args={"module_id": oid}) oids = sco_edit_module.do_module_list(self.context, args={"module_id": oid})
if not oids: if not oids:
raise ScoValueError("module not created ! (oid=%s)" % oid) raise ScoValueError("module not created ! (oid=%s)" % oid)
return oids[0] return oids[0]
@ -223,7 +232,7 @@ class ScoFake:
etapes=None, etapes=None,
responsables=["bach"], responsables=["bach"],
): ):
oid = self.context.do_formsemestre_create(locals(), REQUEST) oid = sco_formsemestre.do_formsemestre_create(self.context, locals(), REQUEST)
# oids = self.context.do_formsemestre_list(args={"formsemestre_id": oid}) # oids = self.context.do_formsemestre_list(args={"formsemestre_id": oid})
oids = sco_formsemestre.do_formsemestre_list( oids = sco_formsemestre.do_formsemestre_list(
self.context, args={"formsemestre_id": oid} self.context, args={"formsemestre_id": oid}
@ -277,8 +286,10 @@ class ScoFake:
): ):
args = locals() args = locals()
del args["self"] del args["self"]
oid = self.context.do_evaluation_create(**args) oid = sco_evaluations.do_evaluation_create(self.context, **args)
oids = self.context.do_evaluation_list(args={"evaluation_id": oid}) oids = sco_evaluations.do_evaluation_list(
self.context, args={"evaluation_id": oid}
)
if not oids: if not oids:
raise ScoValueError("evaluation not created !") raise ScoValueError("evaluation not created !")
return oids[0] return oids[0]
@ -418,3 +429,8 @@ class ScoFake:
assidu=assidu, assidu=assidu,
REQUEST=REQUEST, REQUEST=REQUEST,
) )
# band aid for #sco8 dev (temporaire en attendant Users)
class Sco8Context(object):
Users = scodoc_manager.FakeUsers()

View File

@ -6,26 +6,29 @@
Création 10 étudiants, formation, semestre, inscription etudiant, creation 1 evaluation, saisie 10 notes. Création 10 étudiants, formation, semestre, inscription etudiant, creation 1 evaluation, saisie 10 notes.
Utiliser comme: Utiliser comme:
scotests/scointeractive.sh -r TEST00 scotests/test_basic.py flask test-interactive scotests/test_basic.py
""" """
import random import random
# La variable context est définie par le script de lancement from flask import g
# l'affecte ainsi pour évietr les warnins pylint:
context = context # pylint: disable=undefined-variable
REQUEST = REQUEST # pylint: disable=undefined-variable
import scotests.sco_fake_gen as sco_fake_gen # pylint: disable=import-error
import sco_utils
import sco_abs
import sco_abs_views
import sco_bulletins
import sco_evaluations
import sco_codes_parcours
import sco_parcours_dut
import sco_formsemestre_validation
G = sco_fake_gen.ScoFake(context.Notes) from app import decorators
import scotests.sco_fake_gen as sco_fake_gen # pylint: disable=import-error
from app.scodoc import sco_utils as scu
from app.scodoc import sco_abs
from app.scodoc import sco_abs_views
from app.scodoc import sco_bulletins
from app.scodoc import sco_evaluations
from app.scodoc import sco_codes_parcours
from app.scodoc import sco_parcours_dut
from app.scodoc import sco_formsemestre_validation
context = sco_fake_gen.Sco8Context()
g.scodoc_dept = "TEST00"
G = sco_fake_gen.ScoFake(context)
G.verbose = False G.verbose = False
# --- Création d'étudiants # --- Création d'étudiants
@ -78,10 +81,10 @@ for etud in etuds:
# --- Vérifie que les notes sont prises en compte: # --- Vérifie que les notes sont prises en compte:
b = sco_bulletins.formsemestre_bulletinetud_dict( b = sco_bulletins.formsemestre_bulletinetud_dict(
context.Notes, sem["formsemestre_id"], etud["etudid"], REQUEST=REQUEST context, sem["formsemestre_id"], etud["etudid"], REQUEST=REQUEST
) )
# Toute les notes sont saisies, donc eval complète # Toute les notes sont saisies, donc eval complète
etat = sco_evaluations.do_evaluation_etat(context.Notes, e["evaluation_id"]) etat = sco_evaluations.do_evaluation_etat(context, e["evaluation_id"])
assert etat["evalcomplete"] assert etat["evalcomplete"]
# Un seul module, donc moy gen == note module # Un seul module, donc moy gen == note module
assert b["ues"][0]["cur_moy_ue_txt"] == b["ues"][0]["modules"][0]["mod_moy_txt"] assert b["ues"][0]["cur_moy_ue_txt"] == b["ues"][0]["modules"][0]["mod_moy_txt"]
@ -91,7 +94,6 @@ assert (
== b["ues"][0]["modules"][0]["evaluations"][0]["note_txt"] == b["ues"][0]["modules"][0]["evaluations"][0]["note_txt"]
) )
# --- Une autre évaluation # --- Une autre évaluation
e2 = G.create_evaluation( e2 = G.create_evaluation(
moduleimpl_id=mi["moduleimpl_id"], moduleimpl_id=mi["moduleimpl_id"],
@ -105,16 +107,16 @@ for etud in etuds[:5]:
evaluation=e2, etud=etud, note=float(random.randint(0, 20)) evaluation=e2, etud=etud, note=float(random.randint(0, 20))
) )
# Cette éval n'est pas complète # Cette éval n'est pas complète
etat = sco_evaluations.do_evaluation_etat(context.Notes, e2["evaluation_id"]) etat = sco_evaluations.do_evaluation_etat(context, e2["evaluation_id"])
assert etat["evalcomplete"] == False assert etat["evalcomplete"] == False
# la première éval est toujours complète: # la première éval est toujours complète:
etat = sco_evaluations.do_evaluation_etat(context.Notes, e["evaluation_id"]) etat = sco_evaluations.do_evaluation_etat(context, e["evaluation_id"])
assert etat["evalcomplete"] assert etat["evalcomplete"]
# Modifie l'évaluation 2 pour "prise en compte immédiate" # Modifie l'évaluation 2 pour "prise en compte immédiate"
e2["publish_incomplete"] = "1" e2["publish_incomplete"] = "1"
sco_evaluations.do_evaluation_edit(context, REQUEST, e2) sco_evaluations.do_evaluation_edit(context, REQUEST, e2)
etat = sco_evaluations.do_evaluation_etat(context.Notes, e2["evaluation_id"]) etat = sco_evaluations.do_evaluation_etat(context, e2["evaluation_id"])
assert etat["evalcomplete"] == False assert etat["evalcomplete"] == False
assert etat["nb_att"] == 0 # il n'y a pas de notes (explicitement) en attente assert etat["nb_att"] == 0 # il n'y a pas de notes (explicitement) en attente
assert etat["evalattente"] # mais l'eval est en attente (prise en compte immédiate) assert etat["evalattente"] # mais l'eval est en attente (prise en compte immédiate)
@ -124,7 +126,7 @@ for etud in etuds[5:]:
nb_changed, nb_suppress, existing_decisions = G.create_note( nb_changed, nb_suppress, existing_decisions = G.create_note(
evaluation=e2, etud=etud, note=float(random.randint(0, 20)) evaluation=e2, etud=etud, note=float(random.randint(0, 20))
) )
etat = sco_evaluations.do_evaluation_etat(context.Notes, e2["evaluation_id"]) etat = sco_evaluations.do_evaluation_etat(context, e2["evaluation_id"])
assert etat["evalcomplete"] assert etat["evalcomplete"]
assert etat["nb_att"] == 0 assert etat["nb_att"] == 0
assert not etat["evalattente"] # toutes les notes sont présentes assert not etat["evalattente"] # toutes les notes sont présentes
@ -133,7 +135,7 @@ assert not etat["evalattente"] # toutes les notes sont présentes
etudid = etuds[0]["etudid"] etudid = etuds[0]["etudid"]
_ = sco_abs_views.doSignaleAbsence( _ = sco_abs_views.doSignaleAbsence(
context.Absences, context,
"15/01/2020", "15/01/2020",
"18/01/2020", "18/01/2020",
demijournee=2, demijournee=2,
@ -142,7 +144,7 @@ _ = sco_abs_views.doSignaleAbsence(
) )
_ = sco_abs_views.doJustifAbsence( _ = sco_abs_views.doJustifAbsence(
context.Absences, context,
"17/01/2020", "17/01/2020",
"18/01/2020", "18/01/2020",
demijournee=2, demijournee=2,
@ -150,9 +152,9 @@ _ = sco_abs_views.doJustifAbsence(
REQUEST=REQUEST, REQUEST=REQUEST,
) )
a = sco_abs.getAbsSemEtud(context.Absences, sem, etudid) a = sco_abs.getAbsSemEtud(context, sem, etudid)
assert a.CountAbs() == 3 assert a.CountAbs() == 6, "incorrect CountAbs (%d)" % a.CountAbs()
assert a.CountAbsJust() == 1 assert a.CountAbsJust() == 2, "incorrect CountAbsJust (%s)" % a.CountAbsJust()
# --- Permission saisie notes et décisions de jury, avec ou sans démission ou défaillance # --- Permission saisie notes et décisions de jury, avec ou sans démission ou défaillance
# on n'a pas encore saisi de décisions # on n'a pas encore saisi de décisions
@ -160,7 +162,7 @@ assert not sco_parcours_dut.formsemestre_has_decisions(context, sem["formsemestr
# Saisie d'un décision AJ, non assidu # Saisie d'un décision AJ, non assidu
etudid = etuds[-1]["etudid"] etudid = etuds[-1]["etudid"]
sco_parcours_dut.formsemestre_validate_ues( sco_parcours_dut.formsemestre_validate_ues(
context.Notes, context,
sem["formsemestre_id"], sem["formsemestre_id"],
etudid, etudid,
sco_codes_parcours.AJ, sco_codes_parcours.AJ,
@ -168,12 +170,12 @@ sco_parcours_dut.formsemestre_validate_ues(
REQUEST=REQUEST, REQUEST=REQUEST,
) )
assert sco_parcours_dut.formsemestre_has_decisions( assert sco_parcours_dut.formsemestre_has_decisions(
context.Notes, sem["formsemestre_id"] context, sem["formsemestre_id"]
) ), "décisions manquantes"
# Suppression de la décision # Suppression de la décision
sco_formsemestre_validation.formsemestre_validation_suppress_etud( sco_formsemestre_validation.formsemestre_validation_suppress_etud(
context.Notes, sem["formsemestre_id"], etudid context, sem["formsemestre_id"], etudid
) )
assert not sco_parcours_dut.formsemestre_has_decisions( assert not sco_parcours_dut.formsemestre_has_decisions(
context.Notes, sem["formsemestre_id"] context, sem["formsemestre_id"]
) ), "décisions non effacées"