128 lines
4.1 KiB
Dart
128 lines
4.1 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:motorcycle_dash/features/dashboard/widgets/lean_angle_indicator.dart';
|
|
import 'package:motorcycle_dash/features/rides/ride_state_machine.dart';
|
|
import 'package:motorcycle_dash/models/telemetry_sample.dart';
|
|
import 'package:motorcycle_dash/services/telemetry_service.dart';
|
|
import 'package:motorcycle_dash/services/sensor_fusion_service.dart';
|
|
import 'package:motorcycle_dash/services/calibration_service.dart';
|
|
|
|
void main() {
|
|
testWidgets('LeanAngleIndicator tap while moving (> 3.0 MPH) blocks calibration with warning', (tester) async {
|
|
final sample = TelemetrySample(
|
|
timestamp: DateTime.now(),
|
|
leanAngle: 12.0,
|
|
speed: 25.0, // Moving at 25 MPH
|
|
);
|
|
|
|
await tester.pumpWidget(
|
|
ProviderScope(
|
|
overrides: [
|
|
telemetryStreamProvider.overrideWith(
|
|
(ref) => Stream.value(sample),
|
|
),
|
|
rideStateMachineProvider.overrideWith(
|
|
(ref) => MockRideStateMachine(
|
|
RideSession(state: RideState.riding),
|
|
),
|
|
),
|
|
],
|
|
child: const MaterialApp(
|
|
home: Scaffold(
|
|
body: Center(
|
|
child: LeanAngleIndicator(),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
await tester.pumpAndSettle();
|
|
|
|
// Verify indicator rendered
|
|
expect(find.byKey(const ValueKey('lean_angle_indicator_tap')), findsOneWidget);
|
|
|
|
// Tap on the indicator
|
|
await tester.tap(find.byKey(const ValueKey('lean_angle_indicator_tap')));
|
|
await tester.pump();
|
|
|
|
// Verify warning snackbar is shown
|
|
expect(find.byKey(const ValueKey('lean_calibrate_moving_warning')), findsOneWidget);
|
|
expect(find.textContaining('Cannot calibrate while moving (> 3.0 MPH)'), findsOneWidget);
|
|
|
|
// Calibration dialog must NOT appear
|
|
expect(find.byKey(const ValueKey('lean_calibrate_dialog')), findsNothing);
|
|
});
|
|
|
|
testWidgets('LeanAngleIndicator tap while stationary (< 3.0 MPH) prompts confirmation and calibrates upright', (tester) async {
|
|
final sample = TelemetrySample(
|
|
timestamp: DateTime.now(),
|
|
leanAngle: 0.0,
|
|
speed: 0.0, // Stationary
|
|
);
|
|
|
|
var calibrated = false;
|
|
|
|
await tester.pumpWidget(
|
|
ProviderScope(
|
|
overrides: [
|
|
telemetryStreamProvider.overrideWith(
|
|
(ref) => Stream.value(sample),
|
|
),
|
|
rideStateMachineProvider.overrideWith(
|
|
(ref) => MockRideStateMachine(
|
|
RideSession(state: RideState.idle),
|
|
),
|
|
),
|
|
sensorFusionServiceProvider.overrideWith((ref) => SensorFusionServiceMock(() {
|
|
calibrated = true;
|
|
})),
|
|
],
|
|
child: const MaterialApp(
|
|
home: Scaffold(
|
|
body: Center(
|
|
child: LeanAngleIndicator(),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
await tester.pumpAndSettle();
|
|
|
|
// Tap on indicator
|
|
await tester.tap(find.byKey(const ValueKey('lean_angle_indicator_tap')));
|
|
await tester.pumpAndSettle();
|
|
|
|
// Verify dialog appears
|
|
expect(find.byKey(const ValueKey('lean_calibrate_dialog')), findsOneWidget);
|
|
expect(find.byKey(const ValueKey('confirm_lean_calibrate_button')), findsOneWidget);
|
|
|
|
// Confirm calibration
|
|
await tester.tap(find.byKey(const ValueKey('confirm_lean_calibrate_button')));
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(calibrated, isTrue, reason: 'Must invoke calibrateUpright() on SensorFusionService');
|
|
expect(find.byKey(const ValueKey('lean_calibrate_success_snackbar')), findsOneWidget);
|
|
});
|
|
}
|
|
|
|
class MockRideStateMachine extends StateNotifier<RideSession> implements RideStateMachine {
|
|
MockRideStateMachine(super.initialState);
|
|
|
|
@override
|
|
dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
|
|
}
|
|
|
|
class SensorFusionServiceMock extends SensorFusionService {
|
|
final VoidCallback onCalibrate;
|
|
|
|
SensorFusionServiceMock(this.onCalibrate) : super(CalibrationService());
|
|
|
|
@override
|
|
Future<void> calibrateUpright({int? motorcycleId}) async {
|
|
onCalibrate();
|
|
}
|
|
}
|