# -*- 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 /opt/scodoc/.env pour indiquer FLASK_ENV=test_api FLASK_DEBUG=1 2) En tant qu'utilisateur scodoc, lancer: tools/create_database.sh SCODOC_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 """ import datetime import random import sys from app.auth.models import Role, User from app import models from app.models import Departement, Formation, FormSemestre, Identite, ModuleImpl from app import db from app.scodoc import ( sco_cache, sco_evaluation_db, sco_formations, sco_formsemestre_inscriptions, sco_groups, ) from app.scodoc.sco_permissions import Permission from app.scodoc.sco_saisie_notes import notes_add from tools.fakeportal.gen_nomprenoms import nomprenom random.seed(12345678) # tests reproductibles # La formation à utiliser: FORMATION_XML_FILENAME = "tests/ressources/formations/scodoc_formation_RT_BUT_RT_v1.xml" def init_departement(acronym: str) -> Departement: "Create dept, and switch context into it." import app as mapp dept = Departement(acronym=acronym) db.session.add(dept) mapp.set_sco_dept(acronym) db.session.commit() return dept def import_formation() -> 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 Formation.query.get(f[0]) def create_users(dept: Departement) -> tuple: """créé les utilisateurs nécessaires aux tests""" # Un utilisateur "test" (passwd test) pouvant lire l'API user = User(user_name="test", nom="Doe", prenom="John", dept=dept.acronym) user.set_password("test") db.session.add(user) # Le rôle standard LecteurAPI existe déjà role = Role.query.filter_by(name="LecteurAPI").first() if role is None: print("Erreur: rôle LecteurAPI non existant") sys.exit(1) perm_api_view = Permission.get_by_name("APIView") role.add_permission(perm_api_view) db.session.add(role) user.add_role(role, None) # Un utilisateur "other" n'ayant aucune permission sur l'API other = User(user_name="other", nom="Sans", prenom="Permission", dept=dept.acronym) other.set_password("other") db.session.add(other) db.session.commit() return user, other def create_fake_etud(dept: Departement) -> Identite: """Créé un faux étudiant et l'insère dans la base.""" civilite = random.choice(("M", "F", "X")) nom, prenom = nomprenom(civilite) etud: Identite = Identite( civilite=civilite, nom=nom, prenom=prenom, dept_id=dept.id ) db.session.add(etud) db.session.commit() # créé un étudiant sur deux avec un NIP et INE alphanumérique etud.code_nip = f"{etud.id}" if (etud.id % 2) else f"NIP{etud.id}" etud.code_ine = f"INE{etud.id}" if (etud.id % 2) else f"{etud.id}" db.session.add(etud) db.session.commit() adresse = models.Adresse( etudid=etud.id, email=f"{etud.prenom}.{etud.nom}@example.com" ) db.session.add(adresse) admission = models.Admission(etudid=etud.id) db.session.add(admission) db.session.commit() return etud def create_etuds(dept: Departement, nb=16) -> list: "create nb etuds" return [create_fake_etud(dept) for _ in range(nb)] def create_formsemestre( formation: Formation, responsable: User, semestre_idx=1 ) -> FormSemestre: """Create formsemestre and moduleimpls responsable: resp. du formsemestre """ formsemestre = 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, 8, 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=responsable.id, ) db.session.add(modimpl) db.session.commit() partition_id = sco_groups.partition_create( formsemestre.id, default=True, redirect=False ) _group_id = sco_groups.create_group(partition_id, default=True) return formsemestre def inscrit_etudiants(etuds: list, formsemestre: FormSemestre): """Inscrit les etudiants aux semestres et à tous ses modules""" for etud in etuds: sco_formsemestre_inscriptions.do_formsemestre_inscription_with_modules( formsemestre.id, etud.id, group_ids=[], etat="I", method="init db test", ) def create_evaluations(formsemestre: FormSemestre): "creation d'une evaluation dans cahque modimpl du semestre" for modimpl in formsemestre.modimpls: args = { "moduleimpl_id": modimpl.id, "jour": None, "heure_debut": "8h00", "heure_fin": "9h00", "description": None, "note_max": 20, "coefficient": 1.0, "visibulletin": True, "publish_incomplete": True, "evaluation_type": None, "numero": None, } evaluation_id = sco_evaluation_db.do_evaluation_create(**args) def saisie_note_evaluations(formsemestre: FormSemestre, user: User): """ Saisie les notes des evaluations d'un semestre """ # Récupération des id des étudiants du semestre list_etudids = [etud.id for etud in formsemestre.etuds] list_ues = formsemestre.query_ues() def create_list_etudid_random_notes(): """ Retourne une liste de tuple (etudid, note_random) """ return [(etudid, random.uniform(0.0, 20.0)) for etudid in list_etudids] for ue in list_ues: mods = ue.modules for mod in mods: moduleimpl = ModuleImpl.query.get_or_404(mod.id) for evaluation in moduleimpl.evaluations: notes = create_list_etudid_random_notes() notes_add(user, evaluation.id, notes) def init_test_database(): """Appelé par la commande `flask init-test-database` Création d'un département et de son contenu pour les tests """ dept = init_departement("TAPI") user_lecteur, user_autre = create_users(dept) with sco_cache.DeferredSemCacheManager(): etuds = create_etuds(dept) formation = import_formation() formsemestre = create_formsemestre(formation, user_lecteur) create_evaluations(formsemestre) inscrit_etudiants(etuds, formsemestre) saisie_note_evaluations(formsemestre, user_lecteur) # à compléter # - groupes # - absences # - notes # - décisions de jury # ...