wip(watch): sauvegarde travail en cours lot critique (#157 #163 #164 #174 #175 #178)

This commit is contained in:
2026-07-29 12:34:07 +02:00
parent f523a5a8b5
commit 74d6000606
26 changed files with 516 additions and 62 deletions

View File

@ -7,6 +7,7 @@ import 'package:gametime/application/application.dart';
import 'package:gametime/application/app_bootstrap.dart';
import 'package:gametime/domain/domain.dart';
import 'package:gametime/presentation/home_screen.dart';
import 'package:watch_bridge_contract/watch_bridge_contract.dart';
void main() {
testWidgets('lentrée Progression est présente après Historique', (
@ -292,7 +293,8 @@ final class _FakeBootstrap implements AppDependencies {
repository: _FakeLocalDataBackupRepository(),
mediaStore: _FakeLocalBackupMediaStore(),
clock: _FakeClock(DateTime.utc(2026, 7, 17, 12)),
);
),
watchAlertPublisher = _NoOpWatchAlertPublisher();
@override
final AuthUseCases authUseCases;
@ -339,6 +341,9 @@ final class _FakeBootstrap implements AppDependencies {
@override
final ExercisePerformanceReferenceUseCase exercisePerformanceReferenceUseCase;
@override
final WatchAlertPublisher watchAlertPublisher;
@override
final DataExportUseCase dataExportUseCase;
@ -346,6 +351,11 @@ final class _FakeBootstrap implements AppDependencies {
final DataImportUseCase dataImportUseCase;
}
final class _NoOpWatchAlertPublisher implements WatchAlertPublisher {
@override
Future<void> publishAlert(WatchAlertEnvelope alert) async {}
}
String _sessionSnapshot() {
return jsonEncode({
'name': 'Séance jambes',

View File

@ -1962,6 +1962,7 @@ void main() {
final clock = _FakeClock(DateTime.utc(2026, 7, 17, 12));
final repository = _FakeActiveSessionRepository();
final audio = _FakeStepAudioCuePlayer();
final alerts = _FakeWatchAlertPublisher();
final session = ActiveWorkoutSession(
metadata: _metadata('session-1'),
sourceWorkoutTemplateId: 'template-1',
@ -1991,6 +1992,7 @@ void main() {
closeUseCase: _closeUseCase(repository, clock),
historyUseCases: _historyUseCases(clock),
workoutTemplateUseCases: _workoutTemplateUseCases(),
watchAlertPublisher: alerts,
),
),
);
@ -2004,24 +2006,31 @@ void main() {
expect(find.text('00:03'), findsOneWidget);
expect(audio.shortBeeps, 1);
expect(alerts.alerts, hasLength(1));
expect(alerts.alerts.last.pattern, WatchAlertPattern.countdownTick);
clock.value = DateTime.utc(2026, 7, 17, 12, 0, 3);
await tester.pump(const Duration(milliseconds: 100));
expect(find.text('00:02'), findsOneWidget);
expect(audio.shortBeeps, 2);
expect(alerts.alerts, hasLength(2));
clock.value = DateTime.utc(2026, 7, 17, 12, 0, 4);
await tester.pump(const Duration(milliseconds: 100));
expect(find.text('00:01'), findsOneWidget);
expect(audio.shortBeeps, 3);
expect(alerts.alerts, hasLength(3));
clock.value = DateTime.utc(2026, 7, 17, 12, 0, 5, 200);
await tester.pump(const Duration(milliseconds: 200));
await tester.pump();
expect(audio.longBeeps, 1);
expect(alerts.alerts, hasLength(4));
expect(alerts.alerts.last.kind, WatchAlertKind.countdownFinished);
expect(alerts.alerts.last.pattern, WatchAlertPattern.timerFinished);
});
testWidgets(
@ -2608,6 +2617,15 @@ final class _FakeStepAudioCuePlayer implements ExerciseStepAudioCuePlayer {
}
}
final class _FakeWatchAlertPublisher implements WatchAlertPublisher {
final alerts = <WatchAlertEnvelope>[];
@override
Future<void> publishAlert(WatchAlertEnvelope alert) async {
alerts.add(alert);
}
}
final class _FakeExercisePerformanceReferenceRepository
implements ExercisePerformanceReferenceRepository {
const _FakeExercisePerformanceReferenceRepository({this.last, this.record});