forked from ScoDoc/DocScoDoc
API: creation/edition/suppression département
This commit is contained in:
parent
371b017245
commit
45a5c8ae81
@ -1,12 +1,15 @@
|
||||
############################################### Departements ##########################################################
|
||||
|
||||
from flask import jsonify
|
||||
from flask import jsonify, request
|
||||
|
||||
import app
|
||||
from app import models
|
||||
from app import db, log
|
||||
from app.api import api_bp as bp
|
||||
from app.api.errors import error_response
|
||||
from app.decorators import scodoc, permission_required
|
||||
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
|
||||
|
||||
|
||||
@ -24,7 +27,7 @@ def get_departement(dept_ident: str) -> Departement:
|
||||
@bp.route("/departements", methods=["GET"])
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
def departements():
|
||||
def departements_list():
|
||||
"""Liste les départements"""
|
||||
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())
|
||||
|
||||
|
||||
@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"])
|
||||
@scodoc
|
||||
@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()
|
||||
|
||||
# Les semestres en cours de ce département
|
||||
formsemestres = models.FormSemestre.query.filter(
|
||||
formsemestres = FormSemestre.query.filter(
|
||||
FormSemestre.dept_id == dept.id,
|
||||
FormSemestre.date_debut <= 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)
|
||||
|
||||
# Les semestres en cours de ce département
|
||||
formsemestres = models.FormSemestre.query.filter(
|
||||
formsemestres = FormSemestre.query.filter(
|
||||
FormSemestre.dept_id == dept.id,
|
||||
FormSemestre.date_debut <= 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_USER = os.environ.get("API_USER", "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"
|
||||
print(f"SCODOC_URL={SCODOC_URL}")
|
||||
print(f"API URL={API_URL}")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def api_headers() -> dict:
|
||||
"""
|
||||
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))
|
||||
def get_auth_headers(user, password) -> dict:
|
||||
"Demande de jeton, dict à utiliser dans les en-têtes de requêtes http"
|
||||
r0 = requests.post(API_URL + "/tokens", auth=(user, password))
|
||||
token = r0.json()["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):
|
||||
pass
|
||||
|
||||
|
@ -19,7 +19,14 @@ Utilisation :
|
||||
|
||||
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 (
|
||||
verify_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):
|
||||
"""
|
||||
Routes: /departements_ids, /departement, /departement/<string:dept>/formsemestres_ids
|
||||
|
@ -106,6 +106,16 @@ def create_users(dept: Departement) -> tuple:
|
||||
other.set_password("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()
|
||||
return user, other
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user