Corrige l'affichage des images (#41) et de la vidéo (#42) dans le carrousel de médias, et le format du chrono de score qui n'affichait que les secondes (#43) sur workout_execution_screen.dart. Ajoute la dépendance video_player (2.13.0) pour la lecture vidéo. Ajuste home_screen.dart, history_screen.dart et workout_template_screen.dart en conséquence. flutter analyze propre, flutter test 77/77 vert (plus aucun hang), pub get résolu. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -1,4 +1,5 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
@ -153,6 +154,12 @@ void main() {
|
||||
testWidgets('le bouton médias ouvre la sheet si médias présents', (
|
||||
tester,
|
||||
) async {
|
||||
final imageFile = (await tester.runAsync(_createTestImageFile))!;
|
||||
addTearDown(() async {
|
||||
await tester.runAsync(() async {
|
||||
await imageFile.parent.delete(recursive: true);
|
||||
});
|
||||
});
|
||||
final clock = _FakeClock(DateTime.utc(2026, 7, 17, 12));
|
||||
final session = ActiveWorkoutSession(
|
||||
metadata: _metadata('session-1'),
|
||||
@ -170,34 +177,74 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: WorkoutExecutionScreen(
|
||||
initialSession: session,
|
||||
activeUseCases: _activeUseCases(
|
||||
_FakeActiveSessionRepository(),
|
||||
clock,
|
||||
await tester.runAsync(() async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: WorkoutExecutionScreen(
|
||||
initialSession: session,
|
||||
activeUseCases: _activeUseCases(
|
||||
_FakeActiveSessionRepository(),
|
||||
clock,
|
||||
),
|
||||
closeUseCase: _closeUseCase(_FakeActiveSessionRepository(), clock),
|
||||
historyUseCases: _historyUseCases(clock),
|
||||
workoutTemplateUseCases: _workoutTemplateUseCases(),
|
||||
mediaAssetLoader: (id) async {
|
||||
if (id == 'image-1') {
|
||||
return MediaAsset(
|
||||
metadata: _metadata(id),
|
||||
kind: MediaKind.image,
|
||||
localUri: imageFile.uri.toString(),
|
||||
);
|
||||
}
|
||||
if (id == 'video-1') {
|
||||
return MediaAsset(
|
||||
metadata: _metadata(id),
|
||||
kind: MediaKind.video,
|
||||
localUri: imageFile.uri.toString(),
|
||||
);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
videoMediaBuilder: (context, asset) => SizedBox(
|
||||
height: 260,
|
||||
child: Center(child: Text('Lecteur vidéo ${asset.metadata.id}')),
|
||||
),
|
||||
),
|
||||
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();
|
||||
await tester.runAsync(() async {
|
||||
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);
|
||||
expect(
|
||||
find.byKey(const ValueKey('exercise-image-image-1')),
|
||||
findsOneWidget,
|
||||
);
|
||||
expect(find.text('Image 1'), findsNothing);
|
||||
|
||||
await tester.tap(find.text('Vidéo'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('Lecteur vidéo video-1'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('la galerie médias navigue entre les images', (tester) async {
|
||||
final imageFile = (await tester.runAsync(_createTestImageFile))!;
|
||||
addTearDown(() async {
|
||||
await tester.runAsync(() async {
|
||||
await imageFile.parent.delete(recursive: true);
|
||||
});
|
||||
});
|
||||
final clock = _FakeClock(DateTime.utc(2026, 7, 17, 12));
|
||||
final session = ActiveWorkoutSession(
|
||||
metadata: _metadata('session-1'),
|
||||
@ -214,31 +261,45 @@ void main() {
|
||||
),
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: WorkoutExecutionScreen(
|
||||
initialSession: session,
|
||||
activeUseCases: _activeUseCases(
|
||||
_FakeActiveSessionRepository(),
|
||||
clock,
|
||||
await tester.runAsync(() async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: WorkoutExecutionScreen(
|
||||
initialSession: session,
|
||||
activeUseCases: _activeUseCases(
|
||||
_FakeActiveSessionRepository(),
|
||||
clock,
|
||||
),
|
||||
closeUseCase: _closeUseCase(_FakeActiveSessionRepository(), clock),
|
||||
historyUseCases: _historyUseCases(clock),
|
||||
workoutTemplateUseCases: _workoutTemplateUseCases(),
|
||||
mediaAssetLoader: (id) async => MediaAsset(
|
||||
metadata: _metadata(id),
|
||||
kind: MediaKind.image,
|
||||
localUri: imageFile.uri.toString(),
|
||||
),
|
||||
),
|
||||
closeUseCase: _closeUseCase(_FakeActiveSessionRepository(), clock),
|
||||
historyUseCases: _historyUseCases(clock),
|
||||
workoutTemplateUseCases: _workoutTemplateUseCases(),
|
||||
),
|
||||
),
|
||||
);
|
||||
);
|
||||
});
|
||||
|
||||
await tester.tap(find.text('Voir médias'));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.runAsync(() async {
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
expect(find.text('1/3'), findsOneWidget);
|
||||
|
||||
await tester.drag(find.byType(PageView), const Offset(-400, 0));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.runAsync(() async {
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
expect(find.text('2/3'), findsOneWidget);
|
||||
expect(find.text('Image 2'), findsOneWidget);
|
||||
expect(
|
||||
find.byKey(const ValueKey('exercise-image-image-2')),
|
||||
findsOneWidget,
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('le chrono score démarre et s’arrête avec la bonne durée', (
|
||||
@ -282,6 +343,16 @@ void main() {
|
||||
|
||||
await tester.tap(find.text('Démarrer'));
|
||||
await tester.pump();
|
||||
clock.value = DateTime.utc(2026, 7, 17, 12, 0, 0, 100);
|
||||
await tester.pump(const Duration(milliseconds: 100));
|
||||
|
||||
expect(find.text('00:00.1'), findsOneWidget);
|
||||
|
||||
clock.value = DateTime.utc(2026, 7, 17, 12, 0, 0, 900);
|
||||
await tester.pump(const Duration(milliseconds: 100));
|
||||
|
||||
expect(find.text('00:00.9'), findsOneWidget);
|
||||
|
||||
clock.value = DateTime.utc(2026, 7, 17, 12, 0, 1, 200);
|
||||
await tester.pump(const Duration(seconds: 1));
|
||||
|
||||
@ -843,6 +914,16 @@ Finder _textFieldWithLabel(String label) {
|
||||
);
|
||||
}
|
||||
|
||||
Future<File> _createTestImageFile() async {
|
||||
final directory = await Directory.systemTemp.createTemp('gametime-media-');
|
||||
final file = File('${directory.path}/image.png');
|
||||
const transparentPng =
|
||||
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJ'
|
||||
'AAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==';
|
||||
await file.writeAsBytes(base64Decode(transparentPng));
|
||||
return file;
|
||||
}
|
||||
|
||||
ActiveWorkoutSessionUseCases _activeUseCases(
|
||||
_FakeActiveSessionRepository repository,
|
||||
_FakeClock clock,
|
||||
|
||||
Reference in New Issue
Block a user