Apporte aux compliance officers et controleurs internes l'accès mobile au tableau de bord de conformité backend (P1-NEW-7). Et prépare la diaspora avec Devise enum + sélecteur préférence persisté. Feature Compliance (Clean Architecture) - Domain : ComplianceSnapshot + ConformiteIndicateur (Equatable), helpers scoreSeverite + hasAlertesCritiques - Data : ComplianceSnapshotModel.fromJson (parsing tolerant aux nullables), ComplianceRemoteDataSourceImpl Dio (GET /api/compliance/dashboard), ComplianceRepositoryImpl @Injectable - Presentation : ComplianceBloc (Load/Refresh events, Initial/Loading/Loaded/Error states), ConformiteDashboardPage (Material 3, ScoreCard 0-100 colorée, 9 IndicateurTile, AlertesCard rouge si critiques) Feature Devise - Devise enum (10 valeurs miroirs backend, code/libelle/zone) - fromCode tolérant casse + null/vide → XOF - estInternationale pour AML - DeviseSelector widget DropdownButtonFormField + readPreferred/writePreferred via FlutterSecureStorage (clé unionflow.devise.preferee) Tests (17/17 verts) - ComplianceSnapshot : 7 tests (scoreSeverite × 3, hasAlertesCritiques × 4) - ComplianceSnapshotModel.fromJson : 4 tests (complet, fallbacks, string→double, indicateur invalide) - Devise enum : 6 tests (reference, fromCode parse, fromCode null/inconnu, estInternationale × 2, intégrité valeurs) Note : feature reporting trimestriel mobile (PDF viewer + bloc liste) reportée à un sprint dédié — nécessite intégration pdf viewer + cache local non triviale.
47 lines
1.6 KiB
Dart
47 lines
1.6 KiB
Dart
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:unionflow_mobile_apps/features/devise/domain/entities/devise.dart';
|
|
|
|
void main() {
|
|
group('Devise enum', () {
|
|
test('reference = XOF', () {
|
|
expect(Devise.reference(), Devise.xof);
|
|
});
|
|
|
|
test('fromCode parse correct', () {
|
|
expect(Devise.fromCode('EUR'), Devise.eur);
|
|
expect(Devise.fromCode('usd'), Devise.usd);
|
|
expect(Devise.fromCode('GBP'), Devise.gbp);
|
|
});
|
|
|
|
test('fromCode null/vide/inconnu → XOF (référence)', () {
|
|
expect(Devise.fromCode(null), Devise.xof);
|
|
expect(Devise.fromCode(''), Devise.xof);
|
|
expect(Devise.fromCode('XYZ'), Devise.xof);
|
|
});
|
|
|
|
test('estInternationale — EUR/USD/GBP/CAD/CHF → true', () {
|
|
expect(Devise.eur.estInternationale, isTrue);
|
|
expect(Devise.usd.estInternationale, isTrue);
|
|
expect(Devise.gbp.estInternationale, isTrue);
|
|
expect(Devise.cad.estInternationale, isTrue);
|
|
expect(Devise.chf.estInternationale, isTrue);
|
|
});
|
|
|
|
test('estInternationale — XOF/XAF/GHS/NGN/MAD → false', () {
|
|
expect(Devise.xof.estInternationale, isFalse);
|
|
expect(Devise.xaf.estInternationale, isFalse);
|
|
expect(Devise.ghs.estInternationale, isFalse);
|
|
expect(Devise.ngn.estInternationale, isFalse);
|
|
expect(Devise.mad.estInternationale, isFalse);
|
|
});
|
|
|
|
test('Toutes les devises ont code 3 lettres + libellé non vide + zone', () {
|
|
for (final d in Devise.values) {
|
|
expect(d.code.length, 3);
|
|
expect(d.libelle.isNotEmpty, isTrue);
|
|
expect(d.zone.isNotEmpty, isTrue);
|
|
}
|
|
});
|
|
});
|
|
}
|