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_permissions import Permission
|
||||
|
||||
|
||||
# TODO XXX revoir routes web API et calcul des droits
|
||||
@bp.route("/absences/etudid/<int:etudid>", methods=["GET"])
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
def absences(etudid: int = None):
|
||||
"""
|
||||
Retourne la liste des absences d'un étudiant donné
|
||||
|
||||
etudid : l'etudid d'un étudiant
|
||||
Liste des absences de cet étudiant
|
||||
|
||||
Exemple de résultat:
|
||||
[
|
||||
|
@ -31,16 +31,16 @@ from app.scodoc.sco_bulletins import do_formsemestre_bulletinetud
|
||||
from app.scodoc.sco_permissions import Permission
|
||||
|
||||
# Un exemple:
|
||||
@bp.route("/api_function/<int:arg>")
|
||||
@api_web_bp.route("/api_function/<int:arg>")
|
||||
@login_required
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
def api_function(arg: int):
|
||||
"""Une fonction quelconque de l'API"""
|
||||
return jsonify(
|
||||
{"current_user": current_user.to_dict(), "arg": arg, "dept": g.scodoc_dept}
|
||||
)
|
||||
# @bp.route("/api_function/<int:arg>")
|
||||
# @api_web_bp.route("/api_function/<int:arg>")
|
||||
# @login_required
|
||||
# @scodoc
|
||||
# @permission_required(Permission.ScoView)
|
||||
# def api_function(arg: int):
|
||||
# """Une fonction quelconque de l'API"""
|
||||
# return jsonify(
|
||||
# {"current_user": current_user.to_dict(), "arg": arg, "dept": g.scodoc_dept}
|
||||
# )
|
||||
|
||||
|
||||
@bp.route("/etudiants/courants", defaults={"long": False})
|
||||
|
@ -251,6 +251,10 @@ def formsemestre_programme(formsemestre_id: int):
|
||||
|
||||
@bp.route(
|
||||
"/formsemestre/<int:formsemestre_id>/etudiants",
|
||||
defaults={"etat": None},
|
||||
)
|
||||
@bp.route(
|
||||
"/formsemestre/<int:formsemestre_id>/etudiants/actifs",
|
||||
defaults={"etat": scu.INSCRIT},
|
||||
)
|
||||
@bp.route(
|
||||
@ -263,6 +267,10 @@ def formsemestre_programme(formsemestre_id: int):
|
||||
)
|
||||
@api_web_bp.route(
|
||||
"/formsemestre/<int:formsemestre_id>/etudiants",
|
||||
defaults={"etat": None},
|
||||
)
|
||||
@api_web_bp.route(
|
||||
"/formsemestre/<int:formsemestre_id>/etudiants/actifs",
|
||||
defaults={"etat": scu.INSCRIT},
|
||||
)
|
||||
@api_web_bp.route(
|
||||
@ -276,18 +284,17 @@ def formsemestre_programme(formsemestre_id: int):
|
||||
@login_required
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
def formsemestre_etudiants(formsemestre_id: int, etat: str):
|
||||
"""
|
||||
Retourne la liste des étudiants d'un formsemestre
|
||||
|
||||
formsemestre_id : l'id d'un formsemestre
|
||||
"""
|
||||
def formsemestre_etudiants(formsemestre_id: int, etat: str = None):
|
||||
"""Etudiants d'un formsemestre."""
|
||||
query = FormSemestre.query.filter_by(id=formsemestre_id)
|
||||
if g.scodoc_dept:
|
||||
query = query.filter_by(dept_id=g.scodoc_dept_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]
|
||||
# Ajout des groupes de chaque étudiants
|
||||
# XXX A REVOIR: trop inefficace !
|
||||
|
@ -53,8 +53,8 @@ def users_info_query():
|
||||
"""Utilisateurs, filtrés par dept, active ou début nom
|
||||
/users/query?departement=dept_acronym&active=1&starts_with=<string:nom>
|
||||
|
||||
Si accès via API web, seuls les utilisateurs "accessibles" (selon les
|
||||
permissions) sont retournés: le département de l'URL est ignoré, seules
|
||||
Seuls les utilisateurs "accessibles" (selon les permissions) sont retournés.
|
||||
Si accès via API web, le département de l'URL est ignoré, seules
|
||||
les permissions de l'utilisateur sont prises en compte.
|
||||
"""
|
||||
query = User.query
|
||||
|
@ -1,6 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""Test Logos
|
||||
"""Test formsemestre
|
||||
|
||||
Utilisation :
|
||||
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)
|
||||
|
||||
|
||||
# # 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):
|
||||
"""
|
||||
Route: /formsemestre/<int:formsemestre_id>/etudiants,
|
||||
/formsemestre/<int:formsemestre_id>/etudiants/demissionnaires,
|
||||
Route: /formsemestre/<int:formsemestre_id>/etudiants
|
||||
/formsemestre/<int:formsemestre_id>/etudiants/actifs
|
||||
/formsemestre/<int:formsemestre_id>/etudiants/demissionnaires
|
||||
/formsemestre/<int:formsemestre_id>/etudiants/defaillants
|
||||
"""
|
||||
formsemestre_id = 1
|
||||
r = requests.get(
|
||||
f"{API_URL}/formsemestre/{formsemestre_id}/etudiants",
|
||||
headers=api_headers,
|
||||
verify=CHECK_CERTIFICATE,
|
||||
)
|
||||
assert r.status_code == 200
|
||||
formsemestre_etus = r.json()
|
||||
assert isinstance(formsemestre_etus, list)
|
||||
for etud in formsemestre_etus:
|
||||
etuds = GET(f"/formsemestre/{formsemestre_id}/etudiants", headers=api_headers)
|
||||
assert isinstance(etuds, list)
|
||||
for etud in etuds:
|
||||
assert verify_fields(etud, FORMSEMESTRE_ETUD_FIELDS) is True
|
||||
assert isinstance(etud["id"], int)
|
||||
assert isinstance(etud["code_nip"], str)
|
||||
@ -530,77 +515,26 @@ def test_formsemestre_etudiants(api_headers):
|
||||
assert isinstance(group["group_id"], int)
|
||||
assert group["group_name"] is None or isinstance(group["group_name"], int)
|
||||
|
||||
### demissionnaires ###
|
||||
r_demissionnaires = requests.get(
|
||||
f"{API_URL}/formsemestre/{formsemestre_id}/etudiants/demissionnaires",
|
||||
headers=api_headers,
|
||||
verify=CHECK_CERTIFICATE,
|
||||
### actifs
|
||||
etuds_actifs = GET(
|
||||
f"/formsemestre/{formsemestre_id}/etudiants/actifs", headers=api_headers
|
||||
)
|
||||
assert r_demissionnaires.status_code == 200
|
||||
formsemestre_etus = r_demissionnaires.json()
|
||||
assert isinstance(formsemestre_etus, list)
|
||||
assert isinstance(etuds_actifs, 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)
|
||||
|
||||
### defaillants ###
|
||||
r_defaillants = requests.get(
|
||||
f"{API_URL}/formsemestre/{formsemestre_id}/etudiants/defaillants",
|
||||
### démissionnaires
|
||||
etuds_dem = GET(
|
||||
f"/formsemestre/{formsemestre_id}/etudiants/demissionnaires",
|
||||
headers=api_headers,
|
||||
verify=CHECK_CERTIFICATE,
|
||||
)
|
||||
assert r_defaillants.status_code == 200
|
||||
assert isinstance(etuds_dem, list)
|
||||
|
||||
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)
|
||||
### défaillants
|
||||
etuds_def = GET(
|
||||
f"/formsemestre/{formsemestre_id}/etudiants/defaillants", headers=api_headers
|
||||
)
|
||||
assert isinstance(etuds_def, list)
|
||||
|
||||
assert r.json() != r_demissionnaires.json()
|
||||
assert r.json() != r_defaillants.json()
|
||||
assert r_demissionnaires.json() != r_defaillants.json()
|
||||
assert len(etuds) == (len(etuds_actifs) + len(etuds_dem) + len(etuds_def))
|
||||
|
||||
### ERROR ###
|
||||
id_formsemestre_inexistant = 265165689619851621685
|
||||
|
@ -17,37 +17,24 @@ Utilisation :
|
||||
pytest tests/api/test_api_jury.py
|
||||
"""
|
||||
|
||||
import requests
|
||||
|
||||
from tests.api.setup_test_api import API_URL, CHECK_CERTIFICATE, api_headers
|
||||
|
||||
|
||||
def test_jury_preparation(api_headers):
|
||||
"""
|
||||
Test 'jury_preparation'
|
||||
|
||||
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
|
||||
from tests.api.setup_test_api import (
|
||||
API_URL,
|
||||
CHECK_CERTIFICATE,
|
||||
GET,
|
||||
POST_JSON,
|
||||
api_headers,
|
||||
)
|
||||
|
||||
|
||||
def test_jury_decisions(api_headers):
|
||||
"""
|
||||
Test 'jury_decisions'
|
||||
|
||||
Route :
|
||||
- /jury/formsemestre/<int:formsemestre_id>/decisions_jury
|
||||
- /formsemestre/<int:formsemestre_id>/decisions_jury
|
||||
"""
|
||||
r = requests.get(
|
||||
API_URL + "/jury/formsemestre/<int:formsemestre_id>/decisions_jury",
|
||||
headers=api_headers,
|
||||
verify=CHECK_CERTIFICATE,
|
||||
formsemestre_id = 1
|
||||
etudiants = GET(f"/formsemestre/{formsemestre_id}/etudiants", headers=api_headers)
|
||||
decisions_jury = GET(
|
||||
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 flask
|
||||
from tests.api.setup_test_api import API_URL, SCODOC_URL, CHECK_CERTIFICATE, api_headers
|
||||
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()
|
||||
if str(r).startswith("/ScoDoc/api")
|
||||
and not "logo" in str(r) # ignore logos
|
||||
and not "absence" in str(r) # ignore absences
|
||||
and "GET" in r.methods
|
||||
]
|
||||
assert len(api_rules) > 0
|
||||
args = {
|
||||
"etudid": 1,
|
||||
"dept": "TAPI",
|
||||
"dept_ident": "TAPI",
|
||||
"acronym": "TAPI",
|
||||
"dept_id": 1,
|
||||
"dept_ident": "TAPI",
|
||||
"dept": "TAPI",
|
||||
"etape_apo": "???",
|
||||
"etat": "I",
|
||||
"etudid": 1,
|
||||
"evaluation_id": 1,
|
||||
"formation_id": 1,
|
||||
"formsemestre_id": 1,
|
||||
@ -54,6 +55,8 @@ def test_permissions(api_headers):
|
||||
"moduleimpl_id": 1,
|
||||
"nip": 1,
|
||||
"partition_id": 1,
|
||||
"role_name": "Ens",
|
||||
"uid": 1,
|
||||
}
|
||||
for rule in api_rules:
|
||||
path = rule.build(args)[1]
|
||||
@ -95,4 +98,4 @@ def test_permissions(api_headers):
|
||||
headers=headers,
|
||||
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)
|
||||
perm_sco_view = Permission.get_by_name("ScoView")
|
||||
role_lecteur.add_permission(perm_sco_view)
|
||||
perm_sco_users = Permission.get_by_name("ScoUsersView")
|
||||
role_lecteur.add_permission(perm_sco_users)
|
||||
# Edition billets
|
||||
perm_billets = Permission.get_by_name("ScoAbsAddBillet")
|
||||
role_lecteur.add_permission(perm_billets)
|
||||
@ -92,8 +94,13 @@ def create_users(depts: list[Departement]) -> tuple:
|
||||
db.session.add(role_lecteur)
|
||||
|
||||
# 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)
|
||||
# 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
|
||||
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 dept in depts[: i + 1]:
|
||||
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()
|
||||
return user_test, other
|
||||
|
Loading…
Reference in New Issue
Block a user