forked from ScoDoc/ScoDoc
Fix creation/deletion scripts + more unit tests
This commit is contained in:
parent
31288efb73
commit
b0a77fba66
17
README.md
17
README.md
@ -95,7 +95,7 @@ Lancer le script:
|
||||
|
||||
su postgres
|
||||
cd /opt/scodoc/tools
|
||||
./create_database.sh
|
||||
./create_users_database.sh
|
||||
|
||||
Ce script crée une base nommée `SCO8USERS`, appartenant à l'utilisateur (role) postgres `scodoc`.
|
||||
Cet utilisateur est automatiquement créé si nécessaire.
|
||||
@ -146,6 +146,21 @@ de votre installation ScoDoc 7 pour passer à ScoDoc 8 (*ne pas utiliser en prod
|
||||
cd /opt/scodoc/tools
|
||||
./migrate_from_scodoc7.sh
|
||||
|
||||
## Création d'un département
|
||||
|
||||
sudo su
|
||||
cd /opt/scodoc
|
||||
source venv/bin/activate
|
||||
flask sco-create-dept DEPT
|
||||
|
||||
où `DEPT` est le nom du département (un acronyme en majuscule, comme "RT", "GEA", ...).
|
||||
|
||||
### Suppression d'un département
|
||||
|
||||
sudo su
|
||||
cd /opt/scodoc
|
||||
source venv/bin/activate
|
||||
flask sco-delete-dept DEPT
|
||||
|
||||
## Lancement serveur (développement, sur VM Linux)
|
||||
|
||||
|
@ -120,7 +120,7 @@ def DBInsertDict(cnx, table, vals, commit=0, convert_empty_to_nulls=1):
|
||||
cnx.commit() # get rid of this transaction
|
||||
raise # and re-raise exception
|
||||
if commit:
|
||||
log("DBInsertDict: commit (requested)")
|
||||
# log("DBInsertDict: commit (requested)")
|
||||
cnx.commit()
|
||||
return oid
|
||||
|
||||
|
@ -695,7 +695,7 @@ def do_import_etud_admission(
|
||||
"codelycee": get_opt_str(etud, "lycee"),
|
||||
"boursier": get_opt_str(etud, "bourse"),
|
||||
}
|
||||
log("do_import_etud_admission: etud=%s" % pprint.pformat(etud))
|
||||
# log("do_import_etud_admission: etud=%s" % pprint.pformat(etud))
|
||||
al = sco_etud.admission_list(cnx, args={"etudid": etudid})
|
||||
if not al:
|
||||
sco_etud.admission_create(cnx, args) # -> adm_id
|
||||
|
@ -133,7 +133,7 @@ def user_password(username, password=None): # user-password
|
||||
|
||||
@app.cli.command()
|
||||
@click.argument("dept")
|
||||
def sco_delete_dept(dept):
|
||||
def sco_delete_dept(dept): # sco-delete-dept
|
||||
"Delete existing departement"
|
||||
if os.getuid() != 0:
|
||||
sys.stderr.write("sco_delete_dept: must be run by root\n")
|
||||
@ -146,13 +146,13 @@ def sco_delete_dept(dept):
|
||||
|
||||
@app.cli.command()
|
||||
@click.argument("dept")
|
||||
def sco_create_dept(dept):
|
||||
def sco_create_dept(dept): # sco-create-dept
|
||||
"Create new departement"
|
||||
if os.getuid() != 0:
|
||||
sys.stderr.write("sco_create_dept: must be run by root\n")
|
||||
return 1
|
||||
if os.system('cd tools && ./create_dept.sh -n "{}"'.format(dept)):
|
||||
sys.stderr.write("error deleting dept " + dept)
|
||||
if os.system(f'cd tools && ./create_dept.sh -n "{dept}"'):
|
||||
sys.stderr.write(f"error creating dept {dept}\n")
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
@ -15,7 +15,7 @@ import sys
|
||||
import random
|
||||
import psycopg2
|
||||
|
||||
from gen_nomprenoms import nomprenom
|
||||
from .gen_nomprenoms import nomprenom
|
||||
|
||||
|
||||
def usage():
|
||||
|
@ -1,79 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Lancement d'un python scodoc interactif
|
||||
# dans l'environnement d'un département
|
||||
# et avec chargement des scripts indiqués
|
||||
# via from ... import *
|
||||
#
|
||||
# Si -r est utilisé, veiller à créer au préalable
|
||||
# le département via l'interface web (Zope)
|
||||
|
||||
usage() {
|
||||
echo "Usage: $0 [-h] [-r] [-x] dept [script...]"
|
||||
echo "Lance un environnement interactif python/ScoDoc"
|
||||
echo " -r: supprime et recrée le département (attention: efface la base !)"
|
||||
echo " -x: exit après exécution des scripts, donc mode non interactif"
|
||||
exit 1
|
||||
}
|
||||
|
||||
set -euo pipefail
|
||||
cd /opt/scodoc/Products/ScoDoc || exit 2
|
||||
source config/config.sh
|
||||
source config/utils.sh
|
||||
|
||||
RECREATE_DEPT=0
|
||||
PYTHON_INTERACTIVE="-i"
|
||||
|
||||
while [ -n "$1" ]; do
|
||||
PARAM="$1"
|
||||
[ "${PARAM::1}" != "-" ] && break
|
||||
case $PARAM in
|
||||
-h | --help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
-r)
|
||||
RECREATE_DEPT=1
|
||||
;;
|
||||
-x)
|
||||
PYTHON_INTERACTIVE=""
|
||||
;;
|
||||
*)
|
||||
echo "ERROR: unknown parameter \"$PARAM\""
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
|
||||
|
||||
DEPT="$1"
|
||||
shift
|
||||
|
||||
if [ "$RECREATE_DEPT" = 1 ]
|
||||
then
|
||||
cfg_pathname="${SCODOC_VAR_DIR}/config/depts/$DEPT".cfg
|
||||
if [ -e "$cfg_pathname" ]
|
||||
then
|
||||
(cd config || terminate "no config directory"; ./delete_dept.sh -n "$DEPT") || terminate "error deleting dept $DEPT"
|
||||
fi
|
||||
(cd config || terminate "no config directory"; ./create_dept.sh -n "$DEPT") || terminate "error creating dept $DEPT"
|
||||
# systemctl start scodoc
|
||||
fi
|
||||
|
||||
cmd="from __future__ import print_function;from Zope2 import configure;configure('/opt/scodoc/etc/zope.conf');import Zope2; app=Zope2.app();from debug import *;context = go_dept(app, '""$DEPT""', verbose=False);"
|
||||
|
||||
for f in "$@"
|
||||
do
|
||||
cmd="${cmd}exec(open(\"${f}\").read());"
|
||||
done
|
||||
|
||||
if [ -z "$PYTHON_INTERACTIVE" ]
|
||||
then
|
||||
/opt/zope213/bin/python -c "$cmd"
|
||||
else
|
||||
/opt/zope213/bin/python "$PYTHON_INTERACTIVE" -c "$cmd"
|
||||
fi
|
||||
|
@ -1,38 +0,0 @@
|
||||
|
||||
# Tests avec splinter (expérimental)
|
||||
|
||||
<http://splinter.cobrateam.info/docs/tutorial.html>
|
||||
|
||||
## Installation de Splinter
|
||||
|
||||
```
|
||||
apt-get install python-dev
|
||||
apt-get install libxslt-dev
|
||||
apt-get install libxml2-dev
|
||||
apt-get install python-lxml python-cssselect
|
||||
|
||||
|
||||
/opt/zope213/bin/easy_install zope.testbrowser
|
||||
/opt/zope213/bin/easy_install cssselect
|
||||
/opt/zope213/bin/easy_install splinter
|
||||
```
|
||||
|
||||
|
||||
J'ai du hacker `_mechanize.py`, ligne 218
|
||||
|
||||
```
|
||||
vi +218 /opt/zope213/lib/python2.7/site-packages/mechanize-0.2.5-py2.7.egg/mechanize/_mechanize.py
|
||||
|
||||
url = _rfc3986.urljoin(self._response.geturl()+'/', url)
|
||||
```
|
||||
|
||||
(ajouter le + '/')
|
||||
|
||||
### Essais:
|
||||
/opt/zope213/bin/python common.py
|
||||
|
||||
ne doit pas déclencher d'erreur.
|
||||
|
||||
|
||||
|
||||
|
@ -1,49 +0,0 @@
|
||||
# -*- mode: python -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""Partie commune:
|
||||
|
||||
se connecte et accede a la page d'accueil du premier departement
|
||||
"""
|
||||
from splinter import Browser
|
||||
import re, sys, time
|
||||
import urlparse
|
||||
import pdb
|
||||
from optparse import OptionParser
|
||||
|
||||
from conn_info import *
|
||||
|
||||
parser = OptionParser()
|
||||
parser.add_option("-d", "--dept", dest="dept_index", default=0, help="indice du departement")
|
||||
options, args = parser.parse_args()
|
||||
|
||||
dept_index = int(options.dept_index)
|
||||
|
||||
t0 = time.time()
|
||||
browser = Browser('zope.testbrowser')
|
||||
browser._browser.mech_browser.set_handle_robots(False) # must ignore ScoDoc robots.txt
|
||||
browser.visit(SCODOC)
|
||||
print 'Start: title:', browser.title
|
||||
print 'URL: ', browser.url
|
||||
# print browser.html
|
||||
|
||||
links = browser.find_link_by_partial_text('Scolarit')
|
||||
print '%d departements' % len(links)
|
||||
|
||||
links[dept_index].click() # va sur le premier departement
|
||||
|
||||
# ---- Formulaire authentification
|
||||
print 'Authentification: ', browser.url
|
||||
|
||||
browser.fill('__ac_name', USER)
|
||||
browser.fill('__ac_password', PASSWD)
|
||||
button = browser.find_by_id('submit')
|
||||
button[0].click()
|
||||
|
||||
# ---- Page accueil Dept
|
||||
print browser.url
|
||||
|
||||
links = browser.find_link_by_partial_text('DUT')
|
||||
links[0].click()
|
||||
print 'Starting test from %s' % browser.url
|
||||
print browser.title
|
@ -1,10 +0,0 @@
|
||||
|
||||
"""Put here the informations neeede to connect to your development test user
|
||||
"""
|
||||
|
||||
#SCODOC='https://scodoc.example.com/'
|
||||
SCODOC='https://scodoc.viennet.net/'
|
||||
USER = 'tester'
|
||||
#PASSWD = 'XXXXXXXXXXXX'
|
||||
PASSWD = '67un^:653'
|
||||
|
@ -1,51 +0,0 @@
|
||||
# -*- mode: python -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""Essais de base:
|
||||
|
||||
se connecte, accede a un semestre puis a un module,
|
||||
et modifie les notes existantes dans la premiere evaluation
|
||||
|
||||
"""
|
||||
|
||||
from common import *
|
||||
# ici on est sur la page d'accueil du departement !
|
||||
|
||||
links = browser.find_link_by_partial_text('DUT informatique en FI')
|
||||
links[0].click()
|
||||
|
||||
# ---- Tableau bord semestre
|
||||
print browser.url
|
||||
# va dans module AP2 saisir des notes (dans la p1ere evaluation):
|
||||
browser.find_link_by_partial_text('AP1').first.click()
|
||||
browser.find_link_by_partial_text('Saisir notes').first.click()
|
||||
|
||||
# ---- Ici c'est complique car le bouton submit est disabled
|
||||
# on construit l'url a la main:
|
||||
url = browser.find_by_id('gr')[0]["action"]
|
||||
evaluation_id = browser.find_by_name('evaluation_id').value
|
||||
group_id = re.search( r'value="(.*?)".*?tous', browser.html ).group(1)
|
||||
dest = urlparse.urljoin(url, 'notes_evaluation_formnotes?evaluation_id='+evaluation_id+'&group_ids:list='+group_id+'¬e_method=form')
|
||||
browser.visit(dest)
|
||||
|
||||
# ---- Change une note:
|
||||
# browser.fill('note_EID3835', '15')
|
||||
etudids = re.findall( r'name="note_(.*?)"', browser.html )[1:]
|
||||
note_max = float(re.search( r'notes sur ([0-9]+?)</span>\)', browser.html ).group(1))
|
||||
for etudid in etudids:
|
||||
# essaie d'ajouter 1 à la note !
|
||||
old_val = browser.find_by_name('note_%s' % etudid).value
|
||||
try:
|
||||
val = min(float(old_val) + 1, note_max)
|
||||
browser.fill('note_%s'%etudid, str(val))
|
||||
print etudid, old_val, '->', val
|
||||
except:
|
||||
pass
|
||||
|
||||
# ... et met la derniere au max (pour tester)
|
||||
browser.fill('note_%s'%etudids[-1], str(note_max))
|
||||
print etudids[-1], '->', note_max
|
||||
|
||||
# ---- Validation formulaire saisie notes:
|
||||
browser.find_by_id('tf_submit').click()
|
||||
browser.find_by_id('tf_submit').click()
|
@ -1,66 +0,0 @@
|
||||
#!/opt/zope213/bin/python
|
||||
# -*- mode: python -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""Essais de changements intensifs des notes
|
||||
(pour faire des tests en parallele)
|
||||
|
||||
se connecte, accede a un semestre puis a un module,
|
||||
et modifie les notes existantes dans la premiere evaluation
|
||||
|
||||
ajoute puis soustrait 1 aux notes valides, N fois
|
||||
|
||||
"""
|
||||
import time
|
||||
|
||||
from common import *
|
||||
# -> ici on est sur la page d'accueil du departement !
|
||||
|
||||
links = browser.find_link_by_partial_text('DUT')
|
||||
links[0].click() # va sur le 1er semestre de DUT trouve
|
||||
|
||||
# ---- Tableau bord semestre
|
||||
print browser.url
|
||||
# va dans module M1101 saisir des notes (dans la p1ere evaluation):
|
||||
browser.find_link_by_partial_text('M1101').first.click()
|
||||
browser.find_link_by_partial_text('Saisir notes').first.click()
|
||||
|
||||
# ---- Ici c'est complique car le bouton submit est disabled
|
||||
# on construit l'url a la main:
|
||||
url = browser.find_by_id('gr')[0]["action"]
|
||||
evaluation_id = browser.find_by_name('evaluation_id').value
|
||||
group_id = re.search( r'value="(.*?)".*?tous', browser.html ).group(1)
|
||||
url_form = urlparse.urljoin(url, 'notes_evaluation_formnotes?evaluation_id='+evaluation_id+'&group_ids:list='+group_id+'¬e_method=form')
|
||||
|
||||
|
||||
# ---- Ajoute une constante aux notes valides:
|
||||
# le browser doit etre sur le formulaire saisie note
|
||||
def add_to_notes(increment):
|
||||
etudids = re.findall( r'name="note_(.*?)"', browser.html )[1:]
|
||||
note_max = float(re.search( r'notes sur ([0-9]+?)</span>\)', browser.html ).group(1))
|
||||
print 'add_to_notes: %d etudiants' % len(etudids)
|
||||
for etudid in etudids:
|
||||
# essaie d'ajouter 1 a la note !
|
||||
old_val = browser.find_by_name('note_%s' % etudid).value
|
||||
try:
|
||||
val = max(0,min(float(old_val) + increment, note_max))
|
||||
browser.fill('note_%s'%etudid, str(val))
|
||||
print etudid, old_val, '->', val
|
||||
except:
|
||||
pass
|
||||
|
||||
# ---- Validation formulaire saisie notes:
|
||||
browser.find_by_id('tf_submit').click()
|
||||
browser.find_by_id('tf_submit').click()
|
||||
|
||||
|
||||
for i in range(10):
|
||||
browser.visit(url_form) # va sur form saisie notes
|
||||
add_to_notes(1)
|
||||
#time.sleep(1)
|
||||
browser.visit(url_form) # va sur form saisie notes
|
||||
add_to_notes(-1)
|
||||
#time.sleep(1)
|
||||
|
||||
t1 = time.time()
|
||||
print 'done in %gs' % (t1-t0)
|
@ -1,44 +0,0 @@
|
||||
# -*- mode: python -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""Modification decision de jury
|
||||
"""
|
||||
from common import *
|
||||
# -> ici on est sur la page d'accueil du departement !
|
||||
DeptURL = browser.url
|
||||
|
||||
# Cherche un formsemestre_id:
|
||||
links = browser.find_link_by_partial_text('DUT')
|
||||
u = links[0]['href']
|
||||
formsemestre_id = re.search( r'formsemestre_id=(SEM[0-9]*)', u ).group(1)
|
||||
|
||||
# Cherche les etudids
|
||||
browser.visit( urlparse.urljoin(DeptURL, 'formsemestre_recapcomplet?modejury=1&hidemodules=1&formsemestre_id=' + formsemestre_id) )
|
||||
|
||||
#u = browser.find_link_by_partial_href('formsemestre_bulletinetud')[0]['href']
|
||||
#etudid = re.search( r'etudid=([A-Za-z0-9]*)', u ).group(1)
|
||||
|
||||
L = browser.find_link_by_partial_href('formsemestre_bulletinetud')
|
||||
etudids = [ re.search(r'etudid=([A-Za-z0-9_]*)', x['href']).group(1) for x in L ]
|
||||
|
||||
def suppress_then_set( etudid, formsemestre_id, code='ADM' ):
|
||||
"""Supprime decision de jury pour cet étudiant dans ce semestre
|
||||
puis saisie de la decision (manuelle) indiquée par code
|
||||
"""
|
||||
# Suppression décision existante
|
||||
browser.visit( urlparse.urljoin(DeptURL, 'formsemestre_validation_suppress_etud?etudid=%s&formsemestre_id=%s&dialog_confirmed=1' % (etudid, formsemestre_id)))
|
||||
|
||||
# Saisie décision
|
||||
browser.visit( urlparse.urljoin(DeptURL, 'formsemestre_validation_etud_form?etudid=%s&formsemestre_id=%s' % (etudid, formsemestre_id)))
|
||||
browser.fill('code_etat', [code])
|
||||
browser.find_by_name('formvalidmanu_submit').first.click()
|
||||
# pas de verification de la page résultat
|
||||
|
||||
# Change decisions de jury de tous les étudiants:
|
||||
for etudid in etudids:
|
||||
print 'decision pour %s' % etudid
|
||||
suppress_then_set( etudid, formsemestre_id, code='ADM')
|
||||
|
||||
t1 = time.time()
|
||||
print '%d etudiants traites en %gs' % (len(etudids),t1-t0)
|
||||
|
@ -1,45 +0,0 @@
|
||||
# -*- mode: python -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Enregistre les moyennes générales de tous les étudiants de tous les
|
||||
semestres.
|
||||
A utiliser avec debug.py (côté serveur).
|
||||
"""
|
||||
|
||||
|
||||
from __future__ import print_function
|
||||
from debug import go_dept
|
||||
import time
|
||||
|
||||
from app.scodoc import sco_cache
|
||||
|
||||
DeptName = "CJ"
|
||||
context = go_dept(app, DeptName)
|
||||
|
||||
sems = context.Notes.formsemestre_list()
|
||||
|
||||
print("%d semestres" % len(sems))
|
||||
|
||||
L = []
|
||||
n = 0
|
||||
for sem in sems:
|
||||
formsemestre_id = sem["formsemestre_id"]
|
||||
nt = sco_cache.NotesTableCache.get(formsemestre_id)
|
||||
etudids = nt.get_etudids()
|
||||
use_ue_coef = sco_preferences.get_preference("use_ue_coefs", formsemestre_id)
|
||||
n += 1
|
||||
print("%d %s (%d) use_ue_coef=%s" % (n, formsemestre_id, len(etudids), use_ue_coef))
|
||||
for etudid in etudids:
|
||||
mg = nt.get_etud_moy_gen(etudid)
|
||||
L.append((formsemestre_id, str(use_ue_coef), etudid, str(mg)))
|
||||
|
||||
print("Done: %s moys computed" % len(L))
|
||||
|
||||
filename = "/opt/tests/%s-%s" % (DeptName, time.strftime("%Y-%m-%dT%H:%M:%S"))
|
||||
print("Writing file '%s'..." % filename)
|
||||
f = open(filename, "w")
|
||||
for l in L:
|
||||
f.write("\t".join(l) + "\n")
|
||||
|
||||
f.close()
|
@ -1,64 +0,0 @@
|
||||
# -*- mode: python -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""Petits essais sur les fichiers CSV Apogée
|
||||
|
||||
Utiliser avec
|
||||
/opt/scodoc/bin/zopectl debug
|
||||
|
||||
"""
|
||||
from __future__ import print_function
|
||||
from debug import *
|
||||
|
||||
import sco_apogee_csv
|
||||
import sco_apogee_compare
|
||||
|
||||
#data = open('/opt/scodoc/var/scodoc/archives/apo_csv/RT/2018-2/2019-09-23-15-46-40/V2RT2!116.csv', 'r').read()
|
||||
#data = open('/opt/scodoc/var/scodoc/archives/apo_csv/RT/2018-1/2019-02-20-11-53-05/V2RT!116.csv', 'r').read()
|
||||
data = open('/tmp/V2RT116.csv', 'r').read()
|
||||
A = sco_apogee_csv.ApoData(data)
|
||||
data = open('/tmp/V2RT116-modif.csv', 'r').read()
|
||||
B = sco_apogee_csv.ApoData(data)
|
||||
sco_apogee_compare.compare_etuds_res(A, B)
|
||||
|
||||
|
||||
|
||||
|
||||
A.col_ids
|
||||
# -> ['apoL_a01_code', 'apoL_a02_nom', 'apoL_a03_prenom', 'apoL_a04_naissance', 'apoL_c0001', 'apoL_c0002', 'apoL_c0003', 'apoL_c0004']
|
||||
|
||||
e = A.etuds[0]
|
||||
pp(e.cols)
|
||||
# {'apoL_a01_code': '11809768',
|
||||
# 'apoL_a02_nom': 'AKYOL',
|
||||
# 'apoL_a03_prenom': 'OLIVIER',
|
||||
# 'apoL_a04_naissance': ' 31/01/1999',
|
||||
# 'apoL_c0001': '',
|
||||
# 'apoL_c0002': '',
|
||||
# ... }
|
||||
|
||||
A.apo_elts.keys()
|
||||
# ['VRTW4', 'VRTW3', 'VRTU42', 'VRTU41', 'VRTU32', ... ]
|
||||
elt = A.apo_elts['VRT3101']
|
||||
|
||||
elt.code # 'VRT3102'
|
||||
|
||||
B = sco_apogee_csv.ApoData( open('/opt/tests/V2RT-modif.csv').read() )
|
||||
|
||||
# les colonnes de l'élément
|
||||
col_ids = [ ec['apoL_a01_code'] for ec in elt.cols ]
|
||||
e.cols['apoL_c0033']
|
||||
|
||||
common_nips = set([e["nip"] for e in A.etuds])
|
||||
A.etud_by_nip.keys()
|
||||
|
||||
B_etud_by_nip = { e["nip"] : e for e in B.etuds }
|
||||
|
||||
d = build_etud_res(B.etuds[0], B)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,46 +0,0 @@
|
||||
# -*- mode: python -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""Essai export des semestres impairs avec VET seulement pour les diplômés
|
||||
|
||||
Utiliser avec
|
||||
/opt/scodoc/bin/zopectl debug
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
from debug import *
|
||||
|
||||
import sco_apogee_csv
|
||||
import sco_parcours_dut
|
||||
|
||||
context = go_dept(app, 'RT').Notes
|
||||
|
||||
etudid='EID33751'
|
||||
formsemestre_id='SEM37099'
|
||||
|
||||
etud = context.getEtudInfo(etudid=etudid, filled=True)[0]
|
||||
Se = sco_parcours_dut.SituationEtudParcours(context, etud, formsemestre_id)
|
||||
|
||||
print(Se.all_other_validated())
|
||||
|
||||
|
||||
data = open('/opt/scodoc/var/scodoc/archives/apo_csv/RT/2019-1/2020-07-07-17-24-18/V2RT!117.csv', 'r').read()
|
||||
|
||||
apo_data = sco_apogee_csv.ApoData(data, periode=1, export_res_etape=False)
|
||||
|
||||
apo_data.setup(context)
|
||||
|
||||
ix = [ x['nom'] for x in apo_data.etuds ].index('HAMILA')
|
||||
|
||||
e = apo_data.etuds[ix]
|
||||
e.lookup_scodoc(context, apo_data.etape_formsemestre_ids)
|
||||
|
||||
e.associate_sco(context, apo_data)
|
||||
|
||||
pp({ k : e.new_cols[k] for k in e.new_cols if e.new_cols[k] != '' })
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,181 +0,0 @@
|
||||
# -*- mode: python -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""Test de base de ScoDoc
|
||||
|
||||
Création 10 étudiants, formation, semestre, inscription etudiant, creation 1 evaluation, saisie 10 notes.
|
||||
|
||||
Utiliser comme:
|
||||
flask test-interactive scotests/test_basic.py
|
||||
|
||||
"""
|
||||
import random
|
||||
|
||||
from flask import g
|
||||
|
||||
from app import decorators
|
||||
import scotests.sco_fake_gen as sco_fake_gen # pylint: disable=import-error
|
||||
from app.scodoc import sco_utils as scu
|
||||
from app.scodoc import sco_abs
|
||||
from app.scodoc import sco_abs_views
|
||||
from app.scodoc import sco_bulletins
|
||||
from app.scodoc import sco_evaluations
|
||||
from app.scodoc import sco_codes_parcours
|
||||
from app.scodoc import sco_parcours_dut
|
||||
from app.scodoc import sco_formsemestre_validation
|
||||
|
||||
|
||||
context = sco_fake_gen.Sco8Context()
|
||||
g.scodoc_dept = "TEST00"
|
||||
|
||||
G = sco_fake_gen.ScoFake(context)
|
||||
G.verbose = False
|
||||
|
||||
# --- Création d'étudiants
|
||||
etuds = [G.create_etud(code_nip=None) for _ in range(10)]
|
||||
|
||||
# --- Création d'une formation
|
||||
f = G.create_formation(acronyme="")
|
||||
ue = G.create_ue(formation_id=f["formation_id"], acronyme="TST1", titre="ue test")
|
||||
mat = G.create_matiere(ue_id=ue["ue_id"], titre="matière test")
|
||||
mod = G.create_module(
|
||||
matiere_id=mat["matiere_id"],
|
||||
code="TSM1",
|
||||
coefficient=1.0,
|
||||
titre="module test",
|
||||
ue_id=ue["ue_id"], # faiblesse de l'API
|
||||
formation_id=f["formation_id"], # faiblesse de l'API
|
||||
)
|
||||
|
||||
# --- Mise place d'un semestre
|
||||
sem = G.create_formsemestre(
|
||||
formation_id=f["formation_id"],
|
||||
semestre_id=1,
|
||||
date_debut="01/01/2020",
|
||||
date_fin="30/06/2020",
|
||||
)
|
||||
|
||||
mi = G.create_moduleimpl(
|
||||
module_id=mod["module_id"],
|
||||
formsemestre_id=sem["formsemestre_id"],
|
||||
responsable_id="bach",
|
||||
)
|
||||
|
||||
# --- Inscription des étudiants
|
||||
for etud in etuds:
|
||||
G.inscrit_etudiant(sem, etud)
|
||||
|
||||
# --- Creation évaluation
|
||||
e = G.create_evaluation(
|
||||
moduleimpl_id=mi["moduleimpl_id"],
|
||||
jour="01/01/2020",
|
||||
description="evaluation test",
|
||||
coefficient=1.0,
|
||||
)
|
||||
|
||||
# --- Saisie toutes les notes de l'évaluation
|
||||
for etud in etuds:
|
||||
nb_changed, nb_suppress, existing_decisions = G.create_note(
|
||||
evaluation=e, etud=etud, note=float(random.randint(0, 20))
|
||||
)
|
||||
|
||||
# --- Vérifie que les notes sont prises en compte:
|
||||
b = sco_bulletins.formsemestre_bulletinetud_dict(
|
||||
context, sem["formsemestre_id"], etud["etudid"], REQUEST=REQUEST
|
||||
)
|
||||
# Toute les notes sont saisies, donc eval complète
|
||||
etat = sco_evaluations.do_evaluation_etat(context, e["evaluation_id"])
|
||||
assert etat["evalcomplete"]
|
||||
# Un seul module, donc moy gen == note module
|
||||
assert b["ues"][0]["cur_moy_ue_txt"] == b["ues"][0]["modules"][0]["mod_moy_txt"]
|
||||
# Note au module égale à celle de l'éval
|
||||
assert (
|
||||
b["ues"][0]["modules"][0]["mod_moy_txt"]
|
||||
== b["ues"][0]["modules"][0]["evaluations"][0]["note_txt"]
|
||||
)
|
||||
|
||||
# --- Une autre évaluation
|
||||
e2 = G.create_evaluation(
|
||||
moduleimpl_id=mi["moduleimpl_id"],
|
||||
jour="02/01/2020",
|
||||
description="evaluation test 2",
|
||||
coefficient=1.0,
|
||||
)
|
||||
# Saisie les notes des 5 premiers étudiants:
|
||||
for etud in etuds[:5]:
|
||||
nb_changed, nb_suppress, existing_decisions = G.create_note(
|
||||
evaluation=e2, etud=etud, note=float(random.randint(0, 20))
|
||||
)
|
||||
# Cette éval n'est pas complète
|
||||
etat = sco_evaluations.do_evaluation_etat(context, e2["evaluation_id"])
|
||||
assert etat["evalcomplete"] == False
|
||||
# la première éval est toujours complète:
|
||||
etat = sco_evaluations.do_evaluation_etat(context, e["evaluation_id"])
|
||||
assert etat["evalcomplete"]
|
||||
|
||||
# Modifie l'évaluation 2 pour "prise en compte immédiate"
|
||||
e2["publish_incomplete"] = "1"
|
||||
sco_evaluations.do_evaluation_edit(context, REQUEST, e2)
|
||||
etat = sco_evaluations.do_evaluation_etat(context, e2["evaluation_id"])
|
||||
assert etat["evalcomplete"] == False
|
||||
assert etat["nb_att"] == 0 # il n'y a pas de notes (explicitement) en attente
|
||||
assert etat["evalattente"] # mais l'eval est en attente (prise en compte immédiate)
|
||||
|
||||
# Saisie des notes qui manquent:
|
||||
for etud in etuds[5:]:
|
||||
nb_changed, nb_suppress, existing_decisions = G.create_note(
|
||||
evaluation=e2, etud=etud, note=float(random.randint(0, 20))
|
||||
)
|
||||
etat = sco_evaluations.do_evaluation_etat(context, e2["evaluation_id"])
|
||||
assert etat["evalcomplete"]
|
||||
assert etat["nb_att"] == 0
|
||||
assert not etat["evalattente"] # toutes les notes sont présentes
|
||||
|
||||
# --- Saisie absences
|
||||
etudid = etuds[0]["etudid"]
|
||||
|
||||
_ = sco_abs_views.doSignaleAbsence(
|
||||
context,
|
||||
"15/01/2020",
|
||||
"18/01/2020",
|
||||
demijournee=2,
|
||||
etudid=etudid,
|
||||
REQUEST=REQUEST,
|
||||
)
|
||||
|
||||
_ = sco_abs_views.doJustifAbsence(
|
||||
context,
|
||||
"17/01/2020",
|
||||
"18/01/2020",
|
||||
demijournee=2,
|
||||
etudid=etudid,
|
||||
REQUEST=REQUEST,
|
||||
)
|
||||
|
||||
nbabs, nbabsjust = sco_abs.get_abs_count(etudid, sem)
|
||||
assert nbabs == 6, "incorrect nbabs (%d)" % nbabs
|
||||
assert nbabsjust == 2, "incorrect nbabsjust (%s)" % nbabsjust
|
||||
|
||||
# --- Permission saisie notes et décisions de jury, avec ou sans démission ou défaillance
|
||||
# on n'a pas encore saisi de décisions
|
||||
assert not sco_parcours_dut.formsemestre_has_decisions(context, sem["formsemestre_id"])
|
||||
# Saisie d'un décision AJ, non assidu
|
||||
etudid = etuds[-1]["etudid"]
|
||||
sco_parcours_dut.formsemestre_validate_ues(
|
||||
context,
|
||||
sem["formsemestre_id"],
|
||||
etudid,
|
||||
sco_codes_parcours.AJ,
|
||||
False,
|
||||
REQUEST=REQUEST,
|
||||
)
|
||||
assert sco_parcours_dut.formsemestre_has_decisions(
|
||||
context, sem["formsemestre_id"]
|
||||
), "décisions manquantes"
|
||||
# Suppression de la décision
|
||||
sco_formsemestre_validation.formsemestre_validation_suppress_etud(
|
||||
context, sem["formsemestre_id"], etudid
|
||||
)
|
||||
assert not sco_parcours_dut.formsemestre_has_decisions(
|
||||
context, sem["formsemestre_id"]
|
||||
), "décisions non effacées"
|
@ -1,19 +0,0 @@
|
||||
# -*- mode: python -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sys
|
||||
from pyExcelerator import *
|
||||
|
||||
#UnicodeUtils.DEFAULT_ENCODING = 'utf-8'
|
||||
|
||||
wb = Workbook()
|
||||
|
||||
title = "Essai"
|
||||
|
||||
ws = wb.add_sheet(u"çelé")
|
||||
|
||||
ws.write(1,1, "çeci où".decode('utf-8'))
|
||||
ws.write(2,2, "Hélène".decode('utf-8'))
|
||||
|
||||
wb.save("toto.xls")
|
||||
|
@ -1,6 +1,7 @@
|
||||
import pytest
|
||||
|
||||
from flask import g
|
||||
from flask_login import login_user, logout_user, current_user
|
||||
|
||||
import app as myapp
|
||||
from app import db, create_app
|
||||
@ -14,16 +15,25 @@ def test_client():
|
||||
# Setup
|
||||
myapp.Config.TESTING = True
|
||||
myapp.Config.SQLALCHEMY_DATABASE_URI = "sqlite://"
|
||||
myapp.Config.SERVER_NAME = "test.gr"
|
||||
apptest = create_app()
|
||||
# Run tests:
|
||||
with apptest.test_client() as client:
|
||||
with apptest.app_context():
|
||||
db.create_all()
|
||||
Role.insert_roles()
|
||||
g.scodoc_dept = "RT"
|
||||
g.db_conn = ndb.open_dept_connection()
|
||||
yield client
|
||||
ndb.close_dept_connection()
|
||||
# Teardown:
|
||||
db.session.remove()
|
||||
db.drop_all()
|
||||
with apptest.test_request_context():
|
||||
db.create_all()
|
||||
Role.insert_roles()
|
||||
u = User(user_name="admin")
|
||||
admin_role = Role.query.filter_by(name="Admin").first()
|
||||
u.add_role(admin_role, "TEST00")
|
||||
# u.set_password("admin")
|
||||
login_user(u)
|
||||
# db.session.add(u)
|
||||
|
||||
g.scodoc_dept = "RT"
|
||||
g.db_conn = ndb.open_dept_connection()
|
||||
yield client
|
||||
# ndb.close_dept_connection()
|
||||
# Teardown:
|
||||
db.session.remove()
|
||||
db.drop_all()
|
||||
|
1
tests/unit/__init__.py
Normal file
1
tests/unit/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
# Unit tests
|
@ -4,11 +4,10 @@
|
||||
"""Creation environnement pour test.
|
||||
A utiliser avec debug.py (côté serveur).
|
||||
|
||||
La classe ScoFake offre un ensemble de raccourcis permettant d'écrire
|
||||
La classe ScoFake offre un ensemble de raccourcis permettant d'écrire
|
||||
facilement des tests ou de reproduire des bugs.
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
from functools import wraps
|
||||
import sys
|
||||
import string
|
||||
@ -47,7 +46,9 @@ PRENOMS_H = [x.strip() for x in open(DEMO_DIR + "/prenoms-h.txt").readlines()]
|
||||
PRENOMS_F = [x.strip() for x in open(DEMO_DIR + "/prenoms-f.txt").readlines()]
|
||||
PRENOMS_X = [x.strip() for x in open(DEMO_DIR + "/prenoms-x.txt").readlines()]
|
||||
|
||||
# nb: en python2, les chaines ci-dessus sont en utf8
|
||||
# En ScoDoc 8 le "context" ne sert plus (remplacé par les contextes de Flask)
|
||||
# Laisse cette globale pendant la transition du code #sco8 #context
|
||||
context = None
|
||||
|
||||
|
||||
def id_generator(size=6, chars=string.ascii_uppercase + string.digits):
|
||||
@ -58,15 +59,16 @@ def logging_meth(func):
|
||||
@wraps(func)
|
||||
def wrapper_logging_meth(self, *args, **kwargs):
|
||||
r = func(self, *args, **kwargs)
|
||||
self.log("%s(%s) -> \n%s" % (func.__name__, kwargs, pprint.pformat(r)))
|
||||
# self.log("%s(%s) -> \n%s" % (func.__name__, kwargs, pprint.pformat(r)))
|
||||
return r
|
||||
|
||||
return wrapper_logging_meth
|
||||
|
||||
|
||||
class ScoFake(object):
|
||||
def __init__(self, context, verbose=True):
|
||||
self.context = context
|
||||
"""Helper for ScoSoc tests"""
|
||||
|
||||
def __init__(self, verbose=True):
|
||||
self.verbose = verbose
|
||||
|
||||
def log(self, msg):
|
||||
@ -127,10 +129,10 @@ class ScoFake(object):
|
||||
nom = r_nom
|
||||
if not prenom:
|
||||
prenom = r_prenom
|
||||
etud = sco_etud.create_etud(self.context, cnx, args=locals(), REQUEST=REQUEST)
|
||||
inscription = "2020" # pylint: disable=unused-variable
|
||||
etud = sco_etud.create_etud(context, cnx, args=locals(), REQUEST=REQUEST)
|
||||
inscription = "2020" # pylint: disable=possibly-unused-variable
|
||||
sco_synchro_etuds.do_import_etud_admission(
|
||||
self.context, cnx, etud["etudid"], locals()
|
||||
context, cnx, etud["etudid"], locals()
|
||||
)
|
||||
return etud
|
||||
|
||||
@ -147,10 +149,8 @@ class ScoFake(object):
|
||||
"""Crée une formation"""
|
||||
if not acronyme:
|
||||
acronyme = "TEST" + str(random.randint(100000, 999999))
|
||||
oid = sco_edit_formation.do_formation_create(
|
||||
self.context, locals(), REQUEST=REQUEST
|
||||
)
|
||||
oids = sco_formations.formation_list(self.context, formation_id=oid)
|
||||
oid = sco_edit_formation.do_formation_create(context, locals(), REQUEST=REQUEST)
|
||||
oids = sco_formations.formation_list(context, formation_id=oid)
|
||||
if not oids:
|
||||
raise ScoValueError("formation not created !")
|
||||
return oids[0]
|
||||
@ -171,17 +171,17 @@ class ScoFake(object):
|
||||
):
|
||||
"""Crée une UE"""
|
||||
if numero is None:
|
||||
numero = sco_edit_ue.next_ue_numero(self.context, formation_id, 0)
|
||||
oid = sco_edit_ue.do_ue_create(self.context, locals(), REQUEST)
|
||||
oids = sco_edit_ue.do_ue_list(self.context, args={"ue_id": oid})
|
||||
numero = sco_edit_ue.next_ue_numero(context, formation_id, 0)
|
||||
oid = sco_edit_ue.do_ue_create(context, locals(), REQUEST)
|
||||
oids = sco_edit_ue.do_ue_list(context, args={"ue_id": oid})
|
||||
if not oids:
|
||||
raise ScoValueError("ue not created !")
|
||||
return oids[0]
|
||||
|
||||
@logging_meth
|
||||
def create_matiere(self, ue_id=None, titre=None, numero=None):
|
||||
oid = sco_edit_matiere.do_matiere_create(self.context, locals(), REQUEST)
|
||||
oids = sco_edit_matiere.do_matiere_list(self.context, args={"matiere_id": oid})
|
||||
oid = sco_edit_matiere.do_matiere_create(context, locals(), REQUEST)
|
||||
oids = sco_edit_matiere.do_matiere_list(context, args={"matiere_id": oid})
|
||||
if not oids:
|
||||
raise ScoValueError("matiere not created !")
|
||||
return oids[0]
|
||||
@ -205,8 +205,8 @@ class ScoFake(object):
|
||||
code_apogee=None,
|
||||
module_type=None,
|
||||
):
|
||||
oid = sco_edit_module.do_module_create(self.context, locals(), REQUEST)
|
||||
oids = sco_edit_module.do_module_list(self.context, args={"module_id": oid})
|
||||
oid = sco_edit_module.do_module_create(context, locals(), REQUEST)
|
||||
oids = sco_edit_module.do_module_list(context, args={"module_id": oid})
|
||||
if not oids:
|
||||
raise ScoValueError("module not created ! (oid=%s)" % oid)
|
||||
return oids[0]
|
||||
@ -231,12 +231,11 @@ class ScoFake(object):
|
||||
elt_sem_apo=None,
|
||||
elt_annee_apo=None,
|
||||
etapes=None,
|
||||
responsables=["bach"],
|
||||
responsables=("bach",),
|
||||
):
|
||||
oid = sco_formsemestre.do_formsemestre_create(locals())
|
||||
# oids = self.context.do_formsemestre_list(args={"formsemestre_id": oid})
|
||||
oids = sco_formsemestre.do_formsemestre_list(
|
||||
self.context, args={"formsemestre_id": oid}
|
||||
context, args={"formsemestre_id": oid}
|
||||
) # API inconsistency
|
||||
if not oids:
|
||||
raise ScoValueError("formsemestre not created !")
|
||||
@ -249,9 +248,9 @@ class ScoFake(object):
|
||||
formsemestre_id=None,
|
||||
responsable_id=None,
|
||||
):
|
||||
oid = sco_moduleimpl.do_moduleimpl_create(self.context, locals())
|
||||
oid = sco_moduleimpl.do_moduleimpl_create(context, locals())
|
||||
oids = sco_moduleimpl.do_moduleimpl_list(
|
||||
self.context, moduleimpl_id=oid
|
||||
context, moduleimpl_id=oid
|
||||
) # API inconsistency
|
||||
if not oids:
|
||||
raise ScoValueError("moduleimpl not created !")
|
||||
@ -260,7 +259,7 @@ class ScoFake(object):
|
||||
@logging_meth
|
||||
def inscrit_etudiant(self, sem, etud):
|
||||
sco_formsemestre_inscriptions.do_formsemestre_inscription_with_modules(
|
||||
self.context,
|
||||
context,
|
||||
sem["formsemestre_id"],
|
||||
etud["etudid"],
|
||||
etat="I",
|
||||
@ -287,10 +286,8 @@ class ScoFake(object):
|
||||
):
|
||||
args = locals()
|
||||
del args["self"]
|
||||
oid = sco_evaluations.do_evaluation_create(self.context, **args)
|
||||
oids = sco_evaluations.do_evaluation_list(
|
||||
self.context, args={"evaluation_id": oid}
|
||||
)
|
||||
oid = sco_evaluations.do_evaluation_create(**args)
|
||||
oids = sco_evaluations.do_evaluation_list(args={"evaluation_id": oid})
|
||||
if not oids:
|
||||
raise ScoValueError("evaluation not created !")
|
||||
return oids[0]
|
||||
@ -305,7 +302,7 @@ class ScoFake(object):
|
||||
uid="bach",
|
||||
):
|
||||
return sco_saisie_notes._notes_add(
|
||||
self.context,
|
||||
context,
|
||||
uid,
|
||||
evaluation["evaluation_id"],
|
||||
[(etud["etudid"], note)],
|
||||
@ -422,7 +419,7 @@ class ScoFake(object):
|
||||
):
|
||||
"""Affecte décision de jury"""
|
||||
sco_formsemestre_validation.formsemestre_validation_etud_manu(
|
||||
self.context,
|
||||
context,
|
||||
formsemestre_id=sem["formsemestre_id"],
|
||||
etudid=etud["etudid"],
|
||||
code_etat=code_etat,
|
@ -17,11 +17,12 @@ from app.scodoc import sco_evaluations
|
||||
from app.scodoc import sco_formsemestre
|
||||
|
||||
DEPT = "RT" # ce département (BD) doit exister
|
||||
context = None # #context
|
||||
|
||||
|
||||
def test_notes_table(test_client):
|
||||
"""Test construction et cache de NotesTable"""
|
||||
sems = sco_formsemestre.do_formsemestre_list(None)
|
||||
sems = sco_formsemestre.do_formsemestre_list(context)
|
||||
assert len(sems)
|
||||
sem = sems[0]
|
||||
formsemestre_id = sem["formsemestre_id"]
|
||||
|
178
tests/unit/test_sco_basic.py
Normal file
178
tests/unit/test_sco_basic.py
Normal file
@ -0,0 +1,178 @@
|
||||
# -*- mode: python -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""Test de base de ScoDoc
|
||||
|
||||
|
||||
Utiliser comme:
|
||||
pytest tests/unit/test_sco_basic.py
|
||||
|
||||
"""
|
||||
import random
|
||||
|
||||
from flask import g
|
||||
|
||||
from tests.unit import sco_fake_gen
|
||||
|
||||
from app import decorators
|
||||
from app.scodoc import notesdb as ndb
|
||||
from app.scodoc import sco_utils as scu
|
||||
from app.scodoc import sco_abs
|
||||
from app.scodoc import sco_abs_views
|
||||
from app.scodoc import sco_bulletins
|
||||
from app.scodoc import sco_evaluations
|
||||
from app.scodoc import sco_codes_parcours
|
||||
from app.scodoc import sco_parcours_dut
|
||||
from app.scodoc import sco_formsemestre_validation
|
||||
|
||||
context = None # #context
|
||||
|
||||
|
||||
def test_sco_basic(test_client):
|
||||
"""Test quelques opérations élémentaires de ScoDoc
|
||||
Création 10 étudiants, formation, semestre, inscription etudiant,
|
||||
creation 1 evaluation, saisie 10 notes.
|
||||
"""
|
||||
ndb.set_sco_dept("TEST00") # ce département doit exister !
|
||||
G = sco_fake_gen.ScoFake(verbose=False)
|
||||
G.verbose = True
|
||||
|
||||
# --- Création d'étudiants
|
||||
etuds = [G.create_etud(code_nip=None) for _ in range(10)]
|
||||
|
||||
# --- Création d'une formation
|
||||
f = G.create_formation(acronyme="")
|
||||
ue = G.create_ue(formation_id=f["formation_id"], acronyme="TST1", titre="ue test")
|
||||
mat = G.create_matiere(ue_id=ue["ue_id"], titre="matière test")
|
||||
mod = G.create_module(
|
||||
matiere_id=mat["matiere_id"],
|
||||
code="TSM1",
|
||||
coefficient=1.0,
|
||||
titre="module test",
|
||||
ue_id=ue["ue_id"], # faiblesse de l'API
|
||||
formation_id=f["formation_id"], # faiblesse de l'API
|
||||
)
|
||||
|
||||
# --- Mise place d'un semestre
|
||||
sem = G.create_formsemestre(
|
||||
formation_id=f["formation_id"],
|
||||
semestre_id=1,
|
||||
date_debut="01/01/2020",
|
||||
date_fin="30/06/2020",
|
||||
)
|
||||
|
||||
mi = G.create_moduleimpl(
|
||||
module_id=mod["module_id"],
|
||||
formsemestre_id=sem["formsemestre_id"],
|
||||
responsable_id="bach",
|
||||
)
|
||||
|
||||
# --- Inscription des étudiants
|
||||
for etud in etuds:
|
||||
G.inscrit_etudiant(sem, etud)
|
||||
|
||||
# --- Creation évaluation
|
||||
e = G.create_evaluation(
|
||||
moduleimpl_id=mi["moduleimpl_id"],
|
||||
jour="01/01/2020",
|
||||
description="evaluation test",
|
||||
coefficient=1.0,
|
||||
)
|
||||
|
||||
# --- Saisie toutes les notes de l'évaluation
|
||||
for etud in etuds:
|
||||
nb_changed, nb_suppress, existing_decisions = G.create_note(
|
||||
evaluation=e, etud=etud, note=float(random.randint(0, 20))
|
||||
)
|
||||
|
||||
# --- Vérifie que les notes sont prises en compte:
|
||||
b = sco_bulletins.formsemestre_bulletinetud_dict(
|
||||
context, sem["formsemestre_id"], etud["etudid"]
|
||||
)
|
||||
# Toute les notes sont saisies, donc eval complète
|
||||
etat = sco_evaluations.do_evaluation_etat(e["evaluation_id"])
|
||||
assert etat["evalcomplete"]
|
||||
# Un seul module, donc moy gen == note module
|
||||
assert b["ues"][0]["cur_moy_ue_txt"] == b["ues"][0]["modules"][0]["mod_moy_txt"]
|
||||
# Note au module égale à celle de l'éval
|
||||
assert (
|
||||
b["ues"][0]["modules"][0]["mod_moy_txt"]
|
||||
== b["ues"][0]["modules"][0]["evaluations"][0]["note_txt"]
|
||||
)
|
||||
|
||||
# --- Une autre évaluation
|
||||
e2 = G.create_evaluation(
|
||||
moduleimpl_id=mi["moduleimpl_id"],
|
||||
jour="02/01/2020",
|
||||
description="evaluation test 2",
|
||||
coefficient=1.0,
|
||||
)
|
||||
# Saisie les notes des 5 premiers étudiants:
|
||||
for etud in etuds[:5]:
|
||||
nb_changed, nb_suppress, existing_decisions = G.create_note(
|
||||
evaluation=e2, etud=etud, note=float(random.randint(0, 20))
|
||||
)
|
||||
# Cette éval n'est pas complète
|
||||
etat = sco_evaluations.do_evaluation_etat(e2["evaluation_id"])
|
||||
assert etat["evalcomplete"] == False
|
||||
# la première éval est toujours complète:
|
||||
etat = sco_evaluations.do_evaluation_etat(e["evaluation_id"])
|
||||
assert etat["evalcomplete"]
|
||||
|
||||
# Modifie l'évaluation 2 pour "prise en compte immédiate"
|
||||
e2["publish_incomplete"] = "1"
|
||||
sco_evaluations.do_evaluation_edit(e2)
|
||||
etat = sco_evaluations.do_evaluation_etat(e2["evaluation_id"])
|
||||
assert etat["evalcomplete"] == False
|
||||
assert etat["nb_att"] == 0 # il n'y a pas de notes (explicitement) en attente
|
||||
assert etat["evalattente"] # mais l'eval est en attente (prise en compte immédiate)
|
||||
|
||||
# Saisie des notes qui manquent:
|
||||
for etud in etuds[5:]:
|
||||
nb_changed, nb_suppress, existing_decisions = G.create_note(
|
||||
evaluation=e2, etud=etud, note=float(random.randint(0, 20))
|
||||
)
|
||||
etat = sco_evaluations.do_evaluation_etat(e2["evaluation_id"])
|
||||
assert etat["evalcomplete"]
|
||||
assert etat["nb_att"] == 0
|
||||
assert not etat["evalattente"] # toutes les notes sont présentes
|
||||
|
||||
# --- Saisie absences
|
||||
etudid = etuds[0]["etudid"]
|
||||
|
||||
_ = sco_abs_views.doSignaleAbsence(
|
||||
context, "15/01/2020", "18/01/2020", demijournee=2, etudid=etudid
|
||||
)
|
||||
|
||||
_ = sco_abs_views.doJustifAbsence(
|
||||
context,
|
||||
"17/01/2020",
|
||||
"18/01/2020",
|
||||
demijournee=2,
|
||||
etudid=etudid,
|
||||
)
|
||||
|
||||
nbabs, nbabsjust = sco_abs.get_abs_count(etudid, sem)
|
||||
assert nbabs == 6, "incorrect nbabs (%d)" % nbabs
|
||||
assert nbabsjust == 2, "incorrect nbabsjust (%s)" % nbabsjust
|
||||
|
||||
# --- Permission saisie notes et décisions de jury, avec ou sans démission ou défaillance
|
||||
# on n'a pas encore saisi de décisions
|
||||
assert not sco_parcours_dut.formsemestre_has_decisions(
|
||||
context, sem["formsemestre_id"]
|
||||
)
|
||||
# Saisie d'un décision AJ, non assidu
|
||||
etudid = etuds[-1]["etudid"]
|
||||
sco_parcours_dut.formsemestre_validate_ues(
|
||||
context, sem["formsemestre_id"], etudid, sco_codes_parcours.AJ, False
|
||||
)
|
||||
assert sco_parcours_dut.formsemestre_has_decisions(
|
||||
context, sem["formsemestre_id"]
|
||||
), "décisions manquantes"
|
||||
# Suppression de la décision
|
||||
sco_formsemestre_validation.formsemestre_validation_suppress_etud(
|
||||
context, sem["formsemestre_id"], etudid
|
||||
)
|
||||
assert not sco_parcours_dut.formsemestre_has_decisions(
|
||||
context, sem["formsemestre_id"]
|
||||
), "décisions non effacées"
|
@ -1,20 +1,16 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Create database for a ScoDoc instance
|
||||
# This script must be executed as root
|
||||
# Create database for a ScoDoc departement
|
||||
# This script must be executed as postgres super user
|
||||
#
|
||||
# $db_name is passed as an environment variable
|
||||
|
||||
source config.sh
|
||||
source utils.sh
|
||||
|
||||
check_uid_root "$0"
|
||||
|
||||
# 1--- CREATION UTILISATEUR POSTGRESQL
|
||||
init_postgres_user
|
||||
|
||||
# 2--- CREATION BASE UTILISATEURS
|
||||
echo 'Creating postgresql database for users:' "$SCODOC_USER_DB"
|
||||
su -c "createdb -E UTF-8 -p $POSTGRES_PORT -O $SCODOC_USER $SCODOC_USER_DB" $POSTGRES_SUPERUSER
|
||||
echo 'Creating postgresql database'
|
||||
|
||||
# ---
|
||||
echo 'Creating postgresql database ' $db_name
|
||||
createdb -E UTF-8 -p $POSTGRES_PORT -O $POSTGRES_USER $db_name
|
||||
|
||||
|
@ -56,13 +56,13 @@ then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# --- Ensure postgres user scodoc exists
|
||||
# --- Ensure postgres user "scodoc" ($POSTGRES_USER) exists
|
||||
init_postgres_user
|
||||
|
||||
# ----------------------- Create database
|
||||
su -c ./create_database.sh "$POSTGRES_SUPERUSER"
|
||||
# ----------------------- Create Dept database
|
||||
su -c ./create_database.sh "$POSTGRES_SUPERUSER"
|
||||
|
||||
# ----------------------- Create tables
|
||||
# ----------------------- Initialize table database
|
||||
# POSTGRES_USER == regular unix user (scodoc)
|
||||
if [ "$interactive" = 1 ]
|
||||
then
|
||||
@ -91,8 +91,5 @@ then
|
||||
echo " Departement $DEPT cree"
|
||||
echo
|
||||
echo " Attention: la base de donnees n'a pas de copies de sauvegarde"
|
||||
echo
|
||||
echo " Maintenant, vous pouvez ajouter le departement via l'application web"
|
||||
echo " en suivant le lien \"Administration de ScoDoc\" sur la page d'accueil."
|
||||
echo
|
||||
fi
|
||||
|
18
tools/create_users_database.sh
Normal file
18
tools/create_users_database.sh
Normal file
@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Create USERS database for ScoDoc 8
|
||||
# This script must be executed as root
|
||||
#
|
||||
# $db_name is passed as an environment variable
|
||||
|
||||
source config.sh
|
||||
source utils.sh
|
||||
|
||||
check_uid_root "$0"
|
||||
|
||||
# 1--- CREATION UTILISATEUR POSTGRESQL
|
||||
init_postgres_user
|
||||
|
||||
# 2--- CREATION BASE UTILISATEURS
|
||||
echo 'Creating postgresql database for users:' "$SCODOC_USER_DB"
|
||||
su -c "createdb -E UTF-8 -p $POSTGRES_PORT -O $SCODOC_USER $SCODOC_USER_DB" "$POSTGRES_SUPERUSER"
|
Loading…
Reference in New Issue
Block a user