import 'package:flutter_test/flutter_test.dart'; import 'package:motorcycle_dash/services/group_rides/group_ride_models.dart'; import 'package:motorcycle_dash/services/group_rides/group_ride_service.dart'; import 'package:motorcycle_dash/services/social/rider_profile_models.dart'; void main() { group('GroupRideService Offline & Validation Tests', () { final organizer = RiderProfile( uid: 'user_alice', handle: 'alice_apex', displayName: 'Alice Apex', createdAt: DateTime.now(), updatedAt: DateTime.now(), ); test('rejects ride creation with invalid title', () async { final service = GroupRideService(); const meetup = GroupRideLocation( latitude: 34.0, longitude: -84.0, displayName: 'Meetup', ); expect( () => service.createGroupRide( organizer: organizer, title: 'Hi', // too short (< 3) scheduledStartAt: DateTime.now(), departureAt: DateTime.now().add(const Duration(minutes: 30)), meetingPoint: meetup, ), throwsA(isA()), ); }); test('rejects departure before arrival time', () async { final service = GroupRideService(); const meetup = GroupRideLocation( latitude: 34.0, longitude: -84.0, displayName: 'Meetup', ); final now = DateTime.now(); expect( () => service.createGroupRide( organizer: organizer, title: 'Morning Cruise', scheduledStartAt: now.add(const Duration(hours: 2)), departureAt: now.add(const Duration(hours: 1)), // earlier! meetingPoint: meetup, ), throwsA(isA()), ); }); test('rejects participant limit less than 2', () async { final service = GroupRideService(); const meetup = GroupRideLocation( latitude: 34.0, longitude: -84.0, displayName: 'Meetup', ); final now = DateTime.now(); expect( () => service.createGroupRide( organizer: organizer, title: 'Solo Ride', scheduledStartAt: now, departureAt: now.add(const Duration(minutes: 30)), participantLimit: 1, // Invalid! meetingPoint: meetup, ), throwsA(isA()), ); }); test('creates offline fallback ride safely when unconfigured', () async { final service = GroupRideService(); const meetup = GroupRideLocation( latitude: 34.5, longitude: -83.9, displayName: 'Dahlonega', ); final start = DateTime.now().add(const Duration(days: 1)); final dep = start.add(const Duration(minutes: 30)); final ride = await service.createGroupRide( organizer: organizer, title: 'Sunday Morning Run', description: 'Twisty mountain roads', visibility: GroupRideVisibility.friendsOnly, scheduledStartAt: start, departureAt: dep, meetingPoint: meetup, ); expect(ride.title, equals('Sunday Morning Run')); expect(ride.organizerUid, equals('user_alice')); expect(ride.meetingPoint.displayName, equals('Dahlonega')); expect(ride.participantCount, equals(1)); }); test('cannot invite self to group ride', () async { final service = GroupRideService(); expect( () => service.inviteFriend( callerUid: 'user_alice', groupRideId: 'ride_1', friendProfile: organizer, // same UID! ), throwsA(isA()), ); }); test('publishLivePresence validates physical coordinates', () async { final service = GroupRideService(); expect( () => service.publishLivePresence( callerUid: 'user_alice', groupRideId: 'ride_1', latitude: 105.0, // out of range longitude: -84.0, ), throwsA(isA()), ); }); test('offline live presence and upcoming streams return safely', () async { final service = GroupRideService(); final stream = service.livePresenceStream('ride_offline'); expect(await stream.first, isEmpty); final upcoming = service.upcomingRidesStream(callerUid: 'user_alice'); expect(await upcoming.first, isEmpty); }); }); }