merge master

This commit is contained in:
leonard_montalbano 2022-05-06 12:14:56 +02:00
commit c0c4fd8a39
23 changed files with 654 additions and 490 deletions

View File

@ -123,39 +123,40 @@ def absences_just(etudid: int = None, nip: int = None, ine: int = None):
return jsonify(abs_just) return jsonify(abs_just)
@bp.route( # XXX TODO INACHEVEE
"/absences/abs_group_etat/<int:group_id>", # @bp.route(
methods=["GET"], # "/absences/abs_group_etat/<int:group_id>",
) # methods=["GET"],
@bp.route( # )
"/absences/abs_group_etat/group_id/<int:group_id>/date_debut/<string:date_debut>/date_fin/<string:date_fin>", # @bp.route(
methods=["GET"], # "/absences/abs_group_etat/group_id/<int:group_id>/date_debut/<string:date_debut>/date_fin/<string:date_fin>",
) # methods=["GET"],
@token_auth.login_required # )
@token_permission_required(Permission.APIView) # @token_auth.login_required
def abs_groupe_etat( # XXX A REVOIR XXX # @token_permission_required(Permission.APIView)
group_id: int, date_debut, date_fin, with_boursier=True, format="html" # def abs_groupe_etat( # XXX A REVOIR XXX
): # group_id: int, date_debut, date_fin, with_boursier=True, format="html"
""" # ):
Liste des absences d'un ou plusieurs groupes entre deux dates # """
""" # Liste des absences d'un ou plusieurs groupes entre deux dates
return error_response(501, message="Not implemented") # """
# return error_response(501, message="Not implemented")
# Fonction utilisée : app.scodoc.sco_groups.get_group_members() et app.scodoc.sco_abs.list_abs_date() # # Fonction utilisée : app.scodoc.sco_groups.get_group_members() et app.scodoc.sco_abs.list_abs_date()
try: # try:
# Utilisation de la fonction get_group_members # # Utilisation de la fonction get_group_members
members = get_group_members(group_id) # members = get_group_members(group_id)
except ValueError: # except ValueError:
return error_response( # return error_response(
409, message="La requête ne peut être traitée en létat actuel" # 409, message="La requête ne peut être traitée en létat actuel"
) # )
data = [] # data = []
# Filtre entre les deux dates renseignées # # Filtre entre les deux dates renseignées
for member in members: # for member in members:
abs = sco_abs.list_abs_date(member.id, date_debut, date_fin) # abs = sco_abs.list_abs_date(member.id, date_debut, date_fin)
data.append(abs) # data.append(abs)
# return jsonify(data) # XXX TODO faire en sorte de pouvoir renvoyer sa (ex to_dict() dans absences) # # return jsonify(data) # XXX TODO faire en sorte de pouvoir renvoyer sa (ex to_dict() dans absences)
return error_response(501, message="Not implemented") # return error_response(501, message="Not implemented")

View File

@ -441,14 +441,14 @@ def etudiant_bulletin_semestre(
@bp.route( @bp.route(
"/etudiant/etudid/<int:etudid>/semestre/<int:formsemestre_id>/groups", "/etudiant/etudid/<int:etudid>/formsemestre/<int:formsemestre_id>/groups",
methods=["GET"], methods=["GET"],
) )
@bp.route( @bp.route(
"/etudiant/nip/<int:nip>/semestre/<int:formsemestre_id>/groups", methods=["GET"] "/etudiant/nip/<int:nip>/formsemestre/<int:formsemestre_id>/groups", methods=["GET"]
) )
@bp.route( @bp.route(
"/etudiant/ine/<int:ine>/semestre/<int:formsemestre_id>/groups", methods=["GET"] "/etudiant/ine/<int: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)
@ -456,7 +456,7 @@ def etudiant_groups(
formsemestre_id: int, etudid: int = None, nip: int = None, ine: int = None formsemestre_id: int, etudid: int = None, nip: int = None, ine: int = None
): ):
""" """
Retourne la liste des groupes auxquels appartient l'étudiant dans le semestre indiqué Retourne la liste des groupes auxquels appartient l'étudiant dans le formsemestre indiqué
formsemestre_id : l'id d'un formsemestre formsemestre_id : l'id d'un formsemestre
etudid : l'etudid d'un étudiant etudid : l'etudid d'un étudiant

View File

@ -54,7 +54,7 @@ def evaluations(moduleimpl_id: int):
return jsonify(data) return jsonify(data)
@bp.route("/evaluations/eval_notes/<int:evaluation_id>", methods=["GET"]) @bp.route("/evaluation/eval_notes/<int:evaluation_id>", methods=["GET"])
@token_auth.login_required @token_auth.login_required
@token_permission_required(Permission.APIView) @token_permission_required(Permission.APIView)
def evaluation_notes(evaluation_id: int): def evaluation_notes(evaluation_id: int):

View File

@ -228,7 +228,7 @@ def invalidate_formsemestre( # was inval_cache(formsemestre_id=None, pdfonly=Fa
if getattr(g, "defer_cache_invalidation", False): if getattr(g, "defer_cache_invalidation", False):
g.sem_to_invalidate.add(formsemestre_id) g.sem_to_invalidate.add(formsemestre_id)
return return
log("inval_cache, formsemestre_id={formsemestre_id} pdfonly={pdfonly}") log(f"inval_cache, formsemestre_id={formsemestre_id} pdfonly={pdfonly}")
if formsemestre_id is None: if formsemestre_id is None:
# clear all caches # clear all caches
log("----- invalidate_formsemestre: clearing all caches -----") log("----- invalidate_formsemestre: clearing all caches -----")
@ -272,7 +272,7 @@ def invalidate_formsemestre( # was inval_cache(formsemestre_id=None, pdfonly=Fa
SemBulletinsPDFCache.invalidate_sems(formsemestre_ids) SemBulletinsPDFCache.invalidate_sems(formsemestre_ids)
class DefferedSemCacheManager: class DeferredSemCacheManager:
"""Contexte pour effectuer des opérations indépendantes dans la """Contexte pour effectuer des opérations indépendantes dans la
même requete qui invalident le cache. Par exemple, quand on inscrit même requete qui invalident le cache. Par exemple, quand on inscrit
des étudiants un par un à un semestre, chaque inscription va invalider des étudiants un par un à un semestre, chaque inscription va invalider

View File

@ -70,7 +70,8 @@ class Permission(object):
setattr(Permission, symbol, perm) setattr(Permission, symbol, perm)
Permission.description[symbol] = description Permission.description[symbol] = description
Permission.permission_by_name[symbol] = perm Permission.permission_by_name[symbol] = perm
Permission.NBITS = len(_SCO_PERMISSIONS) max_perm = max(p[0] for p in _SCO_PERMISSIONS)
Permission.NBITS = max_perm.bit_length()
@staticmethod @staticmethod
def get_by_name(permission_name: str) -> int: def get_by_name(permission_name: str) -> int:

View File

@ -252,7 +252,7 @@ def formsemestre_synchro_etuds(
etudids_a_desinscrire = [nip2etudid(x) for x in a_desinscrire] etudids_a_desinscrire = [nip2etudid(x) for x in a_desinscrire]
etudids_a_desinscrire += a_desinscrire_without_key etudids_a_desinscrire += a_desinscrire_without_key
# #
with sco_cache.DefferedSemCacheManager(): with sco_cache.DeferredSemCacheManager():
do_import_etuds_from_portal(sem, a_importer, etudsapo_ident) do_import_etuds_from_portal(sem, a_importer, etudsapo_ident)
sco_inscr_passage.do_inscrit(sem, etudids_a_inscrire) sco_inscr_passage.do_inscrit(sem, etudids_a_inscrire)
sco_inscr_passage.do_desinscrit(sem, etudids_a_desinscrire) sco_inscr_passage.do_desinscrit(sem, etudids_a_desinscrire)

View File

@ -13,7 +13,7 @@ class Config:
SQLALCHEMY_DATABASE_URI = None # set in subclass SQLALCHEMY_DATABASE_URI = None # set in subclass
FLASK_ENV = None # # set in subclass FLASK_ENV = None # # set in subclass
SECRET_KEY = os.environ.get("SECRET_KEY") or "90e01e75831e4176a3c70d29564b425f" SECRET_KEY = os.environ.get("SECRET_KEY") or "90e01e75831e4276a4c70d29564b425f"
SQLALCHEMY_TRACK_MODIFICATIONS = False SQLALCHEMY_TRACK_MODIFICATIONS = False
LOG_TO_STDOUT = os.environ.get("LOG_TO_STDOUT") LOG_TO_STDOUT = os.environ.get("LOG_TO_STDOUT")
MAIL_SERVER = os.environ.get("MAIL_SERVER", "localhost") MAIL_SERVER = os.environ.get("MAIL_SERVER", "localhost")
@ -46,6 +46,7 @@ class Config:
class ProdConfig(Config): class ProdConfig(Config):
"mode production, normalement derrière nginx/gunicorn"
FLASK_ENV = "production" FLASK_ENV = "production"
DEBUG = False DEBUG = False
TESTING = False TESTING = False
@ -56,6 +57,7 @@ class ProdConfig(Config):
class DevConfig(Config): class DevConfig(Config):
"mode développement"
FLASK_ENV = "development" FLASK_ENV = "development"
DEBUG = True DEBUG = True
TESTING = False TESTING = False
@ -66,6 +68,7 @@ class DevConfig(Config):
class TestConfig(DevConfig): class TestConfig(DevConfig):
"Pour les tests unitaires"
TESTING = True TESTING = True
DEBUG = True DEBUG = True
SQLALCHEMY_DATABASE_URI = ( SQLALCHEMY_DATABASE_URI = (
@ -76,6 +79,19 @@ class TestConfig(DevConfig):
SECRET_KEY = os.environ.get("TEST_SECRET_KEY") or "c7ecff5db1594c208f573ff30e0f6bca" SECRET_KEY = os.environ.get("TEST_SECRET_KEY") or "c7ecff5db1594c208f573ff30e0f6bca"
class TestAPIConfig(Config):
"Pour les tests de l'API"
FLASK_ENV = "test_api"
TESTING = False
DEBUG = True
SQLALCHEMY_DATABASE_URI = (
os.environ.get("SCODOC_TEST_API_DATABASE_URI")
or "postgresql:///SCODOC_TEST_API"
)
DEPT_TEST = "TAPI_" # nom du département, ne pas l'utiliser pour un "vrai"
SECRET_KEY = os.environ.get("TEST_SECRET_KEY") or "c7ecff5db15946789Hhahbh88aja175"
mode = os.environ.get("FLASK_ENV", "production") mode = os.environ.get("FLASK_ENV", "production")
if mode == "production": if mode == "production":
RunningConfig = ProdConfig RunningConfig = ProdConfig
@ -83,3 +99,5 @@ elif mode == "development":
RunningConfig = DevConfig RunningConfig = DevConfig
elif mode == "test": elif mode == "test":
RunningConfig = TestConfig RunningConfig = TestConfig
elif mode == "test_api":
RunningConfig = TestAPIConfig

View File

@ -496,12 +496,11 @@ def clear_cache(sanitize): # clear-cache
@app.cli.command() @app.cli.command()
def init_test_database(): def init_test_database(): # init-test-database
"""Initialise les objets en base pour les tests API """Initialise les objets en base pour les tests API
(à appliquer sur SCODOC_TEST ou SCODOC_DEV) (à appliquer sur SCODOC_TEST ou SCODOC_DEV)
""" """
click.echo("Initialisation base de test API...") click.echo("Initialisation base de test API...")
# import app as mapp # le package app
ctx = app.test_request_context() ctx = app.test_request_context()
ctx.push() ctx.push()

11
tests/api/dotenv_exemple Normal file
View File

@ -0,0 +1,11 @@
# Configuration du _client_ test API
# A renommer .env
# and /opt/scodoc/tests/api/
# et à remplir.
# URL du serveur ScoDoc à interroger
SCODOC_URL = "http://localhost:5000/"
# Le client (python) doit-il vérifier le certificat SSL du serveur ?
# ou True si serveur de production avec certif SSL valide
CHECK_CERTIFICATE = False

View File

@ -1,13 +1,13 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""Test Logos """Test API
Utilisation : Utilisation :
créer les variables d'environnement: (indiquer les valeurs créer les variables d'environnement: (indiquer les valeurs
pour le serveur ScoDoc que vous voulez interroger) pour le serveur ScoDoc que vous voulez interroger)
export SCODOC_URL="https://scodoc.xxx.net/" export SCODOC_URL="https://scodoc.xxx.net/"
export SCODOC_USER="xxx" export API_USER="xxx"
export SCODOC_PASSWD="xxx" export SCODOC_PASSWD="xxx"
export CHECK_CERTIFICATE=0 # ou 1 si serveur de production avec certif SSL valide export CHECK_CERTIFICATE=0 # ou 1 si serveur de production avec certif SSL valide
@ -15,23 +15,25 @@ Utilisation :
""" """
import os import os
import requests import requests
from dotenv import load_dotenv
import pytest
BASEDIR = "/opt/scodoc/tests/api"
load_dotenv(os.path.join(BASEDIR, ".env"))
CHECK_CERTIFICATE = bool(os.environ.get("CHECK_CERTIFICATE", False))
SCODOC_URL = os.environ["SCODOC_URL"]
API_URL = SCODOC_URL + "/ScoDoc/api"
API_USER = os.environ.get("API_USER", "test")
API_PASSWORD = os.environ.get("API_PASSWD", "test")
print(f"SCODOC_URL={SCODOC_URL}")
print(f"API URL={API_URL}")
SCODOC_USER = "test" @pytest.fixture
SCODOC_PASSWORD = "test" def api_headers() -> dict:
SCODOC_URL = "http://192.168.1.12:5000"
CHECK_CERTIFICATE = bool(int(os.environ.get("CHECK_CERTIFICATE", False)))
def get_token():
""" """
Permet de set le token dans le header Demande un jeton et renvoie un dict à utiliser dans les en-têtes de requêtes http
""" """
r0 = requests.post( r0 = requests.post(API_URL + "/tokens", auth=(API_USER, API_PASSWORD))
SCODOC_URL + "/ScoDoc/api/tokens", auth=(SCODOC_USER, SCODOC_PASSWORD)
)
token = r0.json()["token"] token = r0.json()["token"]
return {"Authorization": f"Bearer {token}"} return {"Authorization": f"Bearer {token}"}
HEADERS = get_token()

View File

@ -18,99 +18,78 @@ Utilisation :
""" """
import requests import requests
from tests.api.setup_test_api import SCODOC_URL, CHECK_CERTIFICATE, HEADERS from tests.api.setup_test_api import API_URL, CHECK_CERTIFICATE, api_headers
from tests.api.tools_test_api import verify_fields
# Etudiant pour les tests
ETUDID = 1
INE = "1"
NIP = "1"
# absences # absences
def test_absences(): def test_absences(api_headers):
"""
fields = ["jour", "matin", "estabs", "estjust", "description", "begin", "end"] Route: /absences/etudid/<int:etudid>
"""
r = requests.get( r = requests.get(
SCODOC_URL + "/ScoDoc/api/absences/etudid/1", f"{API_URL}/absences/etudid/{ETUDID}",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
abs = r.json()[0]
fields_OK = verify_fields(abs, fields)
assert r.status_code == 200 assert r.status_code == 200
assert fields_OK is True
r = requests.get( r = requests.get(
SCODOC_URL + "/ScoDoc/api/absences/nip/1", f"{API_URL}/absences/nip/{NIP}",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
abs = r.json()[0]
fields_OK = verify_fields(abs, fields)
assert r.status_code == 200 assert r.status_code == 200
assert fields_OK is True
r = requests.get( r = requests.get(
SCODOC_URL + "/ScoDoc/api/absences/ine/1", f"{API_URL}/absences/ine/{INE}",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
abs = r.json()[0]
fields_OK = verify_fields(abs, fields)
assert r.status_code == 200 assert r.status_code == 200
assert fields_OK is True
# absences_justify # absences_justify
def test_absences_justify(): def test_absences_justify(api_headers):
fields = ["jour", "matin", "estabs", "estjust", "description", "begin", "end"] """
Route: /absences/etudid/<etudid:int>/just
"""
r = requests.get( r = requests.get(
SCODOC_URL + "/ScoDoc/api/absences/etudid/1/just", API_URL + f"/absences/etudid/{ETUDID}/just",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
abs = r.json()[0]
fields_OK = verify_fields(abs, fields)
assert r.status_code == 200 assert r.status_code == 200
assert fields_OK is True # TODO vérifier résultat
r = requests.get( r = requests.get(
SCODOC_URL + "/ScoDoc/api/absences/nip/1/just", API_URL + f"/absences/nip/{NIP}/just",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
abs = r.json()[0]
fields_OK = verify_fields(abs, fields)
assert r.status_code == 200 assert r.status_code == 200
assert fields_OK is True # TODO vérifier résultat
r = requests.get( r = requests.get(
SCODOC_URL + "/ScoDoc/api/absences/ine/1/just", API_URL + f"/absences/ine/{INE}/just",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
abs = r.json()[0]
fields_OK = verify_fields(abs, fields)
assert r.status_code == 200 assert r.status_code == 200
assert fields_OK is True # TODO vérifier résultat
# abs_groupe_etat # XXX TODO
# def test_abs_groupe_etat(): # def test_abs_groupe_etat(api_headers):
# """
# Route:
# """
# r = requests.get( # r = requests.get(
# SCODOC_URL # API_URL + "/absences/abs_group_etat/?group_id=<int:group_id>&date_debut=date_debut&date_fin=date_fin",
# + "/ScoDoc/api/absences/abs_group_etat/?group_id=<int:group_id>&date_debut=date_debut&date_fin=date_fin", # headers=api_headers,
# headers=HEADERS,
# verify=CHECK_CERTIFICATE, # verify=CHECK_CERTIFICATE,
# ) # )
# assert r.status_code == 200 # assert r.status_code == 200

View File

@ -19,11 +19,12 @@ Utilisation :
import requests import requests
from tests.api.setup_test_api import SCODOC_URL, CHECK_CERTIFICATE, 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
# departements
def test_departements(): def test_departements(api_headers):
"check liste de sdépartements"
fields = [ fields = [
"id", "id",
"acronym", "acronym",
@ -33,8 +34,8 @@ def test_departements():
] ]
r = requests.get( r = requests.get(
SCODOC_URL + "/ScoDoc/api/departements", API_URL + "/departements",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
assert r.status_code == 200 assert r.status_code == 200
@ -47,9 +48,8 @@ def test_departements():
assert fields_OK is True assert fields_OK is True
# liste_etudiants def test_list_etudiants(api_headers):
def test_liste_etudiants(): fields = {
fields = [
"civilite", "civilite",
"code_ine", "code_ine",
"code_nip", "code_nip",
@ -74,11 +74,11 @@ def test_liste_etudiants():
"telephone", "telephone",
"fax", "fax",
"description", "description",
] }
r = requests.get( r = requests.get(
SCODOC_URL + "/ScoDoc/api/departements/TAPI/etudiants/list", API_URL + "/departements/TAPI/etudiants/list",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
@ -91,8 +91,8 @@ def test_liste_etudiants():
assert fields_OK is True assert fields_OK is True
r = requests.get( r = requests.get(
SCODOC_URL + "/ScoDoc/api/departements/TAPI/etudiants/list/1", API_URL + "/departements/TAPI/etudiants/list/1",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
@ -106,7 +106,7 @@ def test_liste_etudiants():
# liste_semestres_courant # liste_semestres_courant
def test_semestres_courant(): def test_semestres_courant(api_headers):
fields = [ fields = [
"titre", "titre",
"gestion_semestrielle", "gestion_semestrielle",
@ -136,8 +136,8 @@ def test_semestres_courant():
] ]
r = requests.get( r = requests.get(
SCODOC_URL + "/ScoDoc/api/departements/TAPI/semestres_courants", API_URL + "/departements/TAPI/semestres_courants",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
@ -148,14 +148,3 @@ def test_semestres_courant():
assert r.status_code == 200 assert r.status_code == 200
assert len(r.json()) == 1 assert len(r.json()) == 1
assert fields_OK is True assert fields_OK is True
# referenciel_competences
def test_referenciel_competences():
r = requests.get(
SCODOC_URL
+ "/ScoDoc/api/departements/TAPI/formations/1/referentiel_competences",
headers=HEADERS,
verify=CHECK_CERTIFICATE,
)
assert r.status_code == 200 or 204

View File

@ -20,12 +20,14 @@ from random import randint
import requests import requests
from tests.api.setup_test_api import SCODOC_URL, CHECK_CERTIFICATE, 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
# etudiants_courant # etudiants_courant
def test_etudiants_courant(): def test_etudiants_courant(api_headers):
"""
Route: /etudiants/courant
"""
fields = [ fields = [
"id", "id",
"nip", "nip",
@ -36,21 +38,21 @@ def test_etudiants_courant():
] ]
r = requests.get( r = requests.get(
SCODOC_URL + "/ScoDoc/api/etudiants/courant", API_URL + "/etudiants/courant",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
assert r.status_code == 200 assert r.status_code == 200
assert len(r.json()) == 16 etudiants = r.json()
assert len(etudiants) == 16 # XXX HARDCODED
# Choisis aléatoirement un étudiant dans la liste des étudiants etud = etudiants[-1]
etu = r.json()[randint(0, len(r.json())) - 1]
fields_OK = verify_fields(etu, fields) fields_ok = verify_fields(etud, fields)
assert fields_OK is True assert fields_ok is True
########## Version long################ ########## Version long ################
fields_long = [ fields_long = [
"civilite", "civilite",
@ -80,24 +82,24 @@ def test_etudiants_courant():
] ]
r = requests.get( r = requests.get(
SCODOC_URL + "/ScoDoc/api/etudiants/courant/long", API_URL + "/etudiants/courant/long",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
assert r.status_code == 200 assert r.status_code == 200
assert len(r.json()) == 16 etudiants = r.json()
assert len(etudiants) == 16 # HARDCODED
# Choisis aléatoirement un étudiant dans la liste des étudiants etud = etudiants[-1]
etu = r.json()[randint(0, len(r.json())) - 1] fields_ok = verify_fields(etud, fields_long)
fields_OK = verify_fields(etu, fields_long) assert fields_ok is True
assert fields_OK is True
# etudiant def test_etudiant(api_headers):
def test_etudiant(): """
Route:
"""
fields = [ fields = [
"civilite", "civilite",
"code_ine", "code_ine",
@ -126,57 +128,49 @@ def test_etudiant():
] ]
######### Test etudid ######### ######### Test etudid #########
r = requests.get( r = requests.get(
SCODOC_URL + "/ScoDoc/api/etudiant/etudid/1", API_URL + "/etudiant/etudid/1",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
assert r.status_code == 200 assert r.status_code == 200
assert len(r.json()) == 24 etud = r.json()
assert len(etud) == 24 # ? HARDCODED
etu = r.json() fields_ok = verify_fields(etud, fields)
assert fields_ok is True
fields_OK = verify_fields(etu, fields)
assert fields_OK is True
######### Test code nip ######### ######### Test code nip #########
r = requests.get( r = requests.get(
SCODOC_URL + "/ScoDoc/api/etudiant/nip/1", API_URL + "/etudiant/nip/1",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
assert r.status_code == 200 assert r.status_code == 200
assert len(r.json()) == 24 etud = r.json()
assert len(etud) == 24
etu = r.json() fields_ok = verify_fields(etud, fields)
assert fields_ok is True
fields_OK = verify_fields(etu, fields)
assert fields_OK is True
######### Test code ine ######### ######### Test code ine #########
r = requests.get( r = requests.get(
SCODOC_URL + "/ScoDoc/api/etudiant/ine/1", API_URL + "/etudiant/ine/1",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
assert r.status_code == 200 assert r.status_code == 200
assert len(r.json()) == 24 etud = r.json()
assert len(etud) == 24
etu = r.json() fields_ok = verify_fields(etud, fields)
assert fields_ok is True
fields_OK = verify_fields(etu, fields)
assert fields_OK is True
# etudiant_formsemestres def test_etudiant_formsemestres(api_headers):
def test_etudiant_formsemestres(): """
Route: /etudiant/etudid/<etudid:int>/formsemestres
"""
fields = [ fields = [
"date_fin", "date_fin",
"resp_can_edit", "resp_can_edit",
@ -208,89 +202,92 @@ def test_etudiant_formsemestres():
######### Test etudid ######### ######### Test etudid #########
r = requests.get( r = requests.get(
SCODOC_URL + "/ScoDoc/api/etudiant/etudid/1/formsemestres", API_URL + "/etudiant/etudid/1/formsemestres",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
assert r.status_code == 200 assert r.status_code == 200
assert len(r.json()) == 1 formsemestres = r.json()
assert len(formsemestres) == 1
formsemestre = r.json()[0] formsemestre = formsemestres[0]
fields_OK = verify_fields(formsemestre, fields) fields_ok = verify_fields(formsemestre, fields)
assert fields_ok is True
assert fields_OK is True
######### Test code nip ######### ######### Test code nip #########
r = requests.get( r = requests.get(
SCODOC_URL + "/ScoDoc/api/etudiant/nip/1/formsemestres", API_URL + "/etudiant/nip/1/formsemestres",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
assert r.status_code == 200 assert r.status_code == 200
assert len(r.json()) == 1 formsemestres = r.json()
assert len(formsemestres) == 1
formsemestre = r.json()[0] formsemestre = formsemestres[0]
fields_OK = verify_fields(formsemestre, fields) fields_ok = verify_fields(formsemestre, fields)
assert fields_ok is True
assert fields_OK is True
######### Test code ine ######### ######### Test code ine #########
r = requests.get( r = requests.get(
SCODOC_URL + "/ScoDoc/api/etudiant/ine/1/formsemestres", API_URL + "/etudiant/ine/1/formsemestres",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
assert r.status_code == 200 assert r.status_code == 200
assert len(r.json()) == 1 formsemestres = r.json()
assert len(formsemestres) == 1
formsemestre = r.json()[0] formsemestre = formsemestres[0]
fields_OK = verify_fields(formsemestre, fields) fields_ok = verify_fields(formsemestre, fields)
assert fields_ok is True
assert fields_OK is True
# etudiant_bulletin_semestre def test_etudiant_bulletin_semestre(api_headers):
def test_etudiant_bulletin_semestre(): """
Route: /etudiant/etudid/<etudid>/formsemestre/<formsemestre_id>/bulletin
"""
######### Test etudid ######### ######### Test etudid #########
r = requests.get( r = requests.get(
SCODOC_URL + "/ScoDoc/api/etudiant/etudid/1/formsemestre/1/bulletin", API_URL + "/etudiant/etudid/1/formsemestre/1/bulletin",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
assert r.status_code == 200 assert r.status_code == 200
assert len(r.json()) == 13 bul = r.json()
assert len(bul) == 13 # HARDCODED
######### Test code nip ######### ######### Test code nip #########
r = requests.get( r = requests.get(
SCODOC_URL + "/ScoDoc/api/etudiant/nip/1/formsemestre/1/bulletin", API_URL + "/etudiant/nip/1/formsemestre/1/bulletin",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
assert r.status_code == 200 assert r.status_code == 200
assert len(r.json()) == 13 bul = r.json()
assert len(bul) == 13 # HARDCODED
######### Test code ine ######### ######### Test code ine #########
r = requests.get( r = requests.get(
SCODOC_URL + "/ScoDoc/api/etudiant/ine/1/formsemestre/1/bulletin", API_URL + "/etudiant/ine/1/formsemestre/1/bulletin",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
assert r.status_code == 200 assert r.status_code == 200
assert len(r.json()) == 13 bul = r.json()
assert len(bul) == 13 # HARDCODED
# etudiant_groups def test_etudiant_groups(api_headers):
def test_etudiant_groups(): """
Route:
/etudiant/etudid/<int:etudid>/formsemestre/<int:formsemestre_id>/groups
"""
fields = [ fields = [
"partition_id", "partition_id",
"id", "id",
@ -306,47 +303,39 @@ def test_etudiant_groups():
######### Test etudid ######### ######### Test etudid #########
r = requests.get( r = requests.get(
SCODOC_URL + "/ScoDoc/api/etudiant/etudid/1/semestre/1/groups", API_URL + "/etudiant/etudid/1/formsemestre/1/groups",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
assert r.status_code == 200 assert r.status_code == 200
assert len(r.json()) == 1 groups = r.json()
assert len(groups) == 1 # dans un seul groupe
groups = r.json()[0] group = groups[0]
fields_ok = verify_fields(group, fields)
fields_OK = verify_fields(groups, fields) assert fields_ok is True
assert fields_OK is True
######### Test code nip ######### ######### Test code nip #########
r = requests.get( r = requests.get(
SCODOC_URL + "/ScoDoc/api/etudiant/nip/1/semestre/1/groups", API_URL + "/etudiant/nip/1/formsemestre/1/groups",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
assert r.status_code == 200 assert r.status_code == 200
assert len(r.json()) == 1 groups = r.json()
assert len(groups) == 1 # dans un seul groupe
groups = r.json()[0] group = groups[0]
fields_ok = verify_fields(group, fields)
fields_OK = verify_fields(groups, fields) assert fields_ok is True
assert fields_OK is True
######### Test code ine ######### ######### Test code ine #########
r = requests.get( r = requests.get(
SCODOC_URL + "/ScoDoc/api/etudiant/ine/1/semestre/1/groups", API_URL + "/etudiant/ine/1/formsemestre/1/groups",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
assert r.status_code == 200 assert r.status_code == 200
assert len(r.json()) == 1 groups = r.json()
assert len(groups) == 1 # dans un seul groupe
groups = r.json()[0] group = groups[0]
fields_ok = verify_fields(group, fields)
fields_OK = verify_fields(groups, fields) assert fields_ok is True
assert fields_OK is True

View File

@ -19,53 +19,31 @@ Utilisation :
import requests import requests
from tests.api.setup_test_api import SCODOC_URL, CHECK_CERTIFICATE, HEADERS from tests.api.setup_test_api import API_URL, CHECK_CERTIFICATE, api_headers
from tests.api.tools_test_api import verify_fields
# evaluations def test_evaluations(api_headers):
def test_evaluations(): """
fields = [ Route: /evaluation/<int:moduleimpl_id>
"moduleimpl_id", """
"jour",
"heure_debut",
"description",
"coefficient",
"publish_incomplete",
"numero",
"id",
"heure_fin",
"note_max",
"visibulletin",
"evaluation_type",
"evaluation_id",
"jouriso",
"duree",
"descrheure",
"matin",
"apresmidi",
]
r = requests.get( r = requests.get(
SCODOC_URL + "/ScoDoc/api/evaluations/1", API_URL + "/evaluations/1",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE,
)
eval = r.json()[0]
fields_OK = verify_fields(eval, fields)
assert r.status_code == 200
# assert len(r.json()) == 1
assert fields_OK is True
# evaluation_notes
def test_evaluation_notes():
r = requests.get(
SCODOC_URL + "/ScoDoc/api/evaluations/eval_notes/1",
headers=HEADERS,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
assert r.status_code == 200 assert r.status_code == 200
# TODO
# TODO car pas d'évaluations créées à ce stade
# def test_evaluation_notes(api_headers):
# """
# Route: /evaluation/eval_notes/<int:evaluation_id>
# """
# r = requests.get(
# API_URL + "/evaluation/eval_notes/1",
# headers=api_headers,
# verify=CHECK_CERTIFICATE,
# )
# assert r.status_code == 200
# # TODO

View File

@ -19,43 +19,33 @@ Utilisation :
import requests import requests
from tests.api.setup_test_api import SCODOC_URL, CHECK_CERTIFICATE, 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
# formations # formations
def test_formations(): def test_formations_ids(api_headers):
fields = [ """
"id", Route: /formations_ids
"acronyme", """
"titre_officiel",
"formation_code",
"code_specialite",
"dept_id",
"titre",
"version",
"type_parcours",
"referentiel_competence_id",
"formation_id",
]
r = requests.get( r = requests.get(
SCODOC_URL + "/ScoDoc/api/formations", API_URL + "/formations_ids",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
formation = r.json()[0]
fields_OK = verify_fields(formation, fields)
assert r.status_code == 200 assert r.status_code == 200
assert len(r.json()) == 1 formations_ids = r.json()
assert fields_OK is True # Une liste non vide d'entiers
assert isinstance(formations_ids, list)
assert len(formations_ids) > 0
assert all(isinstance(x, int) for x in formations_ids)
# formations_by_id # formations_by_id
def test_formations_by_id(): def test_formations_by_id(api_headers):
"""
Route: /formations/<int:formation_id>
"""
fields = [ fields = [
"id", "id",
"acronyme", "acronyme",
@ -71,21 +61,22 @@ def test_formations_by_id():
] ]
r = requests.get( r = requests.get(
SCODOC_URL + "/ScoDoc/api/formations/1", API_URL + "/formations/1",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
assert r.status_code == 200
formation = r.json() formation = r.json()
fields_OK = verify_fields(formation, fields) fields_ok = verify_fields(formation, fields)
assert fields_ok is True
assert r.status_code == 200 # TODO tester le contenu de certains champs
assert fields_OK is True
# formation_export_by_formation_id def test_formation_export(api_headers):
def test_formation_export_by_formation_id(): """
Route: /formations/formation_export/<int:formation_id>
"""
fields = [ fields = [
"id", "id",
"acronyme", "acronyme",
@ -101,32 +92,33 @@ def test_formation_export_by_formation_id():
"ue", "ue",
] ]
r = requests.get( r = requests.get(
SCODOC_URL + "/ScoDoc/api/formations/formation_export/1", API_URL + "/formations/formation_export/1",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
assert r.status_code == 200
export_formation = r.json() export_formation = r.json()
fields_OK = verify_fields(export_formation, fields) fields_ok = verify_fields(export_formation, fields)
assert fields_ok is True
assert r.status_code == 200 # TODO tester le contenu de certains champs
assert fields_OK is True
# formsemestre_apo # TODO
# def test_formsemestre_apo(): # def test_formsemestre_apo(api_headers):
# r = requests.get( # r = requests.get(
# SCODOC_URL + "/ScoDoc/api/formations/apo/<string:etape_apo>", # API_URL + "/formations/apo/<string:etape_apo>",
# headers=HEADERS, # headers=api_headers,
# verify=CHECK_CERTIFICATE, # verify=CHECK_CERTIFICATE,
# ) # )
# assert r.status_code == 200 # assert r.status_code == 200
# moduleimpl def test_moduleimpl(api_headers):
def test_moduleimpl(): """
Route: /formations/moduleimpl/<int:moduleimpl_id>
"""
fields = [ fields = [
"id", "id",
"formsemestre_id", "formsemestre_id",
@ -139,22 +131,22 @@ def test_moduleimpl():
] ]
r = requests.get( r = requests.get(
SCODOC_URL + "/ScoDoc/api/formations/moduleimpl/1", API_URL + "/formations/moduleimpl/1",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
assert r.status_code == 200
moduleimpl = r.json() moduleimpl = r.json()
fields_OK = verify_fields(moduleimpl, fields) fields_ok = verify_fields(moduleimpl, fields)
assert fields_ok is True
assert r.status_code == 200 # TODO tester le contenu de certains champs
assert fields_OK is True
# moduleimpls_sem def test_moduleimpls_sem(api_headers):
def test_moduleimpls_sem(): """
Route: /formations/moduleimpl/formsemestre/<int:formsemestre_id>/list
"""
fields = [ fields = [
"id", "id",
"formsemestre_id", "formsemestre_id",
@ -168,14 +160,27 @@ def test_moduleimpls_sem():
"ens", "ens",
] ]
r = requests.get( r = requests.get(
SCODOC_URL + "/ScoDoc/api/formations/moduleimpl/formsemestre/1/list", API_URL + "/formations/moduleimpl/formsemestre/1/list",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
moduleimpl = r.json()[0]
fields_OK = verify_fields(moduleimpl, fields)
assert r.status_code == 200 assert r.status_code == 200
assert len(r.json()) == 21 moduleimpls = r.json()
assert fields_OK is True moduleimpl = moduleimpls[0]
fields_ok = verify_fields(moduleimpl, fields)
assert len(moduleimpls) == 21 # XXX HARDCODED !
assert fields_ok is True
def test_referentiel_competences(api_headers):
"""
Route: "/formations/<int:formation_id>/referentiel_competences",
"""
r = requests.get(
API_URL + "/formations/1/referentiel_competences",
headers=api_headers,
verify=CHECK_CERTIFICATE,
)
assert r.status_code == 200
# XXX A compléter

View File

@ -19,14 +19,17 @@ Utilisation :
import requests import requests
from tests.api.setup_test_api import SCODOC_URL, CHECK_CERTIFICATE, 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
# formsemestre
def test_formsemestre(): def test_formsemestre(api_headers):
"""
Route:
"""
r = requests.get( r = requests.get(
SCODOC_URL + "/ScoDoc/api/formsemestre/1", API_URL + "/formsemestre/1",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
assert r.status_code == 200 assert r.status_code == 200
@ -61,40 +64,44 @@ def test_formsemestre():
"responsables", "responsables",
] ]
fields_OK = verify_fields(formsemestre, fields) fields_ok = verify_fields(formsemestre, fields)
assert fields_OK is True assert fields_ok is True
# etudiant_bulletin def test_etudiant_bulletin(api_headers):
def test_etudiant_bulletin(): """
Route:
"""
r = requests.get( r = requests.get(
SCODOC_URL + "/ScoDoc/api/formsemestre/1/etudiant/etudid/1/bulletin", API_URL + "/formsemestre/1/etudiant/etudid/1/bulletin",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
assert r.status_code == 200 assert r.status_code == 200
r = requests.get( r = requests.get(
SCODOC_URL + "/ScoDoc/api/formsemestre/1/etudiant/nip/1/bulletin", API_URL + "/formsemestre/1/etudiant/nip/1/bulletin",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
assert r.status_code == 200 assert r.status_code == 200
r = requests.get( r = requests.get(
SCODOC_URL + "/ScoDoc/api/formsemestre/1/etudiant/ine/1/bulletin", API_URL + "/formsemestre/1/etudiant/ine/1/bulletin",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
assert r.status_code == 200 assert r.status_code == 200
# bulletins def test_bulletins(api_headers):
def test_bulletins(): """
Route:
"""
r = requests.get( r = requests.get(
SCODOC_URL + "/ScoDoc/api/formsemestre/1/bulletins", API_URL + "/formsemestre/1/bulletins",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
assert r.status_code == 200 assert r.status_code == 200
@ -103,15 +110,17 @@ def test_bulletins():
# # jury # # jury
# def test_jury(): # def test_jury():
# r = requests.get( # r = requests.get(
# SCODOC_URL + "/ScoDoc/api/formsemestre/1/jury", # API_URL + "/formsemestre/1/jury",
# headers=HEADERS, # headers=api_headers,
# verify=CHECK_CERTIFICATE, # verify=CHECK_CERTIFICATE,
# ) # )
# assert r.status_code == 200 # assert r.status_code == 200
# semestre_index # TODO A revoir
def test_semestre_index(): def test_semestre_index(api_headers):
"""
Route: TODO
"""
ue_fields = [ ue_fields = [
"semestre_idx", "semestre_idx",
"type", "type",
@ -170,8 +179,8 @@ def test_semestre_index():
] ]
r = requests.get( r = requests.get(
SCODOC_URL + "/ScoDoc/api/formsemestre/1/programme", API_URL + "/formsemestre/1/programme",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
assert r.status_code == 200 assert r.status_code == 200

View File

@ -19,37 +19,41 @@ Utilisation :
import requests import requests
from tests.api.setup_test_api import SCODOC_URL, CHECK_CERTIFICATE, HEADERS from tests.api.setup_test_api import API_URL, CHECK_CERTIFICATE, api_headers
# jury_preparation
def test_jury_preparation(): def test_jury_preparation(api_headers):
"""
Route:
"""
r = requests.get( r = requests.get(
SCODOC_URL SCODOC_URL
+ "/ScoDoc/api/jury/formsemestre/<int:formsemestre_id>/preparation_jury", + "/ScoDoc/api/jury/formsemestre/<int:formsemestre_id>/preparation_jury",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
assert r.status_code == 200 assert r.status_code == 200
# jury_decisions def test_jury_decisions(api_headers):
def test_jury_decisions(): """
Route:
"""
r = requests.get( r = requests.get(
SCODOC_URL API_URL + "/jury/formsemestre/<int:formsemestre_id>/decisions_jury",
+ "/ScoDoc/api/jury/formsemestre/<int:formsemestre_id>/decisions_jury", headers=api_headers,
headers=HEADERS,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
assert r.status_code == 200 assert r.status_code == 200
# set_decision_jury # set_decision_jury
def test_set_decision_jury(): def test_set_decision_jury(api_headers):
r = requests.get( r = requests.get(
SCODOC_URL SCODOC_URL
+ "/ScoDoc/api/jury/set_decision/etudid?etudid=<int:etudid>&formsemestre_id=<int:formesemestre_id>" + "/ScoDoc/api/jury/set_decision/etudid?etudid=<int:etudid>&formsemestre_id=<int:formesemestre_id>"
"&jury=<string:decision_jury>&devenir=<string:devenir_jury>&assiduite=<bool>", "&jury=<string:decision_jury>&devenir=<string:devenir_jury>&assiduite=<bool>",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
assert r.status_code == 200 assert r.status_code == 200
@ -58,7 +62,7 @@ def test_set_decision_jury():
SCODOC_URL SCODOC_URL
+ "/ScoDoc/api/jury/set_decision/nip?etudid=<int:etudid>&formsemestre_id=<int:formesemestre_id>" + "/ScoDoc/api/jury/set_decision/nip?etudid=<int:etudid>&formsemestre_id=<int:formesemestre_id>"
"&jury=<string:decision_jury>&devenir=<string:devenir_jury>&assiduite=<bool>", "&jury=<string:decision_jury>&devenir=<string:devenir_jury>&assiduite=<bool>",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
assert r.status_code == 200 assert r.status_code == 200
@ -67,18 +71,20 @@ def test_set_decision_jury():
SCODOC_URL SCODOC_URL
+ "/ScoDoc/api/jury/set_decision/ine?etudid=<int:etudid>&formsemestre_id=<int:formesemestre_id>" + "/ScoDoc/api/jury/set_decision/ine?etudid=<int:etudid>&formsemestre_id=<int:formesemestre_id>"
"&jury=<string:decision_jury>&devenir=<string:devenir_jury>&assiduite=<bool>", "&jury=<string:decision_jury>&devenir=<string:devenir_jury>&assiduite=<bool>",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
assert r.status_code == 200 assert r.status_code == 200
# annule_decision_jury def test_annule_decision_jury(api_headers):
def test_annule_decision_jury(): """
Route:
"""
r = requests.get( r = requests.get(
SCODOC_URL SCODOC_URL
+ "/ScoDoc/api/jury/etudid/<int:etudid>/formsemestre/<int:formsemestre_id>/annule_decision", + "/ScoDoc/api/jury/etudid/<int:etudid>/formsemestre/<int:formsemestre_id>/annule_decision",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
assert r.status_code == 200 assert r.status_code == 200
@ -86,7 +92,7 @@ def test_annule_decision_jury():
r = requests.get( r = requests.get(
SCODOC_URL SCODOC_URL
+ "/ScoDoc/api/jury/nip/<int:nip>/formsemestre/<int:formsemestre_id>/annule_decision", + "/ScoDoc/api/jury/nip/<int:nip>/formsemestre/<int:formsemestre_id>/annule_decision",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
assert r.status_code == 200 assert r.status_code == 200
@ -94,7 +100,7 @@ def test_annule_decision_jury():
r = requests.get( r = requests.get(
SCODOC_URL SCODOC_URL
+ "/ScoDoc/api/jury/ine/<int:ine>/formsemestre/<int:formsemestre_id>/annule_decision", + "/ScoDoc/api/jury/ine/<int:ine>/formsemestre/<int:formsemestre_id>/annule_decision",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
assert r.status_code == 200 assert r.status_code == 200

View File

@ -5,11 +5,16 @@
"""Exemple utilisation API ScoDoc 9 avec jeton obtenu par basic authentication """Exemple utilisation API ScoDoc 9 avec jeton obtenu par basic authentication
utilisation: utilisation:
à faire fonctionner en environnment de test (FLASK_ENV=test dans le fichier .env) à faire fonctionner en environnment de test (FLASK_ENV=test_api dans le fichier .env)
pytest tests/api/test_api_logos.py pytest tests/api/test_api_logos.py
""" """
from tests.api.setup_test_api import SCODOC_URL, CHECK_CERTIFICATE, HEADERS
# XXX TODO
# Ce test a une logique très différente des autres : A UNIFIER
from tests.api.setup_test_api import API_URL
from scodoc import app from scodoc import app
from tests.unit.config_test_logos import ( from tests.unit.config_test_logos import (
@ -22,35 +27,47 @@ from tests.unit.config_test_logos import (
def test_super_access(create_super_token): def test_super_access(create_super_token):
"""
Route:
"""
dept1, dept2, dept3, token = create_super_token dept1, dept2, dept3, token = create_super_token
HEADERS = {"Authorization": f"Bearer {token}"} headers = {"Authorization": f"Bearer {token}"}
with app.test_client() as client: with app.test_client() as client:
response = client.get("/ScoDoc/api/logos", headers=HEADERS) response = client.get(API_URL + "/logos", headers=headers)
assert response.status_code == 200 assert response.status_code == 200
assert response.json is not None assert response.json is not None
def test_admin_access(create_admin_token): def test_admin_access(create_admin_token):
"""
Route:
"""
dept1, dept2, dept3, token = create_admin_token dept1, dept2, dept3, token = create_admin_token
headers = {"Authorization": f"Bearer {token}"} headers = {"Authorization": f"Bearer {token}"}
with app.test_client() as client: with app.test_client() as client:
response = client.get("/ScoDoc/api/logos", headers=headers) response = client.get(API_URL + "/logos", headers=headers)
assert response.status_code == 401 assert response.status_code == 401
def test_lambda_access(create_lambda_token): def test_lambda_access(create_lambda_token):
"""
Route:
"""
dept1, dept2, dept3, token = create_lambda_token dept1, dept2, dept3, token = create_lambda_token
headers = {"Authorization": f"Bearer {token}"} headers = {"Authorization": f"Bearer {token}"}
with app.test_client() as client: with app.test_client() as client:
response = client.get("/ScoDoc/api/logos", headers=headers) response = client.get(API_URL + "/logos", headers=headers)
assert response.status_code == 401 assert response.status_code == 401
def test_initial_with_header_and_footer(create_super_token): def test_initial_with_header_and_footer(create_super_token):
"""
Route:
"""
dept1, dept2, dept3, token = create_super_token dept1, dept2, dept3, token = create_super_token
headers = {"Authorization": f"Bearer {token}"} headers = {"Authorization": f"Bearer {token}"}
with app.test_client() as client: with app.test_client() as client:
response = client.get("/ScoDoc/api/logos", headers=headers) response = client.get(API_URL + "/logos", headers=headers)
assert response.status_code == 200 assert response.status_code == 200
assert response.json is not None assert response.json is not None
assert len(response.json) == 7 assert len(response.json) == 7

View File

@ -19,12 +19,14 @@ Utilisation :
import requests import requests
from tests.api.setup_test_api import SCODOC_URL, CHECK_CERTIFICATE, 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
# partition def test_partition(api_headers):
def test_partition(): """
Route:
"""
fields = [ fields = [
"partition_id", "partition_id",
"id", "id",
@ -36,23 +38,22 @@ def test_partition():
] ]
r = requests.get( r = requests.get(
SCODOC_URL + "/ScoDoc/api/partitions/1", API_URL + "/partitions/1",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
partition = r.json()[0]
fields_OK = verify_fields(partition, fields)
assert r.status_code == 200 assert r.status_code == 200
assert len(r.json()) == 2 partitions = r.json()
assert fields_OK is True assert len(partitions) == 1
partition = partitions[0]
fields_ok = verify_fields(partition, fields)
assert fields_ok is True
# etud_in_group def test_etud_in_group(api_headers):
def test_etud_in_group(): """
Route:
"""
fields = [ fields = [
"etudid", "etudid",
"id", "id",
@ -92,33 +93,36 @@ def test_etud_in_group():
] ]
r = requests.get( r = requests.get(
SCODOC_URL + "/ScoDoc/api/partitions/groups/1", API_URL + "/partitions/groups/1",
headers=HEADERS, headers=api_headers,
verify=CHECK_CERTIFICATE, verify=CHECK_CERTIFICATE,
) )
etu = r.json()[0] etu = r.json()[0]
fields_OK = verify_fields(etu, fields) fields_ok = verify_fields(etu, fields)
assert r.status_code == 200 assert r.status_code == 200
assert len(r.json()) == 16 assert len(r.json()) == 16
assert fields_OK is True assert fields_ok is True
# r = requests.get( # r = requests.get(
# SCODOC_URL + "/ScoDoc/api/partitions/groups/1/etat/<string:etat>", # API_URL + "/partitions/groups/1/etat/<string:etat>",
# headers=HEADERS, # headers=api_headers,
# verify=CHECK_CERTIFICATE, # verify=CHECK_CERTIFICATE,
# ) # )
# assert r.status_code == 200 # assert r.status_code == 200
# # set_groups # # set_groups
# def test_set_groups(): # def test_set_groups(api_headers):
# """
# Route:
# """
# r = requests.get( # r = requests.get(
# SCODOC_URL # SCODOC_URL
# + "/partitions/set_groups/partition/<int:partition_id>/groups/<string:groups_id>" # + "/partitions/set_groups/partition/<int:partition_id>/groups/<string:groups_id>"
# "/delete/<string:groups_to_delete>/create/<string:groups_to_create>", # "/delete/<string:groups_to_delete>/create/<string:groups_to_create>",
# headers=HEADERS, # headers=api_headers,
# verify=CHECK_CERTIFICATE, # verify=CHECK_CERTIFICATE,
# ) # )
# assert r.status_code == 200 # assert r.status_code == 200

View File

@ -0,0 +1,98 @@
# -*- coding: utf-8 -*-
"""Test permissions
On a deux utilisateurs dans la base test API:
- "test", avec le rôle LecteurAPI qui a APIView,
- et "other", qui n'a aucune permission.
Lancer :
pytest tests/api/test_api_permissions.py
"""
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
from app import create_app
from config import RunningConfig
def test_permissions(api_headers):
"""
vérification de la permissions APIView et du non accès sans role
de toutes les routes de l'API
"""
# Ce test va récupérer toutes les routes de l'API
app = create_app(RunningConfig)
assert app
# Les routes de l'API avec GET, excluant les logos pour le momeent XXX
api_rules = [
r
for r in app.url_map.iter_rules()
if str(r).startswith("/ScoDoc/api")
and not "logo" in str(r) # ignore logos
and "GET" in r.methods
]
assert len(api_rules) > 0
args = {
"etudid": 1,
# "date_debut":
# "date_fin":
"dept": "TAPI",
"etape_apo": "???",
"etat": "I",
"evaluation_id": 1,
"formation_id": 1,
"formsemestre_id": 1,
"group_id": 1,
"ine": "1",
"module_id": 1,
"moduleimpl_id": 1,
"nip": 1,
"partition_id": 1,
}
for rule in api_rules:
path = rule.build(args)[1]
if not "GET" in rule.methods:
# skip all POST routes
continue
r = requests.get(
SCODOC_URL + path,
headers=api_headers,
verify=CHECK_CERTIFICATE,
)
assert r.status_code == 200
# Même chose sans le jeton:
for rule in api_rules:
path = rule.build(args)[1]
if not "GET" in rule.methods:
# skip all POST routes
continue
r = requests.get(
SCODOC_URL + path,
verify=CHECK_CERTIFICATE,
)
assert r.status_code == 401
# Demande un jeton pour "other"
r = requests.post(API_URL + "/tokens", auth=("other", "other"))
assert r.status_code == 200
token = r.json()["token"]
headers = {"Authorization": f"Bearer {token}"}
# Vérifie que tout est interdit
for rule in api_rules:
path = rule.build(args)[1]
if not "GET" in rule.methods:
# skip all POST routes
continue
r = requests.get(
SCODOC_URL + path,
headers=headers,
verify=CHECK_CERTIFICATE,
)
assert r.status_code == 403

View File

@ -1,9 +1,13 @@
def verify_fields(json_response, fields): """Utilitaires pour les tests de l'API
"""
def verify_fields(json_response: dict, fields: set) -> bool:
""" """
Vérifie si les champs de la réponse json sont corrects Vérifie si les champs attendu de la réponse json sont présents
json_response : la réponse de la requête json_response : la réponse de la requête
fields : une liste avec l'ensemble des champs à vérifier fields : ensemble des champs à vérifier
Retourne True ou False Retourne True ou False
""" """

View File

@ -9,8 +9,16 @@ die() {
echo echo
exit 1 exit 1
} }
[ $# = 1 ] || die "Usage $0 db_name" [ $# = 1 ] || [ $# = 2 ] || die "Usage $0 [--drop] db_name"
db_name="$1"
if [ "$1" = "--drop" ]
then
db_name="$2"
echo "Dropping database $db_name..."
dropdb "$db_name"
else
db_name="$1"
fi
# Le répertoire de ce script: # Le répertoire de ce script:
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"

View File

@ -5,60 +5,59 @@
Création des départements, formations, semestres, étudiants, groupes... Création des départements, formations, semestres, étudiants, groupes...
utilisation: utilisation:
1) modifier le .env pour indiquer 1) modifier /opt/scodoc/.env pour indiquer
SCODOC_DATABASE_URI="postgresql:///SCO_TEST_API" FLASK_ENV=test_api
FLASK_DEBUG=1
2) En tant qu'utilisateur scodoc, lancer: 2) En tant qu'utilisateur scodoc, lancer:
tools/create_database.sh SCO_TEST_API tools/create_database.sh SCODOC_TEST_API
flask db upgrade flask db upgrade
flask sco-db-init --erase flask sco-db-init --erase
flask init-test-database flask init-test-database
flask user-role -a Admin -d TAPI test
flask user-password test
flask create-role APIUserViewer
flask edit-role APIUserViewer -a APIView
flask user-role test -a APIUserViewer
3) relancer ScoDoc: 3) relancer ScoDoc:
flask run --host 0.0.0.0 flask run --host 0.0.0.0
4) lancer client de test (ou vérifier dans le navigateur) 4) lancer client de test
""" """
import datetime import datetime
import random import random
import sys
random.seed(12345678) # tests reproductibles from app.auth.models import Role, User
from flask_login import login_user
from app import auth
from app import models from app import models
from app.models import Departement, Formation, FormSemestre
from app import db from app import db
from app.scodoc import ( from app.scodoc import (
sco_cache,
sco_evaluation_db,
sco_formations, sco_formations,
sco_formsemestre,
sco_formsemestre_inscriptions, sco_formsemestre_inscriptions,
sco_groups, sco_groups,
) )
from app.scodoc.sco_permissions import Permission
from tools.fakeportal.gen_nomprenoms import nomprenom from tools.fakeportal.gen_nomprenoms import nomprenom
random.seed(12345678) # tests reproductibles
# La formation à utiliser: # La formation à utiliser:
FORMATION_XML_FILENAME = "tests/ressources/formations/scodoc_formation_RT_BUT_RT_v1.xml" FORMATION_XML_FILENAME = "tests/ressources/formations/scodoc_formation_RT_BUT_RT_v1.xml"
def init_departement(acronym): def init_departement(acronym: str) -> Departement:
"Create dept, and switch context into it." "Create dept, and switch context into it."
import app as mapp import app as mapp
dept = models.Departement(acronym=acronym) dept = Departement(acronym=acronym)
db.session.add(dept) db.session.add(dept)
mapp.set_sco_dept(acronym) mapp.set_sco_dept(acronym)
db.session.commit() db.session.commit()
return dept return dept
def import_formation() -> models.Formation: def import_formation() -> Formation:
"""Import formation from XML. """Import formation from XML.
Returns formation_id Returns formation_id
""" """
@ -66,20 +65,37 @@ def import_formation() -> models.Formation:
doc = f.read() doc = f.read()
# --- Création de la formation # --- Création de la formation
f = sco_formations.formation_import_xml(doc) f = sco_formations.formation_import_xml(doc)
return models.Formation.query.get(f[0]) return Formation.query.get(f[0])
def create_user(dept): def create_users(dept: Departement) -> tuple:
"""créé les utilisaterurs nécessaires aux tests""" """créé les utilisateurs nécessaires aux tests"""
user = auth.models.User( # Un utilisateur "test" (passwd test) pouvant lire l'API
user_name="test", nom="Doe", prenom="John", dept=dept.acronym user = User(user_name="test", nom="Doe", prenom="John", dept=dept.acronym)
) user.set_password("test")
db.session.add(user) db.session.add(user)
# Le rôle standard LecteurAPI existe déjà
role = Role.query.filter_by(name="LecteurAPI").first()
if role is None:
print("Erreur: rôle LecteurAPI non existant")
sys.exit(1)
perm_api_view = Permission.get_by_name("APIView")
role.add_permission(perm_api_view)
db.session.add(role)
user.add_role(role, None)
# Un utilisateur "other" n'ayant aucune permission sur l'API
other = User(user_name="other", nom="Sans", prenom="Permission", dept=dept.acronym)
other.set_password("other")
db.session.add(other)
db.session.commit() db.session.commit()
return user return user, other
def create_fake_etud(dept): def create_fake_etud(dept: Departement) -> models.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)
@ -100,14 +116,18 @@ def create_fake_etud(dept):
return etud return etud
def create_etuds(dept, nb=16): def create_etuds(dept: Departement, nb=16) -> list:
"create nb etuds" "create nb etuds"
return [create_fake_etud(dept) for _ in range(nb)] return [create_fake_etud(dept) for _ in range(nb)]
def create_formsemestre(formation, user, semestre_idx=1): def create_formsemestre(
"""Create formsemestre and moduleimpls""" formation: Formation, responsable: User, semestre_idx=1
formsemestre = models.FormSemestre( ) -> FormSemestre:
"""Create formsemestre and moduleimpls
responsable: resp. du formsemestre
"""
formsemestre = FormSemestre(
dept_id=formation.dept_id, dept_id=formation.dept_id,
semestre_id=semestre_idx, semestre_id=semestre_idx,
titre="Semestre test", titre="Semestre test",
@ -121,7 +141,9 @@ def create_formsemestre(formation, user, semestre_idx=1):
# Crée un modulimpl par module de ce semestre: # Crée un modulimpl par module de ce semestre:
for module in formation.modules.filter_by(semestre_id=semestre_idx): for module in formation.modules.filter_by(semestre_id=semestre_idx):
modimpl = models.ModuleImpl( modimpl = models.ModuleImpl(
module_id=module.id, formsemestre_id=formsemestre.id, responsable_id=user.id module_id=module.id,
formsemestre_id=formsemestre.id,
responsable_id=responsable.id,
) )
db.session.add(modimpl) db.session.add(modimpl)
db.session.commit() db.session.commit()
@ -132,7 +154,7 @@ def create_formsemestre(formation, user, semestre_idx=1):
return formsemestre return formsemestre
def inscrit_etudiants(etuds, formsemestre): def inscrit_etudiants(etuds: list, formsemestre: FormSemestre):
"""Inscrit les etudiants aux semestres et à tous ses modules""" """Inscrit les etudiants aux semestres et à tous ses modules"""
for etud in etuds: for etud in etuds:
sco_formsemestre_inscriptions.do_formsemestre_inscription_with_modules( sco_formsemestre_inscriptions.do_formsemestre_inscription_with_modules(
@ -144,14 +166,38 @@ def inscrit_etudiants(etuds, formsemestre):
) )
def init_test_database(): def create_evaluations(formsemestre: FormSemestre):
"creation d'une evaluation dans cahque modimpl du semestre"
for modimpl in formsemestre.modimpls:
args = {
"moduleimpl_id": modimpl.id,
"jour": None,
"heure_debut": "8h00",
"heure_fin": "9h00",
"description": None,
"note_max": 20,
"coefficient": 1.0,
"visibulletin": True,
"publish_incomplete": True,
"evaluation_type": None,
"numero": None,
}
evaluation_id = sco_evaluation_db.do_evaluation_create(**args)
def init_test_database():
"""Appelé par la commande `flask init-test-database`
Création d'un département et de son contenu pour les tests
"""
dept = init_departement("TAPI") dept = init_departement("TAPI")
user = create_user(dept) user_lecteur, user_autre = create_users(dept)
etuds = create_etuds(dept) with sco_cache.DeferredSemCacheManager():
formation = import_formation() etuds = create_etuds(dept)
formsemestre = create_formsemestre(formation, user) formation = import_formation()
inscrit_etudiants(etuds, formsemestre) formsemestre = create_formsemestre(formation, user_lecteur)
create_evaluations(formsemestre)
inscrit_etudiants(etuds, formsemestre)
# à compléter # à compléter
# - groupes # - groupes
# - absences # - absences