Initial commit: unionflow-mobile-apps

Application Flutter complète (sans build artifacts).

Signed-off-by: lions dev Team
This commit is contained in:
dahoud
2026-03-15 16:30:08 +00:00
commit d094d6db9c
1790 changed files with 507435 additions and 0 deletions

View File

@@ -0,0 +1,117 @@
/// Tests unitaires pour CreateMember use case
library create_member_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/create_member.dart';
import 'package:unionflow_mobile_apps/features/members/data/models/membre_complete_model.dart';
@GenerateMocks([IMembreRepository])
import 'create_member_test.mocks.dart';
void main() {
late CreateMember useCase;
late MockIMembreRepository mockRepository;
setUp(() {
mockRepository = MockIMembreRepository();
useCase = CreateMember(mockRepository);
});
group('CreateMember Use Case', () {
final tMemberData = MembreCompletModel(
nom: 'Ndiaye',
prenom: 'Fatou',
email: 'fatou.ndiaye@example.com',
telephone: '+221776543210',
genre: Genre.femme,
statut: StatutMembre.enAttente,
dateNaissance: DateTime(1990, 7, 22),
adresse: '45 Rue de la République, Dakar',
);
final tCreatedMember = MembreCompletModel(
id: '456',
nom: 'Ndiaye',
prenom: 'Fatou',
email: 'fatou.ndiaye@example.com',
telephone: '+221776543210',
genre: Genre.femme,
statut: StatutMembre.enAttente,
dateNaissance: DateTime(1990, 7, 22),
adresse: '45 Rue de la République, Dakar',
);
test('should create new member successfully', () async {
// Arrange
when(mockRepository.createMembre(tMemberData))
.thenAnswer((_) async => tCreatedMember);
// Act
final result = await useCase(tMemberData);
// Assert
expect(result, equals(tCreatedMember));
expect(result.id, equals('456'));
expect(result.nom, equals('Ndiaye'));
expect(result.email, equals('fatou.ndiaye@example.com'));
verify(mockRepository.createMembre(tMemberData));
verifyNoMoreInteractions(mockRepository);
});
test('should create member with minimal required fields', () async {
// Arrange
final minimalMember = MembreCompletModel(
nom: 'Ba',
prenom: 'Moussa',
email: 'moussa.ba@example.com',
genre: Genre.homme,
statut: StatutMembre.enAttente,
);
final createdMinimal = MembreCompletModel(
id: '789',
nom: 'Ba',
prenom: 'Moussa',
email: 'moussa.ba@example.com',
genre: Genre.homme,
statut: StatutMembre.enAttente,
);
when(mockRepository.createMembre(minimalMember))
.thenAnswer((_) async => createdMinimal);
// Act
final result = await useCase(minimalMember);
// Assert
expect(result.id, equals('789'));
expect(result.nom, equals('Ba'));
});
test('should throw exception when email already exists', () async {
// Arrange
when(mockRepository.createMembre(any))
.thenThrow(Exception('Email déjà utilisé'));
// Act & Assert
expect(() => useCase(tMemberData), throwsA(isA<Exception>()));
});
test('should throw exception when validation fails', () async {
// Arrange
final invalidMember = MembreCompletModel(
nom: '',
prenom: 'Test',
email: 'invalid-email',
genre: Genre.autre,
statut: StatutMembre.enAttente,
);
when(mockRepository.createMembre(any))
.thenThrow(Exception('Données invalides'));
// Act & Assert
expect(() => useCase(invalidMember), throwsException);
});
});
}

View File

@@ -0,0 +1,286 @@
// Mocks generated by Mockito 5.4.4 from annotations
// in unionflow_mobile_apps/test/features/members/domain/usecases/create_member_test.dart.
// Do not manually edit this file.
// ignore_for_file: no_leading_underscores_for_library_prefixes
import 'dart:async' as _i5;
import 'package:mockito/mockito.dart' as _i1;
import 'package:unionflow_mobile_apps/features/members/data/models/membre_complete_model.dart'
as _i3;
import 'package:unionflow_mobile_apps/features/members/domain/repositories/membre_repository.dart'
as _i4;
import 'package:unionflow_mobile_apps/shared/models/membre_search_criteria.dart'
as _i6;
import 'package:unionflow_mobile_apps/shared/models/membre_search_result.dart'
as _i2;
// ignore_for_file: type=lint
// ignore_for_file: avoid_redundant_argument_values
// ignore_for_file: avoid_setters_without_getters
// ignore_for_file: comment_references
// ignore_for_file: deprecated_member_use
// ignore_for_file: deprecated_member_use_from_same_package
// ignore_for_file: implementation_imports
// ignore_for_file: invalid_use_of_visible_for_testing_member
// ignore_for_file: prefer_const_constructors
// ignore_for_file: unnecessary_parenthesis
// ignore_for_file: camel_case_types
// ignore_for_file: subtype_of_sealed_class
class _FakeMembreSearchResult_0 extends _i1.SmartFake
implements _i2.MembreSearchResult {
_FakeMembreSearchResult_0(
Object parent,
Invocation parentInvocation,
) : super(
parent,
parentInvocation,
);
}
class _FakeMembreCompletModel_1 extends _i1.SmartFake
implements _i3.MembreCompletModel {
_FakeMembreCompletModel_1(
Object parent,
Invocation parentInvocation,
) : super(
parent,
parentInvocation,
);
}
/// A class which mocks [IMembreRepository].
///
/// See the documentation for Mockito's code generation for more information.
class MockIMembreRepository extends _i1.Mock implements _i4.IMembreRepository {
MockIMembreRepository() {
_i1.throwOnMissingStub(this);
}
@override
_i5.Future<_i2.MembreSearchResult> getMembres({
int? page = 0,
int? size = 20,
String? recherche,
}) =>
(super.noSuchMethod(
Invocation.method(
#getMembres,
[],
{
#page: page,
#size: size,
#recherche: recherche,
},
),
returnValue:
_i5.Future<_i2.MembreSearchResult>.value(_FakeMembreSearchResult_0(
this,
Invocation.method(
#getMembres,
[],
{
#page: page,
#size: size,
#recherche: recherche,
},
),
)),
) as _i5.Future<_i2.MembreSearchResult>);
@override
_i5.Future<_i3.MembreCompletModel?> getMembreById(String? id) =>
(super.noSuchMethod(
Invocation.method(
#getMembreById,
[id],
),
returnValue: _i5.Future<_i3.MembreCompletModel?>.value(),
) as _i5.Future<_i3.MembreCompletModel?>);
@override
_i5.Future<_i3.MembreCompletModel> createMembre(
_i3.MembreCompletModel? membre) =>
(super.noSuchMethod(
Invocation.method(
#createMembre,
[membre],
),
returnValue:
_i5.Future<_i3.MembreCompletModel>.value(_FakeMembreCompletModel_1(
this,
Invocation.method(
#createMembre,
[membre],
),
)),
) as _i5.Future<_i3.MembreCompletModel>);
@override
_i5.Future<_i3.MembreCompletModel> updateMembre(
String? id,
_i3.MembreCompletModel? membre,
) =>
(super.noSuchMethod(
Invocation.method(
#updateMembre,
[
id,
membre,
],
),
returnValue:
_i5.Future<_i3.MembreCompletModel>.value(_FakeMembreCompletModel_1(
this,
Invocation.method(
#updateMembre,
[
id,
membre,
],
),
)),
) as _i5.Future<_i3.MembreCompletModel>);
@override
_i5.Future<void> deleteMembre(String? id) => (super.noSuchMethod(
Invocation.method(
#deleteMembre,
[id],
),
returnValue: _i5.Future<void>.value(),
returnValueForMissingStub: _i5.Future<void>.value(),
) as _i5.Future<void>);
@override
_i5.Future<_i3.MembreCompletModel> activateMembre(String? id) =>
(super.noSuchMethod(
Invocation.method(
#activateMembre,
[id],
),
returnValue:
_i5.Future<_i3.MembreCompletModel>.value(_FakeMembreCompletModel_1(
this,
Invocation.method(
#activateMembre,
[id],
),
)),
) as _i5.Future<_i3.MembreCompletModel>);
@override
_i5.Future<_i3.MembreCompletModel> deactivateMembre(String? id) =>
(super.noSuchMethod(
Invocation.method(
#deactivateMembre,
[id],
),
returnValue:
_i5.Future<_i3.MembreCompletModel>.value(_FakeMembreCompletModel_1(
this,
Invocation.method(
#deactivateMembre,
[id],
),
)),
) as _i5.Future<_i3.MembreCompletModel>);
@override
_i5.Future<_i2.MembreSearchResult> searchMembres({
required _i6.MembreSearchCriteria? criteria,
int? page = 0,
int? size = 20,
}) =>
(super.noSuchMethod(
Invocation.method(
#searchMembres,
[],
{
#criteria: criteria,
#page: page,
#size: size,
},
),
returnValue:
_i5.Future<_i2.MembreSearchResult>.value(_FakeMembreSearchResult_0(
this,
Invocation.method(
#searchMembres,
[],
{
#criteria: criteria,
#page: page,
#size: size,
},
),
)),
) as _i5.Future<_i2.MembreSearchResult>);
@override
_i5.Future<_i2.MembreSearchResult> getActiveMembers({
int? page = 0,
int? size = 20,
}) =>
(super.noSuchMethod(
Invocation.method(
#getActiveMembers,
[],
{
#page: page,
#size: size,
},
),
returnValue:
_i5.Future<_i2.MembreSearchResult>.value(_FakeMembreSearchResult_0(
this,
Invocation.method(
#getActiveMembers,
[],
{
#page: page,
#size: size,
},
),
)),
) as _i5.Future<_i2.MembreSearchResult>);
@override
_i5.Future<_i2.MembreSearchResult> getBureauMembers({
int? page = 0,
int? size = 20,
}) =>
(super.noSuchMethod(
Invocation.method(
#getBureauMembers,
[],
{
#page: page,
#size: size,
},
),
returnValue:
_i5.Future<_i2.MembreSearchResult>.value(_FakeMembreSearchResult_0(
this,
Invocation.method(
#getBureauMembers,
[],
{
#page: page,
#size: size,
},
),
)),
) as _i5.Future<_i2.MembreSearchResult>);
@override
_i5.Future<Map<String, dynamic>> getMembresStats() => (super.noSuchMethod(
Invocation.method(
#getMembresStats,
[],
),
returnValue:
_i5.Future<Map<String, dynamic>>.value(<String, dynamic>{}),
) as _i5.Future<Map<String, dynamic>>);
}

View File

@@ -0,0 +1,68 @@
/// Tests unitaires pour DeleteMember use case
library delete_member_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/delete_member.dart';
@GenerateMocks([IMembreRepository])
import 'delete_member_test.mocks.dart';
void main() {
late DeleteMember useCase;
late MockIMembreRepository mockRepository;
setUp(() {
mockRepository = MockIMembreRepository();
useCase = DeleteMember(mockRepository);
});
group('DeleteMember Use Case', () {
const tMemberId = '123';
test('should delete member successfully', () async {
// Arrange
when(mockRepository.deleteMembre(tMemberId))
.thenAnswer((_) async => Future.value());
// Act
await useCase(tMemberId);
// Assert
verify(mockRepository.deleteMembre(tMemberId));
verifyNoMoreInteractions(mockRepository);
});
test('should delete member with confirmation', () async {
// Arrange
when(mockRepository.deleteMembre(tMemberId))
.thenAnswer((_) async => Future.value());
// Act
await useCase(tMemberId);
// Assert
verify(mockRepository.deleteMembre(tMemberId)).called(1);
});
test('should throw exception when member not found', () async {
// Arrange
when(mockRepository.deleteMembre(any))
.thenThrow(Exception('Membre non trouvé'));
// Act & Assert
expect(() => useCase('999'), throwsA(isA<Exception>()));
});
test('should throw exception when member has dependencies', () async {
// Arrange
when(mockRepository.deleteMembre(any))
.thenThrow(Exception('Impossible de supprimer: membre a des contributions actives'));
// Act & Assert
expect(() => useCase(tMemberId), throwsException);
});
});
}

View File

@@ -0,0 +1,286 @@
// Mocks generated by Mockito 5.4.4 from annotations
// in unionflow_mobile_apps/test/features/members/domain/usecases/delete_member_test.dart.
// Do not manually edit this file.
// ignore_for_file: no_leading_underscores_for_library_prefixes
import 'dart:async' as _i5;
import 'package:mockito/mockito.dart' as _i1;
import 'package:unionflow_mobile_apps/features/members/data/models/membre_complete_model.dart'
as _i3;
import 'package:unionflow_mobile_apps/features/members/domain/repositories/membre_repository.dart'
as _i4;
import 'package:unionflow_mobile_apps/shared/models/membre_search_criteria.dart'
as _i6;
import 'package:unionflow_mobile_apps/shared/models/membre_search_result.dart'
as _i2;
// ignore_for_file: type=lint
// ignore_for_file: avoid_redundant_argument_values
// ignore_for_file: avoid_setters_without_getters
// ignore_for_file: comment_references
// ignore_for_file: deprecated_member_use
// ignore_for_file: deprecated_member_use_from_same_package
// ignore_for_file: implementation_imports
// ignore_for_file: invalid_use_of_visible_for_testing_member
// ignore_for_file: prefer_const_constructors
// ignore_for_file: unnecessary_parenthesis
// ignore_for_file: camel_case_types
// ignore_for_file: subtype_of_sealed_class
class _FakeMembreSearchResult_0 extends _i1.SmartFake
implements _i2.MembreSearchResult {
_FakeMembreSearchResult_0(
Object parent,
Invocation parentInvocation,
) : super(
parent,
parentInvocation,
);
}
class _FakeMembreCompletModel_1 extends _i1.SmartFake
implements _i3.MembreCompletModel {
_FakeMembreCompletModel_1(
Object parent,
Invocation parentInvocation,
) : super(
parent,
parentInvocation,
);
}
/// A class which mocks [IMembreRepository].
///
/// See the documentation for Mockito's code generation for more information.
class MockIMembreRepository extends _i1.Mock implements _i4.IMembreRepository {
MockIMembreRepository() {
_i1.throwOnMissingStub(this);
}
@override
_i5.Future<_i2.MembreSearchResult> getMembres({
int? page = 0,
int? size = 20,
String? recherche,
}) =>
(super.noSuchMethod(
Invocation.method(
#getMembres,
[],
{
#page: page,
#size: size,
#recherche: recherche,
},
),
returnValue:
_i5.Future<_i2.MembreSearchResult>.value(_FakeMembreSearchResult_0(
this,
Invocation.method(
#getMembres,
[],
{
#page: page,
#size: size,
#recherche: recherche,
},
),
)),
) as _i5.Future<_i2.MembreSearchResult>);
@override
_i5.Future<_i3.MembreCompletModel?> getMembreById(String? id) =>
(super.noSuchMethod(
Invocation.method(
#getMembreById,
[id],
),
returnValue: _i5.Future<_i3.MembreCompletModel?>.value(),
) as _i5.Future<_i3.MembreCompletModel?>);
@override
_i5.Future<_i3.MembreCompletModel> createMembre(
_i3.MembreCompletModel? membre) =>
(super.noSuchMethod(
Invocation.method(
#createMembre,
[membre],
),
returnValue:
_i5.Future<_i3.MembreCompletModel>.value(_FakeMembreCompletModel_1(
this,
Invocation.method(
#createMembre,
[membre],
),
)),
) as _i5.Future<_i3.MembreCompletModel>);
@override
_i5.Future<_i3.MembreCompletModel> updateMembre(
String? id,
_i3.MembreCompletModel? membre,
) =>
(super.noSuchMethod(
Invocation.method(
#updateMembre,
[
id,
membre,
],
),
returnValue:
_i5.Future<_i3.MembreCompletModel>.value(_FakeMembreCompletModel_1(
this,
Invocation.method(
#updateMembre,
[
id,
membre,
],
),
)),
) as _i5.Future<_i3.MembreCompletModel>);
@override
_i5.Future<void> deleteMembre(String? id) => (super.noSuchMethod(
Invocation.method(
#deleteMembre,
[id],
),
returnValue: _i5.Future<void>.value(),
returnValueForMissingStub: _i5.Future<void>.value(),
) as _i5.Future<void>);
@override
_i5.Future<_i3.MembreCompletModel> activateMembre(String? id) =>
(super.noSuchMethod(
Invocation.method(
#activateMembre,
[id],
),
returnValue:
_i5.Future<_i3.MembreCompletModel>.value(_FakeMembreCompletModel_1(
this,
Invocation.method(
#activateMembre,
[id],
),
)),
) as _i5.Future<_i3.MembreCompletModel>);
@override
_i5.Future<_i3.MembreCompletModel> deactivateMembre(String? id) =>
(super.noSuchMethod(
Invocation.method(
#deactivateMembre,
[id],
),
returnValue:
_i5.Future<_i3.MembreCompletModel>.value(_FakeMembreCompletModel_1(
this,
Invocation.method(
#deactivateMembre,
[id],
),
)),
) as _i5.Future<_i3.MembreCompletModel>);
@override
_i5.Future<_i2.MembreSearchResult> searchMembres({
required _i6.MembreSearchCriteria? criteria,
int? page = 0,
int? size = 20,
}) =>
(super.noSuchMethod(
Invocation.method(
#searchMembres,
[],
{
#criteria: criteria,
#page: page,
#size: size,
},
),
returnValue:
_i5.Future<_i2.MembreSearchResult>.value(_FakeMembreSearchResult_0(
this,
Invocation.method(
#searchMembres,
[],
{
#criteria: criteria,
#page: page,
#size: size,
},
),
)),
) as _i5.Future<_i2.MembreSearchResult>);
@override
_i5.Future<_i2.MembreSearchResult> getActiveMembers({
int? page = 0,
int? size = 20,
}) =>
(super.noSuchMethod(
Invocation.method(
#getActiveMembers,
[],
{
#page: page,
#size: size,
},
),
returnValue:
_i5.Future<_i2.MembreSearchResult>.value(_FakeMembreSearchResult_0(
this,
Invocation.method(
#getActiveMembers,
[],
{
#page: page,
#size: size,
},
),
)),
) as _i5.Future<_i2.MembreSearchResult>);
@override
_i5.Future<_i2.MembreSearchResult> getBureauMembers({
int? page = 0,
int? size = 20,
}) =>
(super.noSuchMethod(
Invocation.method(
#getBureauMembers,
[],
{
#page: page,
#size: size,
},
),
returnValue:
_i5.Future<_i2.MembreSearchResult>.value(_FakeMembreSearchResult_0(
this,
Invocation.method(
#getBureauMembers,
[],
{
#page: page,
#size: size,
},
),
)),
) as _i5.Future<_i2.MembreSearchResult>);
@override
_i5.Future<Map<String, dynamic>> getMembresStats() => (super.noSuchMethod(
Invocation.method(
#getMembresStats,
[],
),
returnValue:
_i5.Future<Map<String, dynamic>>.value(<String, dynamic>{}),
) as _i5.Future<Map<String, dynamic>>);
}

View File

@@ -0,0 +1,134 @@
/// Tests unitaires pour ExportMembers use case
library export_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/export_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 'export_members_test.mocks.dart';
void main() {
late ExportMembers useCase;
late MockIMembreRepository mockRepository;
setUp(() {
mockRepository = MockIMembreRepository();
useCase = ExportMembers(mockRepository);
});
group('ExportMembers Use Case', () {
const tFormat = 'csv';
final tCriteria = MembreSearchCriteria(
statut: 'ACTIF',
);
final tMembers = [
MembreCompletModel(
id: '1',
nom: 'Diallo',
prenom: 'Amadou',
email: 'amadou@example.com',
genre: Genre.homme,
statut: StatutMembre.actif,
),
MembreCompletModel(
id: '2',
nom: 'Ndiaye',
prenom: 'Fatou',
email: 'fatou@example.com',
genre: Genre.femme,
statut: StatutMembre.actif,
),
];
final tSearchResult = MembreSearchResult(
membres: tMembers,
totalElements: 2,
totalPages: 1,
currentPage: 0,
pageSize: 10000,
numberOfElements: 2,
hasNext: false,
hasPrevious: false,
isFirst: true,
isLast: true,
criteria: tCriteria,
executionTimeMs: 50,
);
test('should export members to CSV format successfully', () async {
// Arrange
when(mockRepository.searchMembres(
criteria: anyNamed('criteria'),
page: anyNamed('page'),
size: anyNamed('size'),
)).thenAnswer((_) async => tSearchResult);
// Act
final result = await useCase(criteria: tCriteria, format: tFormat);
// Assert
expect(result, isA<List<Map<String, dynamic>>>());
expect(result.length, equals(2));
expect(result[0]['nom'], equals('Diallo'));
expect(result[0]['email'], equals('amadou@example.com'));
verify(mockRepository.searchMembres(
criteria: anyNamed('criteria'),
page: anyNamed('page'),
size: anyNamed('size'),
));
verifyNoMoreInteractions(mockRepository);
});
test('should export members to PDF format', () async {
// Arrange
const pdfFormat = 'pdf';
when(mockRepository.searchMembres(
criteria: anyNamed('criteria'),
page: anyNamed('page'),
size: anyNamed('size'),
)).thenAnswer((_) async => tSearchResult);
// Act
final result = await useCase(criteria: tCriteria, format: pdfFormat);
// Assert
expect(result.length, equals(2));
expect(result[1]['prenom'], equals('Fatou'));
});
test('should export all members when no criteria provided', () async {
// Arrange
when(mockRepository.searchMembres(
criteria: anyNamed('criteria'),
page: anyNamed('page'),
size: anyNamed('size'),
)).thenAnswer((_) async => tSearchResult);
// Act
final result = await useCase(criteria: null, format: tFormat);
// Assert
expect(result, isNotNull);
expect(result.length, equals(2));
});
test('should throw exception when export fails', () async {
// Arrange
when(mockRepository.searchMembres(
criteria: anyNamed('criteria'),
page: anyNamed('page'),
size: anyNamed('size'),
)).thenThrow(Exception('Échec de l\'export'));
// Act & Assert
expect(() => useCase(criteria: tCriteria, format: tFormat), throwsException);
});
});
}

View File

@@ -0,0 +1,286 @@
// Mocks generated by Mockito 5.4.4 from annotations
// in unionflow_mobile_apps/test/features/members/domain/usecases/export_members_test.dart.
// Do not manually edit this file.
// ignore_for_file: no_leading_underscores_for_library_prefixes
import 'dart:async' as _i5;
import 'package:mockito/mockito.dart' as _i1;
import 'package:unionflow_mobile_apps/features/members/data/models/membre_complete_model.dart'
as _i3;
import 'package:unionflow_mobile_apps/features/members/domain/repositories/membre_repository.dart'
as _i4;
import 'package:unionflow_mobile_apps/shared/models/membre_search_criteria.dart'
as _i6;
import 'package:unionflow_mobile_apps/shared/models/membre_search_result.dart'
as _i2;
// ignore_for_file: type=lint
// ignore_for_file: avoid_redundant_argument_values
// ignore_for_file: avoid_setters_without_getters
// ignore_for_file: comment_references
// ignore_for_file: deprecated_member_use
// ignore_for_file: deprecated_member_use_from_same_package
// ignore_for_file: implementation_imports
// ignore_for_file: invalid_use_of_visible_for_testing_member
// ignore_for_file: prefer_const_constructors
// ignore_for_file: unnecessary_parenthesis
// ignore_for_file: camel_case_types
// ignore_for_file: subtype_of_sealed_class
class _FakeMembreSearchResult_0 extends _i1.SmartFake
implements _i2.MembreSearchResult {
_FakeMembreSearchResult_0(
Object parent,
Invocation parentInvocation,
) : super(
parent,
parentInvocation,
);
}
class _FakeMembreCompletModel_1 extends _i1.SmartFake
implements _i3.MembreCompletModel {
_FakeMembreCompletModel_1(
Object parent,
Invocation parentInvocation,
) : super(
parent,
parentInvocation,
);
}
/// A class which mocks [IMembreRepository].
///
/// See the documentation for Mockito's code generation for more information.
class MockIMembreRepository extends _i1.Mock implements _i4.IMembreRepository {
MockIMembreRepository() {
_i1.throwOnMissingStub(this);
}
@override
_i5.Future<_i2.MembreSearchResult> getMembres({
int? page = 0,
int? size = 20,
String? recherche,
}) =>
(super.noSuchMethod(
Invocation.method(
#getMembres,
[],
{
#page: page,
#size: size,
#recherche: recherche,
},
),
returnValue:
_i5.Future<_i2.MembreSearchResult>.value(_FakeMembreSearchResult_0(
this,
Invocation.method(
#getMembres,
[],
{
#page: page,
#size: size,
#recherche: recherche,
},
),
)),
) as _i5.Future<_i2.MembreSearchResult>);
@override
_i5.Future<_i3.MembreCompletModel?> getMembreById(String? id) =>
(super.noSuchMethod(
Invocation.method(
#getMembreById,
[id],
),
returnValue: _i5.Future<_i3.MembreCompletModel?>.value(),
) as _i5.Future<_i3.MembreCompletModel?>);
@override
_i5.Future<_i3.MembreCompletModel> createMembre(
_i3.MembreCompletModel? membre) =>
(super.noSuchMethod(
Invocation.method(
#createMembre,
[membre],
),
returnValue:
_i5.Future<_i3.MembreCompletModel>.value(_FakeMembreCompletModel_1(
this,
Invocation.method(
#createMembre,
[membre],
),
)),
) as _i5.Future<_i3.MembreCompletModel>);
@override
_i5.Future<_i3.MembreCompletModel> updateMembre(
String? id,
_i3.MembreCompletModel? membre,
) =>
(super.noSuchMethod(
Invocation.method(
#updateMembre,
[
id,
membre,
],
),
returnValue:
_i5.Future<_i3.MembreCompletModel>.value(_FakeMembreCompletModel_1(
this,
Invocation.method(
#updateMembre,
[
id,
membre,
],
),
)),
) as _i5.Future<_i3.MembreCompletModel>);
@override
_i5.Future<void> deleteMembre(String? id) => (super.noSuchMethod(
Invocation.method(
#deleteMembre,
[id],
),
returnValue: _i5.Future<void>.value(),
returnValueForMissingStub: _i5.Future<void>.value(),
) as _i5.Future<void>);
@override
_i5.Future<_i3.MembreCompletModel> activateMembre(String? id) =>
(super.noSuchMethod(
Invocation.method(
#activateMembre,
[id],
),
returnValue:
_i5.Future<_i3.MembreCompletModel>.value(_FakeMembreCompletModel_1(
this,
Invocation.method(
#activateMembre,
[id],
),
)),
) as _i5.Future<_i3.MembreCompletModel>);
@override
_i5.Future<_i3.MembreCompletModel> deactivateMembre(String? id) =>
(super.noSuchMethod(
Invocation.method(
#deactivateMembre,
[id],
),
returnValue:
_i5.Future<_i3.MembreCompletModel>.value(_FakeMembreCompletModel_1(
this,
Invocation.method(
#deactivateMembre,
[id],
),
)),
) as _i5.Future<_i3.MembreCompletModel>);
@override
_i5.Future<_i2.MembreSearchResult> searchMembres({
required _i6.MembreSearchCriteria? criteria,
int? page = 0,
int? size = 20,
}) =>
(super.noSuchMethod(
Invocation.method(
#searchMembres,
[],
{
#criteria: criteria,
#page: page,
#size: size,
},
),
returnValue:
_i5.Future<_i2.MembreSearchResult>.value(_FakeMembreSearchResult_0(
this,
Invocation.method(
#searchMembres,
[],
{
#criteria: criteria,
#page: page,
#size: size,
},
),
)),
) as _i5.Future<_i2.MembreSearchResult>);
@override
_i5.Future<_i2.MembreSearchResult> getActiveMembers({
int? page = 0,
int? size = 20,
}) =>
(super.noSuchMethod(
Invocation.method(
#getActiveMembers,
[],
{
#page: page,
#size: size,
},
),
returnValue:
_i5.Future<_i2.MembreSearchResult>.value(_FakeMembreSearchResult_0(
this,
Invocation.method(
#getActiveMembers,
[],
{
#page: page,
#size: size,
},
),
)),
) as _i5.Future<_i2.MembreSearchResult>);
@override
_i5.Future<_i2.MembreSearchResult> getBureauMembers({
int? page = 0,
int? size = 20,
}) =>
(super.noSuchMethod(
Invocation.method(
#getBureauMembers,
[],
{
#page: page,
#size: size,
},
),
returnValue:
_i5.Future<_i2.MembreSearchResult>.value(_FakeMembreSearchResult_0(
this,
Invocation.method(
#getBureauMembers,
[],
{
#page: page,
#size: size,
},
),
)),
) as _i5.Future<_i2.MembreSearchResult>);
@override
_i5.Future<Map<String, dynamic>> getMembresStats() => (super.noSuchMethod(
Invocation.method(
#getMembresStats,
[],
),
returnValue:
_i5.Future<Map<String, dynamic>>.value(<String, dynamic>{}),
) as _i5.Future<Map<String, dynamic>>);
}

View File

@@ -0,0 +1,92 @@
/// Tests unitaires pour GetMemberById use case
library get_member_by_id_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/get_member_by_id.dart';
import 'package:unionflow_mobile_apps/features/members/data/models/membre_complete_model.dart';
@GenerateMocks([IMembreRepository])
import 'get_member_by_id_test.mocks.dart';
void main() {
late GetMemberById useCase;
late MockIMembreRepository mockRepository;
setUp(() {
mockRepository = MockIMembreRepository();
useCase = GetMemberById(mockRepository);
});
group('GetMemberById Use Case', () {
const tMemberId = '123';
final tMember = MembreCompletModel(
id: tMemberId,
nom: 'Diallo',
prenom: 'Amadou',
email: 'amadou.diallo@example.com',
telephone: '+221771234567',
genre: Genre.homme,
statut: StatutMembre.actif,
dateNaissance: DateTime(1985, 3, 15),
adresse: '12 Avenue Bourguiba, Dakar',
profession: 'Ingénieur Informatique',
);
test('should return member details by ID', () async {
// Arrange
when(mockRepository.getMembreById(tMemberId))
.thenAnswer((_) async => tMember);
// Act
final result = await useCase(tMemberId);
// Assert
expect(result, equals(tMember));
expect(result!.id, equals(tMemberId));
expect(result.nom, equals('Diallo'));
expect(result.prenom, equals('Amadou'));
expect(result.email, equals('amadou.diallo@example.com'));
verify(mockRepository.getMembreById(tMemberId));
verifyNoMoreInteractions(mockRepository);
});
test('should return member with all optional fields populated', () async {
// Arrange
when(mockRepository.getMembreById(tMemberId))
.thenAnswer((_) async => tMember);
// Act
final result = await useCase(tMemberId);
// Assert
expect(result!.telephone, equals('+221771234567'));
expect(result.dateNaissance, isNotNull);
expect(result.adresse, equals('12 Avenue Bourguiba, Dakar'));
expect(result.profession, equals('Ingénieur Informatique'));
});
test('should return null when member not found', () async {
// Arrange
when(mockRepository.getMembreById(any))
.thenAnswer((_) async => null);
// Act
final result = await useCase('999');
// Assert
expect(result, isNull);
});
test('should throw exception when repository fails', () async {
// Arrange
when(mockRepository.getMembreById(any))
.thenThrow(Exception('Membre non trouvé'));
// Act & Assert
expect(() => useCase(tMemberId), throwsException);
});
});
}

View File

@@ -0,0 +1,286 @@
// Mocks generated by Mockito 5.4.4 from annotations
// in unionflow_mobile_apps/test/features/members/domain/usecases/get_member_by_id_test.dart.
// Do not manually edit this file.
// ignore_for_file: no_leading_underscores_for_library_prefixes
import 'dart:async' as _i5;
import 'package:mockito/mockito.dart' as _i1;
import 'package:unionflow_mobile_apps/features/members/data/models/membre_complete_model.dart'
as _i3;
import 'package:unionflow_mobile_apps/features/members/domain/repositories/membre_repository.dart'
as _i4;
import 'package:unionflow_mobile_apps/shared/models/membre_search_criteria.dart'
as _i6;
import 'package:unionflow_mobile_apps/shared/models/membre_search_result.dart'
as _i2;
// ignore_for_file: type=lint
// ignore_for_file: avoid_redundant_argument_values
// ignore_for_file: avoid_setters_without_getters
// ignore_for_file: comment_references
// ignore_for_file: deprecated_member_use
// ignore_for_file: deprecated_member_use_from_same_package
// ignore_for_file: implementation_imports
// ignore_for_file: invalid_use_of_visible_for_testing_member
// ignore_for_file: prefer_const_constructors
// ignore_for_file: unnecessary_parenthesis
// ignore_for_file: camel_case_types
// ignore_for_file: subtype_of_sealed_class
class _FakeMembreSearchResult_0 extends _i1.SmartFake
implements _i2.MembreSearchResult {
_FakeMembreSearchResult_0(
Object parent,
Invocation parentInvocation,
) : super(
parent,
parentInvocation,
);
}
class _FakeMembreCompletModel_1 extends _i1.SmartFake
implements _i3.MembreCompletModel {
_FakeMembreCompletModel_1(
Object parent,
Invocation parentInvocation,
) : super(
parent,
parentInvocation,
);
}
/// A class which mocks [IMembreRepository].
///
/// See the documentation for Mockito's code generation for more information.
class MockIMembreRepository extends _i1.Mock implements _i4.IMembreRepository {
MockIMembreRepository() {
_i1.throwOnMissingStub(this);
}
@override
_i5.Future<_i2.MembreSearchResult> getMembres({
int? page = 0,
int? size = 20,
String? recherche,
}) =>
(super.noSuchMethod(
Invocation.method(
#getMembres,
[],
{
#page: page,
#size: size,
#recherche: recherche,
},
),
returnValue:
_i5.Future<_i2.MembreSearchResult>.value(_FakeMembreSearchResult_0(
this,
Invocation.method(
#getMembres,
[],
{
#page: page,
#size: size,
#recherche: recherche,
},
),
)),
) as _i5.Future<_i2.MembreSearchResult>);
@override
_i5.Future<_i3.MembreCompletModel?> getMembreById(String? id) =>
(super.noSuchMethod(
Invocation.method(
#getMembreById,
[id],
),
returnValue: _i5.Future<_i3.MembreCompletModel?>.value(),
) as _i5.Future<_i3.MembreCompletModel?>);
@override
_i5.Future<_i3.MembreCompletModel> createMembre(
_i3.MembreCompletModel? membre) =>
(super.noSuchMethod(
Invocation.method(
#createMembre,
[membre],
),
returnValue:
_i5.Future<_i3.MembreCompletModel>.value(_FakeMembreCompletModel_1(
this,
Invocation.method(
#createMembre,
[membre],
),
)),
) as _i5.Future<_i3.MembreCompletModel>);
@override
_i5.Future<_i3.MembreCompletModel> updateMembre(
String? id,
_i3.MembreCompletModel? membre,
) =>
(super.noSuchMethod(
Invocation.method(
#updateMembre,
[
id,
membre,
],
),
returnValue:
_i5.Future<_i3.MembreCompletModel>.value(_FakeMembreCompletModel_1(
this,
Invocation.method(
#updateMembre,
[
id,
membre,
],
),
)),
) as _i5.Future<_i3.MembreCompletModel>);
@override
_i5.Future<void> deleteMembre(String? id) => (super.noSuchMethod(
Invocation.method(
#deleteMembre,
[id],
),
returnValue: _i5.Future<void>.value(),
returnValueForMissingStub: _i5.Future<void>.value(),
) as _i5.Future<void>);
@override
_i5.Future<_i3.MembreCompletModel> activateMembre(String? id) =>
(super.noSuchMethod(
Invocation.method(
#activateMembre,
[id],
),
returnValue:
_i5.Future<_i3.MembreCompletModel>.value(_FakeMembreCompletModel_1(
this,
Invocation.method(
#activateMembre,
[id],
),
)),
) as _i5.Future<_i3.MembreCompletModel>);
@override
_i5.Future<_i3.MembreCompletModel> deactivateMembre(String? id) =>
(super.noSuchMethod(
Invocation.method(
#deactivateMembre,
[id],
),
returnValue:
_i5.Future<_i3.MembreCompletModel>.value(_FakeMembreCompletModel_1(
this,
Invocation.method(
#deactivateMembre,
[id],
),
)),
) as _i5.Future<_i3.MembreCompletModel>);
@override
_i5.Future<_i2.MembreSearchResult> searchMembres({
required _i6.MembreSearchCriteria? criteria,
int? page = 0,
int? size = 20,
}) =>
(super.noSuchMethod(
Invocation.method(
#searchMembres,
[],
{
#criteria: criteria,
#page: page,
#size: size,
},
),
returnValue:
_i5.Future<_i2.MembreSearchResult>.value(_FakeMembreSearchResult_0(
this,
Invocation.method(
#searchMembres,
[],
{
#criteria: criteria,
#page: page,
#size: size,
},
),
)),
) as _i5.Future<_i2.MembreSearchResult>);
@override
_i5.Future<_i2.MembreSearchResult> getActiveMembers({
int? page = 0,
int? size = 20,
}) =>
(super.noSuchMethod(
Invocation.method(
#getActiveMembers,
[],
{
#page: page,
#size: size,
},
),
returnValue:
_i5.Future<_i2.MembreSearchResult>.value(_FakeMembreSearchResult_0(
this,
Invocation.method(
#getActiveMembers,
[],
{
#page: page,
#size: size,
},
),
)),
) as _i5.Future<_i2.MembreSearchResult>);
@override
_i5.Future<_i2.MembreSearchResult> getBureauMembers({
int? page = 0,
int? size = 20,
}) =>
(super.noSuchMethod(
Invocation.method(
#getBureauMembers,
[],
{
#page: page,
#size: size,
},
),
returnValue:
_i5.Future<_i2.MembreSearchResult>.value(_FakeMembreSearchResult_0(
this,
Invocation.method(
#getBureauMembers,
[],
{
#page: page,
#size: size,
},
),
)),
) as _i5.Future<_i2.MembreSearchResult>);
@override
_i5.Future<Map<String, dynamic>> getMembresStats() => (super.noSuchMethod(
Invocation.method(
#getMembresStats,
[],
),
returnValue:
_i5.Future<Map<String, dynamic>>.value(<String, dynamic>{}),
) as _i5.Future<Map<String, dynamic>>);
}

View File

@@ -0,0 +1,111 @@
/// Tests unitaires pour GetMemberStats use case
library get_member_stats_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/get_member_stats.dart';
@GenerateMocks([IMembreRepository])
import 'get_member_stats_test.mocks.dart';
void main() {
late GetMemberStats useCase;
late MockIMembreRepository mockRepository;
setUp(() {
mockRepository = MockIMembreRepository();
useCase = GetMemberStats(mockRepository);
});
group('GetMemberStats Use Case', () {
final tMemberStats = {
'totalMembres': 250,
'membresActifs': 180,
'membresInactifs': 50,
'membresSuspendus': 15,
'membresEnAttente': 5,
'repartitionGenre': {
'hommes': 130,
'femmes': 115,
'autre': 5,
},
'nouveauxMembresMois': 12,
'tauxActivation': 0.72,
'agesMoyens': {
'global': 42.5,
'hommes': 44.2,
'femmes': 40.8,
},
};
test('should return comprehensive member statistics', () async {
// Arrange
when(mockRepository.getMembresStats())
.thenAnswer((_) async => tMemberStats);
// Act
final result = await useCase();
// Assert
expect(result, equals(tMemberStats));
expect(result['totalMembres'], equals(250));
expect(result['membresActifs'], equals(180));
expect(result['tauxActivation'], equals(0.72));
verify(mockRepository.getMembresStats());
verifyNoMoreInteractions(mockRepository);
});
test('should return gender distribution statistics', () async {
// Arrange
when(mockRepository.getMembresStats())
.thenAnswer((_) async => tMemberStats);
// Act
final result = await useCase();
// Assert
final repartition = result['repartitionGenre'] as Map<String, dynamic>;
expect(repartition['hommes'], equals(130));
expect(repartition['femmes'], equals(115));
expect(repartition['autre'], equals(5));
});
test('should return empty stats when no members exist', () async {
// Arrange
final emptyStats = {
'totalMembres': 0,
'membresActifs': 0,
'membresInactifs': 0,
'membresSuspendus': 0,
'membresEnAttente': 0,
'repartitionGenre': {
'hommes': 0,
'femmes': 0,
'autre': 0,
},
'nouveauxMembresMois': 0,
'tauxActivation': 0.0,
};
when(mockRepository.getMembresStats())
.thenAnswer((_) async => emptyStats);
// Act
final result = await useCase();
// Assert
expect(result['totalMembres'], equals(0));
expect(result['tauxActivation'], equals(0.0));
});
test('should throw exception when stats retrieval fails', () async {
// Arrange
when(mockRepository.getMembresStats())
.thenThrow(Exception('Erreur serveur'));
// Act & Assert
expect(() => useCase(), throwsException);
});
});
}

View File

@@ -0,0 +1,286 @@
// Mocks generated by Mockito 5.4.4 from annotations
// in unionflow_mobile_apps/test/features/members/domain/usecases/get_member_stats_test.dart.
// Do not manually edit this file.
// ignore_for_file: no_leading_underscores_for_library_prefixes
import 'dart:async' as _i5;
import 'package:mockito/mockito.dart' as _i1;
import 'package:unionflow_mobile_apps/features/members/data/models/membre_complete_model.dart'
as _i3;
import 'package:unionflow_mobile_apps/features/members/domain/repositories/membre_repository.dart'
as _i4;
import 'package:unionflow_mobile_apps/shared/models/membre_search_criteria.dart'
as _i6;
import 'package:unionflow_mobile_apps/shared/models/membre_search_result.dart'
as _i2;
// ignore_for_file: type=lint
// ignore_for_file: avoid_redundant_argument_values
// ignore_for_file: avoid_setters_without_getters
// ignore_for_file: comment_references
// ignore_for_file: deprecated_member_use
// ignore_for_file: deprecated_member_use_from_same_package
// ignore_for_file: implementation_imports
// ignore_for_file: invalid_use_of_visible_for_testing_member
// ignore_for_file: prefer_const_constructors
// ignore_for_file: unnecessary_parenthesis
// ignore_for_file: camel_case_types
// ignore_for_file: subtype_of_sealed_class
class _FakeMembreSearchResult_0 extends _i1.SmartFake
implements _i2.MembreSearchResult {
_FakeMembreSearchResult_0(
Object parent,
Invocation parentInvocation,
) : super(
parent,
parentInvocation,
);
}
class _FakeMembreCompletModel_1 extends _i1.SmartFake
implements _i3.MembreCompletModel {
_FakeMembreCompletModel_1(
Object parent,
Invocation parentInvocation,
) : super(
parent,
parentInvocation,
);
}
/// A class which mocks [IMembreRepository].
///
/// See the documentation for Mockito's code generation for more information.
class MockIMembreRepository extends _i1.Mock implements _i4.IMembreRepository {
MockIMembreRepository() {
_i1.throwOnMissingStub(this);
}
@override
_i5.Future<_i2.MembreSearchResult> getMembres({
int? page = 0,
int? size = 20,
String? recherche,
}) =>
(super.noSuchMethod(
Invocation.method(
#getMembres,
[],
{
#page: page,
#size: size,
#recherche: recherche,
},
),
returnValue:
_i5.Future<_i2.MembreSearchResult>.value(_FakeMembreSearchResult_0(
this,
Invocation.method(
#getMembres,
[],
{
#page: page,
#size: size,
#recherche: recherche,
},
),
)),
) as _i5.Future<_i2.MembreSearchResult>);
@override
_i5.Future<_i3.MembreCompletModel?> getMembreById(String? id) =>
(super.noSuchMethod(
Invocation.method(
#getMembreById,
[id],
),
returnValue: _i5.Future<_i3.MembreCompletModel?>.value(),
) as _i5.Future<_i3.MembreCompletModel?>);
@override
_i5.Future<_i3.MembreCompletModel> createMembre(
_i3.MembreCompletModel? membre) =>
(super.noSuchMethod(
Invocation.method(
#createMembre,
[membre],
),
returnValue:
_i5.Future<_i3.MembreCompletModel>.value(_FakeMembreCompletModel_1(
this,
Invocation.method(
#createMembre,
[membre],
),
)),
) as _i5.Future<_i3.MembreCompletModel>);
@override
_i5.Future<_i3.MembreCompletModel> updateMembre(
String? id,
_i3.MembreCompletModel? membre,
) =>
(super.noSuchMethod(
Invocation.method(
#updateMembre,
[
id,
membre,
],
),
returnValue:
_i5.Future<_i3.MembreCompletModel>.value(_FakeMembreCompletModel_1(
this,
Invocation.method(
#updateMembre,
[
id,
membre,
],
),
)),
) as _i5.Future<_i3.MembreCompletModel>);
@override
_i5.Future<void> deleteMembre(String? id) => (super.noSuchMethod(
Invocation.method(
#deleteMembre,
[id],
),
returnValue: _i5.Future<void>.value(),
returnValueForMissingStub: _i5.Future<void>.value(),
) as _i5.Future<void>);
@override
_i5.Future<_i3.MembreCompletModel> activateMembre(String? id) =>
(super.noSuchMethod(
Invocation.method(
#activateMembre,
[id],
),
returnValue:
_i5.Future<_i3.MembreCompletModel>.value(_FakeMembreCompletModel_1(
this,
Invocation.method(
#activateMembre,
[id],
),
)),
) as _i5.Future<_i3.MembreCompletModel>);
@override
_i5.Future<_i3.MembreCompletModel> deactivateMembre(String? id) =>
(super.noSuchMethod(
Invocation.method(
#deactivateMembre,
[id],
),
returnValue:
_i5.Future<_i3.MembreCompletModel>.value(_FakeMembreCompletModel_1(
this,
Invocation.method(
#deactivateMembre,
[id],
),
)),
) as _i5.Future<_i3.MembreCompletModel>);
@override
_i5.Future<_i2.MembreSearchResult> searchMembres({
required _i6.MembreSearchCriteria? criteria,
int? page = 0,
int? size = 20,
}) =>
(super.noSuchMethod(
Invocation.method(
#searchMembres,
[],
{
#criteria: criteria,
#page: page,
#size: size,
},
),
returnValue:
_i5.Future<_i2.MembreSearchResult>.value(_FakeMembreSearchResult_0(
this,
Invocation.method(
#searchMembres,
[],
{
#criteria: criteria,
#page: page,
#size: size,
},
),
)),
) as _i5.Future<_i2.MembreSearchResult>);
@override
_i5.Future<_i2.MembreSearchResult> getActiveMembers({
int? page = 0,
int? size = 20,
}) =>
(super.noSuchMethod(
Invocation.method(
#getActiveMembers,
[],
{
#page: page,
#size: size,
},
),
returnValue:
_i5.Future<_i2.MembreSearchResult>.value(_FakeMembreSearchResult_0(
this,
Invocation.method(
#getActiveMembers,
[],
{
#page: page,
#size: size,
},
),
)),
) as _i5.Future<_i2.MembreSearchResult>);
@override
_i5.Future<_i2.MembreSearchResult> getBureauMembers({
int? page = 0,
int? size = 20,
}) =>
(super.noSuchMethod(
Invocation.method(
#getBureauMembers,
[],
{
#page: page,
#size: size,
},
),
returnValue:
_i5.Future<_i2.MembreSearchResult>.value(_FakeMembreSearchResult_0(
this,
Invocation.method(
#getBureauMembers,
[],
{
#page: page,
#size: size,
},
),
)),
) as _i5.Future<_i2.MembreSearchResult>);
@override
_i5.Future<Map<String, dynamic>> getMembresStats() => (super.noSuchMethod(
Invocation.method(
#getMembresStats,
[],
),
returnValue:
_i5.Future<Map<String, dynamic>>.value(<String, dynamic>{}),
) as _i5.Future<Map<String, dynamic>>);
}

View File

@@ -0,0 +1,157 @@
/// Tests unitaires pour GetMembers use case
library get_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/get_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 'get_members_test.mocks.dart';
void main() {
late GetMembers useCase;
late MockIMembreRepository mockRepository;
setUp(() {
mockRepository = MockIMembreRepository();
useCase = GetMembers(mockRepository);
});
group('GetMembers Use Case', () {
final tMembersList = [
MembreCompletModel(
id: '1',
nom: 'Diallo',
prenom: 'Amadou',
email: 'amadou.diallo@example.com',
genre: Genre.homme,
statut: StatutMembre.actif,
),
MembreCompletModel(
id: '2',
nom: 'Ndiaye',
prenom: 'Fatou',
email: 'fatou.ndiaye@example.com',
genre: Genre.femme,
statut: StatutMembre.actif,
),
];
final tSearchResult = MembreSearchResult(
membres: tMembersList,
totalElements: 2,
totalPages: 1,
currentPage: 0,
pageSize: 50,
numberOfElements: 2,
hasNext: false,
hasPrevious: false,
isFirst: true,
isLast: true,
criteria: MembreSearchCriteria(),
executionTimeMs: 45,
);
test('should return paginated list of all members', () async {
// Arrange
when(mockRepository.getMembres(
page: anyNamed('page'),
size: anyNamed('size'),
recherche: anyNamed('recherche'),
)).thenAnswer((_) async => tSearchResult);
// Act
final result = await useCase(page: 0, size: 50);
// Assert
expect(result, equals(tSearchResult));
expect(result.membres.length, equals(2));
expect(result.totalElements, equals(2));
expect(result.membres[0].nom, equals('Diallo'));
verify(mockRepository.getMembres(
page: 0,
size: 50,
recherche: null,
));
verifyNoMoreInteractions(mockRepository);
});
test('should return members with custom page size', () async {
// Arrange
final smallResult = MembreSearchResult(
membres: [tMembersList[0]],
totalElements: 2,
totalPages: 2,
currentPage: 0,
pageSize: 1,
numberOfElements: 1,
hasNext: true,
hasPrevious: false,
isFirst: true,
isLast: false,
criteria: MembreSearchCriteria(),
executionTimeMs: 30,
);
when(mockRepository.getMembres(
page: 0,
size: 1,
recherche: null,
)).thenAnswer((_) async => smallResult);
// Act
final result = await useCase(page: 0, size: 1);
// Assert
expect(result.membres.length, equals(1));
expect(result.pageSize, equals(1));
expect(result.hasNext, isTrue);
});
test('should return empty result when no members exist', () async {
// Arrange
final emptyResult = MembreSearchResult(
membres: [],
totalElements: 0,
totalPages: 0,
currentPage: 0,
pageSize: 50,
numberOfElements: 0,
hasNext: false,
hasPrevious: false,
isFirst: true,
isLast: true,
criteria: MembreSearchCriteria(),
executionTimeMs: 20,
);
when(mockRepository.getMembres(
page: anyNamed('page'),
size: anyNamed('size'),
recherche: anyNamed('recherche'),
)).thenAnswer((_) async => emptyResult);
// Act
final result = await useCase(page: 0, size: 50);
// Assert
expect(result.membres, isEmpty);
expect(result.totalElements, equals(0));
});
test('should throw exception when repository fails', () async {
// Arrange
when(mockRepository.getMembres(
page: anyNamed('page'),
size: anyNamed('size'),
recherche: anyNamed('recherche'),
)).thenThrow(Exception('Erreur serveur'));
// Act & Assert
expect(() => useCase(page: 0, size: 50), throwsException);
});
});
}

View File

@@ -0,0 +1,286 @@
// Mocks generated by Mockito 5.4.4 from annotations
// in unionflow_mobile_apps/test/features/members/domain/usecases/get_members_test.dart.
// Do not manually edit this file.
// ignore_for_file: no_leading_underscores_for_library_prefixes
import 'dart:async' as _i5;
import 'package:mockito/mockito.dart' as _i1;
import 'package:unionflow_mobile_apps/features/members/data/models/membre_complete_model.dart'
as _i3;
import 'package:unionflow_mobile_apps/features/members/domain/repositories/membre_repository.dart'
as _i4;
import 'package:unionflow_mobile_apps/shared/models/membre_search_criteria.dart'
as _i6;
import 'package:unionflow_mobile_apps/shared/models/membre_search_result.dart'
as _i2;
// ignore_for_file: type=lint
// ignore_for_file: avoid_redundant_argument_values
// ignore_for_file: avoid_setters_without_getters
// ignore_for_file: comment_references
// ignore_for_file: deprecated_member_use
// ignore_for_file: deprecated_member_use_from_same_package
// ignore_for_file: implementation_imports
// ignore_for_file: invalid_use_of_visible_for_testing_member
// ignore_for_file: prefer_const_constructors
// ignore_for_file: unnecessary_parenthesis
// ignore_for_file: camel_case_types
// ignore_for_file: subtype_of_sealed_class
class _FakeMembreSearchResult_0 extends _i1.SmartFake
implements _i2.MembreSearchResult {
_FakeMembreSearchResult_0(
Object parent,
Invocation parentInvocation,
) : super(
parent,
parentInvocation,
);
}
class _FakeMembreCompletModel_1 extends _i1.SmartFake
implements _i3.MembreCompletModel {
_FakeMembreCompletModel_1(
Object parent,
Invocation parentInvocation,
) : super(
parent,
parentInvocation,
);
}
/// A class which mocks [IMembreRepository].
///
/// See the documentation for Mockito's code generation for more information.
class MockIMembreRepository extends _i1.Mock implements _i4.IMembreRepository {
MockIMembreRepository() {
_i1.throwOnMissingStub(this);
}
@override
_i5.Future<_i2.MembreSearchResult> getMembres({
int? page = 0,
int? size = 20,
String? recherche,
}) =>
(super.noSuchMethod(
Invocation.method(
#getMembres,
[],
{
#page: page,
#size: size,
#recherche: recherche,
},
),
returnValue:
_i5.Future<_i2.MembreSearchResult>.value(_FakeMembreSearchResult_0(
this,
Invocation.method(
#getMembres,
[],
{
#page: page,
#size: size,
#recherche: recherche,
},
),
)),
) as _i5.Future<_i2.MembreSearchResult>);
@override
_i5.Future<_i3.MembreCompletModel?> getMembreById(String? id) =>
(super.noSuchMethod(
Invocation.method(
#getMembreById,
[id],
),
returnValue: _i5.Future<_i3.MembreCompletModel?>.value(),
) as _i5.Future<_i3.MembreCompletModel?>);
@override
_i5.Future<_i3.MembreCompletModel> createMembre(
_i3.MembreCompletModel? membre) =>
(super.noSuchMethod(
Invocation.method(
#createMembre,
[membre],
),
returnValue:
_i5.Future<_i3.MembreCompletModel>.value(_FakeMembreCompletModel_1(
this,
Invocation.method(
#createMembre,
[membre],
),
)),
) as _i5.Future<_i3.MembreCompletModel>);
@override
_i5.Future<_i3.MembreCompletModel> updateMembre(
String? id,
_i3.MembreCompletModel? membre,
) =>
(super.noSuchMethod(
Invocation.method(
#updateMembre,
[
id,
membre,
],
),
returnValue:
_i5.Future<_i3.MembreCompletModel>.value(_FakeMembreCompletModel_1(
this,
Invocation.method(
#updateMembre,
[
id,
membre,
],
),
)),
) as _i5.Future<_i3.MembreCompletModel>);
@override
_i5.Future<void> deleteMembre(String? id) => (super.noSuchMethod(
Invocation.method(
#deleteMembre,
[id],
),
returnValue: _i5.Future<void>.value(),
returnValueForMissingStub: _i5.Future<void>.value(),
) as _i5.Future<void>);
@override
_i5.Future<_i3.MembreCompletModel> activateMembre(String? id) =>
(super.noSuchMethod(
Invocation.method(
#activateMembre,
[id],
),
returnValue:
_i5.Future<_i3.MembreCompletModel>.value(_FakeMembreCompletModel_1(
this,
Invocation.method(
#activateMembre,
[id],
),
)),
) as _i5.Future<_i3.MembreCompletModel>);
@override
_i5.Future<_i3.MembreCompletModel> deactivateMembre(String? id) =>
(super.noSuchMethod(
Invocation.method(
#deactivateMembre,
[id],
),
returnValue:
_i5.Future<_i3.MembreCompletModel>.value(_FakeMembreCompletModel_1(
this,
Invocation.method(
#deactivateMembre,
[id],
),
)),
) as _i5.Future<_i3.MembreCompletModel>);
@override
_i5.Future<_i2.MembreSearchResult> searchMembres({
required _i6.MembreSearchCriteria? criteria,
int? page = 0,
int? size = 20,
}) =>
(super.noSuchMethod(
Invocation.method(
#searchMembres,
[],
{
#criteria: criteria,
#page: page,
#size: size,
},
),
returnValue:
_i5.Future<_i2.MembreSearchResult>.value(_FakeMembreSearchResult_0(
this,
Invocation.method(
#searchMembres,
[],
{
#criteria: criteria,
#page: page,
#size: size,
},
),
)),
) as _i5.Future<_i2.MembreSearchResult>);
@override
_i5.Future<_i2.MembreSearchResult> getActiveMembers({
int? page = 0,
int? size = 20,
}) =>
(super.noSuchMethod(
Invocation.method(
#getActiveMembers,
[],
{
#page: page,
#size: size,
},
),
returnValue:
_i5.Future<_i2.MembreSearchResult>.value(_FakeMembreSearchResult_0(
this,
Invocation.method(
#getActiveMembers,
[],
{
#page: page,
#size: size,
},
),
)),
) as _i5.Future<_i2.MembreSearchResult>);
@override
_i5.Future<_i2.MembreSearchResult> getBureauMembers({
int? page = 0,
int? size = 20,
}) =>
(super.noSuchMethod(
Invocation.method(
#getBureauMembers,
[],
{
#page: page,
#size: size,
},
),
returnValue:
_i5.Future<_i2.MembreSearchResult>.value(_FakeMembreSearchResult_0(
this,
Invocation.method(
#getBureauMembers,
[],
{
#page: page,
#size: size,
},
),
)),
) as _i5.Future<_i2.MembreSearchResult>);
@override
_i5.Future<Map<String, dynamic>> getMembresStats() => (super.noSuchMethod(
Invocation.method(
#getMembresStats,
[],
),
returnValue:
_i5.Future<Map<String, dynamic>>.value(<String, dynamic>{}),
) as _i5.Future<Map<String, dynamic>>);
}

View File

@@ -0,0 +1,168 @@
/// 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 || m.statut == null), 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);
});
});
}

View File

@@ -0,0 +1,286 @@
// Mocks generated by Mockito 5.4.4 from annotations
// in unionflow_mobile_apps/test/features/members/domain/usecases/search_members_test.dart.
// Do not manually edit this file.
// ignore_for_file: no_leading_underscores_for_library_prefixes
import 'dart:async' as _i5;
import 'package:mockito/mockito.dart' as _i1;
import 'package:unionflow_mobile_apps/features/members/data/models/membre_complete_model.dart'
as _i3;
import 'package:unionflow_mobile_apps/features/members/domain/repositories/membre_repository.dart'
as _i4;
import 'package:unionflow_mobile_apps/shared/models/membre_search_criteria.dart'
as _i6;
import 'package:unionflow_mobile_apps/shared/models/membre_search_result.dart'
as _i2;
// ignore_for_file: type=lint
// ignore_for_file: avoid_redundant_argument_values
// ignore_for_file: avoid_setters_without_getters
// ignore_for_file: comment_references
// ignore_for_file: deprecated_member_use
// ignore_for_file: deprecated_member_use_from_same_package
// ignore_for_file: implementation_imports
// ignore_for_file: invalid_use_of_visible_for_testing_member
// ignore_for_file: prefer_const_constructors
// ignore_for_file: unnecessary_parenthesis
// ignore_for_file: camel_case_types
// ignore_for_file: subtype_of_sealed_class
class _FakeMembreSearchResult_0 extends _i1.SmartFake
implements _i2.MembreSearchResult {
_FakeMembreSearchResult_0(
Object parent,
Invocation parentInvocation,
) : super(
parent,
parentInvocation,
);
}
class _FakeMembreCompletModel_1 extends _i1.SmartFake
implements _i3.MembreCompletModel {
_FakeMembreCompletModel_1(
Object parent,
Invocation parentInvocation,
) : super(
parent,
parentInvocation,
);
}
/// A class which mocks [IMembreRepository].
///
/// See the documentation for Mockito's code generation for more information.
class MockIMembreRepository extends _i1.Mock implements _i4.IMembreRepository {
MockIMembreRepository() {
_i1.throwOnMissingStub(this);
}
@override
_i5.Future<_i2.MembreSearchResult> getMembres({
int? page = 0,
int? size = 20,
String? recherche,
}) =>
(super.noSuchMethod(
Invocation.method(
#getMembres,
[],
{
#page: page,
#size: size,
#recherche: recherche,
},
),
returnValue:
_i5.Future<_i2.MembreSearchResult>.value(_FakeMembreSearchResult_0(
this,
Invocation.method(
#getMembres,
[],
{
#page: page,
#size: size,
#recherche: recherche,
},
),
)),
) as _i5.Future<_i2.MembreSearchResult>);
@override
_i5.Future<_i3.MembreCompletModel?> getMembreById(String? id) =>
(super.noSuchMethod(
Invocation.method(
#getMembreById,
[id],
),
returnValue: _i5.Future<_i3.MembreCompletModel?>.value(),
) as _i5.Future<_i3.MembreCompletModel?>);
@override
_i5.Future<_i3.MembreCompletModel> createMembre(
_i3.MembreCompletModel? membre) =>
(super.noSuchMethod(
Invocation.method(
#createMembre,
[membre],
),
returnValue:
_i5.Future<_i3.MembreCompletModel>.value(_FakeMembreCompletModel_1(
this,
Invocation.method(
#createMembre,
[membre],
),
)),
) as _i5.Future<_i3.MembreCompletModel>);
@override
_i5.Future<_i3.MembreCompletModel> updateMembre(
String? id,
_i3.MembreCompletModel? membre,
) =>
(super.noSuchMethod(
Invocation.method(
#updateMembre,
[
id,
membre,
],
),
returnValue:
_i5.Future<_i3.MembreCompletModel>.value(_FakeMembreCompletModel_1(
this,
Invocation.method(
#updateMembre,
[
id,
membre,
],
),
)),
) as _i5.Future<_i3.MembreCompletModel>);
@override
_i5.Future<void> deleteMembre(String? id) => (super.noSuchMethod(
Invocation.method(
#deleteMembre,
[id],
),
returnValue: _i5.Future<void>.value(),
returnValueForMissingStub: _i5.Future<void>.value(),
) as _i5.Future<void>);
@override
_i5.Future<_i3.MembreCompletModel> activateMembre(String? id) =>
(super.noSuchMethod(
Invocation.method(
#activateMembre,
[id],
),
returnValue:
_i5.Future<_i3.MembreCompletModel>.value(_FakeMembreCompletModel_1(
this,
Invocation.method(
#activateMembre,
[id],
),
)),
) as _i5.Future<_i3.MembreCompletModel>);
@override
_i5.Future<_i3.MembreCompletModel> deactivateMembre(String? id) =>
(super.noSuchMethod(
Invocation.method(
#deactivateMembre,
[id],
),
returnValue:
_i5.Future<_i3.MembreCompletModel>.value(_FakeMembreCompletModel_1(
this,
Invocation.method(
#deactivateMembre,
[id],
),
)),
) as _i5.Future<_i3.MembreCompletModel>);
@override
_i5.Future<_i2.MembreSearchResult> searchMembres({
required _i6.MembreSearchCriteria? criteria,
int? page = 0,
int? size = 20,
}) =>
(super.noSuchMethod(
Invocation.method(
#searchMembres,
[],
{
#criteria: criteria,
#page: page,
#size: size,
},
),
returnValue:
_i5.Future<_i2.MembreSearchResult>.value(_FakeMembreSearchResult_0(
this,
Invocation.method(
#searchMembres,
[],
{
#criteria: criteria,
#page: page,
#size: size,
},
),
)),
) as _i5.Future<_i2.MembreSearchResult>);
@override
_i5.Future<_i2.MembreSearchResult> getActiveMembers({
int? page = 0,
int? size = 20,
}) =>
(super.noSuchMethod(
Invocation.method(
#getActiveMembers,
[],
{
#page: page,
#size: size,
},
),
returnValue:
_i5.Future<_i2.MembreSearchResult>.value(_FakeMembreSearchResult_0(
this,
Invocation.method(
#getActiveMembers,
[],
{
#page: page,
#size: size,
},
),
)),
) as _i5.Future<_i2.MembreSearchResult>);
@override
_i5.Future<_i2.MembreSearchResult> getBureauMembers({
int? page = 0,
int? size = 20,
}) =>
(super.noSuchMethod(
Invocation.method(
#getBureauMembers,
[],
{
#page: page,
#size: size,
},
),
returnValue:
_i5.Future<_i2.MembreSearchResult>.value(_FakeMembreSearchResult_0(
this,
Invocation.method(
#getBureauMembers,
[],
{
#page: page,
#size: size,
},
),
)),
) as _i5.Future<_i2.MembreSearchResult>);
@override
_i5.Future<Map<String, dynamic>> getMembresStats() => (super.noSuchMethod(
Invocation.method(
#getMembresStats,
[],
),
returnValue:
_i5.Future<Map<String, dynamic>>.value(<String, dynamic>{}),
) as _i5.Future<Map<String, dynamic>>);
}

View File

@@ -0,0 +1,102 @@
/// Tests unitaires pour UpdateMember use case
library update_member_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/update_member.dart';
import 'package:unionflow_mobile_apps/features/members/data/models/membre_complete_model.dart';
@GenerateMocks([IMembreRepository])
import 'update_member_test.mocks.dart';
void main() {
late UpdateMember useCase;
late MockIMembreRepository mockRepository;
setUp(() {
mockRepository = MockIMembreRepository();
useCase = UpdateMember(mockRepository);
});
group('UpdateMember Use Case', () {
const tMemberId = '123';
final tUpdatedData = MembreCompletModel(
id: tMemberId,
nom: 'Diallo',
prenom: 'Amadou',
email: 'amadou.diallo.updated@example.com',
telephone: '+221771112222',
genre: Genre.homme,
statut: StatutMembre.actif,
profession: 'Directeur IT',
);
final tUpdatedMember = MembreCompletModel(
id: tMemberId,
nom: 'Diallo',
prenom: 'Amadou',
email: 'amadou.diallo.updated@example.com',
telephone: '+221771112222',
genre: Genre.homme,
statut: StatutMembre.actif,
profession: 'Directeur IT',
);
test('should update member successfully', () async {
// Arrange
when(mockRepository.updateMembre(tMemberId, tUpdatedData))
.thenAnswer((_) async => tUpdatedMember);
// Act
final result = await useCase(tMemberId, tUpdatedData);
// Assert
expect(result, equals(tUpdatedMember));
expect(result.email, equals('amadou.diallo.updated@example.com'));
expect(result.telephone, equals('+221771112222'));
expect(result.profession, equals('Directeur IT'));
verify(mockRepository.updateMembre(tMemberId, tUpdatedData));
verifyNoMoreInteractions(mockRepository);
});
test('should update member status to suspended', () async {
// Arrange
final suspendedMember = MembreCompletModel(
id: tMemberId,
nom: 'Diallo',
prenom: 'Amadou',
email: 'amadou.diallo@example.com',
genre: Genre.homme,
statut: StatutMembre.suspendu,
);
when(mockRepository.updateMembre(tMemberId, suspendedMember))
.thenAnswer((_) async => suspendedMember);
// Act
final result = await useCase(tMemberId, suspendedMember);
// Assert
expect(result.statut, equals(StatutMembre.suspendu));
});
test('should throw exception when member not found', () async {
// Arrange
when(mockRepository.updateMembre(any, any))
.thenThrow(Exception('Membre non trouvé'));
// Act & Assert
expect(() => useCase('999', tUpdatedData), throwsA(isA<Exception>()));
});
test('should throw exception when validation fails', () async {
// Arrange
when(mockRepository.updateMembre(any, any))
.thenThrow(Exception('Email invalide'));
// Act & Assert
expect(() => useCase(tMemberId, tUpdatedData), throwsException);
});
});
}

View File

@@ -0,0 +1,286 @@
// Mocks generated by Mockito 5.4.4 from annotations
// in unionflow_mobile_apps/test/features/members/domain/usecases/update_member_test.dart.
// Do not manually edit this file.
// ignore_for_file: no_leading_underscores_for_library_prefixes
import 'dart:async' as _i5;
import 'package:mockito/mockito.dart' as _i1;
import 'package:unionflow_mobile_apps/features/members/data/models/membre_complete_model.dart'
as _i3;
import 'package:unionflow_mobile_apps/features/members/domain/repositories/membre_repository.dart'
as _i4;
import 'package:unionflow_mobile_apps/shared/models/membre_search_criteria.dart'
as _i6;
import 'package:unionflow_mobile_apps/shared/models/membre_search_result.dart'
as _i2;
// ignore_for_file: type=lint
// ignore_for_file: avoid_redundant_argument_values
// ignore_for_file: avoid_setters_without_getters
// ignore_for_file: comment_references
// ignore_for_file: deprecated_member_use
// ignore_for_file: deprecated_member_use_from_same_package
// ignore_for_file: implementation_imports
// ignore_for_file: invalid_use_of_visible_for_testing_member
// ignore_for_file: prefer_const_constructors
// ignore_for_file: unnecessary_parenthesis
// ignore_for_file: camel_case_types
// ignore_for_file: subtype_of_sealed_class
class _FakeMembreSearchResult_0 extends _i1.SmartFake
implements _i2.MembreSearchResult {
_FakeMembreSearchResult_0(
Object parent,
Invocation parentInvocation,
) : super(
parent,
parentInvocation,
);
}
class _FakeMembreCompletModel_1 extends _i1.SmartFake
implements _i3.MembreCompletModel {
_FakeMembreCompletModel_1(
Object parent,
Invocation parentInvocation,
) : super(
parent,
parentInvocation,
);
}
/// A class which mocks [IMembreRepository].
///
/// See the documentation for Mockito's code generation for more information.
class MockIMembreRepository extends _i1.Mock implements _i4.IMembreRepository {
MockIMembreRepository() {
_i1.throwOnMissingStub(this);
}
@override
_i5.Future<_i2.MembreSearchResult> getMembres({
int? page = 0,
int? size = 20,
String? recherche,
}) =>
(super.noSuchMethod(
Invocation.method(
#getMembres,
[],
{
#page: page,
#size: size,
#recherche: recherche,
},
),
returnValue:
_i5.Future<_i2.MembreSearchResult>.value(_FakeMembreSearchResult_0(
this,
Invocation.method(
#getMembres,
[],
{
#page: page,
#size: size,
#recherche: recherche,
},
),
)),
) as _i5.Future<_i2.MembreSearchResult>);
@override
_i5.Future<_i3.MembreCompletModel?> getMembreById(String? id) =>
(super.noSuchMethod(
Invocation.method(
#getMembreById,
[id],
),
returnValue: _i5.Future<_i3.MembreCompletModel?>.value(),
) as _i5.Future<_i3.MembreCompletModel?>);
@override
_i5.Future<_i3.MembreCompletModel> createMembre(
_i3.MembreCompletModel? membre) =>
(super.noSuchMethod(
Invocation.method(
#createMembre,
[membre],
),
returnValue:
_i5.Future<_i3.MembreCompletModel>.value(_FakeMembreCompletModel_1(
this,
Invocation.method(
#createMembre,
[membre],
),
)),
) as _i5.Future<_i3.MembreCompletModel>);
@override
_i5.Future<_i3.MembreCompletModel> updateMembre(
String? id,
_i3.MembreCompletModel? membre,
) =>
(super.noSuchMethod(
Invocation.method(
#updateMembre,
[
id,
membre,
],
),
returnValue:
_i5.Future<_i3.MembreCompletModel>.value(_FakeMembreCompletModel_1(
this,
Invocation.method(
#updateMembre,
[
id,
membre,
],
),
)),
) as _i5.Future<_i3.MembreCompletModel>);
@override
_i5.Future<void> deleteMembre(String? id) => (super.noSuchMethod(
Invocation.method(
#deleteMembre,
[id],
),
returnValue: _i5.Future<void>.value(),
returnValueForMissingStub: _i5.Future<void>.value(),
) as _i5.Future<void>);
@override
_i5.Future<_i3.MembreCompletModel> activateMembre(String? id) =>
(super.noSuchMethod(
Invocation.method(
#activateMembre,
[id],
),
returnValue:
_i5.Future<_i3.MembreCompletModel>.value(_FakeMembreCompletModel_1(
this,
Invocation.method(
#activateMembre,
[id],
),
)),
) as _i5.Future<_i3.MembreCompletModel>);
@override
_i5.Future<_i3.MembreCompletModel> deactivateMembre(String? id) =>
(super.noSuchMethod(
Invocation.method(
#deactivateMembre,
[id],
),
returnValue:
_i5.Future<_i3.MembreCompletModel>.value(_FakeMembreCompletModel_1(
this,
Invocation.method(
#deactivateMembre,
[id],
),
)),
) as _i5.Future<_i3.MembreCompletModel>);
@override
_i5.Future<_i2.MembreSearchResult> searchMembres({
required _i6.MembreSearchCriteria? criteria,
int? page = 0,
int? size = 20,
}) =>
(super.noSuchMethod(
Invocation.method(
#searchMembres,
[],
{
#criteria: criteria,
#page: page,
#size: size,
},
),
returnValue:
_i5.Future<_i2.MembreSearchResult>.value(_FakeMembreSearchResult_0(
this,
Invocation.method(
#searchMembres,
[],
{
#criteria: criteria,
#page: page,
#size: size,
},
),
)),
) as _i5.Future<_i2.MembreSearchResult>);
@override
_i5.Future<_i2.MembreSearchResult> getActiveMembers({
int? page = 0,
int? size = 20,
}) =>
(super.noSuchMethod(
Invocation.method(
#getActiveMembers,
[],
{
#page: page,
#size: size,
},
),
returnValue:
_i5.Future<_i2.MembreSearchResult>.value(_FakeMembreSearchResult_0(
this,
Invocation.method(
#getActiveMembers,
[],
{
#page: page,
#size: size,
},
),
)),
) as _i5.Future<_i2.MembreSearchResult>);
@override
_i5.Future<_i2.MembreSearchResult> getBureauMembers({
int? page = 0,
int? size = 20,
}) =>
(super.noSuchMethod(
Invocation.method(
#getBureauMembers,
[],
{
#page: page,
#size: size,
},
),
returnValue:
_i5.Future<_i2.MembreSearchResult>.value(_FakeMembreSearchResult_0(
this,
Invocation.method(
#getBureauMembers,
[],
{
#page: page,
#size: size,
},
),
)),
) as _i5.Future<_i2.MembreSearchResult>);
@override
_i5.Future<Map<String, dynamic>> getMembresStats() => (super.noSuchMethod(
Invocation.method(
#getMembresStats,
[],
),
returnValue:
_i5.Future<Map<String, dynamic>>.value(<String, dynamic>{}),
) as _i5.Future<Map<String, dynamic>>);
}