feat(exercice): affichage des médias pendant l'exécution (ticket #36)
Expose la galerie d'images d'exercice (backend du ticket #35) pendant l'exécution de séance sur workout_execution_screen.dart et program_screen.dart, avec les ajustements domain/use cases/repositories nécessaires. flutter analyze propre, 67/67 tests verts, build APK debug validé. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -116,6 +116,131 @@ void main() {
|
||||
expect(find.text('Pas de repos'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('le bouton médias est absent sans média', (tester) async {
|
||||
final clock = _FakeClock(DateTime.utc(2026, 7, 17, 12));
|
||||
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: 0,
|
||||
resolvedTemplateSnapshotJson: _sessionSnapshot(),
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: WorkoutExecutionScreen(
|
||||
initialSession: session,
|
||||
activeUseCases: _activeUseCases(
|
||||
_FakeActiveSessionRepository(),
|
||||
clock,
|
||||
),
|
||||
closeUseCase: _closeUseCase(_FakeActiveSessionRepository(), clock),
|
||||
historyUseCases: _historyUseCases(clock),
|
||||
workoutTemplateUseCases: _workoutTemplateUseCases(),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(find.text('Voir médias'), findsNothing);
|
||||
expect(find.byTooltip('Voir les médias de l’exercice'), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('le bouton médias ouvre la sheet si médias présents', (
|
||||
tester,
|
||||
) async {
|
||||
final clock = _FakeClock(DateTime.utc(2026, 7, 17, 12));
|
||||
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: 0,
|
||||
resolvedTemplateSnapshotJson: _sessionSnapshot(
|
||||
imageMediaIds: const ['image-1'],
|
||||
videoMediaId: 'video-1',
|
||||
),
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: WorkoutExecutionScreen(
|
||||
initialSession: session,
|
||||
activeUseCases: _activeUseCases(
|
||||
_FakeActiveSessionRepository(),
|
||||
clock,
|
||||
),
|
||||
closeUseCase: _closeUseCase(_FakeActiveSessionRepository(), clock),
|
||||
historyUseCases: _historyUseCases(clock),
|
||||
workoutTemplateUseCases: _workoutTemplateUseCases(),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(find.byTooltip('Voir les médias de l’exercice'), findsOneWidget);
|
||||
|
||||
await tester.tap(find.text('Voir médias'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('Médias de l’exercice'), findsOneWidget);
|
||||
expect(find.text('Images'), findsOneWidget);
|
||||
expect(find.text('Vidéo'), findsOneWidget);
|
||||
expect(find.text('1/1'), findsOneWidget);
|
||||
expect(find.text('Image 1'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('la galerie médias navigue entre les images', (tester) async {
|
||||
final clock = _FakeClock(DateTime.utc(2026, 7, 17, 12));
|
||||
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: 0,
|
||||
resolvedTemplateSnapshotJson: _sessionSnapshot(
|
||||
imageMediaIds: const ['image-1', 'image-2', 'image-3'],
|
||||
),
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: WorkoutExecutionScreen(
|
||||
initialSession: session,
|
||||
activeUseCases: _activeUseCases(
|
||||
_FakeActiveSessionRepository(),
|
||||
clock,
|
||||
),
|
||||
closeUseCase: _closeUseCase(_FakeActiveSessionRepository(), clock),
|
||||
historyUseCases: _historyUseCases(clock),
|
||||
workoutTemplateUseCases: _workoutTemplateUseCases(),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.tap(find.text('Voir médias'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('1/3'), findsOneWidget);
|
||||
|
||||
await tester.drag(find.byType(PageView), const Offset(-400, 0));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('2/3'), findsOneWidget);
|
||||
expect(find.text('Image 2'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('un repos actif est repris avec le temps restant recalculé', (
|
||||
tester,
|
||||
) async {
|
||||
@ -559,6 +684,8 @@ String _sessionSnapshot({
|
||||
double targetScore = 80,
|
||||
String scoreUnit = 'kg',
|
||||
ScoreInputMode scoreInputMode = ScoreInputMode.manual,
|
||||
List<String> imageMediaIds = const [],
|
||||
String? videoMediaId,
|
||||
}) {
|
||||
return jsonEncode({
|
||||
'name': 'Séance jambes',
|
||||
@ -582,6 +709,10 @@ String _sessionSnapshot({
|
||||
'scoreLabelSnapshot': 'Score',
|
||||
'scoreUnitSnapshot': scoreUnit,
|
||||
'restSecondsOverride': restSeconds,
|
||||
'exerciseImageMediaIdsSnapshot': imageMediaIds,
|
||||
'imageMediaIdsSnapshot': imageMediaIds,
|
||||
'exerciseVideoMediaIdSnapshot': videoMediaId,
|
||||
'videoMediaIdSnapshot': videoMediaId,
|
||||
},
|
||||
],
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user