Files
GameTime/test/application/use_cases_test.dart
Blomios 1ae6248fb4 feat(ui): écran Création/édition de programme
Ajoute l'écran de programme (presentation/program_screen.dart) et un
écran d'accueil (presentation/home_screen.dart) pour la navigation,
avec les ajustements application/domaine/repositories nécessaires.
flutter analyze propre, 11/11 tests verts, build APK debug validé.

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

124 lines
3.3 KiB
Dart

import 'package:flutter_test/flutter_test.dart';
import 'package:gametime/application/application.dart';
import 'package:gametime/domain/domain.dart';
void main() {
test('Exercise requires at least one active measure', () {
expect(
() => Exercise(
metadata: _metadata('exercise-1'),
name: 'Push up',
hasTimeMeasure: false,
hasRepsMeasure: false,
hasScoreMeasure: false,
),
throwsA(isA<DomainException>()),
);
});
test('Workout template use case rejects active measure overrides', () async {
final useCase = WorkoutTemplateUseCases(
templateRepository: _FakeWorkoutTemplateRepository(),
programRepository: _FakeProgramRepository(),
clock: _FakeClock(DateTime.utc(2026, 7, 17, 12)),
ids: _FakeIds(),
originDeviceId: 'device-1',
);
await expectLater(
useCase.overrideExerciseTargets(
workoutTemplateProgramId: 'template-program-1',
snapshotProgramExerciseId: 'exercise-snapshot-1',
attemptedMeasureOverride: {WorkoutMeasure.reps},
),
throwsA(isA<DomainException>()),
);
});
test('Active session elapsed time is based on persisted timestamps', () {
final clock = _FakeClock(DateTime.utc(2026, 7, 17, 12));
final session = ActiveWorkoutSession(
metadata: _metadata('session-1'),
status: ActiveWorkoutStatus.running,
startedAt: clock.now(),
lastPersistedAt: clock.now(),
elapsedActiveMs: 0,
currentProgramIndex: 0,
currentExerciseIndex: 0,
currentSetIndex: 0,
resolvedTemplateSnapshotJson: '{}',
);
clock.value = clock.value.add(const Duration(seconds: 30));
final paused = session.pause(clock.now());
expect(paused.elapsedActiveMs, 30000);
clock.value = clock.value.add(const Duration(minutes: 5));
final resumed = paused.resume(clock.now());
expect(resumed.elapsedActiveMillisecondsAt(clock.now()), 30000);
clock.value = clock.value.add(const Duration(seconds: 15));
expect(resumed.elapsedActiveMillisecondsAt(clock.now()), 45000);
});
}
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 {
_FakeClock(this.value);
DateTime value;
@override
DateTime now() => value;
}
final class _FakeIds implements IdGenerator {
var _next = 0;
@override
String newId() {
_next += 1;
return 'id-$_next';
}
}
final class _FakeWorkoutTemplateRepository
implements WorkoutTemplateRepository {
@override
Future<WorkoutTemplate?> findById(String id) async => null;
@override
Future<void> save(WorkoutTemplate template) async {}
@override
Future<void> saveOverride(WorkoutTemplateExerciseOverride override) async {}
@override
Future<void> saveProgram(WorkoutTemplateProgram program) async {}
}
final class _FakeProgramRepository implements ProgramRepository {
@override
Future<Program?> findById(String id) async => null;
@override
Future<List<Program>> listActive() async => const [];
@override
Future<void> replaceExercises(Program program, DateTime deletedAt) async {}
@override
Future<void> save(Program program) async {}
@override
Future<void> saveExercise(ProgramExercise exercise) async {}
}