127 lines
4.1 KiB
Dart
127 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/models/telemetry_sample.dart';
|
|
import 'package:motorcycle_dash/features/rides/ride_state_machine.dart';
|
|
import 'package:motorcycle_dash/features/dashboard/widgets/evolution_portrait_dashboard.dart';
|
|
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
import 'package:motorcycle_dash/features/records/records_service.dart';
|
|
|
|
void main() {
|
|
TestWidgetsFlutterBinding.ensureInitialized();
|
|
late SharedPreferences prefs;
|
|
|
|
setUp(() async {
|
|
SharedPreferences.setMockInitialValues({});
|
|
prefs = await SharedPreferences.getInstance();
|
|
});
|
|
|
|
Widget buildDashboard({TelemetrySample? telemetry, RideSession? session}) {
|
|
return ProviderScope(
|
|
overrides: [
|
|
sharedPreferencesProvider.overrideWithValue(prefs),
|
|
],
|
|
child: MaterialApp(
|
|
home: Scaffold(
|
|
body: EvolutionPortraitDashboard(
|
|
currentSpeedMph: 45.0,
|
|
heading: 180.0,
|
|
leanAngle: 12.0,
|
|
accelG: 0.2,
|
|
lateralG: 0.1,
|
|
session: session ?? RideSession(
|
|
state: RideState.riding,
|
|
startTime: DateTime.now(),
|
|
tripDistanceMiles: 3.5,
|
|
topSpeedMph: 55.0,
|
|
averageSpeedMph: 42.0,
|
|
maxLeanLeft: 22.0,
|
|
maxLeanRight: 25.0,
|
|
maxAccelG: 0.6,
|
|
maxBrakingG: 0.8,
|
|
),
|
|
telemetry: telemetry,
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
testWidgets('displays GPS LOCKED when accuracy <= 15m and no fake placeholders', (tester) async {
|
|
final sample = TelemetrySample(
|
|
timestamp: DateTime.now(),
|
|
gpsAccuracy: 8.5,
|
|
);
|
|
|
|
await tester.pumpWidget(buildDashboard(telemetry: sample));
|
|
await tester.pump();
|
|
|
|
// Truthful GPS
|
|
expect(find.text('GPS LOCKED'), findsOneWidget);
|
|
|
|
// Placeholders removed
|
|
expect(find.text('FIXED'), findsNothing);
|
|
expect(find.text('HEADSET'), findsNothing);
|
|
expect(find.text('92%'), findsNothing);
|
|
|
|
// RID-3C-2: the visible badge is a health CLAIM, not a RideState claim. This
|
|
// fixture builds RideSession(state: riding) with the DEFAULT
|
|
// healthStatus: recordingArmed and no health evidence, so the truthful label
|
|
// is WARMING UP. RideState.riding alone is never sufficient for RECORDING.
|
|
// The Stop action remains available throughout - see U2/U9 in
|
|
// test/rid3c2_truthful_recording_ui_test.dart.
|
|
expect(find.text('WARMING UP'), findsOneWidget);
|
|
expect(find.text('RECORDING'), findsNothing);
|
|
});
|
|
|
|
testWidgets('displays GPS FAIR when accuracy is 25m', (tester) async {
|
|
final sample = TelemetrySample(
|
|
timestamp: DateTime.now(),
|
|
gpsAccuracy: 25.0,
|
|
);
|
|
|
|
await tester.pumpWidget(buildDashboard(telemetry: sample));
|
|
await tester.pump();
|
|
|
|
expect(find.text('GPS FAIR'), findsOneWidget);
|
|
expect(find.text('HEADSET'), findsNothing);
|
|
expect(find.text('92%'), findsNothing);
|
|
});
|
|
|
|
testWidgets('displays GPS WEAK when accuracy is 50m', (tester) async {
|
|
final sample = TelemetrySample(
|
|
timestamp: DateTime.now(),
|
|
gpsAccuracy: 50.0,
|
|
);
|
|
|
|
await tester.pumpWidget(buildDashboard(telemetry: sample));
|
|
await tester.pump();
|
|
|
|
expect(find.text('GPS WEAK'), findsOneWidget);
|
|
expect(find.text('HEADSET'), findsNothing);
|
|
});
|
|
|
|
testWidgets('displays GPS STALE when accuracy exists but fix is older than staleness bound', (tester) async {
|
|
final sample = TelemetrySample(
|
|
timestamp: DateTime.now(),
|
|
gpsAccuracy: 8.5,
|
|
gpsAgeMs: 5000,
|
|
);
|
|
|
|
await tester.pumpWidget(buildDashboard(telemetry: sample));
|
|
await tester.pump();
|
|
|
|
expect(find.text('GPS STALE'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('displays NO GPS when telemetry is null', (tester) async {
|
|
await tester.pumpWidget(buildDashboard(telemetry: null));
|
|
await tester.pump();
|
|
|
|
expect(find.text('NO GPS'), findsOneWidget);
|
|
expect(find.text('HEADSET'), findsNothing);
|
|
expect(find.text('92%'), findsNothing);
|
|
});
|
|
}
|