API: diverses corrections, tests unitaires (sauf absences et logos).

This commit is contained in:
Emmanuel Viennet 2022-07-29 16:19:40 +02:00
parent 3342c3222a
commit 6306e8ca26
20 changed files with 300 additions and 456 deletions

View File

@ -53,10 +53,7 @@ def absences(etudid: int = None):
"""
etud = Identite.query.get(etudid)
if etud is None:
return error_response(
404,
message="id de l'étudiant (etudid, nip, ine) inconnu",
)
return error_response(404, message="etudiant inexistant")
# Absences de l'étudiant
ndb.open_db_connection()
abs_list = sco_abs.list_abs_date(etud.id)
@ -100,10 +97,7 @@ def absences_just(etudid: int = None):
"""
etud = Identite.query.get(etudid)
if etud is None:
return error_response(
404,
message="id de l'étudiant (etudid, nip, ine) inconnu",
)
return error_response(404, message="etudiant inexistant")
# Absences justifiées de l'étudiant
abs_just = [

View File

@ -81,8 +81,8 @@ def dept_etudiants(acronym: str):
[
{
"civilite": "M",
"ine": "7899X61616",
"nip": "F6777H88",
"code_ine": "7899X61616",
"code_nip": "F6777H88",
"date_naissance": null,
"email": "toto@toto.fr",
"emailperso": null,

View File

@ -11,14 +11,20 @@
from flask import g, jsonify
from flask_login import current_user
from flask_login import login_required
from sqlalchemy import or_
from sqlalchemy import desc, or_
import app
from app.api import api_bp as bp, api_web_bp
from app.api.errors import error_response
from app.api import tools
from app.decorators import scodoc, permission_required
from app.models import Departement, FormSemestreInscription, FormSemestre, Identite
from app.models import (
Admission,
Departement,
FormSemestreInscription,
FormSemestre,
Identite,
)
from app.scodoc import sco_bulletins
from app.scodoc import sco_groups
from app.scodoc.sco_bulletins import do_formsemestre_bulletinetud
@ -55,8 +61,8 @@ def etudiants_courants(long=False):
[
{
"id": 1234,
"nip": "12345678",
"ine": null,
"code_nip": "12345678",
"code_ine": null,
"nom": "JOHN",
"nom_usuel": None,
"prenom": "DEUF",
@ -259,28 +265,22 @@ def etudiant_formsemestres(etudid: int = None, nip: int = None, ine: int = None)
]
"""
if etudid is not None:
query = FormSemestre.query.filter(
FormSemestreInscription.etudid == etudid,
FormSemestreInscription.formsemestre_id == FormSemestre.id,
)
q_etud = Identite.query.filter_by(id=etudid)
elif nip is not None:
query = FormSemestre.query.filter(
Identite.code_nip == nip,
FormSemestreInscription.etudid == Identite.id,
FormSemestreInscription.formsemestre_id == FormSemestre.id,
)
q_etud = Identite.query.filter_by(code_nip=nip)
elif ine is not None:
query = FormSemestre.query.filter(
Identite.code_ine == ine,
FormSemestreInscription.etudid == Identite.id,
FormSemestreInscription.formsemestre_id == FormSemestre.id,
)
q_etud = Identite.query.filter_by(code_ine=ine)
else:
return error_response(
404,
message="parametre manquant",
)
return error_response(404, message="parametre manquant")
if g.scodoc_dept is not None:
q_etud = q_etud.filter_by(dept_id=g.scodoc_dept_id)
etud = q_etud.join(Admission).order_by(desc(Admission.annee)).first()
if etud is None:
return error_response(404, message="etudiant inexistant")
query = FormSemestre.query.filter(
FormSemestreInscription.etudid == etud.id,
FormSemestreInscription.formsemestre_id == FormSemestre.id,
)
if g.scodoc_dept is not None:
query = query.filter_by(dept_id=g.scodoc_dept_id)
@ -422,23 +422,17 @@ def etudiant_bulletin_semestre(
elif ine is not None:
query = Identite.query.filter_by(code_ine=ine, dept_id=dept.id)
else:
return error_response(
404,
message="parametre manquant",
)
return error_response(404, message="parametre manquant")
etud = query.first()
if etud is None:
return error_response(
404,
message="id de l'étudiant (etudid, nip, ine) inconnu",
)
return error_response(404, message="etudiant inexistant")
app.set_sco_dept(dept.acronym)
if pdf:
pdf_response, _ = do_formsemestre_bulletinetud(
formsemestre, etudid, version=version, format="pdf"
formsemestre, etud.id, version=version, format="pdf"
)
return pdf_response

View File

@ -92,7 +92,7 @@ def formation_by_id(formation_id: int):
defaults={"export_ids": False},
)
@bp.route(
"/formation/<int:formation_id>/export/with_ids",
"/formation/<int:formation_id>/export_with_ids",
defaults={"export_ids": True},
)
@api_web_bp.route(
@ -100,7 +100,7 @@ def formation_by_id(formation_id: int):
defaults={"export_ids": False},
)
@api_web_bp.route(
"/formation/<int:formation_id>/export/with_ids",
"/formation/<int:formation_id>/export_with_ids",
defaults={"export_ids": True},
)
@login_required

View File

@ -23,6 +23,7 @@ from app.models import (
FormSemestre,
FormSemestreEtape,
ModuleImpl,
NotesNotes,
)
from app.scodoc.sco_bulletins import get_formsemestre_bulletin_etud_json
from app.scodoc import sco_groups
@ -101,11 +102,7 @@ def formsemestres_query():
dept_id = request.args.get("dept_id")
formsemestres = FormSemestre.query
if g.scodoc_dept:
query = query.filter_by(dept_id=g.scodoc_dept_id)
if etape_apo is not None:
formsemestres = formsemestres.join(FormSemestreEtape).filter(
FormSemestreEtape.etape_apo == etape_apo
)
formsemestres = formsemestres.filter_by(dept_id=g.scodoc_dept_id)
if annee_scolaire is not None:
try:
annee_scolaire_int = int(annee_scolaire)
@ -124,6 +121,10 @@ def formsemestres_query():
except ValueError:
return error_response(404, "invalid dept_id: not int")
formsemestres = formsemestres.filter_by(dept_id=dept_id)
if etape_apo is not None:
formsemestres = formsemestres.join(FormSemestreEtape).filter(
FormSemestreEtape.etape_apo == etape_apo
)
return jsonify([formsemestre.to_dict_api() for formsemestre in formsemestres])
@ -371,7 +372,7 @@ def etat_evals(formsemestre_id: int):
# Récupération de toutes les notes de l'évaluation
# eval["notes"] = modimpl_results.get_eval_notes_dict(evaluation_id)
notes = models.NotesNotes.query.filter_by(evaluation_id=evaluation.id).all()
notes = NotesNotes.query.filter_by(evaluation_id=evaluation.id).all()
date_debut = None
date_fin = None

View File

@ -149,8 +149,9 @@ class Identite(db.Model):
"""Les champs essentiels"""
return {
"id": self.id,
"nip": self.code_nip,
"ine": self.code_ine,
"code_nip": self.code_nip,
"code_ine": self.code_ine,
"dept_id": self.dept_id,
"nom": self.nom,
"nom_usuel": self.nom_usuel,
"prenom": self.prenom,

View File

@ -830,7 +830,7 @@ class JuryPE(object):
else ""
),
"bac": etudinfo["bac"],
"nip": etudinfo["code_nip"], # pour la photo
"code_nip": etudinfo["code_nip"], # pour la photo
"entree": self.get_dateEntree(etudid),
"promo": self.diplome,
}

View File

@ -764,7 +764,7 @@ JURY_SYNTHESE_POUR_DEBUG = {
},
},
"nbSemestres": 4,
"nip": "21414563",
"code_nip": "21414563",
"prenom": "Baptiste",
"age": "21",
"lycee": "PONCET",

View File

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

40
tests/api/README.md Normal file
View File

@ -0,0 +1,40 @@
# Tests unitaires de l'API ScoDoc
Démarche générale:
1. On génère une base SQL de test: voir
`tools/fakedatabase/create_test_api_database.py`
1. modifier /opt/scodoc/.env pour indiquer
```
FLASK_ENV=test_api
FLASK_DEBUG=1
```
2. En tant qu'utilisateur scodoc, lancer:
```
tools/create_database.sh --drop SCODOC_TEST_API
flask db upgrade
flask sco-db-init --erase
flask init-test-database
```
2. On lance le serveur ScoDoc sur cette base
```
flask run --host 0.0.0.0
```
3. On lance les tests unitaires API
```
pytest tests/api/test_api_departements.py
```
Rappel: pour interroger l'API, il fait avoir un utilisateur avec (au moins) la permission
ScoView dans tous les départements. Pour en créer un:
```
flask user-create lecteur_api LecteurAPI @all
flask user-password lecteur_api
flask edit-role LecteurAPI -a ScoView
flask user-role lecteur_api -a LecteurAPI
```

View File

@ -24,7 +24,7 @@ from tests.api.tools_test_api import (
verify_fields,
DEPARTEMENT_FIELDS,
FORMSEMESTRE_FIELDS,
verify_occurences_ids_etus,
verify_occurences_ids_etuds,
)
@ -56,7 +56,7 @@ def test_departements(api_headers):
# --- departement
# Infos sur un département, accès par id
r = requests.get(
f"{API_URL}/departement/{dept_id}",
f"{API_URL}/departement/id/{dept_id}",
headers=api_headers,
verify=CHECK_CERTIFICATE,
)
@ -97,7 +97,7 @@ def test_departements(api_headers):
dept_ids_a = r.json()
r = requests.get(
f"{API_URL}/departement/{dept_a['id']}/formsemestres_ids",
f"{API_URL}/departement/id/{dept_a['id']}/formsemestres_ids",
headers=api_headers,
verify=CHECK_CERTIFICATE,
)
@ -143,7 +143,7 @@ def test_departements(api_headers):
def test_list_etudiants(api_headers):
fields = {"id", "nip", "ine", "nom", "nom_usuel", "prenom", "civilite"}
fields = {"id", "code_nip", "code_ine", "nom", "nom_usuel", "prenom", "civilite"}
r = requests.get(
API_URL + "/departement/TAPI/etudiants",
@ -154,7 +154,7 @@ def test_list_etudiants(api_headers):
etud_a = r.json()[0]
r = requests.get(
API_URL + "/departement/1/etudiants",
API_URL + "/departement/id/1/etudiants",
headers=api_headers,
verify=CHECK_CERTIFICATE,
)
@ -164,15 +164,15 @@ def test_list_etudiants(api_headers):
assert etud_a == etud_b
assert verify_fields(etud_a, fields) is True
assert isinstance(etud_a["id"], int)
assert etud_a["nip"] is None or isinstance(etud_a["nip"], str)
assert etud_a["ine"] is None or isinstance(etud_a["ine"], str)
assert etud_a["code_nip"] is None or isinstance(etud_a["code_nip"], str)
assert etud_a["code_ine"] is None or isinstance(etud_a["code_ine"], str)
assert etud_a["nom"] is None or isinstance(etud_a["nom"], str)
assert etud_a["nom_usuel"] is None or isinstance(etud_a["nom_usuel"], str)
assert etud_a["prenom"] is None or isinstance(etud_a["prenom"], str)
assert isinstance(etud_a["civilite"], str)
assert len(etud_a["civilite"]) == 1
all_unique = verify_occurences_ids_etus(r.text)
all_unique = verify_occurences_ids_etuds(r.text)
assert all_unique is True
# Les erreurs
@ -197,7 +197,7 @@ def test_list_etudiants(api_headers):
def test_semestres_courant(api_headers):
dept_id = 1
r = requests.get(
f"{API_URL}/departement/{dept_id}",
f"{API_URL}/departement/id/{dept_id}",
headers=api_headers,
verify=CHECK_CERTIFICATE,
)
@ -216,7 +216,7 @@ def test_semestres_courant(api_headers):
# accès via dept_id
r = requests.get(
f"{API_URL}/departement/{dept['id']}/formsemestres_courants",
f"{API_URL}/departement/id/{dept['id']}/formsemestres_courants",
headers=api_headers,
verify=CHECK_CERTIFICATE,
)

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
"""Test Logos
"""Test accès étudiants
Utilisation :
créer les variables d'environnement: (indiquer les valeurs
@ -22,7 +22,7 @@ import requests
from tests.api.setup_test_api import API_URL, CHECK_CERTIFICATE, api_headers
from tests.api.tools_test_api import (
verify_fields,
verify_occurences_ids_etus,
verify_occurences_ids_etuds,
BULLETIN_FIELDS,
BULLETIN_ETUDIANT_FIELDS,
BULLETIN_FORMATION_FIELDS,
@ -55,15 +55,15 @@ from tests.api.tools_test_api import ETUD_FIELDS, FSEM_FIELDS
ETUDID = 1
NIP = "1"
INE = "1"
NIP = "NIP2"
INE = "INE1"
def test_etudiants_courant(api_headers):
"""
Route: /etudiants/courant
"""
fields = {"id", "nip", "nom", "prenom", "civilite"}
fields = {"id", "code_nip", "nom", "prenom", "civilite"}
r = requests.get(
API_URL + "/etudiants/courants",
@ -77,12 +77,12 @@ def test_etudiants_courant(api_headers):
etud = etudiants[-1]
assert verify_fields(etud, fields) is True
assert isinstance(etud["id"], int)
assert isinstance(etud["nip"], str)
assert isinstance(etud["code_nip"], str)
assert isinstance(etud["nom"], str)
assert isinstance(etud["prenom"], str)
assert isinstance(etud["civilite"], str)
all_unique = verify_occurences_ids_etus(r.text)
all_unique = verify_occurences_ids_etuds(r.text)
assert all_unique is True
########## Version long ################
@ -263,7 +263,7 @@ def test_etudiant_formsemestres(api_headers):
assert isinstance(formsemestre["date_debut_iso"], str)
assert isinstance(formsemestre["date_fin_iso"], str)
assert isinstance(formsemestre["responsables"], list)
assert isinstance(formsemestre["titre_formation"], str)
assert isinstance(formsemestre["formation"]["titre"], str)
assert verify_fields(formsemestre, FSEM_FIELDS) is True
@ -611,7 +611,7 @@ def test_etudiant_bulletin_semestre(api_headers):
assert (
verify_fields(bulletin_semestre["ECTS"], BULLETIN_SEMESTRE_ECTS_FIELDS) is True
)
assert isinstance(bulletin_semestre["ECTS"]["acquis"], int)
assert isinstance(bulletin_semestre["ECTS"]["acquis"], float)
assert isinstance(bulletin_semestre["ECTS"]["total"], float)
assert (
@ -777,29 +777,3 @@ def test_etudiant_groups(api_headers):
group = groups[0]
fields_ok = verify_fields(group, fields)
assert fields_ok is True
######### Test code nip #########
r = requests.get(
API_URL + "/etudiant/nip/" + str(NIP) + "/formsemestre/1/groups",
headers=api_headers,
verify=CHECK_CERTIFICATE,
)
assert r.status_code == 200
groups = r.json()
assert len(groups) == 1 # dans un seul groupe
group = groups[0]
fields_ok = verify_fields(group, fields)
assert fields_ok is True
######### Test code ine #########
r = requests.get(
API_URL + "/etudiant/ine/" + str(INE) + "/formsemestre/1/groups",
headers=api_headers,
verify=CHECK_CERTIFICATE,
)
assert r.status_code == 200
groups = r.json()
assert len(groups) == 1 # dans un seul groupe
group = groups[0]
fields_ok = verify_fields(group, fields)
assert fields_ok is True

View File

@ -70,16 +70,18 @@ def test_evaluations(api_headers):
assert eval["moduleimpl_id"] == moduleimpl_id
def test_evaluation_notes(api_headers): # XXX TODO changer la boucle pour parcourir le dict sans les indices
def test_evaluation_notes(
api_headers,
): # XXX TODO changer la boucle pour parcourir le dict sans les indices
"""
Test 'evaluation_notes'
Route :
- /evaluation/eval_notes/<int:evaluation_id>
- /evaluation/<int:evaluation_id>/notes
"""
eval_id = 1
r = requests.get(
f"{API_URL}/evaluation/eval_notes/{eval_id}",
f"{API_URL}/evaluation/{eval_id}/notes",
headers=api_headers,
verify=CHECK_CERTIFICATE,
)

View File

@ -104,10 +104,10 @@ def test_formations_by_id(api_headers):
def test_formation_export(api_headers):
"""
Route: /formation/formation_export/<int:formation_id>
Route: /formation/<int:formation_id>/export
"""
r = requests.get(
API_URL + "/formation/formation_export/1",
API_URL + "/formation/1/export",
headers=api_headers,
verify=CHECK_CERTIFICATE,
)
@ -185,7 +185,7 @@ def test_formation_export(api_headers):
# ERROR
id_formation_inexistant = 1516476846861656351
r_error = requests.get(
f"{API_URL}/formation/formation_export/{id_formation_inexistant}",
f"{API_URL}/formation/export/{id_formation_inexistant}",
headers=api_headers,
verify=CHECK_CERTIFICATE,
)
@ -198,7 +198,7 @@ def test_moduleimpl(api_headers):
"""
moduleimpl_id = 1
r = requests.get(
f"{API_URL}/formation/moduleimpl/{moduleimpl_id}",
f"{API_URL}/moduleimpl/{moduleimpl_id}",
headers=api_headers,
verify=CHECK_CERTIFICATE,
)
@ -240,7 +240,7 @@ def test_moduleimpl(api_headers):
assert moduleimpl_id == moduleimpl["moduleimpl_id"]
r1 = requests.get(
f"{API_URL}/formation/moduleimpl/{moduleimpl['moduleimpl_id']}",
f"{API_URL}/moduleimpl/{moduleimpl['moduleimpl_id']}",
headers=api_headers,
verify=CHECK_CERTIFICATE,
)

View File

@ -18,7 +18,6 @@ Utilisation :
"""
import requests
from app.api.formsemestres import formsemestre
from tests.api.setup_test_api import API_URL, CHECK_CERTIFICATE, api_headers
@ -27,7 +26,7 @@ from tests.api.tools_test_api import (
MODIMPL_FIELDS,
EVAL_FIELDS,
SAISIE_NOTES_FIELDS,
FORMSEMESTRE_ETUS_FIELDS,
FORMSEMESTRE_ETUD_FIELDS,
FSEM_FIELDS,
FSEM_FIELDS,
UE_FIELDS,
@ -100,7 +99,6 @@ def test_formsemestre(api_headers):
formsemestre["scodoc7_id"], int
)
assert isinstance(formsemestre["semestre_id"], int)
assert isinstance(formsemestre["titre_formation"], str)
assert isinstance(formsemestre["titre_num"], str)
assert isinstance(formsemestre["titre"], str)
@ -116,11 +114,11 @@ def test_formsemestre(api_headers):
def test_formsemestre_apo(api_headers):
"""
Route: /formsemestre/apo/<string:etape_apo>
Route: formsemestres/query?etape_apo=<string:etape_apo>
"""
etape_apo = "A1"
r = requests.get(
f"{API_URL}/formsemestre/apo/{etape_apo}",
f"{API_URL}/formsemestres/query?etape_apo={etape_apo}",
headers=api_headers,
verify=CHECK_CERTIFICATE,
)
@ -160,7 +158,6 @@ def test_formsemestre_apo(api_headers):
formsemestre["scodoc7_id"], int
)
assert isinstance(formsemestre["semestre_id"], int)
assert isinstance(formsemestre["titre_formation"], str)
assert isinstance(formsemestre["titre_num"], str)
assert isinstance(formsemestre["titre"], str)
@ -458,7 +455,7 @@ def test_bulletins(api_headers):
verify_fields(bulletin_semestre["ECTS"], BULLETIN_SEMESTRE_ECTS_FIELDS)
is True
)
assert isinstance(bulletin_semestre["ECTS"]["acquis"], int)
assert isinstance(bulletin_semestre["ECTS"]["acquis"], float)
assert isinstance(bulletin_semestre["ECTS"]["total"], float)
assert (
@ -503,17 +500,17 @@ def test_formsemestre_etudiants(api_headers):
assert r.status_code == 200
formsemestre_etus = r.json()
assert isinstance(formsemestre_etus, list)
for etu in formsemestre_etus:
assert verify_fields(etu, FORMSEMESTRE_ETUS_FIELDS) is True
assert isinstance(etu["id"], int)
assert isinstance(etu["nip"], str)
assert isinstance(etu["ine"], str)
assert isinstance(etu["nom"], str)
assert etu["nom_usuel"] is None or isinstance(etu["nom_usuel"], str)
assert isinstance(etu["prenom"], str)
assert isinstance(etu["civilite"], str)
assert isinstance(etu["groups"], list)
etu_groups = etu["groups"]
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)
@ -521,7 +518,7 @@ def test_formsemestre_etudiants(api_headers):
assert group["partition_name"] is None or isinstance(
group["partition_name"], str
)
assert isinstance(group["numero"], int)
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)
@ -537,17 +534,17 @@ def test_formsemestre_etudiants(api_headers):
formsemestre_etus = r_demissionnaires.json()
assert isinstance(formsemestre_etus, list)
for etu in formsemestre_etus:
assert verify_fields(etu, FORMSEMESTRE_ETUS_FIELDS) is True
assert isinstance(etu["id"], int)
assert isinstance(etu["nip"], str)
assert isinstance(etu["ine"], str)
assert isinstance(etu["nom"], str)
assert etu["nom_usuel"] is None or isinstance(etu["nom_usuel"], str)
assert isinstance(etu["prenom"], str)
assert isinstance(etu["civilite"], str)
assert isinstance(etu["groups"], list)
etu_groups = etu["groups"]
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)
@ -555,7 +552,7 @@ def test_formsemestre_etudiants(api_headers):
assert group["partition_name"] is None or isinstance(
group["partition_name"], str
)
assert isinstance(group["numero"], int)
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)
@ -571,17 +568,17 @@ def test_formsemestre_etudiants(api_headers):
formsemestre_etus = r_defaillants.json()
assert isinstance(formsemestre_etus, list)
for etu in formsemestre_etus:
assert verify_fields(etu, FORMSEMESTRE_ETUS_FIELDS) is True
assert isinstance(etu["id"], int)
assert isinstance(etu["nip"], str)
assert isinstance(etu["ine"], str)
assert isinstance(etu["nom"], str)
assert etu["nom_usuel"] is None or isinstance(etu["nom_usuel"], str)
assert isinstance(etu["prenom"], str)
assert isinstance(etu["civilite"], str)
assert isinstance(etu["groups"], list)
etu_groups = etu["groups"]
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)
@ -589,7 +586,7 @@ def test_formsemestre_etudiants(api_headers):
assert group["partition_name"] is None or isinstance(
group["partition_name"], str
)
assert isinstance(group["numero"], int)
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)
@ -670,99 +667,65 @@ def test_etat_evals(
etat_evals = r.json()
assert len(etat_evals) == 3
assert len(etat_evals) == 21
for ue in etat_evals.values():
for module in ue:
assert isinstance(module["id"], int)
assert isinstance(module["titre"], str)
assert isinstance(module["evaluations"], list)
for etat_modimpl in etat_evals:
assert isinstance(etat_modimpl["id"], int)
assert isinstance(etat_modimpl["evaluations"], list)
for eval in module["evaluations"]:
assert verify_fields(eval, EVAL_FIELDS)
assert isinstance(eval["id"], int)
assert eval["description"] is None or isinstance(
eval["description"], str
for evaluation in etat_modimpl["evaluations"]:
assert verify_fields(evaluation, EVAL_FIELDS)
assert isinstance(evaluation["id"], int)
assert evaluation["description"] is None or isinstance(
evaluation["description"], str
)
assert evaluation["jour"] is None or isinstance(evaluation["jour"], str)
assert isinstance(evaluation["heure_fin"], str)
assert isinstance(evaluation["coefficient"], float)
assert isinstance(evaluation["etat"], dict)
assert isinstance(evaluation["nb_inscrits"], int)
assert isinstance(evaluation["nb_notes_manquantes"], int)
assert isinstance(evaluation["nb_notes_abs"], int)
assert isinstance(evaluation["nb_notes_att"], int)
assert isinstance(evaluation["nb_notes_exc"], int)
assert isinstance(evaluation["saisie_notes"], dict)
list_eval_id = [e["id"] for e in etat_modimpl["evaluations"]]
all_unique = True
for id in list_eval_id:
if list_eval_id.count(id) > 1:
all_unique = False
assert all_unique is True
saisie_notes = evaluation["saisie_notes"]
assert verify_fields(saisie_notes, SAISIE_NOTES_FIELDS)
assert evaluation["saisie_notes"]["datetime_debut"] is None or isinstance(
evaluation["saisie_notes"]["datetime_debut"], str
)
assert evaluation["saisie_notes"]["datetime_debut"] is None or isinstance(
evaluation["saisie_notes"]["datetime_fin"], str
)
assert evaluation["saisie_notes"]["datetime_debut"] is None or isinstance(
evaluation["saisie_notes"]["datetime_mediane"], str
)
if (
evaluation["saisie_notes"]["datetime_fin"] is not None
and evaluation["saisie_notes"]["datetime_mediane"] is not None
and evaluation["saisie_notes"]["datetime_debut"] is not None
):
assert (
evaluation["saisie_notes"]["datetime_fin"]
> evaluation["saisie_notes"]["datetime_mediane"]
)
assert eval["datetime_epreuve"] is None or isinstance(
eval["datetime_epreuve"], str
assert (
evaluation["saisie_notes"]["datetime_fin"]
> evaluation["saisie_notes"]["datetime_debut"]
)
assert isinstance(eval["heure_fin"], str)
assert isinstance(eval["coefficient"], float)
assert isinstance(eval["comptee"], str)
assert isinstance(eval["inscrits"], int)
assert isinstance(eval["manquantes"], int)
assert isinstance(eval["ABS"], int)
assert isinstance(eval["ATT"], int)
assert isinstance(eval["EXC"], int)
assert isinstance(eval["saisie_notes"], dict)
list_eval_id = [e["id"] for e in module["evaluations"]]
all_unique = True
for id in list_eval_id:
if list_eval_id.count(id) > 1:
all_unique = False
assert all_unique is True
saisie_notes = eval["saisie_notes"]
assert verify_fields(saisie_notes, SAISIE_NOTES_FIELDS)
assert eval["saisie_notes"]["datetime_debut"] is None or isinstance(
eval["saisie_notes"]["datetime_debut"], str
assert (
evaluation["saisie_notes"]["datetime_mediane"]
> evaluation["saisie_notes"]["datetime_debut"]
)
assert eval["saisie_notes"]["datetime_debut"] is None or isinstance(
eval["saisie_notes"]["datetime_fin"], str
)
assert eval["saisie_notes"]["datetime_debut"] is None or isinstance(
eval["saisie_notes"]["datetime_mediane"], str
)
if (
eval["saisie_notes"]["datetime_fin"] is not None
and eval["saisie_notes"]["datetime_mediane"] is not None
and eval["saisie_notes"]["datetime_debut"] is not None
):
assert (
eval["saisie_notes"]["datetime_fin"]
> eval["saisie_notes"]["datetime_mediane"]
)
assert (
eval["saisie_notes"]["datetime_fin"]
> eval["saisie_notes"]["datetime_debut"]
)
assert (
eval["saisie_notes"]["datetime_mediane"]
> eval["saisie_notes"]["datetime_debut"]
)
list_id_ue1 = []
list_titre_ue1 = []
list_id_ue2 = []
list_titre_ue2 = []
list_id_ue3 = []
list_titre_ue3 = []
i = 0
for ue in etat_evals.values():
i += 1
for module in ue:
if i == 1:
list_id_ue1.append(module["id"])
list_titre_ue1.append(module["id"])
elif i == 2:
list_id_ue2.append(module["id"])
list_titre_ue2.append(module["id"])
elif i == 3:
list_id_ue3.append(module["id"])
list_titre_ue3.append(module["id"])
assert list_id_ue1 != list_id_ue2
assert list_id_ue1 != list_titre_ue3
assert list_id_ue2 != list_titre_ue3
assert list_titre_ue1 != list_titre_ue2
assert list_titre_ue1 != list_titre_ue3
assert list_titre_ue2 != list_titre_ue3
##### ERROR #####
fake_eval_id = 153165161656849846516511321651651

View File

@ -28,7 +28,7 @@ from tests.unit.config_test_logos import (
def test_super_access(create_super_token):
"""
Route:
Route: /logos
"""
dept1, dept2, dept3, token = create_super_token
headers = {"Authorization": f"Bearer {token}"}

View File

@ -23,7 +23,7 @@ from tests.api.setup_test_api import API_URL, CHECK_CERTIFICATE, api_headers
from tests.api.tools_test_api import (
verify_fields,
PARTITIONS_FIELDS,
PARTITIONS_GROUPS_ETU_FIELDS,
PARTITION_GROUPS_ETUD_FIELDS,
)
@ -32,24 +32,21 @@ def test_partition(api_headers):
Test 'partition'
Route :
- /partitions/<int:formsemestre_id>
- /partition/<int:partition_id>
"""
partition_id = 1
r = requests.get(
f"{API_URL}/partitions/{partition_id}",
f"{API_URL}/partition/{partition_id}",
headers=api_headers,
verify=CHECK_CERTIFICATE,
)
assert r.status_code == 200
partitions = r.json()
assert len(partitions) == 1
assert isinstance(partitions, list)
partition = partitions[0]
partition = r.json()
assert isinstance(partition, dict)
assert verify_fields(partition, PARTITIONS_FIELDS) is True
assert partition_id == partition["partition_id"]
assert partition_id == partition["id"]
assert isinstance(partition["partition_id"], int)
assert isinstance(partition["id"], int)
assert isinstance(partition["id"], int)
assert isinstance(partition["formsemestre_id"], int)
assert partition["partition_name"] is None or isinstance(
@ -65,61 +62,32 @@ def test_etud_in_group(api_headers):
Test 'etud_in_group'
Routes :
- /partition/group/<int:group_id>
- /partition/group/<int:group_id>/etat/<string:etat>
- /group/<int:group_id>/etudiants
- /group/<int:group_id>/etudiants/query?etat=<string:etat>
"""
group_id = 1
r = requests.get(
f"{API_URL}/partition/group/{group_id}",
f"{API_URL}/group/{group_id}/etudiants",
headers=api_headers,
verify=CHECK_CERTIFICATE,
)
assert r.status_code == 200
assert isinstance(r.json(), list)
for etu in r.json():
assert verify_fields(etu, PARTITIONS_GROUPS_ETU_FIELDS)
assert isinstance(etu["etudid"], int)
assert isinstance(etu["id"], int)
assert isinstance(etu["dept_id"], int)
assert isinstance(etu["nom"], str)
assert isinstance(etu["prenom"], str)
assert isinstance(etu["nom_usuel"], str)
assert isinstance(etu["civilite"], str)
assert etu["date_naissance"] is None or isinstance(etu["date_naissance"], str)
assert etu["lieu_naissance"] is None or isinstance(etu["lieu_naissance"], str)
assert etu["dept_naissance"] is None or isinstance(etu["dept_naissance"], str)
assert etu["nationalite"] is None or isinstance(etu["nationalite"], str)
assert etu["statut"] is None or isinstance(etu["statut"], str)
assert etu["boursier"] is None or isinstance(etu["boursier"], bool)
assert etu["photo_filename"] is None or isinstance(etu["photo_filename"], str)
assert isinstance(etu["code_nip"], str)
assert isinstance(etu["code_ine"], str)
assert etu["scodoc7_id"] is None or isinstance(etu["scodoc7_id"], int)
assert isinstance(etu["email"], str)
assert etu["emailperso"] is None or isinstance(etu["emailperso"], str)
assert etu["domicile"] is None or isinstance(etu["domicile"], str)
assert etu["codepostaldomicile"] is None or isinstance(
etu["codepostaldomicile"], str
)
assert etu["villedomicile"] is None or isinstance(etu["villedomicile"], str)
assert etu["paysdomicile"] is None or isinstance(etu["paysdomicile"], str)
assert etu["telephone"] is None or isinstance(etu["telephone"], str)
assert etu["telephonemobile"] is None or isinstance(etu["telephonemobile"], str)
assert etu["fax"] is None or isinstance(etu["fax"], str)
assert isinstance(etu["typeadresse"], str)
assert etu["description"] is None or isinstance(etu["description"], int)
assert isinstance(etu["group_id"], int)
assert isinstance(etu["etat"], str)
assert isinstance(etu["civilite_str"], str)
assert isinstance(etu["nom_disp"], str)
assert isinstance(etu["nomprenom"], str)
assert isinstance(etu["ne"], str)
assert isinstance(etu["email_default"], str)
for etud in r.json():
assert verify_fields(etud, PARTITION_GROUPS_ETUD_FIELDS)
assert isinstance(etud["id"], int)
assert isinstance(etud["dept_id"], int)
assert isinstance(etud["nom"], str)
assert isinstance(etud["prenom"], str)
assert etud["nom_usuel"] is None or isinstance(etud["nom_usuel"], str)
assert isinstance(etud["civilite"], str)
assert isinstance(etud["code_nip"], str)
assert isinstance(etud["code_ine"], str)
etat = "I"
r_etat = requests.get(
f"{API_URL}/partition/group/{group_id}/etat/{etat}",
f"{API_URL}/group/{group_id}/etudiants/query?etat={etat}",
headers=api_headers,
verify=CHECK_CERTIFICATE,
)
@ -127,47 +95,14 @@ def test_etud_in_group(api_headers):
assert isinstance(r_etat.json(), list)
for etu in r_etat.json():
assert verify_fields(etu, PARTITIONS_GROUPS_ETU_FIELDS)
assert isinstance(etu["etudid"], int)
assert isinstance(etu["id"], int)
assert isinstance(etu["dept_id"], int)
assert isinstance(etu["nom"], str)
assert isinstance(etu["prenom"], str)
assert isinstance(etu["nom_usuel"], str)
assert isinstance(etu["civilite"], str)
assert etu["date_naissance"] is None or isinstance(etu["date_naissance"], str)
assert etu["lieu_naissance"] is None or isinstance(etu["lieu_naissance"], str)
assert etu["dept_naissance"] is None or isinstance(etu["dept_naissance"], str)
assert etu["nationalite"] is None or isinstance(etu["nationalite"], str)
assert etu["statut"] is None or isinstance(etu["statut"], str)
assert etu["boursier"] is None or isinstance(etu["boursier"], bool)
assert etu["photo_filename"] is None or isinstance(etu["photo_filename"], str)
assert isinstance(etu["code_nip"], str)
assert isinstance(etu["code_ine"], str)
assert etu["scodoc7_id"] is None or isinstance(etu["scodoc7_id"], int)
assert isinstance(etu["email"], str)
assert etu["emailperso"] is None or isinstance(etu["emailperso"], str)
assert etu["domicile"] is None or isinstance(etu["domicile"], str)
assert etu["codepostaldomicile"] is None or isinstance(
etu["codepostaldomicile"], str
)
assert etu["villedomicile"] is None or isinstance(etu["villedomicile"], str)
assert etu["paysdomicile"] is None or isinstance(etu["paysdomicile"], str)
assert etu["telephone"] is None or isinstance(etu["telephone"], str)
assert etu["telephonemobile"] is None or isinstance(etu["telephonemobile"], str)
assert etu["fax"] is None or isinstance(etu["fax"], str)
assert isinstance(etu["typeadresse"], str)
assert etu["description"] is None or isinstance(etu["description"], int)
assert isinstance(etu["group_id"], int)
assert isinstance(etu["etat"], str)
assert isinstance(etu["civilite_str"], str)
assert isinstance(etu["nom_disp"], str)
assert isinstance(etu["nomprenom"], str)
assert isinstance(etu["ne"], str)
assert isinstance(etu["email_default"], str)
assert etat == etu["etat"]
for etud in r_etat.json():
assert verify_fields(etud, PARTITION_GROUPS_ETUD_FIELDS)
assert isinstance(etud["id"], int)
assert isinstance(etud["dept_id"], int)
assert isinstance(etud["nom"], str)
assert isinstance(etud["prenom"], str)
assert etud["nom_usuel"] is None or isinstance(etud["nom_usuel"], str)
assert isinstance(etud["civilite"], str)
# # set_groups

View File

@ -40,8 +40,6 @@ def test_permissions(api_headers):
assert len(api_rules) > 0
args = {
"etudid": 1,
# "date_debut":
# "date_fin":
"dept": "TAPI",
"dept_ident": "TAPI",
"dept_id": 1,
@ -51,7 +49,7 @@ def test_permissions(api_headers):
"formation_id": 1,
"formsemestre_id": 1,
"group_id": 1,
"ine": "1",
"ine": "INE1",
"module_id": 1,
"moduleimpl_id": 1,
"nip": 1,

View File

@ -15,7 +15,7 @@ def verify_fields(json_response: dict, expected_fields: set) -> bool:
return all(field in json_response for field in expected_fields)
def verify_occurences_ids_etus(json_response) -> bool:
def verify_occurences_ids_etuds(json_response) -> bool:
"""
Vérifie si il n'y a pas deux fois le même id dans la liste d'étudiant donnée en paramètres
@ -23,22 +23,17 @@ def verify_occurences_ids_etus(json_response) -> bool:
Retourne True ou False
"""
list_etu = json.loads(json_response)
etuds = 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]
ids = [etud["id"] for etud in etuds]
nips = [etud["code_nip"] for etud in etuds]
ines = [etud["code_ine"] for etud in etuds]
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
return (
(len(set(ids)) == len(ids))
and (len(set(nips)) == len(nips))
and (len(set(ines)) == len(ines))
)
DEPARTEMENT_FIELDS = [
@ -200,7 +195,6 @@ FSEM_FIELDS = {
"resp_can_edit",
"responsables",
"semestre_id",
"titre_formation",
"titre_num",
"titre",
}
@ -494,15 +488,16 @@ BULLETIN_SEMESTRE_RANG_FIELDS = {"value", "total"}
EVAL_FIELDS = {
"id",
"description",
"datetime_epreuve",
"jour",
"heure_debut",
"heure_fin",
"coefficient",
"comptee",
"inscrits",
"manquantes",
"ABS",
"ATT",
"EXC",
"etat",
"nb_inscrits",
"nb_notes_manquantes",
"nb_notes_abs",
"nb_notes_att",
"nb_notes_exc",
"saisie_notes",
}
@ -536,10 +531,10 @@ ABSENCES_FIELDS = {
ABSENCES_GROUP_ETAT_FIELDS = {"etudid", "list_abs"}
FORMSEMESTRE_ETUS_FIELDS = {
FORMSEMESTRE_ETUD_FIELDS = {
"id",
"nip",
"ine",
"code_nip",
"code_ine",
"nom",
"nom_usuel",
"prenom",
@ -595,7 +590,6 @@ EVALUATION_FIELDS = {
PARTITIONS_FIELDS = {
"partition_id",
"id",
"formsemestre_id",
"partition_name",
@ -604,42 +598,15 @@ PARTITIONS_FIELDS = {
"show_in_lists",
}
PARTITIONS_GROUPS_ETU_FIELDS = {
"etudid",
PARTITION_GROUPS_ETUD_FIELDS = {
"id",
"dept_id",
"nom",
"prenom",
"nom_usuel",
"civilite",
"date_naissance",
"lieu_naissance",
"dept_naissance",
"nationalite",
"statut",
"boursier",
"photo_filename",
"code_nip",
"code_ine",
"scodoc7_id",
"email",
"emailperso",
"domicile",
"codepostaldomicile",
"villedomicile",
"paysdomicile",
"telephone",
"telephonemobile",
"fax",
"typeadresse",
"description",
"group_id",
"etat",
"civilite_str",
"nom_disp",
"nomprenom",
"ne",
"email_default",
}
FORMSEMESTRE_BULLETINS_FIELDS = {

View File

@ -4,22 +4,7 @@
Création des départements, formations, semestres, étudiants, groupes...
utilisation:
1) modifier /opt/scodoc/.env pour indiquer
FLASK_ENV=test_api
FLASK_DEBUG=1
2) En tant qu'utilisateur scodoc, lancer:
tools/create_database.sh
flask db upgrade
flask sco-db-init --erase
flask init-test-database
3) relancer ScoDoc:
flask run --host 0.0.0.0
4) lancer client de test
Utilisation: voir tests/api/README.md
"""
import datetime
@ -249,34 +234,26 @@ def saisie_notes_evaluations(formsemestre: FormSemestre, user: User):
1 : all_notes_manquantes
2 : some_notes_manquantes
"""
if condition == 0 or condition == 2:
if condition == 0:
for etu in list_etuds:
note = NotesNotes(
etu.id,
evaluation_id,
random.uniform(0, 20),
"",
date_debut + random.random() * (date_fin - date_debut),
user.id,
)
db.session.add(note)
db.session.commit()
else:
percent = 80 / 100
len_etuds = len(list_etuds)
new_list_etuds = random.sample(list_etuds, k=int(percent * len_etuds))
for etu in new_list_etuds:
note = NotesNotes(
etu.id,
evaluation_id,
random.uniform(0, 20),
"",
date_debut + random.random() * (date_fin - date_debut),
user.id,
)
db.session.add(note)
db.session.commit()
if condition == 2:
return # nothing to do
if condition == 0:
list_a_saisir = list_etuds
else:
percent = 80 / 100
len_etuds = len(list_etuds)
list_a_saisir = random.sample(list_etuds, k=int(percent * len_etuds))
for etud in list_a_saisir:
note = NotesNotes(
etudid=etud.id,
evaluation_id=evaluation_id,
value=random.uniform(0, 20),
comment="",
date=date_debut + random.random() * (date_fin - date_debut),
uid=user.id,
)
db.session.add(note)
db.session.commit()
for ue in list_ues:
mods = ue.modules
@ -433,21 +410,15 @@ def create_ref_comp(formation: Formation):
# apc_referentiel_competences_formations = formation
apc_referentiel_competences = ApcReferentielCompetences(
apc_referentiel_competences_id,
apc_referentiel_competences_dept_id,
apc_referentiel_competences_annexe,
apc_referentiel_competences_specialite,
apc_referentiel_competences_specialite_long,
apc_referentiel_competences_type_titre,
apc_referentiel_competences_type_structure,
apc_referentiel_competences_type_departement,
apc_referentiel_competences_version_orebut,
apc_referentiel_competences_xml_attribs,
# apc_referentiel_competences_scodoc_date_loaded,
apc_referentiel_competences_scodoc_orig_filename,
# apc_referentiel_competences_competences,
# apc_referentiel_competences_parcours,
# apc_referentiel_competences_formations,
dept_id=apc_referentiel_competences_dept_id,
annexe=apc_referentiel_competences_annexe,
specialite=apc_referentiel_competences_specialite,
specialite_long=apc_referentiel_competences_specialite_long,
type_titre=apc_referentiel_competences_type_titre,
type_structure=apc_referentiel_competences_type_structure,
type_departement=apc_referentiel_competences_type_departement,
version_orebut=apc_referentiel_competences_version_orebut,
scodoc_orig_filename=apc_referentiel_competences_scodoc_orig_filename,
)
db.session.add(apc_referentiel_competences)
db.session.commit()
@ -464,23 +435,27 @@ def add_absences(formsemestre: FormSemestre):
date_fin = formsemestre.date_fin
etuds = formsemestre.etuds
id_db = 1
for etu in etuds:
aleatoire = random.randint(0, 1)
if aleatoire == 1:
nb_absences = random.randint(1, 5)
for absence in range(0, nb_absences):
id = id_db
etudid = etu.id
jour = date_debut + random.random() * (date_fin - date_debut)
estabs = True
estjust = True if random.randint(0, 1) == 1 else False
matin = True if random.randint(0, 1) == 1 else False
description = ""
abs = Absence(id, etudid, jour, estabs, estjust, matin, description)
db.session.add(abs)
db.session.commit()
id_db += 1
absence = Absence(
etudid=etudid,
jour=jour,
estabs=estabs,
estjust=estjust,
matin=matin,
description=description,
)
db.session.add(absence)
db.session.commit()
def create_etape_apo(formsemestre: FormSemestre):