import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:dio/dio.dart'; import '../lib/core/error/error_handler.dart'; import '../lib/core/validation/form_validator.dart'; import '../lib/core/failures/failures.dart'; void main() { group('FormValidator Tests', () { test('should validate required fields correctly', () { // Test champ requis vide expect(FormValidator.required(''), 'Ce champ est requis'); expect(FormValidator.required(' '), 'Ce champ est requis'); expect(FormValidator.required(null), 'Ce champ est requis'); // Test champ requis valide expect(FormValidator.required('valeur'), null); expect(FormValidator.required(' valeur '), null); }); test('should validate email correctly', () { // Test emails invalides expect(FormValidator.email(''), 'L\'email est requis'); expect(FormValidator.email('invalid'), 'Format d\'email invalide'); expect(FormValidator.email('test@'), 'Format d\'email invalide'); expect(FormValidator.email('@domain.com'), 'Format d\'email invalide'); expect(FormValidator.email('test.domain.com'), 'Format d\'email invalide'); // Test emails valides expect(FormValidator.email('test@domain.com'), null); expect(FormValidator.email('user.name@example.org'), null); expect(FormValidator.email('test123@sub.domain.co.uk'), null); }); test('should validate phone numbers correctly', () { // Test téléphones invalides expect(FormValidator.phone(''), 'Le numéro de téléphone est requis'); expect(FormValidator.phone('123'), 'Format de téléphone invalide (ex: +225XXXXXXXX)'); expect(FormValidator.phone('abcdefgh'), 'Format de téléphone invalide (ex: +225XXXXXXXX)'); // Test téléphones valides expect(FormValidator.phone('12345678'), null); expect(FormValidator.phone('+22512345678'), null); expect(FormValidator.phone('1234567890'), null); expect(FormValidator.phone('+225 12 34 56 78'), null); // Avec espaces }); test('should validate names correctly', () { // Test noms invalides expect(FormValidator.name(''), 'Ce champ est requis'); expect(FormValidator.name('A'), 'Ce champ doit contenir au moins 2 caractères'); expect(FormValidator.name('123'), 'Ce champ ne peut contenir que des lettres'); expect(FormValidator.name('Name@123'), 'Ce champ ne peut contenir que des lettres'); // Test noms valides expect(FormValidator.name('Jean'), null); expect(FormValidator.name('Marie-Claire'), null); expect(FormValidator.name('Jean-Baptiste'), null); expect(FormValidator.name('O\'Connor'), null); expect(FormValidator.name('José'), null); expect(FormValidator.name('François'), null); }); test('should validate birth dates correctly', () { final now = DateTime.now(); final validDate = DateTime(now.year - 25, now.month, now.day); final futureDate = DateTime(now.year + 1, now.month, now.day); final tooYoungDate = DateTime(now.year - 10, now.month, now.day); final tooOldDate = DateTime(now.year - 150, now.month, now.day); // Test dates invalides expect(FormValidator.birthDate(null), 'La date de naissance est requise'); expect(FormValidator.birthDate(futureDate), 'La date de naissance ne peut pas être dans le futur'); expect(FormValidator.birthDate(tooYoungDate, minAge: 16), 'L\'âge minimum requis est de 16 ans'); expect(FormValidator.birthDate(tooOldDate, maxAge: 120), 'L\'âge maximum autorisé est de 120 ans'); // Test date valide expect(FormValidator.birthDate(validDate), null); }); test('should validate member numbers correctly', () { // Test numéros invalides expect(FormValidator.memberNumber(''), 'Le numéro de membre est requis'); expect(FormValidator.memberNumber('123'), 'Format invalide (ex: MBR001)'); expect(FormValidator.memberNumber('MBR'), 'Format invalide (ex: MBR001)'); expect(FormValidator.memberNumber('MBR12'), 'Format invalide (ex: MBR001)'); // Test numéros valides expect(FormValidator.memberNumber('MBR001'), null); expect(FormValidator.memberNumber('MBR123456'), null); }); test('should combine validators correctly', () { final combinedValidator = FormValidator.combine([ (value) => FormValidator.required(value), (value) => FormValidator.minLength(value, 3), (value) => FormValidator.maxLength(value, 10), ]); // Test avec erreurs expect(combinedValidator(''), 'Ce champ est requis'); expect(combinedValidator('ab'), 'Ce champ doit contenir au moins 3 caractères'); expect(combinedValidator('12345678901'), 'Ce champ ne peut pas dépasser 10 caractères'); // Test valide expect(combinedValidator('valide'), null); }); test('should validate complete member data', () { final validMemberData = { 'prenom': 'Jean', 'nom': 'Dupont', 'email': 'jean.dupont@email.com', 'telephone': '+22512345678', 'dateNaissance': DateTime(1990, 1, 1), 'adresse': '123 Rue de la Paix', 'profession': 'Ingénieur', }; final invalidMemberData = { 'prenom': '', 'nom': 'D', 'email': 'invalid-email', 'telephone': '123', 'dateNaissance': DateTime.now().add(const Duration(days: 1)), 'adresse': '', 'profession': '', }; // Test données valides final validErrors = FormValidator.validateMember(validMemberData); expect(validErrors.isEmpty, true); // Test données invalides final invalidErrors = FormValidator.validateMember(invalidMemberData); expect(invalidErrors.isNotEmpty, true); expect(invalidErrors.containsKey('prenom'), true); expect(invalidErrors.containsKey('nom'), true); expect(invalidErrors.containsKey('email'), true); expect(invalidErrors.containsKey('telephone'), true); }); }); group('ErrorHandler Tests', () { test('should analyze DioException correctly', () { // Test DioException de type connectTimeout final timeoutException = DioException( requestOptions: RequestOptions(path: '/test'), type: DioExceptionType.connectionTimeout, message: 'Connection timeout', ); // Nous ne pouvons pas tester directement _analyzeError car elle est privée // Mais nous pouvons tester que la classe ErrorHandler existe et compile expect(ErrorHandler, isNotNull); }); test('should create appropriate failure types', () { // Test NetworkFailure final networkFailure = NetworkFailure.noConnection(); expect(networkFailure.message, 'Aucune connexion internet disponible'); expect(networkFailure.code, 'NO_CONNECTION'); // Test ServerFailure final serverFailure = ServerFailure.internalError(); expect(serverFailure.message, 'Erreur interne du serveur'); expect(serverFailure.statusCode, 500); // Test ValidationFailure final validationFailure = ValidationFailure.requiredField('email'); expect(validationFailure.message, 'Champ requis manquant'); expect(validationFailure.fieldErrors?['email']?.first, 'Ce champ est requis'); // Test AuthFailure final authFailure = AuthFailure.tokenExpired(); expect(authFailure.message, 'Session expirée, veuillez vous reconnecter'); expect(authFailure.code, 'TOKEN_EXPIRED'); }); test('should handle failure equality correctly', () { final failure1 = NetworkFailure.noConnection(); final failure2 = NetworkFailure.noConnection(); final failure3 = NetworkFailure.timeout(); expect(failure1 == failure2, true); expect(failure1 == failure3, false); expect(failure1.hashCode == failure2.hashCode, true); }); }); group('Failure Classes Tests', () { test('should create DataFailure correctly', () { final notFoundFailure = DataFailure.notFound('Membre'); expect(notFoundFailure.message, 'Membre non trouvé(e)'); expect(notFoundFailure.code, 'NOT_FOUND'); expect(notFoundFailure.details?['resource'], 'Membre'); final conflictFailure = DataFailure.conflict('Email déjà utilisé'); expect(conflictFailure.message, 'Conflit de données : Email déjà utilisé'); expect(conflictFailure.code, 'CONFLICT'); }); test('should create FileFailure correctly', () { final fileNotFound = FileFailure.notFound('/path/to/file.txt'); expect(fileNotFound.message, 'Fichier non trouvé'); expect(fileNotFound.details?['filePath'], '/path/to/file.txt'); final invalidFormat = FileFailure.invalidFormat('PDF'); expect(invalidFormat.message, 'Format de fichier invalide'); expect(invalidFormat.details?['expectedFormat'], 'PDF'); }); test('should create UnknownFailure from exception', () { final exception = Exception('Test exception'); final unknownFailure = UnknownFailure.fromException(exception); expect(unknownFailure.message.contains('Test exception'), true); expect(unknownFailure.code, 'UNKNOWN_ERROR'); }); }); }