1
0
forked from ScoDoc/ScoDoc

API: ajout samples + amélioration des tests

This commit is contained in:
Emmanuel Viennet 2024-07-27 13:30:02 +02:00
parent 4824b33358
commit 75c10a4917
31 changed files with 522 additions and 741 deletions

View File

@ -25,6 +25,7 @@ from app.models import BilletAbsence
from app.models.etudiants import Identite from app.models.etudiants import Identite
from app.scodoc import sco_abs_billets from app.scodoc import sco_abs_billets
from app.scodoc.sco_permissions import Permission from app.scodoc.sco_permissions import Permission
from app.scodoc import sco_utils as scu
@bp.route("/billets_absence/etudiant/<int:etudid>") @bp.route("/billets_absence/etudiant/<int:etudid>")
@ -59,13 +60,17 @@ def billets_absence_create():
"justified" : bool "justified" : bool
} }
``` ```
SAMPLES
-------
/billets_absence/create;{""etudid"":""1"",""abs_begin"":""2023-10-27T10:00"",""abs_end"":""2023-10-28T10:00"",""description"":""grave malade"",""justified"":""1""}
""" """
data = request.get_json(force=True) # may raise 400 Bad Request data = request.get_json(force=True) # may raise 400 Bad Request
etudid = data.get("etudid") etudid = data.get("etudid")
abs_begin = data.get("abs_begin") abs_begin = data.get("abs_begin")
abs_end = data.get("abs_end") abs_end = data.get("abs_end")
description = data.get("description", "") description = data.get("description", "")
justified = data.get("justified", False) justified = scu.to_bool(data.get("justified", False))
if None in (etudid, abs_begin, abs_end): if None in (etudid, abs_begin, abs_end):
return json_error( return json_error(
404, message="Paramètre manquant: etudid, abs_begin, abs_end requis" 404, message="Paramètre manquant: etudid, abs_begin, abs_end requis"

View File

@ -38,7 +38,13 @@ from app.scodoc.sco_utils import json_error
@permission_required(Permission.ScoView) @permission_required(Permission.ScoView)
@as_json @as_json
def departements_list(): def departements_list():
"""Liste tous les départements.""" """Liste tous les départements.
SAMPLES
-------
/departements;
"""
return [dept.to_dict(with_dept_name=True) for dept in Departement.query] return [dept.to_dict(with_dept_name=True) for dept in Departement.query]
@ -48,7 +54,13 @@ def departements_list():
@permission_required(Permission.ScoView) @permission_required(Permission.ScoView)
@as_json @as_json
def departements_ids(): def departements_ids():
"""Liste des ids de tous les départements.""" """Liste des ids de tous les départements.
SAMPLES
-------
/departements_ids;
"""
return [dept.id for dept in Departement.query] return [dept.id for dept in Departement.query]
@ -61,17 +73,10 @@ def departement_by_acronym(acronym: str):
""" """
Info sur un département. Accès par acronyme. Info sur un département. Accès par acronyme.
Exemple de résultat : SAMPLES
```json -------
{ /departement/TAPI;
"id": 1,
"acronym": "TAPI",
"dept_name" : "TEST",
"description": null,
"visible": true,
"date_creation": "Fri, 15 Apr 2022 12:19:28 GMT"
}
```
""" """
dept = Departement.query.filter_by(acronym=acronym).first_or_404() dept = Departement.query.filter_by(acronym=acronym).first_or_404()
return dept.to_dict(with_dept_name=True) return dept.to_dict(with_dept_name=True)
@ -82,9 +87,14 @@ def departement_by_acronym(acronym: str):
@scodoc @scodoc
@permission_required(Permission.ScoView) @permission_required(Permission.ScoView)
@as_json @as_json
def departement_by_id(dept_id: int): def departement_get(dept_id: int):
""" """
Info sur un département. Accès par id. Info sur un département. Accès par id.
SAMPLES
-------
/departement/id/1;
""" """
dept = Departement.query.get_or_404(dept_id) dept = Departement.query.get_or_404(dept_id)
return dept.to_dict() return dept.to_dict()
@ -107,6 +117,10 @@ def departement_create():
"visible": bool, "visible": bool,
} }
``` ```
SAMPLES
-------
/departement/create;{""acronym"":""MYDEPT"",""visible"":""1""}
""" """
data = request.get_json(force=True) # may raise 400 Bad Request data = request.get_json(force=True) # may raise 400 Bad Request
acronym = str(data.get("acronym", "")) acronym = str(data.get("acronym", ""))
@ -180,23 +194,10 @@ def departement_etudiants(acronym: str):
------ ------
acronym : l'acronyme d'un département acronym : l'acronyme d'un département
Exemple de résultat : SAMPLES
```json -------
[ /departement/TAPI/etudiants;
{
"civilite": "M",
"code_ine": "7899X61616",
"code_nip": "F6777H88",
"date_naissance": null,
"email": "toto@toto.fr",
"emailperso": null,
"etudid": 18,
"nom": "MOREL",
"prenom": "JACQUES"
},
...
]
```
""" """
dept = Departement.query.filter_by(acronym=acronym).first_or_404() dept = Departement.query.filter_by(acronym=acronym).first_or_404()
return [etud.to_dict_short() for etud in dept.etudiants] return [etud.to_dict_short() for etud in dept.etudiants]
@ -221,7 +222,13 @@ def departement_etudiants_by_id(dept_id: int):
@permission_required(Permission.ScoView) @permission_required(Permission.ScoView)
@as_json @as_json
def departement_formsemestres_ids(acronym: str): def departement_formsemestres_ids(acronym: str):
"""Liste des ids de tous les formsemestres du département.""" """Liste des ids de tous les formsemestres du département.
SAMPLES
-------
/departement/TAPI/formsemestres_ids;
"""
dept = Departement.query.filter_by(acronym=acronym).first_or_404() dept = Departement.query.filter_by(acronym=acronym).first_or_404()
return [formsemestre.id for formsemestre in dept.formsemestres] return [formsemestre.id for formsemestre in dept.formsemestres]
@ -232,7 +239,13 @@ def departement_formsemestres_ids(acronym: str):
@permission_required(Permission.ScoView) @permission_required(Permission.ScoView)
@as_json @as_json
def departement_formsemestres_ids_by_id(dept_id: int): def departement_formsemestres_ids_by_id(dept_id: int):
"""Liste des ids de tous les formsemestres du département.""" """Liste des ids de tous les formsemestres du département.
SAMPLES
-------
/departement/id/1/formsemestres_ids;
"""
dept = Departement.query.get_or_404(dept_id) dept = Departement.query.get_or_404(dept_id)
return [formsemestre.id for formsemestre in dept.formsemestres] return [formsemestre.id for formsemestre in dept.formsemestres]
@ -253,6 +266,9 @@ def departement_formsemestres_courants(acronym: str = "", dept_id: int | None =
----- -----
date_courante:<string:date_courante> date_courante:<string:date_courante>
SAMPLES
-------
/departement/id/1/formsemestres_courants?date_courante=2022-01-01
""" """
dept = ( dept = (
Departement.query.filter_by(acronym=acronym).first_or_404() Departement.query.filter_by(acronym=acronym).first_or_404()

View File

@ -101,27 +101,16 @@ def etudiants_courants(long: bool = False):
et les formsemestres contenant la date courante, et les formsemestres contenant la date courante,
ou à défaut celle indiquée en argument (au format ISO). ou à défaut celle indiquée en argument (au format ISO).
En format "long": voir l'exemple.
QUERY QUERY
----- -----
date_courante:<string:date_courante> date_courante:<string:date_courante>
Exemple de résultat : SAMPLES
```json -------
[ /etudiants/courants?date_courante=2022-05-01;
{ /etudiants/courants/long?date_courante=2022-05-01;
"id": 1234,
"code_nip": "12345678",
"code_ine": null,
"nom": "JOHN",
"nom_usuel": None,
"prenom": "DEUF",
"civilite": "M",
}
...
]
```
En format "long": voir documentation.
""" """
allowed_depts = current_user.get_depts_with_permission(Permission.ScoView) allowed_depts = current_user.get_depts_with_permission(Permission.ScoView)
@ -436,6 +425,10 @@ def bulletin(
version : type de bulletin (par défaut, "selectedevals"): short, long, selectedevals, butcourt version : type de bulletin (par défaut, "selectedevals"): short, long, selectedevals, butcourt
pdf : si spécifié, bulletin au format PDF (et non JSON). pdf : si spécifié, bulletin au format PDF (et non JSON).
SAMPLES
-------
/etudiant/etudid/1/formsemestre/1/bulletin
""" """
if version == "pdf": if version == "pdf":
version = "long" version = "long"
@ -494,33 +487,9 @@ def etudiant_groups(formsemestre_id: int, etudid: int = None):
formsemestre_id : l'id d'un formsemestre formsemestre_id : l'id d'un formsemestre
etudid : l'etudid d'un étudiant etudid : l'etudid d'un étudiant
Exemple de résultat : SAMPLES
```json -------
[ /etudiant/etudid/1/formsemestre/1/groups
{
"partition_id": 1,
"id": 1,
"formsemestre_id": 1,
"partition_name": null,
"numero": 0,
"bul_show_rank": false,
"show_in_lists": true,
"group_id": 1,
"group_name": null
},
{
"partition_id": 2,
"id": 2,
"formsemestre_id": 1,
"partition_name": "TD",
"numero": 1,
"bul_show_rank": false,
"show_in_lists": true,
"group_id": 2,
"group_name": "A"
}
]
```
""" """
query = FormSemestre.query.filter_by(id=formsemestre_id) query = FormSemestre.query.filter_by(id=formsemestre_id)
if g.scodoc_dept: if g.scodoc_dept:
@ -627,6 +596,10 @@ def etudiant_edit(
------ ------
`code_type`: le type du code, `etudid`, `ine` ou `nip`. `code_type`: le type du code, `etudid`, `ine` ou `nip`.
`code`: la valeur du code `code`: la valeur du code
SAMPLES
-------
/etudiant/ine/INE1/edit;{""prenom"":""Nouveau Prénom"", ""adresses"":[{""email"":""nouvelle@adresse.fr""}]}
""" """
ok, etud = _get_etud_by_code(code_type, code, g.scodoc_dept) ok, etud = _get_etud_by_code(code_type, code, g.scodoc_dept)
if not ok: if not ok:
@ -682,6 +655,10 @@ def etudiant_annotation(
"comment" : string "comment" : string
} }
``` ```
SAMPLES
-------
/etudiant/etudid/1/annotation;{""comment"":""une annotation sur l'étudiant""}
""" """
if not current_user.has_permission(Permission.ViewEtudData): if not current_user.has_permission(Permission.ViewEtudData):
return json_error(403, "non autorisé (manque ViewEtudData)") return json_error(403, "non autorisé (manque ViewEtudData)")

View File

@ -84,7 +84,9 @@ def moduleimpl_evaluations(moduleimpl_id: int):
------ ------
moduleimpl_id : l'id d'un moduleimpl moduleimpl_id : l'id d'un moduleimpl
Exemple de résultat : voir `/evaluation`. SAMPLES
-------
/moduleimpl/1/evaluations
""" """
modimpl = ModuleImpl.get_modimpl(moduleimpl_id) modimpl = ModuleImpl.get_modimpl(moduleimpl_id)
return [evaluation.to_dict_api() for evaluation in modimpl.evaluations] return [evaluation.to_dict_api() for evaluation in modimpl.evaluations]
@ -104,30 +106,9 @@ def evaluation_notes(evaluation_id: int):
------ ------
evaluation_id : l'id de l'évaluation evaluation_id : l'id de l'évaluation
Exemple de résultat : SAMPLES
```json -------
{ /evaluation/2/notes;
"11": {
"etudid": 11,
"evaluation_id": 1,
"value": 15.0,
"note_max" : 20.0,
"comment": "",
"date": "2024-07-19T19:08:44+02:00",
"uid": 2
},
"12": {
"etudid": 12,
"evaluation_id": 1,
"value": "ABS",
"note_max" : 20.0,
"comment": "",
"date": "2024-07-19T19:08:44+02:00",
"uid": 2
},
...
}
```
""" """
query = Evaluation.query.filter_by(id=evaluation_id) query = Evaluation.query.filter_by(id=evaluation_id)
if g.scodoc_dept: if g.scodoc_dept:
@ -173,10 +154,14 @@ def evaluation_set_notes(evaluation_id: int): # evaluation-notes-set
Résultat: Résultat:
- nb_changed: nombre de notes changées - etudids_changed: étudiants dont la note est modifiée
- nb_suppress: nombre de notes effacées
- etudids_with_decision: liste des etudiants dont la note a changé - etudids_with_decision: liste des etudiants dont la note a changé
alors qu'ils ont une décision de jury enregistrée. alors qu'ils ont une décision de jury enregistrée.
- history_menu: un fragment de HTML expliquant l'historique de la note de chaque étudiant modifié.
SAMPLES
-------
/evaluation/1/notes/set;{""notes"": [[1, 17], [2, ""SUPR""]], ""comment"" : ""sample test""}
""" """
query = Evaluation.query.filter_by(id=evaluation_id) query = Evaluation.query.filter_by(id=evaluation_id)
if g.scodoc_dept: if g.scodoc_dept:
@ -224,6 +209,11 @@ def evaluation_create(moduleimpl_id: int):
} }
Résultat: l'évaluation créée. Résultat: l'évaluation créée.
SAMPLES
-------
/moduleimpl/1/evaluation/create;{""description"":""Exemple éval.""}
""" """
moduleimpl: ModuleImpl = ModuleImpl.query.get_or_404(moduleimpl_id) moduleimpl: ModuleImpl = ModuleImpl.query.get_or_404(moduleimpl_id)
if not moduleimpl.can_edit_evaluation(current_user): if not moduleimpl.can_edit_evaluation(current_user):

View File

@ -44,6 +44,11 @@ def formations():
""" """
Retourne la liste de toutes les formations (tous départements, Retourne la liste de toutes les formations (tous départements,
sauf si route départementale). sauf si route départementale).
SAMPLES
-------
/formations;
""" """
query = Formation.query query = Formation.query
if g.scodoc_dept: if g.scodoc_dept:
@ -64,6 +69,11 @@ def formations_ids():
(tous départements, ou du département indiqué dans la route) (tous départements, ou du département indiqué dans la route)
Exemple de résultat : `[ 17, 99, 32 ]`. Exemple de résultat : `[ 17, 99, 32 ]`.
SAMPLES
-------
/formations_ids;
""" """
query = Formation.query query = Formation.query
if g.scodoc_dept: if g.scodoc_dept:
@ -77,28 +87,14 @@ def formations_ids():
@scodoc @scodoc
@permission_required(Permission.ScoView) @permission_required(Permission.ScoView)
@as_json @as_json
def formation_by_id(formation_id: int): def formation_get(formation_id: int):
""" """
La formation d'id donné. La formation d'id donné.
SAMPLES
-------
/formation/1;
Exemple de résultat :
```json
{
"id": 1,
"acronyme": "BUT R&amp;T",
"titre_officiel": "Bachelor technologique réseaux et télécommunications",
"formation_code": "V1RET",
"code_specialite": null,
"dept_id": 1,
"titre": "BUT R&amp;T",
"version": 1,
"type_parcours": 700,
"referentiel_competence_id": null,
"formation_id": 1
}
```
""" """
query = Formation.query.filter_by(id=formation_id) query = Formation.query.filter_by(id=formation_id)
if g.scodoc_dept: if g.scodoc_dept:
@ -135,97 +131,9 @@ def formation_export_by_formation_id(formation_id: int, export_ids=False):
formation_id : l'id d'une formation formation_id : l'id d'une formation
export_with_ids : si présent, exporte aussi les ids des objets ScoDoc de la formation. export_with_ids : si présent, exporte aussi les ids des objets ScoDoc de la formation.
Exemple de résultat : SAMPLES
-------
```json /formation/1/export
{
"id": 1,
"acronyme": "BUT R&amp;T",
"titre_officiel": "Bachelor technologique r\u00e9seaux et t\u00e9l\u00e9communications",
"formation_code": "V1RET",
"code_specialite": null,
"dept_id": 1,
"titre": "BUT R&amp;T",
"version": 1,
"type_parcours": 700,
"referentiel_competence_id": null,
"formation_id": 1,
"ue": [
{
"acronyme": "RT1.1",
"numero": 1,
"titre": "Administrer les r\u00e9seaux et l\u2019Internet",
"type": 0,
"ue_code": "UCOD11",
"ects": 12.0,
"is_external": false,
"code_apogee": "",
"coefficient": 0.0,
"semestre_idx": 1,
"color": "#B80004",
"reference": 1,
"matiere": [
{
"titre": "Administrer les r\u00e9seaux et l\u2019Internet",
"numero": 1,
"module": [
{
"titre": "Initiation aux r\u00e9seaux informatiques",
"abbrev": "Init aux r\u00e9seaux informatiques",
"code": "R101",
"heures_cours": 0.0,
"heures_td": 0.0,
"heures_tp": 0.0,
"coefficient": 1.0,
"ects": "",
"semestre_id": 1,
"numero": 10,
"code_apogee": "",
"module_type": 2,
"coefficients": [
{
"ue_reference": "1",
"coef": "12.0"
},
{
"ue_reference": "2",
"coef": "4.0"
},
{
"ue_reference": "3",
"coef": "4.0"
}
]
},
{
"titre": "Se sensibiliser \u00e0 l&apos;hygi\u00e8ne informatique...",
"abbrev": "Hygi\u00e8ne informatique",
"code": "SAE11",
"heures_cours": 0.0,
"heures_td": 0.0,
"heures_tp": 0.0,
"coefficient": 1.0,
"ects": "",
"semestre_id": 1,
"numero": 10,
"code_apogee": "",
"module_type": 3,
"coefficients": [
{
"ue_reference": "1",
"coef": "16.0"
}
]
},
...
]
},
...
]
},
]
}
```
""" """
query = Formation.query.filter_by(id=formation_id) query = Formation.query.filter_by(id=formation_id)
if g.scodoc_dept: if g.scodoc_dept:
@ -250,6 +158,11 @@ def referentiel_competences(formation_id: int):
""" """
Retourne le référentiel de compétences de la formation Retourne le référentiel de compétences de la formation
ou null si pas de référentiel associé. ou null si pas de référentiel associé.
SAMPLES
-------
/formation/1/referentiel_competences;
""" """
query = Formation.query.filter_by(id=formation_id) query = Formation.query.filter_by(id=formation_id)
if g.scodoc_dept: if g.scodoc_dept:
@ -360,7 +273,12 @@ def ue_desassoc_niveau(ue_id: int):
@scodoc @scodoc
@permission_required(Permission.ScoView) @permission_required(Permission.ScoView)
def get_ue(ue_id: int): def get_ue(ue_id: int):
"""Renvoie l'UE.""" """Renvoie l'UE.
SAMPLES
-------
/formation/ue/1;
"""
query = UniteEns.query.filter_by(id=ue_id) query = UniteEns.query.filter_by(id=ue_id)
if g.scodoc_dept: if g.scodoc_dept:
query = query.join(Formation).filter_by(dept_id=g.scodoc_dept_id) query = query.join(Formation).filter_by(dept_id=g.scodoc_dept_id)
@ -374,7 +292,12 @@ def get_ue(ue_id: int):
@scodoc @scodoc
@permission_required(Permission.ScoView) @permission_required(Permission.ScoView)
def formation_module_get(module_id: int): def formation_module_get(module_id: int):
"""Renvoie le module.""" """Renvoie le module.
SAMPLES
-------
/formation/module/1;
"""
query = Module.query.filter_by(id=module_id) query = Module.query.filter_by(id=module_id)
if g.scodoc_dept: if g.scodoc_dept:
query = query.join(Formation).filter_by(dept_id=g.scodoc_dept_id) query = query.join(Formation).filter_by(dept_id=g.scodoc_dept_id)

View File

@ -54,44 +54,15 @@ from app.tables.recap import TableRecap, RowRecap
@scodoc @scodoc
@permission_required(Permission.ScoView) @permission_required(Permission.ScoView)
@as_json @as_json
def formsemestre_infos(formsemestre_id: int): def formsemestre_get(formsemestre_id: int):
""" """
Information sur le formsemestre indiqué. Information sur le formsemestre indiqué.
formsemestre_id : l'id du formsemestre formsemestre_id : l'id du formsemestre
Exemple de résultat : SAMPLES
```json -------
{ /formsemestre/1
"block_moyennes": false,
"bul_bgcolor": "white",
"bul_hide_xml": false,
"date_debut_iso": "2021-09-01",
"date_debut": "01/09/2021",
"date_fin_iso": "2022-08-31",
"date_fin": "31/08/2022",
"dept_id": 1,
"elt_annee_apo": null,
"elt_passage_apo" : null,
"elt_sem_apo": null,
"ens_can_edit_eval": false,
"etat": true,
"formation_id": 1,
"formsemestre_id": 1,
"gestion_compensation": false,
"gestion_semestrielle": false,
"id": 1,
"modalite": "FI",
"resp_can_change_ens": true,
"resp_can_edit": false,
"responsables": [1, 99], // uids
"scodoc7_id": null,
"semestre_id": 1,
"titre_formation" : "BUT GEA",
"titre_num": "BUT GEA semestre 1",
"titre": "BUT GEA",
}
```
""" """
query = FormSemestre.query.filter_by(id=formsemestre_id) query = FormSemestre.query.filter_by(id=formsemestre_id)
if g.scodoc_dept: if g.scodoc_dept:
@ -270,7 +241,7 @@ def formsemestre_set_apo_etapes():
Le code est une chaîne, avec éventuellement plusieurs valeurs séparées Le code est une chaîne, avec éventuellement plusieurs valeurs séparées
par des virgules. par des virgules.
Ce changement peut être fait sur un semestre verrouillé Ce changement peut être fait sur un semestre verrouillé.
DATA DATA
---- ----
@ -378,7 +349,7 @@ def formsemestre_set_elt_annee_apo():
@scodoc @scodoc
@permission_required(Permission.EditApogee) @permission_required(Permission.EditApogee)
def formsemestre_set_elt_passage_apo(): def formsemestre_set_elt_passage_apo():
"""Change les codes apogée de passage du semestre indiqué (par le champ oid). """Change les codes Apogée de passage du semestre indiqué (par le champ oid).
Le code est une chaîne, avec éventuellement plusieurs valeurs séparées Le code est une chaîne, avec éventuellement plusieurs valeurs séparées
par des virgules. par des virgules.
@ -425,7 +396,9 @@ def bulletins(formsemestre_id: int, version: str = "long"):
formsemestre_id : int formsemestre_id : int
version : string ("long", "short", "selectedevals") version : string ("long", "short", "selectedevals")
Exemple de résultat : liste, voir https://scodoc.org/ScoDoc9API/#bulletin SAMPLES
-------
/formsemestre/1/bulletins
""" """
query = FormSemestre.query.filter_by(id=formsemestre_id) query = FormSemestre.query.filter_by(id=formsemestre_id)
if g.scodoc_dept: if g.scodoc_dept:
@ -455,67 +428,9 @@ def formsemestre_programme(formsemestre_id: int):
""" """
Retourne la liste des UEs, ressources et SAEs d'un semestre Retourne la liste des UEs, ressources et SAEs d'un semestre
SAMPLES
Exemple de résultat : -------
```json /formsemestre/1/programme
{
"ues": [
{
"type": 0,
"formation_id": 1,
"ue_code": "UCOD11",
"id": 1,
"ects": 12.0,
"acronyme": "RT1.1",
"is_external": false,
"numero": 1,
"code_apogee": "",
"titre": "Administrer les r\u00e9seaux et l\u2019Internet",
"coefficient": 0.0,
"semestre_idx": 1,
"color": "#B80004",
"ue_id": 1
},
...
],
"ressources": [
{
"ens": [ 10, 18 ],
"formsemestre_id": 1,
"id": 15,
"module": {
"abbrev": "Programmer",
"code": "SAE15",
"code_apogee": "V7GOP",
"coefficient": 1.0,
"formation_id": 1,
"heures_cours": 0.0,
"heures_td": 0.0,
"heures_tp": 0.0,
"id": 15,
"matiere_id": 3,
"module_id": 15,
"module_type": 3,
"numero": 50,
"semestre_id": 1,
"titre": "Programmer en Python",
"ue_id": 3
},
"module_id": 15,
"moduleimpl_id": 15,
"responsable_id": 2
},
...
],
"saes": [
{
...
},
...
],
"modules" : [ ... les modules qui ne sont ni des SAEs ni des ressources ... ]
}
```
""" """
query = FormSemestre.query.filter_by(id=formsemestre_id) query = FormSemestre.query.filter_by(id=formsemestre_id)
if g.scodoc_dept: if g.scodoc_dept:
@ -588,6 +503,10 @@ def formsemestre_etudiants(
----- -----
etat:<string:etat> etat:<string:etat>
SAMPLES
-------
/formsemestre/1/etudiants/query;
""" """
query = FormSemestre.query.filter_by(id=formsemestre_id) query = FormSemestre.query.filter_by(id=formsemestre_id)
if g.scodoc_dept: if g.scodoc_dept:
@ -634,37 +553,9 @@ def formsemestre_etat_evaluations(formsemestre_id: int):
""" """
Informations sur l'état des évaluations d'un formsemestre. Informations sur l'état des évaluations d'un formsemestre.
Exemple de résultat : SAMPLES
-------
```json /formsemestre/1/etat_evals
[
{
"id": 1, // moduleimpl_id
"titre": "Initiation aux réseaux informatiques",
"evaluations": [
{
"id": 1,
"description": null,
"datetime_epreuve": null,
"heure_fin": "09:00:00",
"coefficient": "02.00"
"is_complete": true,
"nb_inscrits": 16,
"nb_manquantes": 0,
"ABS": 0,
"ATT": 0,
"EXC": 0,
"saisie_notes": {
"datetime_debut": "2021-09-11T00:00:00+02:00",
"datetime_fin": "2022-08-25T00:00:00+02:00",
"datetime_mediane": "2022-03-19T00:00:00+01:00"
}
},
...
]
},
]
```
""" """
formsemestre = FormSemestre.get_formsemestre(formsemestre_id) formsemestre = FormSemestre.get_formsemestre(formsemestre_id)
app.set_sco_dept(formsemestre.departement.acronym) app.set_sco_dept(formsemestre.departement.acronym)
@ -749,6 +640,9 @@ def formsemestre_resultat(formsemestre_id: int):
----- -----
format:<string:format> format:<string:format>
SAMPLES
-------
/formsemestre/1/resultats;
""" """
format_spec = request.args.get("format", None) format_spec = request.args.get("format", None)
if format_spec is not None and format_spec != "raw": if format_spec is not None and format_spec != "raw":

View File

@ -53,7 +53,12 @@ from app.scodoc.sco_utils import json_error
@permission_required(Permission.ScoView) @permission_required(Permission.ScoView)
@as_json @as_json
def decisions_jury(formsemestre_id: int): def decisions_jury(formsemestre_id: int):
"""Décisions du jury des étudiants du formsemestre.""" """Décisions du jury des étudiants du formsemestre.
SAMPLES
-------
/formsemestre/1/decisions_jury
"""
# APC, pair: # APC, pair:
formsemestre: FormSemestre = db.session.get(FormSemestre, formsemestre_id) formsemestre: FormSemestre = db.session.get(FormSemestre, formsemestre_id)
if formsemestre is None: if formsemestre is None:

View File

@ -165,7 +165,7 @@ def justificatifs(etudid: int = None, nip=None, ine=None, with_query: bool = Fal
def justificatifs_dept(dept_id: int = None, with_query: bool = False): def justificatifs_dept(dept_id: int = None, with_query: bool = False):
""" """
Renvoie tous les justificatifs d'un département Renvoie tous les justificatifs d'un département
(en ajoutant un champ "formsemestre" si possible) (en ajoutant un champ "`formsemestre`" si possible).
QUERY QUERY
----- -----
@ -220,9 +220,9 @@ def justificatifs_dept(dept_id: int = None, with_query: bool = False):
def _set_sems(justi: Justificatif, restrict: bool) -> dict: def _set_sems(justi: Justificatif, restrict: bool) -> dict:
""" """
_set_sems Ajoute le formsemestre associé au justificatif s'il existe _set_sems Ajoute le formsemestre associé au justificatif s'il existe.
Si le formsemestre n'existe pas, renvoie la simple représentation du justificatif Si le formsemestre n'existe pas, renvoie la simple représentation du justificatif.
Args: Args:
justi (Justificatif): Le justificatif justi (Justificatif): Le justificatif
@ -263,7 +263,7 @@ def _set_sems(justi: Justificatif, restrict: bool) -> dict:
@as_json @as_json
@permission_required(Permission.ScoView) @permission_required(Permission.ScoView)
def justificatifs_formsemestre(formsemestre_id: int, with_query: bool = False): def justificatifs_formsemestre(formsemestre_id: int, with_query: bool = False):
"""Retourne tous les justificatifs du formsemestre """Retourne tous les justificatifs du formsemestre.
QUERY QUERY
----- -----
@ -337,7 +337,7 @@ def justificatifs_formsemestre(formsemestre_id: int, with_query: bool = False):
@permission_required(Permission.AbsChange) @permission_required(Permission.AbsChange)
def justif_create(etudid: int = None, nip=None, ine=None): def justif_create(etudid: int = None, nip=None, ine=None):
""" """
Création d'un justificatif pour l'étudiant (etudid) Création d'un justificatif pour l'étudiant.
DATA DATA
---- ----
@ -489,7 +489,7 @@ def _create_one(
@permission_required(Permission.AbsChange) @permission_required(Permission.AbsChange)
def justif_edit(justif_id: int): def justif_edit(justif_id: int):
""" """
Edition d'un justificatif à partir de son id Édition d'un justificatif à partir de son id.
DATA DATA
---- ----
@ -611,7 +611,7 @@ def justif_edit(justif_id: int):
@permission_required(Permission.AbsChange) @permission_required(Permission.AbsChange)
def justif_delete(): def justif_delete():
""" """
Suppression d'un justificatif à partir de son id Suppression d'un justificatif à partir de son id.
DATA DATA
---- ----
@ -699,7 +699,7 @@ def _delete_one(justif_id: int) -> tuple[int, str]:
@permission_required(Permission.AbsChange) @permission_required(Permission.AbsChange)
def justif_import(justif_id: int = None): def justif_import(justif_id: int = None):
""" """
Importation d'un fichier (création d'archive) Importation d'un fichier (création d'archive).
> Procédure d'importation de fichier : [importer un justificatif](FichiersJustificatifs.md#importer-un-fichier) > Procédure d'importation de fichier : [importer un justificatif](FichiersJustificatifs.md#importer-un-fichier)
""" """
@ -752,7 +752,8 @@ def justif_import(justif_id: int = None):
def justif_export(justif_id: int | None = None, filename: str | None = None): def justif_export(justif_id: int | None = None, filename: str | None = None):
""" """
Retourne un fichier d'une archive d'un justificatif. Retourne un fichier d'une archive d'un justificatif.
La permission est ScoView + (AbsJustifView ou être l'auteur du justifcatif)
La permission est `ScoView` + (`AbsJustifView` ou être l'auteur du justificatif).
> Procédure de téléchargement de fichier : [télécharger un justificatif](FichiersJustificatifs.md#télécharger-un-fichier) > Procédure de téléchargement de fichier : [télécharger un justificatif](FichiersJustificatifs.md#télécharger-un-fichier)
""" """
@ -791,7 +792,7 @@ def justif_export(justif_id: int | None = None, filename: str | None = None):
@permission_required(Permission.AbsChange) @permission_required(Permission.AbsChange)
def justif_remove(justif_id: int = None): def justif_remove(justif_id: int = None):
""" """
Supression d'un fichier ou d'une archive Supression d'un fichier ou d'une archive.
> Procédure de suppression de fichier : [supprimer un justificatif](FichiersJustificatifs.md#supprimer-un-fichier) > Procédure de suppression de fichier : [supprimer un justificatif](FichiersJustificatifs.md#supprimer-un-fichier)
@ -870,7 +871,7 @@ def justif_remove(justif_id: int = None):
@permission_required(Permission.ScoView) @permission_required(Permission.ScoView)
def justif_list(justif_id: int = None): def justif_list(justif_id: int = None):
""" """
Liste les fichiers du justificatif Liste les fichiers du justificatif.
SAMPLES SAMPLES
------- -------
@ -917,7 +918,7 @@ def justif_list(justif_id: int = None):
@permission_required(Permission.AbsChange) @permission_required(Permission.AbsChange)
def justif_justifies(justif_id: int = None): def justif_justifies(justif_id: int = None):
""" """
Liste assiduite_id justifiées par le justificatif Liste `assiduite_id` justifiées par le justificatif.
SAMPLES SAMPLES
------- -------

View File

@ -50,7 +50,12 @@ from app.scodoc.sco_utils import json_error
@permission_required(Permission.ScoSuperAdmin) @permission_required(Permission.ScoSuperAdmin)
@as_json @as_json
def logo_list_globals(): def logo_list_globals():
"""Liste des noms des logos définis pour le site ScoDoc.""" """Liste des noms des logos définis pour le site ScoDoc.
SAMPLES
-------
/logos
"""
logos = list_logos()[None] logos = list_logos()[None]
return list(logos.keys()) return list(logos.keys())
@ -63,6 +68,10 @@ def logo_get_global(logoname):
L'image est au format png ou jpg; le format retourné dépend du format sous lequel L'image est au format png ou jpg; le format retourné dépend du format sous lequel
l'image a été initialement enregistrée. l'image a été initialement enregistrée.
SAMPLES
-------
/logo/B
""" """
logo = find_logo(logoname=logoname) logo = find_logo(logoname=logoname)
if logo is None: if logo is None:
@ -80,15 +89,19 @@ def _core_get_logos(dept_id) -> list:
return list(logos.keys()) return list(logos.keys())
@bp.route("/departement/<string:departement>/logos") @bp.route("/departement/<string:dept_acronym>/logos")
@scodoc @scodoc
@permission_required(Permission.ScoSuperAdmin) @permission_required(Permission.ScoSuperAdmin)
@as_json @as_json
def logo_get_local_by_acronym(departement): def departement_logos(dept_acronym: str):
"""Liste des noms des logos définis pour le département """Liste des noms des logos définis pour le département
désigné par son acronyme. désigné par son acronyme.
SAMPLES
-------
/departement/TAPI/logos
""" """
dept_id = Departement.from_acronym(departement).id dept_id = Departement.from_acronym(dept_acronym).id
return _core_get_logos(dept_id) return _core_get_logos(dept_id)
@ -96,7 +109,7 @@ def logo_get_local_by_acronym(departement):
@scodoc @scodoc
@permission_required(Permission.ScoSuperAdmin) @permission_required(Permission.ScoSuperAdmin)
@as_json @as_json
def logo_get_local_by_id(dept_id): def departement_logos_by_id(dept_id):
"""Liste des noms des logos définis pour le département """Liste des noms des logos définis pour le département
désigné par son id. désigné par son id.
""" """

View File

@ -38,37 +38,9 @@ def moduleimpl(moduleimpl_id: int):
------ ------
moduleimpl_id : l'id d'un moduleimpl moduleimpl_id : l'id d'un moduleimpl
Exemple de résultat : SAMPLES
-------
```json /moduleimpl/1
{
"id": 1,
"formsemestre_id": 1,
"module_id": 1,
"responsable_id": 2,
"moduleimpl_id": 1,
"ens": [],
"module": {
"heures_tp": 0,
"code_apogee": "",
"titre": "Initiation aux réseaux informatiques",
"coefficient": 1,
"module_type": 2,
"id": 1,
"ects": null,
"abbrev": "Init aux réseaux informatiques",
"ue_id": 1,
"code": "R101",
"formation_id": 1,
"heures_cours": 0,
"matiere_id": 1,
"heures_td": 0,
"semestre_id": 1,
"numero": 10,
"module_id": 1
}
}
```
""" """
modimpl = ModuleImpl.get_modimpl(moduleimpl_id) modimpl = ModuleImpl.get_modimpl(moduleimpl_id)
return modimpl.to_dict(convert_objects=True) return modimpl.to_dict(convert_objects=True)
@ -83,18 +55,9 @@ def moduleimpl(moduleimpl_id: int):
def moduleimpl_inscriptions(moduleimpl_id: int): def moduleimpl_inscriptions(moduleimpl_id: int):
"""Liste des inscriptions à ce moduleimpl. """Liste des inscriptions à ce moduleimpl.
Exemple de résultat : SAMPLES
-------
```json /moduleimpl/1/inscriptions
[
{
"id": 1,
"etudid": 666,
"moduleimpl_id": 1234,
},
...
]
```
""" """
modimpl = ModuleImpl.get_modimpl(moduleimpl_id) modimpl = ModuleImpl.get_modimpl(moduleimpl_id)
return [i.to_dict() for i in modimpl.inscriptions] return [i.to_dict() for i in modimpl.inscriptions]
@ -108,24 +71,9 @@ def moduleimpl_inscriptions(moduleimpl_id: int):
def moduleimpl_notes(moduleimpl_id: int): def moduleimpl_notes(moduleimpl_id: int):
"""Liste des notes dans ce moduleimpl. """Liste des notes dans ce moduleimpl.
Exemple de résultat : SAMPLES
-------
```json /moduleimpl/1/notes
[
{
"etudid": 17776, // code de l'étudiant
"nom": "DUPONT",
"prenom": "Luz",
"38411": 16.0, // Note dans l'évaluation d'id 38411
"38410": 15.0,
"moymod": 15.5, // Moyenne INDICATIVE module
"moy_ue_2875": 15.5, // Moyenne vers l'UE 2875
"moy_ue_2876": 15.5, // Moyenne vers l'UE 2876
"moy_ue_2877": 15.5 // Moyenne vers l'UE 2877
},
...
]
```
""" """
modimpl = ModuleImpl.get_modimpl(moduleimpl_id) modimpl = ModuleImpl.get_modimpl(moduleimpl_id)
app.set_sco_dept(modimpl.formsemestre.departement.acronym) app.set_sco_dept(modimpl.formsemestre.departement.acronym)

View File

@ -45,23 +45,9 @@ from app.scodoc import sco_utils as scu
def partition_info(partition_id: int): def partition_info(partition_id: int):
"""Info sur une partition. """Info sur une partition.
Exemple de résultat : SAMPLES
-------
```json /partition/1
{
'bul_show_rank': False,
'formsemestre_id': 39,
'groups': [
{'id': 268, 'name': 'A', 'partition_id': 100},
{'id': 269, 'name': 'B', 'partition_id': 100}
],
'groups_editable': True,
'id': 100,
'numero': 100,
'partition_name': 'TD',
'show_in_lists': True
}
```
""" """
query = Partition.query.filter_by(id=partition_id) query = Partition.query.filter_by(id=partition_id)
if g.scodoc_dept: if g.scodoc_dept:
@ -79,23 +65,9 @@ def partition_info(partition_id: int):
def formsemestre_partitions(formsemestre_id: int): def formsemestre_partitions(formsemestre_id: int):
"""Liste de toutes les partitions d'un formsemestre. """Liste de toutes les partitions d'un formsemestre.
Exemple de résultat : SAMPLES
-------
```json /formsemestre/1/partitions
{
partition_id : {
"bul_show_rank": False,
"formsemestre_id": 1063,
"groups" :
group_id : {
"id" : 12,
"name" : "A",
"partition_id" : partition_id,
}
},
...
}
```
""" """
query = FormSemestre.query.filter_by(id=formsemestre_id) query = FormSemestre.query.filter_by(id=formsemestre_id)
if g.scodoc_dept: if g.scodoc_dept:
@ -124,22 +96,9 @@ def group_etudiants(group_id: int):
------ ------
group_id : l'id d'un groupe group_id : l'id d'un groupe
Exemple de résultat : SAMPLES
-------
```json /group/1/etudiants
[
{
'civilite': 'M',
'id': 123456,
'ine': None,
'nip': '987654321',
'nom': 'MARTIN',
'nom_usuel': null,
'prenom': 'JEAN'}
},
...
]
```
""" """
query = GroupDescr.query.filter_by(id=group_id) query = GroupDescr.query.filter_by(id=group_id)
if g.scodoc_dept: if g.scodoc_dept:
@ -316,6 +275,10 @@ def group_create(partition_id: int): # partition-group-create
"group_name" : nom_du_groupe, "group_name" : nom_du_groupe,
} }
``` ```
SAMPLES
-------
/partition/1/group/create;{""group_name"" : ""Nouveau Groupe""}
""" """
query = Partition.query.filter_by(id=partition_id) query = Partition.query.filter_by(id=partition_id)
if g.scodoc_dept: if g.scodoc_dept:
@ -391,7 +354,19 @@ def group_delete(group_id: int):
@permission_required(Permission.ScoView) @permission_required(Permission.ScoView)
@as_json @as_json
def group_edit(group_id: int): def group_edit(group_id: int):
"""Édition d'un groupe.""" """Édition d'un groupe.
DATA
----
```json
{
"group_name" : "A1"
}
SAMPLES
-------
/group/1/edit;{""group_name"":""A1""}
"""
query = GroupDescr.query.filter_by(id=group_id) query = GroupDescr.query.filter_by(id=group_id)
if g.scodoc_dept: if g.scodoc_dept:
query = ( query = (
@ -436,6 +411,10 @@ def group_set_edt_id(group_id: int, edt_id: str):
Contrairement à `/edit`, peut-être changé pour toute partition Contrairement à `/edit`, peut-être changé pour toute partition
d'un formsemestre non verrouillé. d'un formsemestre non verrouillé.
SAMPLES
-------
/group/1/set_edt_id/EDT_GR1
""" """
query = GroupDescr.query.filter_by(id=group_id) query = GroupDescr.query.filter_by(id=group_id)
if g.scodoc_dept: if g.scodoc_dept:
@ -632,6 +611,10 @@ def partition_edit(partition_id: int):
"groups_editable":bool "groups_editable":bool
} }
``` ```
SAMPLES
-------
/partition/1/edit;{""bul_show_rank"":1}
""" """
query = Partition.query.filter_by(id=partition_id) query = Partition.query.filter_by(id=partition_id)
if g.scodoc_dept: if g.scodoc_dept:
@ -666,9 +649,8 @@ def partition_edit(partition_id: int):
for boolean_field in ("bul_show_rank", "show_in_lists", "groups_editable"): for boolean_field in ("bul_show_rank", "show_in_lists", "groups_editable"):
value = data.get(boolean_field) value = data.get(boolean_field)
value = scu.to_bool(value) if value is not None else None
if value is not None and value != getattr(partition, boolean_field): if value is not None and value != getattr(partition, boolean_field):
if not isinstance(value, bool):
return json_error(API_CLIENT_ERROR, f"invalid type for {boolean_field}")
if boolean_field == "groups_editable" and partition.is_parcours(): if boolean_field == "groups_editable" and partition.is_parcours():
return json_error( return json_error(
API_CLIENT_ERROR, f"can't change {scu.PARTITION_PARCOURS}" API_CLIENT_ERROR, f"can't change {scu.PARTITION_PARCOURS}"

View File

@ -37,6 +37,10 @@ from app.scodoc.sco_utils import json_error
def user_info(uid: int): def user_info(uid: int):
""" """
Info sur un compte utilisateur ScoDoc. Info sur un compte utilisateur ScoDoc.
SAMPLES
-------
/user/2
""" """
user: User = db.session.get(User, uid) user: User = db.session.get(User, uid)
if user is None: if user is None:
@ -222,14 +226,19 @@ def user_edit(uid: int):
def user_password(uid: int): def user_password(uid: int):
"""Modification du mot de passe d'un utilisateur. """Modification du mot de passe d'un utilisateur.
Champs modifiables: Si le mot de passe ne convient pas, erreur 400.
DATA
----
```json ```json
{ {
"password": str "password": str
} }
```. ```
Si le mot de passe ne convient pas, erreur 400. SAMPLES
-------
/user/3/password;{""password"" : ""rePlaCemeNT456averylongandcomplicated""}
""" """
data = request.get_json(force=True) # may raise 400 Bad Request data = request.get_json(force=True) # may raise 400 Bad Request
user: User = User.query.get_or_404(uid) user: User = User.query.get_or_404(uid)
@ -318,7 +327,12 @@ def user_role_remove(uid: int, role_name: str, dept: str = None):
@permission_required(Permission.UsersView) @permission_required(Permission.UsersView)
@as_json @as_json
def permissions_list(): def permissions_list():
"""Liste des noms de permissions définies.""" """Liste des noms de permissions définies.
SAMPLES
-------
/permissions
"""
return list(Permission.permission_by_name.keys()) return list(Permission.permission_by_name.keys())
@ -329,7 +343,12 @@ def permissions_list():
@permission_required(Permission.UsersView) @permission_required(Permission.UsersView)
@as_json @as_json
def role_get(role_name: str): def role_get(role_name: str):
"""Un rôle""" """Un rôle.
SAMPLES
-------
/role/Ens
"""
return Role.query.filter_by(name=role_name).first_or_404().to_dict() return Role.query.filter_by(name=role_name).first_or_404().to_dict()
@ -340,7 +359,12 @@ def role_get(role_name: str):
@permission_required(Permission.UsersView) @permission_required(Permission.UsersView)
@as_json @as_json
def roles_list(): def roles_list():
"""Tous les rôles définis.""" """Tous les rôles définis.
SAMPLES
-------
/roles
"""
return [role.to_dict() for role in Role.query] return [role.to_dict() for role in Role.query]
@ -410,6 +434,10 @@ def role_create(role_name: str):
"permissions" : [ 'ScoView', ... ] "permissions" : [ 'ScoView', ... ]
} }
``` ```
SAMPLES
-------
/role/create/customRole;{""permissions"": [""ScoView"", ""UsersView""]}
""" """
role: Role = Role.query.filter_by(name=role_name).first() role: Role = Role.query.filter_by(name=role_name).first()
if role: if role:
@ -471,7 +499,12 @@ def role_edit(role_name: str):
@permission_required(Permission.ScoSuperAdmin) @permission_required(Permission.ScoSuperAdmin)
@as_json @as_json
def role_delete(role_name: str): def role_delete(role_name: str):
"""Suprression d'un rôle.""" """Suppression d'un rôle.
SAMPLES
-------
/role/customRole/delete
"""
role: Role = Role.query.filter_by(name=role_name).first_or_404() role: Role = Role.query.filter_by(name=role_name).first_or_404()
db.session.delete(role) db.session.delete(role)
db.session.commit() db.session.commit()

View File

@ -242,6 +242,16 @@ class GroupDescr(ScoDocModel):
f"""<{self.__class__.__name__} {self.id} "{self.group_name or '(tous)'}">""" f"""<{self.__class__.__name__} {self.id} "{self.group_name or '(tous)'}">"""
) )
@classmethod
def filter_model_attributes(cls, data: dict, excluded: set[str] = None) -> dict:
"""Returns a copy of dict with only the keys belonging to the Model and not in excluded.
Exclude `partition_id` : a group cannot be moved from a partition to another.
"""
return super().filter_model_attributes(
data,
excluded=(excluded or set()) | {"partition_id"},
)
def get_nom_with_part(self, default="-") -> str: def get_nom_with_part(self, default="-") -> str:
"""Nom avec partition: 'TD A' """Nom avec partition: 'TD A'
Si groupe par défaut (tous), utilise default ou "-" Si groupe par défaut (tous), utilise default ou "-"

View File

@ -30,7 +30,7 @@ from setup_test_api import (
CHECK_CERTIFICATE, CHECK_CERTIFICATE,
get_auth_headers, get_auth_headers,
GET, GET,
POST_JSON, POST,
SCODOC_URL, SCODOC_URL,
) )

View File

@ -23,7 +23,7 @@ from setup_test_api import (
CHECK_CERTIFICATE, CHECK_CERTIFICATE,
get_auth_headers, get_auth_headers,
GET, GET,
POST_JSON, POST,
SCODOC_URL, SCODOC_URL,
) )

View File

@ -39,7 +39,7 @@ from setup_test_api import (
CHECK_CERTIFICATE, CHECK_CERTIFICATE,
get_auth_headers, get_auth_headers,
GET, GET,
POST_JSON, POST,
SCODOC_URL, SCODOC_URL,
) )
@ -127,14 +127,12 @@ group_id = 5315
POST(f"/group/{group_id}/set_etudiant/{etudid}", headers=HEADERS) POST(f"/group/{group_id}/set_etudiant/{etudid}", headers=HEADERS)
POST_JSON( POST(f"/partition/{pid}/group/create", data={"group_name": "Omega10"}, headers=HEADERS)
f"/partition/{pid}/group/create", data={"group_name": "Omega10"}, headers=HEADERS
)
partitions = GET(f"/formsemestre/{formsemestre_id}/partitions", headers=HEADERS) partitions = GET(f"/formsemestre/{formsemestre_id}/partitions", headers=HEADERS)
pp(partitions) pp(partitions)
POST_JSON(f"/group/5559/delete", headers=HEADERS) POST(f"/group/5559/delete", headers=HEADERS)
POST_JSON(f"/group/5327/edit", data={"group_name": "TDXXX"}, headers=HEADERS) POST(f"/group/5327/edit", data={"group_name": "TDXXX"}, headers=HEADERS)
# --------- Toutes les bulletins, un à un, et les décisions de jury d'un semestre # --------- Toutes les bulletins, un à un, et les décisions de jury d'un semestre
formsemestre_id = 911 formsemestre_id = 911
@ -178,19 +176,19 @@ etud = GET(f"/formsemestre/{formsemestre_id}/etudiants", headers=HEADERS)[10]
etudid = etud["id"] etudid = etud["id"]
# 1- Crée une partition, puis la change de nom # 1- Crée une partition, puis la change de nom
js = POST_JSON( js = POST(
f"/formsemestre/{formsemestre_id}/partition/create", f"/formsemestre/{formsemestre_id}/partition/create",
data={"partition_name": "PART"}, data={"partition_name": "PART"},
) )
partition_id = js["id"] partition_id = js["id"]
POST_JSON( POST(
f"/partition/{partition_id}/edit", f"/partition/{partition_id}/edit",
data={"partition_name": "PART1", "show_in_lists": True}, data={"partition_name": "PART1", "show_in_lists": True},
headers=HEADERS, headers=HEADERS,
) )
# 2- Crée un groupe # 2- Crée un groupe
js = POST_JSON( js = POST(
f"/partition/{partition_id}/group/create", f"/partition/{partition_id}/group/create",
data={"group_name": "G1"}, data={"group_name": "G1"},
headers=HEADERS, headers=HEADERS,
@ -198,28 +196,28 @@ js = POST_JSON(
group_1 = js["id"] group_1 = js["id"]
# 3- Crée deux autres groupes # 3- Crée deux autres groupes
js = POST_JSON( js = POST(
f"/partition/{partition_id}/group/create", f"/partition/{partition_id}/group/create",
data={"group_name": "G2"}, data={"group_name": "G2"},
headers=HEADERS, headers=HEADERS,
) )
js = POST_JSON( js = POST(
f"/partition/{partition_id}/group/create", f"/partition/{partition_id}/group/create",
data={"group_name": "G3"}, data={"group_name": "G3"},
headers=HEADERS, headers=HEADERS,
) )
# 4- Affecte étudiant au groupe G1 # 4- Affecte étudiant au groupe G1
POST_JSON(f"/group/{group_1}/set_etudiant/{etudid}", headers=HEADERS) POST(f"/group/{group_1}/set_etudiant/{etudid}", headers=HEADERS)
# 5- retire du groupe # 5- retire du groupe
POST_JSON(f"/group/{group_1}/remove_etudiant/{etudid}", headers=HEADERS) POST(f"/group/{group_1}/remove_etudiant/{etudid}", headers=HEADERS)
# 6- affecte au groupe G2 # 6- affecte au groupe G2
partition = GET(f"/partition/{partition_id}") partition = GET(f"/partition/{partition_id}")
assert len(partition["groups"]) == 3 assert len(partition["groups"]) == 3
group_2 = [g for g in partition["groups"].values() if g["group_name"] == "G2"][0]["id"] group_2 = [g for g in partition["groups"].values() if g["group_name"] == "G2"][0]["id"]
POST_JSON(f"/group/{group_2}/set_etudiant/{etudid}", headers=HEADERS) POST(f"/group/{group_2}/set_etudiant/{etudid}", headers=HEADERS)
# 7- Membres du groupe # 7- Membres du groupe
etuds_g2 = GET(f"/group/{group_2}/etudiants", headers=HEADERS) etuds_g2 = GET(f"/group/{group_2}/etudiants", headers=HEADERS)
@ -229,7 +227,7 @@ assert etuds_g2[0]["id"] == etudid
# 8- Ordres des groupes # 8- Ordres des groupes
group_3 = [g for g in partition["groups"].values() if g["group_name"] == "G3"][0]["id"] group_3 = [g for g in partition["groups"].values() if g["group_name"] == "G3"][0]["id"]
POST_JSON( POST(
f"/partition/{partition_id}/groups/order", f"/partition/{partition_id}/groups/order",
data=[group_2, group_1, group_3], data=[group_2, group_1, group_3],
headers=HEADERS, headers=HEADERS,
@ -242,7 +240,7 @@ new_groups = [
assert new_groups == [group_2, group_1, group_3] assert new_groups == [group_2, group_1, group_3]
# 9- Suppression # 9- Suppression
POST_JSON(f"/partition/{partition_id}/delete") POST(f"/partition/{partition_id}/delete")
# ------ # ------
# Tests accès API: # Tests accès API:
@ -260,13 +258,13 @@ POST_JSON(f"/partition/{partition_id}/delete")
""" """
# #
POST_JSON( POST(
"/partition/2264/groups/order", "/partition/2264/groups/order",
data=[5563, 5562, 5561, 5560, 5558, 5557, 5316, 5315], data=[5563, 5562, 5561, 5560, 5558, 5557, 5316, 5315],
headers=HEADERS, headers=HEADERS,
) )
POST_JSON( POST(
"/formsemestre/1063/partitions/order", "/formsemestre/1063/partitions/order",
data=[2264, 2263, 2265, 2266, 2267, 2372, 2378], data=[2264, 2263, 2265, 2266, 2267, 2372, 2378],
headers=HEADERS, headers=HEADERS,

View File

@ -41,7 +41,7 @@ from setup_test_api import (
CHECK_CERTIFICATE, CHECK_CERTIFICATE,
get_auth_headers, get_auth_headers,
GET, GET,
POST_JSON, POST,
SCODOC_URL, SCODOC_URL,
) )

View File

@ -10,15 +10,15 @@
Si entry_names est spécifié, la génération est restreinte aux exemples cités. Si entry_names est spécifié, la génération est restreinte aux exemples cités.
Exemple: Exemple:
python make_samples departements departement-formsemestres python make_samples departements departement_formsemestres
Doit être exécutée immédiatement apres une initialisation de la base pour test API! Doit être exécutée immédiatement apres une initialisation de la base pour test API!
(car dépendant des identifiants générés lors de la création des objets) (car dépendant des identifiants générés lors de la création des objets)
Modifer le /opt/scodoc/.env pour pointer sur la base test Modifer le /opt/scodoc/.env pour pointer sur la base test
SCODOC_DATABASE_URI="postgresql:///SCODOC_TEST_API" SCODOC_DATABASE_URI="postgresql:///SCODOC_TEST_API"
puis re-créer cette base puis re-créer cette base
tools/create_database.sh --drop SCODOC_TEST_API tools/create_database.sh --drop SCODOC_TEST_API
flask db upgrade flask db upgrade
flask sco-db-init --erase flask sco-db-init --erase
@ -28,10 +28,10 @@ et lancer le serveur test:
flask run --debug flask run --debug
``` ```
Cet utilitaire prend en argument le fichier de nom `samples.csv` contenant la description Cet utilitaire prend en argument le fichier de nom `samples.csv` contenant la description
des exemples (séparés par une tabulation (\t), une ligne par exemple) des exemples (séparés par une tabulation (\t), une ligne par exemple)
* Le nom de l'exemple donne le nom du fichier généré (nom_exemple => nom_exemple.json.md). * Le nom de l'exemple donne le nom du fichier généré (nom_exemple => nom_exemple.json.md).
Plusieurs lignes peuvent partager le même nom. dans ce cas le fichier contiendra Plusieurs lignes peuvent partager le même nom. dans ce cas le fichier contiendra
chacun des exemples chacun des exemples
* l'url utilisée * l'url utilisée
* la permission nécessaire (par défaut ScoView) * la permission nécessaire (par défaut ScoView)
@ -39,7 +39,7 @@ chacun des exemples
* les arguments éventuel (en cas de POST): une chaîne de caractère selon json * les arguments éventuel (en cas de POST): une chaîne de caractère selon json
Implémentation: Implémentation:
Le code complète une structure de données (Samples) qui est un dictionnaire de set Le code complète une structure de données (Samples) qui est un dictionnaire de set
(indicé par le nom des exemples). (indicé par le nom des exemples).
Chacun des éléments du set est un exemple (Sample) Chacun des éléments du set est un exemple (Sample)
Quand la structure est complète, on génére tous les fichiers textes Quand la structure est complète, on génére tous les fichiers textes
@ -48,7 +48,7 @@ Quand la structure est complète, on génére tous les fichiers textes
- l'url utilisée - l'url utilisée
- les arguments éventuels - les arguments éventuels
- le résultat - le résultat
Le tout mis en forme au format markdown et rangé dans le répertoire DATA_DIR (/tmp/samples) Le tout mis en forme au format markdown et rangé dans le répertoire DATA_DIR (/tmp/samples)
qui est créé ou écrasé si déjà existant. qui est créé ou écrasé si déjà existant.
""" """
import os import os
@ -71,7 +71,7 @@ from setup_test_api import (
CHECK_CERTIFICATE, CHECK_CERTIFICATE,
get_auth_headers, get_auth_headers,
GET, GET,
POST_JSON, POST,
SCODOC_URL, SCODOC_URL,
) )
@ -98,18 +98,23 @@ class Sample:
elif permission == "UsersAdmin": elif permission == "UsersAdmin":
HEADERS = get_auth_headers("admin_api", "admin_api") HEADERS = get_auth_headers("admin_api", "admin_api")
else: else:
raise SampleException(f"Bad permission : {permission}") raise SampleException(f"Bad permission : {permission}, url={self.url}")
if self.method == "GET": if self.method == "GET":
self.result = GET(self.url, HEADERS) self.result = GET(self.url, HEADERS)
elif self.method == "POST": elif self.method == "POST":
if self.content == "": if self.content == "":
self.result = POST_JSON(self.url, headers=HEADERS) self.result = POST(self.url, headers=HEADERS)
else: else:
HEADERS["Content-Type"] = "application/json ; charset=utf-8" HEADERS["Content-Type"] = "application/json ; charset=utf-8"
self.result = POST_JSON(self.url, json.loads(self.content), HEADERS) try:
data = json.loads(self.content)
except json.decoder.JSONDecodeError as exc:
raise ValueError(
f"JSON invalide: {self.content}\nurl={self.url}"
) from exc
self.result = POST(self.url, data, HEADERS)
elif self.method[0] != "#": elif self.method[0] != "#":
error = f'Bad method : "{self.method}"' raise SampleException(f'Bad method : "{self.method}", url={self.url}')
raise SampleException(error)
self.shorten() self.shorten()
with open("sample_TEST.json.md", "tw", encoding="utf-8") as f: with open("sample_TEST.json.md", "tw", encoding="utf-8") as f:
self.dump(f) self.dump(f)
@ -235,3 +240,5 @@ if not CHECK_CERTIFICATE:
urllib3.disable_warnings() urllib3.disable_warnings()
make_samples(SAMPLES_FILENAME) make_samples(SAMPLES_FILENAME)
print(f"Fichiers samples générés dans {DATA_DIR}")

View File

@ -79,6 +79,16 @@ if pytest:
return get_auth_headers(API_USER_ADMIN, API_PASSWORD_ADMIN) return get_auth_headers(API_USER_ADMIN, API_PASSWORD_ADMIN)
class _DefaultHeaders:
headers = {}
def set_headers(headers: dict):
"""Set default headers"""
print(f"set_headers: {headers}")
_DefaultHeaders.headers = headers
def GET(path: str, headers: dict = None, errmsg=None, dept=None, raw=False): def GET(path: str, headers: dict = None, errmsg=None, dept=None, raw=False):
"""Get and optionaly returns as JSON """Get and optionaly returns as JSON
Special case for non json result (image or pdf): Special case for non json result (image or pdf):
@ -91,7 +101,7 @@ def GET(path: str, headers: dict = None, errmsg=None, dept=None, raw=False):
url = API_URL + path url = API_URL + path
reply = requests.get( reply = requests.get(
url, url,
headers=headers or {}, headers=_DefaultHeaders.headers if headers is None else headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
timeout=SCO_TEST_API_TIMEOUT, timeout=SCO_TEST_API_TIMEOUT,
) )
@ -119,7 +129,7 @@ def GET(path: str, headers: dict = None, errmsg=None, dept=None, raw=False):
raise APIError("Unknown returned content {r.headers.get('Content-Type', None} !\n") raise APIError("Unknown returned content {r.headers.get('Content-Type', None} !\n")
def POST_JSON( def POST(
path: str, data: dict = {}, headers: dict = None, errmsg=None, dept=None, raw=False path: str, data: dict = {}, headers: dict = None, errmsg=None, dept=None, raw=False
): ):
"""Post """Post
@ -132,7 +142,7 @@ def POST_JSON(
r = requests.post( r = requests.post(
url, url,
json=data, json=data,
headers=headers or {}, headers=_DefaultHeaders.headers if headers is None else headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
timeout=SCO_TEST_API_TIMEOUT, timeout=SCO_TEST_API_TIMEOUT,
) )
@ -200,7 +210,7 @@ def check_failure_post(path: str, headers: dict, data: dict, err: str = None):
""" """
try: try:
data = POST_JSON(path=path, headers=headers, data=data, dept=DEPT_ACRONYM) data = POST(path=path, headers=headers, data=data, dept=DEPT_ACRONYM)
# ^ Renvoie un 404 # ^ Renvoie un 404
except APIError as api_err: except APIError as api_err:
if err is not None: if err is not None:

View File

@ -10,7 +10,7 @@ from types import NoneType
from tests.api.setup_test_api import ( from tests.api.setup_test_api import (
GET, GET,
POST_JSON, POST,
DEPT_ACRONYM, DEPT_ACRONYM,
APIError, APIError,
api_headers, api_headers,
@ -260,7 +260,7 @@ def test_route_create(api_admin_headers):
# Bon fonctionnement # Bon fonctionnement
data = create_data("present", "03") data = create_data("present", "03")
res = POST_JSON( res = POST(
f"/assiduite/{ETUDID}/create", [data], api_admin_headers, dept=DEPT_ACRONYM f"/assiduite/{ETUDID}/create", [data], api_admin_headers, dept=DEPT_ACRONYM
) )
check_fields(res, BATCH_FIELD) check_fields(res, BATCH_FIELD)
@ -275,7 +275,7 @@ def test_route_create(api_admin_headers):
check_fields(data, fields=ASSIDUITES_FIELDS) check_fields(data, fields=ASSIDUITES_FIELDS)
data2 = create_data("absent", "04", MODULE, "desc") data2 = create_data("absent", "04", MODULE, "desc")
res = POST_JSON( res = POST(
f"/assiduite/{ETUDID}/create", [data2], api_admin_headers, dept=DEPT_ACRONYM f"/assiduite/{ETUDID}/create", [data2], api_admin_headers, dept=DEPT_ACRONYM
) )
check_fields(res, BATCH_FIELD) check_fields(res, BATCH_FIELD)
@ -286,7 +286,7 @@ def test_route_create(api_admin_headers):
# Mauvais fonctionnement # Mauvais fonctionnement
check_failure_post(f"/assiduite/{FAUX}/create", api_admin_headers, [data]) check_failure_post(f"/assiduite/{FAUX}/create", api_admin_headers, [data])
res = POST_JSON( res = POST(
f"/assiduite/{ETUDID}/create", [data], api_admin_headers, dept=DEPT_ACRONYM f"/assiduite/{ETUDID}/create", [data], api_admin_headers, dept=DEPT_ACRONYM
) )
check_fields(res, BATCH_FIELD) check_fields(res, BATCH_FIELD)
@ -296,7 +296,7 @@ def test_route_create(api_admin_headers):
== "Duplication: la période rentre en conflit avec une plage enregistrée" == "Duplication: la période rentre en conflit avec une plage enregistrée"
) )
res = POST_JSON( res = POST(
f"/assiduite/{ETUDID}/create", f"/assiduite/{ETUDID}/create",
[create_data("absent", "05", FAUX)], [create_data("absent", "05", FAUX)],
api_admin_headers, api_admin_headers,
@ -316,7 +316,7 @@ def test_route_create(api_admin_headers):
for d in range(randint(2, 4)) for d in range(randint(2, 4))
] ]
res = POST_JSON( res = POST(
f"/assiduite/{ETUDID}/create", data, api_admin_headers, dept=DEPT_ACRONYM f"/assiduite/{ETUDID}/create", data, api_admin_headers, dept=DEPT_ACRONYM
) )
check_fields(res, BATCH_FIELD) check_fields(res, BATCH_FIELD)
@ -334,7 +334,7 @@ def test_route_create(api_admin_headers):
create_data("absent", "01"), create_data("absent", "01"),
] ]
res = POST_JSON( res = POST(
f"/assiduite/{ETUDID}/create", data2, api_admin_headers, dept=DEPT_ACRONYM f"/assiduite/{ETUDID}/create", data2, api_admin_headers, dept=DEPT_ACRONYM
) )
check_fields(res, BATCH_FIELD) check_fields(res, BATCH_FIELD)
@ -359,13 +359,13 @@ def test_route_edit(api_admin_headers):
# Bon fonctionnement # Bon fonctionnement
data = {"etat": "retard", "moduleimpl_id": MODULE} data = {"etat": "retard", "moduleimpl_id": MODULE}
res = POST_JSON( res = POST(
f"/assiduite/{TO_REMOVE[0]}/edit", data, api_admin_headers, dept=DEPT_ACRONYM f"/assiduite/{TO_REMOVE[0]}/edit", data, api_admin_headers, dept=DEPT_ACRONYM
) )
assert res == {"OK": True} assert res == {"OK": True}
data["moduleimpl_id"] = None data["moduleimpl_id"] = None
res = POST_JSON( res = POST(
f"/assiduite/{TO_REMOVE[1]}/edit", data, api_admin_headers, dept=DEPT_ACRONYM f"/assiduite/{TO_REMOVE[1]}/edit", data, api_admin_headers, dept=DEPT_ACRONYM
) )
assert res == {"OK": True} assert res == {"OK": True}
@ -389,13 +389,13 @@ def test_route_delete(api_admin_headers):
# Bon fonctionnement # Bon fonctionnement
data = TO_REMOVE[0] data = TO_REMOVE[0]
res = POST_JSON("/assiduite/delete", [data], api_admin_headers, dept=DEPT_ACRONYM) res = POST("/assiduite/delete", [data], api_admin_headers, dept=DEPT_ACRONYM)
check_fields(res, BATCH_FIELD) check_fields(res, BATCH_FIELD)
for dat in res["success"]: for dat in res["success"]:
assert dat["message"] == "OK" assert dat["message"] == "OK"
# Mauvais fonctionnement # Mauvais fonctionnement
res = POST_JSON("/assiduite/delete", [data], api_admin_headers, dept=DEPT_ACRONYM) res = POST("/assiduite/delete", [data], api_admin_headers, dept=DEPT_ACRONYM)
check_fields(res, BATCH_FIELD) check_fields(res, BATCH_FIELD)
assert len(res["errors"]) == 1 assert len(res["errors"]) == 1
@ -405,7 +405,7 @@ def test_route_delete(api_admin_headers):
data = TO_REMOVE[1:] data = TO_REMOVE[1:]
res = POST_JSON("/assiduite/delete", data, api_admin_headers, dept=DEPT_ACRONYM) res = POST("/assiduite/delete", data, api_admin_headers, dept=DEPT_ACRONYM)
check_fields(res, BATCH_FIELD) check_fields(res, BATCH_FIELD)
for dat in res["success"]: for dat in res["success"]:
assert dat["message"] == "OK" assert dat["message"] == "OK"
@ -418,7 +418,7 @@ def test_route_delete(api_admin_headers):
FAUX + 2, FAUX + 2,
] ]
res = POST_JSON("/assiduite/delete", data2, api_admin_headers, dept=DEPT_ACRONYM) res = POST("/assiduite/delete", data2, api_admin_headers, dept=DEPT_ACRONYM)
check_fields(res, BATCH_FIELD) check_fields(res, BATCH_FIELD)
assert len(res["errors"]) == 3 assert len(res["errors"]) == 3

View File

@ -8,7 +8,7 @@ Utilisation :
import datetime import datetime
import requests import requests
from tests.api.setup_test_api import GET, POST_JSON, api_headers from tests.api.setup_test_api import GET, POST, api_headers
ETUDID = 1 ETUDID = 1
@ -28,7 +28,7 @@ def test_billets(api_headers):
abs_end="2022-08-01", abs_end="2022-08-01",
description="test 1", description="test 1",
) )
billet_r = POST_JSON("/billets_absence/create", billet_d, headers=api_headers) billet_r = POST("/billets_absence/create", billet_d, headers=api_headers)
assert billet_r["etudid"] == billet_d["etudid"] assert billet_r["etudid"] == billet_d["etudid"]
assert datetime.datetime.fromisoformat(billet_r["abs_begin"]).replace( assert datetime.datetime.fromisoformat(billet_r["abs_begin"]).replace(
tzinfo=None tzinfo=None
@ -43,12 +43,10 @@ def test_billets(api_headers):
abs_end="2022-08-03", abs_end="2022-08-03",
description="test 2", description="test 2",
) )
billet_r = POST_JSON("/billets_absence/create", billet_d2, headers=api_headers) billet_r = POST("/billets_absence/create", billet_d2, headers=api_headers)
billets = GET("/billets_absence/etudiant/1", headers=api_headers) billets = GET("/billets_absence/etudiant/1", headers=api_headers)
assert len(billets) == 2 assert len(billets) == 2
# Suppression # Suppression
for billet in billets: for billet in billets:
reply = POST_JSON( reply = POST(f"/billets_absence/{billet['id']}/delete", headers=api_headers)
f"/billets_absence/{billet['id']}/delete", headers=api_headers
)
assert reply["OK"] == True assert reply["OK"] == True

View File

@ -23,7 +23,7 @@ from tests.api.setup_test_api import (
API_URL, API_URL,
CHECK_CERTIFICATE, CHECK_CERTIFICATE,
GET, GET,
POST_JSON, POST,
api_headers, api_headers,
api_admin_headers, api_admin_headers,
) )
@ -42,7 +42,7 @@ def test_create_dept(api_admin_headers):
/departement/<string:dept_acronym>/edit /departement/<string:dept_acronym>/edit
/departement/<string:dept_acronym>/delete /departement/<string:dept_acronym>/delete
""" """
dept = POST_JSON( dept = POST(
"/departement/create", "/departement/create",
{"acronym": "XTEST", "visible": True}, {"acronym": "XTEST", "visible": True},
headers=api_admin_headers, headers=api_admin_headers,
@ -50,14 +50,14 @@ def test_create_dept(api_admin_headers):
dept_r = GET(f"/departement/{dept['acronym']}", headers=api_admin_headers) dept_r = GET(f"/departement/{dept['acronym']}", headers=api_admin_headers)
assert dept["acronym"] == dept_r["acronym"] assert dept["acronym"] == dept_r["acronym"]
assert dept_r["visible"] is True assert dept_r["visible"] is True
dept_e = POST_JSON( dept_e = POST(
f"/departement/{dept['acronym']}/edit", f"/departement/{dept['acronym']}/edit",
{"visible": False}, {"visible": False},
headers=api_admin_headers, headers=api_admin_headers,
) )
dept_r = GET(f"/departement/{dept['acronym']}", headers=api_admin_headers) dept_r = GET(f"/departement/{dept['acronym']}", headers=api_admin_headers)
assert dept_r["visible"] is False assert dept_r["visible"] is False
r = POST_JSON( r = POST(
f"/departement/{dept['acronym']}/delete", f"/departement/{dept['acronym']}/delete",
headers=api_admin_headers, headers=api_admin_headers,
) )

View File

@ -30,7 +30,7 @@ from tests.api.setup_test_api import (
CHECK_CERTIFICATE, CHECK_CERTIFICATE,
DEPT_ACRONYM, DEPT_ACRONYM,
GET, GET,
POST_JSON, POST,
get_auth_headers, get_auth_headers,
) )
from tests.api.setup_test_api import api_headers # pylint: disable=unused-import from tests.api.setup_test_api import api_headers # pylint: disable=unused-import
@ -262,7 +262,7 @@ def test_etudiants_by_name(api_headers):
"dept": DEPT_ACRONYM, "dept": DEPT_ACRONYM,
"civilite": "X", "civilite": "X",
} }
_ = POST_JSON( _ = POST(
"/etudiant/create", "/etudiant/create",
args, args,
headers=admin_header, headers=admin_header,
@ -292,7 +292,7 @@ def test_etudiant_annotations(api_headers):
"dept": DEPT_ACRONYM, "dept": DEPT_ACRONYM,
"civilite": "M", "civilite": "M",
} }
etud = POST_JSON( etud = POST(
"/etudiant/create", "/etudiant/create",
args, args,
headers=admin_header, headers=admin_header,
@ -304,7 +304,7 @@ def test_etudiant_annotations(api_headers):
assert etud["nom"] assert etud["nom"]
assert etud["annotations"] == [] assert etud["annotations"] == []
# ajoute annotation # ajoute annotation
annotation = POST_JSON( annotation = POST(
f"/etudiant/etudid/{etudid}/annotation", f"/etudiant/etudid/{etudid}/annotation",
{"comment": "annotation 1"}, {"comment": "annotation 1"},
headers=admin_header, headers=admin_header,
@ -318,7 +318,7 @@ def test_etudiant_annotations(api_headers):
assert etud["annotations"][0]["comment"] == "annotation 1" assert etud["annotations"][0]["comment"] == "annotation 1"
assert etud["annotations"][0]["id"] == annotation_id assert etud["annotations"][0]["id"] == annotation_id
# Supprime annotation # Supprime annotation
POST_JSON( POST(
f"/etudiant/etudid/{etudid}/annotation/{annotation_id}/delete", f"/etudiant/etudid/{etudid}/annotation/{annotation_id}/delete",
headers=admin_header, headers=admin_header,
) )
@ -932,7 +932,7 @@ def test_etudiant_bulletin_semestre(api_headers):
### -------- Modifie publication bulletins ### -------- Modifie publication bulletins
admin_header = get_auth_headers(API_USER_ADMIN, API_PASSWORD_ADMIN) admin_header = get_auth_headers(API_USER_ADMIN, API_PASSWORD_ADMIN)
formsemestre = POST_JSON( formsemestre = POST(
f"/formsemestre/{1}/edit", {"bul_hide_xml": True}, headers=admin_header f"/formsemestre/{1}/edit", {"bul_hide_xml": True}, headers=admin_header
) )
assert formsemestre["bul_hide_xml"] is True assert formsemestre["bul_hide_xml"] is True
@ -943,7 +943,7 @@ def test_etudiant_bulletin_semestre(api_headers):
# /ScoDoc/api/etudiant/nip/12345/formsemestre/123/bulletin/long/pdf/nosi # /ScoDoc/api/etudiant/nip/12345/formsemestre/123/bulletin/long/pdf/nosi
# TODO voir forme utilisée par ScoDoc en interne: # TODO voir forme utilisée par ScoDoc en interne:
# formsemestre_bulletinetud?formsemestre_id=1263&etudid=16387 # formsemestre_bulletinetud?formsemestre_id=1263&etudid=16387
formsemestre = POST_JSON( formsemestre = POST(
f"/formsemestre/{1}/edit", {"bul_hide_xml": False}, headers=admin_header f"/formsemestre/{1}/edit", {"bul_hide_xml": False}, headers=admin_header
) )
@ -1000,7 +1000,7 @@ def test_etudiant_create(api_headers):
} }
], ],
} }
etud = POST_JSON( etud = POST(
"/etudiant/create", "/etudiant/create",
args, args,
headers=admin_header, headers=admin_header,
@ -1023,7 +1023,7 @@ def test_etudiant_create(api_headers):
# assert etud["adresses"][0]["emailperso"] == args["adresses"][0]["emailperso"] # assert etud["adresses"][0]["emailperso"] == args["adresses"][0]["emailperso"]
# Edition # Edition
etud = POST_JSON( etud = POST(
f"/etudiant/etudid/{etudid}/edit", f"/etudiant/etudid/{etudid}/edit",
{ {
"civilite": "F", "civilite": "F",
@ -1039,7 +1039,7 @@ def test_etudiant_create(api_headers):
assert len(etud["adresses"]) == 1 assert len(etud["adresses"]) == 1
# assert etud["adresses"][0]["villedomicile"] == args["adresses"][0]["villedomicile"] # assert etud["adresses"][0]["villedomicile"] == args["adresses"][0]["villedomicile"]
# assert etud["adresses"][0]["emailperso"] == args["adresses"][0]["emailperso"] # assert etud["adresses"][0]["emailperso"] == args["adresses"][0]["emailperso"]
etud = POST_JSON( etud = POST(
f"/etudiant/etudid/{etudid}/edit", f"/etudiant/etudid/{etudid}/edit",
{ {
"adresses": [ "adresses": [
@ -1051,7 +1051,7 @@ def test_etudiant_create(api_headers):
headers=admin_header, headers=admin_header,
) )
assert etud["adresses"][0]["villedomicile"] == "Barcelona" assert etud["adresses"][0]["villedomicile"] == "Barcelona"
etud = POST_JSON( etud = POST(
f"/etudiant/etudid/{etudid}/edit", f"/etudiant/etudid/{etudid}/edit",
{ {
"admission": { "admission": {

View File

@ -25,7 +25,7 @@ from tests.api.setup_test_api import (
API_URL, API_URL,
CHECK_CERTIFICATE, CHECK_CERTIFICATE,
GET, GET,
POST_JSON, POST,
api_admin_headers, api_admin_headers,
api_headers, api_headers,
check_failure_post, check_failure_post,
@ -114,7 +114,7 @@ def test_evaluation_create(api_admin_headers):
) )
nb_evals = len(evaluations) nb_evals = len(evaluations)
# #
e = POST_JSON( e = POST(
f"/moduleimpl/{moduleimpl_id}/evaluation/create", f"/moduleimpl/{moduleimpl_id}/evaluation/create",
{"description": "eval test"}, {"description": "eval test"},
api_admin_headers, api_admin_headers,
@ -157,7 +157,7 @@ def test_evaluation_create(api_admin_headers):
"publish_incomplete": True, "publish_incomplete": True,
"note_max": 100.0, "note_max": 100.0,
} }
e = POST_JSON( e = POST(
f"/moduleimpl/{moduleimpl_id}/evaluation/create", f"/moduleimpl/{moduleimpl_id}/evaluation/create",
data, data,
api_admin_headers, api_admin_headers,
@ -209,7 +209,7 @@ def test_evaluation_create(api_admin_headers):
ue_ids = [ue["id"] for ue in ues] ue_ids = [ue["id"] for ue in ues]
poids = {ue_id: float(i) + 0.5 for i, ue_id in enumerate(ue_ids)} poids = {ue_id: float(i) + 0.5 for i, ue_id in enumerate(ue_ids)}
data.update({"description": "eval avec poids", "poids": poids}) data.update({"description": "eval avec poids", "poids": poids})
e = POST_JSON( e = POST(
f"/moduleimpl/{moduleimpl_id}/evaluation/create", f"/moduleimpl/{moduleimpl_id}/evaluation/create",
data, data,
api_admin_headers, api_admin_headers,
@ -223,7 +223,7 @@ def test_evaluation_create(api_admin_headers):
assert new_nb_evals == nb_evals + 1 assert new_nb_evals == nb_evals + 1
nb_evals = new_nb_evals nb_evals = new_nb_evals
# Delete # Delete
ans = POST_JSON( ans = POST(
f"/evaluation/{e_ret['id']}/delete", f"/evaluation/{e_ret['id']}/delete",
headers=api_admin_headers, headers=api_admin_headers,
) )

View File

@ -26,7 +26,7 @@ from tests.api.setup_test_api import (
API_URL, API_URL,
CHECK_CERTIFICATE, CHECK_CERTIFICATE,
GET, GET,
POST_JSON, POST,
) )
from tests.api.tools_test_api import ( from tests.api.tools_test_api import (
verify_fields, verify_fields,
@ -338,11 +338,11 @@ def test_api_ue_apo(api_admin_headers):
ue_id = 1 ue_id = 1
ue = GET(path=f"/formation/ue/{ue_id}", headers=api_admin_headers) ue = GET(path=f"/formation/ue/{ue_id}", headers=api_admin_headers)
assert ue["id"] == ue_id assert ue["id"] == ue_id
r = POST_JSON( r = POST(
f"/formation/ue/{ue_id}/set_code_apogee/APOUE", {}, api_admin_headers, raw=True f"/formation/ue/{ue_id}/set_code_apogee/APOUE", {}, api_admin_headers, raw=True
) )
assert r.text == "APOUE" assert r.text == "APOUE"
r = POST_JSON( r = POST(
f"/formation/ue/{ue_id}/set_code_apogee_rcue/APORCUE", f"/formation/ue/{ue_id}/set_code_apogee_rcue/APORCUE",
{}, {},
api_admin_headers, api_admin_headers,
@ -363,7 +363,7 @@ def test_api_module_apo(api_admin_headers):
module = GET(path=f"/formation/module/{module_id}", headers=api_admin_headers) module = GET(path=f"/formation/module/{module_id}", headers=api_admin_headers)
assert module["id"] == module_id assert module["id"] == module_id
assert module["code_apogee"] == "" assert module["code_apogee"] == ""
r = POST_JSON( r = POST(
f"/formation/module/{module_id}/set_code_apogee/APOMOD", f"/formation/module/{module_id}/set_code_apogee/APOMOD",
{}, {},
api_admin_headers, api_admin_headers,
@ -379,7 +379,7 @@ def test_api_module_edit(api_admin_headers):
/formation/module/<int:module_id>/edit /formation/module/<int:module_id>/edit
""" """
module_id = 1 module_id = 1
module = POST_JSON( module = POST(
f"/formation/module/{module_id}/edit", f"/formation/module/{module_id}/edit",
{"heures_cours": 16, "semestre_id": 1, "abbrev": "ALLO"}, {"heures_cours": 16, "semestre_id": 1, "abbrev": "ALLO"},
api_admin_headers, api_admin_headers,
@ -390,7 +390,7 @@ def test_api_module_edit(api_admin_headers):
assert module["abbrev"] == "ALLO" assert module["abbrev"] == "ALLO"
# tente de changer l'UE: ne devrait rien faire: # tente de changer l'UE: ne devrait rien faire:
ue_id = module["ue_id"] ue_id = module["ue_id"]
module = POST_JSON( module = POST(
f"/formation/module/{module_id}/edit", f"/formation/module/{module_id}/edit",
{"ue_id": 666}, {"ue_id": 666},
api_admin_headers, api_admin_headers,
@ -398,7 +398,7 @@ def test_api_module_edit(api_admin_headers):
assert module["ue_id"] == ue_id assert module["ue_id"] == ue_id
# tente de changer la formation: ne devrait rien faire: # tente de changer la formation: ne devrait rien faire:
formation_id = module["formation_id"] formation_id = module["formation_id"]
module = POST_JSON( module = POST(
f"/formation/module/{module_id}/edit", f"/formation/module/{module_id}/edit",
{"formation_id": 666}, {"formation_id": 666},
api_admin_headers, api_admin_headers,
@ -406,7 +406,7 @@ def test_api_module_edit(api_admin_headers):
assert module["formation_id"] == formation_id assert module["formation_id"] == formation_id
# -- assignation de parcours (ce test suppose que les parcours 1, 2, 3 existent) # -- assignation de parcours (ce test suppose que les parcours 1, 2, 3 existent)
assert module["parcours"] == [] assert module["parcours"] == []
module = POST_JSON( module = POST(
f"/formation/module/{module_id}/edit", f"/formation/module/{module_id}/edit",
{"parcours": [1, 2, 3]}, {"parcours": [1, 2, 3]},
api_admin_headers, api_admin_headers,
@ -419,7 +419,7 @@ def test_api_ue_edit(api_admin_headers):
/formation/ue/<int:ue_id>/edit /formation/ue/<int:ue_id>/edit
""" """
ue_id = 1 ue_id = 1
ue = POST_JSON( ue = POST(
f"/formation/ue/{ue_id}/edit", f"/formation/ue/{ue_id}/edit",
{"titre": "formation test modifiée", "numero": 22}, {"titre": "formation test modifiée", "numero": 22},
api_admin_headers, api_admin_headers,
@ -430,7 +430,7 @@ def test_api_ue_edit(api_admin_headers):
# tente de changer le niveau de compétence: ne devrait rien faire: # tente de changer le niveau de compétence: ne devrait rien faire:
niveau_competence_id = ue["niveau_competence_id"] niveau_competence_id = ue["niveau_competence_id"]
ue = POST_JSON( ue = POST(
f"/formation/ue/{ue_id}/edit", f"/formation/ue/{ue_id}/edit",
{"niveau_competence_id": 666}, {"niveau_competence_id": 666},
api_admin_headers, api_admin_headers,
@ -438,7 +438,7 @@ def test_api_ue_edit(api_admin_headers):
assert ue["niveau_competence_id"] == niveau_competence_id assert ue["niveau_competence_id"] == niveau_competence_id
# tente de changer la formation: ne devrait rien faire: # tente de changer la formation: ne devrait rien faire:
formation_id = ue["formation_id"] formation_id = ue["formation_id"]
ue = POST_JSON( ue = POST(
f"/formation/ue/{ue_id}/edit", f"/formation/ue/{ue_id}/edit",
{"formation_id": 666}, {"formation_id": 666},
api_admin_headers, api_admin_headers,

View File

@ -23,7 +23,7 @@ from tests.api.setup_test_api import (
API_URL, API_URL,
CHECK_CERTIFICATE, CHECK_CERTIFICATE,
GET, GET,
POST_JSON, POST,
api_headers, api_headers,
) )
@ -54,7 +54,7 @@ def test_jury_decisions(api_headers):
# ues = export_formation["ue"] # ues = export_formation["ue"]
# # Enregistre une validation d'RCUE # # Enregistre une validation d'RCUE
# etudid = etudiants[0]["id"] # etudid = etudiants[0]["id"]
# validation = POST_JSON( # validation = POST(
# f"/etudiant/{etudid}/jury/validation_rcue/record", # f"/etudiant/{etudid}/jury/validation_rcue/record",
# data={ # data={
# "code": "ADM", # "code": "ADM",

View File

@ -12,7 +12,7 @@ from tests.api.setup_test_api import (
API_URL, API_URL,
CHECK_CERTIFICATE, CHECK_CERTIFICATE,
GET, GET,
POST_JSON, POST,
APIError, APIError,
api_headers, api_headers,
api_admin_headers, api_admin_headers,
@ -105,7 +105,7 @@ def check_failure_post(path, headers, data, err=None):
APIError: Une erreur car la requête a fonctionné (mauvais comportement) APIError: Une erreur car la requête a fonctionné (mauvais comportement)
""" """
try: try:
data = POST_JSON(path=path, headers=headers, data=data) data = POST(path=path, headers=headers, data=data)
# ^ Renvoi un 404 # ^ Renvoi un 404
except APIError as api_err: except APIError as api_err:
if err is not None: if err is not None:
@ -204,14 +204,14 @@ def test_route_create(api_admin_headers):
# Bon fonctionnement # Bon fonctionnement
data = create_data("valide", "01") data = create_data("valide", "01")
res = POST_JSON(f"/justificatif/{ETUDID}/create", [data], api_admin_headers) res = POST(f"/justificatif/{ETUDID}/create", [data], api_admin_headers)
check_fields(res, BATCH_FIELD) check_fields(res, BATCH_FIELD)
assert len(res["success"]) == 1 assert len(res["success"]) == 1
TO_REMOVE.append(res["success"][0]["message"]["justif_id"]) TO_REMOVE.append(res["success"][0]["message"]["justif_id"])
data2 = create_data("modifie", "02", "raison") data2 = create_data("modifie", "02", "raison")
res = POST_JSON(f"/justificatif/{ETUDID}/create", [data2], api_admin_headers) res = POST(f"/justificatif/{ETUDID}/create", [data2], api_admin_headers)
check_fields(res, BATCH_FIELD) check_fields(res, BATCH_FIELD)
assert len(res["success"]) == 1 assert len(res["success"]) == 1
@ -220,7 +220,7 @@ def test_route_create(api_admin_headers):
# Mauvais fonctionnement # Mauvais fonctionnement
check_failure_post(f"/justificatif/{FAUX}/create", api_admin_headers, [data]) check_failure_post(f"/justificatif/{FAUX}/create", api_admin_headers, [data])
res = POST_JSON( res = POST(
f"/justificatif/{ETUDID}/create", f"/justificatif/{ETUDID}/create",
[create_data("absent", "03")], [create_data("absent", "03")],
api_admin_headers, api_admin_headers,
@ -239,7 +239,7 @@ def test_route_create(api_admin_headers):
for d in range(randint(3, 5)) for d in range(randint(3, 5))
] ]
res = POST_JSON(f"/justificatif/{ETUDID}/create", data, api_admin_headers) res = POST(f"/justificatif/{ETUDID}/create", data, api_admin_headers)
check_fields(res, BATCH_FIELD) check_fields(res, BATCH_FIELD)
for dat in res["success"]: for dat in res["success"]:
check_fields(dat["message"], CREATE_FIELD) check_fields(dat["message"], CREATE_FIELD)
@ -253,7 +253,7 @@ def test_route_create(api_admin_headers):
create_data("valide", 32), create_data("valide", 32),
] ]
res = POST_JSON(f"/justificatif/{ETUDID}/create", data2, api_admin_headers) res = POST(f"/justificatif/{ETUDID}/create", data2, api_admin_headers)
check_fields(res, BATCH_FIELD) check_fields(res, BATCH_FIELD)
assert len(res["errors"]) == 3 assert len(res["errors"]) == 3
@ -270,11 +270,11 @@ def test_route_edit(api_admin_headers):
# Bon fonctionnement # Bon fonctionnement
data = {"etat": "modifie", "raison": "test"} data = {"etat": "modifie", "raison": "test"}
res = POST_JSON(f"/justificatif/{TO_REMOVE[0]}/edit", data, api_admin_headers) res = POST(f"/justificatif/{TO_REMOVE[0]}/edit", data, api_admin_headers)
assert isinstance(res, dict) and "couverture" in res.keys() assert isinstance(res, dict) and "couverture" in res.keys()
data["raison"] = None data["raison"] = None
res = POST_JSON(f"/justificatif/{TO_REMOVE[1]}/edit", data, api_admin_headers) res = POST(f"/justificatif/{TO_REMOVE[1]}/edit", data, api_admin_headers)
assert isinstance(res, dict) and "couverture" in res.keys() assert isinstance(res, dict) and "couverture" in res.keys()
# Mauvais fonctionnement # Mauvais fonctionnement
@ -296,13 +296,13 @@ def test_route_delete(api_admin_headers):
# Bon fonctionnement # Bon fonctionnement
data = TO_REMOVE[0] data = TO_REMOVE[0]
res = POST_JSON("/justificatif/delete", [data], api_admin_headers) res = POST("/justificatif/delete", [data], api_admin_headers)
check_fields(res, BATCH_FIELD) check_fields(res, BATCH_FIELD)
for dat in res["success"]: for dat in res["success"]:
assert dat["message"] == "OK" assert dat["message"] == "OK"
# Mauvais fonctionnement # Mauvais fonctionnement
res = POST_JSON("/justificatif/delete", [data], api_admin_headers) res = POST("/justificatif/delete", [data], api_admin_headers)
check_fields(res, BATCH_FIELD) check_fields(res, BATCH_FIELD)
assert len(res["errors"]) == 1 assert len(res["errors"]) == 1
@ -312,7 +312,7 @@ def test_route_delete(api_admin_headers):
data = TO_REMOVE[1:] data = TO_REMOVE[1:]
res = POST_JSON("/justificatif/delete", data, api_admin_headers) res = POST("/justificatif/delete", data, api_admin_headers)
check_fields(res, BATCH_FIELD) check_fields(res, BATCH_FIELD)
for dat in res["success"]: for dat in res["success"]:
assert dat["message"] == "OK" assert dat["message"] == "OK"
@ -325,7 +325,7 @@ def test_route_delete(api_admin_headers):
FAUX + 2, FAUX + 2,
] ]
res = POST_JSON("/justificatif/delete", data2, api_admin_headers) res = POST("/justificatif/delete", data2, api_admin_headers)
check_fields(res, BATCH_FIELD) check_fields(res, BATCH_FIELD)
assert len(res["errors"]) == 3 assert len(res["errors"]) == 3
@ -473,15 +473,13 @@ def test_remove_justificatif(api_admin_headers):
filename: str = "tests/api/test_api_justificatif2.txt" filename: str = "tests/api/test_api_justificatif2.txt"
_send_file(2, filename, api_admin_headers) _send_file(2, filename, api_admin_headers)
res: dict = POST_JSON( res: dict = POST("/justificatif/1/remove", {"remove": "all"}, api_admin_headers)
"/justificatif/1/remove", {"remove": "all"}, api_admin_headers
)
assert res == {"response": "removed"} assert res == {"response": "removed"}
l = GET("/justificatif/1/list", api_admin_headers) l = GET("/justificatif/1/list", api_admin_headers)
assert isinstance(l, dict) assert isinstance(l, dict)
assert l["total"] == 0 assert l["total"] == 0
res: dict = POST_JSON( res: dict = POST(
"/justificatif/2/remove", "/justificatif/2/remove",
{"remove": "list", "filenames": ["test_api_justificatif2.txt"]}, {"remove": "list", "filenames": ["test_api_justificatif2.txt"]},
api_admin_headers, api_admin_headers,
@ -491,7 +489,7 @@ def test_remove_justificatif(api_admin_headers):
assert isinstance(l, dict) assert isinstance(l, dict)
assert l["total"] == 1 assert l["total"] == 1
res: dict = POST_JSON( res: dict = POST(
"/justificatif/2/remove", "/justificatif/2/remove",
{"remove": "list", "filenames": ["test_api_justificatif.txt"]}, {"remove": "list", "filenames": ["test_api_justificatif.txt"]},
api_admin_headers, api_admin_headers,

View File

@ -21,7 +21,7 @@ from tests.api.setup_test_api import (
API_URL, API_URL,
CHECK_CERTIFICATE, CHECK_CERTIFICATE,
GET, GET,
POST_JSON, POST,
api_headers, api_headers,
) )
from tests.api.tools_test_api import ( from tests.api.tools_test_api import (
@ -73,7 +73,7 @@ def test_formsemestre_partition(api_headers):
"bul_show_rank": True, "bul_show_rank": True,
"show_in_lists": True, "show_in_lists": True,
} }
partition_r = POST_JSON( partition_r = POST(
f"/formsemestre/{formsemestre_id}/partition/create", f"/formsemestre/{formsemestre_id}/partition/create",
partition_d, partition_d,
headers=headers, headers=headers,
@ -83,7 +83,7 @@ def test_formsemestre_partition(api_headers):
assert partition_r["groups"] == {} assert partition_r["groups"] == {}
# --- Création Groupe # --- Création Groupe
group_d = {"group_name": "Aé-&"} group_d = {"group_name": "Aé-&"}
group_r = POST_JSON( group_r = POST(
f"/partition/{partition_r['id']}/group/create", f"/partition/{partition_r['id']}/group/create",
group_d, group_d,
headers=headers, headers=headers,
@ -102,14 +102,14 @@ def test_formsemestre_partition(api_headers):
# --- Ajout d'un groupe avec edt_id # --- Ajout d'un groupe avec edt_id
group_d = {"group_name": "extra", "edt_id": "GEDT"} group_d = {"group_name": "extra", "edt_id": "GEDT"}
group_r = POST_JSON( group_r = POST(
f"/partition/{partition_r['id']}/group/create", f"/partition/{partition_r['id']}/group/create",
group_d, group_d,
headers=headers, headers=headers,
) )
assert group_r["edt_id"] == "GEDT" assert group_r["edt_id"] == "GEDT"
# Edit edt_id # Edit edt_id
group_r = POST_JSON( group_r = POST(
f"/group/{group_r['id']}/edit", f"/group/{group_r['id']}/edit",
{"edt_id": "GEDT2"}, {"edt_id": "GEDT2"},
headers=headers, headers=headers,
@ -121,7 +121,7 @@ def test_formsemestre_partition(api_headers):
assert group["edt_id"] == "GEDT2" assert group["edt_id"] == "GEDT2"
# Change edt_id via route dédiée: # Change edt_id via route dédiée:
group_t = POST_JSON( group_t = POST(
f"/group/{group_r['id']}/set_edt_id/GEDT3", f"/group/{group_r['id']}/set_edt_id/GEDT3",
headers=headers, headers=headers,
) )
@ -130,7 +130,7 @@ def test_formsemestre_partition(api_headers):
# Place un étudiant dans le groupe # Place un étudiant dans le groupe
etud = GET(f"/formsemestre/{formsemestre_id}/etudiants", headers=headers)[0] etud = GET(f"/formsemestre/{formsemestre_id}/etudiants", headers=headers)[0]
repl = POST_JSON(f"/group/{group['id']}/set_etudiant/{etud['id']}", headers=headers) repl = POST(f"/group/{group['id']}/set_etudiant/{etud['id']}", headers=headers)
assert isinstance(repl, dict) assert isinstance(repl, dict)
assert repl["group_id"] == group["id"] assert repl["group_id"] == group["id"]
assert repl["etudid"] == etud["id"] assert repl["etudid"] == etud["id"]
@ -139,21 +139,17 @@ def test_formsemestre_partition(api_headers):
assert len(etuds) == 1 assert len(etuds) == 1
assert etuds[0]["id"] == etud["id"] assert etuds[0]["id"] == etud["id"]
# Retire l'étudiant du groupe # Retire l'étudiant du groupe
repl = POST_JSON( repl = POST(f"/group/{group['id']}/remove_etudiant/{etud['id']}", headers=headers)
f"/group/{group['id']}/remove_etudiant/{etud['id']}", headers=headers
)
assert len(GET(f"/group/{group['id']}/etudiants", headers=headers)) == 0 assert len(GET(f"/group/{group['id']}/etudiants", headers=headers)) == 0
# Le retire à nouveau ! (bug #465) # Le retire à nouveau ! (bug #465)
repl = POST_JSON( repl = POST(f"/group/{group['id']}/remove_etudiant/{etud['id']}", headers=headers)
f"/group/{group['id']}/remove_etudiant/{etud['id']}", headers=headers
)
assert repl["group_id"] == group["id"] assert repl["group_id"] == group["id"]
# Avec partition (vérifie encodeur JSON) # Avec partition (vérifie encodeur JSON)
partitions = GET(f"/formsemestre/{formsemestre_id}/partitions", headers=headers) partitions = GET(f"/formsemestre/{formsemestre_id}/partitions", headers=headers)
assert partitions assert partitions
# Delete partition # Delete partition
repl = POST_JSON(f"/partition/{partition_r['id']}/delete", headers=headers) repl = POST(f"/partition/{partition_r['id']}/delete", headers=headers)
assert repl["OK"] is True assert repl["OK"] is True

View File

@ -11,7 +11,7 @@ from tests.api.setup_test_api import (
APIError, APIError,
CHECK_CERTIFICATE, CHECK_CERTIFICATE,
GET, GET,
POST_JSON, POST,
api_headers, api_headers,
api_admin_headers, api_admin_headers,
get_auth_headers, get_auth_headers,
@ -76,7 +76,7 @@ def test_edit_users(api_admin_headers):
""" """
admin_h = api_admin_headers admin_h = api_admin_headers
nb_users = len(GET("/users/query", headers=admin_h)) nb_users = len(GET("/users/query", headers=admin_h))
user = POST_JSON( user = POST(
"/user/create", "/user/create",
{"user_name": "test_edit_users", "nom": "Toto"}, {"user_name": "test_edit_users", "nom": "Toto"},
headers=admin_h, headers=admin_h,
@ -86,7 +86,7 @@ def test_edit_users(api_admin_headers):
assert user["active"] is True assert user["active"] is True
assert (nb_users + 1) == len(GET("/users/query", headers=admin_h)) assert (nb_users + 1) == len(GET("/users/query", headers=admin_h))
# Change le dept et rend inactif # Change le dept et rend inactif
user = POST_JSON( user = POST(
f"/user/{user['id']}/edit", f"/user/{user['id']}/edit",
{"active": False, "dept": "TAPI", "edt_id": "GGG"}, {"active": False, "dept": "TAPI", "edt_id": "GGG"},
headers=admin_h, headers=admin_h,
@ -107,37 +107,37 @@ def test_roles(api_admin_headers):
/user/<int:uid>/edit /user/<int:uid>/edit
""" """
admin_h = api_admin_headers admin_h = api_admin_headers
user = POST_JSON( user = POST(
"/user/create", "/user/create",
{"user_name": "test_roles", "nom": "Role", "prenom": "Test"}, {"user_name": "test_roles", "nom": "Role", "prenom": "Test"},
headers=admin_h, headers=admin_h,
) )
uid = user["id"] uid = user["id"]
ans = POST_JSON(f"/user/{uid}/role/Secr/add", headers=admin_h) ans = POST(f"/user/{uid}/role/Secr/add", headers=admin_h)
assert ans["user_name"] == "test_roles" assert ans["user_name"] == "test_roles"
role = POST_JSON("/role/create/Test_X", headers=admin_h) role = POST("/role/create/Test_X", headers=admin_h)
assert role["role_name"] == "Test_X" assert role["role_name"] == "Test_X"
assert role["permissions"] == [] assert role["permissions"] == []
role = GET("/role/Test_X", headers=admin_h) role = GET("/role/Test_X", headers=admin_h)
assert role["role_name"] == "Test_X" assert role["role_name"] == "Test_X"
assert role["permissions"] == [] assert role["permissions"] == []
role = POST_JSON("/role/Test_X/edit", {"role_name": "Test_Y"}, headers=admin_h) role = POST("/role/Test_X/edit", {"role_name": "Test_Y"}, headers=admin_h)
assert role["role_name"] == "Test_Y" assert role["role_name"] == "Test_Y"
role = GET("/role/Test_Y", headers=admin_h) role = GET("/role/Test_Y", headers=admin_h)
assert role["role_name"] == "Test_Y" assert role["role_name"] == "Test_Y"
role = POST_JSON( role = POST(
"/role/Test_Y/edit", "/role/Test_Y/edit",
{"permissions": ["ScoView", "AbsChange"]}, {"permissions": ["ScoView", "AbsChange"]},
headers=admin_h, headers=admin_h,
) )
assert set(role["permissions"]) == {"ScoView", "AbsChange"} assert set(role["permissions"]) == {"ScoView", "AbsChange"}
role = POST_JSON("/role/Test_Y/add_permission/AbsAddBillet", headers=admin_h) role = POST("/role/Test_Y/add_permission/AbsAddBillet", headers=admin_h)
assert set(role["permissions"]) == {"ScoView", "AbsChange", "AbsAddBillet"} assert set(role["permissions"]) == {"ScoView", "AbsChange", "AbsAddBillet"}
role = GET("/role/Test_Y", headers=admin_h) role = GET("/role/Test_Y", headers=admin_h)
assert set(role["permissions"]) == {"ScoView", "AbsChange", "AbsAddBillet"} assert set(role["permissions"]) == {"ScoView", "AbsChange", "AbsAddBillet"}
role = POST_JSON("/role/Test_Y/remove_permission/AbsChange", headers=admin_h) role = POST("/role/Test_Y/remove_permission/AbsChange", headers=admin_h)
assert set(role["permissions"]) == {"ScoView", "AbsAddBillet"} assert set(role["permissions"]) == {"ScoView", "AbsAddBillet"}
ans = POST_JSON("/role/Test_Y/delete", headers=admin_h) ans = POST("/role/Test_Y/delete", headers=admin_h)
assert ans["OK"] is True assert ans["OK"] is True
@ -153,7 +153,7 @@ def test_modif_users_depts(api_admin_headers):
# On va utiliser les 3 1er dept (TAPI, AA, BB) # On va utiliser les 3 1er dept (TAPI, AA, BB)
# On crée un nouvel utilisateur "chef2", admin dans les 2 premiers dept # On crée un nouvel utilisateur "chef2", admin dans les 2 premiers dept
# puis un utilisateur lambda, dans le dept 2 (AA) # puis un utilisateur lambda, dans le dept 2 (AA)
chef2 = POST_JSON( chef2 = POST(
"/user/create", "/user/create",
{ {
"user_name": "chef2", "user_name": "chef2",
@ -163,23 +163,23 @@ def test_modif_users_depts(api_admin_headers):
}, },
headers=admin_h, headers=admin_h,
) )
role_chef = POST_JSON( role_chef = POST(
"/role/create/chef", "/role/create/chef",
{"permissions": ["ScoView", "UsersAdmin", "UsersView"]}, {"permissions": ["ScoView", "UsersAdmin", "UsersView"]},
headers=admin_h, headers=admin_h,
) )
_ = POST_JSON( _ = POST(
f"/user/{chef2['id']}/role/chef/add/departement/{dept1['acronym']}", f"/user/{chef2['id']}/role/chef/add/departement/{dept1['acronym']}",
headers=admin_h, headers=admin_h,
) )
_ = POST_JSON( _ = POST(
f"/user/{chef2['id']}/role/chef/add/departement/{dept2['acronym']}", f"/user/{chef2['id']}/role/chef/add/departement/{dept2['acronym']}",
headers=admin_h, headers=admin_h,
) )
# Un mot de passe trop simple: # Un mot de passe trop simple:
ok = False ok = False
try: try:
_ = POST_JSON( _ = POST(
f"/user/{chef2['id']}/password", f"/user/{chef2['id']}/password",
{"password": "123456"}, {"password": "123456"},
headers=admin_h, headers=admin_h,
@ -190,13 +190,13 @@ def test_modif_users_depts(api_admin_headers):
assert ok assert ok
# Un "vrai" mot de passe: # Un "vrai" mot de passe:
chef2_password = "17HIOPpYhabb8qw'E:/jd7FFddjd" chef2_password = "17HIOPpYhabb8qw'E:/jd7FFddjd"
_ = POST_JSON( _ = POST(
f"/user/{chef2['id']}/password", f"/user/{chef2['id']}/password",
{"password": chef2_password}, {"password": chef2_password},
headers=admin_h, headers=admin_h,
) )
# Création user lambda: # Création user lambda:
u_lambda = POST_JSON( u_lambda = POST(
"/user/create", "/user/create",
{ {
"user_name": "lambda", "user_name": "lambda",
@ -210,7 +210,7 @@ def test_modif_users_depts(api_admin_headers):
# Le chef va modifier u_lambda: # Le chef va modifier u_lambda:
chef_h = get_auth_headers(chef2["user_name"], chef2_password) chef_h = get_auth_headers(chef2["user_name"], chef2_password)
# on utilise une URL avec département car on n'a pas le droit sur tous: # on utilise une URL avec département car on n'a pas le droit sur tous:
u = POST_JSON( u = POST(
f"/user/{u_lambda['id']}/edit", f"/user/{u_lambda['id']}/edit",
{"nom": "toto"}, {"nom": "toto"},
headers=chef_h, headers=chef_h,
@ -218,7 +218,7 @@ def test_modif_users_depts(api_admin_headers):
) )
assert u["nom"] == "toto" assert u["nom"] == "toto"
# Dans l'autre ? # Dans l'autre ?
u = POST_JSON( u = POST(
f"/user/{u_lambda['id']}/edit", f"/user/{u_lambda['id']}/edit",
{"nom": "toto"}, {"nom": "toto"},
headers=chef_h, headers=chef_h,
@ -227,7 +227,7 @@ def test_modif_users_depts(api_admin_headers):
# mais pas dans le troisième: # mais pas dans le troisième:
ok = False ok = False
try: try:
u = POST_JSON( u = POST(
f"/user/{u_lambda['id']}/edit", f"/user/{u_lambda['id']}/edit",
{"nom": "toto"}, {"nom": "toto"},
headers=chef_h, headers=chef_h,
@ -240,7 +240,7 @@ def test_modif_users_depts(api_admin_headers):
# Nettoyage: # Nettoyage:
# on ne peut pas supprimer l'utilisateur lambda, mais on # on ne peut pas supprimer l'utilisateur lambda, mais on
# le rend inactif et on le retire de son département # le rend inactif et on le retire de son département
u = POST_JSON( u = POST(
f"/user/{u_lambda['id']}/edit", f"/user/{u_lambda['id']}/edit",
{"active": False, "dept": None}, {"active": False, "dept": None},
headers=admin_h, headers=admin_h,

View File

@ -1,120 +1,90 @@
"entry_name";"url";"permission";"method";"content" "entry_name";"url";"permission";"method";"content"
"assiduite_create";"/assiduite/1/create";"ScoView";"POST";"{""date_debut"": ""2022-10-27T08:00"",""date_fin"": ""2022-10-27T10:00"",""etat"": ""absent""}"
"assiduite_create";"/assiduite/1/create/batch";"ScoView";"POST";"{""batch"":[{""date_debut"": ""2022-10-27T08:00"",""date_fin"": ""2022-10-27T10:00"",""etat"": ""absent""},{""date_debut"": ""2022-10-27T08:00"",""date_fin"": ""2022-10-27T10:00"",""etat"": ""retard""},{""date_debut"": ""2022-10-27T11:00"",""date_fin"": ""2022-10-27T13:00"",""etat"": ""present""}]}"
"assiduite_delete";"/assiduite/delete";"ScoView";"POST";"{""assiduite_id"": 1}"
"assiduite_delete";"/assiduite/delete/batch";"ScoView";"POST";"{""batch"":[2,2,3]}"
"assiduite_edit";"/assiduite/1/edit";"ScoView";"POST";"{""etat"": ""retard"",""moduleimpl_id"":3}"
"assiduite_edit";"/assiduite/1/edit";"ScoView";"POST";"{""etat"":""absent""}"
"assiduite_edit";"/assiduite/1/edit";"ScoView";"POST";"{""moduleimpl_id"":2}"
"assiduite";"/assiduite/1";"ScoView";"GET"; "assiduite";"/assiduite/1";"ScoView";"GET";
"assiduite_justificatifs";"/assiduite/1/justificatifs";"ScoView";"GET";
"assiduite_justificatifs";"/assiduite/1/justificatifs/long";"ScoView";"GET";
"assiduites_count";"/assiduites/1/count";"ScoView";"GET"; "assiduites_count";"/assiduites/1/count";"ScoView";"GET";
"assiduites_count";"/assiduites/1/count/query?etat=present,retard&metric=compte,heure";"ScoView";"GET";
"assiduites_count";"/assiduites/1/count/query?etat=retard";"ScoView";"GET"; "assiduites_count";"/assiduites/1/count/query?etat=retard";"ScoView";"GET";
"assiduites_formsemestre_count";"/assiduites/formsemestre/1/count";"ScoView";"GET"; "assiduites_count";"/assiduites/1/count/query?split";"ScoView";"GET";
"assiduites_formsemestre_count";"/assiduites/formsemestre/1/count/query?etat=present,retard&metric=compte,heure";"ScoView";"GET"; "assiduites_count";"/assiduites/1/count/query?etat=present,retard&metric=compte,heure";"ScoView";"GET";
"assiduites_formsemestre_count";"/assiduites/formsemestre/1/count/query?etat=retard";"ScoView";"GET";
"assiduites_formsemestre";"/assiduites/formsemestre/1";"ScoView";"GET";
"assiduites_formsemestre";"/assiduites/formsemestre/1/query?etat=retard";"ScoView";"GET";
"assiduites_formsemestre";"/assiduites/formsemestre/1/query?moduleimpl_id=1";"ScoView";"GET";
"assiduites";"/assiduites/1";"ScoView";"GET"; "assiduites";"/assiduites/1";"ScoView";"GET";
"assiduites";"/assiduites/1/query?etat=retard";"ScoView";"GET"; "assiduites";"/assiduites/1/query?etat=retard";"ScoView";"GET";
"assiduites";"/assiduites/1/query?moduleimpl_id=1";"ScoView";"GET"; "assiduites";"/assiduites/1/query?moduleimpl_id=1";"ScoView";"GET";
"departement-create";"/departement/create";"ScoSuperAdmin";"POST";"{""acronym"": ""NEWONE"" , ""visible"": true}" "assiduites";"/assiduites/1/query?with_justifs=";"ScoView";"GET";
"departement-delete";"/departement/NEWONE/delete";"ScoSuperAdmin";"POST"; "assiduites_evaluations";"/assiduites/1/evaluations";"ScoView";"GET";
"departement-edit";"/departement/NEWONE/edit";"ScoSuperAdmin";"POST";"{""visible"": false}" "assiduites_group";"/assiduites/group/query?etudids=1,2,3";"ScoView";"GET";
"departement-etudiants";"/departement/id/1/etudiants";"ScoView";"GET"; "assiduites_formsemestre";"/assiduites/formsemestre/1";"ScoView";"GET";
"departement-etudiants";"/departement/TAPI/etudiants";"ScoView";"GET"; "assiduites_formsemestre";"/assiduites/formsemestre/1/query?etat=retard";"ScoView";"GET";
"departement-formsemestres_ids";"/departement/id/1/formsemestres_ids";"ScoView";"GET"; "assiduites_formsemestre";"/assiduites/formsemestre/1/query?moduleimpl_id=1";"ScoView";"GET";
"departement-formsemestres_ids";"/departement/TAPI/formsemestres_ids";"ScoView";"GET"; "assiduites_formsemestre_count";"/assiduites/formsemestre/1/count";"ScoView";"GET";
"departement-formsemestres-courants";"/departement/id/1/formsemestres_courants";"ScoView";"GET"; "assiduites_formsemestre_count";"/assiduites/formsemestre/1/count/query?etat=retard";"ScoView";"GET";
"departement-formsemestres-courants";"/departement/TAPI/formsemestres_courants";"ScoView";"GET"; "assiduites_formsemestre_count";"/assiduites/formsemestre/1/count/query?etat=present,retard&metric=compte,heure";"ScoView";"GET";
"departement-logo";"/departement/id/1/logo/D";"ScoSuperAdmin";"GET"; "assiduite_create";"/assiduite/1/create";"UsersAdmin";"POST";"[{""date_debut"": ""2023-10-27T08:00"",""date_fin"": ""2023-10-27T10:00"",""etat"": ""absent""}]"
"departement-logo";"/departement/TAPI/logo/D";"ScoSuperAdmin";"GET"; "assiduite_create";"/assiduite/1/create";"UsersAdmin";"POST";"[{""date_debut"": ""2023-10-27T08:00"",""date_fin"": ""2023-10-27T10:00"",""etat"": ""absent""}]"
"departement-logos";"/departement/id/1/logos";"ScoSuperAdmin";"GET"; "assiduites_create";"/assiduites/create";"UsersAdmin";"POST";"[{""etudid"":1,""date_debut"": ""2023-10-26T08:00"",""date_fin"": ""2023-10-26T10:00"",""etat"": ""absent""}]"
"departement-logos";"/departement/TAPI/logos";"ScoSuperAdmin";"GET"; "assiduites_create";"/assiduites/create";"UsersAdmin";"POST";"[{""etudid"":-1,""date_debut"": ""2023-10-26T08:00"",""date_fin"": ""2023-10-26T10:00"",""etat"": ""absent""}]"
"departement";"/departement/id/1";"ScoView";"GET"; "assiduite_delete";"/assiduite/delete";"UsersAdmin";"POST";"[2,2,3]"
"departement";"/departement/TAPI";"ScoView";"GET"; "assiduite_edit";"/assiduite/1/edit";"UsersAdmin";"POST";"{""etat"":""absent""}"
"departements-ids";"/departements_ids";"ScoView";"GET"; "assiduite_edit";"/assiduite/1/edit";"UsersAdmin";"POST";"{""moduleimpl_id"":2}"
"departements";"/departements";"ScoView";"GET"; "assiduite_edit";"/assiduite/1/edit";"UsersAdmin";"POST";"{""etat"": ""retard"",""moduleimpl_id"":3}"
"etudiant_formsemestres";"/etudiant/nip/11/formsemestres";"ScoView";"GET"; "billets_absence_create";"/billets_absence/create";"UsersAdmin";"POST";"{""etudid"":""1"",""abs_begin"":""2023-10-27T10:00"",""abs_end"":""2023-10-28T10:00"",""description"":""grave malade"",""justified"":""1""}"
"etudiant-formsemestre-bulletin";"/etudiant/etudid/11/formsemestre/1/bulletin";"ScoView";"GET"; "departements_list";"/departements";"ScoView";"GET";
#"etudiant-formsemestre-bulletin";"/etudiant/ine/INE11/formsemestre/1/bulletin";"ScoView";"GET"; "departements_ids";"/departements_ids";"ScoView";"GET";
#"etudiant-formsemestre-bulletin";"/etudiant/nip/11/formsemestre/1/bulletin";"ScoView";"GET"; "departement_by_acronym";"/departement/TAPI";"ScoView";"GET";
#"etudiant-formsemestre-bulletin";"/etudiant/nip/11/formsemestre/1/bulletin/short/pdf";"ScoView";"GET"; "departement_get";"/departement/id/1";"ScoView";"GET";
"etudiant-formsemestre-groups";"/etudiant/etudid/11/formsemestre/1/groups";"ScoView";"GET"; "departement_create";"/departement/create";"UsersAdmin";"POST";"{""acronym"":""MYDEPT"",""visible"":""1""}"
"etudiant-formsemestres";"/etudiant/etudid/11/formsemestres";"ScoView";"GET"; "departement_etudiants";"/departement/TAPI/etudiants";"ScoView";"GET";
"etudiant-formsemestres";"/etudiant/ine/INE11/formsemestres";"ScoView";"GET"; "departement_formsemestres_ids";"/departement/TAPI/formsemestres_ids";"ScoView";"GET";
"etudiant";"/etudiant/etudid/11";"ScoView";"GET"; "departement_formsemestres_ids_by_id";"/departement/id/1/formsemestres_ids";"ScoView";"GET";
"etudiant";"/etudiant/ine/INE11";"ScoView";"GET"; "departement_formsemestres_courants";"/departement/id/1/formsemestres_courants?date_courante=2022-01-01";"ScoView";"GET";
"etudiant";"/etudiant/nip/11";"ScoView";"GET"; "etudiants_courants";"/etudiants/courants?date_courante=2022-05-01";"ScoView";"GET";
"etudiants-clef";"/etudiants/etudid/11";"ScoView";"GET"; "etudiants_courants";"/etudiants/courants/long?date_courante=2022-05-01";"ScoView";"GET";
"etudiants-clef";"/etudiants/ine/INE11";"ScoView";"GET"; "bulletin";"/etudiant/etudid/1/formsemestre/1/bulletin";"ScoView";"GET";
"etudiants-clef";"/etudiants/nip/11";"ScoView";"GET"; "etudiant_groups";"/etudiant/etudid/1/formsemestre/1/groups";"ScoView";"GET";
"etudiants-courants";"/etudiants/courants?date_courante=2022-07-20";"ScoView";"GET"; "etudiant_edit";"/etudiant/ine/INE1/edit";"UsersAdmin";"POST";"{""prenom"":""Nouveau Prénom"", ""adresses"":[{""email"":""nouvelle@adresse.fr""}]}"
"etudiants-courants";"/etudiants/courants/long?date_courante=2022-07-20";"ScoView";"GET"; "etudiant_annotation";"/etudiant/etudid/1/annotation";"UsersAdmin";"POST";"{""comment"":""une annotation sur l'étudiant""}"
"evaluation";"/evaluation/1";"ScoView";"GET"; "moduleimpl_evaluations";"/moduleimpl/1/evaluations";"ScoView";"GET";
"evaluation-notes";"/evaluation/1/notes";"ScoView";"GET"; "evaluation_notes";"/evaluation/2/notes";"ScoView";"GET";
"formation-export";"/formation/1/export_with_ids";"ScoView";"GET"; "evaluation_set_notes";"/evaluation/1/notes/set";"UsersAdmin";"POST";"{""notes"": [[1, 17], [2, ""SUPR""]], ""comment"" : ""sample test""}"
"formation-export";"/formation/1/export";"ScoView";"GET"; "evaluation_create";"/moduleimpl/1/evaluation/create";"UsersAdmin";"POST";"{""description"":""Exemple éval.""}"
"formation-referentiel_competences";"/formation/1/referentiel_competences";"ScoView";"GET";
"formation";"/formation/1";"ScoView";"GET";
"formations_ids";"/formations_ids";"ScoView";"GET";
"formations";"/formations";"ScoView";"GET"; "formations";"/formations";"ScoView";"GET";
"formsemestre-bulletins";"/formsemestre/1/bulletins";"ScoView";"GET"; "formations_ids";"/formations_ids";"ScoView";"GET";
"formsemestre-decisions_jury";"/formsemestre/1/decisions_jury";"ScoView";"GET"; "formation_get";"/formation/1";"ScoView";"GET";
"formsemestre-etat_evals";"/formsemestre/1/etat_evals";"ScoView";"GET"; "formation_export_by_formation_id";"/formation/1/export";"ScoView";"GET";
"formsemestre-etudiants-query";"/formsemestre/1/etudiants/query?etat=D";"ScoView";"GET"; "referentiel_competences";"/formation/1/referentiel_competences";"ScoView";"GET";
"formsemestre-etudiants";"/formsemestre/1/etudiants";"ScoView";"GET"; "formation_module_get";"/formation/module/1";"ScoView";"GET";
"formsemestre-etudiants";"/formsemestre/1/etudiants/long";"ScoView";"GET"; "formsemestre_get";"/formsemestre/1";"ScoView";"GET";
"formsemestre-partition-create";"/formsemestre/1/partition/create";"ScoSuperAdmin";"POST";"{""partition_name"": ""PART""} " "bulletins";"/formsemestre/1/bulletins";"ScoView";"GET";
"formsemestre-partitions-order";"/formsemestre/1/partitions/order";"ScoSuperAdmin";"POST";"[ 1 ]" "formsemestre_programme";"/formsemestre/1/programme";"ScoView";"GET";
"formsemestre-partitions";"/formsemestre/1/partitions";"ScoView";"GET"; "formsemestre_etudiants";"/formsemestre/1/etudiants/query";"ScoView";"GET";
"formsemestre-programme";"/formsemestre/1/programme";"ScoView";"GET"; "formsemestre_etat_evaluations";"/formsemestre/1/etat_evals";"ScoView";"GET";
"formsemestre-resultats";"/formsemestre/1/resultats";"ScoView";"GET"; "formsemestre_resultat";"/formsemestre/1/resultats";"ScoView";"GET";
"formsemestre";"/formsemestre/1";"ScoView";"GET"; "decisions_jury";"/formsemestre/1/decisions_jury";"ScoView";"GET";
"formsemestres-query";"/formsemestres/query?annee_scolaire=2022&etape_apo=A2";"ScoView";"GET"; "justificatif";"/justificatif/1";"ScoView";"GET";
"formsemestres-query";"/formsemestres/query?nip=11";"ScoView";"GET"; "justificatifs";"/justificatifs/1";"ScoView";"GET";
"group-delete";"/group/2/delete";"ScoSuperAdmin";"POST"; "justificatifs";"/justificatifs/1/query?etat=attente";"ScoView";"GET";
"group-edit";"/group/2/edit";"ScoSuperAdmin";"POST";"{""group_name"": ""NEW_GROUP2""}" "justificatifs_dept";"/justificatifs/dept/1";"ScoView";"GET";
"group-etudiants-query";"/group/1/etudiants/query?etat=D";"ScoView";"GET"; "justificatifs_formsemestre";"/justificatifs/formsemestre/1";"ScoView";"GET";
"group-etudiants";"/group/1/etudiants";"ScoView";"GET"; "justif_edit";"/justificatif/1/edit";"UsersAdmin";"POST";"{""etat"":""valide""}"
"group-remove_etudiant";"/group/1/remove_etudiant/10";"ScoSuperAdmin";"POST"; "justif_edit";"/justificatif/1/edit";"UsersAdmin";"POST";"{""raison"":""MEDIC""}"
"group-set_etudiant";"/group/1/set_etudiant/10";"ScoSuperAdmin";"POST"; "justif_delete";"/justificatif/delete";"UsersAdmin";"POST";"[2, 2, 3]"
"logo";"/logo/B";"ScoSuperAdmin";"GET"; "justif_list";"/justificatif/1/list";"ScoView";"GET";
"logos";"/logos";"ScoSuperAdmin";"GET"; "justif_justifies";"/justificatif/1/justifies";"UsersAdmin";"GET";
"moduleimpl-evaluations";"/moduleimpl/1/evaluations";"ScoView";"GET"; "logo_list_globals";"/logos";"UsersAdmin";"GET";
"moduleimpl";"/moduleimpl/1";"ScoView";"GET"; "logo_get_global";"/logo/B";"UsersAdmin";"GET";
"partition-delete";"/partition/2/delete";"ScoSuperAdmin";"POST"; "departement_logos";"/departement/TAPI/logos";"UsersAdmin";"GET";
"partition-edit";"/partition/1/edit";"ScoSuperAdmin";"POST";"{""partition_name"":""P2BIS"", ""numero"":3,""bul_show_rank"":true,""show_in_lists"":false, ""groups_editable"":true}" "moduleimpl_inscriptions";"/moduleimpl/1/inscriptions";"ScoView";"GET";
"partition-group-create";"/partition/1/group/create";"ScoSuperAdmin";"POST";"{""group_name"": ""NEW_GROUP""}" "moduleimpl_notes";"/moduleimpl/1/notes";"ScoView";"GET";
"partition-groups-order";"/partition/1/groups/order";"ScoSuperAdmin";"POST";"[ 1 ]" "partition_info";"/partition/1";"ScoView";"GET";
"partition-remove_etudiant";"/partition/2/remove_etudiant/10";"ScoSuperAdmin";"POST"; "formsemestre_partitions";"/formsemestre/1/partitions";"ScoView";"GET";
"partition";"/partition/1";"ScoView";"GET"; "group_etudiants";"/group/1/etudiants";"ScoView";"GET";
"permissions";"/permissions";"ScoView";"GET"; "group_create";"/partition/1/group/create";"ScoView";"POST";"{""group_name"" : ""Nouveau Groupe""}"
"role-add_permission";"/role/customRole/add_permission/UsersView";"ScoSuperAdmin";"POST"; "group_edit";"/group/1/edit";"ScoView";"POST";"{""group_name"":""A1""}"
"role-create";"/role/create/customRole";"ScoSuperAdmin";"POST";"{""permissions"": [""ScoView"", ""UsersView""]}" "group_set_edt_id";"/group/1/set_edt_id/EDT_GR1";"ScoView";"POST";
"role-delete";"/role/customRole/delete";"ScoSuperAdmin";"POST"; "partition_edit";"/partition/1/edit";"ScoView";"POST";"{""bul_show_rank"":1}"
"role-edit";"/role/customRole/edit";"ScoSuperAdmin";"POST";"{ ""name"" : ""LaveurDeVitres"", ""permissions"" : [ ""ScoView"" ] }" "user_info";"/user/2";"UsersAdmin";"GET";
"role-remove_permission";"/role/customRole/remove_permission/UsersView";"ScoSuperAdmin";"POST"; "user_password";"/user/3/password";"UsersAdmin";"POST";"{""password"" : ""rePlaCemeNT456averylongandcomplicated""}"
"role";"/role/Observateur";"ScoView";"GET"; "permissions_list";"/permissions";"UsersAdmin";"GET";
"roles";"/roles";"ScoView";"GET"; "role_get";"/role/Ens";"UsersAdmin";"GET";
"test-pdf";"/etudiant/etudid/11/formsemestre/1/bulletin";"ScoView";"GET"; "roles_list";"/roles";"UsersAdmin";"GET";
"test-pdf";"/etudiant/etudid/11/formsemestre/1/bulletin/pdf";"ScoView";"GET"; "role_create";"/role/create/customRole";"UsersAdmin";"POST";"{""permissions"": [""ScoView"", ""UsersView""]}"
"test-pdf";"/etudiant/etudid/11/formsemestre/1/bulletin/short";"ScoView";"GET"; "role_delete";"/role/customRole/delete";"UsersAdmin";"POST";
"test-pdf";"/etudiant/etudid/11/formsemestre/1/bulletin/short/pdf";"ScoView";"GET";
"test-pdf";"/etudiant/ine/INE11/formsemestre/1/bulletin";"ScoView";"GET";
"test-pdf";"/etudiant/ine/INE11/formsemestre/1/bulletin/short";"ScoView";"GET";
"test-pdf";"/etudiant/ine/INE11/formsemestre/1/bulletin/short/pdf";"ScoView";"GET";
"test-pdf";"/etudiant/nip/11/formsemestre/1/bulletin";"ScoView";"GET";
"test-pdf";"/etudiant/nip/11/formsemestre/1/bulletin/pdf";"ScoView";"GET";
"test-pdf";"/etudiant/nip/11/formsemestre/1/bulletin/pdf";"ScoView";"GET";
"test-pdf";"/etudiant/nip/11/formsemestre/1/bulletin/short";"ScoView";"GET";
"test-pdf";"/etudiant/nip/11/formsemestre/1/bulletin/short/pdf";"ScoView";"GET";
"user-create";"/user/create";"ScoSuperAdmin";"POST";"{""user_name"": ""alain"", ""dept"": null, ""nom"": ""alain"", ""prenom"": ""bruno"", ""active"": true }"
"user-edit";"/user/10/edit";"ScoSuperAdmin";"POST";"{ ""dept"": ""TAPI"", ""nom"": ""alain2"", ""prenom"": ""bruno2"", ""active"": false }"
"user-password";"/user/3/password";"ScoSuperAdmin";"POST";"{ ""password"": ""rePlaCemeNT456averylongandcomplicated"" }"
"user-password";"/user/3/password";"ScoSuperAdmin";"POST";"{ ""password"": ""too_simple"" }"
"user-role-add";"/user/10/role/Observateur/add";"ScoSuperAdmin";"POST";
"user-role-remove";"/user/10/role/Observateur/remove";"ScoSuperAdmin";"POST";
"user";"/user/1";"ScoView";"GET";
"users-query";"/users/query?starts_with=u_";"ScoView";"GET";
Can't render this file because it contains an unexpected character in line 41 and column 2.

View File

@ -211,10 +211,17 @@ def create_formsemestre(
) )
db.session.add(modimpl) db.session.add(modimpl)
db.session.commit() db.session.commit()
# Partition par défaut (requise):
partition_id = sco_groups.partition_create( partition_id = sco_groups.partition_create(
formsemestre.id, default=True, redirect=False formsemestre.id, default=True, redirect=False
) )
group = sco_groups.create_group(partition_id, default=True) sco_groups.create_group(partition_id, default=True)
# Ajoute partition normale, TD avec groupes A et B:
partition_id = sco_groups.partition_create(
formsemestre.id, partition_name="TD", redirect=False
)
sco_groups.create_group(partition_id, group_name="A")
sco_groups.create_group(partition_id, group_name="B")
return formsemestre return formsemestre