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
Some checks failed
Deploy to Play Store / build_and_deploy (push) Has been cancelled
This commit is contained in:
130
test/blocs/auth_bloc_test.dart
Normal file
130
test/blocs/auth_bloc_test.dart
Normal file
@@ -0,0 +1,130 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:bloc_test/bloc_test.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:travel_mate/blocs/auth/auth_bloc.dart';
|
||||
import 'package:travel_mate/blocs/auth/auth_event.dart';
|
||||
import 'package:travel_mate/blocs/auth/auth_state.dart';
|
||||
import 'package:travel_mate/repositories/auth_repository.dart';
|
||||
import 'package:travel_mate/models/user.dart';
|
||||
import 'package:firebase_auth/firebase_auth.dart' as firebase_auth;
|
||||
|
||||
import 'package:travel_mate/services/notification_service.dart';
|
||||
|
||||
import 'auth_bloc_test.mocks.dart';
|
||||
|
||||
@GenerateMocks([AuthRepository, NotificationService])
|
||||
void main() {
|
||||
group('AuthBloc', () {
|
||||
late MockAuthRepository mockAuthRepository;
|
||||
late MockNotificationService mockNotificationService;
|
||||
late AuthBloc authBloc;
|
||||
|
||||
final user = User(
|
||||
id: '123',
|
||||
nom: 'Doe',
|
||||
prenom: 'John',
|
||||
email: 'test@example.com',
|
||||
platform: 'email',
|
||||
);
|
||||
|
||||
setUp(() {
|
||||
mockAuthRepository = MockAuthRepository();
|
||||
mockNotificationService = MockNotificationService();
|
||||
authBloc = AuthBloc(
|
||||
authRepository: mockAuthRepository,
|
||||
notificationService: mockNotificationService,
|
||||
);
|
||||
|
||||
// Default stub for saveTokenToFirestore to avoid strict mock errors
|
||||
when(
|
||||
mockNotificationService.saveTokenToFirestore(any),
|
||||
).thenAnswer((_) async {});
|
||||
});
|
||||
|
||||
tearDown(() {
|
||||
authBloc.close();
|
||||
});
|
||||
|
||||
test('initial state is AuthUninitialized', () {
|
||||
expect(authBloc.state, AuthInitial());
|
||||
});
|
||||
|
||||
blocTest<AuthBloc, AuthState>(
|
||||
'emits [AuthAuthenticated] when AuthCheckRequested is added and user is logged in',
|
||||
build: () {
|
||||
when(
|
||||
mockAuthRepository.currentUser,
|
||||
).thenReturn(MockFirebaseUser(uid: '123', email: 'test@example.com'));
|
||||
when(
|
||||
mockAuthRepository.getUserFromFirestore('123'),
|
||||
).thenAnswer((_) async => user);
|
||||
return authBloc;
|
||||
},
|
||||
act: (bloc) => bloc.add(AuthCheckRequested()),
|
||||
expect: () => [AuthLoading(), AuthAuthenticated(user: user)],
|
||||
);
|
||||
|
||||
blocTest<AuthBloc, AuthState>(
|
||||
'emits [AuthUnauthenticated] when AuthCheckRequested is added and user is not logged in',
|
||||
build: () {
|
||||
when(mockAuthRepository.currentUser).thenReturn(null);
|
||||
return authBloc;
|
||||
},
|
||||
act: (bloc) => bloc.add(AuthCheckRequested()),
|
||||
expect: () => [AuthLoading(), AuthUnauthenticated()],
|
||||
);
|
||||
|
||||
blocTest<AuthBloc, AuthState>(
|
||||
'emits [AuthAuthenticated] when AuthSignInRequested is added',
|
||||
build: () {
|
||||
when(
|
||||
mockAuthRepository.signInWithEmailAndPassword(
|
||||
email: 'test@example.com',
|
||||
password: 'password',
|
||||
),
|
||||
).thenAnswer((_) async => user);
|
||||
return authBloc;
|
||||
},
|
||||
act: (bloc) => bloc.add(
|
||||
const AuthSignInRequested(
|
||||
email: 'test@example.com',
|
||||
password: 'password',
|
||||
),
|
||||
),
|
||||
expect: () => [AuthLoading(), AuthAuthenticated(user: user)],
|
||||
);
|
||||
|
||||
blocTest<AuthBloc, AuthState>(
|
||||
'emits [AuthUnauthenticated] when AuthSignOutRequested is added',
|
||||
build: () {
|
||||
when(mockAuthRepository.signOut()).thenAnswer((_) async {});
|
||||
return authBloc;
|
||||
},
|
||||
act: (bloc) => bloc.add(AuthSignOutRequested()),
|
||||
expect: () => [AuthUnauthenticated()],
|
||||
verify: (_) {
|
||||
verify(mockAuthRepository.signOut()).called(1);
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// Simple Mock for FirebaseUser since we can't easily mock the real one without more boilerplate
|
||||
// or using firebase_auth_mocks package which we didn't add.
|
||||
// However, AuthRepository.currentUser returns firebase_auth.User.
|
||||
// Attempting to mock it via extends might be tricky due to private constructors.
|
||||
// Let's rely on Mockito to generate a mock for firebase_auth.User if needed,
|
||||
// or adjusting the test to not depend on the return value of currentUser being a complex object
|
||||
// if the Bloc only checks for null.
|
||||
//
|
||||
// Looking at AuthBloc source (I haven't read it yet), it probably checks `authRepository.currentUser`.
|
||||
// I'll read AuthBloc code in the next step to be sure how to mock the return value.
|
||||
class MockFirebaseUser extends Mock implements firebase_auth.User {
|
||||
@override
|
||||
final String uid;
|
||||
@override
|
||||
final String? email;
|
||||
|
||||
MockFirebaseUser({required this.uid, this.email});
|
||||
}
|
||||
Reference in New Issue
Block a user