Initial commit: unionflow-mobile-apps
Application Flutter complète (sans build artifacts). Signed-off-by: lions dev Team
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
/// Tests unitaires pour CreateContribution use case
|
||||
library create_contribution_test;
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:unionflow_mobile_apps/features/contributions/domain/repositories/contribution_repository.dart';
|
||||
import 'package:unionflow_mobile_apps/features/contributions/domain/usecases/create_contribution.dart';
|
||||
import 'package:unionflow_mobile_apps/features/contributions/data/models/contribution_model.dart';
|
||||
|
||||
@GenerateMocks([IContributionRepository])
|
||||
import 'create_contribution_test.mocks.dart';
|
||||
|
||||
void main() {
|
||||
late CreateContribution useCase;
|
||||
late MockIContributionRepository mockRepository;
|
||||
|
||||
setUp(() {
|
||||
mockRepository = MockIContributionRepository();
|
||||
useCase = CreateContribution(mockRepository);
|
||||
});
|
||||
|
||||
group('CreateContribution Use Case', () {
|
||||
final tNewContribution = ContributionModel(
|
||||
membreId: 'membre1',
|
||||
montant: 5000.0,
|
||||
dateEcheance: DateTime(2024, 12, 31),
|
||||
annee: 2024,
|
||||
type: ContributionType.annuelle,
|
||||
statut: ContributionStatus.nonPayee,
|
||||
);
|
||||
|
||||
final tCreatedContribution = ContributionModel(
|
||||
id: 'cont123',
|
||||
membreId: 'membre1',
|
||||
membreNom: 'Dupont',
|
||||
membrePrenom: 'Jean',
|
||||
montant: 5000.0,
|
||||
dateEcheance: DateTime(2024, 12, 31),
|
||||
annee: 2024,
|
||||
type: ContributionType.annuelle,
|
||||
statut: ContributionStatus.nonPayee,
|
||||
);
|
||||
|
||||
test('should create contribution successfully', () async {
|
||||
// Arrange
|
||||
when(mockRepository.createCotisation(tNewContribution))
|
||||
.thenAnswer((_) async => tCreatedContribution);
|
||||
|
||||
// Act
|
||||
final result = await useCase(tNewContribution);
|
||||
|
||||
// Assert
|
||||
expect(result, equals(tCreatedContribution));
|
||||
expect(result.id, isNotNull);
|
||||
expect(result.id, equals('cont123'));
|
||||
expect(result.montant, equals(5000.0));
|
||||
verify(mockRepository.createCotisation(tNewContribution));
|
||||
verifyNoMoreInteractions(mockRepository);
|
||||
});
|
||||
|
||||
test('should create monthly contribution', () async {
|
||||
// Arrange
|
||||
final monthlyContribution = ContributionModel(
|
||||
membreId: 'membre1',
|
||||
montant: 2000.0,
|
||||
dateEcheance: DateTime(2024, 1, 31),
|
||||
annee: 2024,
|
||||
mois: 1,
|
||||
type: ContributionType.mensuelle,
|
||||
statut: ContributionStatus.nonPayee,
|
||||
);
|
||||
final createdMonthly = ContributionModel(
|
||||
id: 'cont456',
|
||||
membreId: 'membre1',
|
||||
montant: 2000.0,
|
||||
dateEcheance: DateTime(2024, 1, 31),
|
||||
annee: 2024,
|
||||
mois: 1,
|
||||
type: ContributionType.mensuelle,
|
||||
statut: ContributionStatus.nonPayee,
|
||||
);
|
||||
when(mockRepository.createCotisation(monthlyContribution))
|
||||
.thenAnswer((_) async => createdMonthly);
|
||||
|
||||
// Act
|
||||
final result = await useCase(monthlyContribution);
|
||||
|
||||
// Assert
|
||||
expect(result.type, equals(ContributionType.mensuelle));
|
||||
expect(result.mois, equals(1));
|
||||
});
|
||||
|
||||
test('should create contribution with description', () async {
|
||||
// Arrange
|
||||
final contributionWithDesc = ContributionModel(
|
||||
membreId: 'membre1',
|
||||
montant: 5000.0,
|
||||
dateEcheance: DateTime(2024, 12, 31),
|
||||
annee: 2024,
|
||||
type: ContributionType.exceptionnelle,
|
||||
statut: ContributionStatus.nonPayee,
|
||||
description: 'Cotisation exceptionnelle pour projet spécial',
|
||||
);
|
||||
when(mockRepository.createCotisation(any))
|
||||
.thenAnswer((_) async => contributionWithDesc.copyWith(id: 'cont789'));
|
||||
|
||||
// Act
|
||||
final result = await useCase(contributionWithDesc);
|
||||
|
||||
// Assert
|
||||
expect(result.description, isNotNull);
|
||||
expect(result.type, equals(ContributionType.exceptionnelle));
|
||||
});
|
||||
|
||||
test('should throw exception when creation fails', () async {
|
||||
// Arrange
|
||||
when(mockRepository.createCotisation(any))
|
||||
.thenThrow(Exception('Erreur de validation'));
|
||||
|
||||
// Act & Assert
|
||||
expect(() => useCase(tNewContribution), throwsException);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,335 @@
|
||||
// Mocks generated by Mockito 5.4.4 from annotations
|
||||
// in unionflow_mobile_apps/test/features/contributions/domain/usecases/create_contribution_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/contributions/data/models/contribution_model.dart'
|
||||
as _i3;
|
||||
import 'package:unionflow_mobile_apps/features/contributions/data/repositories/contribution_repository.dart'
|
||||
as _i2;
|
||||
import 'package:unionflow_mobile_apps/features/contributions/domain/repositories/contribution_repository.dart'
|
||||
as _i4;
|
||||
|
||||
// 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 _FakeContributionPageResult_0 extends _i1.SmartFake
|
||||
implements _i2.ContributionPageResult {
|
||||
_FakeContributionPageResult_0(
|
||||
Object parent,
|
||||
Invocation parentInvocation,
|
||||
) : super(
|
||||
parent,
|
||||
parentInvocation,
|
||||
);
|
||||
}
|
||||
|
||||
class _FakeContributionModel_1 extends _i1.SmartFake
|
||||
implements _i3.ContributionModel {
|
||||
_FakeContributionModel_1(
|
||||
Object parent,
|
||||
Invocation parentInvocation,
|
||||
) : super(
|
||||
parent,
|
||||
parentInvocation,
|
||||
);
|
||||
}
|
||||
|
||||
class _FakeWavePaiementInitResult_2 extends _i1.SmartFake
|
||||
implements _i2.WavePaiementInitResult {
|
||||
_FakeWavePaiementInitResult_2(
|
||||
Object parent,
|
||||
Invocation parentInvocation,
|
||||
) : super(
|
||||
parent,
|
||||
parentInvocation,
|
||||
);
|
||||
}
|
||||
|
||||
/// A class which mocks [IContributionRepository].
|
||||
///
|
||||
/// See the documentation for Mockito's code generation for more information.
|
||||
class MockIContributionRepository extends _i1.Mock
|
||||
implements _i4.IContributionRepository {
|
||||
MockIContributionRepository() {
|
||||
_i1.throwOnMissingStub(this);
|
||||
}
|
||||
|
||||
@override
|
||||
_i5.Future<_i2.ContributionPageResult> getMesCotisations({
|
||||
int? page = 0,
|
||||
int? size = 50,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getMesCotisations,
|
||||
[],
|
||||
{
|
||||
#page: page,
|
||||
#size: size,
|
||||
},
|
||||
),
|
||||
returnValue: _i5.Future<_i2.ContributionPageResult>.value(
|
||||
_FakeContributionPageResult_0(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getMesCotisations,
|
||||
[],
|
||||
{
|
||||
#page: page,
|
||||
#size: size,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i5.Future<_i2.ContributionPageResult>);
|
||||
|
||||
@override
|
||||
_i5.Future<_i3.ContributionModel> getCotisationById(String? id) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getCotisationById,
|
||||
[id],
|
||||
),
|
||||
returnValue:
|
||||
_i5.Future<_i3.ContributionModel>.value(_FakeContributionModel_1(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getCotisationById,
|
||||
[id],
|
||||
),
|
||||
)),
|
||||
) as _i5.Future<_i3.ContributionModel>);
|
||||
|
||||
@override
|
||||
_i5.Future<_i3.ContributionModel> createCotisation(
|
||||
_i3.ContributionModel? contribution) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#createCotisation,
|
||||
[contribution],
|
||||
),
|
||||
returnValue:
|
||||
_i5.Future<_i3.ContributionModel>.value(_FakeContributionModel_1(
|
||||
this,
|
||||
Invocation.method(
|
||||
#createCotisation,
|
||||
[contribution],
|
||||
),
|
||||
)),
|
||||
) as _i5.Future<_i3.ContributionModel>);
|
||||
|
||||
@override
|
||||
_i5.Future<_i3.ContributionModel> updateCotisation(
|
||||
String? id,
|
||||
_i3.ContributionModel? contribution,
|
||||
) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#updateCotisation,
|
||||
[
|
||||
id,
|
||||
contribution,
|
||||
],
|
||||
),
|
||||
returnValue:
|
||||
_i5.Future<_i3.ContributionModel>.value(_FakeContributionModel_1(
|
||||
this,
|
||||
Invocation.method(
|
||||
#updateCotisation,
|
||||
[
|
||||
id,
|
||||
contribution,
|
||||
],
|
||||
),
|
||||
)),
|
||||
) as _i5.Future<_i3.ContributionModel>);
|
||||
|
||||
@override
|
||||
_i5.Future<void> deleteCotisation(String? id) => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#deleteCotisation,
|
||||
[id],
|
||||
),
|
||||
returnValue: _i5.Future<void>.value(),
|
||||
returnValueForMissingStub: _i5.Future<void>.value(),
|
||||
) as _i5.Future<void>);
|
||||
|
||||
@override
|
||||
_i5.Future<_i3.ContributionModel> enregistrerPaiement(
|
||||
String? cotisationId, {
|
||||
required double? montant,
|
||||
required DateTime? datePaiement,
|
||||
required String? methodePaiement,
|
||||
String? numeroPaiement,
|
||||
String? referencePaiement,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#enregistrerPaiement,
|
||||
[cotisationId],
|
||||
{
|
||||
#montant: montant,
|
||||
#datePaiement: datePaiement,
|
||||
#methodePaiement: methodePaiement,
|
||||
#numeroPaiement: numeroPaiement,
|
||||
#referencePaiement: referencePaiement,
|
||||
},
|
||||
),
|
||||
returnValue:
|
||||
_i5.Future<_i3.ContributionModel>.value(_FakeContributionModel_1(
|
||||
this,
|
||||
Invocation.method(
|
||||
#enregistrerPaiement,
|
||||
[cotisationId],
|
||||
{
|
||||
#montant: montant,
|
||||
#datePaiement: datePaiement,
|
||||
#methodePaiement: methodePaiement,
|
||||
#numeroPaiement: numeroPaiement,
|
||||
#referencePaiement: referencePaiement,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i5.Future<_i3.ContributionModel>);
|
||||
|
||||
@override
|
||||
_i5.Future<_i2.WavePaiementInitResult> initierPaiementEnLigne({
|
||||
required String? cotisationId,
|
||||
required String? methodePaiement,
|
||||
required String? numeroTelephone,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#initierPaiementEnLigne,
|
||||
[],
|
||||
{
|
||||
#cotisationId: cotisationId,
|
||||
#methodePaiement: methodePaiement,
|
||||
#numeroTelephone: numeroTelephone,
|
||||
},
|
||||
),
|
||||
returnValue: _i5.Future<_i2.WavePaiementInitResult>.value(
|
||||
_FakeWavePaiementInitResult_2(
|
||||
this,
|
||||
Invocation.method(
|
||||
#initierPaiementEnLigne,
|
||||
[],
|
||||
{
|
||||
#cotisationId: cotisationId,
|
||||
#methodePaiement: methodePaiement,
|
||||
#numeroTelephone: numeroTelephone,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i5.Future<_i2.WavePaiementInitResult>);
|
||||
|
||||
@override
|
||||
_i5.Future<Map<String, dynamic>?> getMesCotisationsSynthese() =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getMesCotisationsSynthese,
|
||||
[],
|
||||
),
|
||||
returnValue: _i5.Future<Map<String, dynamic>?>.value(),
|
||||
) as _i5.Future<Map<String, dynamic>?>);
|
||||
|
||||
@override
|
||||
_i5.Future<Map<String, dynamic>> getStatistiques() => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getStatistiques,
|
||||
[],
|
||||
),
|
||||
returnValue:
|
||||
_i5.Future<Map<String, dynamic>>.value(<String, dynamic>{}),
|
||||
) as _i5.Future<Map<String, dynamic>>);
|
||||
|
||||
@override
|
||||
_i5.Future<_i2.ContributionPageResult> getMesCotisationsEnAttente() =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getMesCotisationsEnAttente,
|
||||
[],
|
||||
),
|
||||
returnValue: _i5.Future<_i2.ContributionPageResult>.value(
|
||||
_FakeContributionPageResult_0(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getMesCotisationsEnAttente,
|
||||
[],
|
||||
),
|
||||
)),
|
||||
) as _i5.Future<_i2.ContributionPageResult>);
|
||||
|
||||
@override
|
||||
_i5.Future<_i2.ContributionPageResult> getCotisations({
|
||||
int? page = 0,
|
||||
int? size = 20,
|
||||
String? membreId,
|
||||
String? statut,
|
||||
String? type,
|
||||
int? annee,
|
||||
}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#getCotisations,
|
||||
[],
|
||||
{
|
||||
#page: page,
|
||||
#size: size,
|
||||
#membreId: membreId,
|
||||
#statut: statut,
|
||||
#type: type,
|
||||
#annee: annee,
|
||||
},
|
||||
),
|
||||
returnValue: _i5.Future<_i2.ContributionPageResult>.value(
|
||||
_FakeContributionPageResult_0(
|
||||
this,
|
||||
Invocation.method(
|
||||
#getCotisations,
|
||||
[],
|
||||
{
|
||||
#page: page,
|
||||
#size: size,
|
||||
#membreId: membreId,
|
||||
#statut: statut,
|
||||
#type: type,
|
||||
#annee: annee,
|
||||
},
|
||||
),
|
||||
)),
|
||||
) as _i5.Future<_i2.ContributionPageResult>);
|
||||
|
||||
@override
|
||||
_i5.Future<void> envoyerRappel(String? cotisationId) => (super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#envoyerRappel,
|
||||
[cotisationId],
|
||||
),
|
||||
returnValue: _i5.Future<void>.value(),
|
||||
returnValueForMissingStub: _i5.Future<void>.value(),
|
||||
) as _i5.Future<void>);
|
||||
|
||||
@override
|
||||
_i5.Future<int> genererCotisationsAnnuelles(int? annee) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#genererCotisationsAnnuelles,
|
||||
[annee],
|
||||
),
|
||||
returnValue: _i5.Future<int>.value(0),
|
||||
) as _i5.Future<int>);
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/// Tests unitaires pour DeleteContribution use case
|
||||
library delete_contribution_test;
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:unionflow_mobile_apps/features/contributions/domain/repositories/contribution_repository.dart';
|
||||
import 'package:unionflow_mobile_apps/features/contributions/domain/usecases/delete_contribution.dart';
|
||||
|
||||
@GenerateMocks([IContributionRepository])
|
||||
import 'delete_contribution_test.mocks.dart';
|
||||
|
||||
void main() {
|
||||
late DeleteContribution useCase;
|
||||
late MockIContributionRepository mockRepository;
|
||||
|
||||
setUp(() {
|
||||
mockRepository = MockIContributionRepository();
|
||||
useCase = DeleteContribution(mockRepository);
|
||||
});
|
||||
|
||||
group('DeleteContribution Use Case', () {
|
||||
const tContributionId = 'cont123';
|
||||
|
||||
test('should delete contribution successfully', () async {
|
||||
// Arrange
|
||||
when(mockRepository.deleteCotisation(tContributionId))
|
||||
.thenAnswer((_) async => Future.value());
|
||||
|
||||
// Act
|
||||
await useCase(tContributionId);
|
||||
|
||||
// Assert
|
||||
verify(mockRepository.deleteCotisation(tContributionId));
|
||||
verifyNoMoreInteractions(mockRepository);
|
||||
});
|
||||
|
||||
test('should throw exception when contribution not found', () async {
|
||||
// Arrange
|
||||
when(mockRepository.deleteCotisation(any))
|
||||
.thenThrow(Exception('Contribution non trouvée'));
|
||||
|
||||
// Act & Assert
|
||||
expect(() => useCase('nonexistent'), throwsA(isA<Exception>()));
|
||||
verify(mockRepository.deleteCotisation('nonexistent'));
|
||||
});
|
||||
|
||||
test('should throw exception when contribution is already paid', () async {
|
||||
// Arrange
|
||||
when(mockRepository.deleteCotisation(any))
|
||||
.thenThrow(Exception('Impossible de supprimer une cotisation payée'));
|
||||
|
||||
// Act & Assert
|
||||
expect(() => useCase(tContributionId), throwsA(isA<Exception>()));
|
||||
});
|
||||
|
||||
test('should throw exception when deletion fails', () async {
|
||||
// Arrange
|
||||
when(mockRepository.deleteCotisation(any))
|
||||
.thenThrow(Exception('Erreur de suppression'));
|
||||
|
||||
// Act & Assert
|
||||
expect(() => useCase(tContributionId), throwsException);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/// Tests unitaires pour GetContributionById use case
|
||||
library get_contribution_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/contributions/domain/repositories/contribution_repository.dart';
|
||||
import 'package:unionflow_mobile_apps/features/contributions/domain/usecases/get_contribution_by_id.dart';
|
||||
import 'package:unionflow_mobile_apps/features/contributions/data/models/contribution_model.dart';
|
||||
|
||||
@GenerateMocks([IContributionRepository])
|
||||
import 'get_contribution_by_id_test.mocks.dart';
|
||||
|
||||
void main() {
|
||||
late GetContributionById useCase;
|
||||
late MockIContributionRepository mockRepository;
|
||||
|
||||
setUp(() {
|
||||
mockRepository = MockIContributionRepository();
|
||||
useCase = GetContributionById(mockRepository);
|
||||
});
|
||||
|
||||
group('GetContributionById Use Case', () {
|
||||
const tContributionId = 'cont123';
|
||||
final tContribution = ContributionModel(
|
||||
id: tContributionId,
|
||||
membreId: 'membre1',
|
||||
membreNom: 'Dupont',
|
||||
membrePrenom: 'Jean',
|
||||
montant: 5000.0,
|
||||
montantPaye: 5000.0,
|
||||
dateEcheance: DateTime(2024, 12, 31),
|
||||
datePaiement: DateTime(2024, 11, 15),
|
||||
annee: 2024,
|
||||
type: ContributionType.annuelle,
|
||||
statut: ContributionStatus.payee,
|
||||
methodePaiement: PaymentMethod.waveMoney,
|
||||
numeroPaiement: 'WAVE123456',
|
||||
);
|
||||
|
||||
test('should return contribution by id', () async {
|
||||
// Arrange
|
||||
when(mockRepository.getCotisationById(tContributionId))
|
||||
.thenAnswer((_) async => tContribution);
|
||||
|
||||
// Act
|
||||
final result = await useCase(tContributionId);
|
||||
|
||||
// Assert
|
||||
expect(result, equals(tContribution));
|
||||
expect(result.id, equals(tContributionId));
|
||||
expect(result.statut, equals(ContributionStatus.payee));
|
||||
verify(mockRepository.getCotisationById(tContributionId));
|
||||
verifyNoMoreInteractions(mockRepository);
|
||||
});
|
||||
|
||||
test('should return contribution with payment details', () async {
|
||||
// Arrange
|
||||
when(mockRepository.getCotisationById(tContributionId))
|
||||
.thenAnswer((_) async => tContribution);
|
||||
|
||||
// Act
|
||||
final result = await useCase(tContributionId);
|
||||
|
||||
// Assert
|
||||
expect(result.montantPaye, equals(5000.0));
|
||||
expect(result.methodePaiement, equals(PaymentMethod.waveMoney));
|
||||
expect(result.numeroPaiement, isNotNull);
|
||||
});
|
||||
|
||||
test('should return unpaid contribution', () async {
|
||||
// Arrange
|
||||
final unpaidContribution = ContributionModel(
|
||||
id: 'cont456',
|
||||
membreId: 'membre2',
|
||||
montant: 10000.0,
|
||||
dateEcheance: DateTime(2025, 1, 31),
|
||||
annee: 2025,
|
||||
type: ContributionType.mensuelle,
|
||||
statut: ContributionStatus.enRetard,
|
||||
);
|
||||
when(mockRepository.getCotisationById('cont456'))
|
||||
.thenAnswer((_) async => unpaidContribution);
|
||||
|
||||
// Act
|
||||
final result = await useCase('cont456');
|
||||
|
||||
// Assert
|
||||
expect(result.statut, equals(ContributionStatus.enRetard));
|
||||
expect(result.montantPaye, isNull);
|
||||
expect(result.datePaiement, isNull);
|
||||
});
|
||||
|
||||
test('should throw exception when contribution not found', () async {
|
||||
// Arrange
|
||||
when(mockRepository.getCotisationById(any))
|
||||
.thenThrow(Exception('Contribution non trouvée'));
|
||||
|
||||
// Act & Assert
|
||||
expect(() => useCase('nonexistent'), throwsException);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
/// Tests unitaires pour GetContributionHistory use case
|
||||
library get_contribution_history_test;
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:unionflow_mobile_apps/features/contributions/domain/repositories/contribution_repository.dart';
|
||||
import 'package:unionflow_mobile_apps/features/contributions/domain/usecases/get_contribution_history.dart';
|
||||
import 'package:unionflow_mobile_apps/features/contributions/data/models/contribution_model.dart';
|
||||
import 'package:unionflow_mobile_apps/features/contributions/data/repositories/contribution_repository.dart';
|
||||
|
||||
@GenerateMocks([IContributionRepository])
|
||||
import 'get_contribution_history_test.mocks.dart';
|
||||
|
||||
void main() {
|
||||
late GetContributionHistory useCase;
|
||||
late MockIContributionRepository mockRepository;
|
||||
|
||||
setUp(() {
|
||||
mockRepository = MockIContributionRepository();
|
||||
useCase = GetContributionHistory(mockRepository);
|
||||
});
|
||||
|
||||
group('GetContributionHistory Use Case', () {
|
||||
final tHistoryList = [
|
||||
ContributionModel(
|
||||
id: 'cont1',
|
||||
membreId: 'membre1',
|
||||
montant: 5000.0,
|
||||
montantPaye: 5000.0,
|
||||
dateEcheance: DateTime(2024, 1, 31),
|
||||
datePaiement: DateTime(2024, 1, 15),
|
||||
annee: 2024,
|
||||
mois: 1,
|
||||
type: ContributionType.mensuelle,
|
||||
statut: ContributionStatus.payee,
|
||||
),
|
||||
ContributionModel(
|
||||
id: 'cont2',
|
||||
membreId: 'membre1',
|
||||
montant: 5000.0,
|
||||
dateEcheance: DateTime(2024, 2, 28),
|
||||
annee: 2024,
|
||||
mois: 2,
|
||||
type: ContributionType.mensuelle,
|
||||
statut: ContributionStatus.enAttente,
|
||||
),
|
||||
];
|
||||
|
||||
final tPageResult = ContributionPageResult(
|
||||
contributions: tHistoryList,
|
||||
total: 2,
|
||||
totalPages: 1,
|
||||
page: 0,
|
||||
size: 50,
|
||||
);
|
||||
|
||||
test('should return contribution history', () async {
|
||||
// Arrange
|
||||
when(mockRepository.getMesCotisations(page: anyNamed('page'), size: anyNamed('size')))
|
||||
.thenAnswer((_) async => tPageResult);
|
||||
|
||||
// Act
|
||||
final result = await useCase(page: 0, size: 50);
|
||||
|
||||
// Assert
|
||||
expect(result, equals(tPageResult));
|
||||
expect(result.contributions.length, equals(2));
|
||||
expect(result.contributions[0].statut, equals(ContributionStatus.payee));
|
||||
expect(result.contributions[1].statut, equals(ContributionStatus.enAttente));
|
||||
verify(mockRepository.getMesCotisations(page: 0, size: 50));
|
||||
verifyNoMoreInteractions(mockRepository);
|
||||
});
|
||||
|
||||
test('should return history for specific year', () async {
|
||||
// Arrange
|
||||
final year2023List = [
|
||||
ContributionModel(
|
||||
id: 'cont3',
|
||||
membreId: 'membre1',
|
||||
montant: 60000.0,
|
||||
montantPaye: 60000.0,
|
||||
dateEcheance: DateTime(2023, 12, 31),
|
||||
datePaiement: DateTime(2023, 12, 15),
|
||||
annee: 2023,
|
||||
type: ContributionType.annuelle,
|
||||
statut: ContributionStatus.payee,
|
||||
),
|
||||
];
|
||||
final yearPageResult = ContributionPageResult(
|
||||
contributions: year2023List,
|
||||
total: 1,
|
||||
totalPages: 1,
|
||||
page: 0,
|
||||
size: 50,
|
||||
);
|
||||
when(mockRepository.getMesCotisations(page: 0, size: 50))
|
||||
.thenAnswer((_) async => yearPageResult);
|
||||
|
||||
// Act
|
||||
final result = await useCase(page: 0, size: 50, annee: 2023);
|
||||
|
||||
// Assert
|
||||
expect(result.contributions.length, equals(1));
|
||||
expect(result.contributions.first.annee, equals(2023));
|
||||
});
|
||||
|
||||
test('should return history filtered by status', () async {
|
||||
// Arrange
|
||||
final paidOnly = [tHistoryList[0]];
|
||||
final paidPageResult = ContributionPageResult(
|
||||
contributions: paidOnly,
|
||||
total: 1,
|
||||
totalPages: 1,
|
||||
page: 0,
|
||||
size: 50,
|
||||
);
|
||||
when(mockRepository.getMesCotisations(page: 0, size: 50))
|
||||
.thenAnswer((_) async => paidPageResult);
|
||||
|
||||
// Act
|
||||
final result = await useCase(
|
||||
page: 0,
|
||||
size: 50,
|
||||
statut: ContributionStatus.payee,
|
||||
);
|
||||
|
||||
// Assert
|
||||
expect(result.contributions.length, equals(1));
|
||||
expect(result.contributions.first.statut, equals(ContributionStatus.payee));
|
||||
});
|
||||
|
||||
test('should return empty history when no contributions', () async {
|
||||
// Arrange
|
||||
final emptyResult = ContributionPageResult(
|
||||
contributions: [],
|
||||
total: 0,
|
||||
totalPages: 0,
|
||||
page: 0,
|
||||
size: 50,
|
||||
);
|
||||
when(mockRepository.getMesCotisations(page: anyNamed('page'), size: anyNamed('size')))
|
||||
.thenAnswer((_) async => emptyResult);
|
||||
|
||||
// Act
|
||||
final result = await useCase();
|
||||
|
||||
// Assert
|
||||
expect(result.contributions, isEmpty);
|
||||
expect(result.total, equals(0));
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/// Tests unitaires pour GetContributionStats use case
|
||||
library get_contribution_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/contributions/domain/repositories/contribution_repository.dart';
|
||||
import 'package:unionflow_mobile_apps/features/contributions/domain/usecases/get_contribution_stats.dart';
|
||||
|
||||
@GenerateMocks([IContributionRepository])
|
||||
import 'get_contribution_stats_test.mocks.dart';
|
||||
|
||||
void main() {
|
||||
late GetContributionStats useCase;
|
||||
late MockIContributionRepository mockRepository;
|
||||
|
||||
setUp(() {
|
||||
mockRepository = MockIContributionRepository();
|
||||
useCase = GetContributionStats(mockRepository);
|
||||
});
|
||||
|
||||
group('GetContributionStats Use Case', () {
|
||||
final tStats = {
|
||||
'montantDu': 60000.0,
|
||||
'totalPayeAnnee': 45000.0,
|
||||
'cotisationsEnAttente': 3,
|
||||
'prochaineEcheance': '2024-12-31T00:00:00.000Z',
|
||||
'tauxPaiement': 75.0,
|
||||
'nombreCotisations': 12,
|
||||
'montantMoyenCotisation': 5000.0,
|
||||
};
|
||||
|
||||
test('should return contribution statistics', () async {
|
||||
// Arrange
|
||||
when(mockRepository.getMesCotisationsSynthese())
|
||||
.thenAnswer((_) async => tStats);
|
||||
|
||||
// Act
|
||||
final result = await useCase();
|
||||
|
||||
// Assert
|
||||
expect(result, equals(tStats));
|
||||
expect(result?['montantDu'], equals(60000.0));
|
||||
expect(result?['totalPayeAnnee'], equals(45000.0));
|
||||
expect(result?['tauxPaiement'], equals(75.0));
|
||||
verify(mockRepository.getMesCotisationsSynthese());
|
||||
verifyNoMoreInteractions(mockRepository);
|
||||
});
|
||||
|
||||
test('should return stats with payment rate', () async {
|
||||
// Arrange
|
||||
when(mockRepository.getMesCotisationsSynthese())
|
||||
.thenAnswer((_) async => tStats);
|
||||
|
||||
// Act
|
||||
final result = await useCase();
|
||||
|
||||
// Assert
|
||||
expect(result?['tauxPaiement'], equals(75.0));
|
||||
expect(result?['cotisationsEnAttente'], equals(3));
|
||||
});
|
||||
|
||||
test('should return stats with next deadline', () async {
|
||||
// Arrange
|
||||
when(mockRepository.getMesCotisationsSynthese())
|
||||
.thenAnswer((_) async => tStats);
|
||||
|
||||
// Act
|
||||
final result = await useCase();
|
||||
|
||||
// Assert
|
||||
expect(result?['prochaineEcheance'], isNotNull);
|
||||
expect(result?['prochaineEcheance'], contains('2024-12-31'));
|
||||
});
|
||||
|
||||
test('should return null when no data available', () async {
|
||||
// Arrange
|
||||
when(mockRepository.getMesCotisationsSynthese())
|
||||
.thenAnswer((_) async => null);
|
||||
|
||||
// Act
|
||||
final result = await useCase();
|
||||
|
||||
// Assert
|
||||
expect(result, isNull);
|
||||
verify(mockRepository.getMesCotisationsSynthese());
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
/// Tests unitaires pour GetContributions use case
|
||||
library get_contributions_test;
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:unionflow_mobile_apps/features/contributions/domain/repositories/contribution_repository.dart';
|
||||
import 'package:unionflow_mobile_apps/features/contributions/domain/usecases/get_contributions.dart';
|
||||
import 'package:unionflow_mobile_apps/features/contributions/data/models/contribution_model.dart';
|
||||
import 'package:unionflow_mobile_apps/features/contributions/data/repositories/contribution_repository.dart';
|
||||
|
||||
@GenerateMocks([IContributionRepository])
|
||||
import 'get_contributions_test.mocks.dart';
|
||||
|
||||
void main() {
|
||||
late GetContributions useCase;
|
||||
late MockIContributionRepository mockRepository;
|
||||
|
||||
setUp(() {
|
||||
mockRepository = MockIContributionRepository();
|
||||
useCase = GetContributions(mockRepository);
|
||||
});
|
||||
|
||||
group('GetContributions Use Case', () {
|
||||
final tContributionList = [
|
||||
ContributionModel(
|
||||
id: 'cont1',
|
||||
membreId: 'membre1',
|
||||
membreNom: 'Dupont',
|
||||
membrePrenom: 'Jean',
|
||||
montant: 5000.0,
|
||||
dateEcheance: DateTime(2024, 12, 31),
|
||||
annee: 2024,
|
||||
type: ContributionType.mensuelle,
|
||||
statut: ContributionStatus.payee,
|
||||
),
|
||||
ContributionModel(
|
||||
id: 'cont2',
|
||||
membreId: 'membre1',
|
||||
membreNom: 'Dupont',
|
||||
membrePrenom: 'Jean',
|
||||
montant: 5000.0,
|
||||
dateEcheance: DateTime(2025, 1, 31),
|
||||
annee: 2025,
|
||||
type: ContributionType.mensuelle,
|
||||
statut: ContributionStatus.enAttente,
|
||||
),
|
||||
];
|
||||
|
||||
final tPageResult = ContributionPageResult(
|
||||
contributions: tContributionList,
|
||||
total: 2,
|
||||
totalPages: 1,
|
||||
page: 0,
|
||||
size: 50,
|
||||
);
|
||||
|
||||
test('should return paginated list of contributions', () async {
|
||||
// Arrange
|
||||
when(mockRepository.getMesCotisations(page: anyNamed('page'), size: anyNamed('size')))
|
||||
.thenAnswer((_) async => tPageResult);
|
||||
|
||||
// Act
|
||||
final result = await useCase(page: 0, size: 50);
|
||||
|
||||
// Assert
|
||||
expect(result, equals(tPageResult));
|
||||
expect(result.contributions.length, equals(2));
|
||||
expect(result.total, equals(2));
|
||||
verify(mockRepository.getMesCotisations(page: 0, size: 50));
|
||||
verifyNoMoreInteractions(mockRepository);
|
||||
});
|
||||
|
||||
test('should return contributions with custom page size', () async {
|
||||
// Arrange
|
||||
final smallPageResult = ContributionPageResult(
|
||||
contributions: [tContributionList[0]],
|
||||
total: 2,
|
||||
totalPages: 2,
|
||||
page: 0,
|
||||
size: 1,
|
||||
);
|
||||
when(mockRepository.getMesCotisations(page: 0, size: 1))
|
||||
.thenAnswer((_) async => smallPageResult);
|
||||
|
||||
// Act
|
||||
final result = await useCase(page: 0, size: 1);
|
||||
|
||||
// Assert
|
||||
expect(result.contributions.length, equals(1));
|
||||
expect(result.size, equals(1));
|
||||
verify(mockRepository.getMesCotisations(page: 0, size: 1));
|
||||
});
|
||||
|
||||
test('should return empty result when no contributions exist', () async {
|
||||
// Arrange
|
||||
final emptyResult = ContributionPageResult(
|
||||
contributions: [],
|
||||
total: 0,
|
||||
totalPages: 0,
|
||||
page: 0,
|
||||
size: 50,
|
||||
);
|
||||
when(mockRepository.getMesCotisations(page: anyNamed('page'), size: anyNamed('size')))
|
||||
.thenAnswer((_) async => emptyResult);
|
||||
|
||||
// Act
|
||||
final result = await useCase(page: 0, size: 50);
|
||||
|
||||
// Assert
|
||||
expect(result.contributions, isEmpty);
|
||||
expect(result.total, equals(0));
|
||||
});
|
||||
|
||||
test('should throw exception when repository fails', () async {
|
||||
// Arrange
|
||||
when(mockRepository.getMesCotisations(page: anyNamed('page'), size: anyNamed('size')))
|
||||
.thenThrow(Exception('Network error'));
|
||||
|
||||
// Act & Assert
|
||||
expect(() => useCase(page: 0, size: 50), throwsException);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
/// Tests unitaires pour PayContribution use case
|
||||
library pay_contribution_test;
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:unionflow_mobile_apps/features/contributions/domain/repositories/contribution_repository.dart';
|
||||
import 'package:unionflow_mobile_apps/features/contributions/domain/usecases/pay_contribution.dart';
|
||||
import 'package:unionflow_mobile_apps/features/contributions/data/models/contribution_model.dart';
|
||||
|
||||
@GenerateMocks([IContributionRepository])
|
||||
import 'pay_contribution_test.mocks.dart';
|
||||
|
||||
void main() {
|
||||
late PayContribution useCase;
|
||||
late MockIContributionRepository mockRepository;
|
||||
|
||||
setUp(() {
|
||||
mockRepository = MockIContributionRepository();
|
||||
useCase = PayContribution(mockRepository);
|
||||
});
|
||||
|
||||
group('PayContribution Use Case', () {
|
||||
const tContributionId = 'cont123';
|
||||
const tMontant = 5000.0;
|
||||
final tDatePaiement = DateTime(2024, 11, 15);
|
||||
const tMethode = 'WAVE_MONEY';
|
||||
const tNumero = 'WAVE123456';
|
||||
|
||||
final tPaidContribution = ContributionModel(
|
||||
id: tContributionId,
|
||||
membreId: 'membre1',
|
||||
montant: 5000.0,
|
||||
montantPaye: 5000.0,
|
||||
dateEcheance: DateTime(2024, 12, 31),
|
||||
datePaiement: tDatePaiement,
|
||||
annee: 2024,
|
||||
type: ContributionType.annuelle,
|
||||
statut: ContributionStatus.payee,
|
||||
methodePaiement: PaymentMethod.waveMoney,
|
||||
numeroPaiement: tNumero,
|
||||
);
|
||||
|
||||
test('should record payment successfully', () async {
|
||||
// Arrange
|
||||
when(mockRepository.enregistrerPaiement(
|
||||
tContributionId,
|
||||
montant: tMontant,
|
||||
datePaiement: tDatePaiement,
|
||||
methodePaiement: tMethode,
|
||||
numeroPaiement: tNumero,
|
||||
referencePaiement: anyNamed('referencePaiement'),
|
||||
)).thenAnswer((_) async => tPaidContribution);
|
||||
|
||||
// Act
|
||||
final result = await useCase(
|
||||
cotisationId: tContributionId,
|
||||
montant: tMontant,
|
||||
datePaiement: tDatePaiement,
|
||||
methodePaiement: tMethode,
|
||||
numeroPaiement: tNumero,
|
||||
);
|
||||
|
||||
// Assert
|
||||
expect(result, equals(tPaidContribution));
|
||||
expect(result.statut, equals(ContributionStatus.payee));
|
||||
expect(result.montantPaye, equals(5000.0));
|
||||
expect(result.datePaiement, equals(tDatePaiement));
|
||||
verify(mockRepository.enregistrerPaiement(
|
||||
tContributionId,
|
||||
montant: tMontant,
|
||||
datePaiement: tDatePaiement,
|
||||
methodePaiement: tMethode,
|
||||
numeroPaiement: tNumero,
|
||||
referencePaiement: null,
|
||||
));
|
||||
verifyNoMoreInteractions(mockRepository);
|
||||
});
|
||||
|
||||
test('should record partial payment', () async {
|
||||
// Arrange
|
||||
const partialMontant = 2500.0;
|
||||
final partialPaid = ContributionModel(
|
||||
id: tContributionId,
|
||||
membreId: 'membre1',
|
||||
montant: 5000.0,
|
||||
montantPaye: 2500.0,
|
||||
dateEcheance: DateTime(2024, 12, 31),
|
||||
datePaiement: tDatePaiement,
|
||||
annee: 2024,
|
||||
type: ContributionType.annuelle,
|
||||
statut: ContributionStatus.partielle,
|
||||
methodePaiement: PaymentMethod.especes,
|
||||
);
|
||||
when(mockRepository.enregistrerPaiement(
|
||||
tContributionId,
|
||||
montant: partialMontant,
|
||||
datePaiement: tDatePaiement,
|
||||
methodePaiement: 'ESPECES',
|
||||
numeroPaiement: null,
|
||||
referencePaiement: null,
|
||||
)).thenAnswer((_) async => partialPaid);
|
||||
|
||||
// Act
|
||||
final result = await useCase(
|
||||
cotisationId: tContributionId,
|
||||
montant: partialMontant,
|
||||
datePaiement: tDatePaiement,
|
||||
methodePaiement: 'ESPECES',
|
||||
);
|
||||
|
||||
// Assert
|
||||
expect(result.statut, equals(ContributionStatus.partielle));
|
||||
expect(result.montantPaye, equals(2500.0));
|
||||
});
|
||||
|
||||
test('should record payment with reference', () async {
|
||||
// Arrange
|
||||
const reference = 'REF-2024-001';
|
||||
when(mockRepository.enregistrerPaiement(
|
||||
tContributionId,
|
||||
montant: tMontant,
|
||||
datePaiement: tDatePaiement,
|
||||
methodePaiement: tMethode,
|
||||
numeroPaiement: null,
|
||||
referencePaiement: reference,
|
||||
)).thenAnswer((_) async => tPaidContribution.copyWith(referencePaiement: reference));
|
||||
|
||||
// Act
|
||||
final result = await useCase(
|
||||
cotisationId: tContributionId,
|
||||
montant: tMontant,
|
||||
datePaiement: tDatePaiement,
|
||||
methodePaiement: tMethode,
|
||||
referencePaiement: reference,
|
||||
);
|
||||
|
||||
// Assert
|
||||
expect(result.referencePaiement, equals(reference));
|
||||
});
|
||||
|
||||
test('should throw exception when payment fails', () async {
|
||||
// Arrange
|
||||
when(mockRepository.enregistrerPaiement(
|
||||
tContributionId,
|
||||
montant: tMontant,
|
||||
datePaiement: tDatePaiement,
|
||||
methodePaiement: tMethode,
|
||||
numeroPaiement: null,
|
||||
referencePaiement: null,
|
||||
)).thenThrow(Exception('Erreur lors de l\'enregistrement du paiement'));
|
||||
|
||||
// Act & Assert
|
||||
expect(
|
||||
() => useCase(
|
||||
cotisationId: tContributionId,
|
||||
montant: tMontant,
|
||||
datePaiement: tDatePaiement,
|
||||
methodePaiement: tMethode,
|
||||
),
|
||||
throwsException,
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
/// Tests unitaires pour UpdateContribution use case
|
||||
library update_contribution_test;
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:unionflow_mobile_apps/features/contributions/domain/repositories/contribution_repository.dart';
|
||||
import 'package:unionflow_mobile_apps/features/contributions/domain/usecases/update_contribution.dart';
|
||||
import 'package:unionflow_mobile_apps/features/contributions/data/models/contribution_model.dart';
|
||||
|
||||
@GenerateMocks([IContributionRepository])
|
||||
import 'update_contribution_test.mocks.dart';
|
||||
|
||||
void main() {
|
||||
late UpdateContribution useCase;
|
||||
late MockIContributionRepository mockRepository;
|
||||
|
||||
setUp(() {
|
||||
mockRepository = MockIContributionRepository();
|
||||
useCase = UpdateContribution(mockRepository);
|
||||
});
|
||||
|
||||
group('UpdateContribution Use Case', () {
|
||||
const tContributionId = 'cont123';
|
||||
final tUpdatedContribution = ContributionModel(
|
||||
id: tContributionId,
|
||||
membreId: 'membre1',
|
||||
montant: 6000.0,
|
||||
dateEcheance: DateTime(2025, 12, 31),
|
||||
annee: 2025,
|
||||
type: ContributionType.annuelle,
|
||||
statut: ContributionStatus.nonPayee,
|
||||
description: 'Montant mis à jour',
|
||||
);
|
||||
|
||||
test('should update contribution successfully', () async {
|
||||
// Arrange
|
||||
when(mockRepository.updateCotisation(tContributionId, tUpdatedContribution))
|
||||
.thenAnswer((_) async => tUpdatedContribution);
|
||||
|
||||
// Act
|
||||
final result = await useCase(tContributionId, tUpdatedContribution);
|
||||
|
||||
// Assert
|
||||
expect(result, equals(tUpdatedContribution));
|
||||
expect(result.montant, equals(6000.0));
|
||||
expect(result.description, equals('Montant mis à jour'));
|
||||
verify(mockRepository.updateCotisation(tContributionId, tUpdatedContribution));
|
||||
verifyNoMoreInteractions(mockRepository);
|
||||
});
|
||||
|
||||
test('should update contribution status', () async {
|
||||
// Arrange
|
||||
final statusUpdate = ContributionModel(
|
||||
id: tContributionId,
|
||||
membreId: 'membre1',
|
||||
montant: 5000.0,
|
||||
dateEcheance: DateTime(2024, 12, 31),
|
||||
annee: 2024,
|
||||
type: ContributionType.annuelle,
|
||||
statut: ContributionStatus.enRetard,
|
||||
);
|
||||
when(mockRepository.updateCotisation(tContributionId, statusUpdate))
|
||||
.thenAnswer((_) async => statusUpdate);
|
||||
|
||||
// Act
|
||||
final result = await useCase(tContributionId, statusUpdate);
|
||||
|
||||
// Assert
|
||||
expect(result.statut, equals(ContributionStatus.enRetard));
|
||||
});
|
||||
|
||||
test('should update contribution type', () async {
|
||||
// Arrange
|
||||
final typeUpdate = ContributionModel(
|
||||
id: tContributionId,
|
||||
membreId: 'membre1',
|
||||
montant: 5000.0,
|
||||
dateEcheance: DateTime(2024, 3, 31),
|
||||
annee: 2024,
|
||||
trimestre: 1,
|
||||
type: ContributionType.trimestrielle,
|
||||
statut: ContributionStatus.nonPayee,
|
||||
);
|
||||
when(mockRepository.updateCotisation(tContributionId, typeUpdate))
|
||||
.thenAnswer((_) async => typeUpdate);
|
||||
|
||||
// Act
|
||||
final result = await useCase(tContributionId, typeUpdate);
|
||||
|
||||
// Assert
|
||||
expect(result.type, equals(ContributionType.trimestrielle));
|
||||
expect(result.trimestre, equals(1));
|
||||
});
|
||||
|
||||
test('should throw exception when update fails', () async {
|
||||
// Arrange
|
||||
when(mockRepository.updateCotisation(any, any))
|
||||
.thenThrow(Exception('Mise à jour échouée'));
|
||||
|
||||
// Act & Assert
|
||||
expect(() => useCase(tContributionId, tUpdatedContribution), throwsException);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user