forked from ScoDoc/ScoDoc
API: modif formsemestre/etudiant. TESTS unitaires OK sauf logos.
This commit is contained in:
parent
f7a2c1e8e7
commit
c065abd0bb
@ -19,15 +19,13 @@ from app.scodoc import sco_abs
|
|||||||
from app.scodoc.sco_groups import get_group_members
|
from app.scodoc.sco_groups import get_group_members
|
||||||
from app.scodoc.sco_permissions import Permission
|
from app.scodoc.sco_permissions import Permission
|
||||||
|
|
||||||
|
# TODO XXX revoir routes web API et calcul des droits
|
||||||
@bp.route("/absences/etudid/<int:etudid>", methods=["GET"])
|
@bp.route("/absences/etudid/<int:etudid>", methods=["GET"])
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
def absences(etudid: int = None):
|
def absences(etudid: int = None):
|
||||||
"""
|
"""
|
||||||
Retourne la liste des absences d'un étudiant donné
|
Liste des absences de cet étudiant
|
||||||
|
|
||||||
etudid : l'etudid d'un étudiant
|
|
||||||
|
|
||||||
Exemple de résultat:
|
Exemple de résultat:
|
||||||
[
|
[
|
||||||
|
@ -31,16 +31,16 @@ from app.scodoc.sco_bulletins import do_formsemestre_bulletinetud
|
|||||||
from app.scodoc.sco_permissions import Permission
|
from app.scodoc.sco_permissions import Permission
|
||||||
|
|
||||||
# Un exemple:
|
# Un exemple:
|
||||||
@bp.route("/api_function/<int:arg>")
|
# @bp.route("/api_function/<int:arg>")
|
||||||
@api_web_bp.route("/api_function/<int:arg>")
|
# @api_web_bp.route("/api_function/<int:arg>")
|
||||||
@login_required
|
# @login_required
|
||||||
@scodoc
|
# @scodoc
|
||||||
@permission_required(Permission.ScoView)
|
# @permission_required(Permission.ScoView)
|
||||||
def api_function(arg: int):
|
# def api_function(arg: int):
|
||||||
"""Une fonction quelconque de l'API"""
|
# """Une fonction quelconque de l'API"""
|
||||||
return jsonify(
|
# return jsonify(
|
||||||
{"current_user": current_user.to_dict(), "arg": arg, "dept": g.scodoc_dept}
|
# {"current_user": current_user.to_dict(), "arg": arg, "dept": g.scodoc_dept}
|
||||||
)
|
# )
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/etudiants/courants", defaults={"long": False})
|
@bp.route("/etudiants/courants", defaults={"long": False})
|
||||||
|
@ -251,6 +251,10 @@ def formsemestre_programme(formsemestre_id: int):
|
|||||||
|
|
||||||
@bp.route(
|
@bp.route(
|
||||||
"/formsemestre/<int:formsemestre_id>/etudiants",
|
"/formsemestre/<int:formsemestre_id>/etudiants",
|
||||||
|
defaults={"etat": None},
|
||||||
|
)
|
||||||
|
@bp.route(
|
||||||
|
"/formsemestre/<int:formsemestre_id>/etudiants/actifs",
|
||||||
defaults={"etat": scu.INSCRIT},
|
defaults={"etat": scu.INSCRIT},
|
||||||
)
|
)
|
||||||
@bp.route(
|
@bp.route(
|
||||||
@ -263,6 +267,10 @@ def formsemestre_programme(formsemestre_id: int):
|
|||||||
)
|
)
|
||||||
@api_web_bp.route(
|
@api_web_bp.route(
|
||||||
"/formsemestre/<int:formsemestre_id>/etudiants",
|
"/formsemestre/<int:formsemestre_id>/etudiants",
|
||||||
|
defaults={"etat": None},
|
||||||
|
)
|
||||||
|
@api_web_bp.route(
|
||||||
|
"/formsemestre/<int:formsemestre_id>/etudiants/actifs",
|
||||||
defaults={"etat": scu.INSCRIT},
|
defaults={"etat": scu.INSCRIT},
|
||||||
)
|
)
|
||||||
@api_web_bp.route(
|
@api_web_bp.route(
|
||||||
@ -276,18 +284,17 @@ def formsemestre_programme(formsemestre_id: int):
|
|||||||
@login_required
|
@login_required
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
def formsemestre_etudiants(formsemestre_id: int, etat: str):
|
def formsemestre_etudiants(formsemestre_id: int, etat: str = None):
|
||||||
"""
|
"""Etudiants d'un formsemestre."""
|
||||||
Retourne la liste des étudiants d'un formsemestre
|
|
||||||
|
|
||||||
formsemestre_id : l'id d'un formsemestre
|
|
||||||
"""
|
|
||||||
query = FormSemestre.query.filter_by(id=formsemestre_id)
|
query = FormSemestre.query.filter_by(id=formsemestre_id)
|
||||||
if g.scodoc_dept:
|
if g.scodoc_dept:
|
||||||
query = query.filter_by(dept_id=g.scodoc_dept_id)
|
query = query.filter_by(dept_id=g.scodoc_dept_id)
|
||||||
formsemestre: FormSemestre = query.first_or_404(formsemestre_id)
|
formsemestre: FormSemestre = query.first_or_404(formsemestre_id)
|
||||||
|
if etat is None:
|
||||||
|
inscriptions = formsemestre.inscriptions
|
||||||
|
else:
|
||||||
inscriptions = [ins for ins in formsemestre.inscriptions if ins.etat == etat]
|
inscriptions = [ins for ins in formsemestre.inscriptions if ins.etat == etat]
|
||||||
|
|
||||||
etuds = [ins.etud.to_dict_short() for ins in inscriptions]
|
etuds = [ins.etud.to_dict_short() for ins in inscriptions]
|
||||||
# Ajout des groupes de chaque étudiants
|
# Ajout des groupes de chaque étudiants
|
||||||
# XXX A REVOIR: trop inefficace !
|
# XXX A REVOIR: trop inefficace !
|
||||||
|
@ -53,8 +53,8 @@ def users_info_query():
|
|||||||
"""Utilisateurs, filtrés par dept, active ou début nom
|
"""Utilisateurs, filtrés par dept, active ou début nom
|
||||||
/users/query?departement=dept_acronym&active=1&starts_with=<string:nom>
|
/users/query?departement=dept_acronym&active=1&starts_with=<string:nom>
|
||||||
|
|
||||||
Si accès via API web, seuls les utilisateurs "accessibles" (selon les
|
Seuls les utilisateurs "accessibles" (selon les permissions) sont retournés.
|
||||||
permissions) sont retournés: le département de l'URL est ignoré, seules
|
Si accès via API web, le département de l'URL est ignoré, seules
|
||||||
les permissions de l'utilisateur sont prises en compte.
|
les permissions de l'utilisateur sont prises en compte.
|
||||||
"""
|
"""
|
||||||
query = User.query
|
query = User.query
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
"""Test Logos
|
"""Test formsemestre
|
||||||
|
|
||||||
Utilisation :
|
Utilisation :
|
||||||
créer les variables d'environnement: (indiquer les valeurs
|
créer les variables d'environnement: (indiquer les valeurs
|
||||||
@ -481,32 +481,17 @@ def test_bulletins(api_headers):
|
|||||||
assert isinstance(bulletin_semestre["rang"]["total"], int)
|
assert isinstance(bulletin_semestre["rang"]["total"], int)
|
||||||
|
|
||||||
|
|
||||||
# # jury
|
|
||||||
# def test_jury():
|
|
||||||
# r = requests.get(
|
|
||||||
# API_URL + "/formsemestre/1/jury",
|
|
||||||
# headers=api_headers,
|
|
||||||
# verify=CHECK_CERTIFICATE,
|
|
||||||
# )
|
|
||||||
# assert r.status_code == 200
|
|
||||||
|
|
||||||
|
|
||||||
def test_formsemestre_etudiants(api_headers):
|
def test_formsemestre_etudiants(api_headers):
|
||||||
"""
|
"""
|
||||||
Route: /formsemestre/<int:formsemestre_id>/etudiants,
|
Route: /formsemestre/<int:formsemestre_id>/etudiants
|
||||||
/formsemestre/<int:formsemestre_id>/etudiants/demissionnaires,
|
/formsemestre/<int:formsemestre_id>/etudiants/actifs
|
||||||
|
/formsemestre/<int:formsemestre_id>/etudiants/demissionnaires
|
||||||
/formsemestre/<int:formsemestre_id>/etudiants/defaillants
|
/formsemestre/<int:formsemestre_id>/etudiants/defaillants
|
||||||
"""
|
"""
|
||||||
formsemestre_id = 1
|
formsemestre_id = 1
|
||||||
r = requests.get(
|
etuds = GET(f"/formsemestre/{formsemestre_id}/etudiants", headers=api_headers)
|
||||||
f"{API_URL}/formsemestre/{formsemestre_id}/etudiants",
|
assert isinstance(etuds, list)
|
||||||
headers=api_headers,
|
for etud in etuds:
|
||||||
verify=CHECK_CERTIFICATE,
|
|
||||||
)
|
|
||||||
assert r.status_code == 200
|
|
||||||
formsemestre_etus = r.json()
|
|
||||||
assert isinstance(formsemestre_etus, list)
|
|
||||||
for etud in formsemestre_etus:
|
|
||||||
assert verify_fields(etud, FORMSEMESTRE_ETUD_FIELDS) is True
|
assert verify_fields(etud, FORMSEMESTRE_ETUD_FIELDS) is True
|
||||||
assert isinstance(etud["id"], int)
|
assert isinstance(etud["id"], int)
|
||||||
assert isinstance(etud["code_nip"], str)
|
assert isinstance(etud["code_nip"], str)
|
||||||
@ -530,77 +515,26 @@ def test_formsemestre_etudiants(api_headers):
|
|||||||
assert isinstance(group["group_id"], int)
|
assert isinstance(group["group_id"], int)
|
||||||
assert group["group_name"] is None or isinstance(group["group_name"], int)
|
assert group["group_name"] is None or isinstance(group["group_name"], int)
|
||||||
|
|
||||||
### demissionnaires ###
|
### actifs
|
||||||
r_demissionnaires = requests.get(
|
etuds_actifs = GET(
|
||||||
f"{API_URL}/formsemestre/{formsemestre_id}/etudiants/demissionnaires",
|
f"/formsemestre/{formsemestre_id}/etudiants/actifs", headers=api_headers
|
||||||
|
)
|
||||||
|
assert isinstance(etuds_actifs, list)
|
||||||
|
|
||||||
|
### démissionnaires
|
||||||
|
etuds_dem = GET(
|
||||||
|
f"/formsemestre/{formsemestre_id}/etudiants/demissionnaires",
|
||||||
headers=api_headers,
|
headers=api_headers,
|
||||||
verify=CHECK_CERTIFICATE,
|
|
||||||
)
|
)
|
||||||
assert r_demissionnaires.status_code == 200
|
assert isinstance(etuds_dem, list)
|
||||||
formsemestre_etus = r_demissionnaires.json()
|
|
||||||
assert isinstance(formsemestre_etus, list)
|
|
||||||
|
|
||||||
for etud in formsemestre_etus:
|
### défaillants
|
||||||
assert verify_fields(etud, FORMSEMESTRE_ETUD_FIELDS) is True
|
etuds_def = GET(
|
||||||
assert isinstance(etud["id"], int)
|
f"/formsemestre/{formsemestre_id}/etudiants/defaillants", headers=api_headers
|
||||||
assert isinstance(etud["code_nip"], str)
|
|
||||||
assert isinstance(etud["code_ine"], str)
|
|
||||||
assert isinstance(etud["nom"], str)
|
|
||||||
assert etud["nom_usuel"] is None or isinstance(etud["nom_usuel"], str)
|
|
||||||
assert isinstance(etud["prenom"], str)
|
|
||||||
assert isinstance(etud["civilite"], str)
|
|
||||||
assert isinstance(etud["groups"], list)
|
|
||||||
etu_groups = etud["groups"]
|
|
||||||
for group in etu_groups:
|
|
||||||
assert isinstance(group["partition_id"], int)
|
|
||||||
assert isinstance(group["id"], int)
|
|
||||||
assert isinstance(group["formsemestre_id"], int)
|
|
||||||
assert group["partition_name"] is None or isinstance(
|
|
||||||
group["partition_name"], str
|
|
||||||
)
|
)
|
||||||
assert (group["numero"] is None) or isinstance(group["numero"], int)
|
assert isinstance(etuds_def, list)
|
||||||
assert isinstance(group["bul_show_rank"], bool)
|
|
||||||
assert isinstance(group["show_in_lists"], bool)
|
|
||||||
assert isinstance(group["group_id"], int)
|
|
||||||
assert group["group_name"] is None or isinstance(group["group_name"], int)
|
|
||||||
|
|
||||||
### defaillants ###
|
assert len(etuds) == (len(etuds_actifs) + len(etuds_dem) + len(etuds_def))
|
||||||
r_defaillants = requests.get(
|
|
||||||
f"{API_URL}/formsemestre/{formsemestre_id}/etudiants/defaillants",
|
|
||||||
headers=api_headers,
|
|
||||||
verify=CHECK_CERTIFICATE,
|
|
||||||
)
|
|
||||||
assert r_defaillants.status_code == 200
|
|
||||||
|
|
||||||
formsemestre_etus = r_defaillants.json()
|
|
||||||
assert isinstance(formsemestre_etus, list)
|
|
||||||
for etud in formsemestre_etus:
|
|
||||||
assert verify_fields(etud, FORMSEMESTRE_ETUD_FIELDS) is True
|
|
||||||
assert isinstance(etud["id"], int)
|
|
||||||
assert isinstance(etud["code_nip"], str)
|
|
||||||
assert isinstance(etud["code_ine"], str)
|
|
||||||
assert isinstance(etud["nom"], str)
|
|
||||||
assert etud["nom_usuel"] is None or isinstance(etud["nom_usuel"], str)
|
|
||||||
assert isinstance(etud["prenom"], str)
|
|
||||||
assert isinstance(etud["civilite"], str)
|
|
||||||
assert isinstance(etud["groups"], list)
|
|
||||||
etu_groups = etud["groups"]
|
|
||||||
for group in etu_groups:
|
|
||||||
assert isinstance(group["partition_id"], int)
|
|
||||||
assert isinstance(group["id"], int)
|
|
||||||
assert isinstance(group["formsemestre_id"], int)
|
|
||||||
assert group["partition_name"] is None or isinstance(
|
|
||||||
group["partition_name"], str
|
|
||||||
)
|
|
||||||
assert (group["numero"] is None) or isinstance(group["numero"], int)
|
|
||||||
assert isinstance(group["bul_show_rank"], bool)
|
|
||||||
assert isinstance(group["show_in_lists"], bool)
|
|
||||||
assert isinstance(group["group_id"], int)
|
|
||||||
assert group["group_name"] is None or isinstance(group["group_name"], int)
|
|
||||||
|
|
||||||
assert r.json() != r_demissionnaires.json()
|
|
||||||
assert r.json() != r_defaillants.json()
|
|
||||||
assert r_demissionnaires.json() != r_defaillants.json()
|
|
||||||
|
|
||||||
### ERROR ###
|
### ERROR ###
|
||||||
id_formsemestre_inexistant = 265165689619851621685
|
id_formsemestre_inexistant = 265165689619851621685
|
||||||
|
@ -17,37 +17,24 @@ Utilisation :
|
|||||||
pytest tests/api/test_api_jury.py
|
pytest tests/api/test_api_jury.py
|
||||||
"""
|
"""
|
||||||
|
|
||||||
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,
|
||||||
def test_jury_preparation(api_headers):
|
GET,
|
||||||
"""
|
POST_JSON,
|
||||||
Test 'jury_preparation'
|
api_headers,
|
||||||
|
)
|
||||||
Route :
|
|
||||||
- /jury/formsemestre/<int:formsemestre_id>/preparation_jury
|
|
||||||
"""
|
|
||||||
r = requests.get(
|
|
||||||
API_URL
|
|
||||||
+ "/ScoDoc/api/jury/formsemestre/<int:formsemestre_id>/preparation_jury",
|
|
||||||
headers=api_headers,
|
|
||||||
verify=CHECK_CERTIFICATE,
|
|
||||||
)
|
|
||||||
assert r.status_code == 200
|
|
||||||
|
|
||||||
|
|
||||||
def test_jury_decisions(api_headers):
|
def test_jury_decisions(api_headers):
|
||||||
"""
|
"""
|
||||||
Test 'jury_decisions'
|
|
||||||
|
|
||||||
Route :
|
Route :
|
||||||
- /jury/formsemestre/<int:formsemestre_id>/decisions_jury
|
- /formsemestre/<int:formsemestre_id>/decisions_jury
|
||||||
"""
|
"""
|
||||||
r = requests.get(
|
formsemestre_id = 1
|
||||||
API_URL + "/jury/formsemestre/<int:formsemestre_id>/decisions_jury",
|
etudiants = GET(f"/formsemestre/{formsemestre_id}/etudiants", headers=api_headers)
|
||||||
headers=api_headers,
|
decisions_jury = GET(
|
||||||
verify=CHECK_CERTIFICATE,
|
f"/formsemestre/{formsemestre_id}/decisions_jury", headers=api_headers
|
||||||
)
|
)
|
||||||
assert r.status_code == 200
|
assert len(etudiants) == len(decisions_jury)
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
import flask
|
|
||||||
from tests.api.setup_test_api import API_URL, SCODOC_URL, CHECK_CERTIFICATE, api_headers
|
from tests.api.setup_test_api import API_URL, SCODOC_URL, CHECK_CERTIFICATE, api_headers
|
||||||
from tests.api.tools_test_api import verify_fields
|
from tests.api.tools_test_api import verify_fields
|
||||||
|
|
||||||
@ -35,16 +34,18 @@ def test_permissions(api_headers):
|
|||||||
for r in app.url_map.iter_rules()
|
for r in app.url_map.iter_rules()
|
||||||
if str(r).startswith("/ScoDoc/api")
|
if str(r).startswith("/ScoDoc/api")
|
||||||
and not "logo" in str(r) # ignore logos
|
and not "logo" in str(r) # ignore logos
|
||||||
|
and not "absence" in str(r) # ignore absences
|
||||||
and "GET" in r.methods
|
and "GET" in r.methods
|
||||||
]
|
]
|
||||||
assert len(api_rules) > 0
|
assert len(api_rules) > 0
|
||||||
args = {
|
args = {
|
||||||
"etudid": 1,
|
"acronym": "TAPI",
|
||||||
"dept": "TAPI",
|
|
||||||
"dept_ident": "TAPI",
|
|
||||||
"dept_id": 1,
|
"dept_id": 1,
|
||||||
|
"dept_ident": "TAPI",
|
||||||
|
"dept": "TAPI",
|
||||||
"etape_apo": "???",
|
"etape_apo": "???",
|
||||||
"etat": "I",
|
"etat": "I",
|
||||||
|
"etudid": 1,
|
||||||
"evaluation_id": 1,
|
"evaluation_id": 1,
|
||||||
"formation_id": 1,
|
"formation_id": 1,
|
||||||
"formsemestre_id": 1,
|
"formsemestre_id": 1,
|
||||||
@ -54,6 +55,8 @@ def test_permissions(api_headers):
|
|||||||
"moduleimpl_id": 1,
|
"moduleimpl_id": 1,
|
||||||
"nip": 1,
|
"nip": 1,
|
||||||
"partition_id": 1,
|
"partition_id": 1,
|
||||||
|
"role_name": "Ens",
|
||||||
|
"uid": 1,
|
||||||
}
|
}
|
||||||
for rule in api_rules:
|
for rule in api_rules:
|
||||||
path = rule.build(args)[1]
|
path = rule.build(args)[1]
|
||||||
@ -95,4 +98,4 @@ def test_permissions(api_headers):
|
|||||||
headers=headers,
|
headers=headers,
|
||||||
verify=CHECK_CERTIFICATE,
|
verify=CHECK_CERTIFICATE,
|
||||||
)
|
)
|
||||||
assert r.status_code == 403
|
assert r.status_code == 401
|
||||||
|
@ -84,6 +84,8 @@ def create_users(depts: list[Departement]) -> tuple:
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
perm_sco_view = Permission.get_by_name("ScoView")
|
perm_sco_view = Permission.get_by_name("ScoView")
|
||||||
role_lecteur.add_permission(perm_sco_view)
|
role_lecteur.add_permission(perm_sco_view)
|
||||||
|
perm_sco_users = Permission.get_by_name("ScoUsersView")
|
||||||
|
role_lecteur.add_permission(perm_sco_users)
|
||||||
# Edition billets
|
# Edition billets
|
||||||
perm_billets = Permission.get_by_name("ScoAbsAddBillet")
|
perm_billets = Permission.get_by_name("ScoAbsAddBillet")
|
||||||
role_lecteur.add_permission(perm_billets)
|
role_lecteur.add_permission(perm_billets)
|
||||||
@ -92,8 +94,13 @@ def create_users(depts: list[Departement]) -> tuple:
|
|||||||
db.session.add(role_lecteur)
|
db.session.add(role_lecteur)
|
||||||
|
|
||||||
# Un role pour juste voir les utilisateurs
|
# Un role pour juste voir les utilisateurs
|
||||||
role_users_viewer = Role(name="UsersViewer", permissions=Permission.ScoUsersView)
|
role_users_viewer = Role(
|
||||||
|
name="UsersViewer", permissions=Permission.ScoUsersView | Permission.ScoView
|
||||||
|
)
|
||||||
db.session.add(role_users_viewer)
|
db.session.add(role_users_viewer)
|
||||||
|
# Role View sur l'API, pour demander un jeton
|
||||||
|
role_view = Role(name="Viewer", permissions=Permission.ScoView)
|
||||||
|
db.session.add(role_view)
|
||||||
|
|
||||||
# Un utilisateur "test" (passwd test) pouvant lire l'API
|
# Un utilisateur "test" (passwd test) pouvant lire l'API
|
||||||
user_test = User(user_name="test", nom="Doe", prenom="John", dept=dept.acronym)
|
user_test = User(user_name="test", nom="Doe", prenom="John", dept=dept.acronym)
|
||||||
@ -132,7 +139,7 @@ def create_users(depts: list[Departement]) -> tuple:
|
|||||||
for i, u in enumerate(users):
|
for i, u in enumerate(users):
|
||||||
for dept in depts[: i + 1]:
|
for dept in depts[: i + 1]:
|
||||||
u.add_role(role_users_viewer, dept.acronym)
|
u.add_role(role_users_viewer, dept.acronym)
|
||||||
u.add_role(role_lecteur, None) # necessaire pour avoir le jeton
|
u.add_role(role_view, None) # necessaire pour avoir le jeton
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return user_test, other
|
return user_test, other
|
||||||
|
Loading…
Reference in New Issue
Block a user