API: groups_auto_assignment

This commit is contained in:
Emmanuel Viennet 2023-05-15 23:39:08 +02:00
parent a6b8f2b059
commit ee9fd059da
4 changed files with 155 additions and 1 deletions

View File

@ -9,11 +9,12 @@
"""
from operator import attrgetter, itemgetter
from flask import g, request
from flask import g, make_response, request
from flask_json import as_json
from flask_login import login_required
import app
from app import db
from app.api import api_bp as bp, api_web_bp, API_CLIENT_ERROR
from app.decorators import scodoc, permission_required
from app.scodoc.sco_utils import json_error
@ -30,6 +31,7 @@ from app.models import (
ModuleImpl,
NotesNotes,
)
from app.models.formsemestre import GROUPS_AUTO_ASSIGNMENT_DATA_MAX
from app.scodoc.sco_bulletins import get_formsemestre_bulletin_etud_json
from app.scodoc import sco_groups
from app.scodoc.sco_permissions import Permission
@ -496,3 +498,44 @@ def formsemestre_resultat(formsemestre_id: int):
row["partitions"] = etud_groups.get(row["etudid"], {})
return rows
@bp.route("/formsemestre/<int:formsemestre_id>/get_groups_auto_assignment")
@api_web_bp.route("/formsemestre/<int:formsemestre_id>/get_groups_auto_assignment")
@login_required
@scodoc
@permission_required(Permission.ScoView)
@as_json
def get_groups_auto_assignment(formsemestre_id: int):
"""rend les données"""
query = FormSemestre.query.filter_by(id=formsemestre_id)
if g.scodoc_dept:
query = query.filter_by(dept_id=g.scodoc_dept_id)
formsemestre: FormSemestre = query.first_or_404(formsemestre_id)
response = make_response(formsemestre.groups_auto_assignment_data or b"")
response.headers["Content-Type"] = scu.JSON_MIMETYPE
return response
@bp.route(
"/formsemestre/<int:formsemestre_id>/save_groups_auto_assignment", methods=["POST"]
)
@api_web_bp.route(
"/formsemestre/<int:formsemestre_id>/save_groups_auto_assignment", methods=["POST"]
)
@login_required
@scodoc
@permission_required(Permission.ScoView)
@as_json
def save_groups_auto_assignment(formsemestre_id: int):
"""enregistre les données"""
query = FormSemestre.query.filter_by(id=formsemestre_id)
if g.scodoc_dept:
query = query.filter_by(dept_id=g.scodoc_dept_id)
formsemestre: FormSemestre = query.first_or_404(formsemestre_id)
if len(request.data) > GROUPS_AUTO_ASSIGNMENT_DATA_MAX:
return json_error(413, "data too large")
formsemestre.groups_auto_assignment_data = request.data
db.session.add(formsemestre)
db.session.commit()

View File

@ -42,6 +42,8 @@ from app.scodoc.sco_permissions import Permission
from app.scodoc.sco_utils import MONTH_NAMES_ABBREV
from app.scodoc.sco_vdi import ApoEtapeVDI
GROUPS_AUTO_ASSIGNMENT_DATA_MAX = 1024 * 1024 # bytes
class FormSemestre(db.Model):
"""Mise en oeuvre d'un semestre de formation"""
@ -108,6 +110,10 @@ class FormSemestre(db.Model):
elt_annee_apo = db.Column(db.Text())
"code element annee Apogee, eg 'VRT1A' ou 'V2INLA,V2INCA,...'"
# Data pour groups_auto_assignment
# (ce champ est utilisé uniquement via l'API par le front js)
groups_auto_assignment_data = db.Column(db.LargeBinary(), nullable=True)
# Relations:
etapes = db.relationship(
"FormSemestreEtape", cascade="all,delete", backref="formsemestre"

View File

@ -0,0 +1,34 @@
"""Add data for groups_auto_assignment
Revision ID: b8df1b913c79
Revises: 054dd6133b9c
Create Date: 2023-05-15 23:12:58.257709
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = "b8df1b913c79"
down_revision = "054dd6133b9c"
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table("notes_formsemestre", schema=None) as batch_op:
batch_op.add_column(
sa.Column("groups_auto_assignment_data", sa.LargeBinary(), nullable=True)
)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table("notes_formsemestre", schema=None) as batch_op:
batch_op.drop_column("groups_auto_assignment_data")
# ### end Alembic commands ###

View File

@ -0,0 +1,71 @@
"""Test formsemestre
Utilisation :
créer les variables d'environnement: (indiquer les valeurs
pour le serveur ScoDoc que vous voulez interroger)
export SCODOC_URL="https://scodoc.xxx.net/"
export SCODOC_USER="xxx"
export SCODOC_PASSWD="xxx"
export CHECK_CERTIFICATE=0 # ou 1 si serveur de production avec certif SSL valide
(on peut aussi placer ces valeurs dans un fichier .env du répertoire tests/api).
Lancer :
pytest tests/api/test_api_formsemestre.py
"""
import requests
from app.scodoc import sco_utils as scu
from tests.api.setup_test_api import (
API_URL,
CHECK_CERTIFICATE,
api_headers,
)
def test_save_groups_auto_assignment(api_headers):
"""
Routes:
/formsemestre/<id>/save_groups_auto_assignment
/formsemestre/<id>/get_groups_auto_assignment
"""
formsemestre_id = 1
r = requests.get(
f"{API_URL}/formsemestre/{formsemestre_id}",
headers=api_headers,
verify=CHECK_CERTIFICATE,
timeout=scu.SCO_TEST_API_TIMEOUT,
)
assert r.status_code == 200
# On stocke une chaine quelconque
data_orig = (
"""{ "attribute" : "Un paquet de json", "valide": pas nécessairement +}--"""
)
r = requests.post(
f"{API_URL}/formsemestre/{formsemestre_id}/save_groups_auto_assignment",
data=data_orig.encode("utf-8"),
headers=api_headers,
verify=CHECK_CERTIFICATE,
timeout=scu.SCO_TEST_API_TIMEOUT,
)
assert r.status_code == 200
# GET
r = requests.get(
f"{API_URL}/formsemestre/{formsemestre_id}/get_groups_auto_assignment",
headers=api_headers,
verify=CHECK_CERTIFICATE,
timeout=scu.SCO_TEST_API_TIMEOUT,
)
assert r.status_code == 200
assert r.text == data_orig
# Tente d'envoyer trop de données
r = requests.post(
f"{API_URL}/formsemestre/{formsemestre_id}/save_groups_auto_assignment",
data="F*CK" * 1000000, # environ 4MB
headers=api_headers,
verify=CHECK_CERTIFICATE,
timeout=scu.SCO_TEST_API_TIMEOUT,
)
assert r.status_code == 413