MotorSignal-App/test/evolution_dashboard_truthfu...

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);
});
}