forked from ScoDoc/DocScoDoc
API: creation/edition/suppression département
This commit is contained in:
parent
371b017245
commit
45a5c8ae81
@ -1,12 +1,15 @@
|
|||||||
############################################### Departements ##########################################################
|
############################################### Departements ##########################################################
|
||||||
|
|
||||||
from flask import jsonify
|
from flask import jsonify, request
|
||||||
|
|
||||||
import app
|
import app
|
||||||
from app import models
|
from app import db, log
|
||||||
from app.api import api_bp as bp
|
from app.api import api_bp as bp
|
||||||
|
from app.api.errors import error_response
|
||||||
from app.decorators import scodoc, permission_required
|
from app.decorators import scodoc, permission_required
|
||||||
from app.models import Departement, FormSemestre
|
from app.models import Departement, FormSemestre
|
||||||
|
from app.models import departements
|
||||||
|
from app.scodoc.sco_exceptions import ScoValueError
|
||||||
from app.scodoc.sco_permissions import Permission
|
from app.scodoc.sco_permissions import Permission
|
||||||
|
|
||||||
|
|
||||||
@ -24,7 +27,7 @@ def get_departement(dept_ident: str) -> Departement:
|
|||||||
@bp.route("/departements", methods=["GET"])
|
@bp.route("/departements", methods=["GET"])
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
def departements():
|
def departements_list():
|
||||||
"""Liste les départements"""
|
"""Liste les départements"""
|
||||||
return jsonify([dept.to_dict() for dept in Departement.query])
|
return jsonify([dept.to_dict() for dept in Departement.query])
|
||||||
|
|
||||||
@ -68,6 +71,66 @@ def departement_by_id(dept_id: int):
|
|||||||
return jsonify(dept.to_dict())
|
return jsonify(dept.to_dict())
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/departement/create", methods=["POST"])
|
||||||
|
@scodoc
|
||||||
|
@permission_required(Permission.ScoSuperAdmin)
|
||||||
|
def departement_create():
|
||||||
|
"""
|
||||||
|
Création d'un département.
|
||||||
|
The request content type should be "application/json":
|
||||||
|
{
|
||||||
|
"acronym": str,
|
||||||
|
"visible":bool,
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
data = request.get_json(force=True) # may raise 400 Bad Request
|
||||||
|
acronym = str(data.get("acronym", ""))
|
||||||
|
if not acronym:
|
||||||
|
return error_response(404, "missing acronym")
|
||||||
|
visible = bool(data.get("visible", True))
|
||||||
|
try:
|
||||||
|
dept = departements.create_dept(acronym, visible=visible)
|
||||||
|
except ScoValueError as exc:
|
||||||
|
return error_response(404, exc.args[0] if exc.args else "")
|
||||||
|
return jsonify(dept.to_dict())
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/departement/<string:acronym>/edit", methods=["POST"])
|
||||||
|
@scodoc
|
||||||
|
@permission_required(Permission.ScoSuperAdmin)
|
||||||
|
def departement_edit(acronym):
|
||||||
|
"""
|
||||||
|
Edition d'un département: seul visible peut être modifié
|
||||||
|
The request content type should be "application/json":
|
||||||
|
{
|
||||||
|
"visible":bool,
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
dept = Departement.query.filter_by(acronym=acronym).first_or_404()
|
||||||
|
data = request.get_json(force=True) # may raise 400 Bad Request
|
||||||
|
visible = bool(data.get("visible", None))
|
||||||
|
if visible is None:
|
||||||
|
return error_response(404, "missing argument: visible")
|
||||||
|
visible = bool(visible)
|
||||||
|
dept.visible = visible
|
||||||
|
db.session.add(dept)
|
||||||
|
db.session.commit()
|
||||||
|
return jsonify(dept.to_dict())
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route("/departement/<string:acronym>/delete", methods=["POST"])
|
||||||
|
@scodoc
|
||||||
|
@permission_required(Permission.ScoSuperAdmin)
|
||||||
|
def departement_delete(acronym):
|
||||||
|
"""
|
||||||
|
Suppression d'un département.
|
||||||
|
"""
|
||||||
|
dept = Departement.query.filter_by(acronym=acronym).first_or_404()
|
||||||
|
db.session.delete(dept)
|
||||||
|
db.session.commit()
|
||||||
|
return jsonify({"OK": True})
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/departement/<string:acronym>/etudiants", methods=["GET"])
|
@bp.route("/departement/<string:acronym>/etudiants", methods=["GET"])
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.ScoView)
|
@permission_required(Permission.ScoView)
|
||||||
@ -168,11 +231,10 @@ def dept_formsemestres_courants(acronym: str):
|
|||||||
...
|
...
|
||||||
]
|
]
|
||||||
"""
|
"""
|
||||||
# Le département, spécifié par un id ou un acronyme
|
|
||||||
dept = Departement.query.filter_by(acronym=acronym).first_or_404()
|
dept = Departement.query.filter_by(acronym=acronym).first_or_404()
|
||||||
|
|
||||||
# Les semestres en cours de ce département
|
# Les semestres en cours de ce département
|
||||||
formsemestres = models.FormSemestre.query.filter(
|
formsemestres = FormSemestre.query.filter(
|
||||||
FormSemestre.dept_id == dept.id,
|
FormSemestre.dept_id == dept.id,
|
||||||
FormSemestre.date_debut <= app.db.func.now(),
|
FormSemestre.date_debut <= app.db.func.now(),
|
||||||
FormSemestre.date_fin >= app.db.func.now(),
|
FormSemestre.date_fin >= app.db.func.now(),
|
||||||
@ -192,7 +254,7 @@ def dept_formsemestres_courants_by_id(dept_id: int):
|
|||||||
dept = Departement.query.get_or_404(dept_id)
|
dept = Departement.query.get_or_404(dept_id)
|
||||||
|
|
||||||
# Les semestres en cours de ce département
|
# Les semestres en cours de ce département
|
||||||
formsemestres = models.FormSemestre.query.filter(
|
formsemestres = FormSemestre.query.filter(
|
||||||
FormSemestre.dept_id == dept.id,
|
FormSemestre.dept_id == dept.id,
|
||||||
FormSemestre.date_debut <= app.db.func.now(),
|
FormSemestre.date_debut <= app.db.func.now(),
|
||||||
FormSemestre.date_fin >= app.db.func.now(),
|
FormSemestre.date_fin >= app.db.func.now(),
|
||||||
|
@ -25,21 +25,32 @@ SCODOC_URL = os.environ["SCODOC_URL"]
|
|||||||
API_URL = SCODOC_URL + "/ScoDoc/api"
|
API_URL = SCODOC_URL + "/ScoDoc/api"
|
||||||
API_USER = os.environ.get("API_USER", "test")
|
API_USER = os.environ.get("API_USER", "test")
|
||||||
API_PASSWORD = os.environ.get("API_PASSWD", "test")
|
API_PASSWORD = os.environ.get("API_PASSWD", "test")
|
||||||
|
API_USER_ADMIN = os.environ.get("API_USER_ADMIN", "admin_api")
|
||||||
|
API_PASSWORD_ADMIN = os.environ.get("API_PASSWD_ADMIN", "admin_api")
|
||||||
DEPT_ACRONYM = "TAPI"
|
DEPT_ACRONYM = "TAPI"
|
||||||
print(f"SCODOC_URL={SCODOC_URL}")
|
print(f"SCODOC_URL={SCODOC_URL}")
|
||||||
print(f"API URL={API_URL}")
|
print(f"API URL={API_URL}")
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
def get_auth_headers(user, password) -> dict:
|
||||||
def api_headers() -> dict:
|
"Demande de jeton, dict à utiliser dans les en-têtes de requêtes http"
|
||||||
"""
|
r0 = requests.post(API_URL + "/tokens", auth=(user, password))
|
||||||
Demande un jeton et renvoie un dict à utiliser dans les en-têtes de requêtes http
|
|
||||||
"""
|
|
||||||
r0 = requests.post(API_URL + "/tokens", auth=(API_USER, API_PASSWORD))
|
|
||||||
token = r0.json()["token"]
|
token = r0.json()["token"]
|
||||||
return {"Authorization": f"Bearer {token}"}
|
return {"Authorization": f"Bearer {token}"}
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def api_headers() -> dict:
|
||||||
|
"""Jeton, utilisateur API ordinaire"""
|
||||||
|
return get_auth_headers(API_USER, API_PASSWORD)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def api_admin_headers() -> dict:
|
||||||
|
"""Jeton, utilisateur API SuperAdmin"""
|
||||||
|
return get_auth_headers(API_USER_ADMIN, API_PASSWORD_ADMIN)
|
||||||
|
|
||||||
|
|
||||||
class APIError(Exception):
|
class APIError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -19,7 +19,14 @@ Utilisation :
|
|||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from tests.api.setup_test_api import API_URL, CHECK_CERTIFICATE, api_headers
|
from tests.api.setup_test_api import (
|
||||||
|
API_URL,
|
||||||
|
CHECK_CERTIFICATE,
|
||||||
|
GET,
|
||||||
|
POST_JSON,
|
||||||
|
api_headers,
|
||||||
|
api_admin_headers,
|
||||||
|
)
|
||||||
from tests.api.tools_test_api import (
|
from tests.api.tools_test_api import (
|
||||||
verify_fields,
|
verify_fields,
|
||||||
DEPARTEMENT_FIELDS,
|
DEPARTEMENT_FIELDS,
|
||||||
@ -28,6 +35,34 @@ from tests.api.tools_test_api import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_create_dept(api_admin_headers):
|
||||||
|
"""
|
||||||
|
Routes: /departement/create,
|
||||||
|
/departement/<string:dept_acronym>/edit
|
||||||
|
/departement/<string:dept_acronym>/delete
|
||||||
|
"""
|
||||||
|
dept = POST_JSON(
|
||||||
|
"/departement/create",
|
||||||
|
{"acronym": "XTEST", "visible": True},
|
||||||
|
headers=api_admin_headers,
|
||||||
|
)
|
||||||
|
dept_r = GET(f"/departement/{dept['acronym']}", headers=api_admin_headers)
|
||||||
|
assert dept["acronym"] == dept_r["acronym"]
|
||||||
|
assert dept_r["visible"] is True
|
||||||
|
dept_e = POST_JSON(
|
||||||
|
f"/departement/{dept['acronym']}/edit",
|
||||||
|
{"visible": False},
|
||||||
|
headers=api_admin_headers,
|
||||||
|
)
|
||||||
|
dept_r = GET(f"/departement/{dept['acronym']}", headers=api_admin_headers)
|
||||||
|
assert dept_r["visible"] is False
|
||||||
|
r = POST_JSON(
|
||||||
|
f"/departement/{dept['acronym']}/delete",
|
||||||
|
headers=api_admin_headers,
|
||||||
|
)
|
||||||
|
assert r["OK"] is True
|
||||||
|
|
||||||
|
|
||||||
def test_departements(api_headers):
|
def test_departements(api_headers):
|
||||||
"""
|
"""
|
||||||
Routes: /departements_ids, /departement, /departement/<string:dept>/formsemestres_ids
|
Routes: /departements_ids, /departement, /departement/<string:dept>/formsemestres_ids
|
||||||
|
@ -106,6 +106,16 @@ def create_users(dept: Departement) -> tuple:
|
|||||||
other.set_password("other")
|
other.set_password("other")
|
||||||
db.session.add(other)
|
db.session.add(other)
|
||||||
|
|
||||||
|
# Un utilisateur "admin_api"
|
||||||
|
admin_api = User(user_name="admin_api", nom="Admin", prenom="API")
|
||||||
|
admin_api.set_password("admin_api")
|
||||||
|
db.session.add(admin_api)
|
||||||
|
role = Role.query.filter_by(name="SuperAdmin").first()
|
||||||
|
if role is None:
|
||||||
|
print("Erreur: rôle SuperAdmin non existant")
|
||||||
|
sys.exit(1)
|
||||||
|
admin_api.add_role(role, None)
|
||||||
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return user, other
|
return user, other
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user