feat(application): couche application avec use cases et repositories
Ajoute les entités du domaine (domain/entities.dart), les ports de repository (application/ports.dart), les use cases (application/use_cases.dart) et leur implémentation Drift (infrastructure/local/drift_repositories.dart). flutter analyze propre, tests unitaires verts, build APK debug validé. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
117
test/application/use_cases_test.dart
Normal file
117
test/application/use_cases_test.dart
Normal file
@ -0,0 +1,117 @@
|
||||
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<void> save(Program program) async {}
|
||||
|
||||
@override
|
||||
Future<void> saveExercise(ProgramExercise exercise) async {}
|
||||
}
|
||||
Reference in New Issue
Block a user