feat: BLoC tests complets + sécurité production + freerasp 7.5.1 migration
## Tests BLoC (Task P2.4 Mobile) - 25 nouveaux fichiers *_bloc_test.dart + mocks générés (build_runner) - Features couvertes : authentication, admin_users, adhesions, backup, communication/messaging, contributions, dashboard, finance (approval/budget), events, explore/network, feed, logs_monitoring, notifications, onboarding, organizations (switcher/types/CRUD), profile, reports, settings, solidarity - ~380 tests, > 80% coverage BLoCs ## Sécurité Production (Task P2.2) - lib/core/security/app_integrity_service.dart (freerasp 7.5.1) - Migration API breaking changes freerasp 7.5.1 : - onRootDetected → onPrivilegedAccess - onDebuggerDetected → onDebug - onSignatureDetected → onAppIntegrity - onHookDetected → onHooks - onEmulatorDetected → onSimulator - onUntrustedInstallationSourceDetected → onUnofficialStore - onDeviceBindingDetected → onDeviceBinding - onObfuscationIssuesDetected → onObfuscationIssues - Talsec.start() split → start() + attachListener() - const AndroidConfig/IOSConfig → final (constructors call ConfigVerifier) - supportedAlternativeStores → supportedStores ## Pubspec - bloc_test: ^9.1.7 → ^10.0.0 (compat flutter_bloc ^9.0.0) - freerasp 7.5.1 ## Config - android/app/build.gradle : ajustements release - lib/core/config/environment.dart : URLs API actualisées - lib/main.dart + app_router : intégrations sécurité/BLoC ## Cleanup - Suppression docs intermédiaires (TACHES_*.md, TASK_*_COMPLETION_REPORT.md, TESTS_UNITAIRES_PROGRESS.md) - .g.dart régénérés (json_serializable) - .mocks.dart régénérés (mockito) ## Résultat - 142 fichiers, +27 596 insertions - Toutes les tâches P2 mobile complétées Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
540
test/features/adhesions/bloc/adhesions_bloc_test.dart
Normal file
540
test/features/adhesions/bloc/adhesions_bloc_test.dart
Normal file
@@ -0,0 +1,540 @@
|
||||
/// Tests unitaires pour AdhesionsBloc
|
||||
library adhesions_bloc_test;
|
||||
|
||||
import 'package:bloc_test/bloc_test.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
|
||||
import 'package:unionflow_mobile_apps/features/adhesions/bloc/adhesions_bloc.dart';
|
||||
import 'package:unionflow_mobile_apps/features/adhesions/data/models/adhesion_model.dart';
|
||||
import 'package:unionflow_mobile_apps/features/adhesions/data/repositories/adhesion_repository.dart';
|
||||
|
||||
@GenerateMocks([AdhesionRepository])
|
||||
import 'adhesions_bloc_test.mocks.dart';
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Helpers
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
AdhesionModel _makeAdhesion({
|
||||
String id = 'adh1',
|
||||
String statut = 'EN_ATTENTE',
|
||||
}) =>
|
||||
AdhesionModel(
|
||||
id: id,
|
||||
membreId: 'membre1',
|
||||
nomMembre: 'Dupont Jean',
|
||||
organisationId: 'org1',
|
||||
nomOrganisation: 'TestOrg',
|
||||
statut: statut,
|
||||
fraisAdhesion: 10000,
|
||||
);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Tests
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
void main() {
|
||||
late MockAdhesionRepository mockRepository;
|
||||
|
||||
AdhesionsBloc buildBloc() => AdhesionsBloc(mockRepository);
|
||||
|
||||
setUp(() {
|
||||
mockRepository = MockAdhesionRepository();
|
||||
});
|
||||
|
||||
// ---- initial state -------------------------------------------------------
|
||||
|
||||
test('initial state has status initial and empty adhesions list', () {
|
||||
final bloc = buildBloc();
|
||||
expect(bloc.state.status, AdhesionsStatus.initial);
|
||||
expect(bloc.state.adhesions, isEmpty);
|
||||
bloc.close();
|
||||
});
|
||||
|
||||
// ---- LoadAdhesions -------------------------------------------------------
|
||||
|
||||
group('LoadAdhesions', () {
|
||||
final adhesionList = [_makeAdhesion(), _makeAdhesion(id: 'adh2')];
|
||||
|
||||
blocTest<AdhesionsBloc, AdhesionsState>(
|
||||
'emits loading then loaded with adhesions list',
|
||||
build: () {
|
||||
when(mockRepository.getAll(
|
||||
page: anyNamed('page'), size: anyNamed('size')))
|
||||
.thenAnswer((_) async => adhesionList);
|
||||
return buildBloc();
|
||||
},
|
||||
act: (b) => b.add(const LoadAdhesions()),
|
||||
expect: () => [
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.loading),
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.loaded)
|
||||
.having((s) => s.adhesions.length, 'count', 2),
|
||||
],
|
||||
);
|
||||
|
||||
blocTest<AdhesionsBloc, AdhesionsState>(
|
||||
'emits loading then loaded with empty list',
|
||||
build: () {
|
||||
when(mockRepository.getAll(
|
||||
page: anyNamed('page'), size: anyNamed('size')))
|
||||
.thenAnswer((_) async => []);
|
||||
return buildBloc();
|
||||
},
|
||||
act: (b) => b.add(const LoadAdhesions()),
|
||||
expect: () => [
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.loading),
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.loaded)
|
||||
.having((s) => s.adhesions, 'adhesions', isEmpty),
|
||||
],
|
||||
);
|
||||
|
||||
blocTest<AdhesionsBloc, AdhesionsState>(
|
||||
'emits loading then error on exception',
|
||||
build: () {
|
||||
when(mockRepository.getAll(
|
||||
page: anyNamed('page'), size: anyNamed('size')))
|
||||
.thenThrow(Exception('network failure'));
|
||||
return buildBloc();
|
||||
},
|
||||
act: (b) => b.add(const LoadAdhesions()),
|
||||
expect: () => [
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.loading),
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.error),
|
||||
],
|
||||
);
|
||||
|
||||
blocTest<AdhesionsBloc, AdhesionsState>(
|
||||
'uses custom page and size',
|
||||
build: () {
|
||||
when(mockRepository.getAll(page: 1, size: 5))
|
||||
.thenAnswer((_) async => [_makeAdhesion()]);
|
||||
return buildBloc();
|
||||
},
|
||||
act: (b) => b.add(const LoadAdhesions(page: 1, size: 5)),
|
||||
expect: () => [
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.loading),
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.loaded),
|
||||
],
|
||||
verify: (_) => verify(mockRepository.getAll(page: 1, size: 5)),
|
||||
);
|
||||
});
|
||||
|
||||
// ---- LoadAdhesionsByMembre -----------------------------------------------
|
||||
|
||||
group('LoadAdhesionsByMembre', () {
|
||||
final list = [_makeAdhesion()];
|
||||
|
||||
blocTest<AdhesionsBloc, AdhesionsState>(
|
||||
'emits loading then loaded with membre adhesions',
|
||||
build: () {
|
||||
when(mockRepository.getByMembre(any,
|
||||
page: anyNamed('page'), size: anyNamed('size')))
|
||||
.thenAnswer((_) async => list);
|
||||
return buildBloc();
|
||||
},
|
||||
act: (b) => b.add(LoadAdhesionsByMembre('membre1')),
|
||||
expect: () => [
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.loading),
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.loaded)
|
||||
.having((s) => s.adhesions.length, 'count', 1),
|
||||
],
|
||||
);
|
||||
|
||||
blocTest<AdhesionsBloc, AdhesionsState>(
|
||||
'emits error when repository throws',
|
||||
build: () {
|
||||
when(mockRepository.getByMembre(any,
|
||||
page: anyNamed('page'), size: anyNamed('size')))
|
||||
.thenThrow(Exception('server error'));
|
||||
return buildBloc();
|
||||
},
|
||||
act: (b) => b.add(LoadAdhesionsByMembre('membre1')),
|
||||
expect: () => [
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.loading),
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.error),
|
||||
],
|
||||
);
|
||||
});
|
||||
|
||||
// ---- LoadAdhesionsEnAttente ----------------------------------------------
|
||||
|
||||
group('LoadAdhesionsEnAttente', () {
|
||||
final enAttente = [_makeAdhesion(statut: 'EN_ATTENTE')];
|
||||
|
||||
blocTest<AdhesionsBloc, AdhesionsState>(
|
||||
'emits loading then loaded with pending adhesions',
|
||||
build: () {
|
||||
when(mockRepository.getEnAttente(
|
||||
page: anyNamed('page'), size: anyNamed('size')))
|
||||
.thenAnswer((_) async => enAttente);
|
||||
return buildBloc();
|
||||
},
|
||||
act: (b) => b.add(const LoadAdhesionsEnAttente()),
|
||||
expect: () => [
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.loading),
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.loaded)
|
||||
.having((s) => s.adhesions.length, 'count', 1),
|
||||
],
|
||||
);
|
||||
|
||||
blocTest<AdhesionsBloc, AdhesionsState>(
|
||||
'emits error on repository failure',
|
||||
build: () {
|
||||
when(mockRepository.getEnAttente(
|
||||
page: anyNamed('page'), size: anyNamed('size')))
|
||||
.thenThrow(Exception('server error'));
|
||||
return buildBloc();
|
||||
},
|
||||
act: (b) => b.add(const LoadAdhesionsEnAttente()),
|
||||
expect: () => [
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.loading),
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.error),
|
||||
],
|
||||
);
|
||||
});
|
||||
|
||||
// ---- LoadAdhesionsByStatut -----------------------------------------------
|
||||
|
||||
group('LoadAdhesionsByStatut', () {
|
||||
final approved = [_makeAdhesion(statut: 'APPROUVEE')];
|
||||
|
||||
blocTest<AdhesionsBloc, AdhesionsState>(
|
||||
'emits loading then loaded filtered by statut',
|
||||
build: () {
|
||||
when(mockRepository.getByStatut(any,
|
||||
page: anyNamed('page'), size: anyNamed('size')))
|
||||
.thenAnswer((_) async => approved);
|
||||
return buildBloc();
|
||||
},
|
||||
act: (b) => b.add(LoadAdhesionsByStatut('APPROUVEE')),
|
||||
expect: () => [
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.loading),
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.loaded),
|
||||
],
|
||||
);
|
||||
|
||||
blocTest<AdhesionsBloc, AdhesionsState>(
|
||||
'emits error on failure',
|
||||
build: () {
|
||||
when(mockRepository.getByStatut(any,
|
||||
page: anyNamed('page'), size: anyNamed('size')))
|
||||
.thenThrow(Exception('filter failed'));
|
||||
return buildBloc();
|
||||
},
|
||||
act: (b) => b.add(LoadAdhesionsByStatut('APPROUVEE')),
|
||||
expect: () => [
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.loading),
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.error),
|
||||
],
|
||||
);
|
||||
});
|
||||
|
||||
// ---- LoadAdhesionById ----------------------------------------------------
|
||||
|
||||
group('LoadAdhesionById', () {
|
||||
final adhesion = _makeAdhesion();
|
||||
|
||||
blocTest<AdhesionsBloc, AdhesionsState>(
|
||||
'emits loading then loaded with adhesionDetail',
|
||||
build: () {
|
||||
when(mockRepository.getById(any))
|
||||
.thenAnswer((_) async => adhesion);
|
||||
return buildBloc();
|
||||
},
|
||||
act: (b) => b.add(LoadAdhesionById('adh1')),
|
||||
expect: () => [
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.loading),
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.loaded)
|
||||
.having((s) => s.adhesionDetail?.id, 'detail id', 'adh1'),
|
||||
],
|
||||
);
|
||||
|
||||
blocTest<AdhesionsBloc, AdhesionsState>(
|
||||
'emits error when not found',
|
||||
build: () {
|
||||
when(mockRepository.getById(any))
|
||||
.thenThrow(Exception('not found'));
|
||||
return buildBloc();
|
||||
},
|
||||
act: (b) => b.add(LoadAdhesionById('missing')),
|
||||
expect: () => [
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.loading),
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.error),
|
||||
],
|
||||
);
|
||||
});
|
||||
|
||||
// ---- CreateAdhesion ------------------------------------------------------
|
||||
|
||||
group('CreateAdhesion', () {
|
||||
final adhesion = _makeAdhesion();
|
||||
|
||||
blocTest<AdhesionsBloc, AdhesionsState>(
|
||||
'creates adhesion then re-triggers LoadAdhesions',
|
||||
build: () {
|
||||
when(mockRepository.create(any)).thenAnswer((_) async => adhesion);
|
||||
// LoadAdhesions triggered internally
|
||||
when(mockRepository.getAll(
|
||||
page: anyNamed('page'), size: anyNamed('size')))
|
||||
.thenAnswer((_) async => [adhesion]);
|
||||
return buildBloc();
|
||||
},
|
||||
act: (b) => b.add(CreateAdhesion(adhesion)),
|
||||
expect: () => [
|
||||
// Loading from CreateAdhesion
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.loading),
|
||||
// Loading from auto-triggered LoadAdhesions
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.loading),
|
||||
// Loaded from LoadAdhesions result
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.loaded),
|
||||
],
|
||||
);
|
||||
|
||||
blocTest<AdhesionsBloc, AdhesionsState>(
|
||||
'emits error on failure',
|
||||
build: () {
|
||||
when(mockRepository.create(any))
|
||||
.thenThrow(Exception('creation failed'));
|
||||
return buildBloc();
|
||||
},
|
||||
act: (b) => b.add(CreateAdhesion(adhesion)),
|
||||
expect: () => [
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.loading),
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.error),
|
||||
],
|
||||
);
|
||||
});
|
||||
|
||||
// ---- ApprouverAdhesion ---------------------------------------------------
|
||||
|
||||
group('ApprouverAdhesion', () {
|
||||
final approved = _makeAdhesion(statut: 'APPROUVEE');
|
||||
|
||||
blocTest<AdhesionsBloc, AdhesionsState>(
|
||||
'approves adhesion and re-triggers LoadAdhesions',
|
||||
build: () {
|
||||
when(mockRepository.approuver(any, approuvePar: anyNamed('approuvePar')))
|
||||
.thenAnswer((_) async => approved);
|
||||
when(mockRepository.getAll(
|
||||
page: anyNamed('page'), size: anyNamed('size')))
|
||||
.thenAnswer((_) async => [approved]);
|
||||
return buildBloc();
|
||||
},
|
||||
act: (b) => b.add(ApprouverAdhesion('adh1', approuvePar: 'admin1')),
|
||||
expect: () => [
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.loading),
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.loaded)
|
||||
.having((s) => s.adhesionDetail?.statut, 'statut', 'APPROUVEE'),
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.loading),
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.loaded),
|
||||
],
|
||||
);
|
||||
|
||||
blocTest<AdhesionsBloc, AdhesionsState>(
|
||||
'emits error on failure',
|
||||
build: () {
|
||||
when(mockRepository.approuver(any, approuvePar: anyNamed('approuvePar')))
|
||||
.thenThrow(Exception('approval failed'));
|
||||
return buildBloc();
|
||||
},
|
||||
act: (b) => b.add(ApprouverAdhesion('adh1')),
|
||||
expect: () => [
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.loading),
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.error),
|
||||
],
|
||||
);
|
||||
});
|
||||
|
||||
// ---- RejeterAdhesion -----------------------------------------------------
|
||||
|
||||
group('RejeterAdhesion', () {
|
||||
final rejected = _makeAdhesion(statut: 'REJETEE');
|
||||
|
||||
blocTest<AdhesionsBloc, AdhesionsState>(
|
||||
'rejects adhesion with motif and re-triggers LoadAdhesions',
|
||||
build: () {
|
||||
when(mockRepository.rejeter(any, any))
|
||||
.thenAnswer((_) async => rejected);
|
||||
when(mockRepository.getAll(
|
||||
page: anyNamed('page'), size: anyNamed('size')))
|
||||
.thenAnswer((_) async => []);
|
||||
return buildBloc();
|
||||
},
|
||||
act: (b) => b.add(RejeterAdhesion('adh1', 'Dossier incomplet')),
|
||||
expect: () => [
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.loading),
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.loaded)
|
||||
.having((s) => s.adhesionDetail?.statut, 'statut', 'REJETEE'),
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.loading),
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.loaded),
|
||||
],
|
||||
);
|
||||
|
||||
blocTest<AdhesionsBloc, AdhesionsState>(
|
||||
'emits error on failure',
|
||||
build: () {
|
||||
when(mockRepository.rejeter(any, any))
|
||||
.thenThrow(Exception('rejection failed'));
|
||||
return buildBloc();
|
||||
},
|
||||
act: (b) => b.add(RejeterAdhesion('adh1', 'motif')),
|
||||
expect: () => [
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.loading),
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.error),
|
||||
],
|
||||
);
|
||||
});
|
||||
|
||||
// ---- EnregistrerPaiementAdhesion -----------------------------------------
|
||||
|
||||
group('EnregistrerPaiementAdhesion', () {
|
||||
final paid = _makeAdhesion(statut: 'PAYEE');
|
||||
|
||||
blocTest<AdhesionsBloc, AdhesionsState>(
|
||||
'records payment then re-triggers LoadAdhesions',
|
||||
build: () {
|
||||
when(mockRepository.enregistrerPaiement(
|
||||
any,
|
||||
montantPaye: anyNamed('montantPaye'),
|
||||
methodePaiement: anyNamed('methodePaiement'),
|
||||
referencePaiement: anyNamed('referencePaiement'),
|
||||
)).thenAnswer((_) async => paid);
|
||||
when(mockRepository.getAll(
|
||||
page: anyNamed('page'), size: anyNamed('size')))
|
||||
.thenAnswer((_) async => [paid]);
|
||||
return buildBloc();
|
||||
},
|
||||
act: (b) => b.add(EnregistrerPaiementAdhesion(
|
||||
'adh1',
|
||||
montantPaye: 10000,
|
||||
methodePaiement: 'WAVE_MONEY',
|
||||
referencePaiement: 'REF-001',
|
||||
)),
|
||||
expect: () => [
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.loading),
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.loaded)
|
||||
.having((s) => s.adhesionDetail?.statut, 'statut', 'PAYEE'),
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.loading),
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.loaded),
|
||||
],
|
||||
);
|
||||
|
||||
blocTest<AdhesionsBloc, AdhesionsState>(
|
||||
'emits error on failure',
|
||||
build: () {
|
||||
when(mockRepository.enregistrerPaiement(
|
||||
any,
|
||||
montantPaye: anyNamed('montantPaye'),
|
||||
methodePaiement: anyNamed('methodePaiement'),
|
||||
referencePaiement: anyNamed('referencePaiement'),
|
||||
)).thenThrow(Exception('payment failed'));
|
||||
return buildBloc();
|
||||
},
|
||||
act: (b) => b.add(EnregistrerPaiementAdhesion('adh1', montantPaye: 5000)),
|
||||
expect: () => [
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.loading),
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.error),
|
||||
],
|
||||
);
|
||||
});
|
||||
|
||||
// ---- LoadAdhesionsStats --------------------------------------------------
|
||||
|
||||
group('LoadAdhesionsStats', () {
|
||||
final stats = {
|
||||
'total': 10,
|
||||
'enAttente': 3,
|
||||
'approuvees': 5,
|
||||
'rejetees': 2,
|
||||
};
|
||||
|
||||
blocTest<AdhesionsBloc, AdhesionsState>(
|
||||
'emits state with stats populated on success',
|
||||
build: () {
|
||||
when(mockRepository.getStats()).thenAnswer((_) async => stats);
|
||||
return buildBloc();
|
||||
},
|
||||
act: (b) => b.add(const LoadAdhesionsStats()),
|
||||
expect: () => [
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.stats, 'stats', stats),
|
||||
],
|
||||
);
|
||||
|
||||
blocTest<AdhesionsBloc, AdhesionsState>(
|
||||
'emits state with null stats when repository returns null',
|
||||
build: () {
|
||||
when(mockRepository.getStats()).thenAnswer((_) async => null);
|
||||
return buildBloc();
|
||||
},
|
||||
act: (b) => b.add(const LoadAdhesionsStats()),
|
||||
expect: () => [
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.stats, 'stats', isNull),
|
||||
],
|
||||
);
|
||||
|
||||
blocTest<AdhesionsBloc, AdhesionsState>(
|
||||
'emits error on failure',
|
||||
build: () {
|
||||
when(mockRepository.getStats())
|
||||
.thenThrow(Exception('stats error'));
|
||||
return buildBloc();
|
||||
},
|
||||
act: (b) => b.add(const LoadAdhesionsStats()),
|
||||
expect: () => [
|
||||
isA<AdhesionsState>()
|
||||
.having((s) => s.status, 'status', AdhesionsStatus.error),
|
||||
],
|
||||
);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user