feat: Introduce comprehensive unit tests for models and BLoCs using mockito and bloc_test, and refine TripBloc error handling.
Some checks failed
Deploy to Play Store / build_and_deploy (push) Has been cancelled

This commit is contained in:
Van Leemput Dayron
2025-12-05 11:55:20 +01:00
parent 9b11836409
commit cac0770467
17 changed files with 1608 additions and 48 deletions

128
test/models/trip_test.dart Normal file
View File

@@ -0,0 +1,128 @@
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);
});
});
});
}