chore(wip): lot #165-169 validé QA + rework foreground #163 (KO - preuve device/toolchain insuffisante)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -585,6 +585,104 @@ void main() {
|
||||
viewModel.dispose();
|
||||
});
|
||||
|
||||
testWidgets('shows reps target and direct completion on a reps-only step', (
|
||||
tester,
|
||||
) async {
|
||||
final client = _FakeNativeWatchBridgeClient();
|
||||
final viewModel = WatchSessionViewModel(nativeClient: client);
|
||||
|
||||
tester.view.devicePixelRatio = 1;
|
||||
tester.view.physicalSize = const Size(192, 192);
|
||||
addTearDown(tester.view.resetPhysicalSize);
|
||||
addTearDown(tester.view.resetDevicePixelRatio);
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: watchTheme(),
|
||||
home: WatchSessionScreen(viewModel: viewModel),
|
||||
),
|
||||
);
|
||||
|
||||
client.emitProjection(_repsStepProjection());
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 100));
|
||||
|
||||
expect(find.text('Répétitions'), findsOneWidget);
|
||||
expect(find.text('12'), findsOneWidget);
|
||||
expect(find.text('SÉRIE'), findsNothing);
|
||||
expect(find.text('Prêt pour la série suivante'), findsNothing);
|
||||
expect(find.byTooltip('Valider l’étape'), findsOneWidget);
|
||||
expect(tester.takeException(), isNull);
|
||||
|
||||
await tester.tap(find.byTooltip('Valider l’étape'));
|
||||
await tester.pump();
|
||||
|
||||
expect(
|
||||
client.sentCommands.single.type,
|
||||
WatchCommandType.completeCurrentStep,
|
||||
);
|
||||
|
||||
await tester.pumpWidget(const SizedBox.shrink());
|
||||
viewModel.dispose();
|
||||
});
|
||||
|
||||
testWidgets(
|
||||
'keeps optimistic score visible after timeout until explicit rejection',
|
||||
(tester) async {
|
||||
final client = _FakeNativeWatchBridgeClient();
|
||||
final viewModel = WatchSessionViewModel(
|
||||
nativeClient: client,
|
||||
waitingThreshold: const Duration(milliseconds: 50),
|
||||
commandTimeout: const Duration(milliseconds: 120),
|
||||
);
|
||||
|
||||
tester.view.devicePixelRatio = 1;
|
||||
tester.view.physicalSize = const Size(192, 192);
|
||||
addTearDown(tester.view.resetPhysicalSize);
|
||||
addTearDown(tester.view.resetDevicePixelRatio);
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: watchTheme(),
|
||||
home: WatchSessionScreen(viewModel: viewModel),
|
||||
),
|
||||
);
|
||||
|
||||
client.emitProjection(_manualScoreProjection());
|
||||
await tester.pump();
|
||||
|
||||
await tester.tap(find.byTooltip('Ajouter'));
|
||||
await tester.pump();
|
||||
|
||||
final commandId = client.sentCommands.single.commandId;
|
||||
expect(find.text('4'), findsOneWidget);
|
||||
|
||||
await tester.pump(const Duration(milliseconds: 150));
|
||||
|
||||
expect(find.text('4'), findsOneWidget);
|
||||
expect(find.byKey(const ValueKey('score-pending-dot')), findsOneWidget);
|
||||
expect(client.resyncRequests, greaterThanOrEqualTo(2));
|
||||
|
||||
client.emitProjection(_manualScoreProjection());
|
||||
await tester.pump();
|
||||
expect(find.text('4'), findsOneWidget);
|
||||
|
||||
client.emitAck(
|
||||
WatchCommandAckEvent(
|
||||
commandId: commandId,
|
||||
status: WatchCommandAck.rejectedNotApplicable,
|
||||
sessionId: 'session-1',
|
||||
),
|
||||
);
|
||||
await tester.pump();
|
||||
|
||||
expect(find.text('3'), findsOneWidget);
|
||||
|
||||
await tester.pumpWidget(const SizedBox.shrink());
|
||||
viewModel.dispose();
|
||||
},
|
||||
);
|
||||
|
||||
testWidgets('vibrates once when a countdown timer reaches zero', (
|
||||
tester,
|
||||
) async {
|
||||
@ -762,6 +860,26 @@ WatchSessionProjection _readyProjection() {
|
||||
);
|
||||
}
|
||||
|
||||
WatchSessionProjection _repsStepProjection() {
|
||||
return WatchSessionProjection(
|
||||
deviceSessionId: 'session-1',
|
||||
revision: 7,
|
||||
projectedAtEpochMs: DateTime.utc(2026, 7, 27, 10).millisecondsSinceEpoch,
|
||||
phase: WatchSessionPhase.running,
|
||||
phoneReachable: true,
|
||||
seriesIndex: 1,
|
||||
seriesTotal: 3,
|
||||
exerciseName: 'Pompes',
|
||||
stepIndex: 1,
|
||||
stepTotal: 2,
|
||||
stepName: 'Pompes strictes',
|
||||
stepType: WatchStepType.reps,
|
||||
stepTargetValue: 12,
|
||||
primaryAction: WatchPrimaryAction.pauseSession,
|
||||
secondaryActions: const [WatchSecondaryAction.skipCurrentStep],
|
||||
);
|
||||
}
|
||||
|
||||
WatchSessionProjection _secondaryRestActionProjection() {
|
||||
return WatchSessionProjection(
|
||||
deviceSessionId: 'session-1',
|
||||
|
||||
Reference in New Issue
Block a user