- Added TripInvitationRepository for managing trip invitations. - Created TripInvitation model with serialization methods. - Implemented notification payload parser for handling FCM notifications. - Enhanced NotificationService to manage trip invitations and related actions. - Updated UserRepository to include user search functionality. - Modified AuthRepository to store multiple FCM tokens. - Added tests for trip invitation logic and notification payload parsing. - Updated pubspec.yaml and pubspec.lock for dependency management.
155 lines
5.0 KiB
Dart
155 lines
5.0 KiB
Dart
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:firebase_core/firebase_core.dart';
|
|
import 'package:firebase_core_platform_interface/test.dart';
|
|
|
|
import 'package:travel_mate/services/notification_service.dart';
|
|
import 'package:travel_mate/services/analytics_service.dart';
|
|
|
|
import 'auth_bloc_test.mocks.dart';
|
|
|
|
@GenerateMocks([AuthRepository, NotificationService])
|
|
void main() {
|
|
TestWidgetsFlutterBinding.ensureInitialized();
|
|
|
|
group('AuthBloc', () {
|
|
late MockAuthRepository mockAuthRepository;
|
|
late MockNotificationService mockNotificationService;
|
|
late FakeAnalyticsService fakeAnalyticsService;
|
|
late AuthBloc authBloc;
|
|
|
|
final user = User(
|
|
id: '123',
|
|
nom: 'Doe',
|
|
prenom: 'John',
|
|
email: 'test@example.com',
|
|
platform: 'email',
|
|
);
|
|
|
|
setUpAll(() async {
|
|
setupFirebaseCoreMocks();
|
|
await Firebase.initializeApp();
|
|
});
|
|
|
|
setUp(() {
|
|
mockAuthRepository = MockAuthRepository();
|
|
mockNotificationService = MockNotificationService();
|
|
fakeAnalyticsService = FakeAnalyticsService();
|
|
authBloc = AuthBloc(
|
|
authRepository: mockAuthRepository,
|
|
notificationService: mockNotificationService,
|
|
analyticsService: fakeAnalyticsService,
|
|
);
|
|
|
|
// 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});
|
|
}
|
|
|
|
class FakeAnalyticsService extends AnalyticsService {
|
|
@override
|
|
Future<void> logEvent({
|
|
required String name,
|
|
Map<String, Object>? parameters,
|
|
}) async {}
|
|
|
|
@override
|
|
Future<void> setUserId(String? id) async {}
|
|
}
|