/// Tests unitaires pour SearchMembers use case library search_members_test; import 'package:flutter_test/flutter_test.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; import 'package:unionflow_mobile_apps/features/members/domain/repositories/membre_repository.dart'; import 'package:unionflow_mobile_apps/features/members/domain/usecases/search_members.dart'; import 'package:unionflow_mobile_apps/features/members/data/models/membre_complete_model.dart'; import 'package:unionflow_mobile_apps/shared/models/membre_search_result.dart'; import 'package:unionflow_mobile_apps/shared/models/membre_search_criteria.dart'; @GenerateMocks([IMembreRepository]) import 'search_members_test.mocks.dart'; void main() { late SearchMembers useCase; late MockIMembreRepository mockRepository; setUp(() { mockRepository = MockIMembreRepository(); useCase = SearchMembers(mockRepository); }); group('SearchMembers Use Case', () { final tSearchCriteria = MembreSearchCriteria( query: 'Diallo', statut: 'ACTIF', ); final tMatchingMembers = [ MembreCompletModel( id: '1', nom: 'Diallo', prenom: 'Amadou', email: 'amadou.diallo@example.com', genre: Genre.homme, statut: StatutMembre.actif, ), MembreCompletModel( id: '2', nom: 'Diallo', prenom: 'Fatou', email: 'fatou.diallo@example.com', genre: Genre.femme, statut: StatutMembre.actif, ), ]; final tSearchResult = MembreSearchResult( membres: tMatchingMembers, totalElements: 2, totalPages: 1, currentPage: 0, pageSize: 20, numberOfElements: 2, hasNext: false, hasPrevious: false, isFirst: true, isLast: true, criteria: tSearchCriteria, executionTimeMs: 65, ); test('should return search results matching criteria', () async { // Arrange when(mockRepository.searchMembres( criteria: tSearchCriteria, page: 0, size: 20, )).thenAnswer((_) async => tSearchResult); // Act final result = await useCase(criteria: tSearchCriteria, page: 0, size: 20); // Assert expect(result, equals(tSearchResult)); expect(result.membres.length, equals(2)); expect(result.membres.every((m) => m.nom == 'Diallo'), isTrue); expect(result.membres.every((m) => m.statut == StatutMembre.actif), isTrue); verify(mockRepository.searchMembres( criteria: tSearchCriteria, page: 0, size: 20, )); verifyNoMoreInteractions(mockRepository); }); test('should search members by prenom', () async { // Arrange final prenomCriteria = MembreSearchCriteria( prenom: 'Fatou', ); final fatouMembers = [tMatchingMembers[1]]; final prenomResult = MembreSearchResult( membres: fatouMembers, totalElements: 1, totalPages: 1, currentPage: 0, pageSize: 20, numberOfElements: 1, hasNext: false, hasPrevious: false, isFirst: true, isLast: true, criteria: prenomCriteria, executionTimeMs: 40, ); when(mockRepository.searchMembres( criteria: prenomCriteria, page: 0, size: 20, )).thenAnswer((_) async => prenomResult); // Act final result = await useCase(criteria: prenomCriteria, page: 0, size: 20); // Assert expect(result.membres.length, equals(1)); expect(result.membres[0].prenom, equals('Fatou')); }); test('should return empty result when no matches found', () async { // Arrange final noMatchCriteria = MembreSearchCriteria( query: 'NonExistant', ); final emptyResult = MembreSearchResult( membres: [], totalElements: 0, totalPages: 0, currentPage: 0, pageSize: 20, numberOfElements: 0, hasNext: false, hasPrevious: false, isFirst: true, isLast: true, criteria: noMatchCriteria, executionTimeMs: 25, ); when(mockRepository.searchMembres( criteria: noMatchCriteria, page: 0, size: 20, )).thenAnswer((_) async => emptyResult); // Act final result = await useCase(criteria: noMatchCriteria, page: 0, size: 20); // Assert expect(result.membres, isEmpty); expect(result.totalElements, equals(0)); }); test('should throw exception when search fails', () async { // Arrange when(mockRepository.searchMembres( criteria: anyNamed('criteria'), page: anyNamed('page'), size: anyNamed('size'), )).thenThrow(Exception('Erreur de recherche')); // Act & Assert expect(() => useCase(criteria: tSearchCriteria, page: 0, size: 20), throwsException); }); }); }