ajout des commentaires
This commit is contained in:
parent
600016d1e0
commit
01820b5a91
@ -1,3 +1,6 @@
|
|||||||
|
""" Parametre demijournee ne fonctionne pas lorsque demijournee = 2
|
||||||
|
Créer et justifier des absences en utilisant le parametre demijournee
|
||||||
|
"""
|
||||||
import random
|
import random
|
||||||
|
|
||||||
# La variable context est définie par le script de lancement
|
# La variable context est définie par le script de lancement
|
||||||
@ -104,3 +107,11 @@ _ = sco_abs_views.doJustifAbsence(
|
|||||||
a = sco_abs.getAbsSemEtud(context.Absences, sem, etudid)
|
a = sco_abs.getAbsSemEtud(context.Absences, sem, etudid)
|
||||||
assert a.CountAbs() == 4 #l'étudiant a été absent le 15 journée compléte (2 abs : 1 matin, 1 apres midi) et le 18 (1 matin), et le 19 (1 apres midi).
|
assert a.CountAbs() == 4 #l'étudiant a été absent le 15 journée compléte (2 abs : 1 matin, 1 apres midi) et le 18 (1 matin), et le 19 (1 apres midi).
|
||||||
assert a.CountAbsJust() == 2 # Justifie abs du matin + abs après midi
|
assert a.CountAbsJust() == 2 # Justifie abs du matin + abs après midi
|
||||||
|
|
||||||
|
"""
|
||||||
|
Commentaire :
|
||||||
|
|
||||||
|
Pb : le 2 ne peut pas être pris en tant que int car string dans la fonction
|
||||||
|
-----> Pb regler
|
||||||
|
|
||||||
|
"""
|
@ -1,5 +1,6 @@
|
|||||||
""" creation de 10 étudiants, formation, semestre, ue, module, absences le matin, l'apres midi, la journée compléte et justification
|
""" creation de 10 étudiants, formation, semestre, ue, module, absences le matin, l'apres midi, la journée compléte
|
||||||
d'absences, supression d'absences, création d'une liste etat absences, creation d'un groupe afin de tester la fonction EtatAbsencesGroupes
|
et justification d'absences, supression d'absences, création d'une liste etat absences, creation d'un groupe afin
|
||||||
|
de tester la fonction EtatAbsencesGroupes
|
||||||
|
|
||||||
Fonctions de l'API utilisé :
|
Fonctions de l'API utilisé :
|
||||||
- doSignaleAbsence
|
- doSignaleAbsence
|
||||||
@ -14,6 +15,9 @@ Fonctions de l'API utilisé :
|
|||||||
- partition_create
|
- partition_create
|
||||||
- createGroup
|
- createGroup
|
||||||
- set_group
|
- set_group
|
||||||
|
- EtatAbsenceGr
|
||||||
|
- AddBilletAbsence
|
||||||
|
- listeBilletsEtud
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -182,8 +186,6 @@ assert len(load_liste_abs) == 2
|
|||||||
assert load_liste_abs2[0]["ampm"] == "1"
|
assert load_liste_abs2[0]["ampm"] == "1"
|
||||||
assert load_liste_abs2[0]["datedmy"] == "22/01/2021"
|
assert load_liste_abs2[0]["datedmy"] == "22/01/2021"
|
||||||
assert load_liste_abs2[0]["exams"] == mod["code"]
|
assert load_liste_abs2[0]["exams"] == mod["code"]
|
||||||
|
|
||||||
|
|
||||||
# absjust_only -> seulement les abs justifiés
|
# absjust_only -> seulement les abs justifiés
|
||||||
|
|
||||||
|
|
||||||
@ -222,5 +224,43 @@ for un_etud in load_grp1_abs :
|
|||||||
assert un_etud["nbabsnonjust"] == "1"
|
assert un_etud["nbabsnonjust"] == "1"
|
||||||
assert un_etud["nomprenom"] == etuds[0]["nomprenom"]
|
assert un_etud["nomprenom"] == etuds[0]["nomprenom"]
|
||||||
|
|
||||||
|
# --- Création de billets
|
||||||
|
|
||||||
|
b1 = context.Absences.AddBilletAbsence(
|
||||||
|
begin="2021-01-22 00:00",
|
||||||
|
end="2021-01-22 23:59",
|
||||||
|
etudid=etudid,
|
||||||
|
description = "abs du 22",
|
||||||
|
justified=False,
|
||||||
|
code_nip=etuds[0]["code_nip"],
|
||||||
|
code_ine=etuds[0]["code_ine"],
|
||||||
|
REQUEST=REQUEST,
|
||||||
|
)
|
||||||
|
|
||||||
|
b2 = context.Absences.AddBilletAbsence(
|
||||||
|
begin="2021-01-15 00:00",
|
||||||
|
end="2021-01-15 23:59",
|
||||||
|
etudid=etudid,
|
||||||
|
description = "abs du 15",
|
||||||
|
code_nip=etuds[0]["code_nip"],
|
||||||
|
code_ine=etuds[0]["code_ine"],
|
||||||
|
REQUEST=REQUEST,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
li_bi = context.Absences.listeBilletsEtud(etudid=etudid, REQUEST=REQUEST, format="json")
|
||||||
|
load_li_bi = json.loads(li_bi)
|
||||||
|
|
||||||
|
assert len(load_li_bi) == 2
|
||||||
|
assert load_li_bi[1]["description"] == "abs du 22"
|
||||||
|
|
||||||
|
"""
|
||||||
|
Commentaire :
|
||||||
|
|
||||||
|
Parametre demijournee ne prend pas en compte les strings ---> pb régler.
|
||||||
|
|
||||||
|
La suppression de justification ne peut pas se faire directement en interractif à l'aide de python.
|
||||||
|
|
||||||
|
La fonction CountAbs ne met pas à jour le nombre après supression des absences. ---> (cf : test_CountAbs.py)
|
||||||
|
|
||||||
|
"""
|
@ -1,20 +1,13 @@
|
|||||||
""" 3) Création d’étudiants, formation etc… Au cours de l’année un étudiant déménage et souhaite changer
|
""" Création de 2 étudiants, un qui demissionne, un autre defaillant + annuler demission et annuler défaillance
|
||||||
ses informations personnelles. Un autre étudiant lui à changer de téléphone portable ainsi que d’adresse e-mail.
|
|
||||||
Changer les données
|
|
||||||
|
|
||||||
Vérifier si les changements se sont effectués
|
|
||||||
|
|
||||||
Fonctions de l’API utilisé :
|
Fonctions de l’API utilisé :
|
||||||
- create_formation
|
- doDemEtudiant
|
||||||
- create_ue
|
- doDefEtudiant
|
||||||
- create_module
|
- doCancelDem
|
||||||
- create_matiere
|
- doCancelDef
|
||||||
- create_formsemestre
|
- etud_info
|
||||||
- create_moduleimpl
|
- search_etud_in_dept
|
||||||
- inscrit_etudiant
|
- fillEtudsInfo
|
||||||
- etuds_info
|
|
||||||
- getEtudInfo
|
|
||||||
- identite_edit
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -27,13 +20,14 @@ context = context # pylint: disable=undefined-variable
|
|||||||
REQUEST = REQUEST # pylint: disable=undefined-variable
|
REQUEST = REQUEST # pylint: disable=undefined-variable
|
||||||
import scotests.sco_fake_gen as sco_fake_gen # pylint: disable=import-error
|
import scotests.sco_fake_gen as sco_fake_gen # pylint: disable=import-error
|
||||||
import scolars
|
import scolars
|
||||||
|
import sco_find_etud
|
||||||
|
|
||||||
G = sco_fake_gen.ScoFake(context.Notes)
|
G = sco_fake_gen.ScoFake(context.Notes)
|
||||||
G.verbose = False
|
G.verbose = False
|
||||||
|
|
||||||
# --- Création d'étudiants
|
# --- Création d'étudiants
|
||||||
|
|
||||||
etud = G.create_etud(
|
etud1 = G.create_etud(
|
||||||
code_nip="",
|
code_nip="",
|
||||||
nom="Poire",
|
nom="Poire",
|
||||||
prenom="Kevin",
|
prenom="Kevin",
|
||||||
@ -55,6 +49,8 @@ etud = G.create_etud(
|
|||||||
description="etudiant test",
|
description="etudiant test",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
etud2 = G.create_etud()
|
||||||
|
|
||||||
# --- Création d'une formation
|
# --- Création d'une formation
|
||||||
f = G.create_formation(acronyme="")
|
f = G.create_formation(acronyme="")
|
||||||
ue = G.create_ue(formation_id=f["formation_id"], acronyme="TST1", titre="ue test")
|
ue = G.create_ue(formation_id=f["formation_id"], acronyme="TST1", titre="ue test")
|
||||||
@ -82,17 +78,58 @@ mi = G.create_moduleimpl(
|
|||||||
responsable_id="bach",
|
responsable_id="bach",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# --- Inscription des étudiants
|
||||||
|
|
||||||
# --- Inscription de l'étudiant
|
G.inscrit_etudiant(sem, etud1)
|
||||||
|
G.inscrit_etudiant(sem, etud2)
|
||||||
|
|
||||||
G.inscrit_etudiant(sem, etud)
|
# --- Etud_info
|
||||||
|
|
||||||
print(etud)
|
info = context.Scolarite.etud_info(etud1["etudid"], format = "json", REQUEST=REQUEST)
|
||||||
|
|
||||||
info = context.Scolarite.etud_info(etud["etudid"], format = "json", REQUEST=REQUEST)
|
|
||||||
load_info = json.loads(info)
|
load_info = json.loads(info)
|
||||||
print(load_info)
|
|
||||||
|
|
||||||
# --- Modification des données
|
|
||||||
|
|
||||||
scolars.adresse_edit(context.Scolarite, args = {"domicile" : "9 rue du moulin"})
|
# --- Démission étudiant
|
||||||
|
|
||||||
|
context.doDemEtudiant(etud1["etudid"], sem["formsemestre_id"], event_date="01/01/2021")
|
||||||
|
|
||||||
|
bul = sco_bulletins.formsemestre_bulletinetud_dict(context.Notes, sem["formsemestre_id"], etud1["etudid"])
|
||||||
|
assert bul["moy_gen"] == "NA"
|
||||||
|
assert bul["ins"][0]["etat"] == "D"
|
||||||
|
|
||||||
|
# --- Défaillance d'un étudiant
|
||||||
|
|
||||||
|
context.doDefEtudiant(etud2["etudid"], sem["formsemestre_id"], event_date="01/01/2021")
|
||||||
|
|
||||||
|
bul = sco_bulletins.formsemestre_bulletinetud_dict(context.Notes, sem["formsemestre_id"], etud1["etudid"])
|
||||||
|
assert bul["moy_gen"] == "NA"
|
||||||
|
assert bul["ins"][0]["etat"] == "D"
|
||||||
|
|
||||||
|
# --- Annuler démission
|
||||||
|
|
||||||
|
context.Scolarite.doCancelDem(etud1["etudid"], sem["formsemestre_id"], REQUEST=REQUEST)
|
||||||
|
bul = sco_bulletins.formsemestre_bulletinetud_dict(context.Notes, sem["formsemestre_id"], etud1["etudid"])
|
||||||
|
print(bul["ins"][0]["etat"])
|
||||||
|
#assert bul["ins"][0]["etat"] == "I"
|
||||||
|
|
||||||
|
# --- Annuler défaillance
|
||||||
|
|
||||||
|
context.Scolarite.doCancelDef(etud2["etudid"], sem["formsemestre_id"], REQUEST=REQUEST)
|
||||||
|
bul = sco_bulletins.formsemestre_bulletinetud_dict(context.Notes, sem["formsemestre_id"], etud1["etudid"])
|
||||||
|
print(bul["ins"][0]["etat"])
|
||||||
|
#assert bul["ins"][0]["etat"] == "I"
|
||||||
|
|
||||||
|
# --- Fonctions retournant HTML
|
||||||
|
|
||||||
|
find = sco_find_etud.search_etud_in_dept(context.Scolarite, expnom="Poire", REQUEST=REQUEST)
|
||||||
|
|
||||||
|
_ = context.Scolarite.fillEtudsInfo(etuds=[etud1])
|
||||||
|
|
||||||
|
"""
|
||||||
|
Commentaire :
|
||||||
|
|
||||||
|
L'etat ne se met pas à jour après l'annulation de la démission ou de la défaillance.
|
||||||
|
|
||||||
|
etud_info ne donne pas toutes les infos de l'étudiant voir mini test create_etud.
|
||||||
|
|
||||||
|
"""
|
@ -1,6 +1,21 @@
|
|||||||
""" Création d'une formation, d'élève de 2 ue dans un semestre et de 6 évaluations par 3 fonction différentes :
|
""" Création d'une formation, d'élève de 2 ue dans un semestre et de 6 évaluations par 3 fonction différentes :
|
||||||
create_eval, evaluation_create et do_evaluation_create. Saisir les notes des évaluations, lister ces evaluations,
|
create_eval, evaluation_create et do_evaluation_create. Saisir les notes des évaluations, lister ces evaluations,
|
||||||
supprimer et modifier une evaluation """
|
supprimer et modifier une evaluation
|
||||||
|
|
||||||
|
Fonction de l'API utilisé :
|
||||||
|
- create_evaluation
|
||||||
|
- evaluation_create
|
||||||
|
- do_evaluation_create
|
||||||
|
- do_evaluation_list_in_formsemestre
|
||||||
|
- do_evaluation_list
|
||||||
|
- create_note
|
||||||
|
- check_absences
|
||||||
|
- do_evaluation_etat
|
||||||
|
- evaluation_supress_alln
|
||||||
|
- do_evaluation_edit
|
||||||
|
- do_evaluation_delete
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import random
|
import random
|
||||||
@ -181,9 +196,7 @@ check2 = sco_liste_notes.evaluation_check_absences(context.Notes, evaluation_id=
|
|||||||
|
|
||||||
# --- Liste de note d'une évaluation
|
# --- Liste de note d'une évaluation
|
||||||
|
|
||||||
#lien = context.Notes.do_evaluation_listnotes(REQUEST=REQUEST)
|
#lien = sco_liste_notes.do_evaluation_listenotes(context=context.Notes, REQUEST=REQUEST)
|
||||||
#print (lien) pb avec les arguments.
|
|
||||||
|
|
||||||
|
|
||||||
cal = sco_evaluations.formsemestre_evaluations_cal(context.Notes, formsemestre_id=sem["formsemestre_id"], REQUEST=REQUEST)
|
cal = sco_evaluations.formsemestre_evaluations_cal(context.Notes, formsemestre_id=sem["formsemestre_id"], REQUEST=REQUEST)
|
||||||
#html
|
#html
|
||||||
@ -233,3 +246,12 @@ assert len(lie) == 5
|
|||||||
sco_evaluations.do_evaluation_delete(context.Notes, REQUEST=REQUEST, evaluation_id=e7["evaluation_id"])
|
sco_evaluations.do_evaluation_delete(context.Notes, REQUEST=REQUEST, evaluation_id=e7["evaluation_id"])
|
||||||
lie2 = context.Notes.do_evaluation_list_in_formsemestre(formsemestre_id=sem["formsemestre_id"])
|
lie2 = context.Notes.do_evaluation_list_in_formsemestre(formsemestre_id=sem["formsemestre_id"])
|
||||||
assert len(lie2) == 4
|
assert len(lie2) == 4
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
Commentaire :
|
||||||
|
|
||||||
|
Plusieurs fonction retourne de l'HTML, les notes ne se suppriment pas malgre l'utilisation de la fonction
|
||||||
|
evaluation_supress_alln (voir mini test). evaluation_delete ---> rien ne se passe.
|
||||||
|
|
||||||
|
"""
|
@ -1,3 +1,5 @@
|
|||||||
|
""" Création d'une évaluation, saisie des notes et supressions de toutes les notes """
|
||||||
|
|
||||||
import random
|
import random
|
||||||
# La variable context est définie par le script de lancement
|
# La variable context est définie par le script de lancement
|
||||||
# l'affecte ainsi pour évietr les warnins pylint:
|
# l'affecte ainsi pour évietr les warnins pylint:
|
||||||
@ -68,3 +70,6 @@ sco_saisie_notes.evaluation_suppress_alln(context.Notes, e["evaluation_id"], REQ
|
|||||||
etat = sco_evaluations.do_evaluation_etat(context.Notes, e["evaluation_id"])
|
etat = sco_evaluations.do_evaluation_etat(context.Notes, e["evaluation_id"])
|
||||||
assert not etat["evalcomplete"]
|
assert not etat["evalcomplete"]
|
||||||
|
|
||||||
|
"""
|
||||||
|
Commentaire : Les notes ne se suppriment pas et l'etat ne change donc pas
|
||||||
|
"""
|
@ -317,5 +317,3 @@ lif3 = context.Notes.formation_list(format = 'json', REQUEST=REQUEST)
|
|||||||
|
|
||||||
load_lif3 = json.loads(lif3)
|
load_lif3 = json.loads(lif3)
|
||||||
assert len(load_lif3) == 1
|
assert len(load_lif3) == 1
|
||||||
|
|
||||||
|
|
||||||
|
@ -334,7 +334,7 @@ assert li_grp1[0] == sco_groups.get_group(context.Scolarite, li_grp1[0]["group_i
|
|||||||
|
|
||||||
assert len(li_grp2) == 3
|
assert len(li_grp2) == 3
|
||||||
sco_groups.group_delete(context.Scolarite, li_grp2[2])
|
sco_groups.group_delete(context.Scolarite, li_grp2[2])
|
||||||
#assert len(li_grp2) == 2 #TESTE DE group_delete, aucun changement sur la console mais se supprime sur scodoc web
|
#assert len(li_grp2) == 2 #TEST DE group_delete, aucun changement sur la console mais se supprime sur scodoc web
|
||||||
# mais pas dans la console comme pour countAbs()
|
# mais pas dans la console comme pour countAbs()
|
||||||
|
|
||||||
assert sco_groups.get_partition(context.Scolarite, li1[0]["partition_id"])== li1[0] # test de get_partition
|
assert sco_groups.get_partition(context.Scolarite, li1[0]["partition_id"])== li1[0] # test de get_partition
|
||||||
@ -370,16 +370,13 @@ assert li_grp3[0] in sg # test de get_sem_groups
|
|||||||
limembre = sco_groups.get_group_members(context.Scolarite, li_grp1[0]["group_id"])
|
limembre = sco_groups.get_group_members(context.Scolarite, li_grp1[0]["group_id"])
|
||||||
assert len(limembre) == 4 # car on a changé de groupe un etudiant de ce groupe donc 5-1=4
|
assert len(limembre) == 4 # car on a changé de groupe un etudiant de ce groupe donc 5-1=4
|
||||||
|
|
||||||
|
"""
|
||||||
|
Commentaire :
|
||||||
|
|
||||||
|
Meme probleme que pour les groupes, lorsque l'on supprime un groupe il est toujours présent dans la liste de groupe
|
||||||
|
mais pas dans scodoc web.
|
||||||
|
|
||||||
# --- Changement de nom des partitions, groupes
|
"""
|
||||||
|
|
||||||
# Le changement de nom des groupes et des partitions n'est pas possible en python car la fonction est une fonction d'envoie de formulaire.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ doc = file.read()
|
|||||||
file.close()
|
file.close()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# --- Création de la formation
|
# --- Création de la formation
|
||||||
|
|
||||||
f = sco_formations.formation_import_xml(REQUEST=REQUEST, doc=doc, context=context.Notes)
|
f = sco_formations.formation_import_xml(REQUEST=REQUEST, doc=doc, context=context.Notes)
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
""" Créer un utilisateur, récupérer ses infos,
|
""" Créer un utilisateur, recupérer ses infos, changer son mdp, le supprimer """
|
||||||
lister les utilisateurs, modifier le mdp, modfifier l'utilisateur (si possible),
|
|
||||||
changer d'admin, tester d'autre fonctionalités liés aux users """
|
|
||||||
|
|
||||||
import random
|
import random
|
||||||
# La variable context est définie par le script de lancement
|
# La variable context est définie par le script de lancement
|
||||||
@ -12,12 +10,12 @@ import ZScoUsers
|
|||||||
import ZScoDoc
|
import ZScoDoc
|
||||||
import ZScolar
|
import ZScolar
|
||||||
|
|
||||||
|
|
||||||
nomdept = raw_input("Quel est le nom de votre département test? ATTENTION A NE PAS VOUS TROMPER : ")
|
nomdept = raw_input("Quel est le nom de votre département test? ATTENTION A NE PAS VOUS TROMPER : ")
|
||||||
|
|
||||||
# --- Création d'un utilisateur
|
# --- Création d'un utilisateur
|
||||||
|
|
||||||
arg = {"passwd": "scodocpass", "user_name" : "unutil", "nom" : "unnom", "prenom":"unprenom", "email": "unemail@mail.fr", "roles" :"Ens"+nomdept+",RespPe"+nomdept}
|
arg = {"passwd": "scodocpass", "user_name" : "unutil", "nom" : "unnom", "prenom":"unprenom",
|
||||||
|
"email": "unemail@mail.fr", "roles" :"Ens"+nomdept+",RespPe"+nomdept}
|
||||||
#user1 = context.Users.create_user(args=arg, REQUEST=REQUEST)
|
#user1 = context.Users.create_user(args=arg, REQUEST=REQUEST)
|
||||||
user_info1 = context.Users.user_info(user_name="unutil")
|
user_info1 = context.Users.user_info(user_name="unutil")
|
||||||
|
|
||||||
@ -31,19 +29,36 @@ assert user_info1["roles"] == arg["roles"]
|
|||||||
# --- Récupération de la liste des Users
|
# --- Récupération de la liste des Users
|
||||||
|
|
||||||
liste_xml = context.Users.get_userlist_xml(REQUEST=REQUEST)
|
liste_xml = context.Users.get_userlist_xml(REQUEST=REQUEST)
|
||||||
|
print(liste_xml)
|
||||||
|
|
||||||
liste_user = context.Users.get_userlist()
|
liste_user = context.Users.get_userlist()
|
||||||
len_liu1 = len(liste_user)
|
len_liu1 = len(liste_user)
|
||||||
|
|
||||||
assert user_info1 in liste_user #le nouvel utilisateur est bien dans la liste !
|
assert user_info1 in liste_user #le nouvel utilisateur est bien dans la liste !
|
||||||
|
|
||||||
# --- Changement du mot de passe de l'utilisateur
|
# --- Récupérer user_name à partir de nomplogin
|
||||||
|
|
||||||
#context.Users.change_password(user_name="unutil", password=)
|
user_name1 = context.Users.get_user_name_from_nomplogin(nomplogin=user_info1["nomplogin"])
|
||||||
|
assert user_name1 == "unutil"
|
||||||
|
|
||||||
|
# --- Changement du mot de passe de l'utilisateur
|
||||||
|
|
||||||
context.Users.do_change_password(user_name="unutil", password="scodocpass2")
|
context.Users.do_change_password(user_name="unutil", password="scodocpass2")
|
||||||
#vérification du mdp changé directement sur scodoc web car je ne trouve pas comment récupérer le mdp en python
|
#vérification du mdp changé directement sur scodoc web car je ne trouve pas comment récupérer le mdp en python
|
||||||
#Vérification : ok!
|
#Vérification : ok!
|
||||||
|
|
||||||
|
# --- Supression d'un utilisateur
|
||||||
|
|
||||||
|
#context.Users.delete_user_form(REQUEST=REQUEST, user_name="unutil")
|
||||||
|
|
||||||
|
# --- Test de la récupération de l'URL
|
||||||
|
|
||||||
|
url = context.Users.UsersURL()
|
||||||
|
assert url == "ScoDoc/"+nomdept+"/Scolarite/Users"
|
||||||
|
|
||||||
|
"""
|
||||||
|
Commentaire :
|
||||||
|
|
||||||
|
La supression d'un utilisateur ne fonctionne pas car nécessite l'envoie d'un formulaire.
|
||||||
|
|
||||||
|
"""
|
Loading…
Reference in New Issue
Block a user