feat(exercice): modèle et migration pour l'auto-enchaînement des chronos d'étapes (ticket #75)
Étend le modèle Drift (migration schemaVersion 13→14, ADD COLUMN) et la couche application (entités, use cases, repositories) pour supporter l'auto-enchaînement des chronos d'étapes. flutter pub get OK, build_runner OK, analyze propre (mêmes infos préexistantes), 141/141 tests verts, build APK debug validé. Premier ticket du chantier "auto-enchaînement des chronos d'étapes" (#73). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -98,6 +98,100 @@ void main() {
|
||||
expect(restored!.defaultTargetScore, 0);
|
||||
});
|
||||
|
||||
test('step chaining settings round-trip through drift repositories', () async {
|
||||
final now = DateTime.utc(2026, 7, 17, 12);
|
||||
final exercise = Exercise(
|
||||
metadata: _metadata('exercise-chain-1', now),
|
||||
name: 'Circuit',
|
||||
hasTimeMeasure: false,
|
||||
hasRepsMeasure: true,
|
||||
hasScoreMeasure: false,
|
||||
defaultTargetReps: 10,
|
||||
autoStartNextTimedStep: false,
|
||||
);
|
||||
await exerciseRepository.save(exercise);
|
||||
|
||||
final restoredExercise = await exerciseRepository.findById(
|
||||
exercise.metadata.id,
|
||||
);
|
||||
expect(restoredExercise!.autoStartNextTimedStep, isFalse);
|
||||
|
||||
final programExercise = _programExercise(
|
||||
'program-exercise-chain-1',
|
||||
now,
|
||||
programId: 'program-chain-1',
|
||||
position: 0,
|
||||
autoStartNextTimedStepSnapshot: false,
|
||||
autoStartNextTimedStepOverride: true,
|
||||
);
|
||||
await programRepository.save(
|
||||
Program(
|
||||
metadata: _metadata('program-chain-1', now),
|
||||
name: 'Programme',
|
||||
defaultRestSeconds: 60,
|
||||
exercises: [programExercise],
|
||||
),
|
||||
);
|
||||
|
||||
final restoredProgram = await programRepository.findById('program-chain-1');
|
||||
expect(
|
||||
restoredProgram!.exercises.single.autoStartNextTimedStepSnapshot,
|
||||
isFalse,
|
||||
);
|
||||
expect(
|
||||
restoredProgram.exercises.single.autoStartNextTimedStepOverride,
|
||||
isTrue,
|
||||
);
|
||||
|
||||
final templateProgram = WorkoutTemplateProgram(
|
||||
metadata: _metadata('template-program-chain-1', now),
|
||||
workoutTemplateId: 'template-chain-1',
|
||||
sourceProgramId: 'program-chain-1',
|
||||
position: 0,
|
||||
programNameSnapshot: 'Programme',
|
||||
defaultRestSecondsSnapshot: 60,
|
||||
programSnapshotJson: jsonEncode({
|
||||
'exercises': [programExercise.toSnapshotJson()],
|
||||
}),
|
||||
);
|
||||
await templateRepository.save(
|
||||
WorkoutTemplate(
|
||||
metadata: _metadata('template-chain-1', now),
|
||||
name: 'Séance',
|
||||
programs: [templateProgram],
|
||||
overrides: [
|
||||
WorkoutTemplateExerciseOverride(
|
||||
metadata: _metadata('override-chain-1', now),
|
||||
workoutTemplateProgramId: templateProgram.metadata.id,
|
||||
snapshotProgramExerciseId: programExercise.metadata.id,
|
||||
),
|
||||
WorkoutTemplateExerciseOverride(
|
||||
metadata: _metadata('override-chain-2', now),
|
||||
workoutTemplateProgramId: templateProgram.metadata.id,
|
||||
snapshotProgramExerciseId: 'program-exercise-chain-2',
|
||||
autoStartNextTimedStepOverride: false,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
final restoredTemplate = await templateRepository.findById(
|
||||
'template-chain-1',
|
||||
);
|
||||
expect(
|
||||
restoredTemplate!.overrides
|
||||
.singleWhere((override) => override.metadata.id == 'override-chain-1')
|
||||
.autoStartNextTimedStepOverride,
|
||||
isNull,
|
||||
);
|
||||
expect(
|
||||
restoredTemplate.overrides
|
||||
.singleWhere((override) => override.metadata.id == 'override-chain-2')
|
||||
.autoStartNextTimedStepOverride,
|
||||
isFalse,
|
||||
);
|
||||
});
|
||||
|
||||
test('exercise repository round-trips configured steps', () async {
|
||||
final now = DateTime.utc(2026, 7, 17, 12);
|
||||
final exercise = Exercise(
|
||||
@ -453,13 +547,18 @@ EntityMetadata _metadata(String id, DateTime now, [int localRevision = 0]) {
|
||||
ProgramExercise _programExercise(
|
||||
String id,
|
||||
DateTime now, {
|
||||
String programId = 'program-1',
|
||||
required int position,
|
||||
bool autoStartNextTimedStepSnapshot = true,
|
||||
bool? autoStartNextTimedStepOverride,
|
||||
}) {
|
||||
return ProgramExercise(
|
||||
metadata: _metadata(id, now),
|
||||
programId: 'program-1',
|
||||
programId: programId,
|
||||
position: position,
|
||||
exerciseNameSnapshot: 'Exercise $position',
|
||||
autoStartNextTimedStepSnapshot: autoStartNextTimedStepSnapshot,
|
||||
autoStartNextTimedStepOverride: autoStartNextTimedStepOverride,
|
||||
availableTimeSnapshot: false,
|
||||
availableRepsSnapshot: true,
|
||||
availableScoreSnapshot: false,
|
||||
|
||||
Reference in New Issue
Block a user