etm-powersync-app/test/energy_ratios_snapshot_test.dart
Patrick Schurig bcf5b87e43 feat(bilan): la journée vient de la BOX — periodStartedAt, et non minuit du téléphone
Sondé avant de câbler (`+etm56`) : `periodStartedAt` = 1788562800 = 00:00 Londres
= 01:00 Paris, `measuredSince` = 07:04 Londres, `timeZone` = Europe/London. Sept
heures d'écart entre les deux bornes.

- `EnergyRatiosSnapshot` — les deux instants et le fuseau. `baselineRepriseEnJournee`
  dit quand les ratios de la box ne parlent que depuis un redémarrage : c'est le
  silence que `measuredSince` existe pour fermer, et quand les deux coïncident —
  le cas normal — il n'y a rien à dire de plus ;
- `fetchEnergyRatios()`, et `fetchDailyBalance()` qui prend désormais la frontière
  publiée. Repli sur minuit local pour une box antérieure, écrit comme tel.

Et un effet de bord attrapé avant qu'il ne parte : `startsLate` comparait à minuit
du TÉLÉPHONE. Avec la frontière de la box, il aurait crié « partiel » tous les
jours sur un bilan complet — un avertissement permanent cesse d'être lu. Il se
compare maintenant à `periodStart`, porté par le bilan, et un test fige le piège.

Les taux journaliers de `DailyBalance` sont donc corrigés du même geste : ils se
calculent déjà par différence de compteurs sur la fenêtre, c'était la fenêtre qui
était fausse.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GKM8FDNHZWogAsjjfB8pSw
2026-09-05 09:20:31 +02:00

66 lines
2.9 KiB
Dart

/// **Les deux bornes des ratios de la box** — et la phrase que leur écart autorise.
///
/// Relevé sur `.75` le 2026-09-05 en `+etm56` : `periodStartedAt` à 00:00 Londres
/// (01:00 Paris), `measuredSince` à 07:04 Londres. **Sept heures d'écart.** Un ratio
/// étiqueté « aujourd'hui » aurait donc parlé d'une fenêtre commencée à 08:04 sans que rien
/// ne le signale — c'est ce silence que la paire ferme.
library;
import 'package:etm_powersync_app/models/energy_ratios_snapshot.dart';
import 'package:flutter_test/flutter_test.dart';
/// La charge utile réelle, telle que la sonde l'a lue.
Map<String, dynamic> _releve({int? measuredSince}) => {
'autonomyRate': 41.0,
'selfConsumptionRate': 63.0,
'periodStartedAt': 1788562800,
'measuredSince': measuredSince ?? 1788588269,
'timeZone': 'Europe/London',
};
void main() {
group('les deux instants se lisent, et leur écart parle', () {
test('la frontière de journée est PUBLIÉE, pas dérivée', () {
final r = EnergyRatiosSnapshot.fromJson(_releve());
// 1788562800 = 2026-09-04T23:00:00Z = minuit à Londres. L'app ne recalcule rien :
// un nom de fuseau IANA ne donne pas de décalage, et une base de fuseaux ne donnerait
// pas les jours à 23 ou 25 heures.
expect(r.periodStartedAt!.toUtc(),
DateTime.utc(2026, 9, 4, 23, 0, 0));
expect(r.timeZone, 'Europe/London');
expect(r.datePeriode, isTrue);
});
test('baseline reprise en journée : l\'écran doit le dire', () {
expect(EnergyRatiosSnapshot.fromJson(_releve()).baselineRepriseEnJournee,
isTrue,
reason: 'sept heures après le début de journée — un redémarrage de nymead');
});
test('les deux coïncident : rien à dire de plus', () {
// Le cas normal. Une phrase supplémentaire y serait du bruit.
final r = EnergyRatiosSnapshot.fromJson(_releve(measuredSince: 1788562800));
expect(r.baselineRepriseEnJournee, isFalse);
});
test('une minute d\'écart n\'est pas une reprise', () {
// Les deux instants viennent de la même box, mais rien ne garantit qu'ils tombent
// sur la même seconde au premier cycle après minuit.
final r = EnergyRatiosSnapshot.fromJson(_releve(measuredSince: 1788562840));
expect(r.baselineRepriseEnJournee, isFalse);
});
});
group('box antérieure : on ne conclut pas d\'une absence', () {
test('sans les champs, aucune date et aucune alerte', () {
const vide = <String, dynamic>{'autonomyRate': 41.0};
final r = EnergyRatiosSnapshot.fromJson(vide);
expect(r.periodStartedAt, isNull);
expect(r.datePeriode, isFalse,
reason: 'le bilan retombera sur minuit local, et c\'est écrit');
expect(r.baselineRepriseEnJournee, isFalse,
reason: 'ne pas savoir n\'est pas « la baseline a bougé »');
});
});
}