feat(ui): navigation libre dans le plan de séance (ticket #22)

Permet de circuler librement entre les exercices/séries du plan de
séance sur workout_execution_screen.dart, au lieu d'un déroulé
strictement linéaire. flutter analyze propre, 31/31 tests verts, build
APK debug validé.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-18 00:30:41 +02:00
parent 1cca07df58
commit a936478413
2 changed files with 385 additions and 1 deletions

View File

@ -217,6 +217,69 @@ void main() {
expect(repository.results.single.actualTimeMs, greaterThan(0));
});
testWidgets('le plan de séance affiche les états des séries', (tester) async {
final clock = _FakeClock(DateTime.utc(2026, 7, 17, 12));
final repository = _FakeActiveSessionRepository();
final session = ActiveWorkoutSession(
metadata: _metadata('session-1'),
sourceWorkoutTemplateId: 'template-1',
status: ActiveWorkoutStatus.running,
startedAt: DateTime.utc(2026, 7, 17, 12),
lastPersistedAt: DateTime.utc(2026, 7, 17, 12),
elapsedActiveMs: 0,
currentProgramIndex: 0,
currentExerciseIndex: 0,
currentSetIndex: 2,
resolvedTemplateSnapshotJson: _sessionSnapshot(
setsCount: 4,
restSeconds: 0,
),
);
repository.session = session;
repository.results.add(
ActiveSetResult(
metadata: _metadata('result-1'),
activeWorkoutSessionId: 'session-1',
programSnapshotId: 'template-program-1',
exerciseSnapshotId: 'exercise-1',
programIndex: 0,
exerciseIndex: 0,
setIndex: 0,
actualReps: 10,
actualScore: 7,
scoreUnitSnapshot: 'paniers',
),
);
await tester.pumpWidget(
MaterialApp(
home: WorkoutExecutionScreen(
initialSession: session,
activeUseCases: _activeUseCases(repository, clock),
closeUseCase: _closeUseCase(repository, clock),
historyUseCases: _historyUseCases(clock),
workoutTemplateUseCases: _workoutTemplateUseCases(),
),
),
);
await tester.tap(find.byTooltip('Voir le plan'));
await tester.pumpAndSettle();
expect(find.text('Plan de séance'), findsOneWidget);
expect(find.text('Terminée'), findsOneWidget);
expect(find.text('10 reps · 7 paniers'), findsOneWidget);
expect(find.text('Passée'), findsOneWidget);
expect(find.text('Aucun résultat'), findsOneWidget);
expect(find.text('En cours'), findsOneWidget);
expect(find.text('À faire'), findsOneWidget);
await tester.tap(find.text('En cours'));
await tester.pumpAndSettle();
expect(find.text('Plan de séance'), findsNothing);
});
}
ActiveWorkoutSessionUseCases _activeUseCases(