Mobile mirror du backend P2-NEW-3. DRY strict — Clean Architecture identique aux autres features (compliance, devise). Domain - StatutRapport enum (draft, signe, archive, inconnu) + extension StatutRapportX (code/libelle/severite/fromCode) - RapportTrimestriel entity (Equatable) + helpers libellePeriode, scoreSeverite (>=80 success, >=60 warning, <60 danger) Data - RapportTrimestrielModel.fromJson (parsing tolérant null + dates ISO) - ReportingRemoteDataSourceImpl (Dio) : lister/generer/signer/archiver/telechargerPdf - ReportingRepositoryImpl @Injectable Presentation - ReportingBloc : Load/Generer/Signer/Archiver events, 4 states (Initial/Loading/Loaded/Error) - RapportsTrimestrielsPage : Material 3 ListView avec cards (period, score coloré, tag statut, hash tronqué) + EmptyView + ErrorView Tests (10/10 verts) - StatutRapportX × 2 (fromCode parse/null/inconnu, libelle/severite/code) - RapportTrimestriel × 5 (libellePeriode, estDraft/estSigne/estArchive, scoreSeverite × 3) - RapportTrimestrielModel.fromJson × 3 (complet, fallbacks, date invalide) Note : viewer PDF interne reporté à un sprint dédié (intégration pdfx + permission storage Android). Téléchargement bytes via API exposé dans datasource pour usage futur.
95 lines
3.4 KiB
Dart
95 lines
3.4 KiB
Dart
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:unionflow_mobile_apps/features/reporting/data/models/rapport_trimestriel_model.dart';
|
|
import 'package:unionflow_mobile_apps/features/reporting/domain/entities/rapport_trimestriel.dart';
|
|
|
|
void main() {
|
|
group('StatutRapportX', () {
|
|
test('fromCode parse correct', () {
|
|
expect(StatutRapportX.fromCode('DRAFT'), StatutRapport.draft);
|
|
expect(StatutRapportX.fromCode('SIGNE'), StatutRapport.signe);
|
|
expect(StatutRapportX.fromCode('ARCHIVE'), StatutRapport.archive);
|
|
expect(StatutRapportX.fromCode(null), StatutRapport.inconnu);
|
|
expect(StatutRapportX.fromCode('AUTRE'), StatutRapport.inconnu);
|
|
});
|
|
|
|
test('libellé / sévérité / code', () {
|
|
expect(StatutRapport.draft.code, 'DRAFT');
|
|
expect(StatutRapport.draft.libelle, 'Brouillon');
|
|
expect(StatutRapport.draft.severite, 'warning');
|
|
expect(StatutRapport.signe.code, 'SIGNE');
|
|
expect(StatutRapport.signe.severite, 'info');
|
|
expect(StatutRapport.archive.code, 'ARCHIVE');
|
|
expect(StatutRapport.archive.severite, 'success');
|
|
expect(StatutRapport.inconnu.code, '');
|
|
expect(StatutRapport.inconnu.severite, 'secondary');
|
|
});
|
|
});
|
|
|
|
group('RapportTrimestriel', () {
|
|
RapportTrimestriel build({int score = 75, StatutRapport statut = StatutRapport.draft}) {
|
|
return RapportTrimestriel(
|
|
id: 'r1', organisationId: 'o1', annee: 2026, trimestre: 1,
|
|
dateGeneration: DateTime(2026, 4, 1),
|
|
statut: statut, scoreConformite: score,
|
|
);
|
|
}
|
|
|
|
test('libellePeriode formaté', () {
|
|
expect(build().libellePeriode, 'T1 / 2026');
|
|
});
|
|
|
|
test('estDraft / estSigne / estArchive', () {
|
|
expect(build(statut: StatutRapport.draft).estDraft, isTrue);
|
|
expect(build(statut: StatutRapport.signe).estSigne, isTrue);
|
|
expect(build(statut: StatutRapport.archive).estArchive, isTrue);
|
|
});
|
|
|
|
test('scoreSeverite — score >=80 → success', () {
|
|
expect(build(score: 85).scoreSeverite, 'success');
|
|
});
|
|
|
|
test('scoreSeverite — 60..79 → warning', () {
|
|
expect(build(score: 70).scoreSeverite, 'warning');
|
|
});
|
|
|
|
test('scoreSeverite — <60 → danger', () {
|
|
expect(build(score: 50).scoreSeverite, 'danger');
|
|
});
|
|
});
|
|
|
|
group('RapportTrimestrielModel.fromJson', () {
|
|
test('parsing complet', () {
|
|
final json = {
|
|
'id': 'r-uuid', 'organisationId': 'o-uuid',
|
|
'annee': 2026, 'trimestre': 2,
|
|
'dateGeneration': '2026-04-01T10:00:00',
|
|
'statut': 'SIGNE', 'scoreConformite': 82,
|
|
'signataireId': 's-uuid',
|
|
'dateSignature': '2026-04-05T14:30:00',
|
|
'hashSha256': 'a' * 64,
|
|
};
|
|
final m = RapportTrimestrielModel.fromJson(json);
|
|
expect(m.id, 'r-uuid');
|
|
expect(m.annee, 2026);
|
|
expect(m.trimestre, 2);
|
|
expect(m.statut, StatutRapport.signe);
|
|
expect(m.scoreConformite, 82);
|
|
expect(m.signataireId, 's-uuid');
|
|
expect(m.hashSha256, 'a' * 64);
|
|
});
|
|
|
|
test('valeurs manquantes → fallbacks', () {
|
|
final m = RapportTrimestrielModel.fromJson(<String, dynamic>{});
|
|
expect(m.id, '');
|
|
expect(m.statut, StatutRapport.inconnu);
|
|
expect(m.scoreConformite, 0);
|
|
expect(m.dateGeneration, isNull);
|
|
});
|
|
|
|
test('date invalide → null', () {
|
|
final m = RapportTrimestrielModel.fromJson({'dateGeneration': 'not-a-date'});
|
|
expect(m.dateGeneration, isNull);
|
|
});
|
|
});
|
|
}
|