From 10230d20eff9bd41170b01c21de8a601228f5d4c Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Wed, 9 Mar 2022 16:05:44 +0100 Subject: [PATCH] =?UTF-8?q?Commande=20init-test-database=20pour=20g=C3=A9n?= =?UTF-8?q?=C3=A9rer=20base=20de=20test=20(pour=20l'API)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scodoc.py | 15 ++ .../scodoc_formation_RT_BUT_RT_v1.xml | 90 ++++++++++++ tests/scenarios/test_scenario1_formation.py | 3 +- .../fakedatabase/create_test_api_database.py | 139 ++++++++++++++++++ 4 files changed, 246 insertions(+), 1 deletion(-) create mode 100644 tests/ressources/formations/scodoc_formation_RT_BUT_RT_v1.xml create mode 100644 tools/fakedatabase/create_test_api_database.py diff --git a/scodoc.py b/scodoc.py index 4dc5165f..9eea0f1c 100755 --- a/scodoc.py +++ b/scodoc.py @@ -33,6 +33,7 @@ from app.models.evaluations import Evaluation from app.scodoc.sco_permissions import Permission from app.views import notes, scolar import tools +from tools.fakedatabase import create_test_api_database from config import RunningConfig @@ -84,6 +85,7 @@ def make_shell_context(): # ctx.push() +# admin = User.query.filter_by(user_name="admin").first() # login_user(admin) @@ -492,6 +494,19 @@ def clear_cache(sanitize): # clear-cache formation.sanitize_old_formation() +@app.cli.command() +def init_test_database(): + """Initialise les objets en base pour les tests API + (à appliquer sur SCODOC_TEST ou SCODOC_DEV) + """ + click.echo("Initialisation base de test API...") + # import app as mapp # le package app + + ctx = app.test_request_context() + ctx.push() + create_test_api_database.init_test_database() + + def recursive_help(cmd, parent=None): ctx = click.core.Context(cmd, info_name=cmd.name, parent=parent) print(cmd.get_help(ctx)) diff --git a/tests/ressources/formations/scodoc_formation_RT_BUT_RT_v1.xml b/tests/ressources/formations/scodoc_formation_RT_BUT_RT_v1.xml new file mode 100644 index 00000000..dd4bd01b --- /dev/null +++ b/tests/ressources/formations/scodoc_formation_RT_BUT_RT_v1.xml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/scenarios/test_scenario1_formation.py b/tests/scenarios/test_scenario1_formation.py index 9447674b..a4b13ee3 100644 --- a/tests/scenarios/test_scenario1_formation.py +++ b/tests/scenarios/test_scenario1_formation.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- -""" +"""XXX OBSOLETE + Scenario: préparation base de données pour tests Selenium S'utilise comme un test avec pytest, mais n'est pas un test ! diff --git a/tools/fakedatabase/create_test_api_database.py b/tools/fakedatabase/create_test_api_database.py new file mode 100644 index 00000000..bfd346fa --- /dev/null +++ b/tools/fakedatabase/create_test_api_database.py @@ -0,0 +1,139 @@ +# -*- coding: utf-8 -*- + +"""Initialise une base pour les tests de l'API ScoDoc 9 + + Création des départements, formations, semestres, étudiants, groupes... + + utilisation: + 1) modifier le .env pour indiquer + SCODOC_DATABASE_URI="postgresql:///SCO_TEST_API" + + 2) En tant qu'utilisateur scodoc, lancer: + tools/create_database.sh SCO_TEST_API + flask db upgrade + flask sco-db-init --erase + flask init-test-database + + 3) relancer ScoDoc: + flask run --host 0.0.0.0 + + 4) lancer client de test (ou vérifier dans le navigateur) + +""" +import datetime +import random + +random.seed(12345678) # tests reproductibles + +from flask_login import login_user + +from app import auth +from app import models +from app import db +from app.scodoc import sco_formations +from tools.fakeportal.gen_nomprenoms import nomprenom + +# La formation à utiliser: +FORMATION_XML_FILENAME = "tests/ressources/formations/scodoc_formation_RT_BUT_RT_v1.xml" + + +def init_departement(acronym): + "Create dept, and switch context into it." + import app as mapp + + dept = models.Departement(acronym=acronym) + db.session.add(dept) + mapp.set_sco_dept(acronym) + db.session.commit() + return dept + + +def import_formation() -> models.Formation: + """Import formation from XML. + Returns formation_id + """ + with open(FORMATION_XML_FILENAME) as f: + doc = f.read() + # --- Création de la formation + f = sco_formations.formation_import_xml(doc) + return models.Formation.query.get(f[0]) + + +def create_user(dept): + """créé les utilisaterurs nécessaires aux tests""" + user = auth.models.User( + user_name="test", nom="Doe", prenom="John", dept=dept.acronym + ) + db.session.add(user) + db.session.commit() + return user + + +def create_fake_etud(): + """Créé un faux étudiant et l'insère dans la base""" + civilite = random.choice(("M", "F", "X")) + nom, prenom = nomprenom(civilite) + etud = models.Identite(civilite=civilite, nom=nom, prenom=prenom) + db.session.add(etud) + db.session.commit() + return etud + + +def create_etuds(nb=16): + "create nb etuds" + return [create_fake_etud() for _ in range(nb)] + + +def create_formsemestre(formation, user, semestre_idx=1): + """Create formsemestre and moduleimpls""" + formsemestre = models.FormSemestre( + dept_id=formation.dept_id, + semestre_id=semestre_idx, + titre="Semestre test", + date_debut=datetime.datetime(2021, 9, 1), + date_fin=datetime.datetime(2022, 1, 31), + modalite="FI", + formation=formation, + ) + db.session.add(formsemestre) + db.session.commit() + # Crée un modulimpl par module de ce semestre: + for module in formation.modules.filter_by(semestre_id=semestre_idx): + modimpl = models.ModuleImpl( + module_id=module.id, formsemestre_id=formsemestre.id, responsable_id=user.id + ) + db.session.add(modimpl) + db.session.commit() + return formsemestre + + +def inscrit_etudiants(etuds, formsemestre): + """Inscrit les etudiants aux semestres et à tous ses modules""" + for etud in etuds: + ins = models.FormSemestreInscription( + etudid=etud.id, formsemestre_id=formsemestre.id, etat="I" + ) + db.session.add(ins) + for modimpl in formsemestre.modimpls: + insmod = models.ModuleImplInscription( + etudid=etud.id, moduleimpl_id=modimpl.id + ) + db.session.add(insmod) + db.session.commit() + + +def init_test_database(): + dept = init_departement("TAPI") + user = create_user(dept) + login_user(user) + + etuds = create_etuds() + formation = import_formation() + formsemestre = create_formsemestre(formation, user) + inscrit_etudiants(etuds, formsemestre) + # à compléter + # - groupes + # - absences + # - notes + # - décisions de jury + # ...