import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:travel_mate/models/trip.dart'; void main() { group('Trip Model Tests', () { const id = 'trip1'; const title = 'Summer Vacation'; const description = 'Trip to the beach'; const location = 'Miami'; final startDate = DateTime(2023, 6, 1); final endDate = DateTime(2023, 6, 10); const createdBy = 'user1'; final createdAt = DateTime(2023, 1, 1); final updatedAt = DateTime(2023, 1, 2); const budget = 2000.0; const participants = ['user1', 'user2', 'user3']; final trip = Trip( id: id, title: title, description: description, location: location, startDate: startDate, endDate: endDate, createdBy: createdBy, createdAt: createdAt, updatedAt: updatedAt, budget: budget, participants: participants, status: 'active', ); test('supports value equality', () { final trip2 = Trip( id: id, title: title, description: description, location: location, startDate: startDate, endDate: endDate, createdBy: createdBy, createdAt: createdAt, updatedAt: updatedAt, budget: budget, participants: participants, status: 'active', ); expect(trip, equals(trip2)); }); group('Helpers', () { test('durationInDays returns correct number of days', () { // 1st to 10th inclusive = 10 days expect(trip.durationInDays, 10); }); test('totalParticipants includes creator + participants list count?', () { // Source code says: participants.length + 1 // participants has 3 items. So total should be 4. expect(trip.totalParticipants, 4); }); test('budgetPerParticipant calculation', () { // 2000 / 4 = 500 expect(trip.budgetPerParticipant, 500.0); }); test( 'status checks logic (mocking DateTime.now is tricky without injection, skipping exact time logic or testing logic assumption only)', () { // For simple unit tests without time mocking, we can create trips with dates relative to "now". final now = DateTime.now(); final pastTrip = trip.copyWith( startDate: now.subtract(const Duration(days: 10)), endDate: now.subtract(const Duration(days: 5)), status: 'completed', ); expect(pastTrip.isCompleted, isTrue); final futureTrip = trip.copyWith( startDate: now.add(const Duration(days: 5)), endDate: now.add(const Duration(days: 10)), status: 'active', ); expect(futureTrip.isUpcoming, isTrue); final activeTrip = trip.copyWith( startDate: now.subtract(const Duration(days: 2)), endDate: now.add(const Duration(days: 2)), status: 'active', ); expect(activeTrip.isActive, isTrue); }, ); }); group('fromMap', () { test('parses standard Map inputs correctly', () { final map = { 'title': title, 'description': description, 'location': location, 'startDate': startDate .toIso8601String(), // _parseDateTime handles String 'endDate': Timestamp.fromDate( endDate, ), // _parseDateTime handles Timestamp 'createdBy': createdBy, 'createdAt': createdAt.millisecondsSinceEpoch, // _parseDateTime handles int 'updatedAt': updatedAt, // _parseDateTime handles DateTime 'budget': budget, 'participants': participants, 'status': 'active', }; final fromMapTrip = Trip.fromMap(map, id); expect(fromMapTrip.id, id); expect(fromMapTrip.title, title); // Dates might vary slightly due to precision if using milliseconds vs microseconds, checking explicitly later expect(fromMapTrip.description, description); expect(fromMapTrip.budget, budget); }); }); }); }