Compare commits

...

14 Commits

Author SHA1 Message Date
53aea89560 Merge branch 'master' into dyn_fields 2021-09-25 14:01:01 +02:00
1aa39c72fd Merge branch 'master' into dyn_fields 2021-09-25 10:01:09 +02:00
bd6e3e6648 temp 2021-09-24 23:15:14 +02:00
cd06a780d5 Merge branch 'master' into dyn_fields 2021-09-24 21:51:25 +02:00
3f86d9b380 WIP 2021-09-24 16:10:01 +02:00
37303df74c add_fields ok 2021-09-24 16:00:55 +02:00
e4c9e5f9e8 merged master 2021-09-24 10:44:13 +02:00
1af6f79da9 Merge branch 'master' into dyn_fields
# Conflicts:
#	app/scodoc/sco_placement.py
#	app/static/css/scodoc.css
#	app/templates/scodoc/forms/placement.html
#	tests/unit/test_abs_demijournee.py
#	tests/unit/test_formations.py
2021-09-24 10:29:24 +02:00
b05aea95b6 test ajout cb 2021-09-21 05:35:56 +02:00
b552588c1c remove cr 2021-09-19 06:19:11 +02:00
2dbc1ca695 push avec crlf 2021-09-18 14:34:59 +02:00
9383a53569 restest 2021-09-18 14:31:45 +02:00
0621cb1d0f test cr 2021-09-18 14:04:45 +02:00
ae1feba96c template + accessors 2021-09-18 10:05:11 +02:00
7 changed files with 1114 additions and 1107 deletions

327
README.md
View File

@ -1,163 +1,164 @@
# ScoDoc - Gestion de la scolarité - Version ScoDoc 9
(c) Emmanuel Viennet 1999 - 2021 (voir LICENCE.txt)
VERSION EXPERIMENTALE - NE PAS DEPLOYER - TESTS EN COURS
Installation: voir instructions à jour sur <https://scodoc.org/GuideInstallDebian11>
Documentation utilisateur: <https://scodoc.org>
## Version ScoDoc 9
N'utiliser que pour les développements et tests.
La version ScoDoc 9 est basée sur Flask (au lieu de Zope) et sur
**python 3.9+**.
La version 9.0 s'efforce de reproduire presque à l'identique le fonctionnement
de ScoDoc7, avec des composants logiciels différents (Debian 11, Python 3,
Flask, SQLAlchemy, au lien de Python2/Zope dans les versions précédentes).
### État actuel (27 août 21)
- Tests en cours, notamment système d'installation et de migration.
**Fonctionnalités non intégrées:**
- feuille "placement" (en cours)
- ancien module "Entreprises" (obsolete)
### Lignes de commandes
Voir [https://scodoc.org/GuideConfig](le guide de configuration).
## Organisation des fichiers
L'installation comporte les fichiers de l'application, sous `/opt/scodoc/`, et
les fichiers locaux (archives, photos, configurations, logs) sous
`/opt/scodoc-data`. Par ailleurs, il y a évidemment les bases de données
postgresql et la configuration du système Linux.
### Fichiers locaux
Sous `/opt/scodoc-data`, fichiers et répertoires appartienant à l'utilisateur `scodoc`.
Ils ne doivent pas être modifiés à la main, sauf certains fichiers de configuration sous
`/opt/scodoc-data/config`.
Le répertoire `/opt/scodoc-data` doit être régulièrement sauvegardé.
Principaux contenus:
/opt/scodoc-data
/opt/scodoc-data/log # Fichiers de log ScoDoc
/opt/scodoc-data/config # Fichiers de configuration
.../config/logos # Logos de l'établissement
.../config/depts # un fichier par département
/opt/scodoc-data/photos # Photos des étudiants
/opt/scodoc-data/archives # Archives: PV de jury, maquettes Apogée, fichiers étudiants
## Pour les développeurs
### Installation du code
Installer ScoDoc 9 normalement ([voir la doc](https://scodoc.org/GuideInstallDebian11)).
Puis remplacer `/opt/scodoc` par un clone du git.
sudo su
mv /opt/scodoc /opt/off-scodoc # ou ce que vous voulez
apt-get install git # si besoin
cd /opt
git clone https://scodoc.org/git/viennet/ScoDoc.git
# (ou bien utiliser votre clone gitea si vous l'avez déjà créé !)
mv ScoDoc scodoc # important !
Il faut ensuite installer l'environnement et le fichier de configuration:
# Le plus simple est de piquer le virtualenv configuré par l'installeur:
mv /opt/off-scodoc/venv /opt/scodoc
Et la config:
ln -s /opt/scodoc-data/.env /opt/scodoc
Cette dernière commande utilise le `.env` crée lors de l'install, ce qui
n'est pas toujours le plus judicieux: vous pouvez modifier son contenu, par
exemple pour travailler en mode "développement" avec `FLASK_ENV=development`.
### Tests unitaires
Certains tests ont besoin d'un département déjà créé, qui n'est pas créé par les
scripts de tests:
Lancer au préalable:
flask sco-delete-dept TEST00 && flask sco-create-dept TEST00
Puis dérouler les tests unitaires:
pytest tests/unit
Ou avec couverture (`pip install pytest-cov`)
pytest --cov=app --cov-report=term-missing --cov-branch tests/unit/*
#### Utilisation des tests unitaires pour initialiser la base de dev
On peut aussi utiliser les tests unitaires pour mettre la base
de données de développement dans un état connu, par exemple pour éviter de recréer à la main étudianst et semestres quand on développe.
Il suffit de positionner une variable d'environnement indiquant la BD utilisée par les tests:
export SCODOC_TEST_DATABASE_URI=postgresql:///SCODOC_DEV
puis de les lancer normalement, par exemple:
pytest tests/unit/test_sco_basic.py
Il est en général nécessaire d'affecter ensuite un mot de passe à (au moins)
un utilisateur:
flask user-password admin
**Attention:** les tests unitaires **effacent** complètement le contenu de la
base de données (tous les départements, et les utilisateurs) avant de commencer !
#### Modification du schéma de la base
On utilise SQLAlchemy avec Alembic et Flask-Migrate.
flask db migrate -m "ScoDoc 9.0.x: ..." # ajuster le message !
flask db upgrade
Ne pas oublier de commiter les migrations (`git add migrations` ...).
Mémo pour développeurs: séquence re-création d'une base:
dropdb SCODOC_DEV
tools/create_database.sh SCODOC_DEV # créé base SQL
flask db upgrade # créé les tables à partir des migrations
flask sco-db-init # ajoute au besoin les constantes (fait en migration 0)
# puis imports:
flask import-scodoc7-users
flask import-scodoc7-dept STID SCOSTID
Si la base utilisée pour les dev n'est plus en phase avec les scripts de
migration, utiliser les commandes `flask db history`et `flask db stamp`pour se
positionner à la bonne étape.
# Paquet debian 11
Les scripts associés au paquet Debian (.deb) sont dans `tools/debian`. Le plus
important est `postinst`qui se charge de configurer le système (install ou
upgrade de scodoc9).
La préparation d'une release se fait à l'aide du script
`tools/build_release.sh`.
# ScoDoc - Gestion de la scolarité - Version ScoDoc 9
(c) Emmanuel Viennet 1999 - 2021 (voir LICENCE.txt)\r
VERSION EXPERIMENTALE - NE PAS DEPLOYER - TESTS EN COURS
Installation: voir instructions à jour sur <https://scodoc.org/GuideInstallDebian11>
Documentation utilisateur: <https://scodoc.org>
## Version ScoDoc 9
N'utiliser que pour les développements et tests.
La version ScoDoc 9 est basée sur Flask (au lieu de Zope) et sur
**python 3.9+**.
La version 9.0 s'efforce de reproduire presque à l'identique le fonctionnement
de ScoDoc7, avec des composants logiciels différents (Debian 11, Python 3,
Flask, SQLAlchemy, au lien de Python2/Zope dans les versions précédentes).
### État actuel (27 août 21)
- Tests en cours, notamment système d'installation et de migration.
**Fonctionnalités non intégrées:**
- feuille "placement" (en cours)
- ancien module "Entreprises" (obsolete)
### Lignes de commandes
Voir [https://scodoc.org/GuideConfig](le guide de configuration).
## Organisation des fichiers
L'installation comporte les fichiers de l'application, sous `/opt/scodoc/`, et
les fichiers locaux (archives, photos, configurations, logs) sous
`/opt/scodoc-data`. Par ailleurs, il y a évidemment les bases de données
postgresql et la configuration du système Linux.
### Fichiers locaux
Sous `/opt/scodoc-data`, fichiers et répertoires appartienant à l'utilisateur `scodoc`.
Ils ne doivent pas être modifiés à la main, sauf certains fichiers de configuration sous
`/opt/scodoc-data/config`.
Le répertoire `/opt/scodoc-data` doit être régulièrement sauvegardé.
Principaux contenus:
/opt/scodoc-data
/opt/scodoc-data/log # Fichiers de log ScoDoc
/opt/scodoc-data/config # Fichiers de configuration
.../config/logos # Logos de l'établissement
.../config/depts # un fichier par département
/opt/scodoc-data/photos # Photos des étudiants
/opt/scodoc-data/archives # Archives: PV de jury, maquettes Apogée, fichiers étudiants
## Pour les développeurs
### Installation du code
Installer ScoDoc 9 normalement ([voir la doc](https://scodoc.org/GuideInstallDebian11)).
Puis remplacer `/opt/scodoc` par un clone du git.
sudo su
mv /opt/scodoc /opt/off-scodoc # ou ce que vous voulez
apt-get install git # si besoin
cd /opt
git clone https://scodoc.org/git/viennet/ScoDoc.git
# (ou bien utiliser votre clone gitea si vous l'avez déjà créé !)
mv ScoDoc scodoc # important !
Il faut ensuite installer l'environnement et le fichier de configuration:
# Le plus simple est de piquer le virtualenv configuré par l'installeur:
mv /opt/off-scodoc/venv /opt/scodoc
Et la config:
ln -s /opt/scodoc-data/.env /opt/scodoc
Cette dernière commande utilise le `.env` crée lors de l'install, ce qui
n'est pas toujours le plus judicieux: vous pouvez modifier son contenu, par
exemple pour travailler en mode "développement" avec `FLASK_ENV=development`.
### Tests unitaires
Certains tests ont besoin d'un département déjà créé, qui n'est pas créé par les
scripts de tests:
Lancer au préalable:
flask sco-delete-dept TEST00 && flask sco-create-dept TEST00
Puis dérouler les tests unitaires:
pytest tests/unit
Ou avec couverture (`pip install pytest-cov`)
pytest --cov=app --cov-report=term-missing --cov-branch tests/unit/*
#### Utilisation des tests unitaires pour initialiser la base de dev
On peut aussi utiliser les tests unitaires pour mettre la base
de données de développement dans un état connu, par exemple pour éviter de recréer à la main étudianst et semestres quand on développe.
Il suffit de positionner une variable d'environnement indiquant la BD utilisée par les tests:
export SCODOC_TEST_DATABASE_URI=postgresql:///SCODOC_DEV
puis de les lancer normalement, par exemple:
pytest tests/unit/test_sco_basic.py
Il est en général nécessaire d'affecter ensuite un mot de passe à (au moins)
un utilisateur:
flask user-password admin
**Attention:** les tests unitaires **effacent** complètement le contenu de la
base de données (tous les départements, et les utilisateurs) avant de commencer !
#### Modification du schéma de la base
On utilise SQLAlchemy avec Alembic et Flask-Migrate.
flask db migrate -m "ScoDoc 9.0.x: ..." # ajuster le message !
flask db upgrade
Ne pas oublier de commiter les migrations (`git add migrations` ...).
Mémo pour développeurs: séquence re-création d'une base:
dropdb SCODOC_DEV
tools/create_database.sh SCODOC_DEV # créé base SQL
flask db upgrade # créé les tables à partir des migrations
flask sco-db-init # ajoute au besoin les constantes (fait en migration 0)
# puis imports:
flask import-scodoc7-users
flask import-scodoc7-dept STID SCOSTID
Si la base utilisée pour les dev n'est plus en phase avec les scripts de
migration, utiliser les commandes `flask db history`et `flask db stamp`pour se
positionner à la bonne étape.
# Paquet debian 11
Les scripts associés au paquet Debian (.deb) sont dans `tools/debian`. Le plus
important est `postinst`qui se charge de configurer le système (install ou
upgrade de scodoc9).
La préparation d'une release se fait à l'aide du script
`tools/build_release.sh`.

View File

@ -47,6 +47,7 @@ from wtforms import (
RadioField,
HiddenField,
SelectMultipleField,
BooleanField,
)
import app.scodoc.sco_utils as scu
import app.scodoc.notesdb as ndb
@ -74,6 +75,10 @@ SEQ = "Continue"
TOUS = "Tous"
def get_name(selfgroup, partition):
return 'GR_{partition]_{groupe]'
def _get_group_info(evaluation_id):
# groupes
groups = sco_groups.do_evaluation_listegroupes(evaluation_id, include_default=True)
@ -85,14 +90,13 @@ def _get_group_info(evaluation_id):
group_name = group["group_name"] or TOUS
if partition not in groups_tree:
groups_tree[partition] = {}
groups_tree[partition][group_name] = group_id
if partition != TOUS:
has_groups = True
nb_groups = len(groups_tree)
else:
has_groups = False
nb_groups = 1
return groups_tree, has_groups, nb_groups
name = get_name(partition, group_name)
groups_tree[partition][group_name] = {
"id": group_id,
"field": BooleanField(name),
"name": name,
}
return groups_tree
class PlacementForm(FlaskForm):
@ -122,42 +126,42 @@ class PlacementForm(FlaskForm):
wtforms.validators.DataRequired("indiquez le style de numérotation"),
],
)
groups = SelectMultipleField(
"Groupe(s)",
validators=[],
)
# groups = SelectMultipleField(
# "Groupe(s)",
# validators=[
# wtforms.validators.DataRequired("indiquez au moins un groupe"),
# ],
# )
submit = SubmitField("OK")
def __init__(self, formdata=None, data=None):
super().__init__(formdata=formdata, data=data)
self.groups_tree = {}
self.has_groups = None
self.nb_groups = None
self.tous_id = None
self.set_evaluation_infos(data["evaluation_id"])
def add_dynamic(self, name, field):
self._unbound_fields.append((name, field))
def set_evaluation_infos(self, evaluation_id):
def __init__(self, groups_tree, formdata=None, data=None, **kwargs):
self.groups_tree = groups_tree
self.nb_partitions = len(groups_tree)
self.nb_groups = sum([len(x) for x in self.groups_tree.values()])
self.max_groups = max([len(x) for x in self.groups_tree.values()])
self.has_groups = self.nb_groups > 1
# add dynamic fields to Class
for partition in groups_tree:
for groupe in groups_tree[partition]:
name = self.groups_tree[partition][groupe]['name']
field = self.groups_tree[partition][groupe]['field']
self.add_dynamic(name, field)
# create the form (including new dynamic fields) and proccess all fields
super().__init__(formdata=formdata, data=data, **kwargs)
# first remove previous dynamic fields that might have been created for this form
# compute the values for new dynamic fields
evaluation_id = data["evaluation_id"]
"""Initialise les données du formulaire avec les données de l'évaluation."""
eval_data = sco_evaluations.do_evaluation_list({"evaluation_id": evaluation_id})
if not eval_data:
raise ScoValueError("invalid evaluation_id")
self.groups_tree, self.has_groups, self.nb_groups = _get_group_info(
evaluation_id
)
choices = []
for partition in self.groups_tree:
for groupe in self.groups_tree[partition]:
if (
groupe == TOUS
): # Affichage et valeur spécifique pour le groupe TOUS
self.tous_id = str(self.groups_tree[partition][groupe])
choices.append((TOUS, TOUS))
else:
groupe_id = str(self.groups_tree[partition][groupe])
choices.append((groupe_id, "%s (%s)" % (str(groupe), partition)))
self.groups.choices = choices
# self.groups.default = [TOUS] # Ne fonctionnne pas... (ni dans la déclaration de PlaceForm.groups)
# la réponse [] est de toute façon transposée en [ self.tous_id ] lors du traitement (cas du groupe unique)
def get_checkbox(self, partition, groupe):
return self._fields[get_name(partition, groupe)]
class _DistributeurContinu:
@ -193,7 +197,10 @@ class _Distributeur2D:
def placement_eval_selectetuds(evaluation_id):
"""Creation de l'écran de placement"""
groups_tree = _get_group_info(evaluation_id)
breakpoint()
form = PlacementForm(
groups_tree,
request.form,
data={"evaluation_id": int(evaluation_id), "groups": TOUS},
)
@ -209,6 +216,7 @@ def placement_eval_selectetuds(evaluation_id):
% runner.__dict__
)
return runner.exec_placement() # calcul et generation du fichier
# return flask.redirect(url_for("scodoc.index"))
htmls = [
html_sco_header.sco_header(init_jquery_ui=True),
sco_evaluations.evaluation_describe(evaluation_id=evaluation_id),

View File

@ -27,22 +27,20 @@
{{ render_field(form.nb_rangs) }}
{{ render_field(form.etiquetage) }}
{% if form.has_groups %}
{{ render_field(form.groups) }}
<!-- Tentative de recréer le choix des groupes sous forme de cases à cocher // demande à créer des champs wtf dynamiquement
{# {{ render_field(form.groups) }}#}
{% for partition in form.groups_tree %}
<tr>
{% if partition == 'Tous' %}
<td rowspan="{{ form.nb_groups }}">Groupes</td>
<td rowspan="{{ form.nb_partitions }}">Groupes</td>
{% endif %}
<td>{{ partition }}</td>
<td>
{% for groupe in form.groups_tree[partition] %}
{{ groupe }}{{ form[form.groups_tree[partition][groupe]] }}
{{ groupe }}{{ form.get_checkbox(partition, groupe)() }}
{% endfor %}
</td>
</tr>
{% endfor %}
-->
{% endif %}
{{ render_field(form.file_format) }}
</tbody>

View File

@ -1,62 +1,62 @@
# -*- coding: utf-8 -*-
"""
Scenario: préparation base de données pour tests Selenium
S'utilise comme un test avec pytest, mais n'est pas un test !
Modifie la base de données du département TEST00
Usage: pytest tests/scenarios/test_scenario1_formation.py
"""
# code écrit par Fares Amer, mai 2021 et porté sur ScoDoc 8 en août 2021
import random
from tests.unit import sco_fake_gen
from app.scodoc import sco_edit_module
from app.scodoc import sco_formations
from app.scodoc import sco_moduleimpl
def test_scenario1(test_client):
"""Applique "scenario 1"""
run_scenario1()
def run_scenario1():
G = sco_fake_gen.ScoFake(verbose=False)
# Lecture fichier XML local:
with open("tests/unit/formation-exemple-1.xml") as f:
doc = f.read()
# --- Création de la formation
f = sco_formations.formation_import_xml(doc=doc)
# --- Création des semestres
formation_id = f[0]
# --- Mise en place de 4 semestres
sems = [
G.create_formsemestre(
formation_id=formation_id,
semestre_id=x[0],
date_debut=x[1],
date_fin=x[2],
)
for x in (
(1, "01/09/2020", "01/02/2021"),
(2, "02/02/2021", "01/06/2021"),
(3, "01/09/2020", "01/02/2021"),
(4, "02/02/2021", "01/06/2021"),
)
]
# --- Implémentation des modules
modules = sco_edit_module.do_module_list({"formation_id": formation_id})
mods_imp = []
for mod in modules:
mi = G.create_moduleimpl(
module_id=mod["module_id"],
formsemestre_id=sems[mod["semestre_id"] - 1]["formsemestre_id"],
)
mods_imp.append(mi)
# -*- coding: utf-8 -*-
"""
Scenario: préparation base de données pour tests Selenium
S'utilise comme un test avec pytest, mais n'est pas un test !
Modifie la base de données du département TEST00
Usage: pytest tests/scenarios/test_scenario1_formation.py
"""
# code écrit par Fares Amer, mai 2021 et porté sur ScoDoc 8 en août 2021
import random
from tests.unit import sco_fake_gen
from app.scodoc import sco_edit_module
from app.scodoc import sco_formations
from app.scodoc import sco_moduleimpl
def test_scenario1(test_client):
"""Applique "scenario 1"""
run_scenario1()
def run_scenario1():
G = sco_fake_gen.ScoFake(verbose=False)
# Lecture fichier XML local:
with open("tests/unit/formation-exemple-1.xml") as f:
doc = f.read()
# --- Création de la formation
f = sco_formations.formation_import_xml(doc=doc)
# --- Création des semestres
formation_id = f[0]
# --- Mise en place de 4 semestres
sems = [
G.create_formsemestre(
formation_id=formation_id,
semestre_id=x[0],
date_debut=x[1],
date_fin=x[2],
)
for x in (
(1, "01/09/2020", "01/02/2021"),
(2, "02/02/2021", "01/06/2021"),
(3, "01/09/2020", "01/02/2021"),
(4, "02/02/2021", "01/06/2021"),
)
]
# --- Implémentation des modules
modules = sco_edit_module.do_module_list({"formation_id": formation_id})
mods_imp = []
for mod in modules:
mi = G.create_moduleimpl(
module_id=mod["module_id"],
formsemestre_id=sems[mod["semestre_id"] - 1]["formsemestre_id"],
)
mods_imp.append(mi)

View File

@ -1,123 +1,123 @@
# -*- mode: python -*-
# -*- coding: utf-8 -*-
"""
Comptage des absences
"""
# test écrit par Fares Amer, mai 2021 et porté sur ScoDoc 8 en juillet 2021
import json
from tests.unit import sco_fake_gen
from app.scodoc import sco_abs
from app.scodoc import sco_abs_views
from app.scodoc import sco_groups
from app.views import absences
def test_abs_counts(test_client):
"""Comptage des absences"""
G = sco_fake_gen.ScoFake(verbose=False)
# --- Création d'étudiants
etud = G.create_etud(code_nip=None)
# --- Création d'une formation
f = G.create_formation(acronyme="")
ue = G.create_ue(formation_id=f["formation_id"], acronyme="TST1", titre="ue test")
mat = G.create_matiere(ue_id=ue["ue_id"], titre="matière test")
mod = G.create_module(
matiere_id=mat["matiere_id"],
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
)
# --- Mise place d'un semestre
sem = G.create_formsemestre(
formation_id=f["formation_id"],
semestre_id=1,
date_debut="01/01/2021",
date_fin="30/06/2021",
)
mi = G.create_moduleimpl(
module_id=mod["module_id"],
formsemestre_id=sem["formsemestre_id"],
)
# --- Inscription des étudiants
G.inscrit_etudiant(sem, etud)
# --- Saisie absences
etudid = etud["etudid"]
for debut, fin, demijournee in [
("01/01/2020", "31/01/2020", 2), # hors semestre
("15/01/2021", "15/01/2021", 1),
("18/01/2021", "18/01/2021", 0),
("19/01/2021", "19/01/2021", 2),
("22/01/2021", "22/01/2021", 1),
("30/06/2021", "30/06/2021", 2), # dernier jour
]:
sco_abs_views.doSignaleAbsence(
datedebut=debut,
datefin=fin,
demijournee=demijournee,
etudid=etudid,
)
# --- Justification de certaines absences
for debut, fin, demijournee in [
("15/01/2021", "15/01/2021", 1),
("18/01/2021", "18/01/2021", 0),
("19/01/2021", "19/01/2021", 2),
]:
sco_abs_views.doJustifAbsence(
datedebut=debut,
datefin=fin,
demijournee=demijournee,
etudid=etudid,
)
# --- Utilisation de get_abs_count() de sco_abs
nbabs, nbabsjust = sco_abs.get_abs_count(etudid, sem)
# --- Utilisation de sco_abs.count_abs()
nb_abs2 = sco_abs.count_abs(etudid=etudid, debut="2021-01-01", fin="2021-06-30")
nb_absj2 = sco_abs.count_abs_just(
etudid=etudid, debut="2021-01-01", fin="2021-06-30"
)
assert nbabs == nb_abs2 == 7
assert nbabsjust == nb_absj2 == 4
# --- Nombre de justificatifs:
justifs = sco_abs.list_abs_justifs(etudid, "2021-01-01", datefin="2021-06-30")
assert len(justifs) == 4
# --- Suppression d'absence
_ = sco_abs_views.doAnnuleAbsence("19/01/2021", "19/01/2021", 2, etudid=etudid)
# --- Vérification
justifs_2 = sco_abs.list_abs_justifs(etudid, "2021-01-01", datefin="2021-06-30")
assert len(justifs_2) == len(justifs)
new_nbabs, _ = sco_abs.get_abs_count(etudid, sem) # version cachée
new_nbabs2 = sco_abs.count_abs(etudid=etudid, debut="2021-01-01", fin="2021-06-30")
assert new_nbabs == new_nbabs2
assert new_nbabs == (nbabs - 2) # on a supprimé deux absences
# --- annulation absence sans supprimer le justificatif
sco_abs_views.AnnuleAbsencesDatesNoJust(etudid, ["2021-01-15"])
nbabs_3, nbjust_3 = sco_abs.get_abs_count(etudid, sem)
assert nbabs_3 == new_nbabs
justifs_3 = sco_abs.list_abs_justifs(etudid, "2021-01-01", datefin="2021-06-30")
assert len(justifs_3) == len(justifs_2)
# -*- mode: python -*-
# -*- coding: utf-8 -*-
"""
Comptage des absences
"""
# test écrit par Fares Amer, mai 2021 et porté sur ScoDoc 8 en juillet 2021
import json
from tests.unit import sco_fake_gen
from app.scodoc import sco_abs
from app.scodoc import sco_abs_views
from app.scodoc import sco_groups
from app.views import absences
def test_abs_counts(test_client):
"""Comptage des absences"""
G = sco_fake_gen.ScoFake(verbose=False)
# --- Création d'étudiants
etud = G.create_etud(code_nip=None)
# --- Création d'une formation
f = G.create_formation(acronyme="")
ue = G.create_ue(formation_id=f["formation_id"], acronyme="TST1", titre="ue test")
mat = G.create_matiere(ue_id=ue["ue_id"], titre="matière test")
mod = G.create_module(
matiere_id=mat["matiere_id"],
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
)
# --- Mise place d'un semestre
sem = G.create_formsemestre(
formation_id=f["formation_id"],
semestre_id=1,
date_debut="01/01/2021",
date_fin="30/06/2021",
)
mi = G.create_moduleimpl(
module_id=mod["module_id"],
formsemestre_id=sem["formsemestre_id"],
)
# --- Inscription des étudiants
G.inscrit_etudiant(sem, etud)
# --- Saisie absences
etudid = etud["etudid"]
for debut, fin, demijournee in [
("01/01/2020", "31/01/2020", 2), # hors semestre
("15/01/2021", "15/01/2021", 1),
("18/01/2021", "18/01/2021", 0),
("19/01/2021", "19/01/2021", 2),
("22/01/2021", "22/01/2021", 1),
("30/06/2021", "30/06/2021", 2), # dernier jour
]:
sco_abs_views.doSignaleAbsence(
datedebut=debut,
datefin=fin,
demijournee=demijournee,
etudid=etudid,
)
# --- Justification de certaines absences
for debut, fin, demijournee in [
("15/01/2021", "15/01/2021", 1),
("18/01/2021", "18/01/2021", 0),
("19/01/2021", "19/01/2021", 2),
]:
sco_abs_views.doJustifAbsence(
datedebut=debut,
datefin=fin,
demijournee=demijournee,
etudid=etudid,
)
# --- Utilisation de get_abs_count() de sco_abs
nbabs, nbabsjust = sco_abs.get_abs_count(etudid, sem)
# --- Utilisation de sco_abs.count_abs()
nb_abs2 = sco_abs.count_abs(etudid=etudid, debut="2021-01-01", fin="2021-06-30")
nb_absj2 = sco_abs.count_abs_just(
etudid=etudid, debut="2021-01-01", fin="2021-06-30"
)
assert nbabs == nb_abs2 == 7
assert nbabsjust == nb_absj2 == 4
# --- Nombre de justificatifs:
justifs = sco_abs.list_abs_justifs(etudid, "2021-01-01", datefin="2021-06-30")
assert len(justifs) == 4
# --- Suppression d'absence
_ = sco_abs_views.doAnnuleAbsence("19/01/2021", "19/01/2021", 2, etudid=etudid)
# --- Vérification
justifs_2 = sco_abs.list_abs_justifs(etudid, "2021-01-01", datefin="2021-06-30")
assert len(justifs_2) == len(justifs)
new_nbabs, _ = sco_abs.get_abs_count(etudid, sem) # version cachée
new_nbabs2 = sco_abs.count_abs(etudid=etudid, debut="2021-01-01", fin="2021-06-30")
assert new_nbabs == new_nbabs2
assert new_nbabs == (nbabs - 2) # on a supprimé deux absences
# --- annulation absence sans supprimer le justificatif
sco_abs_views.AnnuleAbsencesDatesNoJust(etudid, ["2021-01-15"])
nbabs_3, nbjust_3 = sco_abs.get_abs_count(etudid, sem)
assert nbabs_3 == new_nbabs
justifs_3 = sco_abs.list_abs_justifs(etudid, "2021-01-01", datefin="2021-06-30")
assert len(justifs_3) == len(justifs_2)
# XXX à continuer

View File

@ -1,339 +1,339 @@
# -*- mode: python -*-
# -*- coding: utf-8 -*-
"""
Créer et justifier des absences en utilisant le parametre demijournee
"""
# test écrit par Fares Amer, mai 2021 et porté sur ScoDoc 8 en juillet 2021
import json
from tests.unit import sco_fake_gen
from app.scodoc import sco_abs
from app.scodoc import sco_abs_views
from app.scodoc import sco_groups
from app.views import absences
def test_abs_demijournee(test_client):
"""Opération élémentaires sur les absences, tests demi-journées
Travaille dans base TEST00 (defaut)
"""
G = sco_fake_gen.ScoFake(verbose=False)
# --- Création d'étudiants
etud = G.create_etud(code_nip=None)
# --- Création d'une formation
f = G.create_formation(acronyme="")
ue = G.create_ue(formation_id=f["formation_id"], acronyme="TST1", titre="ue test")
mat = G.create_matiere(ue_id=ue["ue_id"], titre="matière test")
mod = G.create_module(
matiere_id=mat["matiere_id"],
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
)
# --- Mise place d'un semestre
sem = G.create_formsemestre(
formation_id=f["formation_id"],
semestre_id=1,
date_debut="01/01/2021",
date_fin="30/06/2021",
)
mi = G.create_moduleimpl(
module_id=mod["module_id"],
formsemestre_id=sem["formsemestre_id"],
)
# --- Inscription des étudiants
G.inscrit_etudiant(sem, etud)
# --- Saisie absences
etudid = etud["etudid"]
_ = sco_abs_views.doSignaleAbsence(
"15/01/2021",
"15/01/2021",
demijournee=2,
etudid=etudid,
)
_ = sco_abs_views.doSignaleAbsence(
"18/01/2021",
"18/01/2021",
demijournee=1,
etudid=etudid,
)
_ = sco_abs_views.doSignaleAbsence(
"19/01/2021",
"19/01/2021",
demijournee=0,
etudid=etudid,
)
# --- Justification de certaines absences
_ = sco_abs_views.doJustifAbsence(
"18/01/2021",
"18/01/2021",
demijournee=1,
etudid=etudid,
)
_ = sco_abs_views.doJustifAbsence(
"19/01/2021",
"19/01/2021",
demijournee=2,
etudid=etudid,
)
# NE JUSTIFIE QUE LE MATIN MALGRES LE PARAMETRE demijournee = 2
# --- Test
nbabs, nbabs_just = sco_abs.get_abs_count(etudid, sem)
assert (
nbabs == 4
) # l'étudiant a été absent le 15 journée compléte (2 abs : 1 matin, 1 apres midi) et le 18 (1 matin), et le 19 (1 apres midi).
assert nbabs_just == 2 # Justifie abs du matin + abs après midi
def test_abs_basic(test_client):
"""creation de 10 étudiants, formation, semestre, ue, module, absences le matin, l'apres midi, la journée compléte
et justification d'absences, supression d'absences, création d'une liste etat absences, creation d'un groupe afin
de tester la fonction EtatAbsencesGroupes
Fonctions de l'API utilisé :
- doSignaleAbsence
- doAnnuleAbsence
- doJustifAbsence
- get_partition_groups
- get_partitions_list
- sco_abs.get_abs_count(etudid, sem)
- ListeAbsEtud
- partition_create
- createGroup
- set_group
- EtatAbsenceGr
- AddBilletAbsence
- listeBilletsEtud
"""
G = sco_fake_gen.ScoFake(verbose=False)
# --- Création d'étudiants
etuds = [G.create_etud(code_nip=None) for _ in range(10)]
# --- Création d'une formation
f = G.create_formation(acronyme="")
ue = G.create_ue(formation_id=f["formation_id"], acronyme="TST1", titre="ue test")
mat = G.create_matiere(ue_id=ue["ue_id"], titre="matière test")
mod = G.create_module(
matiere_id=mat["matiere_id"],
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
)
# --- Mise place d'un semestre
sem = G.create_formsemestre(
formation_id=f["formation_id"],
semestre_id=1,
date_debut="01/01/2021",
date_fin="30/06/2021",
)
mi = G.create_moduleimpl(
module_id=mod["module_id"],
formsemestre_id=sem["formsemestre_id"],
)
# --- Inscription des étudiants
for etud in etuds:
G.inscrit_etudiant(sem, etud)
# --- Création d'une évaluation
e = G.create_evaluation(
moduleimpl_id=mi["moduleimpl_id"],
jour="22/01/2021",
description="evaluation test",
coefficient=1.0,
)
# --- Saisie absences
etudid = etuds[0]["etudid"]
_ = sco_abs_views.doSignaleAbsence(
"15/01/2021",
"15/01/2021",
demijournee=1,
etudid=etudid,
)
_ = sco_abs_views.doSignaleAbsence(
"18/01/2021",
"18/01/2021",
demijournee=0,
etudid=etudid,
)
_ = sco_abs_views.doSignaleAbsence(
"19/01/2021",
"19/01/2021",
demijournee=2,
etudid=etudid,
)
_ = sco_abs_views.doSignaleAbsence(
"22/01/2021",
"22/01/2021",
demijournee=1,
etudid=etudid,
)
# --- Justification de certaines absences
_ = sco_abs_views.doJustifAbsence(
"15/01/2021",
"15/01/2021",
demijournee=1,
etudid=etudid,
)
_ = sco_abs_views.doJustifAbsence(
"18/01/2021",
"18/01/2021",
demijournee=0,
etudid=etudid,
)
_ = sco_abs_views.doJustifAbsence(
"19/01/2021",
"19/01/2021",
demijournee=2,
etudid=etudid,
)
# --- Test
b = sco_abs.is_work_saturday()
assert b == 0 # samedi ne sont pas compris
nbabs, nbabsjust = sco_abs.get_abs_count(etudid, sem)
# l'étudiant a été absent le 15 (apres midi) , (16 et 17 we),
# 18 (matin) et 19 janvier (matin et apres midi), et 22 (matin)
assert nbabs == 5
# l'étudiant justifie ses abs du 15, 18 et 19
assert nbabsjust == 4
# --- Suppression d'une absence et d'une justification
_ = sco_abs_views.doAnnuleAbsence("19/01/2021", "19/01/2021", 2, etudid=etudid)
nbabs, nbabsjust = sco_abs.get_abs_count(etudid, sem)
assert nbabs == 3
assert nbabsjust == 2
# --- suppression d'une justification pas encore disponible à l'aide de python.
# --- Création d'une liste d'abs
liste_abs = sco_abs_views.ListeAbsEtud(
etudid, format="json", absjust_only=1, sco_year="2020"
).get_data(as_text=True)
liste_abs2 = sco_abs_views.ListeAbsEtud(
etudid, format="json", sco_year="2020"
).get_data(as_text=True)
load_liste_abs = json.loads(liste_abs)
load_liste_abs2 = json.loads(liste_abs2)
assert len(load_liste_abs2) == 1
assert len(load_liste_abs) == 2
assert load_liste_abs2[0]["ampm"] == 1
assert load_liste_abs2[0]["datedmy"] == "22/01/2021"
assert load_liste_abs2[0]["exams"] == mod["code"]
# absjust_only -> seulement les abs justifiés
# --- Création d'un groupe
_ = sco_groups.partition_create(
formsemestre_id=sem["formsemestre_id"],
partition_name="Eleve",
)
li1 = sco_groups.get_partitions_list(sem["formsemestre_id"])
_ = sco_groups.createGroup(li1[0]["partition_id"], "Groupe 1")
# --- Affectation des élèves dans des groupes
li_grp1 = sco_groups.get_partition_groups(li1[0])
for etud in etuds:
sco_groups.set_group(etud["etudid"], li_grp1[0]["group_id"])
# --- Test de EtatAbsencesGroupes
grp1_abs = absences.EtatAbsencesGr(
group_ids=[li_grp1[0]["group_id"]],
debut="01/01/2021",
fin="30/06/2021",
format="json",
)
# grp1_abs est une Response car on a appelé une vue (1er appel)
load_grp1_abs = json.loads(grp1_abs.get_data(as_text=True))
assert len(load_grp1_abs) == 10
tab_id = [] # tab des id present dans load_grp1_abs
for un_etud in load_grp1_abs:
tab_id.append(un_etud["etudid"])
for (
etud
) in (
etuds
): # verification si tous les etudiants sont present dans la liste du groupe d'absence
assert etud["etudid"] in tab_id
for un_etud in load_grp1_abs:
if un_etud["etudid"] == etudid:
assert un_etud["nbabs"] == 3
assert un_etud["nbjustifs_noabs"] == 2
assert un_etud["nbabsjust"] == 2
assert un_etud["nbabsnonjust"] == 1
assert un_etud["nomprenom"] == etuds[0]["nomprenom"]
# --- Création de billets
b1 = absences.AddBilletAbsence(
begin="2021-01-22 00:00",
end="2021-01-22 23:59",
etudid=etudid,
description="abs du 22",
justified=False,
code_nip=etuds[0]["code_nip"],
code_ine=etuds[0]["code_ine"],
)
b2 = absences.AddBilletAbsence(
begin="2021-01-15 00:00",
end="2021-01-15 23:59",
etudid=etudid,
description="abs du 15",
code_nip=etuds[0]["code_nip"],
code_ine=etuds[0]["code_ine"],
)
li_bi = absences.listeBilletsEtud(etudid=etudid, format="json").get_data(
as_text=True
)
assert isinstance(li_bi, str)
load_li_bi = json.loads(li_bi)
assert len(load_li_bi) == 2
assert load_li_bi[1]["description"] == "abs du 22"
# -*- mode: python -*-
# -*- coding: utf-8 -*-
"""
Créer et justifier des absences en utilisant le parametre demijournee
"""
# test écrit par Fares Amer, mai 2021 et porté sur ScoDoc 8 en juillet 2021
import json
from tests.unit import sco_fake_gen
from app.scodoc import sco_abs
from app.scodoc import sco_abs_views
from app.scodoc import sco_groups
from app.views import absences
def test_abs_demijournee(test_client):
"""Opération élémentaires sur les absences, tests demi-journées
Travaille dans base TEST00 (defaut)
"""
G = sco_fake_gen.ScoFake(verbose=False)
# --- Création d'étudiants
etud = G.create_etud(code_nip=None)
# --- Création d'une formation
f = G.create_formation(acronyme="")
ue = G.create_ue(formation_id=f["formation_id"], acronyme="TST1", titre="ue test")
mat = G.create_matiere(ue_id=ue["ue_id"], titre="matière test")
mod = G.create_module(
matiere_id=mat["matiere_id"],
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
)
# --- Mise place d'un semestre
sem = G.create_formsemestre(
formation_id=f["formation_id"],
semestre_id=1,
date_debut="01/01/2021",
date_fin="30/06/2021",
)
mi = G.create_moduleimpl(
module_id=mod["module_id"],
formsemestre_id=sem["formsemestre_id"],
)
# --- Inscription des étudiants
G.inscrit_etudiant(sem, etud)
# --- Saisie absences
etudid = etud["etudid"]
_ = sco_abs_views.doSignaleAbsence(
"15/01/2021",
"15/01/2021",
demijournee=2,
etudid=etudid,
)
_ = sco_abs_views.doSignaleAbsence(
"18/01/2021",
"18/01/2021",
demijournee=1,
etudid=etudid,
)
_ = sco_abs_views.doSignaleAbsence(
"19/01/2021",
"19/01/2021",
demijournee=0,
etudid=etudid,
)
# --- Justification de certaines absences
_ = sco_abs_views.doJustifAbsence(
"18/01/2021",
"18/01/2021",
demijournee=1,
etudid=etudid,
)
_ = sco_abs_views.doJustifAbsence(
"19/01/2021",
"19/01/2021",
demijournee=2,
etudid=etudid,
)
# NE JUSTIFIE QUE LE MATIN MALGRES LE PARAMETRE demijournee = 2
# --- Test
nbabs, nbabs_just = sco_abs.get_abs_count(etudid, sem)
assert (
nbabs == 4
) # l'étudiant a été absent le 15 journée compléte (2 abs : 1 matin, 1 apres midi) et le 18 (1 matin), et le 19 (1 apres midi).
assert nbabs_just == 2 # Justifie abs du matin + abs après midi
def test_abs_basic(test_client):
"""creation de 10 étudiants, formation, semestre, ue, module, absences le matin, l'apres midi, la journée compléte
et justification d'absences, supression d'absences, création d'une liste etat absences, creation d'un groupe afin
de tester la fonction EtatAbsencesGroupes
Fonctions de l'API utilisé :
- doSignaleAbsence
- doAnnuleAbsence
- doJustifAbsence
- get_partition_groups
- get_partitions_list
- sco_abs.get_abs_count(etudid, sem)
- ListeAbsEtud
- partition_create
- createGroup
- set_group
- EtatAbsenceGr
- AddBilletAbsence
- listeBilletsEtud
"""
G = sco_fake_gen.ScoFake(verbose=False)
# --- Création d'étudiants
etuds = [G.create_etud(code_nip=None) for _ in range(10)]
# --- Création d'une formation
f = G.create_formation(acronyme="")
ue = G.create_ue(formation_id=f["formation_id"], acronyme="TST1", titre="ue test")
mat = G.create_matiere(ue_id=ue["ue_id"], titre="matière test")
mod = G.create_module(
matiere_id=mat["matiere_id"],
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
)
# --- Mise place d'un semestre
sem = G.create_formsemestre(
formation_id=f["formation_id"],
semestre_id=1,
date_debut="01/01/2021",
date_fin="30/06/2021",
)
mi = G.create_moduleimpl(
module_id=mod["module_id"],
formsemestre_id=sem["formsemestre_id"],
)
# --- Inscription des étudiants
for etud in etuds:
G.inscrit_etudiant(sem, etud)
# --- Création d'une évaluation
e = G.create_evaluation(
moduleimpl_id=mi["moduleimpl_id"],
jour="22/01/2021",
description="evaluation test",
coefficient=1.0,
)
# --- Saisie absences
etudid = etuds[0]["etudid"]
_ = sco_abs_views.doSignaleAbsence(
"15/01/2021",
"15/01/2021",
demijournee=1,
etudid=etudid,
)
_ = sco_abs_views.doSignaleAbsence(
"18/01/2021",
"18/01/2021",
demijournee=0,
etudid=etudid,
)
_ = sco_abs_views.doSignaleAbsence(
"19/01/2021",
"19/01/2021",
demijournee=2,
etudid=etudid,
)
_ = sco_abs_views.doSignaleAbsence(
"22/01/2021",
"22/01/2021",
demijournee=1,
etudid=etudid,
)
# --- Justification de certaines absences
_ = sco_abs_views.doJustifAbsence(
"15/01/2021",
"15/01/2021",
demijournee=1,
etudid=etudid,
)
_ = sco_abs_views.doJustifAbsence(
"18/01/2021",
"18/01/2021",
demijournee=0,
etudid=etudid,
)
_ = sco_abs_views.doJustifAbsence(
"19/01/2021",
"19/01/2021",
demijournee=2,
etudid=etudid,
)
# --- Test
b = sco_abs.is_work_saturday()
assert b == 0 # samedi ne sont pas compris
nbabs, nbabsjust = sco_abs.get_abs_count(etudid, sem)
# l'étudiant a été absent le 15 (apres midi) , (16 et 17 we),
# 18 (matin) et 19 janvier (matin et apres midi), et 22 (matin)
assert nbabs == 5
# l'étudiant justifie ses abs du 15, 18 et 19
assert nbabsjust == 4
# --- Suppression d'une absence et d'une justification
_ = sco_abs_views.doAnnuleAbsence("19/01/2021", "19/01/2021", 2, etudid=etudid)
nbabs, nbabsjust = sco_abs.get_abs_count(etudid, sem)
assert nbabs == 3
assert nbabsjust == 2
# --- suppression d'une justification pas encore disponible à l'aide de python.
# --- Création d'une liste d'abs
liste_abs = sco_abs_views.ListeAbsEtud(
etudid, format="json", absjust_only=1, sco_year="2020"
).get_data(as_text=True)
liste_abs2 = sco_abs_views.ListeAbsEtud(
etudid, format="json", sco_year="2020"
).get_data(as_text=True)
load_liste_abs = json.loads(liste_abs)
load_liste_abs2 = json.loads(liste_abs2)
assert len(load_liste_abs2) == 1
assert len(load_liste_abs) == 2
assert load_liste_abs2[0]["ampm"] == 1
assert load_liste_abs2[0]["datedmy"] == "22/01/2021"
assert load_liste_abs2[0]["exams"] == mod["code"]
# absjust_only -> seulement les abs justifiés
# --- Création d'un groupe
_ = sco_groups.partition_create(
formsemestre_id=sem["formsemestre_id"],
partition_name="Eleve",
)
li1 = sco_groups.get_partitions_list(sem["formsemestre_id"])
_ = sco_groups.createGroup(li1[0]["partition_id"], "Groupe 1")
# --- Affectation des élèves dans des groupes
li_grp1 = sco_groups.get_partition_groups(li1[0])
for etud in etuds:
sco_groups.set_group(etud["etudid"], li_grp1[0]["group_id"])
# --- Test de EtatAbsencesGroupes
grp1_abs = absences.EtatAbsencesGr(
group_ids=[li_grp1[0]["group_id"]],
debut="01/01/2021",
fin="30/06/2021",
format="json",
)
# grp1_abs est une Response car on a appelé une vue (1er appel)
load_grp1_abs = json.loads(grp1_abs.get_data(as_text=True))
assert len(load_grp1_abs) == 10
tab_id = [] # tab des id present dans load_grp1_abs
for un_etud in load_grp1_abs:
tab_id.append(un_etud["etudid"])
for (
etud
) in (
etuds
): # verification si tous les etudiants sont present dans la liste du groupe d'absence
assert etud["etudid"] in tab_id
for un_etud in load_grp1_abs:
if un_etud["etudid"] == etudid:
assert un_etud["nbabs"] == 3
assert un_etud["nbjustifs_noabs"] == 2
assert un_etud["nbabsjust"] == 2
assert un_etud["nbabsnonjust"] == 1
assert un_etud["nomprenom"] == etuds[0]["nomprenom"]
# --- Création de billets
b1 = absences.AddBilletAbsence(
begin="2021-01-22 00:00",
end="2021-01-22 23:59",
etudid=etudid,
description="abs du 22",
justified=False,
code_nip=etuds[0]["code_nip"],
code_ine=etuds[0]["code_ine"],
)
b2 = absences.AddBilletAbsence(
begin="2021-01-15 00:00",
end="2021-01-15 23:59",
etudid=etudid,
description="abs du 15",
code_nip=etuds[0]["code_nip"],
code_ine=etuds[0]["code_ine"],
)
li_bi = absences.listeBilletsEtud(etudid=etudid, format="json").get_data(
as_text=True
)
assert isinstance(li_bi, str)
load_li_bi = json.loads(li_bi)
assert len(load_li_bi) == 2
assert load_li_bi[1]["description"] == "abs du 22"

View File

@ -1,379 +1,379 @@
# -*- mode: python -*-
# -*- coding: utf-8 -*-
""" Test creation/edition/import/export formations
"""
# test écrit par Fares Amer, mai 2021 et porté sur ScoDoc 8 en juillet 2021
# Créer 2 formations, une test et une normale. Créer 2 semestres dans la formation normale et un
# dans la formation test, créer 2 semestres dans la formation normale (un test et un normal),
# 2 ue (un test et un normal), 2 modules (un test et un normal) et 2 matieres (test et normal).
# Et dans la formations test, un semestre, un module, un ue et une matiere.
# Afficher la liste de tout ca puis supprimer les ue, mod, mat et sem test ainsi
# que la formation test. Afficher la liste des UE, formations et modules restante.
#
# Vérification :
#
# - Les listes initiales comprennent bien tout les éléments créés avec les bon noms etc
# - La supression s'est bien effectué au niveau de scodoc web et en python
# - Vérifier que les fonctions listes font bien la mise à jour après supression
#
# Fonction de l'API utilisé :
#
# - create_formation
# - create_ue
# - create_matiere
# - create_module
# - create_formsemestre
# - create_moduleimpl
# - formation_list
# - formation_export
# - formsemestre_list
# - do_moduleimpl_list
# - do_module_impl_with_module_list
# - do_formsemestre_delete
# - do_module_list
# - do_module_delete
# - do_matiere_list
# - do_matiere_delete
# - do_ue_list
# - do_ue_delete
# - do_formation_delete
import json
import xml.dom.minidom
import flask
from flask import g
from tests.unit import sco_fake_gen
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_formations
from app.scodoc import sco_formsemestre_edit
from app.scodoc import sco_moduleimpl
from app.views import notes
def test_formations(test_client):
"""Test création/édition/import/export formations"""
G = sco_fake_gen.ScoFake(verbose=False)
# --- Création de formations
f = G.create_formation(
acronyme="F1", titre="Formation 1", titre_officiel="Titre officiel 1"
)
ue = G.create_ue(formation_id=f["formation_id"], acronyme="TST1", titre="ue test")
mat = G.create_matiere(ue_id=ue["ue_id"], titre="matière test")
mod = G.create_module(
matiere_id=mat["matiere_id"],
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
)
ue2 = G.create_ue(formation_id=f["formation_id"], acronyme="TST2", titre="ue test2")
mat2 = G.create_matiere(ue_id=ue2["ue_id"], titre="matière test2")
mod2 = G.create_module(
matiere_id=mat2["matiere_id"],
code="TSM2",
coefficient=1.0,
titre="module test",
ue_id=ue2["ue_id"], # faiblesse de l'API
formation_id=f["formation_id"], # faiblesse de l'API
)
uet = G.create_ue(formation_id=f["formation_id"], acronyme="TSTt", titre="ue testt")
matt = G.create_matiere(ue_id=uet["ue_id"], titre="matière testt")
modt = G.create_module(
matiere_id=matt["matiere_id"],
code="TSMt",
coefficient=1.0,
titre="module test",
ue_id=uet["ue_id"], # faiblesse de l'API
formation_id=f["formation_id"], # faiblesse de l'API
)
f2 = G.create_formation(acronyme="", titre="Formation test")
ue3 = G.create_ue(
formation_id=f2["formation_id"], acronyme="TST3", titre="ue test3"
)
mat3 = G.create_matiere(ue_id=ue3["ue_id"], titre="matière test3")
mod3 = G.create_module(
matiere_id=mat3["matiere_id"],
code="TSM3",
coefficient=1.0,
titre="module test3",
ue_id=ue3["ue_id"], # faiblesse de l'API
formation_id=f2["formation_id"], # faiblesse de l'API
)
# --- Création et implémentation des semestres
sem1 = G.create_formsemestre(
formation_id=f["formation_id"],
semestre_id=1,
date_debut="01/01/2021",
date_fin="30/06/2021",
)
sem2 = G.create_formsemestre(
formation_id=f["formation_id"],
semestre_id=2,
date_debut="01/09/2020",
date_fin="31/12/2020",
)
mi = G.create_moduleimpl(
module_id=mod["module_id"],
formsemestre_id=sem1["formsemestre_id"],
)
mi2 = G.create_moduleimpl(
module_id=mod2["module_id"],
formsemestre_id=sem1["formsemestre_id"],
)
mit = G.create_moduleimpl(
module_id=modt["module_id"],
formsemestre_id=sem2["formsemestre_id"],
)
semt = G.create_formsemestre(
formation_id=f2["formation_id"],
semestre_id=3,
date_debut="01/01/2021",
date_fin="30/06/2021",
)
mi3 = G.create_moduleimpl(
module_id=mod3["module_id"],
formsemestre_id=semt["formsemestre_id"],
)
# --- Afficher la liste des formations
lif = notes.formation_list(format="json", formation_id=f["formation_id"])
# lif est une Response car on a appelé une vue (1er appel)
assert isinstance(lif, flask.Response)
load_lif = json.loads(lif.get_data().decode("utf-8"))
assert len(load_lif) == 1
assert load_lif[0]["acronyme"] == f["acronyme"]
assert load_lif[0]["titre_officiel"] == f["titre_officiel"]
assert load_lif[0]["formation_id"] == f["formation_id"]
assert load_lif[0]["titre"] == f["titre"]
lif2 = notes.formation_list(format="json").get_data(as_text=True)
# lif2 est un chaine
assert isinstance(lif2, str)
load_lif2 = json.loads(lif2)
assert len(load_lif2) == 2
assert load_lif2[0] == load_lif[0]
assert load_lif2[1]["titre"] == f2["titre"]
# --- Export de formation_id
exp = sco_formations.formation_export(
formation_id=f["formation_id"], format="json"
).get_data(as_text=True)
assert isinstance(exp, str)
load_exp = json.loads(exp)
assert load_exp["acronyme"] == "F1"
assert load_exp["titre_officiel"] == "Titre officiel 1"
assert load_exp["titre"] == "Formation 1"
assert load_exp["formation_code"] == f["formation_code"]
assert len(load_exp["ue"]) == 3
assert load_exp["ue"][0]["acronyme"] == "TST1"
assert load_exp["ue"][0]["titre"] == "ue test"
assert load_exp["formation_id"] == f["formation_id"]
assert load_exp["formation_code"] == f["formation_code"]
# --- Liste des semestres
li_sem1 = notes.formsemestre_list(
formsemestre_id=sem1["formsemestre_id"], format="json"
).get_data(as_text=True)
assert isinstance(li_sem1, str)
load_li_sem1 = json.loads(li_sem1) # uniquement le semestre 1 dans la liste
assert len(load_li_sem1) == 1
assert load_li_sem1[0]["date_fin"] == sem1["date_fin"]
assert load_li_sem1[0]["semestre_id"] == sem1["semestre_id"]
assert load_li_sem1[0]["formation_id"] == sem1["formation_id"]
li_semf = notes.formsemestre_list(
formation_id=f["formation_id"],
format="json",
).get_data(as_text=True)
assert isinstance(li_semf, str)
load_li_semf = json.loads(li_semf)
assert load_li_sem1[0] in load_li_semf
assert len(load_li_semf) == 2
assert load_li_semf[1]["semestre_id"] == sem2["semestre_id"]
li_sem = notes.formsemestre_list(format="json").get_data(as_text=True)
load_li_sem = json.loads(li_sem)
assert len(load_li_sem) == 3
assert load_li_semf[0] and load_li_semf[1] in load_li_sem
assert load_li_sem[0]["semestre_id"] == semt["semestre_id"]
# --- Liste des modules
lim_sem1 = sco_moduleimpl.do_moduleimpl_list(
formsemestre_id=sem1["formsemestre_id"]
)
assert len(lim_sem1) == 2
assert mod["module_id"] in (lim_sem1[0]["module_id"], lim_sem1[1]["module_id"])
assert mod2["module_id"] in (lim_sem1[0]["module_id"], lim_sem1[1]["module_id"])
lim_modid = sco_moduleimpl.do_moduleimpl_list(module_id=mod["module_id"])
assert len(lim_modid) == 1
lim_modimpl_id = sco_moduleimpl.do_moduleimpl_list(
moduleimpl_id=mi["moduleimpl_id"]
)
# print(lim_modimpl_id)
# ---- Test de do_moduleimpl_withmodule_list
assert lim_modid == lim_modimpl_id # doit etre le meme resultat
liimp_sem1 = sco_moduleimpl.do_moduleimpl_withmodule_list(
formsemestre_id=sem1["formsemestre_id"]
)
assert len(liimp_sem1) == 2
assert mod["module_id"] in (liimp_sem1[0]["module_id"], liimp_sem1[1]["module_id"])
assert mod2["module_id"] in (
liimp_sem1[0]["module_id"],
liimp_sem1[1]["module_id"],
)
liimp_sem2 = sco_moduleimpl.do_moduleimpl_withmodule_list(
formsemestre_id=sem2["formsemestre_id"]
)
assert modt["module_id"] == liimp_sem2[0]["module_id"]
liimp_modid = sco_moduleimpl.do_moduleimpl_withmodule_list(
module_id=mod["module_id"]
)
assert len(liimp_modid) == 1
liimp_modimplid = sco_moduleimpl.do_moduleimpl_withmodule_list(
moduleimpl_id=mi["moduleimpl_id"]
)
assert liimp_modid == liimp_modimplid
# --- Suppression du module, matiere et ue test du semestre 2
# on doit d'abbord supprimer le semestre
# sco_formsemestre_edit.formsemestre_delete( formsemestre_id=sem2["formsemestre_id"], REQUEST=REQUEST)
# sco_formsemestre_edit.formsemestre_createwithmodules( formsemestre_id=sem2["formsemestre_id"], REQUEST=REQUEST)
# RIEN NE SE PASSE AVEC CES FONCTIONS
sco_formsemestre_edit.do_formsemestre_delete(
formsemestre_id=sem2["formsemestre_id"]
)
# sco_edit_module.module_delete( module_id=modt["module_id"], REQUEST=REQUEST)
# sco_edit_matiere.matiere_delete( matiere_id=matt["matiere_id"], REQUEST=REQUEST)
# sco_edit_ue.ue_delete( ue_id=uet["ue_id"], REQUEST=REQUEST)
# RIEN NE SE PASSE AVEC CES FONCTIONS
li_module = sco_edit_module.do_module_list()
assert len(li_module) == 4
sco_edit_module.do_module_delete(oid=modt["module_id"]) # on supprime le semestre
# sco_formsemestre_edit.formsemestre_delete_moduleimpls( formsemestre_id=sem2["formsemestre_id"], module_ids_to_del=[modt["module_id"]])
# deuxieme methode de supression d'un module
li_module2 = sco_edit_module.do_module_list()
assert len(li_module2) == 3 # verification de la suppression du module
lim_sem2 = sco_moduleimpl.do_moduleimpl_list(
formsemestre_id=sem2["formsemestre_id"]
)
assert len(lim_sem2) == 0 # deuxieme vérification si le module s'est bien sup
li_mat = sco_edit_matiere.do_matiere_list()
assert len(li_mat) == 4
sco_edit_matiere.do_matiere_delete(oid=matt["matiere_id"]) # on supprime la matiere
li_mat2 = sco_edit_matiere.do_matiere_list()
assert len(li_mat2) == 3 # verification de la suppression de la matiere
li_ue = sco_edit_ue.do_ue_list()
assert len(li_ue) == 4
sco_edit_ue.ue_delete(ue_id=uet["ue_id"], dialog_confirmed=True)
li_ue2 = sco_edit_ue.do_ue_list()
assert len(li_ue2) == 3 # verification de la suppression de l'UE
# --- Suppression d'une formation
# Il faut d'abbord supprimer le semestre aussi.
sco_formsemestre_edit.do_formsemestre_delete(
formsemestre_id=semt["formsemestre_id"]
)
sco_edit_formation.do_formation_delete(oid=f2["formation_id"])
lif3 = notes.formation_list(format="json").get_data(as_text=True)
assert isinstance(lif3, str)
load_lif3 = json.loads(lif3)
assert len(load_lif3) == 1
def test_import_formation(test_client):
"""Test import/export formations"""
G = sco_fake_gen.ScoFake(verbose=False)
# Lecture fichier XML local:
with open("tests/unit/formation-exemple-1.xml") as f:
doc = f.read()
# --- Création de la formation
f = sco_formations.formation_import_xml(doc)
assert len(f) == 3 # 3-uple
formation_id = f[0]
# --- Mise en place de 4 semestres
sems = [
G.create_formsemestre(
formation_id=formation_id,
semestre_id=x[0],
date_debut=x[1],
date_fin=x[2],
)
for x in (
(1, "05/09/2019", "05/01/2020"),
(2, "06/01/2020", "30/06/2020"),
(3, "01/09/2020", "05/01/2021"),
(4, "06/01/2021", "30/06/2021"),
)
]
# et les modules
modules = sco_edit_module.do_module_list({"formation_id": formation_id})
for mod in modules:
mi = G.create_moduleimpl(
module_id=mod["module_id"],
formsemestre_id=sems[mod["semestre_id"] - 1]["formsemestre_id"],
)
assert mi["ens"] == []
assert mi["module_id"] == mod["module_id"]
# --- Export formation en XML
doc1 = sco_formations.formation_export(formation_id, format="xml").get_data(
as_text=True
)
assert isinstance(doc1, str)
# -*- mode: python -*-
# -*- coding: utf-8 -*-
""" Test creation/edition/import/export formations
"""
# test écrit par Fares Amer, mai 2021 et porté sur ScoDoc 8 en juillet 2021
# Créer 2 formations, une test et une normale. Créer 2 semestres dans la formation normale et un
# dans la formation test, créer 2 semestres dans la formation normale (un test et un normal),
# 2 ue (un test et un normal), 2 modules (un test et un normal) et 2 matieres (test et normal).
# Et dans la formations test, un semestre, un module, un ue et une matiere.
# Afficher la liste de tout ca puis supprimer les ue, mod, mat et sem test ainsi
# que la formation test. Afficher la liste des UE, formations et modules restante.
#
# Vérification :
#
# - Les listes initiales comprennent bien tout les éléments créés avec les bon noms etc
# - La supression s'est bien effectué au niveau de scodoc web et en python
# - Vérifier que les fonctions listes font bien la mise à jour après supression
#
# Fonction de l'API utilisé :
#
# - create_formation
# - create_ue
# - create_matiere
# - create_module
# - create_formsemestre
# - create_moduleimpl
# - formation_list
# - formation_export
# - formsemestre_list
# - do_moduleimpl_list
# - do_module_impl_with_module_list
# - do_formsemestre_delete
# - do_module_list
# - do_module_delete
# - do_matiere_list
# - do_matiere_delete
# - do_ue_list
# - do_ue_delete
# - do_formation_delete
import json
import xml.dom.minidom
import flask
from flask import g
from tests.unit import sco_fake_gen
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_formations
from app.scodoc import sco_formsemestre_edit
from app.scodoc import sco_moduleimpl
from app.views import notes
def test_formations(test_client):
"""Test création/édition/import/export formations"""
G = sco_fake_gen.ScoFake(verbose=False)
# --- Création de formations
f = G.create_formation(
acronyme="F1", titre="Formation 1", titre_officiel="Titre officiel 1"
)
ue = G.create_ue(formation_id=f["formation_id"], acronyme="TST1", titre="ue test")
mat = G.create_matiere(ue_id=ue["ue_id"], titre="matière test")
mod = G.create_module(
matiere_id=mat["matiere_id"],
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
)
ue2 = G.create_ue(formation_id=f["formation_id"], acronyme="TST2", titre="ue test2")
mat2 = G.create_matiere(ue_id=ue2["ue_id"], titre="matière test2")
mod2 = G.create_module(
matiere_id=mat2["matiere_id"],
code="TSM2",
coefficient=1.0,
titre="module test",
ue_id=ue2["ue_id"], # faiblesse de l'API
formation_id=f["formation_id"], # faiblesse de l'API
)
uet = G.create_ue(formation_id=f["formation_id"], acronyme="TSTt", titre="ue testt")
matt = G.create_matiere(ue_id=uet["ue_id"], titre="matière testt")
modt = G.create_module(
matiere_id=matt["matiere_id"],
code="TSMt",
coefficient=1.0,
titre="module test",
ue_id=uet["ue_id"], # faiblesse de l'API
formation_id=f["formation_id"], # faiblesse de l'API
)
f2 = G.create_formation(acronyme="", titre="Formation test")
ue3 = G.create_ue(
formation_id=f2["formation_id"], acronyme="TST3", titre="ue test3"
)
mat3 = G.create_matiere(ue_id=ue3["ue_id"], titre="matière test3")
mod3 = G.create_module(
matiere_id=mat3["matiere_id"],
code="TSM3",
coefficient=1.0,
titre="module test3",
ue_id=ue3["ue_id"], # faiblesse de l'API
formation_id=f2["formation_id"], # faiblesse de l'API
)
# --- Création et implémentation des semestres
sem1 = G.create_formsemestre(
formation_id=f["formation_id"],
semestre_id=1,
date_debut="01/01/2021",
date_fin="30/06/2021",
)
sem2 = G.create_formsemestre(
formation_id=f["formation_id"],
semestre_id=2,
date_debut="01/09/2020",
date_fin="31/12/2020",
)
mi = G.create_moduleimpl(
module_id=mod["module_id"],
formsemestre_id=sem1["formsemestre_id"],
)
mi2 = G.create_moduleimpl(
module_id=mod2["module_id"],
formsemestre_id=sem1["formsemestre_id"],
)
mit = G.create_moduleimpl(
module_id=modt["module_id"],
formsemestre_id=sem2["formsemestre_id"],
)
semt = G.create_formsemestre(
formation_id=f2["formation_id"],
semestre_id=3,
date_debut="01/01/2021",
date_fin="30/06/2021",
)
mi3 = G.create_moduleimpl(
module_id=mod3["module_id"],
formsemestre_id=semt["formsemestre_id"],
)
# --- Afficher la liste des formations
lif = notes.formation_list(format="json", formation_id=f["formation_id"])
# lif est une Response car on a appelé une vue (1er appel)
assert isinstance(lif, flask.Response)
load_lif = json.loads(lif.get_data().decode("utf-8"))
assert len(load_lif) == 1
assert load_lif[0]["acronyme"] == f["acronyme"]
assert load_lif[0]["titre_officiel"] == f["titre_officiel"]
assert load_lif[0]["formation_id"] == f["formation_id"]
assert load_lif[0]["titre"] == f["titre"]
lif2 = notes.formation_list(format="json").get_data(as_text=True)
# lif2 est un chaine
assert isinstance(lif2, str)
load_lif2 = json.loads(lif2)
assert len(load_lif2) == 2
assert load_lif2[0] == load_lif[0]
assert load_lif2[1]["titre"] == f2["titre"]
# --- Export de formation_id
exp = sco_formations.formation_export(
formation_id=f["formation_id"], format="json"
).get_data(as_text=True)
assert isinstance(exp, str)
load_exp = json.loads(exp)
assert load_exp["acronyme"] == "F1"
assert load_exp["titre_officiel"] == "Titre officiel 1"
assert load_exp["titre"] == "Formation 1"
assert load_exp["formation_code"] == f["formation_code"]
assert len(load_exp["ue"]) == 3
assert load_exp["ue"][0]["acronyme"] == "TST1"
assert load_exp["ue"][0]["titre"] == "ue test"
assert load_exp["formation_id"] == f["formation_id"]
assert load_exp["formation_code"] == f["formation_code"]
# --- Liste des semestres
li_sem1 = notes.formsemestre_list(
formsemestre_id=sem1["formsemestre_id"], format="json"
).get_data(as_text=True)
assert isinstance(li_sem1, str)
load_li_sem1 = json.loads(li_sem1) # uniquement le semestre 1 dans la liste
assert len(load_li_sem1) == 1
assert load_li_sem1[0]["date_fin"] == sem1["date_fin"]
assert load_li_sem1[0]["semestre_id"] == sem1["semestre_id"]
assert load_li_sem1[0]["formation_id"] == sem1["formation_id"]
li_semf = notes.formsemestre_list(
formation_id=f["formation_id"],
format="json",
).get_data(as_text=True)
assert isinstance(li_semf, str)
load_li_semf = json.loads(li_semf)
assert load_li_sem1[0] in load_li_semf
assert len(load_li_semf) == 2
assert load_li_semf[1]["semestre_id"] == sem2["semestre_id"]
li_sem = notes.formsemestre_list(format="json").get_data(as_text=True)
load_li_sem = json.loads(li_sem)
assert len(load_li_sem) == 3
assert load_li_semf[0] and load_li_semf[1] in load_li_sem
assert load_li_sem[0]["semestre_id"] == semt["semestre_id"]
# --- Liste des modules
lim_sem1 = sco_moduleimpl.do_moduleimpl_list(
formsemestre_id=sem1["formsemestre_id"]
)
assert len(lim_sem1) == 2
assert mod["module_id"] in (lim_sem1[0]["module_id"], lim_sem1[1]["module_id"])
assert mod2["module_id"] in (lim_sem1[0]["module_id"], lim_sem1[1]["module_id"])
lim_modid = sco_moduleimpl.do_moduleimpl_list(module_id=mod["module_id"])
assert len(lim_modid) == 1
lim_modimpl_id = sco_moduleimpl.do_moduleimpl_list(
moduleimpl_id=mi["moduleimpl_id"]
)
# print(lim_modimpl_id)
# ---- Test de do_moduleimpl_withmodule_list
assert lim_modid == lim_modimpl_id # doit etre le meme resultat
liimp_sem1 = sco_moduleimpl.do_moduleimpl_withmodule_list(
formsemestre_id=sem1["formsemestre_id"]
)
assert len(liimp_sem1) == 2
assert mod["module_id"] in (liimp_sem1[0]["module_id"], liimp_sem1[1]["module_id"])
assert mod2["module_id"] in (
liimp_sem1[0]["module_id"],
liimp_sem1[1]["module_id"],
)
liimp_sem2 = sco_moduleimpl.do_moduleimpl_withmodule_list(
formsemestre_id=sem2["formsemestre_id"]
)
assert modt["module_id"] == liimp_sem2[0]["module_id"]
liimp_modid = sco_moduleimpl.do_moduleimpl_withmodule_list(
module_id=mod["module_id"]
)
assert len(liimp_modid) == 1
liimp_modimplid = sco_moduleimpl.do_moduleimpl_withmodule_list(
moduleimpl_id=mi["moduleimpl_id"]
)
assert liimp_modid == liimp_modimplid
# --- Suppression du module, matiere et ue test du semestre 2
# on doit d'abbord supprimer le semestre
# sco_formsemestre_edit.formsemestre_delete( formsemestre_id=sem2["formsemestre_id"], REQUEST=REQUEST)
# sco_formsemestre_edit.formsemestre_createwithmodules( formsemestre_id=sem2["formsemestre_id"], REQUEST=REQUEST)
# RIEN NE SE PASSE AVEC CES FONCTIONS
sco_formsemestre_edit.do_formsemestre_delete(
formsemestre_id=sem2["formsemestre_id"]
)
# sco_edit_module.module_delete( module_id=modt["module_id"], REQUEST=REQUEST)
# sco_edit_matiere.matiere_delete( matiere_id=matt["matiere_id"], REQUEST=REQUEST)
# sco_edit_ue.ue_delete( ue_id=uet["ue_id"], REQUEST=REQUEST)
# RIEN NE SE PASSE AVEC CES FONCTIONS
li_module = sco_edit_module.do_module_list()
assert len(li_module) == 4
sco_edit_module.do_module_delete(oid=modt["module_id"]) # on supprime le semestre
# sco_formsemestre_edit.formsemestre_delete_moduleimpls( formsemestre_id=sem2["formsemestre_id"], module_ids_to_del=[modt["module_id"]])
# deuxieme methode de supression d'un module
li_module2 = sco_edit_module.do_module_list()
assert len(li_module2) == 3 # verification de la suppression du module
lim_sem2 = sco_moduleimpl.do_moduleimpl_list(
formsemestre_id=sem2["formsemestre_id"]
)
assert len(lim_sem2) == 0 # deuxieme vérification si le module s'est bien sup
li_mat = sco_edit_matiere.do_matiere_list()
assert len(li_mat) == 4
sco_edit_matiere.do_matiere_delete(oid=matt["matiere_id"]) # on supprime la matiere
li_mat2 = sco_edit_matiere.do_matiere_list()
assert len(li_mat2) == 3 # verification de la suppression de la matiere
li_ue = sco_edit_ue.do_ue_list()
assert len(li_ue) == 4
sco_edit_ue.ue_delete(ue_id=uet["ue_id"], dialog_confirmed=True)
li_ue2 = sco_edit_ue.do_ue_list()
assert len(li_ue2) == 3 # verification de la suppression de l'UE
# --- Suppression d'une formation
# Il faut d'abbord supprimer le semestre aussi.
sco_formsemestre_edit.do_formsemestre_delete(
formsemestre_id=semt["formsemestre_id"]
)
sco_edit_formation.do_formation_delete(oid=f2["formation_id"])
lif3 = notes.formation_list(format="json").get_data(as_text=True)
assert isinstance(lif3, str)
load_lif3 = json.loads(lif3)
assert len(load_lif3) == 1
def test_import_formation(test_client):
"""Test import/export formations"""
G = sco_fake_gen.ScoFake(verbose=False)
# Lecture fichier XML local:
with open("tests/unit/formation-exemple-1.xml") as f:
doc = f.read()
# --- Création de la formation
f = sco_formations.formation_import_xml(doc)
assert len(f) == 3 # 3-uple
formation_id = f[0]
# --- Mise en place de 4 semestres
sems = [
G.create_formsemestre(
formation_id=formation_id,
semestre_id=x[0],
date_debut=x[1],
date_fin=x[2],
)
for x in (
(1, "05/09/2019", "05/01/2020"),
(2, "06/01/2020", "30/06/2020"),
(3, "01/09/2020", "05/01/2021"),
(4, "06/01/2021", "30/06/2021"),
)
]
# et les modules
modules = sco_edit_module.do_module_list({"formation_id": formation_id})
for mod in modules:
mi = G.create_moduleimpl(
module_id=mod["module_id"],
formsemestre_id=sems[mod["semestre_id"] - 1]["formsemestre_id"],
)
assert mi["ens"] == []
assert mi["module_id"] == mod["module_id"]
# --- Export formation en XML
doc1 = sco_formations.formation_export(formation_id, format="xml").get_data(
as_text=True
)
assert isinstance(doc1, str)