ScoDoc/tests/unit/test_assiduites.py
2024-06-25 11:27:10 +02:00

1839 lines
58 KiB
Python

# -*- mode: python -*-
# -*- coding: utf-8 -*-
"""
Tests unitaires vérifiant le bon fonctionnement du modèle Assiduité et de
ses fonctions liées
Ecrit par HARTMANN Matthias (en s'inspirant de tests.unit.test_abs_count.py par Fares Amer )
"""
import pytest
from flask_sqlalchemy.query import Query
import app.scodoc.sco_assiduites as scass
import app.scodoc.sco_utils as scu
from app import db, log
from app.models import (
Assiduite,
Evaluation,
FormSemestre,
Identite,
Justificatif,
ModuleImpl,
Absence,
)
from app.scodoc.sco_exceptions import ScoValueError
from tests.unit import sco_fake_gen
from tools import downgrade_module, migrate_abs_to_assiduites
import datetime as dt
class BiInt(int, scu.BiDirectionalEnum):
"""Classe pour tester la classe BiDirectionalEnum"""
A = 1
B = 2
def test_bi_directional_enum(test_client):
"""Test le bon fonctionnement de la classe BiDirectionalEnum"""
assert BiInt.get("A") == BiInt.get("a") == BiInt.A == 1
assert BiInt.get("B") == BiInt.get("b") == BiInt.B == 2
assert BiInt.get("blabla") is None
assert BiInt.get("blabla", -1) == -1
assert isinstance(BiInt.inverse(), dict)
assert BiInt.inverse()[1] == BiInt.A and BiInt.inverse()[2] == BiInt.B
def test_general(test_client):
"""tests général du modèle assiduite"""
data: dict = _setup_fake_db(
dates_formsemestre=[
("01/09/2022", "31/12/2022"),
("01/01/2023", "31/07/2023"),
("01/01/2024", "31/07/2024"),
],
nb_modules=2,
nb_etuds=3,
)
etuds, moduleimpls, etud_faux, formsemestres = (
data["etuds"],
data["moduleimpls"],
data["etud_faux"],
data["formsemestres"],
)
verif_migration_abs_assiduites()
ajouter_assiduites(etuds, moduleimpls, etud_faux)
justificatifs: list[Justificatif] = ajouter_justificatifs(etuds[0])
verifier_comptage_et_filtrage_assiduites(etuds, moduleimpls[:4], formsemestres)
verifier_filtrage_justificatifs(etuds[0], justificatifs)
editer_supprimer_assiduites(etuds, moduleimpls)
editer_supprimer_justificatif(etuds[0])
def verif_migration_abs_assiduites():
"""Vérification que le script de migration fonctionne correctement"""
downgrade_module(assiduites=True, justificatifs=True)
etudid: int = 1
for debut, fin, demijournee, justifiee in [
(
"02/01/2023",
"02/01/2023",
1,
False,
), # 1 assi 02/01/2023 8h > 13h (1dj)
(
"03/01/2023",
"03/01/2023",
0,
False,
), # 1 assi 03/01/2023 13h > 18h (1dj)
(
"05/01/2023",
"05/01/2023",
2,
False,
), # 1 assi 05/01/2023 8h > 18h (2dj)
(
"09/01/2023",
"09/01/2023",
1,
False,
),
(
"09/01/2023",
"09/01/2023",
0,
False,
), # 1 assi 09/01/2023 8h > 18h (2dj)
(
"10/01/2023",
"10/01/2023",
0,
False,
),
(
"11/01/2023",
"11/01/2023",
1,
False,
), # 1 assi 10/01/2023 - 11/01/2023 13h > 13h (2dj)
(
"12/01/2023",
"12/01/2023",
1,
False,
), # 1 assi 12/01/2023 8h > 13h (1dj)
(
"13/01/2023",
"13/01/2023",
1,
False,
), # 1 assi 13/01/2023 8h > 13h (1dj)
(
"16/01/2023",
"16/01/2023",
1,
False,
),
(
"16/01/2023",
"16/01/2023",
1,
False,
), # 1 assi 16/01/2023 8h > 13h (1dj)
(
"19/01/2023",
"24/01/2023",
2,
False,
), # 2 assi 19/01/2023 - 20/01/2023 8h > 18h (4dj) + 23/01/23 - 24/01/2023 8h>18h (4dj)
(
"01/02/2023",
"01/02/2023",
1,
True,
), # 1 assi 01/02/2023 8h > 13h (1dj) JUSTI
(
"02/02/2023",
"02/02/2023",
0,
True,
), # 1 assi 02/02/2023 13h > 18h (1dj) JUSTI
(
"06/02/2023",
"06/02/2023",
2,
True,
), # 1 assi 06/02/2023 8h > 18h (2dj) JUSTI
(
"07/02/2023",
"07/02/2023",
0,
True,
),
(
"07/02/2023",
"07/02/2023",
0,
False,
), # 1 assi 07/02/2023 13h > 18h (1dj) JUSTI
(
"08/02/2023",
"08/02/2023",
0,
False,
),
(
"08/02/2023",
"08/02/2023",
0,
True,
), # 1 assi 08/02/2023 13h > 18h (1dj) JUSTI
(
"10/02/2023",
"10/02/2023",
1,
True,
),
(
"10/02/2023",
"10/02/2023",
0,
False,
), # 1 assi 10/02/2023 08h > 18h (2dj) JUSTI
(
"13/02/2023",
"13/02/2023",
1,
False,
),
(
"13/02/2023",
"13/02/2023",
0,
True,
), # 1 assi 13/02/2023 08h > 18h (2dj) JUSTI
(
"15/02/2023",
"15/02/2023",
2,
False,
), # 1 assi 13/02/2023 08h > 18h (2dj) JUSTI(ext)
(
"22/02/2023",
"24/02/2023",
1,
False,
), # 3 assi 22-23-24/02/2023 08h > 13h (3dj) JUSTI(ext)
]:
_create_abs(
date_debut=debut,
date_fin=fin,
demijournee=demijournee,
etudid=etudid,
estjust=justifiee,
)
# --- Justification de certaines absences
for debut, fin, demijournee in [
(
"15/02/2023",
"15/02/2023",
2,
),
(
"21/02/2023",
"24/02/2023",
2,
),
]:
_create_abs(
date_debut=debut,
date_fin=fin,
demijournee=demijournee,
etudid=etudid,
estjust=True,
estabs=False,
)
migrate_abs_to_assiduites()
assert Assiduite.query.count() == 21, "Migration : Nb Assiduités FAUX"
assert Justificatif.query.count() == 9, "Migration : Nb Justificatif FAUX"
# Cas classiques sans justification
assert (
_get_assi("2023-01-02T08:00", "2023-01-02T13:00") is not None
), "Migration : Abs n°1 mal migrée"
assert (
_get_assi("2023-01-03T13:00", "2023-01-03T18:00") is not None
), "Migration : Abs n°2 mal migrée"
assert (
_get_assi("2023-01-05T08:00", "2023-01-05T18:00") is not None
), "Migration : Abs n°3 mal migrée"
assert (
_get_assi("2023-01-09T08:00", "2023-01-09T18:00") is not None
), "Migration : Abs n°4&5 mal migrée"
assert (
_get_assi("2023-01-10T13:00", "2023-01-11T13:00") is not None
), "Migration : Abs n°6&7 mal migrée"
assert (
_get_assi("2023-01-12T08:00", "2023-01-12T13:00") is not None
), "Migration : Abs n°8 mal migrée"
assert (
_get_assi("2023-01-13T08:00", "2023-01-13T13:00") is not None
), "Migration : Abs n°9 mal migrée"
assert (
_get_assi("2023-01-16T08:00", "2023-01-16T13:00") is not None
), "Migration : Abs n°10&11 mal migrée"
assert (
_get_assi("2023-01-19T08:00", "2023-01-20T18:00") is not None
), "Migration : Abs n°12 mal migrée"
assert (
_get_assi("2023-01-23T08:00", "2023-01-24T18:00") is not None
), "Migration : Abs n°12 mal migrée"
# Cas d'absences justifiées
assert (
_get_assi("2023-02-01T08:00", "2023-02-01T13:00", True) is not None
), "Migration : Abs n°13 mal migrée"
assert (
_get_assi("2023-02-02T13:00", "2023-02-02T18:00", True) is not None
), "Migration : Abs n°14 mal migrée"
assert (
_get_assi("2023-02-06T08:00", "2023-02-06T18:00", True) is not None
), "Migration : Abs n°15 mal migrée"
assert (
_get_assi("2023-02-07T13:00", "2023-02-07T18:00", True) is not None
), "Migration : Abs n°16&17 mal migrée"
assert (
_get_assi("2023-02-08T13:00", "2023-02-08T18:00", True) is not None
), "Migration : Abs n°18&19 mal migrée"
assert (
_get_assi("2023-02-10T08:00", "2023-02-10T18:00", True) is not None
), "Migration : Abs n°20&21 mal migrée"
assert (
_get_assi("2023-02-13T08:00", "2023-02-13T18:00", True) is not None
), "Migration : Abs n°22&23 mal migrée"
# Cas Justificatifs
assert (
_get_justi("2023-02-01T08:00", "2023-02-01T13:00") is not None
), "Migration : Abs n°13 mal migrée"
assert (
_get_justi("2023-02-02T13:00", "2023-02-02T18:00") is not None
), "Migration : Abs n°14 mal migrée"
assert (
_get_justi("2023-02-06T08:00", "2023-02-06T18:00") is not None
), "Migration : Abs n°15 mal migrée"
assert (
_get_justi("2023-02-07T13:00", "2023-02-07T18:00") is not None
), "Migration : Abs n°16&17 mal migrée"
assert (
_get_justi("2023-02-08T13:00", "2023-02-08T18:00") is not None
), "Migration : Abs n°18&19 mal migrée"
assert (
_get_justi("2023-02-10T08:00", "2023-02-10T18:00") is not None
), "Migration : Abs n°20&21 mal migrée"
assert (
_get_justi("2023-02-13T08:00", "2023-02-13T18:00") is not None
), "Migration : Abs n°22&23 mal migrée"
assert (
_get_justi("2023-02-15T08:00", "2023-02-15T18:00") is not None
), "Migration : Justi n°1 mal migré"
assert (
_get_assi("2023-02-15T08:00", "2023-02-15T18:00", True) is not None
), "Migration : Abs n°24 mal migrée"
assert (
_get_justi("2023-02-21T08:00", "2023-02-24T18:00") is not None
), "Migration : Justi n°2 mal migré"
assert (
_get_assi("2023-02-22T08:00", "2023-02-22T13:00", True) is not None
), "Migration : Abs n°25 mal migrée"
assert (
_get_assi("2023-02-23T08:00", "2023-02-23T13:00", True) is not None
), "Migration : Abs n°26 mal migrée"
assert (
_get_assi("2023-02-24T08:00", "2023-02-24T13:00", True) is not None
), "Migration : Abs n°27 mal migrée"
downgrade_module(assiduites=True, justificatifs=True)
def _get_assi(
deb: str,
fin: str,
est_just: bool = False,
):
deb = scu.localize_datetime(scu.is_iso_formated(deb, True))
fin = scu.localize_datetime(scu.is_iso_formated(fin, True))
return Assiduite.query.filter(
Assiduite.date_debut >= deb,
Assiduite.date_fin <= fin,
Assiduite.est_just == est_just,
).first()
def _get_justi(
deb: str,
fin: str,
):
deb = scu.localize_datetime(scu.is_iso_formated(deb, True))
fin = scu.localize_datetime(scu.is_iso_formated(fin, True))
return Justificatif.query.filter(
Justificatif.date_debut >= deb,
Justificatif.date_fin <= fin,
).first()
def ajouter_justificatifs(etud):
"""test de l'ajout des justificatifs"""
obj_justificatifs = [
{
"etat": scu.EtatJustificatif.ATTENTE,
"deb": "2022-09-05T08:00+01:00",
"fin": "2022-09-05T09:59:59+01:00",
"raison": None,
},
{
"etat": scu.EtatJustificatif.VALIDE,
"deb": "2023-01-03T07:00+01:00",
"fin": "2023-01-03T11:00+01:00",
"raison": None,
},
{
"etat": scu.EtatJustificatif.VALIDE,
"deb": "2022-09-05T10:00:00+01:00",
"fin": "2022-09-05T12:00+01:00",
"raison": None,
},
{
"etat": scu.EtatJustificatif.NON_VALIDE,
"deb": "2022-09-05T14:00:00+01:00",
"fin": "2022-09-05T15:00+01:00",
"raison": "Description",
},
{
"etat": scu.EtatJustificatif.MODIFIE,
"deb": "2023-01-03T11:30+01:00",
"fin": "2023-01-03T12:00+01:00",
"raison": None,
},
]
justificatifs = []
for just in obj_justificatifs:
just_obj = Justificatif.create_justificatif(
etud,
scu.is_iso_formated(just["deb"], True),
scu.is_iso_formated(just["fin"], True),
just["etat"],
just["raison"],
)
db.session.add(just_obj)
db.session.commit()
just_obj.justifier_assiduites()
justificatifs.append(just_obj)
# Vérification de la création des justificatifs
assert [
justi for justi in justificatifs if not isinstance(justi, Justificatif)
] == [], "La création des justificatifs de base n'est pas OK"
return justificatifs
def verifier_filtrage_justificatifs(etud: Identite, justificatifs: list[Justificatif]):
"""
- vérifier le filtrage des justificatifs (etat, debut, fin)
"""
# Vérification du filtrage classique
# Etat
assert (
scass.filter_justificatifs_by_etat(etud.justificatifs, "valide").count() == 2
), "Filtrage de l'état 'valide' mauvais"
assert (
scass.filter_justificatifs_by_etat(etud.justificatifs, "attente").count() == 1
), "Filtrage de l'état 'attente' mauvais"
assert (
scass.filter_justificatifs_by_etat(etud.justificatifs, "modifie").count() == 1
), "Filtrage de l'état 'modifie' mauvais"
assert (
scass.filter_justificatifs_by_etat(etud.justificatifs, "non_valide").count()
== 1
), "Filtrage de l'état 'non_valide' mauvais"
assert (
scass.filter_justificatifs_by_etat(etud.justificatifs, "valide,modifie").count()
== 3
), "Filtrage de l'état 'valide,modifie' mauvais"
assert (
scass.filter_justificatifs_by_etat(
etud.justificatifs, "valide,modifie,attente"
).count()
== 4
), "Filtrage de l'état 'valide,modifie,attente' mauvais"
assert (
scass.filter_justificatifs_by_etat(
etud.justificatifs, "valide,modifie,attente,non_valide"
).count()
== 5
), "Filtrage de l'état 'valide,modifie,attente,_non_valide' mauvais"
assert (
scass.filter_justificatifs_by_etat(etud.justificatifs, "autre").count() == 0
), "Filtrage de l'état 'autre' mauvais"
# Dates
assert (
scass.filter_by_date(etud.justificatifs, Justificatif).count() == 5
), "Filtrage 'Toute Date' mauvais 1"
date = scu.localize_datetime(
scu.is_iso_formated("2022-09-01T10:00+01:00", convert=True)
)
assert (
scass.filter_by_date(etud.justificatifs, Justificatif, date_deb=date).count()
== 5
), "Filtrage 'Toute Date' mauvais 2"
date = scu.localize_datetime(
scu.is_iso_formated("2022-09-05T08:00+01:00", convert=True)
)
assert (
scass.filter_by_date(etud.justificatifs, Justificatif, date_deb=date).count()
== 5
), "Filtrage 'date début' mauvais 3"
date = scu.localize_datetime(
scu.is_iso_formated("2022-09-05T08:00:01+01:00", convert=True)
)
assert (
scass.filter_by_date(etud.justificatifs, Justificatif, date_deb=date).count()
== 5
), "Filtrage 'date début' mauvais 4"
date = scu.localize_datetime(
scu.is_iso_formated("2022-09-05T10:00+01:00", convert=True)
)
assert (
scass.filter_by_date(etud.justificatifs, Justificatif, date_deb=date).count()
== 4
), "Filtrage 'date début' mauvais 5"
date = scu.localize_datetime(
scu.is_iso_formated("2022-09-01T10:00+01:00", convert=True)
)
assert (
scass.filter_by_date(etud.justificatifs, Justificatif, date_fin=date).count()
== 0
), "Filtrage 'date fin' mauvais 6"
date = scu.localize_datetime(
scu.is_iso_formated("2022-09-05T08:00+01:00", convert=True)
)
assert (
scass.filter_by_date(etud.justificatifs, Justificatif, date_fin=date).count()
== 1
), "Filtrage 'date fin' mauvais 7"
date = scu.localize_datetime(
scu.is_iso_formated("2022-09-05T10:00:01+01:00", convert=True)
)
assert (
scass.filter_by_date(etud.justificatifs, Justificatif, date_fin=date).count()
== 2
), "Filtrage 'date fin' mauvais 8"
date = scu.localize_datetime(
scu.is_iso_formated("2023-01-03T12:00+01:00", convert=True)
)
assert (
scass.filter_by_date(etud.justificatifs, Justificatif, date_fin=date).count()
== 5
), "Filtrage 'date fin' mauvais 9"
# Justifications des assiduites
assert len(scass.justifies(justificatifs[2])) == 1, "Justifications mauvais"
assert len(scass.justifies(justificatifs[0])) == 0, "Justifications mauvais"
def editer_supprimer_justificatif(etud: Identite):
"""
Troisième Partie:
- Vérification de l'édition des justificatifs
- Vérification de la suppression des justificatifs
"""
justi: Justificatif = etud.justificatifs.first()
# Modification de l'état
justi.etat = scu.EtatJustificatif.MODIFIE
# Modification du moduleimpl
justi.date_debut = scu.localize_datetime(
scu.is_iso_formated("2023-02-03T11:00:01+01:00", convert=True)
)
justi.date_fin = scu.localize_datetime(
scu.is_iso_formated("2023-02-03T12:00:01+01:00", convert=True)
)
db.session.add(justi)
db.session.commit()
# Vérification du changement
assert (
scass.filter_justificatifs_by_etat(etud.justificatifs, "modifie").count() == 2
), "Edition de justificatif mauvais"
assert (
scass.filter_by_date(
etud.justificatifs,
Justificatif,
date_deb=scu.localize_datetime(
scu.is_iso_formated("2023-02-01T11:00:00+01:00", convert=True)
),
).count()
== 1
), "Edition de justificatif mauvais 2"
# Supression d'une assiduité
db.session.delete(justi)
db.session.commit()
assert etud.justificatifs.count() == 4, "Supression de justificatif mauvais"
def editer_supprimer_assiduites(etuds: list[Identite], moduleimpls: list[int]):
"""
Troisième Partie:
- Vérification de l'édition des assiduitées
- Vérification de la suppression des assiduitées
"""
ass1: Assiduite = etuds[0].assiduites.first()
ass2: Assiduite = etuds[1].assiduites.first()
ass3: Assiduite = etuds[2].assiduites.first()
# Modification de l'état
ass1.etat = scu.EtatAssiduite.RETARD
db.session.add(ass1)
# Modification du moduleimpl
ass2.moduleimpl_id = moduleimpls[0].id
db.session.add(ass2)
db.session.commit()
# Vérification du changement
assert (
scass.filter_assiduites_by_etat(etuds[0].assiduites, "retard").count() == 4
), "Edition d'assiduité mauvais"
assert (
scass.filter_by_module_impl(etuds[1].assiduites, moduleimpls[0].id).count() == 2
), "Edition d'assiduité mauvais"
# Supression d'une assiduité
db.session.delete(ass3)
db.session.commit()
assert etuds[2].assiduites.count() == 6, "Supression d'assiduité mauvais"
def ajouter_assiduites(
etuds: list[Identite], moduleimpls: list[ModuleImpl], etud_faux: Identite
):
"""
Première partie:
- Ajoute 6 assiduités à chaque étudiant
- 2 présence (semestre 1 et 2)
- 2 retard (semestre 2)
- 2 absence (semestre 1)
- Vérifie la création des assiduités
"""
for etud in etuds:
obj_assiduites = [
{
"etat": scu.EtatAssiduite.PRESENT,
"deb": "2022-09-05T08:00+01:00",
"fin": "2022-09-05T10:00+01:00",
"moduleimpl": None,
"desc": None,
},
{
"etat": scu.EtatAssiduite.PRESENT,
"deb": "2023-01-03T08:00+01:00",
"fin": "2023-01-03T10:00+01:00",
"moduleimpl": moduleimpls[2],
"desc": None,
},
{
"etat": scu.EtatAssiduite.ABSENT,
"deb": "2022-09-05T10:00:01+01:00",
"fin": "2022-09-05T11:00+01:00",
"moduleimpl": moduleimpls[0],
"desc": None,
},
{
"etat": scu.EtatAssiduite.ABSENT,
"deb": "2022-09-05T14:00:00+01:00",
"fin": "2022-09-05T15:00+01:00",
"moduleimpl": moduleimpls[1],
"desc": "Description",
},
{
"etat": scu.EtatAssiduite.RETARD,
"deb": "2023-01-03T11:00:01+01:00",
"fin": "2023-01-03T12:00+01:00",
"moduleimpl": moduleimpls[3],
"desc": None,
},
{
"etat": scu.EtatAssiduite.RETARD,
"deb": "2023-01-04T11:00:01+01:00",
"fin": "2023-01-04T12:00+01:00",
"moduleimpl": moduleimpls[3],
"desc": "Description",
},
{
"etat": scu.EtatAssiduite.RETARD,
"deb": "2022-11-04T11:00:01+01:00",
"fin": "2022-12-05T12:00+01:00",
"moduleimpl": None,
"desc": "Description",
},
]
assiduites = []
for ass in obj_assiduites:
ass_obj = Assiduite.create_assiduite(
etud,
scu.is_iso_formated(ass["deb"], True),
scu.is_iso_formated(ass["fin"], True),
ass["etat"],
ass["moduleimpl"],
ass["desc"],
)
assiduites.append(ass_obj)
db.session.add(ass_obj)
db.session.commit()
# Vérification de la création des assiduités
assert [
ass for ass in assiduites if not isinstance(ass, Assiduite)
] == [], "La création des assiduités de base n'est pas OK"
# Vérification de la gestion des erreurs
test_assiduite = {
"etat": scu.EtatAssiduite.RETARD,
"deb": "2023-01-04T11:00:01+01:00",
"fin": "2023-01-04T12:00+01:00",
"moduleimpl": moduleimpls[3],
"desc": "Description",
}
try:
Assiduite.create_assiduite(
etuds[0],
scu.is_iso_formated(test_assiduite["deb"], True),
scu.is_iso_formated(test_assiduite["fin"], True),
test_assiduite["etat"],
test_assiduite["moduleimpl"],
test_assiduite["desc"],
)
except ScoValueError as excp:
assert (
excp.args[0]
== "Duplication: la période rentre en conflit avec une plage enregistrée"
)
try:
test_assiduite2 = {
"etat": scu.EtatAssiduite.RETARD,
"deb": "2022-09-03T11:00:01+01:00",
"fin": "2022-09-03T12:00+01:00",
"moduleimpl": moduleimpls[3],
"desc": "Description",
}
Assiduite.create_assiduite(
etuds[0],
scu.is_iso_formated(test_assiduite2["deb"], True),
scu.is_iso_formated(test_assiduite2["fin"], True),
test_assiduite2["etat"],
test_assiduite2["moduleimpl"],
test_assiduite2["desc"],
)
except ScoValueError as excp:
assert excp.args[0] == "La date de début n'est pas un jour travaillé"
try:
test_assiduite2 = {
"etat": scu.EtatAssiduite.RETARD,
"deb": "2022-09-02T11:00:01+01:00",
"fin": "2022-09-03T12:00+01:00",
"moduleimpl": moduleimpls[3],
"desc": "Description",
}
Assiduite.create_assiduite(
etuds[0],
scu.is_iso_formated(test_assiduite2["deb"], True),
scu.is_iso_formated(test_assiduite2["fin"], True),
test_assiduite2["etat"],
test_assiduite2["moduleimpl"],
test_assiduite2["desc"],
)
except ScoValueError as excp:
assert excp.args[0] == "La date de fin n'est pas un jour travaillé"
try:
Assiduite.create_assiduite(
etud_faux,
scu.is_iso_formated(test_assiduite["deb"], True),
scu.is_iso_formated(test_assiduite["fin"], True),
test_assiduite["etat"],
test_assiduite["moduleimpl"],
test_assiduite["desc"],
)
except ScoValueError as excp:
assert excp.args[0] == "L'étudiant n'est pas inscrit au module"
def verifier_comptage_et_filtrage_assiduites(
etuds: list[Identite], moduleimpls: list[int], formsemestres: tuple[FormSemestre]
):
"""
Deuxième partie:
- vérifier les valeurs du comptage (compte, heure, journée, demi-journée)
- vérifier le filtrage des assiduites (etat, debut, fin, module, formsemestre)
"""
etu1, etu2, etu3 = etuds
mod11, mod12, mod21, mod22 = moduleimpls
# Vérification du filtrage classique
# Etat
assert (
scass.filter_assiduites_by_etat(etu2.assiduites, "present").count() == 2
), "Filtrage de l'état 'présent' mauvais"
assert (
scass.filter_assiduites_by_etat(etu2.assiduites, "retard").count() == 3
), "Filtrage de l'état 'retard' mauvais"
assert (
scass.filter_assiduites_by_etat(etu2.assiduites, "absent").count() == 2
), "Filtrage de l'état 'absent' mauvais"
assert (
scass.filter_assiduites_by_etat(etu2.assiduites, "absent,retard").count() == 5
), "Filtrage de l'état 'absent,retard' mauvais"
assert (
scass.filter_assiduites_by_etat(
etu2.assiduites, "absent,retard,present"
).count()
== 7
), "Filtrage de l'état 'absent,retard,present' mauvais"
assert (
scass.filter_assiduites_by_etat(etu2.assiduites, "autre").count() == 0
), "Filtrage de l'état 'autre' mauvais"
# Module
assert (
scass.filter_by_module_impl(etu3.assiduites, mod11.id).count() == 1
), "Filtrage par 'Moduleimpl' mauvais"
assert (
scass.filter_by_module_impl(etu3.assiduites, mod12.id).count() == 1
), "Filtrage par 'Moduleimpl' mauvais"
assert (
scass.filter_by_module_impl(etu3.assiduites, mod21.id).count() == 1
), "Filtrage par 'Moduleimpl' mauvais"
assert (
scass.filter_by_module_impl(etu3.assiduites, mod22.id).count() == 2
), "Filtrage par 'Moduleimpl' mauvais"
assert (
scass.filter_by_module_impl(etu3.assiduites, None).count() == 2
), "Filtrage par 'Moduleimpl' mauvais"
assert (
scass.filter_by_module_impl(etu3.assiduites, 152).count() == 0
), "Filtrage par 'Moduleimpl' mauvais"
# Formsemestre
assert (
scass.filter_by_formsemestre(
etu1.assiduites, Assiduite, formsemestres[0]
).count()
== 4
), "Filtrage 'Formsemestre' mauvais"
assert (
scass.filter_by_formsemestre(
etu1.assiduites, Assiduite, formsemestres[1]
).count()
== 3
), "Filtrage 'Formsemestre' mauvais"
assert (
scass.filter_by_formsemestre(
etu1.assiduites, Assiduite, formsemestres[2]
).count()
== 0
), "Filtrage 'Formsemestre' mauvais"
# Date début
assert (
scass.filter_by_date(etu2.assiduites, Assiduite).count() == 7
), "Filtrage 'Date début' mauvais 1"
date = scu.localize_datetime(
scu.is_iso_formated("2022-09-01T10:00+01:00", convert=True)
)
assert (
scass.filter_by_date(etu2.assiduites, Assiduite, date_deb=date).count() == 7
), "Filtrage 'Date début' mauvais 2"
date = scu.localize_datetime(
scu.is_iso_formated("2022-09-05T10:00+01:00", convert=True)
)
assert (
scass.filter_by_date(etu2.assiduites, Assiduite, date_deb=date).count() == 7
), "Filtrage 'Date début' mauvais 3"
date = scu.localize_datetime(
scu.is_iso_formated("2022-09-05T16:00+01:00", convert=True)
)
assert (
scass.filter_by_date(etu2.assiduites, Assiduite, date_deb=date).count() == 4
), "Filtrage 'Date début' mauvais 4"
# Date Fin
date = scu.localize_datetime(
scu.is_iso_formated("2022-09-01T10:00+01:00", convert=True)
)
assert (
scass.filter_by_date(etu2.assiduites, Assiduite, date_fin=date).count() == 0
), "Filtrage 'Date fin' mauvais 1"
date = scu.localize_datetime(
scu.is_iso_formated("2022-09-05T10:00+01:00", convert=True)
)
assert (
scass.filter_by_date(etu2.assiduites, Assiduite, date_fin=date).count() == 1
), "Filtrage 'Date fin' mauvais 2"
date = scu.localize_datetime(
scu.is_iso_formated("2022-09-05T10:00:01+01:00", convert=True)
)
assert (
scass.filter_by_date(etu2.assiduites, Assiduite, date_fin=date).count() == 2
), "Filtrage 'Date fin' mauvais 3"
date = scu.localize_datetime(
scu.is_iso_formated("2022-09-05T16:00+01:00", convert=True)
)
assert (
scass.filter_by_date(etu2.assiduites, Assiduite, date_fin=date).count() == 3
), "Filtrage 'Date fin' mauvais 4"
date = scu.localize_datetime(
scu.is_iso_formated("2023-01-04T16:00+01:00", convert=True)
)
assert (
scass.filter_by_date(etu2.assiduites, Assiduite, date_fin=date).count() == 7
), "Filtrage 'Date fin' mauvais 5"
def _create_abs(
date_debut, date_fin, demijournee, estjust=False, etudid=False, estabs=True
):
etud = Identite.from_request(etudid)
deb: dt.date = dt.datetime.strptime(date_debut, scu.DATE_FMT).date()
fin: dt.date = dt.datetime.strptime(date_fin, scu.DATE_FMT).date()
abs_list: list[Absence] = []
while deb < fin:
if deb.weekday() in [5, 6]:
deb += dt.timedelta(days=1)
continue
if demijournee == 2:
abs_list.append(
Absence(
etudid=etud.id,
jour=deb.isoformat(),
estabs=estabs,
estjust=estjust,
matin=True,
)
)
abs_list.append(
Absence(
etudid=etud.id,
jour=deb.isoformat(),
estabs=estabs,
estjust=estjust,
matin=False,
)
)
else:
abs_list.append(
Absence(
etudid=etud.id,
jour=deb.isoformat(),
estabs=estabs,
estjust=estjust,
matin=demijournee,
)
)
log(
f"create_abs [{etudid}, {deb.isoformat()}, {estabs}, {estjust}, {['aprem', 'matin', 'journee'][demijournee]}]"
)
deb += dt.timedelta(days=1)
if deb == fin and deb.weekday() not in [5, 6]:
if demijournee == 2:
abs_list.append(
Absence(
etudid=etud.id,
jour=deb.isoformat(),
estabs=estabs,
estjust=estjust,
matin=True,
)
)
abs_list.append(
Absence(
etudid=etud.id,
jour=deb.isoformat(),
estabs=estabs,
estjust=estjust,
matin=False,
)
)
else:
abs_list.append(
Absence(
etudid=etud.id,
jour=deb.isoformat(),
estabs=estabs,
estjust=estjust,
matin=demijournee,
)
)
log(
f"create_abs [{etudid}, {deb.isoformat()}, {estabs}, {estjust}, {['aprem', 'matin', 'journee'][demijournee]}]"
)
db.session.add_all(abs_list)
db.session.commit()
def _setup_fake_db(
dates_formsemestre: list[tuple[str, str]],
nb_modules: int = 0,
nb_etuds: int = 1,
) -> dict:
g_fake = sco_fake_gen.ScoFake(verbose=False)
# Création d'une formation
formation_id = g_fake.create_formation()
ue_id = g_fake.create_ue(
formation_id=formation_id, acronyme="T1", titre="UE TEST 1"
)
matiere_id = g_fake.create_matiere(ue_id=ue_id, titre="test matière")
module_ids: list[int] = [
g_fake.create_module(
matiere_id=matiere_id,
code=f"Mo{i}",
coefficient=1.0,
titre=f"test module{i}",
)
for i in range(nb_modules)
]
# Création semestre
formsemestre_ids: list[int] = [
g_fake.create_formsemestre(
formation_id=formation_id,
semestre_id=1,
date_debut=deb,
date_fin=fin,
)
for deb, fin in dates_formsemestre
]
formsemestres: list[FormSemestre] = list(
map(FormSemestre.get_formsemestre, formsemestre_ids)
)
# Création des modulesimpls (2 par semestre)
moduleimpls: list[int] = []
for i in range(len(dates_formsemestre)):
for j in range(nb_modules):
mod, form = module_ids[j], formsemestres[i]
moduleimpl_id: int = g_fake.create_moduleimpl(
module_id=mod,
formsemestre_id=form.id,
)
moduleimpls.append(ModuleImpl.query.filter_by(id=moduleimpl_id).first())
# Création de x étudiants
etuds_dict: list[dict] = [
g_fake.create_etud(prenom=f"etud{i}") for i in range(nb_etuds)
]
etuds = []
for etud in etuds_dict:
for form_id in formsemestre_ids:
g_fake.inscrit_etudiant(formsemestre_id=form_id, etud=etud)
etuds.append(Identite.query.filter_by(id=etud["etudid"]).first())
# Etudiant faux
etud_faux_dict = g_fake.create_etud(prenom="etudfaux")
etud_faux = Identite.query.filter_by(id=etud_faux_dict["etudid"]).first()
return {
"moduleimpls": moduleimpls,
"formsemestres": formsemestres,
"etuds": etuds,
"etud_faux": etud_faux,
"g_fake": g_fake,
}
def test_calcul_assiduites(test_client):
"""Vérification du bon calcul des assiduités"""
data: dict = _setup_fake_db([("01/12/2023", "31/12/2023")])
formsemestre: FormSemestre = data["formsemestres"][0]
etud: Identite = data["etuds"][0]
"""
Exemple tuple:
(
"12-04T08:00", # Date de début
"12-04T09:00", # Date de fin
scu.EtatAssiduite.ABSENT, # Etat
False # est_just
)
"""
assiduites: list[tuple] = [
# Journée du 04/12
(
"12-04T08:00",
"12-04T10:00",
scu.EtatAssiduite.ABSENT,
False,
),
(
"12-04T10:15",
"12-04T12:15",
scu.EtatAssiduite.RETARD,
False,
),
(
"12-04T13:15",
"12-04T15:15",
scu.EtatAssiduite.PRESENT,
False,
),
(
"12-04T15:15",
"12-04T17:00",
scu.EtatAssiduite.ABSENT,
True,
),
# 05/12
(
"12-05T08:00",
"12-05T09:00",
scu.EtatAssiduite.RETARD,
True,
),
(
"12-05T09:00",
"12-05T10:00",
scu.EtatAssiduite.PRESENT,
False,
),
(
"12-05T10:15",
"12-05T12:15",
scu.EtatAssiduite.PRESENT,
False,
),
(
"12-05T13:15",
"12-05T14:30",
scu.EtatAssiduite.ABSENT,
False,
),
(
"12-05T14:30",
"12-05T16:30",
scu.EtatAssiduite.RETARD,
False,
),
(
"12-05T16:30",
"12-05T17:00",
scu.EtatAssiduite.PRESENT,
False,
),
# 06/12
(
"12-06T08:00",
"12-06T10:00",
scu.EtatAssiduite.PRESENT,
False,
),
(
"12-06T10:15",
"12-06T12:15",
scu.EtatAssiduite.RETARD,
False,
),
(
"12-06T13:15",
"12-06T13:45",
scu.EtatAssiduite.ABSENT,
True,
),
(
"12-06T13:45",
"12-06T15:00",
scu.EtatAssiduite.PRESENT,
False,
),
(
"12-06T15:00",
"12-06T17:00",
scu.EtatAssiduite.RETARD,
False,
),
# 07/12
(
"12-07T08:00",
"12-07T08:30",
scu.EtatAssiduite.RETARD,
True,
),
(
"12-07T08:30",
"12-07T10:00",
scu.EtatAssiduite.PRESENT,
False,
),
(
"12-07T10:15",
"12-07T12:15",
scu.EtatAssiduite.ABSENT,
True,
),
# 08/12
(
"12-08T08:00",
"12-08T10:00",
scu.EtatAssiduite.PRESENT,
False,
),
(
"12-08T10:15",
"12-08T12:15",
scu.EtatAssiduite.ABSENT,
False,
),
(
"12-08T13:15",
"12-08T14:15",
scu.EtatAssiduite.RETARD,
True,
),
(
"12-08T14:15",
"12-08T15:15",
scu.EtatAssiduite.PRESENT,
False,
),
(
"12-08T15:15",
"12-08T17:00",
scu.EtatAssiduite.ABSENT,
False,
),
# 11/12 -> 15/12
(
"12-11T08:00",
"12-15T17:00",
scu.EtatAssiduite.ABSENT,
False,
),
# 18/12
(
"12-18T08:00",
"12-18T10:00",
scu.EtatAssiduite.ABSENT,
False,
),
(
"12-18T10:00",
"12-18T12:00",
scu.EtatAssiduite.ABSENT,
False,
),
]
for ass in assiduites:
ass_obj = Assiduite.create_assiduite(
etud=etud,
date_debut=scu.is_iso_formated("2023-" + ass[0], True),
date_fin=scu.is_iso_formated("2023-" + ass[1], True),
etat=ass[2],
est_just=ass[3],
)
db.session.add(ass_obj)
db.session.commit()
calculator = scass.CountCalculator(
morning="08:00", noon="12:15", evening="17:00", nb_heures_par_jour=8
)
calculator.compute_assiduites(etud.assiduites)
result: dict = calculator.to_dict(only_total=False)
# Résultat attendu :
# (les additions dans les absences corresponde à (compte_assiduite + compte_assiduite_longue))
resultat_attendu: dict = {
"present": {"journee": 5, "demi": 8, "heure": 13.25, "compte": 9},
"absent": {
"journee": 6 + 5,
"demi": 8 + 10,
"heure": 15.25 + 42,
"compte": 9 + 1,
},
"absent_just": {"journee": 3, "demi": 3, "heure": 4.25, "compte": 3},
"absent_non_just": {
"journee": 4 + 5,
"demi": 5 + 10,
"heure": 11 + 42,
"compte": 6 + 1,
},
"retard": {
"journee": 5,
"demi": 7,
"heure": 10.5,
"compte": 7,
},
"retard_just": {"journee": 3, "demi": 3, "heure": 2.5, "compte": 3},
"retard_non_just": {"journee": 3, "demi": 4, "heure": 8.0, "compte": 4},
"total": {"journee": 11, "demi": 20, "heure": 81.0, "compte": 26},
}
for key, value in resultat_attendu.items():
assert value["journee"] * 2 >= value["demi"], f"Trop de demi-journées [{key}]"
for key, value in resultat_attendu.items():
for key2, value2 in value.items():
assert (
result[key][key2] == value2
), f"Le calcul [{key}][{key2}] est faux (attendu > {value2}{result[key][key2]} < obtenu)"
def test_cas_justificatifs(test_client):
"""
Tests de certains cas particuliers des justificatifs
- Création du justificatif avant ou après assiduité
- Assiduité complétement couverte ou non
- Modification de la couverture (edition du justificatif)
"""
data = _setup_fake_db(
[("2024-01-01", "2024-06-30")],
0,
1,
)
# <- Vérification justification si justif créé avant assi ->
# Période : 8h -> 10h le 01/01/2024
etud_1: Identite = data["etuds"][0]
justif_1: Justificatif = Justificatif.create_justificatif(
etudiant=etud_1,
date_debut=scu.is_iso_formated("2024-01-01T08:00:00+01:00", True),
date_fin=scu.is_iso_formated("2024-01-01T10:00:00+01:00", True),
etat=scu.EtatJustificatif.VALIDE,
)
assi_1: Assiduite = Assiduite.create_assiduite(
etud=etud_1,
date_debut=scu.is_iso_formated("2024-01-01T08:00:00+01:00", True),
date_fin=scu.is_iso_formated("2024-01-01T10:00:00+01:00", True),
etat=scu.EtatAssiduite.ABSENT,
)
assert assi_1.est_just is True, "Justification non prise en compte (a1)"
assert len(scass.justifies(justif_1)) == 1, "Justification non prise en compte (a2)"
# <- Vérification justification si justif créé après assi ->
# Période : 8h -> 10h le 02/01/2024
Assiduite.create_assiduite(
etud=etud_1,
date_debut=scu.is_iso_formated("2024-01-02T08:00:00+01:00", True),
date_fin=scu.is_iso_formated("2024-01-02T10:00:00+01:00", True),
etat=scu.EtatAssiduite.ABSENT,
)
justif_2: Justificatif = Justificatif.create_justificatif(
etudiant=etud_1,
date_debut=scu.is_iso_formated("2024-01-02T08:00:00+01:00", True),
date_fin=scu.is_iso_formated("2024-01-02T10:00:00+01:00", True),
etat=scu.EtatJustificatif.VALIDE,
)
justif_2.justifier_assiduites()
assert len(scass.justifies(justif_2)) == 1, "Justification non prise en compte (b1)"
# Ne fonctionne pas ⬇️
# assert assi_2.est_just is True, "Justification non prise en compte (b2)"
# <- Vérification assiduité complétement couverte ->
# Période : 12h -> 19h le 03/01/2024
Assiduite.create_assiduite(
etud=etud_1,
date_debut=scu.is_iso_formated("2024-01-03T12:00:00+01:00", True),
date_fin=scu.is_iso_formated("2024-01-03T19:00:00+01:00", True),
etat=scu.EtatAssiduite.ABSENT,
)
# Justification complète
justif_3: Justificatif = Justificatif.create_justificatif(
etudiant=etud_1,
date_debut=scu.is_iso_formated("2024-01-03T00:00:00", True),
date_fin=scu.is_iso_formated("2024-01-03T23:59:59", True),
etat=scu.EtatJustificatif.VALIDE,
)
# Justification incomplète
justif_4: Justificatif = Justificatif.create_justificatif(
etudiant=etud_1,
date_debut=scu.is_iso_formated("2024-01-03T08:00:00", True),
date_fin=scu.is_iso_formated("2024-01-03T18:00:00", True),
etat=scu.EtatJustificatif.VALIDE,
)
# Mise à jour de l'assiduité
justif_3.justifier_assiduites()
justif_4.justifier_assiduites()
assert (
len(scass.justifies(justif_3)) == 1
), "Justification complète non prise en compte (c1)"
assert (
len(scass.justifies(justif_4)) == 0
), "Justification complète non prise en compte (c2)"
# <- Vérification modification de la couverture ->
# Deux assiduités, 8/01/2024 de 8h à 10h et 14h à 16h
assi_2: Assiduite = Assiduite.create_assiduite(
etud=etud_1,
date_debut=scu.is_iso_formated("2024-01-08T08:00", True),
date_fin=scu.is_iso_formated("2024-01-08T10:00", True),
etat=scu.EtatAssiduite.ABSENT,
)
assi_3: Assiduite = Assiduite.create_assiduite(
etud=etud_1,
date_debut=scu.is_iso_formated("2024-01-08T14:00", True),
date_fin=scu.is_iso_formated("2024-01-08T16:00", True),
etat=scu.EtatAssiduite.ABSENT,
)
# <=>Justification complète<=>
# les deux assiduités sont couvertes
justif_5: Justificatif = Justificatif.create_justificatif(
etudiant=etud_1,
date_debut=scu.is_iso_formated("2024-01-08T00:00:00", True),
date_fin=scu.is_iso_formated("2024-01-08T23:59:59", True),
etat=scu.EtatJustificatif.VALIDE,
)
# Justification des assiduités
assi_ids: list[int] = justif_5.justifier_assiduites()
assert len(assi_ids) == 2, "Vérification Modification couverture (d1)"
assert assi_2.assiduite_id in assi_ids, "Vérification Modification couverture (d2)"
assert assi_3.assiduite_id in assi_ids, "Vérification Modification couverture (d3)"
assert assi_2.est_just is True, "Vérification Modification couverture (d4)"
assert assi_3.est_just is True, "Vérification Modification couverture (d5)"
# Déjustification des assiduités
justif_5.dejustifier_assiduites()
assi_ids: list[int] = justif_5.dejustifier_assiduites()
assert len(assi_ids) == 2, "Vérification Modification couverture (d6)"
assert assi_2.assiduite_id in assi_ids, "Vérification Modification couverture (d7)"
assert assi_3.assiduite_id in assi_ids, "Vérification Modification couverture (d8)"
assert assi_2.est_just is False, "Vérification Modification couverture (d9)"
assert assi_3.est_just is False, "Vérification Modification couverture (d10)"
# <=>Justification Partielle<=>
# Seule la première assiduité est couverte
justif_5.date_fin = scu.is_iso_formated("2024-01-08T11:00", True)
db.session.add(justif_5)
db.session.commit()
assi_ids: list[int] = justif_5.justifier_assiduites()
assert len(assi_ids) == 1, "Vérification Modification couverture (e1)"
assert assi_2.assiduite_id in assi_ids, "Vérification Modification couverture (e2)"
assert (
assi_3.assiduite_id not in assi_ids
), "Vérification Modification couverture (e3)"
assert assi_2.est_just is True, "Vérification Modification couverture (e4)"
assert assi_3.est_just is False, "Vérification Modification couverture (e5)"
assi_ids: list[int] = justif_5.dejustifier_assiduites()
assert len(assi_ids) == 1, "Vérification Modification couverture (e6)"
assert assi_2.assiduite_id in assi_ids, "Vérification Modification couverture (e7)"
assert (
assi_3.assiduite_id not in assi_ids
), "Vérification Modification couverture (e3)"
assert assi_2.est_just is False, "Vérification Modification couverture (e8)"
assert assi_3.est_just is False, "Vérification Modification couverture (e9)"
# <=>Justification Multiple<=>
# Deux justificatifs couvrent une même assiduité
# on justifie la première assiduité avec le premier justificatif
justif_5.justifier_assiduites()
# deuxième justificatif
justif_6: Justificatif = Justificatif.create_justificatif(
etudiant=etud_1,
date_debut=scu.is_iso_formated("2024-01-08T08:00", True),
date_fin=scu.is_iso_formated("2024-01-08T10:00", True),
etat=scu.EtatJustificatif.VALIDE,
)
assi_ids: list[int] = justif_6.justifier_assiduites()
assert len(assi_ids) == 1, "Vérification Modification couverture (f1)"
assert assi_2.assiduite_id in assi_ids, "Vérification Modification couverture (f2)"
assert (
assi_3.assiduite_id not in assi_ids
), "Vérification Modification couverture (f3)"
assert assi_2.est_just is True, "Vérification Modification couverture (f4)"
assert assi_3.est_just is False, "Vérification Modification couverture (f5)"
# on déjustifie le justificatif 5
justif_5.etat = scu.EtatJustificatif.NON_VALIDE
db.session.add(justif_5)
db.session.commit()
assi_ids: list[int] = justif_5.dejustifier_assiduites()
assert len(assi_ids) == 0, "Vérification Modification couverture (f6)"
assert (
assi_2.assiduite_id not in assi_ids
), "Vérification Modification couverture (f7)"
assert assi_2.est_just is True, "Vérification Modification couverture (f8)"
# on déjustifie le justificatif 6
justif_6.etat = scu.EtatJustificatif.NON_VALIDE
db.session.add(justif_6)
db.session.commit()
assi_ids: list[int] = justif_6.dejustifier_assiduites()
assert len(assi_ids) == 1, "Vérification Modification couverture (f9)"
assert assi_2.assiduite_id in assi_ids, "Vérification Modification couverture (f10)"
assert assi_2.est_just is False, "Vérification Modification couverture (f11)"
# <=>Justification Chevauchée<=>
# 1 justificatif chevauche une assiduité (8h -> 10h) (9h -> 11h)
justif_7: Justificatif = Justificatif.create_justificatif(
etudiant=etud_1,
date_debut=scu.is_iso_formated("2024-01-08T09:00", True),
date_fin=scu.is_iso_formated("2024-01-08T11:00", True),
etat=scu.EtatJustificatif.VALIDE,
)
assi_ids: list[int] = justif_7.justifier_assiduites()
assert len(assi_ids) == 0, "Vérification Modification couverture (g1)"
assert (
assi_2.assiduite_id not in assi_ids
), "Vérification Modification couverture (g2)"
assert assi_2.est_just is False, "Vérification Modification couverture (g3)"
# Modification pour correspondre à l'assiduité
justif_7.date_debut = scu.is_iso_formated("2024-01-08T08:00", True)
db.session.add(justif_7)
db.session.commit()
assi_ids: list[int] = justif_7.justifier_assiduites()
assert len(assi_ids) == 1, "Vérification Modification couverture (g4)"
assert assi_2.assiduite_id in assi_ids, "Vérification Modification couverture (g5)"
assert assi_2.est_just is True, "Vérification Modification couverture (g6)"
def test_cache_assiduites(test_client):
"""Vérification du bon fonctionnement du cache des assiduités"""
data = _setup_fake_db(
[("2024-01-01", "2024-06-30"), ("2024-07-01", "2024-12-31")],
1,
1,
)
formsemestre1: FormSemestre = data["formsemestres"][0]
formsemestre2: FormSemestre = data["formsemestres"][1]
moduleimpl: ModuleImpl = data["moduleimpls"][0]
etud: Identite = data["etuds"][0]
# Création des assiduités
assiduites: list[dict] = [
# Semestre 1
{
"date_debut": "2024-01-08T08:00",
"date_fin": "2024-01-08T10:00",
"moduleimpl": moduleimpl,
},
{
"date_debut": "2024-01-08T14:00",
"date_fin": "2024-01-08T16:00",
"moduleimpl": moduleimpl,
},
{
"date_debut": "2024-01-09T08:00",
"date_fin": "2024-01-09T10:00",
"moduleimpl": None,
},
{
"date_debut": "2024-01-09T14:00",
"date_fin": "2024-01-09T16:00",
"moduleimpl": None,
},
{
"date_debut": "2024-01-10T08:00",
"date_fin": "2024-01-10T10:00",
"moduleimpl": None,
},
{
"date_debut": "2024-01-10T14:00",
"date_fin": "2024-01-10T16:00",
"moduleimpl": moduleimpl,
},
# Semestre 2
{
"date_debut": "2024-07-09T14:00",
"date_fin": "2024-07-09T16:00",
"moduleimpl": None,
},
{
"date_debut": "2024-07-10T08:00",
"date_fin": "2024-07-10T10:00",
"moduleimpl": None,
},
{
"date_debut": "2024-07-10T14:00",
"date_fin": "2024-07-10T16:00",
"moduleimpl": None,
},
]
justificatifs: list[dict] = [
{
"date_debut": "2024-01-10T00:00",
"date_fin": "2024-01-10T23:59",
},
{
"date_debut": "2024-07-09T00:00",
"date_fin": "2024-07-09T23:59",
},
]
# On ajoute les assiduités et les justificatifs
for assi in assiduites:
Assiduite.create_assiduite(
etud=etud,
date_debut=scu.is_iso_formated(assi["date_debut"], True),
date_fin=scu.is_iso_formated(assi["date_fin"], True),
moduleimpl=assi["moduleimpl"],
etat=scu.EtatAssiduite.ABSENT,
)
for justi in justificatifs:
Justificatif.create_justificatif(
etudiant=etud,
date_debut=scu.is_iso_formated(justi["date_debut"], True),
date_fin=scu.is_iso_formated(justi["date_fin"], True),
etat=scu.EtatJustificatif.VALIDE,
).justifier_assiduites()
# Premier semestre 4nj / 2j / 6t
assert scass.get_assiduites_count(etud.id, formsemestre1.to_dict()) == (4, 2, 6)
assert scass.formsemestre_get_assiduites_count(etud.id, formsemestre1) == (4, 2, 6)
# ModuleImpl 2nj / 1j / 3t
assert scass.formsemestre_get_assiduites_count(
etud.id, formsemestre1, moduleimpl.id
) == (2, 1, 3)
# Deuxième semestre 2nj / 1j / 3t
assert scass.get_assiduites_count(etud.id, formsemestre2.to_dict()) == (2, 1, 3)
# On supprime la première assiduité (sans invalider le cache)
assi: Assiduite = Assiduite.query.filter_by(etudid=etud.id).first()
db.session.delete(assi)
db.session.commit()
# Premier semestre 4nj / 2j / 6t (Identique car cache)
assert scass.get_assiduites_count(etud.id, formsemestre1.to_dict()) == (4, 2, 6)
assert scass.formsemestre_get_assiduites_count(etud.id, formsemestre1) == (4, 2, 6)
# ModuleImpl 1nj / 1j / 2t (Change car non cache)
assert scass.formsemestre_get_assiduites_count(
etud.id, formsemestre1, moduleimpl.id
) == (1, 1, 2)
# Deuxième semestre 2nj / 1j / 3t (Identique car cache et non modifié)
assert scass.get_assiduites_count(etud.id, formsemestre2.to_dict()) == (2, 1, 3)
# On invalide maintenant le cache
scass.invalidate_assiduites_count(etud.id, formsemestre1.to_dict())
# Premier semestre 3nj / 2j / 5t (Change car cache invalidé)
assert scass.get_assiduites_count(etud.id, formsemestre1.to_dict()) == (3, 2, 5)
assert scass.formsemestre_get_assiduites_count(etud.id, formsemestre1) == (3, 2, 5)
# ModuleImpl 1nj / 1j / 2t (Ne change pas car pas de changement)
assert scass.formsemestre_get_assiduites_count(
etud.id, formsemestre1, moduleimpl.id
) == (1, 1, 2)
# Deuxième semestre 2nj / 1j / 3t (Identique car cache et non modifié)
assert scass.get_assiduites_count(etud.id, formsemestre2.to_dict()) == (2, 1, 3)
def test_recuperation_evaluations(test_client):
"""
Vérification du bon fonctionnement de la récupération des assiduités d'une évaluation
et de la récupération de l'assiduité aux évaluations d'un étudiant
"""
data = _setup_fake_db(
[("2024-01-01", "2024-06-30")],
1,
1,
)
moduleimpl: ModuleImpl = data["moduleimpls"][0]
etud: Identite = data["etuds"][0]
# Création d'assiduités pour tester les évaluations
assiduites_dates = [
"2024-01-01",
"2024-01-02",
"2024-01-03",
]
assiduites = []
for assi in assiduites_dates:
assiduites.append(
Assiduite.create_assiduite(
etud=etud,
date_debut=scu.is_iso_formated(assi + "T10:00", True),
date_fin=scu.is_iso_formated(assi + "T12:00", True),
etat=scu.EtatAssiduite.ABSENT,
)
)
# On génère une évaluation sans date
# elle devrait renvoyer une liste vide
evaluation_1: Evaluation = Evaluation.create(
moduleimpl=moduleimpl,
)
assert scass.get_evaluation_assiduites(evaluation_1) == []
# On génère une évaluation le 01/01/24 de 10h à 12h
evaluation_2: Evaluation = Evaluation.create(
moduleimpl=moduleimpl,
date_debut=scu.is_iso_formated("2024-01-01T10:00", True),
date_fin=scu.is_iso_formated("2024-01-01T12:00", True),
)
query: Query = scass.get_evaluation_assiduites(evaluation_2)
assert isinstance(query, Query), "Erreur, la fonction ne renvoie pas une Query"
# On vérifie le contenu de la query
# Cette query devrait contenir que la première assiduité
assert (
query.count() == 1
), "Erreur, la query ne contient pas le bon nombre d'assiduités"
assert (
query.first() == assiduites[0]
), "Erreur, la query ne contient pas la bonne assiduité"
# On génère une évaluation du 02/01/24 au 03/01/24
evaluation_3: Evaluation = Evaluation.create(
moduleimpl=moduleimpl,
date_debut=scu.is_iso_formated("2024-01-02T10:00", True),
date_fin=scu.is_iso_formated("2024-01-03T12:00", True),
)
query: Query = scass.get_evaluation_assiduites(evaluation_3)
assert isinstance(query, Query), "Erreur, la fonction ne renvoie pas une Query"
# On vérifie le contenu de la query
# On devrait avoir les deux dernières assiduités
assert (
query.count() == 2
), "Erreur, la query ne contient pas le bon nombre d'assiduités"
assert (
query.all() == assiduites[1:]
), "Erreur, la query ne contient pas les bonnes assiduités"
# Test de la récupération des assiduités aux évaluations
evaluations_assiduites = scass.get_etud_evaluations_assiduites(etud)
assert isinstance(
evaluations_assiduites, list
), "Erreur, la fonction ne renvoie pas une liste"
assert len(evaluations_assiduites) == 3, "Erreur, le nombre d'évaluations est faux"
assert all(
isinstance(e, dict) for e in evaluations_assiduites
), "Erreur, les éléments de la liste ne sont pas des dictionnaires"
assert all(
"evaluation_id" in e and "assiduites" in e for e in evaluations_assiduites
), "Erreur, les dictionnaires ne contiennent pas les bonnes clés"
assert (
evaluations_assiduites[0]["assiduites"] == []
), "Erreur, la première évaluation ne devrait pas contenir d'assiduités"
assert evaluations_assiduites[1]["assiduites"][0] == assiduites[0].to_dict(
format_api=True
), "Erreur, la deuxième évaluation n'est pas bonne"
assert evaluations_assiduites[2]["assiduites"] == [
assi.to_dict(format_api=True) for assi in assiduites[1:]
], "Erreur, la troisième évaluation n'est pas bonne"