clean: remove tests

This commit is contained in:
2025-08-05 21:23:49 +02:00
parent 91eb04ca01
commit 8708606d4f
14 changed files with 0 additions and 1142 deletions

View File

@@ -1,95 +0,0 @@
# Tests Unitaires
Ce dossier contient les tests unitaires pour l'application de gestion scolaire.
## Structure des tests
```
tests/
├── __init__.py
├── conftest.py # Configuration globale des tests
├── test_app.py # Tests de l'application Flask
├── test_models.py # Tests des modèles SQLAlchemy
├── test_forms.py # Tests des formulaires WTForms
├── test_services.py # Tests des services métier
├── test_routes_assessments.py # Tests des routes d'évaluations
└── test_utils.py # Tests des utilitaires
```
## Exécution des tests
### Avec uv (recommandé)
```bash
# Installer les dépendances de test
uv sync
# Exécuter tous les tests
uv run pytest tests/ -v
# Exécuter avec couverture de code
uv run pytest tests/ --cov=. --cov-report=html
# Exécuter des tests spécifiques
uv run pytest tests/test_models.py -v
uv run pytest tests/test_models.py::TestClassGroup -v
```
### Avec le script personnalisé
```bash
# Tous les tests
uv run python run_tests.py
# Avec rapport de couverture
uv run python run_tests.py --coverage
# Tests d'un fichier spécifique
uv run python run_tests.py test_models.py
# Mode silencieux
uv run python run_tests.py --quiet
```
## Configuration
Les tests utilisent:
- **pytest** comme framework de test
- **pytest-flask** pour l'intégration Flask
- **pytest-cov** pour la couverture de code
- **SQLite en mémoire** pour les tests de base de données
## Couverture des tests
Les tests couvrent:
- ✅ Modèles SQLAlchemy (création, validation, relations)
- ✅ Configuration de l'application Flask
- ✅ Services métier (AssessmentService)
- ✅ Utilitaires (validation, gestion d'erreurs)
- ✅ Formulaires WTForms (validation)
- ✅ Routes principales (responses HTTP)
## Bonnes pratiques
1. **Isolation**: Chaque test utilise une base de données temporaire
2. **Fixtures**: Configuration partagée dans `conftest.py`
3. **Nommage**: Tests préfixés par `test_`
4. **Organisation**: Tests groupés par classe selon la fonctionnalité
5. **Assertions**: Vérifications claires et spécifiques
## Ajout de nouveaux tests
Pour ajouter de nouveaux tests:
1. Créer un fichier `test_<module>.py`
2. Importer les fixtures nécessaires
3. OU utiliser les fixtures existantes (`app`, `client`)
4. Suivre la convention de nommage
Exemple:
```python
def test_my_function(app):
with app.app_context():
# Votre test ici
assert True
```

View File

@@ -0,0 +1,106 @@
#!/usr/bin/env python3
"""
Test final pour valider que le système de configuration des échelles
fonctionne correctement de bout en bout.
"""
from app import create_app
from app_config import config_manager
def test_final_validation():
"""Test final de validation du système."""
app = create_app('development')
with app.app_context():
print("=== VALIDATION FINALE : Système de configuration des échelles ===\n")
# 1. Test des modifications via l'interface de configuration
print("1. Test des modifications via config_manager:")
# Modifier le label de la valeur '1'
success = config_manager.update_scale_value('1', 'EN APPRENTISSAGE', '#ff9900', True)
print(f" Modification '1''EN APPRENTISSAGE': {success}")
# Vérifier que la modification est persistée
updated_values = config_manager.get_competence_scale_values()
print(f" Nouveau label pour '1': '{updated_values['1']['label']}'")
print(f" Nouvelle couleur pour '1': '{updated_values['1']['color']}'")
# 2. Test d'affichage dynamique
print("\n2. Test d'affichage dynamique:")
display_info = config_manager.get_display_info('1', 'score')
print(f" get_display_info('1', 'score'): {display_info}")
# 3. Test avec l'interface de notation
print("\n3. Test d'intégration avec l'interface de notation:")
with app.test_client() as client:
# Accéder à une page de notation
response = client.get('/assessments/1/grading')
if response.status_code == 200:
content = response.get_data(as_text=True)
# Vérifier que les labels modifiés apparaissent
if 'EN APPRENTISSAGE' in content:
print(" ✅ Label 'EN APPRENTISSAGE' trouvé dans l'interface de notation")
else:
print(" ❌ Label 'EN APPRENTISSAGE' non trouvé dans l'interface")
if 'SUPER ACQUIS' in content:
print(" ✅ Label 'SUPER ACQUIS' trouvé dans l'interface de notation")
else:
print(" ❌ Label 'SUPER ACQUIS' non trouvé dans l'interface")
else:
print(f" ❌ Erreur d'accès à l'interface de notation: {response.status_code}")
# 4. Test de la page de configuration
print("\n4. Test de la page de configuration:")
with app.test_client() as client:
response = client.get('/config/scale')
if response.status_code == 200:
content = response.get_data(as_text=True)
if 'EN APPRENTISSAGE' in content:
print(" ✅ Label 'EN APPRENTISSAGE' trouvé dans la page de configuration")
else:
print(" ❌ Label 'EN APPRENTISSAGE' non trouvé dans la page de configuration")
else:
print(f" ❌ Erreur d'accès à la page de configuration: {response.status_code}")
# 5. Test de cohérence finale
print("\n5. Test de cohérence finale:")
all_consistent = True
scale_values = config_manager.get_competence_scale_values()
for value in ['0', '1', '2', '3']:
if value in scale_values:
db_label = scale_values[value]['label']
display_info = config_manager.get_display_info(value, 'score')
display_label = display_info['label']
if db_label == display_label:
print(f" ✅ Cohérence pour '{value}': '{db_label}'")
else:
print(f" ❌ Incohérence pour '{value}': DB='{db_label}' vs Display='{display_label}'")
all_consistent = False
# 6. Résultat final
print("\n6. RÉSULTAT FINAL:")
if all_consistent:
print(" 🎉 SUCCÈS : Le système de configuration des échelles fonctionne parfaitement !")
print(" 📋 Les modifications apportées dans la page config/scale sont maintenant")
print(" correctement prises en compte dans toute l'application.")
print(" ✅ Problème de synchronisation des labels : RÉSOLU")
else:
print(" ⚠️ Certaines incohérences subsistent")
print("\n=== Fin de la validation ===")
if __name__ == '__main__':
test_final_validation()

View File

@@ -0,0 +1,167 @@
#!/usr/bin/env python3
"""
Test pour vérifier que la validation stricte fonctionne correctement
et accepte les nombres à virgule.
"""
from app import create_app
from app_config import config_manager
from models import db, Grade
import re
def test_strict_validation():
"""Test de la validation stricte."""
app = create_app('development')
with app.app_context():
print("=== TEST : Validation stricte avec nombres décimaux ===\n")
# 1. Test de la fonction JavaScript générée
print("1. Vérification de la fonction validateGradeValue JavaScript:")
with app.test_client() as client:
response = client.get('/assessments/1/grading')
content = response.get_data(as_text=True)
# Vérifier que la validation stricte est présente
if '/^[0-9]+([.,][0-9]+)?$/.test(trimmedValue)' in content:
print(" ✅ Validation stricte avec regex présente")
else:
print(" ❌ Validation stricte manquante")
# Vérifier la conversion virgule -> point
if "trimmedValue.replace(',', '.')" in content:
print(" ✅ Conversion virgule -> point présente")
else:
print(" ❌ Conversion virgule -> point manquante")
# Vérifier les messages de validation
if 'showValidationMessage(' in content:
print(" ✅ Messages de validation présents")
else:
print(" ❌ Messages de validation manquants")
print()
# 2. Test de validation côté serveur
print("2. Test de validation côté serveur:")
test_cases = [
# Valeurs valides
('15', 'notes', True, 'Nombre entier'),
('15.5', 'notes', True, 'Nombre décimal avec point'),
('4,5', 'notes', True, 'Nombre décimal avec virgule (devrait être accepté côté serveur)'),
('0', 'notes', True, 'Zéro'),
('20', 'notes', True, 'Note maximale'),
('.', 'notes', True, 'Valeur spéciale point'),
('d', 'notes', True, 'Valeur spéciale d'),
# Valeurs invalides
('abc', 'notes', False, 'Texte non numérique'),
('25', 'notes', False, 'Nombre supérieur au maximum'),
('-5', 'notes', False, 'Nombre négatif'),
('15.5.2', 'notes', False, 'Format invalide'),
('15abc', 'notes', False, 'Nombre avec lettres'),
('', 'notes', True, 'Valeur vide (acceptée)'),
# Scores
('0', 'score', True, 'Score 0'),
('3', 'score', True, 'Score 3'),
('4', 'score', False, 'Score invalide'),
]
for value, grade_type, expected, description in test_cases:
is_valid = config_manager.validate_grade_value(value, grade_type)
status = "" if is_valid == expected else ""
print(f" {status} {description}: '{value}'{is_valid} (attendu: {expected})")
print()
# 3. Test de soumission avec valeurs strictes
print("3. Test de soumission avec validation stricte:")
# Nettoyer les données existantes
Grade.query.filter_by(student_id=2).delete()
db.session.commit()
# Test avec différents types de valeurs
test_data = {
'grade_2_1': '15,5', # Nombre à virgule
'grade_2_2': '.', # Valeur spéciale
'grade_2_3': '18.0', # Nombre à point
}
with app.test_client() as client:
print(f" Données de test: {test_data}")
response = client.post('/assessments/1/grading/save',
data=test_data,
follow_redirects=False)
print(f" Soumission: statut {response.status_code}")
if response.status_code == 302:
print(" ✅ Valeurs acceptées par le serveur")
# Vérifier les valeurs sauvées
grades = Grade.query.filter_by(student_id=2).all()
print(f" Grades sauvés: {len(grades)}")
for grade in grades:
print(f" Sauvé: '{grade.value}'")
else:
print(" ❌ Erreur lors de la soumission")
print()
# 4. Test des cas d'erreur
print("4. Test des cas d'erreur:")
error_cases = {
'grade_3_1': 'abc123', # Texte invalide
'grade_3_2': '25', # Nombre trop grand
'grade_3_3': '-5', # Nombre négatif
}
with app.test_client() as client:
print(f" Données d'erreur: {error_cases}")
response = client.post('/assessments/1/grading/save',
data=error_cases,
follow_redirects=True)
print(f" Soumission: statut {response.status_code}")
# Vérifier qu'il y a des messages d'erreur
if response.status_code == 200:
content = response.get_data(as_text=True)
if 'Valeur invalide' in content or 'warning' in content:
print(" ✅ Messages d'erreur présents")
else:
print(" 📋 Pas de messages d'erreur visibles (peut être normal)")
print()
# 5. Résumé des améliorations
print("5. RÉSUMÉ DES AMÉLIORATIONS DE VALIDATION:")
improvements = [
"✅ Validation stricte avec regex /^[0-9]+([.,][0-9]+)?$/",
"✅ Conversion automatique virgule -> point (4,5 → 4.5)",
"✅ Feedback visuel immédiat (rouge/vert)",
"✅ Messages de validation contextuels",
"✅ Validation des plages de valeurs (0 à max_points)",
"✅ Support des valeurs spéciales configurées",
"✅ Validation côté client ET serveur",
]
for improvement in improvements:
print(f" {improvement}")
print("\n 🎯 VALIDATION STRICTE IMPLÉMENTÉE !")
print(" 📋 Comportements validés:")
print(" - Seuls les nombres et valeurs spéciales sont acceptés")
print(" - 4,5 est automatiquement converti en 4.5")
print(" - Messages d'erreur clairs pour l'utilisateur")
print(" - Feedback visuel immédiat (couleurs)")
print(" - Validation des plages de valeurs")
print("\n=== Fin du test ===")
if __name__ == '__main__':
test_strict_validation()

View File

@@ -0,0 +1,190 @@
#!/usr/bin/env python3
"""
Test final pour valider que la validation stricte fonctionne
parfaitement avec les max_points et tous les cas d'usage.
"""
from app import create_app
from app_config import config_manager
from models import db, Grade, GradingElement
import re
def test_final_validation_stricte():
"""Test final de la validation stricte."""
app = create_app('development')
with app.app_context():
print("=== TEST FINAL : Validation stricte parfaite ===\n")
# 1. Test avec max_points réels
print("1. Test avec max_points réels:")
# Récupérer un élément de notation réel
grading_element = GradingElement.query.filter_by(grading_type='notes').first()
if grading_element:
max_points = grading_element.max_points
print(f" Élément testé: {grading_element.label} (max: {max_points} points)")
test_cases = [
('4,5', True, 'Nombre à virgule dans la plage'),
('15.5', True, 'Nombre à point dans la plage'),
(str(max_points), True, 'Valeur maximale exacte'),
(str(max_points + 1), False, 'Valeur supérieure au maximum'),
('0', True, 'Zéro'),
('.', True, 'Valeur spéciale'),
('d', True, 'Valeur spéciale'),
('abc', False, 'Texte invalide'),
('-1', False, 'Valeur négative'),
('', True, 'Valeur vide'),
]
for value, expected, description in test_cases:
is_valid = config_manager.validate_grade_value(value, 'notes', max_points)
status = "" if is_valid == expected else ""
print(f" {status} {description}: '{value}'{is_valid} (attendu: {expected})")
else:
print(" ❌ Aucun élément de type 'notes' trouvé")
print()
# 2. Test de soumission complète avec validation stricte
print("2. Test de soumission avec validation stricte:")
# Nettoyer les données de test
Grade.query.filter_by(student_id=1).delete()
db.session.commit()
# Tester avec des valeurs mixtes
test_data = {
'grade_1_1': '15,5', # Virgule -> doit être converti
'grade_1_2': '2', # Score valide
'grade_1_3': '.', # Valeur spéciale
}
with app.test_client() as client:
print(f" Données de test: {test_data}")
response = client.post('/assessments/1/grading/save',
data=test_data,
follow_redirects=False)
print(f" Soumission: statut {response.status_code}")
if response.status_code == 302:
print(" ✅ Soumission acceptée")
# Vérifier les valeurs sauvées (surtout la conversion virgule->point)
grades = Grade.query.filter_by(student_id=1).all()
print(f" Grades sauvés: {len(grades)}")
for grade in grades:
element = GradingElement.query.get(grade.grading_element_id)
if element:
print(f" {element.label}: '{grade.value}' (type: {element.grading_type})")
# Vérifier spécialement la conversion 15,5 -> 15.5
if element.grading_type == 'notes' and '.' in grade.value:
print(f" ✅ Conversion virgule->point réussie")
else:
print(" ❌ Erreur lors de la soumission")
print()
# 3. Test des cas d'erreur avec validation stricte
print("3. Test des cas d'erreur stricts:")
# Nettoyer
Grade.query.filter_by(student_id=2).delete()
db.session.commit()
# Tester avec des valeurs invalides
error_cases = {
'grade_2_1': 'abc123', # Texte avec chiffres
'grade_2_2': '50', # Nombre trop grand (> max_points)
'grade_2_3': '15.5.2', # Format invalide
}
with app.test_client() as client:
print(f" Données d'erreur: {error_cases}")
response = client.post('/assessments/1/grading/save',
data=error_cases,
follow_redirects=True)
print(f" Soumission: statut {response.status_code}")
# Vérifier qu'aucune valeur invalide n'a été sauvée
invalid_grades = Grade.query.filter_by(student_id=2).all()
print(f" Grades invalides sauvés: {len(invalid_grades)} (devrait être 0)")
if len(invalid_grades) == 0:
print(" ✅ Validation stricte côté serveur fonctionne")
else:
print(" ❌ Des valeurs invalides ont été sauvées")
for grade in invalid_grades:
print(f" Sauvé incorrectement: '{grade.value}'")
print()
# 4. Test de l'interface utilisateur
print("4. Test de l'interface utilisateur:")
with app.test_client() as client:
response = client.get('/assessments/1/grading')
content = response.get_data(as_text=True)
# Vérifier que les champs sont de type text
text_inputs = content.count('type="text"')
number_inputs = content.count('type="number"')
print(f" Champs type='text': {text_inputs}")
print(f" Champs type='number': {number_inputs}")
if number_inputs == 0:
print(" ✅ Plus de champs type='number' qui bloquent les valeurs spéciales")
else:
print(" ❌ Il reste des champs type='number'")
# Vérifier la validation JavaScript
js_validations = [
"validateGradeValue(value, type, maxPoints)",
"SPECIAL_VALUES_KEYS.includes(e.key)",
"showValidationMessage(",
"/^[0-9]+([.,][0-9]+)?$/.test(trimmedValue)"
]
for validation in js_validations:
if validation in content:
print(f"{validation[:30]}... présent")
else:
print(f"{validation[:30]}... manquant")
print()
# 5. Test de performance et UX
print("5. Test de l'expérience utilisateur:")
features = [
"✅ Conversion automatique virgule -> point (15,5 → 15.5)",
"✅ Validation stricte avec regex (seuls nombres + valeurs spéciales)",
"✅ Feedback visuel immédiat (rouge/vert)",
"✅ Messages d'erreur contextuels",
"✅ Validation des plages (0 à max_points)",
"✅ Support complet des valeurs spéciales configurées",
"✅ Validation côté client ET serveur synchronisées",
"✅ Pas de champs type='number' qui bloquent la saisie",
"✅ Placeholders dynamiques informatifs",
]
for feature in features:
print(f" {feature}")
print("\n 🎯 VALIDATION STRICTE PARFAITE !")
print(" 📋 L'utilisateur peut maintenant:")
print(" - Taper 4,5 et voir automatiquement 4.5")
print(" - Recevoir des messages d'erreur clairs")
print(" - Voir immédiatement si sa saisie est valide (couleurs)")
print(" - Utiliser toutes les valeurs spéciales configurées")
print(" - Bénéficier d'une validation cohérente client/serveur")
print(" - Ne plus avoir de comportements bloquants")
print("\n=== Fin du test ===")
if __name__ == '__main__':
test_final_validation_stricte()

View File

@@ -0,0 +1,165 @@
#!/usr/bin/env python3
"""
Test final pour valider que les valeurs spéciales fonctionnent
correctement dans l'interface de notation.
"""
from app import create_app
from app_config import config_manager
from models import db, Grade
import re
def test_final_special_values():
"""Test final des valeurs spéciales."""
app = create_app('development')
with app.app_context():
print("=== TEST FINAL : Valeurs spéciales fonctionnelles ===\n")
# 1. Vérifier la configuration
print("1. Configuration des valeurs spéciales:")
scale_values = config_manager.get_competence_scale_values()
special_values = ['.', 'd']
for value in special_values:
if value in scale_values:
config = scale_values[value]
print(f"'{value}': {config['label']} (couleur: {config['color']})")
else:
print(f"'{value}': NON CONFIGURÉE")
print()
# 2. Vérifier la génération JavaScript
print("2. Configuration JavaScript:")
with app.test_client() as client:
response = client.get('/assessments/1/grading')
content = response.get_data(as_text=True)
start = content.find('special_values: {')
if start != -1:
end = content.find('}', start) + 1
js_config = content[start:end]
print(f" {js_config}")
# Vérifier que les valeurs sont présentes
for value in special_values:
if f"'{value}'" in js_config:
print(f"'{value}' présent dans la config JS")
else:
print(f"'{value}' absent de la config JS")
else:
print(" ❌ Configuration JavaScript non trouvée")
print()
# 3. Vérifier les options SELECT
print("3. Options des champs SELECT (type 'score'):")
with app.test_client() as client:
response = client.get('/assessments/1/grading')
content = response.get_data(as_text=True)
# Extraire toutes les options
option_pattern = r'<option value="([^"]*)"[^>]*>([^<]*)</option>'
options = re.findall(option_pattern, content)
special_options = [(v, t) for v, t in options if v in special_values]
print(f" Options spéciales trouvées: {len(special_options)}")
for value, text in special_options:
print(f" ✅ <option value=\"{value}\">{text}</option>")
print()
# 4. Test de soumission complète
print("4. Test de soumission avec valeurs spéciales:")
# Nettoyer les données existantes pour ce test
Grade.query.filter_by(student_id=1).delete()
db.session.commit()
with app.test_client() as client:
# Test avec différentes valeurs spéciales
test_data = {
'grade_1_1': '.', # Champ notes avec "pas de réponse"
'grade_1_2': 'd', # Champ score avec "dispensé"
'grade_1_3': '2', # Valeur normale pour contrôle
}
response = client.post('/assessments/1/grading/save',
data=test_data,
follow_redirects=False)
print(f" Soumission: statut {response.status_code}")
if response.status_code == 302: # Redirection = succès
print(" ✅ Soumission acceptée")
# Vérifier que les valeurs ont été sauvées
grades = Grade.query.filter_by(student_id=1).all()
print(f" Grades sauvés: {len(grades)}")
for grade in grades:
display_info = config_manager.get_display_info(grade.value, 'score')
print(f" Élément {grade.grading_element_id}: '{grade.value}'{display_info['label']}")
else:
print(" ❌ Erreur lors de la soumission")
print()
# 5. Test de l'affichage après sauvegarde
print("5. Test d'affichage après sauvegarde:")
with app.test_client() as client:
response = client.get('/assessments/1/grading')
if response.status_code == 200:
content = response.get_data(as_text=True)
# Vérifier que les valeurs spéciales sont présélectionnées
for value in special_values:
if f'selected>{value}' in content or f'value="{value}"' in content:
print(f" ✅ Valeur '{value}' correctement affichée/sélectionnée")
else:
print(f" 📋 Valeur '{value}' peut ne pas être visible (normal si pas dans ce champ)")
print()
# 6. Résumé final
print("6. RÉSUMÉ FINAL:")
# Vérification complète
checks = []
# Config de base
all_special_configured = all(v in scale_values for v in special_values)
checks.append(("Valeurs spéciales configurées", all_special_configured))
# JavaScript
with app.test_client() as client:
response = client.get('/assessments/1/grading')
content = response.get_data(as_text=True)
js_has_special = all(f"'{v}'" in content for v in special_values)
checks.append(("JavaScript contient valeurs spéciales", js_has_special))
# Options HTML
option_pattern = r'<option value="([^"]*)"'
html_options = re.findall(option_pattern, content)
html_has_special = all(v in html_options for v in special_values)
checks.append(("HTML contient options spéciales", html_has_special))
# Affichage des résultats
all_passed = True
for check_name, passed in checks:
status = "" if passed else ""
print(f" {status} {check_name}")
if not passed:
all_passed = False
if all_passed:
print("\n 🎉 SUCCÈS : Les valeurs spéciales sont maintenant fonctionnelles !")
print(" 📋 L'utilisateur peut:")
print(" - Sélectionner '.' et 'd' dans les listes déroulantes (type score)")
print(" - Taper '.' et 'd' dans les champs numériques (type notes)")
print(" - Utiliser les raccourcis clavier pour saisir rapidement")
else:
print("\n ⚠️ Certains problèmes subsistent")
print("\n=== Fin du test ===")
if __name__ == '__main__':
test_final_special_values()

View File

@@ -0,0 +1,143 @@
#!/usr/bin/env python3
"""
Test pour diagnostiquer le problème de saisie des valeurs spéciales
dans la page de notation.
"""
from app import create_app
from app_config import config_manager
def test_special_values_input():
"""Test des valeurs spéciales dans l'interface de notation."""
app = create_app('development')
with app.app_context():
print("=== DIAGNOSTIC : Problème saisie valeurs spéciales ===\n")
# 1. Vérifier les valeurs spéciales configurées
print("1. Valeurs spéciales configurées:")
scale_values = config_manager.get_competence_scale_values()
special_values = ['.', 'd', 'a']
for value in special_values:
if value in scale_values:
config = scale_values[value]
print(f" '{value}': {config['label']} (couleur: {config['color']})")
else:
print(f" '{value}': NON CONFIGURÉE")
print()
# 2. Tester l'accès à une page de notation
print("2. Test d'accès à la page de notation:")
with app.test_client() as client:
response = client.get('/assessments/1/grading')
print(f" Statut: {response.status_code}")
if response.status_code == 200:
content = response.get_data(as_text=True)
# Vérifier la présence des valeurs spéciales dans le HTML
print(" Vérification des valeurs spéciales dans le HTML:")
for value in special_values:
if value in scale_values:
label = scale_values[value]['label']
if f"value=\"{value}\"" in content:
print(f"'{value}' trouvé dans le HTML")
else:
print(f"'{value}' NON trouvé dans le HTML")
if label in content:
print(f" ✅ Label '{label}' trouvé dans le HTML")
else:
print(f" ❌ Label '{label}' NON trouvé dans le HTML")
else:
print(f" ❌ Erreur d'accès: {response.status_code}")
print()
# 3. Analyser le template pour les valeurs spéciales
print("3. Analyse du template assessment_grading.html:")
try:
with open('templates/assessment_grading.html', 'r', encoding='utf-8') as f:
template_content = f.read()
# Chercher les patterns pour les valeurs spéciales
import re
# Pattern pour les valeurs spéciales hardcodées
hardcoded_pattern = r"for special_value in \['\.', 'd', 'a'\]"
if re.search(hardcoded_pattern, template_content):
print(" ✅ Pattern des valeurs spéciales trouvé")
else:
print(" ❌ Pattern des valeurs spéciales NON trouvé")
# Pattern pour la vérification si la valeur existe dans scale_values
check_pattern = r"if special_value in scale_values"
if re.search(check_pattern, template_content):
print(" ✅ Vérification 'if special_value in scale_values' trouvée")
else:
print(" ❌ Vérification 'if special_value in scale_values' NON trouvée")
# Pattern pour l'affichage des valeurs spéciales
display_pattern = r"config_manager\.get_display_info\(special_value, 'score'\)"
if re.search(display_pattern, template_content):
print(" ✅ Utilisation de get_display_info pour valeurs spéciales trouvée")
else:
print(" ❌ Utilisation de get_display_info pour valeurs spéciales NON trouvée")
except FileNotFoundError:
print(" ❌ Fichier template non trouvé")
print()
# 4. Test de validation côté serveur
print("4. Test de validation côté serveur:")
# Tester validate_grade_value pour valeurs spéciales
test_values = ['.', 'd', 'a', '0', '1', '2', '3', 'invalid']
for value in test_values:
is_valid_score = config_manager.validate_grade_value(value, 'score')
is_valid_notes = config_manager.validate_grade_value(value, 'notes')
print(f" '{value}': score={is_valid_score}, notes={is_valid_notes}")
print()
# 5. Test de soumission simulée avec valeurs spéciales
print("5. Test de soumission avec valeurs spéciales:")
with app.test_client() as client:
# Simuler une soumission avec des valeurs spéciales
form_data = {
'grade_1_1': '.', # Valeur spéciale "pas de réponse"
'grade_1_2': 'd', # Valeur spéciale "dispensé"
'grade_1_3': '2', # Valeur normale
}
response = client.post('/assessments/1/grading/save', data=form_data, follow_redirects=False)
print(f" Soumission avec valeurs spéciales: {response.status_code}")
if response.status_code == 302: # Redirect après succès
print(" ✅ Soumission acceptée (redirection)")
elif response.status_code == 200:
print(" ⚠️ Soumission retournée à la page (possibles erreurs)")
else:
print(f" ❌ Erreur lors de la soumission: {response.status_code}")
print()
# 6. Diagnostic final
print("6. DIAGNOSTIC FINAL:")
# Vérifier si toutes les valeurs spéciales sont bien configurées
missing_special_values = []
for value in special_values:
if value not in scale_values:
missing_special_values.append(value)
if missing_special_values:
print(f" 🚨 PROBLÈME: Valeurs spéciales manquantes: {missing_special_values}")
print(" 📋 SOLUTION: Ajouter ces valeurs via la page config/scale")
else:
print(" ✅ Toutes les valeurs spéciales sont configurées")
print(" 📋 Vérifier si le problème vient du JavaScript ou de la validation")
print("\n=== Fin du diagnostic ===")
if __name__ == '__main__':
test_special_values_input()