# -*- coding: utf-8 -*-

"""Test accès étudiants

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_etudiants.py
"""

import requests
from app.scodoc import sco_utils as scu

from tests.api.setup_test_api import API_URL, CHECK_CERTIFICATE, api_headers
from tests.api.tools_test_api import (
    verify_fields,
    verify_occurences_ids_etuds,
    BULLETIN_FIELDS,
    BULLETIN_ETUDIANT_FIELDS,
    BULLETIN_FORMATION_FIELDS,
    BULLETIN_OPTIONS_FIELDS,
    BULLETIN_RESSOURCES_FIELDS,
    BULLETIN_SAES_FIELDS,
    BULLETIN_UES_FIELDS,
    BULLETIN_SEMESTRE_FIELDS,
    BULLETIN_UES_RT11_RESSOURCES_FIELDS,
    BULLETIN_UES_RT11_SAES_FIELDS,
    BULLETIN_UES_RT21_RESSOURCES_FIELDS,
    BULLETIN_UES_RT31_RESSOURCES_FIELDS,
    BULLETIN_UES_RT21_SAES_FIELDS,
    BULLETIN_UES_RT31_SAES_FIELDS,
    BULLETIN_SEMESTRE_ABSENCES_FIELDS,
    BULLETIN_SEMESTRE_ECTS_FIELDS,
    BULLETIN_SEMESTRE_NOTES_FIELDS,
    BULLETIN_SEMESTRE_RANG_FIELDS,
    BULLETIN_RESSOURCES_ET_SAES_RESSOURCE_ET_SAE_FIELDS,
    BULLETIN_RESSOURCES_ET_SAES_RESSOURCE_ET_SAE_EVALUATION_FIELDS,
    BULLETIN_RESSOURCES_ET_SAES_RESSOURCE_ET_SAE_EVALUATION_POIDS_FIELDS,
    BULLETIN_RESSOURCES_ET_SAES_RESSOURCE_ET_SAE_EVALUATION_NOTE_FIELDS,
    BULLETIN_UES_UE_FIELDS,
    BULLETIN_UES_UE_MOYENNE_FIELDS,
    BULLETIN_UES_UE_RESSOURCES_RESSOURCE_FIELDS,
    BULLETIN_UES_UE_SAES_SAE_FIELDS,
    BULLETIN_UES_UE_ECTS_FIELDS,
)
from tests.api.tools_test_api import ETUD_FIELDS, FSEM_FIELDS


ETUDID = 1
NIP = "NIP2"
INE = "INE1"


def test_etudiants_courant(api_headers):
    """
    Route: /etudiants/courant
    """
    fields = {"id", "code_nip", "nom", "prenom", "civilite"}

    r = requests.get(
        API_URL + "/etudiants/courants?date_courante=2022-07-01",
        headers=api_headers,
        verify=CHECK_CERTIFICATE,
        timeout=scu.SCO_TEST_API_TIMEOUT,
    )
    assert r.status_code == 200
    etudiants = r.json()
    assert len(etudiants) > 0

    etud = etudiants[-1]
    assert verify_fields(etud, fields) is True
    assert isinstance(etud["id"], int)
    assert isinstance(etud["code_nip"], str)
    assert isinstance(etud["nom"], str)
    assert isinstance(etud["prenom"], str)
    assert isinstance(etud["civilite"], str)

    all_unique = verify_occurences_ids_etuds(r.text)
    assert all_unique is True

    ########## Version long ################
    r = requests.get(
        API_URL + "/etudiants/courants/long?date_courante=2022-07-01",
        headers=api_headers,
        verify=CHECK_CERTIFICATE,
        timeout=scu.SCO_TEST_API_TIMEOUT,
    )
    assert r.status_code == 200
    etudiants = r.json()
    assert len(etudiants) == 16  # HARDCODED

    etud = etudiants[-1]
    assert verify_fields(etud, ETUD_FIELDS) is True


def test_etudiant(api_headers):
    """
    Routes : /etudiant/etudid/<int:etudid>, /etudiant/nip/<string:nip>, /etudiant/ine/<string:ine>
    """

    ######### Test etudid #########
    r = requests.get(
        API_URL + "/etudiant/etudid/" + str(ETUDID),
        headers=api_headers,
        verify=CHECK_CERTIFICATE,
        timeout=scu.SCO_TEST_API_TIMEOUT,
    )
    assert r.status_code == 200
    etud = r.json()
    assert verify_fields(etud, ETUD_FIELDS) is True

    code_nip = r.json()["code_nip"]
    code_ine = r.json()["code_ine"]

    ######### Test code nip #########

    r = requests.get(
        API_URL + "/etudiant/nip/" + code_nip,
        headers=api_headers,
        verify=CHECK_CERTIFICATE,
        timeout=scu.SCO_TEST_API_TIMEOUT,
    )
    assert r.status_code == 200
    etud_nip = r.json()
    fields_ok = verify_fields(etud, ETUD_FIELDS)
    assert fields_ok is True

    ######### Test code ine #########

    r = requests.get(
        API_URL + "/etudiant/ine/" + code_ine,
        headers=api_headers,
        verify=CHECK_CERTIFICATE,
    )
    assert r.status_code == 200
    etud_ine = r.json()
    fields_ok = verify_fields(etud, ETUD_FIELDS)
    assert fields_ok is True

    assert etud == etud_nip == etud_ine


def test_etudiants(api_headers):
    """
    Route : /etudiants/etudid/<int:etudid>, /etudiants/nip/<string:nip>, /etudiants/ine/<string:ine>
    """
    ######### Test etudid #########
    r = requests.get(
        API_URL + "/etudiants/etudid/" + str(ETUDID),
        headers=api_headers,
        verify=CHECK_CERTIFICATE,
        timeout=scu.SCO_TEST_API_TIMEOUT,
    )
    assert r.status_code == 200
    etud = r.json()
    code_nip = etud[0]["code_nip"]
    code_ine = etud[0]["code_ine"]

    assert isinstance(etud, list)
    assert len(etud) == 1
    fields_ok = verify_fields(etud[0], ETUD_FIELDS)
    assert fields_ok is True

    ######### Test code nip #########

    r = requests.get(
        API_URL + "/etudiants/nip/" + code_nip,
        headers=api_headers,
        verify=CHECK_CERTIFICATE,
        timeout=scu.SCO_TEST_API_TIMEOUT,
    )
    assert r.status_code == 200
    etud_nip = r.json()

    assert isinstance(etud_nip, list)
    fields_ok = verify_fields(etud_nip[0], ETUD_FIELDS)
    assert fields_ok is True

    all_unique = True
    list_ids = [etud["id"] for etud in etud_nip]
    for id in list_ids:
        if list_ids.count(id) > 1:
            all_unique = False
    assert all_unique is True

    ######### Test code ine #########

    r = requests.get(
        API_URL + "/etudiants/ine/" + code_ine,
        headers=api_headers,
        verify=CHECK_CERTIFICATE,
        timeout=scu.SCO_TEST_API_TIMEOUT,
    )
    assert r.status_code == 200
    etud_ine = r.json()

    assert isinstance(etud_ine, list)
    fields_ok = verify_fields(etud_ine[0], ETUD_FIELDS)
    assert fields_ok is True

    all_unique = True
    list_ids = [etud["id"] for etud in etud_ine]
    for id in list_ids:
        if list_ids.count(id) > 1:
            all_unique = False
    assert all_unique is True

    ####### Erreurs #######
    r = requests.get(
        API_URL + "/etudiants/etudid/",
        headers=api_headers,
        verify=CHECK_CERTIFICATE,
        timeout=scu.SCO_TEST_API_TIMEOUT,
    )
    assert r.status_code == 404


def test_etudiant_formsemestres(api_headers):
    """
    Route: /etudiant/etudid/<etudid:int>/formsemestres
    """

    ######### Test etudid #########

    r = requests.get(
        API_URL + "/etudiant/etudid/" + str(ETUDID) + "/formsemestres",
        headers=api_headers,
        verify=CHECK_CERTIFICATE,
        timeout=scu.SCO_TEST_API_TIMEOUT,
    )
    assert r.status_code == 200
    list_formsemestres = r.json()
    assert len(list_formsemestres) == 1
    formsemestre = list_formsemestres[0]
    assert isinstance(formsemestre["id"], int)
    assert isinstance(formsemestre["bul_bgcolor"], str)
    assert isinstance(formsemestre["date_debut"], str)
    assert isinstance(formsemestre["date_fin"], str)
    assert isinstance(formsemestre["resp_can_edit"], bool)
    assert isinstance(formsemestre["dept_id"], int)
    assert isinstance(formsemestre["etat"], bool)
    assert isinstance(formsemestre["resp_can_change_ens"], bool)
    assert isinstance(formsemestre["modalite"], str)
    assert isinstance(formsemestre["ens_can_edit_eval"], bool)
    assert isinstance(formsemestre["formation_id"], int)
    assert isinstance(formsemestre["gestion_compensation"], bool)
    assert formsemestre["elt_sem_apo"] is None or isinstance(
        formsemestre["elt_sem_apo"], str
    )
    assert isinstance(formsemestre["semestre_id"], int)
    assert isinstance(formsemestre["bul_hide_xml"], bool)
    assert formsemestre["elt_annee_apo"] is None or isinstance(
        formsemestre["elt_annee_apo"], str
    )
    assert isinstance(formsemestre["titre"], str)
    assert isinstance(formsemestre["block_moyennes"], bool)
    assert isinstance(formsemestre["block_moyenne_generale"], bool)
    assert formsemestre["scodoc7_id"] is None or isinstance(
        formsemestre["scodoc7_id"], int
    )
    assert isinstance(formsemestre["gestion_semestrielle"], bool)
    assert isinstance(formsemestre["formsemestre_id"], int)
    assert isinstance(formsemestre["titre_num"], str)
    assert isinstance(formsemestre["date_debut_iso"], str)
    assert isinstance(formsemestre["date_fin_iso"], str)
    assert isinstance(formsemestre["responsables"], list)
    assert isinstance(formsemestre["formation"]["titre"], str)

    assert verify_fields(formsemestre, FSEM_FIELDS) is True

    ######### Test code nip #########
    r = requests.get(
        API_URL + "/etudiant/nip/" + str(NIP) + "/formsemestres",
        headers=api_headers,
        verify=CHECK_CERTIFICATE,
        timeout=scu.SCO_TEST_API_TIMEOUT,
    )
    assert r.status_code == 200
    formsemestres = r.json()
    assert len(formsemestres) == 1

    formsemestre = formsemestres[0]
    assert verify_fields(formsemestre, FSEM_FIELDS) is True

    ######### Test code ine #########
    r = requests.get(
        API_URL + "/etudiant/ine/" + str(INE) + "/formsemestres",
        headers=api_headers,
        verify=CHECK_CERTIFICATE,
        timeout=scu.SCO_TEST_API_TIMEOUT,
    )
    assert r.status_code == 200
    formsemestres = r.json()
    assert len(formsemestres) == 1

    formsemestre = formsemestres[0]
    assert verify_fields(formsemestre, FSEM_FIELDS) is True


def test_etudiant_bulletin_semestre(api_headers):
    """
    Route: /etudiant/etudid/<etudid>/formsemestre/<formsemestre_id>/bulletin
    """
    ##################### LONG ########################

    ######### Test etudid #########

    r = requests.get(
        API_URL + "/etudiant/etudid/" + str(ETUDID) + "/formsemestre/1/bulletin",
        headers=api_headers,
        verify=CHECK_CERTIFICATE,
        timeout=scu.SCO_TEST_API_TIMEOUT,
    )
    assert r.status_code == 200
    bulletin = r.json()
    assert len(bulletin) == 14  # HARDCODED

    assert verify_fields(bulletin, BULLETIN_FIELDS) is True
    assert isinstance(bulletin["version"], str)
    assert isinstance(bulletin["type"], str)
    assert isinstance(bulletin["date"], str)
    assert isinstance(bulletin["publie"], bool)
    assert isinstance(bulletin["etudiant"], dict)
    assert isinstance(bulletin["formation"], dict)
    assert isinstance(bulletin["formsemestre_id"], int)
    assert isinstance(bulletin["etat_inscription"], str)
    assert isinstance(bulletin["options"], dict)
    assert isinstance(bulletin["ressources"], dict)
    assert isinstance(bulletin["saes"], dict)
    assert isinstance(bulletin["ues"], dict)
    assert isinstance(bulletin["semestre"], dict)
    assert isinstance(bulletin["ues_capitalisees"], dict)

    bulletin_etud = bulletin["etudiant"]
    assert verify_fields(bulletin_etud, BULLETIN_ETUDIANT_FIELDS) is True
    assert isinstance(bulletin_etud["civilite"], str)
    assert isinstance(bulletin_etud["code_ine"], str)
    assert isinstance(bulletin_etud["code_nip"], str)
    assert isinstance(bulletin_etud["date_naissance"], str)
    assert isinstance(bulletin_etud["dept_id"], int)
    assert isinstance(bulletin_etud["dept_acronym"], str)
    assert isinstance(bulletin_etud["email"], str)
    assert isinstance(bulletin_etud["emailperso"], str)
    assert isinstance(bulletin_etud["etudid"], int)
    assert isinstance(bulletin_etud["nom"], str)
    assert isinstance(bulletin_etud["prenom"], str)
    assert isinstance(bulletin_etud["nomprenom"], str)
    assert isinstance(bulletin_etud["lieu_naissance"], str)
    assert isinstance(bulletin_etud["dept_naissance"], str)
    assert isinstance(bulletin_etud["nationalite"], str)
    assert isinstance(bulletin_etud["fiche_url"], str)
    assert isinstance(bulletin_etud["photo_url"], str)
    assert isinstance(bulletin_etud["id"], int)
    assert isinstance(bulletin_etud["domicile"], str)
    assert isinstance(bulletin_etud["villedomicile"], str)
    assert isinstance(bulletin_etud["telephone"], str)
    assert isinstance(bulletin_etud["fax"], str)
    assert isinstance(bulletin_etud["description"], str)
    assert isinstance(bulletin_etud["codepostaldomicile"], str)
    assert isinstance(bulletin_etud["paysdomicile"], str)
    assert isinstance(bulletin_etud["telephonemobile"], str)
    assert isinstance(bulletin_etud["typeadresse"], str)

    bulletin_formation = bulletin["formation"]
    assert verify_fields(bulletin_formation, BULLETIN_FORMATION_FIELDS) is True
    assert isinstance(bulletin_formation["id"], int)
    assert isinstance(bulletin_formation["acronyme"], str)
    assert isinstance(bulletin_formation["titre_officiel"], str)
    assert isinstance(bulletin_formation["titre"], str)

    bulletin_options = bulletin["options"]
    assert verify_fields(bulletin_options, BULLETIN_OPTIONS_FIELDS) is True
    assert isinstance(bulletin_options["show_abs"], bool)
    assert isinstance(bulletin_options["show_abs_modules"], bool)
    assert isinstance(bulletin_options["show_ects"], bool)
    assert isinstance(bulletin_options["show_codemodules"], bool)
    assert isinstance(bulletin_options["show_matieres"], bool)
    assert isinstance(bulletin_options["show_rangs"], bool)
    assert isinstance(bulletin_options["show_ue_rangs"], bool)
    assert isinstance(bulletin_options["show_mod_rangs"], bool)
    assert isinstance(bulletin_options["show_moypromo"], bool)
    assert isinstance(bulletin_options["show_minmax"], bool)
    assert isinstance(bulletin_options["show_minmax_mod"], bool)
    assert isinstance(bulletin_options["show_minmax_eval"], bool)
    assert isinstance(bulletin_options["show_coef"], bool)
    assert isinstance(bulletin_options["show_ue_cap_details"], bool)
    assert isinstance(bulletin_options["show_ue_cap_current"], bool)
    assert isinstance(bulletin_options["show_temporary"], bool)
    assert isinstance(bulletin_options["temporary_txt"], str)
    assert isinstance(bulletin_options["show_uevalid"], bool)
    assert isinstance(bulletin_options["show_date_inscr"], bool)

    bulletin_ressources = bulletin["ressources"]
    assert verify_fields(bulletin_ressources, BULLETIN_RESSOURCES_FIELDS) is True
    assert isinstance(bulletin_ressources, dict)

    for ressource in bulletin_ressources.values():
        assert (
            verify_fields(
                ressource, BULLETIN_RESSOURCES_ET_SAES_RESSOURCE_ET_SAE_FIELDS
            )
            is True
        )
        assert isinstance(ressource, dict)
        assert isinstance(ressource["evaluations"], list)
        for evaluation in ressource["evaluations"]:
            assert (
                verify_fields(
                    evaluation,
                    BULLETIN_RESSOURCES_ET_SAES_RESSOURCE_ET_SAE_EVALUATION_FIELDS,
                )
                is True
            )
            assert isinstance(evaluation["id"], int)
            assert evaluation["description"] is None or isinstance(
                evaluation["description"], str
            )
            assert evaluation["date"] is None or isinstance(evaluation["date"], str)
            assert isinstance(evaluation["heure_debut"], str)
            assert isinstance(evaluation["heure_fin"], str)
            assert isinstance(evaluation["coef"], str)
            assert isinstance(evaluation["poids"], dict)
            assert isinstance(evaluation["note"], dict)
            assert isinstance(evaluation["url"], str)

            assert (
                verify_fields(
                    evaluation["poids"],
                    BULLETIN_RESSOURCES_ET_SAES_RESSOURCE_ET_SAE_EVALUATION_POIDS_FIELDS,
                )
                is True
            )
            assert isinstance(evaluation["poids"]["RT1.1"], float)
            assert isinstance(evaluation["poids"]["RT2.1"], float)
            assert isinstance(evaluation["poids"]["RT3.1"], float)

            assert (
                verify_fields(
                    evaluation["note"],
                    BULLETIN_RESSOURCES_ET_SAES_RESSOURCE_ET_SAE_EVALUATION_NOTE_FIELDS,
                )
                is True
            )
            assert isinstance(evaluation["note"]["value"], str)
            assert isinstance(evaluation["note"]["min"], str)
            assert isinstance(evaluation["note"]["max"], str)
            assert isinstance(evaluation["note"]["moy"], str)

    bulletin_saes = bulletin["saes"]
    assert verify_fields(bulletin_saes, BULLETIN_SAES_FIELDS) is True
    assert isinstance(bulletin_saes, dict)

    for sae in bulletin_saes.values():
        assert (
            verify_fields(sae, BULLETIN_RESSOURCES_ET_SAES_RESSOURCE_ET_SAE_FIELDS)
            is True
        )
        assert isinstance(sae, dict)
        assert isinstance(sae["evaluations"], list)
        for evaluation in sae["evaluations"]:
            assert (
                verify_fields(
                    evaluation,
                    BULLETIN_RESSOURCES_ET_SAES_RESSOURCE_ET_SAE_EVALUATION_FIELDS,
                )
                is True
            )
            assert isinstance(evaluation["id"], int)
            assert evaluation["description"] is None or isinstance(
                evaluation["description"], str
            )
            assert evaluation["date"] is None or isinstance(evaluation["date"], str)
            assert isinstance(evaluation["heure_debut"], str)
            assert isinstance(evaluation["heure_fin"], str)
            assert isinstance(evaluation["coef"], str)
            assert isinstance(evaluation["poids"], dict)
            assert isinstance(evaluation["note"], dict)
            assert isinstance(evaluation["url"], str)

            assert (
                verify_fields(
                    evaluation["poids"],
                    BULLETIN_RESSOURCES_ET_SAES_RESSOURCE_ET_SAE_EVALUATION_POIDS_FIELDS,
                )
                is True
            )
            assert isinstance(evaluation["poids"]["RT1.1"], float)
            assert isinstance(evaluation["poids"]["RT2.1"], float)
            assert isinstance(evaluation["poids"]["RT3.1"], float)

            assert (
                verify_fields(
                    evaluation["note"],
                    BULLETIN_RESSOURCES_ET_SAES_RESSOURCE_ET_SAE_EVALUATION_NOTE_FIELDS,
                )
                is True
            )
            assert isinstance(evaluation["note"]["value"], str)
            assert isinstance(evaluation["note"]["min"], str)
            assert isinstance(evaluation["note"]["max"], str)
            assert isinstance(evaluation["note"]["moy"], str)

    bulletin_ues = bulletin["ues"]
    assert verify_fields(bulletin_ues, BULLETIN_UES_FIELDS) is True
    assert isinstance(bulletin_ues, dict)

    for key_ue, value_ue in bulletin_ues.items():
        assert verify_fields(value_ue, BULLETIN_UES_UE_FIELDS) is True
        assert isinstance(value_ue["id"], int)
        assert isinstance(value_ue["titre"], str)
        assert isinstance(value_ue["numero"], int)
        assert isinstance(value_ue["type"], int)
        assert isinstance(value_ue["color"], str)
        assert value_ue["competence"] is None or isinstance(value_ue["competence"], str)
        assert isinstance(value_ue["moyenne"], dict)
        assert isinstance(value_ue["bonus"], str)
        assert isinstance(value_ue["malus"], str)
        assert value_ue["capitalise"] is None or isinstance(value_ue["capitalise"], str)
        assert isinstance(value_ue["ressources"], dict)
        assert isinstance(value_ue["saes"], dict)
        assert isinstance(value_ue["ECTS"], dict)

        assert (
            verify_fields(value_ue["moyenne"], BULLETIN_UES_UE_MOYENNE_FIELDS) is True
        )
        assert isinstance(value_ue["moyenne"]["value"], str)
        assert isinstance(value_ue["moyenne"]["min"], str)
        assert isinstance(value_ue["moyenne"]["max"], str)
        assert isinstance(value_ue["moyenne"]["moy"], str)
        assert isinstance(value_ue["moyenne"]["rang"], str)
        assert isinstance(value_ue["moyenne"]["total"], int)

        if key_ue == "RT1.1":
            assert (
                verify_fields(
                    bulletin_ues[key_ue]["ressources"],
                    BULLETIN_UES_RT11_RESSOURCES_FIELDS,
                )
                is True
            )
            assert (
                verify_fields(
                    bulletin_ues[key_ue]["saes"], BULLETIN_UES_RT11_SAES_FIELDS
                )
                is True
            )
        elif key_ue == "RT2.1":
            assert (
                verify_fields(
                    bulletin_ues[key_ue]["ressources"],
                    BULLETIN_UES_RT21_RESSOURCES_FIELDS,
                )
                is True
            )
            assert (
                verify_fields(
                    bulletin_ues[key_ue]["saes"], BULLETIN_UES_RT21_SAES_FIELDS
                )
                is True
            )
        elif key_ue == "RT3.1":
            assert (
                verify_fields(
                    bulletin_ues[key_ue]["ressources"],
                    BULLETIN_UES_RT31_RESSOURCES_FIELDS,
                )
                is True
            )
            assert (
                verify_fields(
                    bulletin_ues[key_ue]["saes"], BULLETIN_UES_RT31_SAES_FIELDS
                )
                is True
            )

        for ressource in value_ue["ressources"].values():
            assert (
                verify_fields(ressource, BULLETIN_UES_UE_RESSOURCES_RESSOURCE_FIELDS)
                is True
            )
            assert isinstance(ressource["id"], int)
            assert isinstance(ressource["coef"], float)
            assert isinstance(ressource["moyenne"], str)

        for sae in value_ue["saes"].values():
            assert verify_fields(sae, BULLETIN_UES_UE_SAES_SAE_FIELDS) is True
            assert isinstance(sae["id"], int)
            assert isinstance(sae["coef"], float)
            assert isinstance(sae["moyenne"], str)

        assert verify_fields(value_ue["ECTS"], BULLETIN_UES_UE_ECTS_FIELDS) is True
        assert isinstance(value_ue["ECTS"]["acquis"], float)
        assert isinstance(value_ue["ECTS"]["total"], float)

    bulletin_semestre = bulletin["semestre"]
    assert verify_fields(bulletin_semestre, BULLETIN_SEMESTRE_FIELDS) is True
    assert isinstance(bulletin_semestre["etapes"], list)
    assert isinstance(bulletin_semestre["date_debut"], str)
    assert isinstance(bulletin_semestre["date_fin"], str)
    assert isinstance(bulletin_semestre["annee_universitaire"], str)
    assert isinstance(bulletin_semestre["numero"], int)
    assert isinstance(bulletin_semestre["inscription"], str)
    assert isinstance(bulletin_semestre["groupes"], list)
    assert isinstance(bulletin_semestre["absences"], dict)
    assert isinstance(bulletin_semestre["ECTS"], dict)
    assert isinstance(bulletin_semestre["notes"], dict)
    assert isinstance(bulletin_semestre["rang"], dict)

    assert (
        verify_fields(bulletin_semestre["absences"], BULLETIN_SEMESTRE_ABSENCES_FIELDS)
        is True
    )
    assert isinstance(bulletin_semestre["absences"]["injustifie"], int)
    assert isinstance(bulletin_semestre["absences"]["total"], int)

    assert (
        verify_fields(bulletin_semestre["ECTS"], BULLETIN_SEMESTRE_ECTS_FIELDS) is True
    )
    assert isinstance(bulletin_semestre["ECTS"]["acquis"], float)
    assert isinstance(bulletin_semestre["ECTS"]["total"], float)

    assert (
        verify_fields(bulletin_semestre["notes"], BULLETIN_SEMESTRE_NOTES_FIELDS)
        is True
    )
    assert isinstance(bulletin_semestre["notes"]["value"], str)
    assert isinstance(bulletin_semestre["notes"]["min"], str)
    assert isinstance(bulletin_semestre["notes"]["max"], str)
    assert isinstance(bulletin_semestre["notes"]["moy"], str)

    assert (
        verify_fields(bulletin_semestre["rang"], BULLETIN_SEMESTRE_RANG_FIELDS) is True
    )
    assert isinstance(bulletin_semestre["rang"]["value"], str)
    assert isinstance(bulletin_semestre["rang"]["total"], int)

    ######### Test code nip #########

    r = requests.get(
        API_URL + "/etudiant/nip/" + str(NIP) + "/formsemestre/1/bulletin",
        headers=api_headers,
        verify=CHECK_CERTIFICATE,
        timeout=scu.SCO_TEST_API_TIMEOUT,
    )
    assert r.status_code == 200
    bul = r.json()
    assert len(bul) == 14  # HARDCODED

    ######### Test code ine #########
    r = requests.get(
        API_URL + "/etudiant/ine/" + str(INE) + "/formsemestre/1/bulletin",
        headers=api_headers,
        verify=CHECK_CERTIFICATE,
        timeout=scu.SCO_TEST_API_TIMEOUT,
    )
    assert r.status_code == 200
    bul = r.json()
    assert len(bul) == 14  # HARDCODED

    ################### LONG + PDF #####################

    # ######### Test etudid #########
    #
    # r = requests.get(
    #     API_URL + "/etudiant/etudid/" + str(ETUDID) + "/formsemestre/1/bulletin/pdf",
    #     headers=api_headers,
    #     verify=CHECK_CERTIFICATE,
    #     timeout=scu.SCO_TEST_API_TIMEOUT,
    # )
    # assert r.status_code == 200
    #
    # ######### Test code nip #########
    #
    # r = requests.get(
    #     API_URL + "/etudiant/nip/" + str(NIP) + "/formsemestre/1/bulletin/pdf",
    #     headers=api_headers,
    #     verify=CHECK_CERTIFICATE,
    #     timeout=scu.SCO_TEST_API_TIMEOUT,
    # )
    # assert r.status_code == 200
    #
    # ######### Test code ine #########
    # r = requests.get(
    #     API_URL + "/etudiant/ine/" + str(INE) + "/formsemestre/1/bulletin/pdf",
    #     headers=api_headers,
    #     verify=CHECK_CERTIFICATE,
    #     timeout=scu.SCO_TEST_API_TIMEOUT,
    # )
    # assert r.status_code == 200

    ################### SHORT #####################

    ######### Test etudid #########
    r = requests.get(
        API_URL + "/etudiant/etudid/" + str(ETUDID) + "/formsemestre/1/bulletin/short",
        headers=api_headers,
        verify=CHECK_CERTIFICATE,
        timeout=scu.SCO_TEST_API_TIMEOUT,
    )
    assert r.status_code == 200
    bul = r.json()
    assert len(bul) == 14  # HARDCODED

    ######### Test code nip #########

    r = requests.get(
        API_URL + "/etudiant/nip/" + str(NIP) + "/formsemestre/1/bulletin/short",
        headers=api_headers,
        verify=CHECK_CERTIFICATE,
        timeout=scu.SCO_TEST_API_TIMEOUT,
    )
    assert r.status_code == 200
    bul = r.json()
    assert len(bul) == 14  # HARDCODED

    ######### Test code ine #########
    r = requests.get(
        API_URL + "/etudiant/ine/" + str(INE) + "/formsemestre/1/bulletin/short",
        headers=api_headers,
        verify=CHECK_CERTIFICATE,
        timeout=scu.SCO_TEST_API_TIMEOUT,
    )
    assert r.status_code == 200
    bul = r.json()
    assert len(bul) == 14  # HARDCODED

    ################### SHORT + PDF #####################

    # ######### Test etudid #########
    # r = requests.get(
    #     API_URL + "/etudiant/etudid/" + str(ETUDID) + "/formsemestre/1/bulletin/short/pdf",
    #     headers=api_headers,
    #     verify=CHECK_CERTIFICATE,
    #     timeout=scu.SCO_TEST_API_TIMEOUT,
    # )
    # assert r.status_code == 200
    #
    # ######### Test code nip #########
    #
    # r = requests.get(
    #     API_URL + "/etudiant/nip/" + str(NIP) + "/formsemestre/1/bulletin/short/pdf",
    #     headers=api_headers,
    #     verify=CHECK_CERTIFICATE,
    #     timeout=scu.SCO_TEST_API_TIMEOUT,
    # )
    # assert r.status_code == 200
    #
    # ######### Test code ine #########
    # r = requests.get(
    #     API_URL + "/etudiant/ine/" + str(INE) + "/formsemestre/1/bulletin/short/pdf",
    #     headers=api_headers,
    #     verify=CHECK_CERTIFICATE,
    #     timeout=scu.SCO_TEST_API_TIMEOUT,
    # )
    # assert r.status_code == 200

    ### --- Test étudiant inexistant
    r = requests.get(
        API_URL + "/etudiant/ine/189919919119191/formsemestre/1/bulletin",
        headers=api_headers,
        verify=CHECK_CERTIFICATE,
        timeout=scu.SCO_TEST_API_TIMEOUT,
    )
    assert r.status_code == 404


def test_etudiant_groups(api_headers):
    """
    Route:
    /etudiant/etudid/<int:etudid>/formsemestre/<int:formsemestre_id>/groups
    """
    fields = [
        "partition_id",
        "id",
        "formsemestre_id",
        "partition_name",
        "numero",
        "bul_show_rank",
        "show_in_lists",
        "group_id",
        "group_name",
    ]

    ######### Test etudid #########

    r = requests.get(
        API_URL + "/etudiant/etudid/1/formsemestre/1/groups",
        headers=api_headers,
        verify=CHECK_CERTIFICATE,
        timeout=scu.SCO_TEST_API_TIMEOUT,
    )
    assert r.status_code == 200
    groups = r.json()
    assert len(groups) == 1  # dans un seul groupe
    group = groups[0]
    fields_ok = verify_fields(group, fields)
    assert fields_ok is True
