Files
GameTime/test/presentation/program_screen_test.dart
Blomios bf1134d4ff feat(ui): programme simplifié en cartes compactes (ticket #20)
Simplifie l'affichage du programme sur program_screen.dart avec des
cartes compactes. flutter analyze propre, 30/30 tests verts, build APK
debug validé.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 00:24:29 +02:00

213 lines
5.7 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:gametime/application/application.dart';
import 'package:gametime/domain/domain.dart';
import 'package:gametime/presentation/presentation.dart';
void main() {
testWidgets(
'ajoute un exercice au programme avec sa configuration par défaut',
(tester) async {
final programRepository = _FakeProgramRepository();
final exerciseRepository = _FakeExerciseRepository()
..exercises.add(
Exercise(
metadata: _metadata('exercise-1'),
name: 'Squat',
hasTimeMeasure: true,
hasRepsMeasure: true,
hasScoreMeasure: false,
),
);
await tester.pumpWidget(
MaterialApp(
home: ProgramFormScreen(
programUseCases: _programUseCases(
programRepository,
exerciseRepository,
),
exerciseUseCases: _exerciseUseCases(exerciseRepository),
),
),
);
await tester.enterText(
find.widgetWithText(TextFormField, 'Nom'),
'Jambes',
);
await tester.tap(find.text('Ajouter un exercice'));
await tester.pumpAndSettle();
await tester.tap(find.text('Squat'));
await tester.pumpAndSettle();
expect(find.text('Squat'), findsOneWidget);
expect(find.text('Repos 60 s'), findsOneWidget);
expect(find.text('Exercice ajouté'), findsOneWidget);
expect(find.byTooltip("Personnaliser l'exercice"), findsOneWidget);
expect(find.byType(CheckboxListTile), findsNothing);
await tester.tap(find.text('Enregistrer'));
await tester.pumpAndSettle();
final savedExercise = programRepository.programs.single.exercises.single;
expect(savedExercise.setsCount, 3);
expect(savedExercise.timeEnabled, isTrue);
expect(savedExercise.repsEnabled, isTrue);
expect(savedExercise.scoreEnabled, isFalse);
expect(savedExercise.restSecondsOverride, 60);
},
);
testWidgets(
'limite les mesures aux mesures autorisées par lexercice source',
(tester) async {
final exerciseRepository = _FakeExerciseRepository()
..exercises.add(
Exercise(
metadata: _metadata('exercise-1'),
name: 'Pompes',
hasTimeMeasure: false,
hasRepsMeasure: true,
hasScoreMeasure: false,
),
);
await tester.pumpWidget(
MaterialApp(
home: ProgramFormScreen(
programUseCases: _programUseCases(
_FakeProgramRepository(),
exerciseRepository,
),
exerciseUseCases: _exerciseUseCases(exerciseRepository),
),
),
);
await tester.tap(find.text('Ajouter un exercice'));
await tester.pumpAndSettle();
await tester.tap(find.text('Pompes'));
await tester.pumpAndSettle();
await tester.tap(find.byTooltip("Personnaliser l'exercice"));
await tester.pumpAndSettle();
expect(find.text("Personnaliser l'exercice"), findsOneWidget);
expect(
find.widgetWithText(SwitchListTile, 'Répétitions'),
findsOneWidget,
);
expect(find.widgetWithText(SwitchListTile, 'Temps'), findsNothing);
expect(find.widgetWithText(SwitchListTile, 'Score'), findsNothing);
},
);
}
ExerciseUseCases _exerciseUseCases(_FakeExerciseRepository repository) {
return ExerciseUseCases(
repository: repository,
clock: _FakeClock(DateTime.utc(2026, 7, 17, 12)),
ids: _FakeIds(),
originDeviceId: 'device-1',
);
}
ProgramUseCases _programUseCases(
_FakeProgramRepository programRepository,
_FakeExerciseRepository exerciseRepository,
) {
return ProgramUseCases(
programRepository: programRepository,
exerciseRepository: exerciseRepository,
clock: _FakeClock(DateTime.utc(2026, 7, 17, 12)),
ids: _FakeIds(),
originDeviceId: 'device-1',
);
}
EntityMetadata _metadata(String id) {
return EntityMetadata(
id: id,
createdAt: DateTime.utc(2026, 7, 17),
updatedAt: DateTime.utc(2026, 7, 17),
originDeviceId: 'device-1',
);
}
final class _FakeClock implements Clock {
const _FakeClock(this.value);
final DateTime value;
@override
DateTime now() => value;
}
final class _FakeIds implements IdGenerator {
var _next = 0;
@override
String newId() {
_next += 1;
return 'id-$_next';
}
}
final class _FakeExerciseRepository implements ExerciseRepository {
final exercises = <Exercise>[];
final saved = <Exercise>[];
@override
Future<Exercise?> findById(String id) async {
for (final exercise in exercises) {
if (exercise.metadata.id == id) {
return exercise;
}
}
return null;
}
@override
Future<bool> isReferencedByProgram(String id) async => false;
@override
Future<List<Exercise>> listActive() async => exercises;
@override
Future<void> save(Exercise exercise) async {
saved.add(exercise);
}
}
final class _FakeProgramRepository implements ProgramRepository {
final programs = <Program>[];
@override
Future<Program?> findById(String id) async {
for (final program in programs) {
if (program.metadata.id == id) {
return program;
}
}
return null;
}
@override
Future<List<Program>> listActive() async => programs;
@override
Future<void> replaceExercises(Program program, DateTime deletedAt) async {
programs.removeWhere((item) => item.metadata.id == program.metadata.id);
programs.add(program);
}
@override
Future<void> save(Program program) async {
programs.add(program);
}
@override
Future<void> saveExercise(ProgramExercise exercise) async {}
}