import 'package:drift/native.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:motorcycle_dash/database/database.dart'; import 'package:motorcycle_dash/features/history/ride_detail_screen.dart'; import 'package:motorcycle_dash/services/github/github_sync_service.dart'; class _FakeGitHubSyncService extends ChangeNotifier implements GitHubSyncService { @override GitHubUploadState get state => GitHubUploadState.idle; @override String get statusMessage => ''; @override Set get queuedRideIds => const {}; @override bool isRideUploaded(int rideId) => false; @override String? getRideCommitSha(int rideId) => null; @override dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); } void main() { TestWidgetsFlutterBinding.ensureInitialized(); late AppDatabase db; setUp(() { db = AppDatabase.forTesting(NativeDatabase.memory()); }); tearDown(() async { await db.close(); }); Ride makeTestRide() { return Ride( id: 1, startTime: DateTime(2026, 1, 1, 10, 0), endTime: DateTime(2026, 1, 1, 10, 45), distanceMiles: 25.5, topSpeedMph: 65.0, movingTime: 2400, stoppedTime: 300, distance: 25.5, topSpeed: 65.0, averageSpeed: 42.0, elevationGain: 350.0, elevationLoss: 300.0, maxLeanLeft: 34.0, maxLeanRight: 36.0, maxAccelG: 0.75, maxBrakingG: 0.85, ); } testWidgets('renders on narrow 320px screen without overflow', (tester) async { tester.view.physicalSize = const Size(320, 800); tester.view.devicePixelRatio = 1.0; addTearDown(() => tester.view.resetPhysicalSize()); final ride = makeTestRide(); await tester.pumpWidget( ProviderScope( overrides: [ databaseProvider.overrideWithValue(db), githubSyncServiceProvider.overrideWith((ref) => _FakeGitHubSyncService()), ], child: MaterialApp( home: RideDetailScreen( ride: ride, ), ), ), ); await tester.pumpAndSettle(); expect(tester.takeException(), isNull); expect(find.text('REPLAY RIDE'), findsOneWidget); expect(find.text('EXPORT GPX'), findsOneWidget); expect(find.text('EXPORT CSV'), findsOneWidget); }); testWidgets('renders on standard 360px screen without overflow', (tester) async { tester.view.physicalSize = const Size(360, 800); tester.view.devicePixelRatio = 1.0; addTearDown(() => tester.view.resetPhysicalSize()); final ride = makeTestRide(); await tester.pumpWidget( ProviderScope( overrides: [ databaseProvider.overrideWithValue(db), githubSyncServiceProvider.overrideWith((ref) => _FakeGitHubSyncService()), ], child: MaterialApp( home: RideDetailScreen( ride: ride, ), ), ), ); await tester.pumpAndSettle(); expect(tester.takeException(), isNull); expect(find.text('REPLAY RIDE'), findsOneWidget); expect(find.text('EXPORT GPX'), findsOneWidget); expect(find.text('EXPORT CSV'), findsOneWidget); }); testWidgets('renders on landscape 800x360 screen without overflow', (tester) async { tester.view.physicalSize = const Size(800, 360); tester.view.devicePixelRatio = 1.0; addTearDown(() => tester.view.resetPhysicalSize()); final ride = makeTestRide(); await tester.pumpWidget( ProviderScope( overrides: [ databaseProvider.overrideWithValue(db), githubSyncServiceProvider.overrideWith((ref) => _FakeGitHubSyncService()), ], child: MaterialApp( home: RideDetailScreen( ride: ride, ), ), ), ); await tester.pumpAndSettle(); expect(tester.takeException(), isNull); expect(find.text('REPLAY RIDE'), findsOneWidget); expect(find.text('EXPORT GPX'), findsOneWidget); expect(find.text('EXPORT CSV'), findsOneWidget); }); }