Signalé sur banc, et les deux vues détaillées inventaient.
CONSOMMATION — PAC = 38 % de la maison, eau chaude = 18 %, autres = 22 %. Des
ratios posés à la maquette, marqués « estimé »… et affichés tels quels le
2026-09-06 alors que les compteurs ECS et PAC publiaient `{powerW: 0, source:
meter}`. Un compteur à zéro dit « rien ne chauffe » ; l'écran répondait 720 W.
La mention « estimé » était le problème autant que le remède : sous un nombre
inventé, elle le rend acceptable. Les branches viennent désormais de
`GetLoadTelemetry.measurement`, par domaine, et une charge sans mesure publiée
affiche « non publié ». « Autres » disparaît — c'était un reste calculé sur des
parts inventées, donc inventé lui aussi : sans mesure exhaustive, il n'y a pas de
reste connu.
PRODUCTION — « Onduleur 1 » et « Onduleur 2 » portaient chacun la MOITIÉ de la
production, avec l'état `ok`, donc sans même la marque « estimé » des branches de
consommation. Deux appareils qui n'existent nulle part : le banc n'a qu'un seul
compteur de production. La vue dit maintenant « détail par source non publié par
cette box ».
Et un débordement introduit en chemin, attrapé en test : « non publié » ne tient
pas dans un nœud dimensionné pour « 1.2 kW » — 7 px de trop, donc du texte coupé
sur l'appareil. `FittedBox(scaleDown)`, comme pour l'étiquette des tuiles.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GKM8FDNHZWogAsjjfB8pSw
128 lines
5.2 KiB
Dart
128 lines
5.2 KiB
Dart
/// La vue « consommation » du Sankey — ce qui est mesuré, et ce qui ne l'est pas.
|
|
///
|
|
/// Trois de ses quatre branches sont des **ratios en dur** posés à la maquette : PAC = 38 %
|
|
/// de la consommation maison, eau chaude = 18 %, autres = 22 %. Un seul nœud (« Autres »)
|
|
/// portait le cercle pointillé ; les deux autres se lisaient comme des mesures. Et la
|
|
/// voiture affichait 3,6 kW en permanence, véhicule débranché — la valeur par défaut de
|
|
/// `EnergyData.chargingPower`, supprimée le 2026-08-28.
|
|
///
|
|
/// Ces tests figent le marquage. Ils ne valident pas les ratios : les remplacer par
|
|
/// `measuredW` de `GetLoadTelemetry` est un lot à part.
|
|
library;
|
|
|
|
import 'package:etm_powersync_app/features/dashboard/widgets/energy_flow_card.dart';
|
|
import 'package:etm_powersync_app/models/energy_data.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
/// Largeur contrainte : le schéma est un carré, et en pleine largeur de la fenêtre de test
|
|
/// (800 px) il déborde des 600 px de haut — le nœud « Maison » se retrouve hors écran et
|
|
/// aucune touche ne l'atteint.
|
|
Widget _harness({double? evChargerPowerW, Map<String, double?>? mesures}) =>
|
|
MediaQuery(
|
|
data: const MediaQueryData(disableAnimations: true),
|
|
child: MaterialApp(
|
|
home: Scaffold(
|
|
body: Center(
|
|
child: SizedBox(
|
|
width: 340,
|
|
child: EnergyFlowCard(
|
|
data: const EnergyData(homePower: 4000, pvPower: 5000),
|
|
evChargerPowerW: evChargerPowerW,
|
|
mesuresParDomaine: mesures ?? const {},
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
/// `pumpAndSettle` est inutilisable ici : les particules du schéma tournent en boucle
|
|
/// (`repeat()`), et `disableAnimations` ne change que la valeur lue, pas le contrôleur. On
|
|
/// avance donc d'un nombre fini de trames.
|
|
Future<void> _poser(WidgetTester tester) async {
|
|
for (var i = 0; i < 6; i++) {
|
|
await tester.pump(const Duration(milliseconds: 120));
|
|
}
|
|
}
|
|
|
|
/// Ouvre le détail de consommation — il n'est atteignable qu'en touchant « Maison ».
|
|
///
|
|
/// Le `_poser` AVANT la touche n'est pas décoratif : les nœuds entrent en `ScaleTransition`
|
|
/// et, sur la première trame, leur échelle vaut zéro — la touche traverse sans rien
|
|
/// atteindre, silencieusement.
|
|
Future<void> _ouvrirConso(WidgetTester tester) async {
|
|
await _poser(tester);
|
|
await tester.tap(find.text('Maison'));
|
|
await _poser(tester);
|
|
}
|
|
|
|
void main() {
|
|
testWidgets('la vue d\'ensemble ne parle pas d\'estimation — tout y est mesuré',
|
|
(tester) async {
|
|
await tester.pumpWidget(_harness());
|
|
await _poser(tester);
|
|
expect(find.textContaining('Répartition estimée'), findsNothing);
|
|
});
|
|
|
|
testWidgets('un compteur a 0 W affiche 0 W, pas 18 % de la maison',
|
|
(tester) async {
|
|
// Le cas exact du 2026-09-06 : ECS et PAC publiaient {powerW: 0, source: meter}
|
|
// pendant que l'ecran montrait des parts de la consommation du foyer.
|
|
await tester.pumpWidget(_harness(mesures: {'ecs': 0.0, 'heating': 0.0}));
|
|
await _ouvrirConso(tester);
|
|
|
|
expect(find.text('0.0 kW'), findsNWidgets(2));
|
|
// 18 % et 38 % de 4 000 W : les deux nombres qui ne doivent plus exister.
|
|
expect(find.textContaining('0.7'), findsNothing);
|
|
expect(find.textContaining('1.5'), findsNothing);
|
|
});
|
|
|
|
testWidgets('un domaine sans mesure publiee dit non publie', (tester) async {
|
|
await tester.pumpWidget(_harness(mesures: {'ecs': 1200.0}));
|
|
await _ouvrirConso(tester);
|
|
|
|
expect(find.text('1.2 kW'), findsOneWidget);
|
|
expect(find.text('non publié'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('la note ne parle plus d estimation, il n y a plus rien d estime',
|
|
(tester) async {
|
|
// La mention « estimé » etait le probleme autant que le remede : sous un nombre
|
|
// invente, elle le rend acceptable. L'enlever oblige a ne montrer que du vrai.
|
|
await tester.pumpWidget(_harness(mesures: {'ecs': 1200.0}));
|
|
await _ouvrirConso(tester);
|
|
|
|
expect(find.textContaining('Répartition estimée'), findsNothing);
|
|
expect(find.textContaining('parts types'), findsNothing);
|
|
expect(find.textContaining('non publié'), findsWidgets);
|
|
});
|
|
|
|
testWidgets('Autres a disparu : un reste calcule sur des parts inventees',
|
|
(tester) async {
|
|
await tester.pumpWidget(_harness(mesures: {'ecs': 1200.0, 'heating': 800.0}));
|
|
await _ouvrirConso(tester);
|
|
expect(find.text('Autres'), findsNothing);
|
|
});
|
|
|
|
testWidgets('sans borne, la voiture affiche « non lu » — jamais 0,0 kW',
|
|
(tester) async {
|
|
// 3,6 kW en dur vivait ici, voiture débranchée, sur le premier écran de l'app.
|
|
// Le remplacer par un zéro aurait échangé une fiction contre une autre : « rien ne
|
|
// charge » n'est pas « je ne mesure rien ».
|
|
await tester.pumpWidget(_harness());
|
|
await _ouvrirConso(tester);
|
|
|
|
expect(find.text('non lu'), findsOneWidget);
|
|
expect(find.textContaining('3.6'), findsNothing);
|
|
});
|
|
|
|
testWidgets('avec une borne, elle affiche la puissance mesurée', (tester) async {
|
|
await tester.pumpWidget(_harness(evChargerPowerW: 3907));
|
|
await _ouvrirConso(tester);
|
|
|
|
expect(find.text('3.9 kW'), findsOneWidget);
|
|
expect(find.text('non lu'), findsNothing);
|
|
});
|
|
}
|