Compare commits

...

21 Commits

Author SHA1 Message Date
leonard_montalbano
dd3bea414d consolidations des tests unitaires de départements 2022-05-10 15:56:21 +02:00
6e43ec6feb Affichage groupes sur page étud. Closes #373 2022-05-09 20:01:11 +02:00
21d9655655 Export recap complet en excel brut 2022-05-09 18:32:54 +02:00
34d64b3fd8 API: Fix accès par INE et NIP alphanumériques 2022-05-07 08:23:30 +02:00
bba7906493 API: traitement des paramètres erronés (404) + test 2022-05-06 09:38:30 +02:00
1accb5025a Fix bulletins BUT pdf UE bonus quand non inscrit (#376) 2022-05-06 07:25:35 +02:00
9809936d70 Saisie note eval sans dates: Fixes #378 2022-05-06 01:15:37 +02:00
912af87603 Fixes #377 2022-05-06 01:06:58 +02:00
f0744c594a Typo, fixes #375 2022-05-05 22:44:46 +02:00
7594781001 API: fix test_api_permissions.py 2022-05-05 22:40:44 +02:00
4ab43f59c1 API: test_api_formsemestre 2022-05-05 20:06:49 +02:00
2d40932b50 API: tests: factorisation du code 2022-05-05 19:50:09 +02:00
f2718635bb API: ajout /departement/<string:dept>/formsemestres_ids 2022-05-05 19:49:43 +02:00
f8a3ef8bb5 API Test: fix 2022-05-05 19:13:12 +02:00
be51032b8a API tests: fix verify_fields qui testait à l'envers 2022-05-05 19:12:03 +02:00
8486512f83 API: Departement: tests unitaires et corrections. 2022-05-05 18:50:59 +02:00
ba6b275973 API: WIP 2022-05-05 18:11:44 +02:00
16d968ef95 Ajout code INE à l'export court API 2022-05-05 18:11:10 +02:00
c55a7dcbb4 Ajout titre_formation 2022-05-05 18:10:22 +02:00
69e6b045db Preparation évol. sco_preferences 2022-05-05 18:09:32 +02:00
b740f40389 API: ajout session_id au formsemestre. formsemestre/programme 2022-05-05 08:21:42 +02:00
9 changed files with 220 additions and 90 deletions

View File

@ -55,8 +55,8 @@ def etudiants_courant(long=False):
@bp.route("/etudiant/etudid/<int:etudid>", methods=["GET"]) @bp.route("/etudiant/etudid/<int:etudid>", methods=["GET"])
@bp.route("/etudiant/nip/<int:nip>", methods=["GET"]) @bp.route("/etudiant/nip/<string:nip>", methods=["GET"])
@bp.route("/etudiant/ine/<int:ine>", methods=["GET"]) @bp.route("/etudiant/ine/<string:ine>", methods=["GET"])
@token_auth.login_required @token_auth.login_required
@token_permission_required(Permission.APIView) @token_permission_required(Permission.APIView)
def etudiant(etudid: int = None, nip: int = None, ine: int = None): def etudiant(etudid: int = None, nip: int = None, ine: int = None):
@ -109,8 +109,8 @@ def etudiant(etudid: int = None, nip: int = None, ine: int = None):
@bp.route("/etudiant/etudid/<int:etudid>/formsemestres") @bp.route("/etudiant/etudid/<int:etudid>/formsemestres")
@bp.route("/etudiant/nip/<int:nip>/formsemestres") @bp.route("/etudiant/nip/<string:nip>/formsemestres")
@bp.route("/etudiant/ine/<int:ine>/formsemestres") @bp.route("/etudiant/ine/<string:ine>/formsemestres")
@token_auth.login_required @token_auth.login_required
@token_permission_required(Permission.APIView) @token_permission_required(Permission.APIView)
def etudiant_formsemestres(etudid: int = None, nip: int = None, ine: int = None): def etudiant_formsemestres(etudid: int = None, nip: int = None, ine: int = None):
@ -175,12 +175,12 @@ def etudiant_formsemestres(etudid: int = None, nip: int = None, ine: int = None)
defaults={"version": "long"}, defaults={"version": "long"},
) )
@bp.route( @bp.route(
"/etudiant/nip/<int:nip>/formsemestre/<int:formsemestre_id>/bulletin", "/etudiant/nip/<string:nip>/formsemestre/<int:formsemestre_id>/bulletin",
methods=["GET"], methods=["GET"],
defaults={"version": "long"}, defaults={"version": "long"},
) )
@bp.route( @bp.route(
"/etudiant/ine/<int:ine>/formsemestre/<int:formsemestre_id>/bulletin", "/etudiant/ine/<string:ine>/formsemestre/<int:formsemestre_id>/bulletin",
methods=["GET"], methods=["GET"],
defaults={"version": "long"}, defaults={"version": "long"},
) )
@ -190,12 +190,12 @@ def etudiant_formsemestres(etudid: int = None, nip: int = None, ine: int = None)
defaults={"version": "short"}, defaults={"version": "short"},
) )
@bp.route( @bp.route(
"/etudiant/nip/<int:nip>/formsemestre/<int:formsemestre_id>/bulletin/short", "/etudiant/nip/<string:nip>/formsemestre/<int:formsemestre_id>/bulletin/short",
methods=["GET"], methods=["GET"],
defaults={"version": "short"}, defaults={"version": "short"},
) )
@bp.route( @bp.route(
"/etudiant/ine/<int:ine>/formsemestre/<int:formsemestre_id>/bulletin/short", "/etudiant/ine/<string:ine>/formsemestre/<int:formsemestre_id>/bulletin/short",
methods=["GET"], methods=["GET"],
defaults={"version": "short"}, defaults={"version": "short"},
) )
@ -408,10 +408,12 @@ def etudiant_bulletin_semestre(
methods=["GET"], methods=["GET"],
) )
@bp.route( @bp.route(
"/etudiant/nip/<int:nip>/formsemestre/<int:formsemestre_id>/groups", methods=["GET"] "/etudiant/nip/<string:nip>/formsemestre/<int:formsemestre_id>/groups",
methods=["GET"],
) )
@bp.route( @bp.route(
"/etudiant/ine/<int:ine>/formsemestre/<int:formsemestre_id>/groups", methods=["GET"] "/etudiant/ine/<string:ine>/formsemestre/<int:formsemestre_id>/groups",
methods=["GET"],
) )
@token_auth.login_required @token_auth.login_required
@token_permission_required(Permission.APIView) @token_permission_required(Permission.APIView)

View File

@ -413,8 +413,15 @@ def formsemestre_get_etud_groupnames(formsemestre_id, attr="group_name"):
return R return R
def etud_add_group_infos(etud, formsemestre_id, sep=" "): def etud_add_group_infos(etud, formsemestre_id, sep=" ", only_to_show=False):
"""Add informations on partitions and group memberships to etud (a dict with an etudid)""" """Add informations on partitions and group memberships to etud
(a dict with an etudid)
If only_to_show, restrict to partions such that show_in_lists is True.
etud['partitions'] = { partition_id : group + partition_name }
etud['groupes'] = "TDB, Gr2, TPB1"
etud['partitionsgroupes'] = "Groupes TD:TDB, Groupes TP:Gr2 (...)"
"""
etud[ etud[
"partitions" "partitions"
] = collections.OrderedDict() # partition_id : group + partition_name ] = collections.OrderedDict() # partition_id : group + partition_name
@ -423,11 +430,14 @@ def etud_add_group_infos(etud, formsemestre_id, sep=" "):
return etud return etud
infos = ndb.SimpleDictFetch( infos = ndb.SimpleDictFetch(
"""SELECT p.partition_name, g.*, g.id AS group_id """SELECT p.partition_name, p.show_in_lists, g.*, g.id AS group_id
FROM group_descr g, partition p, group_membership gm WHERE gm.etudid=%(etudid)s FROM group_descr g, partition p, group_membership gm WHERE gm.etudid=%(etudid)s
and gm.group_id = g.id and gm.group_id = g.id
and g.partition_id = p.id and g.partition_id = p.id
and p.formsemestre_id = %(formsemestre_id)s and p.formsemestre_id = %(formsemestre_id)s
"""
+ (" and (p.show_in_lists is True) " if only_to_show else "")
+ """
ORDER BY p.numero ORDER BY p.numero
""", """,
{"etudid": etud["etudid"], "formsemestre_id": formsemestre_id}, {"etudid": etud["etudid"], "formsemestre_id": formsemestre_id},

View File

@ -153,14 +153,14 @@ def ficheEtud(etudid=None):
try: # pour les bookmarks avec d'anciens ids... try: # pour les bookmarks avec d'anciens ids...
etudid = int(etudid) etudid = int(etudid)
except ValueError: except ValueError:
raise ScoValueError("id invalide !") raise ScoValueError("id invalide !") from ValueError
# la sidebar est differente s'il y a ou pas un etudid # la sidebar est differente s'il y a ou pas un etudid
# voir html_sidebar.sidebar() # voir html_sidebar.sidebar()
g.etudid = etudid g.etudid = etudid
args = make_etud_args(etudid=etudid) args = make_etud_args(etudid=etudid)
etuds = sco_etud.etudident_list(cnx, args) etuds = sco_etud.etudident_list(cnx, args)
if not etuds: if not etuds:
log("ficheEtud: etudid=%s request.args=%s" % (etudid, request.args)) log(f"ficheEtud: etudid={etudid!r} request.args={request.args!r}")
raise ScoValueError("Etudiant inexistant !") raise ScoValueError("Etudiant inexistant !")
etud = etuds[0] etud = etuds[0]
etudid = etud["etudid"] etudid = etud["etudid"]
@ -173,7 +173,7 @@ def ficheEtud(etudid=None):
if info["lieu_naissance"]: if info["lieu_naissance"]:
info["info_naissance"] += " à " + info["lieu_naissance"] info["info_naissance"] += " à " + info["lieu_naissance"]
if info["dept_naissance"]: if info["dept_naissance"]:
info["info_naissance"] += " (%s)" % info["dept_naissance"] info["info_naissance"] += f" ({info['dept_naissance']})"
info["etudfoto"] = sco_photos.etud_photo_html(etud) info["etudfoto"] = sco_photos.etud_photo_html(etud)
if ( if (
(not info["domicile"]) (not info["domicile"])
@ -205,7 +205,7 @@ def ficheEtud(etudid=None):
) )
else: else:
info["emaillink"] = "<em>(pas d'adresse e-mail)</em>" info["emaillink"] = "<em>(pas d'adresse e-mail)</em>"
# champs dependant des permissions # Champ dépendant des permissions:
if authuser.has_permission(Permission.ScoEtudChangeAdr): if authuser.has_permission(Permission.ScoEtudChangeAdr):
info["modifadresse"] = ( info["modifadresse"] = (
'<a class="stdlink" href="formChangeCoordonnees?etudid=%s">modifier adresse</a>' '<a class="stdlink" href="formChangeCoordonnees?etudid=%s">modifier adresse</a>'
@ -216,9 +216,10 @@ def ficheEtud(etudid=None):
# Groupes: # Groupes:
sco_groups.etud_add_group_infos( sco_groups.etud_add_group_infos(
info, info["cursem"]["formsemestre_id"] if info["cursem"] else None info,
info["cursem"]["formsemestre_id"] if info["cursem"] else None,
only_to_show=True,
) )
# Parcours de l'étudiant # Parcours de l'étudiant
if info["sems"]: if info["sems"]:
info["last_formsemestre_id"] = info["sems"][0]["formsemestre_id"] info["last_formsemestre_id"] = info["sems"][0]["formsemestre_id"]
@ -235,15 +236,28 @@ def ficheEtud(etudid=None):
) )
grlink = '<span class="fontred">%s</span>' % descr["situation"] grlink = '<span class="fontred">%s</span>' % descr["situation"]
else: else:
group = sco_groups.get_etud_main_group(etudid, sem["formsemestre_id"]) e = {"etudid": etudid}
if group["partition_name"]: sco_groups.etud_add_group_infos(
gr_name = group["group_name"] e,
else: sem["formsemestre_id"],
gr_name = "tous" only_to_show=True,
grlink = (
'<a class="discretelink" href="groups_view?group_ids=%s" title="Liste du groupe">groupe %s</a>'
% (group["group_id"], gr_name)
) )
grlinks = []
for partition in e["partitions"].values():
if partition["partition_name"]:
gr_name = partition["group_name"]
else:
gr_name = "tous"
grlinks.append(
f"""<a class="discretelink" href="{
url_for('scolar.groups_view',
scodoc_dept=g.scodoc_dept, group_ids=partition['group_id'])
}" title="Liste du groupe {gr_name}">{gr_name}</a>
"""
)
grlink = ", ".join(grlinks)
# infos ajoutées au semestre dans le parcours (groupe, menu) # infos ajoutées au semestre dans le parcours (groupe, menu)
menu = _menuScolarite(authuser, sem, etudid) menu = _menuScolarite(authuser, sem, etudid)
if menu: if menu:
@ -423,9 +437,11 @@ def ficheEtud(etudid=None):
# #
if info["groupes"].strip(): if info["groupes"].strip():
info["groupes_row"] = ( info[
'<tr><td class="fichetitre2">Groupe :</td><td>%(groupes)s</td></tr>' % info "groupes_row"
) ] = f"""<tr>
<td class="fichetitre2">Groupes :</td><td>{info['groupes']}</td>
</tr>"""
else: else:
info["groupes_row"] = "" info["groupes_row"] = ""
info["menus_etud"] = menus_etud(etudid) info["menus_etud"] = menus_etud(etudid)

View File

@ -84,12 +84,15 @@ def formsemestre_recapcomplet(
selected_etudid: etudid sélectionné (pour scroller au bon endroit) selected_etudid: etudid sélectionné (pour scroller au bon endroit)
""" """
formsemestre = FormSemestre.query.get_or_404(formsemestre_id) formsemestre = FormSemestre.query.get_or_404(formsemestre_id)
file_formats = {"csv", "json", "xls", "xlsx", "xlsall", "xml"}
supported_formats = file_formats | {"html"}
if tabformat not in supported_formats:
raise ScoValueError(f"Format non supporté: {tabformat}")
is_file = tabformat in file_formats
modejury = int(modejury) modejury = int(modejury)
xml_with_decisions = int(xml_with_decisions) xml_with_decisions = int(xml_with_decisions)
force_publishing = int(force_publishing) force_publishing = int(force_publishing)
is_file = tabformat in {"csv", "json", "xls", "xlsx", "xlsall", "xml"}
data = _do_formsemestre_recapcomplet( data = _do_formsemestre_recapcomplet(
formsemestre_id, formsemestre_id,
format=tabformat, format=tabformat,
@ -128,6 +131,7 @@ def formsemestre_recapcomplet(
for (format, label) in ( for (format, label) in (
("html", "Tableau"), ("html", "Tableau"),
("evals", "Avec toutes les évaluations"), ("evals", "Avec toutes les évaluations"),
("xlsx", "Excel non formatté"),
("xml", "Bulletins XML (obsolète)"), ("xml", "Bulletins XML (obsolète)"),
("json", "Bulletins JSON"), ("json", "Bulletins JSON"),
): ):

View File

@ -1,7 +1,7 @@
# -*- mode: python -*- # -*- mode: python -*-
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
SCOVERSION = "9.2.17" SCOVERSION = "9.2.18"
SCONAME = "ScoDoc" SCONAME = "ScoDoc"

View File

@ -20,15 +20,18 @@ Utilisation :
import requests import requests
from tests.api.setup_test_api import API_URL, CHECK_CERTIFICATE, api_headers from tests.api.setup_test_api import API_URL, CHECK_CERTIFICATE, api_headers
from tests.api.tools_test_api import verify_fields, DEPARTEMENT_FIELDS from tests.api.tools_test_api import (
verify_fields,
DEPARTEMENT_FIELDS,
verify_occurences_ids_etus,
)
def test_departements(api_headers): def test_departements(api_headers):
""" "
Routes: /departements_ids, /departement, /departement/<string:dept>/formsemestres_ids
""" """
# --- Liste des ids Routes: /departements_ids, /departement, /departement/<string:dept>/formsemestres_ids
"""
# --- departement_ids : liste des ids
r = requests.get( r = requests.get(
API_URL + "/departements_ids", API_URL + "/departements_ids",
headers=api_headers, headers=api_headers,
@ -40,8 +43,17 @@ def test_departements(api_headers):
assert len(departements_ids) > 0 assert len(departements_ids) > 0
assert all(isinstance(x, int) for x in departements_ids) assert all(isinstance(x, int) for x in departements_ids)
all_unique = True
for id in departements_ids:
if departements_ids.count(id) > 1:
all_unique = False
assert all_unique is True
dept_id = departements_ids[0] dept_id = departements_ids[0]
# --- Infos sur un département, accès par id
# --- departement
# Infos sur un département, accès par id
r = requests.get( r = requests.get(
f"{API_URL}/departement/{dept_id}", f"{API_URL}/departement/{dept_id}",
headers=api_headers, headers=api_headers,
@ -49,8 +61,7 @@ def test_departements(api_headers):
) )
assert r.status_code == 200 assert r.status_code == 200
dept_a = r.json() dept_a = r.json()
assert verify_fields(dept_a, DEPARTEMENT_FIELDS) is True # Infos sur un département, accès par acronyme4
# --- Infos sur un département, accès par acronyme4
r = requests.get( r = requests.get(
f"{API_URL}/departement/{dept_a['acronym']}", f"{API_URL}/departement/{dept_a['acronym']}",
headers=api_headers, headers=api_headers,
@ -58,20 +69,76 @@ def test_departements(api_headers):
) )
assert r.status_code == 200 assert r.status_code == 200
dept_b = r.json() dept_b = r.json()
assert dept_a == dept_b
# Liste des formsemestres assert dept_a == dept_b
assert verify_fields(dept_a, DEPARTEMENT_FIELDS) is True
assert isinstance(dept_a["id"], int)
assert isinstance(dept_a["acronym"], str)
assert dept_a["description"] is None or isinstance(dept_a["description"], str)
assert isinstance(dept_a["visible"], bool)
assert dept_a["date_creation"] is None or isinstance(dept_a["date_creation"], str)
# --- departements : Liste des départements
r = requests.get(
API_URL + "/departements",
headers=api_headers,
verify=CHECK_CERTIFICATE,
)
assert r.status_code == 200
# --- formsemestre_ids : listes des ids de formsemestres du département
r = requests.get( r = requests.get(
f"{API_URL}/departement/{dept_a['acronym']}/formsemestres_ids", f"{API_URL}/departement/{dept_a['acronym']}/formsemestres_ids",
headers=api_headers, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
assert r.status_code == 200 assert r.status_code == 200
dept_ids = r.json() dept_ids_a = r.json()
assert isinstance(dept_ids, list)
assert all(isinstance(x, int) for x in dept_ids) r = requests.get(
assert len(dept_ids) > 0 f"{API_URL}/departement/{dept_a['id']}/formsemestres_ids",
assert dept_id in dept_ids headers=api_headers,
verify=CHECK_CERTIFICATE,
)
assert r.status_code == 200
dept_ids_b = r.json()
assert dept_ids_a == dept_ids_b
assert isinstance(dept_ids_a, list)
assert all(isinstance(id, int) for id in dept_ids_a)
assert len(dept_ids_a) > 0
assert dept_id in dept_ids_a
# Les erreurs
id_inexistant = 50000
r = requests.get(
f"{API_URL}/departement/{id_inexistant}",
headers=api_headers,
verify=CHECK_CERTIFICATE,
)
assert r.status_code == 404
r = requests.get(
f"{API_URL}/departement/{id_inexistant}/formsemestres_ids",
headers=api_headers,
verify=CHECK_CERTIFICATE,
)
assert r.status_code == 404
acronym_inexistant = "AAAAAAAAAAAAAAAAAAA"
r = requests.get(
f"{API_URL}/departement/{acronym_inexistant}",
headers=api_headers,
verify=CHECK_CERTIFICATE,
)
assert r.status_code == 404
r = requests.get(
f"{API_URL}/departement/{acronym_inexistant}/formsemestres_ids",
headers=api_headers,
verify=CHECK_CERTIFICATE,
)
assert r.status_code == 404
def test_list_etudiants(api_headers): def test_list_etudiants(api_headers):
@ -83,33 +150,46 @@ def test_list_etudiants(api_headers):
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
assert r.status_code == 200 assert r.status_code == 200
etud = r.json()[0] etud_a = r.json()[0]
assert verify_fields(etud, fields) is True
assert isinstance(etud["id"], int)
# Vérification que chaque id, nip et ine sont uniques (EN CHANTIER) r = requests.get(
# all_uniques = True API_URL + "/departement/1/etudiants",
# d = dict() headers=api_headers,
# i = 0 verify=CHECK_CERTIFICATE,
# )
# for etu in r.json(): assert r.status_code == 200
# d[i] = [etu["id"], etu["nip"], etu["ine"]] etud_b = r.json()[0]
# i += 1
# assert etud_a == etud_b
# d[4][2] = 65 assert verify_fields(etud_a, fields) is True
# assert isinstance(etud_a["id"], int)
# for i in range(len(d)-1): assert etud_a["nip"] is None or isinstance(etud_a["nip"], str)
# if d[i][0] == d[i+1][0]: assert etud_a["ine"] is None or isinstance(etud_a["ine"], str)
# all_uniques = False assert etud_a["nom"] is None or isinstance(etud_a["nom"], str)
# else: assert etud_a["nom_usuel"] is None or isinstance(etud_a["nom_usuel"], str)
# if d[i][1] == d[i+1][1]: assert etud_a["prenom"] is None or isinstance(etud_a["prenom"], str)
# all_uniques = False assert isinstance(etud_a["civilite"], str)
# else: assert len(etud_a["civilite"]) == 1
# if d[i][2] == d[i+1][2]:
# all_uniques = False all_unique = verify_occurences_ids_etus(r.text)
# i += 1 assert all_unique is True
#
# assert all_uniques is True # Les erreurs
id_inexistant = 50000
r = requests.get(
f"{API_URL}/departement/{id_inexistant}/etudiants",
headers=api_headers,
verify=CHECK_CERTIFICATE,
)
assert r.status_code == 404
acronym_inexistant = "AAAAAAAAAAAAAAAAAAA"
r = requests.get(
f"{API_URL}/departement/{acronym_inexistant}/etudiants",
headers=api_headers,
verify=CHECK_CERTIFICATE,
)
assert r.status_code == 404
# liste_semestres_courant # liste_semestres_courant
@ -151,6 +231,7 @@ def test_semestres_courant(api_headers):
assert r.status_code == 200 assert r.status_code == 200
dept = r.json() dept = r.json()
assert dept["id"] == dept_id assert dept["id"] == dept_id
# Accès via acronyme # Accès via acronyme
r = requests.get( r = requests.get(
f"{API_URL}/departement/{dept['acronym']}/formsemestres_courants", f"{API_URL}/departement/{dept['acronym']}/formsemestres_courants",

View File

@ -20,7 +20,7 @@ Utilisation :
import requests import requests
from tests.api.setup_test_api import API_URL, CHECK_CERTIFICATE, api_headers from tests.api.setup_test_api import API_URL, CHECK_CERTIFICATE, api_headers
from tests.api.tools_test_api import verify_fields from tests.api.tools_test_api import verify_fields, verify_occurences_ids_etus
from tests.api.tools_test_api import ETUD_FIELDS, FSEM_FIELDS from tests.api.tools_test_api import ETUD_FIELDS, FSEM_FIELDS
@ -47,13 +47,7 @@ def test_etudiants_courant(api_headers):
assert isinstance(etud["prenom"], str) assert isinstance(etud["prenom"], str)
assert isinstance(etud["civilite"], str) assert isinstance(etud["civilite"], str)
all_unique = True all_unique = verify_occurences_ids_etus(r.text)
list_ids = [etu["id"] for etu in etudiants]
for i in range(len(etudiants) - 1):
if etudiants.count(list_ids[i]) > 1:
all_unique = False
assert all_unique is True assert all_unique is True
########## Version long ################ ########## Version long ################
@ -72,7 +66,7 @@ def test_etudiants_courant(api_headers):
def test_etudiant(api_headers): def test_etudiant(api_headers):
""" """
Route: Routes : /etudiant/etudid/<int:etudid>, /etudiant/nip/<string:nip>, /etudiant/ine/<string:ine>
""" """
######### Test etudid ######### ######### Test etudid #########

View File

@ -1,5 +1,6 @@
"""Utilitaires pour les tests de l'API """Utilitaires pour les tests de l'API
""" """
import json
def verify_fields(json_response: dict, expected_fields: set) -> bool: def verify_fields(json_response: dict, expected_fields: set) -> bool:
@ -14,6 +15,25 @@ def verify_fields(json_response: dict, expected_fields: set) -> bool:
return all(field in json_response for field in expected_fields) return all(field in json_response for field in expected_fields)
def verify_occurences_ids_etus(json_response):
list_etu = json.loads(json_response)
list_ids = [etu["id"] for etu in list_etu]
list_nip = [etu["nip"] for etu in list_etu]
list_ine = [etu["ine"] for etu in list_etu]
for id in list_ids:
if list_ids.count(id) > 1:
return False
for nip in list_nip:
if list_nip.count(nip) > 1:
return False
for ine in list_ine:
if list_ine.count(ine) > 1:
return False
return True
DEPARTEMENT_FIELDS = [ DEPARTEMENT_FIELDS = [
"id", "id",
"acronym", "acronym",

View File

@ -28,7 +28,7 @@ import sys
from app.auth.models import Role, User from app.auth.models import Role, User
from app import models from app import models
from app.models import Departement, Formation, FormSemestre from app.models import Departement, Formation, FormSemestre, Identite
from app import db from app import db
from app.scodoc import ( from app.scodoc import (
sco_cache, sco_cache,
@ -95,15 +95,18 @@ def create_users(dept: Departement) -> tuple:
return user, other return user, other
def create_fake_etud(dept: Departement) -> models.Identite: def create_fake_etud(dept: Departement) -> Identite:
"""Créé un faux étudiant et l'insère dans la base""" """Créé un faux étudiant et l'insère dans la base."""
civilite = random.choice(("M", "F", "X")) civilite = random.choice(("M", "F", "X"))
nom, prenom = nomprenom(civilite) nom, prenom = nomprenom(civilite)
etud = models.Identite(civilite=civilite, nom=nom, prenom=prenom, dept_id=dept.id) etud: Identite = Identite(
civilite=civilite, nom=nom, prenom=prenom, dept_id=dept.id
)
db.session.add(etud) db.session.add(etud)
db.session.commit() db.session.commit()
etud.code_nip = etud.id # créé un étudiant sur deux avec un NIP et INE alphanumérique
etud.code_ine = etud.id etud.code_nip = f"{etud.id}" if (etud.id % 2) else f"NIP{etud.id}"
etud.code_ine = f"INE{etud.id}" if (etud.id % 2) else f"{etud.id}"
db.session.add(etud) db.session.add(etud)
db.session.commit() db.session.commit()
adresse = models.Adresse( adresse = models.Adresse(