feat(bibliothèque): badge Exemple, catégories et états vides bibliothèque (ticket #80)
Ajoute le badge "Exemple" (example_badge.dart) affiché sur les exercices/programmes/séances-modèles seedés, le filtrage par catégorie dans la bibliothèque d'exercices et les états vides dédiés. Préserve isExample lors de l'édition d'un programme ou d'une séance-modèle existants (ProgramUseCases/WorkoutTemplateUseCases). Validé GO par Main : dart analyze propre, 173 tests (4 échecs préexistants sans rapport avec ce lot). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -54,6 +54,8 @@ void main() {
|
||||
defaultTargetTimeSeconds: 45,
|
||||
defaultTargetReps: 10,
|
||||
defaultTargetScore: 80,
|
||||
category: ExerciseCategory.finishing,
|
||||
isExample: true,
|
||||
);
|
||||
|
||||
await tester.pumpWidget(
|
||||
@ -67,6 +69,8 @@ void main() {
|
||||
expect(find.text('Temps'), findsOneWidget);
|
||||
expect(find.text('Répétitions'), findsOneWidget);
|
||||
expect(find.text('Score (kg)'), findsOneWidget);
|
||||
expect(find.text('Finition'), findsOneWidget);
|
||||
expect(find.text('Exemple'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('basculer en chrono intégré masque l’unité et affiche le badge', (
|
||||
|
||||
@ -5,6 +5,101 @@ import 'package:gametime/domain/domain.dart';
|
||||
import 'package:gametime/presentation/presentation.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('la liste affiche le badge exemple des programmes seedés', (
|
||||
tester,
|
||||
) async {
|
||||
final programRepository = _FakeProgramRepository()
|
||||
..programs.add(
|
||||
Program(
|
||||
metadata: _metadata('program-1'),
|
||||
name: 'Fondations basket - 45 min',
|
||||
defaultRestSeconds: 45,
|
||||
isExample: true,
|
||||
),
|
||||
);
|
||||
final exerciseRepository = _FakeExerciseRepository();
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: ProgramListScreen(
|
||||
programUseCases: _programUseCases(
|
||||
programRepository,
|
||||
exerciseRepository,
|
||||
),
|
||||
exerciseUseCases: _exerciseUseCases(exerciseRepository),
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pump();
|
||||
await tester.pump();
|
||||
|
||||
expect(find.text('Fondations basket - 45 min'), findsOneWidget);
|
||||
expect(find.text('Exemple'), findsOneWidget);
|
||||
expect(find.byTooltip('Supprimer le programme'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('la liste programmes vide conserve le message dédié', (
|
||||
tester,
|
||||
) async {
|
||||
final programRepository = _FakeProgramRepository();
|
||||
final exerciseRepository = _FakeExerciseRepository();
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: ProgramListScreen(
|
||||
programUseCases: _programUseCases(
|
||||
programRepository,
|
||||
exerciseRepository,
|
||||
),
|
||||
exerciseUseCases: _exerciseUseCases(exerciseRepository),
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pump();
|
||||
await tester.pump();
|
||||
|
||||
expect(find.text('Aucun programme'), findsOneWidget);
|
||||
expect(
|
||||
find.text('Assemble quelques exercices pour préparer une séance.'),
|
||||
findsOneWidget,
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('modifier un programme exemple conserve sa provenance', (
|
||||
tester,
|
||||
) async {
|
||||
final programRepository = _FakeProgramRepository()
|
||||
..programs.add(
|
||||
Program(
|
||||
metadata: _metadata('program-1'),
|
||||
name: 'Fondations basket - 45 min',
|
||||
defaultRestSeconds: 45,
|
||||
isExample: true,
|
||||
),
|
||||
);
|
||||
final exerciseRepository = _FakeExerciseRepository();
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: ProgramFormScreen(
|
||||
programUseCases: _programUseCases(
|
||||
programRepository,
|
||||
exerciseRepository,
|
||||
),
|
||||
exerciseUseCases: _exerciseUseCases(exerciseRepository),
|
||||
program: programRepository.programs.single,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.enterText(find.widgetWithText(TextFormField, 'Nom'), 'Edité');
|
||||
await tester.tap(find.text('Enregistrer'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(programRepository.programs.single.name, 'Edité');
|
||||
expect(programRepository.programs.single.isExample, isTrue);
|
||||
});
|
||||
|
||||
testWidgets(
|
||||
'ajoute un exercice au programme avec sa configuration par défaut',
|
||||
(tester) async {
|
||||
|
||||
@ -7,6 +7,165 @@ import 'package:gametime/domain/domain.dart';
|
||||
import 'package:gametime/presentation/presentation.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('la liste affiche le badge exemple des séances seedées', (
|
||||
tester,
|
||||
) async {
|
||||
final clock = _FakeClock(DateTime.utc(2026, 7, 17, 12));
|
||||
final templateRepository = _FakeWorkoutTemplateRepository([
|
||||
_workoutTemplate(isExample: true),
|
||||
]);
|
||||
final activeRepository = _FakeActiveSessionRepository();
|
||||
final programRepository = _FakeProgramRepository();
|
||||
final historyRepository = _FakeWorkoutHistoryRepository();
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: WorkoutTemplateListScreen(
|
||||
workoutTemplateUseCases: WorkoutTemplateUseCases(
|
||||
templateRepository: templateRepository,
|
||||
programRepository: programRepository,
|
||||
clock: clock,
|
||||
ids: _FakeIds(),
|
||||
originDeviceId: 'device-1',
|
||||
),
|
||||
programUseCases: ProgramUseCases(
|
||||
programRepository: programRepository,
|
||||
exerciseRepository: _FakeExerciseRepository(),
|
||||
templateRepository: templateRepository,
|
||||
clock: clock,
|
||||
ids: _FakeIds(),
|
||||
originDeviceId: 'device-1',
|
||||
),
|
||||
activeUseCases: ActiveWorkoutSessionUseCases(
|
||||
sessionRepository: activeRepository,
|
||||
templateRepository: templateRepository,
|
||||
clock: clock,
|
||||
ids: _FakeIds(),
|
||||
originDeviceId: 'device-1',
|
||||
),
|
||||
closeUseCase: CloseWorkoutSessionUseCase(
|
||||
sessionRepository: activeRepository,
|
||||
historyRepository: historyRepository,
|
||||
clock: clock,
|
||||
ids: _FakeIds(),
|
||||
originDeviceId: 'device-1',
|
||||
),
|
||||
historyUseCases: WorkoutHistoryUseCases(
|
||||
repository: historyRepository,
|
||||
clock: clock,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pump();
|
||||
await tester.pump();
|
||||
|
||||
expect(find.text('Séance jambes'), findsOneWidget);
|
||||
expect(find.text('Exemple'), findsOneWidget);
|
||||
expect(find.byTooltip('Supprimer la séance'), findsOneWidget);
|
||||
expect(find.text('Lancer'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('la liste séances vide conserve le message dédié', (
|
||||
tester,
|
||||
) async {
|
||||
final clock = _FakeClock(DateTime.utc(2026, 7, 17, 12));
|
||||
final templateRepository = _FakeWorkoutTemplateRepository(const []);
|
||||
final activeRepository = _FakeActiveSessionRepository();
|
||||
final programRepository = _FakeProgramRepository();
|
||||
final historyRepository = _FakeWorkoutHistoryRepository();
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: WorkoutTemplateListScreen(
|
||||
workoutTemplateUseCases: WorkoutTemplateUseCases(
|
||||
templateRepository: templateRepository,
|
||||
programRepository: programRepository,
|
||||
clock: clock,
|
||||
ids: _FakeIds(),
|
||||
originDeviceId: 'device-1',
|
||||
),
|
||||
programUseCases: ProgramUseCases(
|
||||
programRepository: programRepository,
|
||||
exerciseRepository: _FakeExerciseRepository(),
|
||||
templateRepository: templateRepository,
|
||||
clock: clock,
|
||||
ids: _FakeIds(),
|
||||
originDeviceId: 'device-1',
|
||||
),
|
||||
activeUseCases: ActiveWorkoutSessionUseCases(
|
||||
sessionRepository: activeRepository,
|
||||
templateRepository: templateRepository,
|
||||
clock: clock,
|
||||
ids: _FakeIds(),
|
||||
originDeviceId: 'device-1',
|
||||
),
|
||||
closeUseCase: CloseWorkoutSessionUseCase(
|
||||
sessionRepository: activeRepository,
|
||||
historyRepository: historyRepository,
|
||||
clock: clock,
|
||||
ids: _FakeIds(),
|
||||
originDeviceId: 'device-1',
|
||||
),
|
||||
historyUseCases: WorkoutHistoryUseCases(
|
||||
repository: historyRepository,
|
||||
clock: clock,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pump();
|
||||
await tester.pump();
|
||||
|
||||
expect(find.text('Aucune séance'), findsOneWidget);
|
||||
expect(
|
||||
find.text(
|
||||
'Crée une séance-modèle pour lancer ton entraînement plus vite.',
|
||||
),
|
||||
findsOneWidget,
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('modifier une séance exemple conserve sa provenance', (
|
||||
tester,
|
||||
) async {
|
||||
final clock = _FakeClock(DateTime.utc(2026, 7, 17, 12));
|
||||
final templateRepository = _FakeWorkoutTemplateRepository([
|
||||
_workoutTemplate(isExample: true),
|
||||
]);
|
||||
final programRepository = _FakeProgramRepository();
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: WorkoutTemplateFormScreen(
|
||||
workoutTemplateUseCases: WorkoutTemplateUseCases(
|
||||
templateRepository: templateRepository,
|
||||
programRepository: programRepository,
|
||||
clock: clock,
|
||||
ids: _FakeIds(),
|
||||
originDeviceId: 'device-1',
|
||||
),
|
||||
programUseCases: ProgramUseCases(
|
||||
programRepository: programRepository,
|
||||
exerciseRepository: _FakeExerciseRepository(),
|
||||
templateRepository: templateRepository,
|
||||
clock: clock,
|
||||
ids: _FakeIds(),
|
||||
originDeviceId: 'device-1',
|
||||
),
|
||||
template: templateRepository.templates.single,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
await tester.enterText(find.widgetWithText(TextFormField, 'Nom'), 'Editée');
|
||||
await tester.tap(find.text('Enregistrer'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(templateRepository.templates.single.name, 'Editée');
|
||||
expect(templateRepository.templates.single.isExample, isTrue);
|
||||
});
|
||||
|
||||
testWidgets(
|
||||
'la vue programme de séance ne permet pas de changer les mesures actives',
|
||||
(tester) async {
|
||||
@ -352,10 +511,11 @@ void main() {
|
||||
});
|
||||
}
|
||||
|
||||
WorkoutTemplate _workoutTemplate() {
|
||||
WorkoutTemplate _workoutTemplate({bool isExample = false}) {
|
||||
return WorkoutTemplate(
|
||||
metadata: _metadata('template-1'),
|
||||
name: 'Séance jambes',
|
||||
isExample: isExample,
|
||||
programs: [
|
||||
WorkoutTemplateProgram(
|
||||
metadata: _metadata('template-program-1'),
|
||||
|
||||
Reference in New Issue
Block a user